It appears that if you select text in the Terminal, then copy it, then paste it into an application that supports rich text (e.g. Mail, TextEdit, Word), then the text color will be preserved.
It appears that in Mail and TextEdit, the background color of the terminal is also pasted; in Word, it is not. I'm not sure how to explain this discrepancy.
Color information is available from the com.apple.FinderInfo
extended attribute.
$ xattr -p com.apple.FinderInfo filename
00 00 00 00 00 00 00 00 00 0C 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
First row, tenth byte, bits 3-1 (i.e. those with binary values 2, 4 and 8). The example output is for a red file with no other values set.
If the attribute isn't available or the nibble is 0
, it's colorless.
Possible values in context-menu order from left to right:
0
(colorless), C
(red), E
, A
, 4
, 8
, 6
, 2
(gray).
Remember to check for possible 1
values for that last bit, i.e. 3
would also be gray + some other attribute.
One possible solution would be the following:
Define a function ls
in ~/.bash_profile
that does something slightly different if no parameters are given:
function ls {
if [ "$#" = "0" ] ; then
find . -maxdepth 1 -exec ~/Library/Scripts/colorize.sh '{}' \;
else
$( which ls ) $@
fi
}
colorize.sh
could look like the following, calling a Python script and printing the filename depending on its output:
#!/bin/bash
filename=$1
if [ ! -e "$filename" ] ; then
exit
fi
filename="$( basename "$filename" )"
attrs=( $( $( dirname $0 )/attrs.py "$filename" | cut -f2 ) )
hidden=${attrs[0]}
if [ "$hidden" = "True" ] ; then
exit
fi
color=${attrs[1]}
case "$color" in
"none" )
format="setab 8"
;;
"red" )
format="setab 1"
;;
"orange" )
format="setab 1"
;;
"yellow" )
format="setab 3"
;;
"green" )
format="setab 2"
;;
"blue" )
format="setab 4"
;;
"purple" )
format="setab 5"
;;
"gray" )
format="setab 7"
;;
esac
echo "$( tput $format )$filename$( tput sgr0 )"
And attrs.py
, which extracts relevant file attributes, in the same directory:
#!/usr/bin/env python
from sys import argv, exit
from xattr import xattr
from struct import unpack
if len(argv) < 2:
print('Missing filename argument!')
exit(1)
attrs = xattr(argv[1])
try:
finder_attrs= attrs[u'com.apple.FinderInfo']
flags = unpack(32*'B', finder_attrs)
hidden = flags[8] & 64 == 64
color = flags[9] >> 1 & 7
except:
hidden = False
color = 0
colornames = { 0: 'none', 1: 'gray', 2 : 'green', 3 : 'purple', 4 : 'blue', 5 : 'yellow', 6 : 'red', 7 : 'orange' }
print 'hidden:\t', hidden
print 'color:\t', colornames[color]
I didn't have a large enough matching color selection here, so red and orange are both printed in red.
I added the hidden
attribute here since I am interested in that part of modifying ls
output. Just remove the if
statement if you don't want it.
Best Answer
Since the colours are stored with their ansi sequence you can create a script to translate each of them... or you can use a script just made.
For example it exists the script ansi2html [v0.15,v0.23] that you can make executable, put in a directory of your path (typically
~/bin
) and use withThen if you need a different format you can convert it or you can rewrite the script.
Note that some commands know if their output is piped or not.
For example,
ls
may change its output if piped.