diff options
-rw-r--r-- | cache.h | 9 | ||||
-rw-r--r-- | config.c | 52 | ||||
-rw-r--r-- | diff.c | 13 | ||||
-rw-r--r-- | environment.c | 1 |
4 files changed, 70 insertions, 5 deletions
@@ -602,4 +602,13 @@ extern int diff_auto_refresh_index; /* match-trees.c */ void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int); +/* + * whitespace rules. + * used by both diff and apply + */ +#define WS_TRAILING_SPACE 01 +#define WS_SPACE_BEFORE_TAB 02 +#define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB) +extern unsigned whitespace_rule; + #endif /* CACHE_H */ @@ -246,6 +246,53 @@ static unsigned long get_unit_factor(const char *end) die("unknown unit: '%s'", end); } +static struct whitespace_rule { + const char *rule_name; + unsigned rule_bits; +} whitespace_rule_names[] = { + { "trailing-space", WS_TRAILING_SPACE }, + { "space-before-tab", WS_SPACE_BEFORE_TAB }, +}; + +static unsigned parse_whitespace_rule(const char *string) +{ + unsigned rule = WS_DEFAULT_RULE; + + while (string) { + int i; + size_t len; + const char *ep; + int negated = 0; + + string = string + strspn(string, ", \t\n\r"); + ep = strchr(string, ','); + if (!ep) + len = strlen(string); + else + len = ep - string; + + if (*string == '-') { + negated = 1; + string++; + len--; + } + if (!len) + break; + for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++) { + if (strncmp(whitespace_rule_names[i].rule_name, + string, len)) + continue; + if (negated) + rule &= ~whitespace_rule_names[i].rule_bits; + else + rule |= whitespace_rule_names[i].rule_bits; + break; + } + string = ep; + } + return rule; +} + int git_parse_long(const char *value, long *ret) { if (value && *value) { @@ -431,6 +478,11 @@ int git_default_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.whitespace")) { + whitespace_rule = parse_whitespace_rule(value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; } @@ -508,7 +508,8 @@ static void emit_line_with_ws(int nparents, for (i = col0; i < len; i++) { if (line[i] == '\t') { last_tab_in_indent = i; - if (0 <= last_space_in_indent) + if ((whitespace_rule & WS_SPACE_BEFORE_TAB) && + 0 <= last_space_in_indent) need_highlight_leading_space = 1; } else if (line[i] == ' ') @@ -540,10 +541,12 @@ static void emit_line_with_ws(int nparents, tail = len - 1; if (line[tail] == '\n' && i < tail) tail--; - while (i < tail) { - if (!isspace(line[tail])) - break; - tail--; + if (whitespace_rule & WS_TRAILING_SPACE) { + while (i < tail) { + if (!isspace(line[tail])) + break; + tail--; + } } if ((i < tail && line[tail + 1] != '\n')) { /* This has whitespace between tail+1..len */ diff --git a/environment.c b/environment.c index b5a6c69f7c..624dd9677c 100644 --- a/environment.c +++ b/environment.c @@ -35,6 +35,7 @@ int pager_in_use; int pager_use_color = 1; char *editor_program; int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */ +unsigned whitespace_rule = WS_DEFAULT_RULE; /* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg; |