summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cache.h9
-rw-r--r--config.c52
-rw-r--r--diff.c13
-rw-r--r--environment.c1
4 files changed, 70 insertions, 5 deletions
diff --git a/cache.h b/cache.h
index bfffa05dff..a6e5988f07 100644
--- a/cache.h
+++ b/cache.h
@@ -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 */
diff --git a/config.c b/config.c
index dc3148d456..ffb418ccff 100644
--- a/config.c
+++ b/config.c
@@ -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;
}
diff --git a/diff.c b/diff.c
index a6aaaf7e5a..211235376d 100644
--- a/diff.c
+++ b/diff.c
@@ -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;