[PATCH 01/21] ls_colors.c: add $LS_COLORS parsing code
Reusing color settings from $LS_COLORS could give a native look and feel on file coloring. This code is basically from coreutils.git [1], rewritten to fit Git. As this is from GNU ls, the environment variable CLICOLOR is not tested. It is to be decided later whether we should ignore $LS_COLORS if $CLICOLOR is not set on Mac or FreeBSD. [1] commit 7326d1f1a67edf21947ae98194f98c38b6e9e527 file src/ls.c. This is the last GPL-2 commit before coreutils turns to GPL-3. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- Makefile | 1 + color.h | 8 ++ ls_colors.c (new) | 398 ++ 3 files changed, 407 insertions(+) create mode 100644 ls_colors.c diff --git a/Makefile b/Makefile index 827006b..459121d 100644 --- a/Makefile +++ b/Makefile @@ -703,6 +703,7 @@ LIB_OBJS += list-objects.o LIB_OBJS += ll-merge.o LIB_OBJS += lockfile.o LIB_OBJS += log-tree.o +LIB_OBJS += ls_colors.o LIB_OBJS += mailmap.o LIB_OBJS += match-trees.o LIB_OBJS += merge.o diff --git a/color.h b/color.h index f5beab1..3eaa5bd 100644 --- a/color.h +++ b/color.h @@ -45,6 +45,12 @@ struct strbuf; #define GIT_COLOR_BG_MAGENTA "\033[45m" #define GIT_COLOR_BG_CYAN "\033[46m" +#define GIT_COLOR_WHITE_ON_RED"\033[37;41m" +#define GIT_COLOR_WHITE_ON_BLUE "\033[37;44m" +#define GIT_COLOR_BLACK_ON_YELLOW "\033[30;43m" +#define GIT_COLOR_BLUE_ON_GREEN "\033[34;42m" +#define GIT_COLOR_BLACK_ON_GREEN "\033[30;42m" + /* A special value meaning "no color selected" */ #define GIT_COLOR_NIL "NIL" @@ -87,4 +93,6 @@ void color_print_strbuf(FILE *fp, const char *color, const struct strbuf *sb); int color_is_nil(const char *color); +void parse_ls_color(void); + #endif /* COLOR_H */ diff --git a/ls_colors.c b/ls_colors.c new file mode 100644 index 000..e743315 --- /dev/null +++ b/ls_colors.c @@ -0,0 +1,398 @@ +#include "cache.h" +#include "color.h" + +enum color_ls { + LS_LC, /* left, unused */ + LS_RC, /* right, unused */ + LS_EC, /* end color, unused */ + LS_RS, /* reset */ + LS_NO, /* normal */ + LS_FL, /* file, default */ + LS_DI, /* directory */ + LS_LN, /* symlink */ + + LS_PI, /* pipe */ + LS_SO, /* socket */ + LS_BD, /* block device */ + LS_CD, /* char device */ + LS_MI, /* missing file */ + LS_OR, /* orphaned symlink */ + LS_EX, /* executable */ + LS_DO, /* Solaris door */ + + LS_SU, /* setuid */ + LS_SG, /* setgid */ + LS_ST, /* sticky */ + LS_OW, /* other-writable */ + LS_TW, /* ow with sticky */ + LS_CA, /* cap */ + LS_MH, /* multi hardlink */ + LS_CL, /* clear end of line */ + + MAX_LS +}; + +static char ls_colors[MAX_LS][COLOR_MAXLEN] = { + "", + "", + "", + GIT_COLOR_RESET, + GIT_COLOR_NORMAL, + GIT_COLOR_NORMAL, + GIT_COLOR_BOLD_BLUE, + GIT_COLOR_BOLD_CYAN, + + GIT_COLOR_YELLOW, + GIT_COLOR_BOLD_MAGENTA, + GIT_COLOR_BOLD_YELLOW, + GIT_COLOR_BOLD_YELLOW, + GIT_COLOR_NORMAL, + GIT_COLOR_NORMAL, + GIT_COLOR_BOLD_GREEN, + GIT_COLOR_BOLD_MAGENTA, + + GIT_COLOR_WHITE_ON_RED, + GIT_COLOR_BLACK_ON_YELLOW, + GIT_COLOR_WHITE_ON_BLUE, + GIT_COLOR_BLUE_ON_GREEN, + GIT_COLOR_BLACK_ON_GREEN, + "", + "", + "" +}; + +static const char *const indicator_name[] = { + "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", + "pi", "so", "bd", "cd", "mi", "or", "ex", "do", + "su", "sg", "st", "ow", "tw", "ca", "mh", "cl", + NULL +}; + +struct bin_str { + size_t len; /* Number of bytes */ + const char *string; /* Pointer to the same */ +}; + +struct color_ext_type { + struct bin_str ext; /* The extension we're looking for */ + struct bin_str seq; /* The sequence to output when we do */ + struct color_ext_type *next;/* Next in list */ +}; + +static struct color_ext_type *color_ext_list; + +/* + * When true, in a color listing, color each symlink name according to the + * type of file it points to. Otherwise, color them according to the `ln' + * directive in LS_COLORS. Dangling (orphan) symlinks are treated specially, + * regardless. This is set when `ln=target' appears in LS_COLORS. + */ +static int color_symlink_as_referent; + +/* + * Parse a string as part of the LS_COLORS variable; this may involve + * decoding all kinds of esca
[PATCH 01/21] ls_colors.c: add $LS_COLORS parsing code
Reusing color settings from $LS_COLORS could give a native look and feel on file coloring. This code is basically from coreutils.git [1], rewritten to fit Git. As this is from GNU ls, the environment variable CLICOLOR is not tested. It is to be decided later whether we should ignore $LS_COLORS if $CLICOLOR is not set on Mac or FreeBSD. [1] commit 7326d1f1a67edf21947ae98194f98c38b6e9e527 file src/ls.c. This is the last GPL-2 commit before coreutils turns to GPL-3. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- Makefile | 1 + color.h | 8 ++ ls_colors.c (new) | 398 ++ 3 files changed, 407 insertions(+) create mode 100644 ls_colors.c diff --git a/Makefile b/Makefile index 827006b..459121d 100644 --- a/Makefile +++ b/Makefile @@ -703,6 +703,7 @@ LIB_OBJS += list-objects.o LIB_OBJS += ll-merge.o LIB_OBJS += lockfile.o LIB_OBJS += log-tree.o +LIB_OBJS += ls_colors.o LIB_OBJS += mailmap.o LIB_OBJS += match-trees.o LIB_OBJS += merge.o diff --git a/color.h b/color.h index f5beab1..3eaa5bd 100644 --- a/color.h +++ b/color.h @@ -45,6 +45,12 @@ struct strbuf; #define GIT_COLOR_BG_MAGENTA "\033[45m" #define GIT_COLOR_BG_CYAN "\033[46m" +#define GIT_COLOR_WHITE_ON_RED"\033[37;41m" +#define GIT_COLOR_WHITE_ON_BLUE "\033[37;44m" +#define GIT_COLOR_BLACK_ON_YELLOW "\033[30;43m" +#define GIT_COLOR_BLUE_ON_GREEN "\033[34;42m" +#define GIT_COLOR_BLACK_ON_GREEN "\033[30;42m" + /* A special value meaning "no color selected" */ #define GIT_COLOR_NIL "NIL" @@ -87,4 +93,6 @@ void color_print_strbuf(FILE *fp, const char *color, const struct strbuf *sb); int color_is_nil(const char *color); +void parse_ls_color(void); + #endif /* COLOR_H */ diff --git a/ls_colors.c b/ls_colors.c new file mode 100644 index 000..e743315 --- /dev/null +++ b/ls_colors.c @@ -0,0 +1,398 @@ +#include "cache.h" +#include "color.h" + +enum color_ls { + LS_LC, /* left, unused */ + LS_RC, /* right, unused */ + LS_EC, /* end color, unused */ + LS_RS, /* reset */ + LS_NO, /* normal */ + LS_FL, /* file, default */ + LS_DI, /* directory */ + LS_LN, /* symlink */ + + LS_PI, /* pipe */ + LS_SO, /* socket */ + LS_BD, /* block device */ + LS_CD, /* char device */ + LS_MI, /* missing file */ + LS_OR, /* orphaned symlink */ + LS_EX, /* executable */ + LS_DO, /* Solaris door */ + + LS_SU, /* setuid */ + LS_SG, /* setgid */ + LS_ST, /* sticky */ + LS_OW, /* other-writable */ + LS_TW, /* ow with sticky */ + LS_CA, /* cap */ + LS_MH, /* multi hardlink */ + LS_CL, /* clear end of line */ + + MAX_LS +}; + +static char ls_colors[MAX_LS][COLOR_MAXLEN] = { + "", + "", + "", + GIT_COLOR_RESET, + GIT_COLOR_NORMAL, + GIT_COLOR_NORMAL, + GIT_COLOR_BOLD_BLUE, + GIT_COLOR_BOLD_CYAN, + + GIT_COLOR_YELLOW, + GIT_COLOR_BOLD_MAGENTA, + GIT_COLOR_BOLD_YELLOW, + GIT_COLOR_BOLD_YELLOW, + GIT_COLOR_NORMAL, + GIT_COLOR_NORMAL, + GIT_COLOR_BOLD_GREEN, + GIT_COLOR_BOLD_MAGENTA, + + GIT_COLOR_WHITE_ON_RED, + GIT_COLOR_BLACK_ON_YELLOW, + GIT_COLOR_WHITE_ON_BLUE, + GIT_COLOR_BLUE_ON_GREEN, + GIT_COLOR_BLACK_ON_GREEN, + "", + "", + "" +}; + +static const char *const indicator_name[] = { + "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", + "pi", "so", "bd", "cd", "mi", "or", "ex", "do", + "su", "sg", "st", "ow", "tw", "ca", "mh", "cl", + NULL +}; + +struct bin_str { + size_t len; /* Number of bytes */ + const char *string; /* Pointer to the same */ +}; + +struct color_ext_type { + struct bin_str ext; /* The extension we're looking for */ + struct bin_str seq; /* The sequence to output when we do */ + struct color_ext_type *next;/* Next in list */ +}; + +static struct color_ext_type *color_ext_list; + +/* + * When true, in a color listing, color each symlink name according to the + * type of file it points to. Otherwise, color them according to the `ln' + * directive in LS_COLORS. Dangling (orphan) symlinks are treated specially, + * regardless. This is set when `ln=target' appears in LS_COLORS. + */ +static int color_symlink_as_referent; + +/* + * Parse a string as part of the LS_COLORS variable; this may involve + * decoding all kinds of esca