Skip to content

Commit f5f213d

Browse files
committed
Use tab-size from EditorConfig
For projects that use tab width != 8, users want to set the "tab-size" config option. Many projects these days already state their preference in a ".editorconfig" file. GitHub honors that file when rendering diffs and blobs. Add an optional dependency to the EditorConfig library to read such files. Prefer the tab-size from EditorConfig, over the "tab-size" config option. Not being able to override the EditorConfig tab-size seems counterintuitive but I don't see why someone would want that, so I'd mayb ewait until someone complains. If we want that we could implement a "tab-size-from-editorconfig" option that defaults to true. Implementation hiccups: Unfortunately, we currently don't always fill "repo.worktree" - only in the special cases where either of $GIT_WORK_TREE or core.worktree is defined. Hence we need to run an extra "git rev-parse --show-toplevel". We do run "git rev-parse --is-inside-worktree [...]" elsewhere but we can't add "--show-toplevel" to that call or else we'd fail when run in bare repos. The use of diff_get_pathname() is a bit wasteful, we should probably refactor this to just remember the last line of type LINE_DIFF_ADD_FILE or LINE_DIFF_HEADER. Closes #840
1 parent 2bec24c commit f5f213d

File tree

16 files changed

+194
-23
lines changed

16 files changed

+194
-23
lines changed

.github/workflows/linux.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@ jobs:
2828
export LANG=en_US.utf8
2929
sudo apt update
3030
sudo DEBIAN_FRONTEND=noninteractive apt -yq install --no-install-recommends \
31-
asciidoc valgrind xmlto
31+
asciidoc \
32+
libeditorconfig-dev \
33+
valgrind \
34+
xmlto
3235
CC=${{ matrix.compiler }} TIG_BUILD=${{ matrix.tig_build }} tools/travis.sh

.github/workflows/macos.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,13 @@ jobs:
4545
- name: Test Tig
4646
shell: 'script -q typescript sh {0}' # Workaround to get a TTY, see https://github.com/gfx/example-github-actions-with-tty
4747
run: |
48-
brew install asciidoc autoconf automake coreutils gnu-sed ncurses xmlto
48+
brew install \
49+
asciidoc \
50+
autoconf \
51+
automake \
52+
coreutils \
53+
editorconfig \
54+
gnu-sed \
55+
ncurses \
56+
xmlto
4957
TIG_BUILD=autoconf tools/travis.sh

INSTALL.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ configure script and building documentation:
206206
search and command prompts.
207207
|PCRE |Adds support for Perl Compatible Regular
208208
Expressions in searches.
209+
|EditorConfig core library |Adds support for setting tab-size based on
210+
an .editorconfig file.
209211
|autoconf |Contains autoreconf for generating configure
210212
from configure.ac.
211213
|asciidoc (>= 8.4) |Generates HTML and (DocBook) XML from text.

NEWS.adoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Release notes
22
=============
33

4+
master
5+
------
6+
7+
Improvements:
8+
9+
- Honor tab width from EditorConfig by linking against the EditorConfig core library. (#1239)
10+
411
tig-2.5.7
512
---------
613

configure.ac

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ AS_IF([test "x$with_pcre" != xno], [
5858
])
5959
])
6060

61+
dnl Check for EditorConfig library
62+
AC_ARG_WITH(editorconfig, [AS_HELP_STRING([--without-editorconfig], [do not use the EditorConfig library])])
63+
AS_IF([test "x$with_editorconfig" != xno], [
64+
AC_CHECK_HEADERS([editorconfig/editorconfig.h])
65+
AS_IF([test "x$ac_cv_header_editorconfig_editorconfig_h" = xyes], [
66+
AC_DEFINE([HAVE_EDITORCONFIG], [1], [Define if you have EditorConfig])
67+
LIBS="$LIBS -leditorconfig"
68+
])
69+
])
70+
6171
dnl OS-specific
6272
case $(uname -s 2>/dev/null || echo unknown) in "OS400")
6373
AC_CHECK_LIB(util, main, [LIBS="$LIBS -lutil"], AC_MSG_ERROR([Please install the libutil-devel package]))

doc/tigrc.5.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ The following variables can be set:
269269
'tab-size' (int)::
270270
271271
Number of spaces per tab. The default is 8 spaces.
272+
This may be overridden by an EditorConfig file.
272273
273274
'diff-context' (int)::
274275

include/tig/diff.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,16 @@
1616

1717
#include "tig/view.h"
1818

19+
#if defined HAVE_EDITORCONFIG
20+
struct diff_common_state {
21+
uint8_t tab_size;
22+
};
23+
#endif
24+
1925
struct diff_state {
26+
#if defined HAVE_EDITORCONFIG
27+
struct diff_common_state common;
28+
#endif
2029
bool after_commit_title;
2130
bool after_diff;
2231
bool reading_diff_chunk;

include/tig/pager.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
#include "tig/view.h"
1818

1919
bool pager_get_column_data(struct view *view, const struct line *line, struct view_column_data *column_data);
20-
bool pager_common_read(struct view *view, const char *data, enum line_type type, struct line **line);
20+
bool pager_common_read(struct view *view, const char *data, enum line_type type, bool is_diff, struct line **line);
2121
enum request pager_request(struct view *view, enum request request, struct line *line);
2222
void pager_select(struct view *view, struct line *line);
2323

24+
uint8_t editorconfig_tab_size(const char file[]);
25+
2426
extern struct view pager_view;
2527

2628
static inline void

include/tig/view.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ struct box {
3939
struct line {
4040
enum line_type type;
4141
unsigned int lineno:24;
42+
#if defined HAVE_EDITORCONFIG
43+
unsigned int tab_size:8;
44+
#endif
4245

4346
/* State flags */
4447
unsigned int selected:1;

src/blob.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "tig/refdb.h"
1515
#include "tig/parse.h"
1616
#include "tig/repo.h"
17+
#include "tig/diff.h"
1718
#include "tig/display.h"
1819
#include "tig/draw.h"
1920
#include "tig/ui.h"
@@ -22,6 +23,9 @@
2223
#include "tig/blob.h"
2324

2425
struct blob_state {
26+
#if defined HAVE_EDITORCONFIG
27+
struct diff_common_state common;
28+
#endif
2529
char commit[SIZEOF_REF];
2630
const char *file;
2731
};
@@ -90,6 +94,10 @@ blob_open(struct view *view, enum open_flags flags)
9094
else
9195
string_copy_rev(view->ref, view->ops->id);
9296

97+
#if defined HAVE_EDITORCONFIG
98+
state->common.tab_size = editorconfig_tab_size(view->env->file);
99+
#endif
100+
93101
return begin_update(view, NULL, argv, flags);
94102
}
95103

@@ -104,7 +112,7 @@ blob_read(struct view *view, struct buffer *buf, bool force_stop)
104112
return true;
105113
}
106114

107-
return pager_common_read(view, buf->data, LINE_DEFAULT, NULL);
115+
return pager_common_read(view, buf->data, LINE_DEFAULT, false, NULL);
108116
}
109117

110118
static void

src/diff.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ diff_common_read_diff_wdiff_group(struct diff_stat_context *context)
263263
return true;
264264
}
265265

266-
static bool
266+
static struct line *
267267
diff_common_read_diff_wdiff(struct view *view, const char *text)
268268
{
269269
struct diff_stat_context context = { text, LINE_DEFAULT };
@@ -282,7 +282,7 @@ diff_common_read_diff_wdiff(struct view *view, const char *text)
282282
return diff_common_add_line(view, text, LINE_DEFAULT, &context);
283283
}
284284

285-
static bool
285+
static struct line *
286286
diff_common_highlight(struct view *view, const char *text, enum line_type type)
287287
{
288288
struct diff_stat_context context = { text, type, true };
@@ -303,6 +303,7 @@ bool
303303
diff_common_read(struct view *view, const char *data, struct diff_state *state)
304304
{
305305
enum line_type type = get_line_type(data);
306+
struct line *line;
306307

307308
/* ADD2 and DEL2 are only valid in combined diff hunks */
308309
if (!state->combined_diff && (type == LINE_DIFF_ADD2 || type == LINE_DIFF_DEL2))
@@ -334,7 +335,7 @@ diff_common_read(struct view *view, const char *data, struct diff_state *state)
334335
}
335336

336337
if (!state->after_commit_title && !prefixcmp(data, " ")) {
337-
struct line *line = add_line_text(view, data, LINE_DEFAULT);
338+
line = add_line_text(view, data, LINE_DEFAULT);
338339

339340
if (line)
340341
line->commit_title = 1;
@@ -345,13 +346,11 @@ diff_common_read(struct view *view, const char *data, struct diff_state *state)
345346
if (type == LINE_DIFF_HEADER) {
346347
state->after_diff = true;
347348
state->reading_diff_chunk = false;
348-
349349
} else if (type == LINE_DIFF_CHUNK) {
350350
const int len = chunk_header_marker_length(data);
351351
const char *context = strstr(data + len, "@@");
352-
struct line *line =
353-
context ? add_line_text_at(view, view->lines, data, LINE_DIFF_CHUNK, len)
354-
: NULL;
352+
line = context ? add_line_text_at(view, view->lines, data, LINE_DIFF_CHUNK, len)
353+
: NULL;
355354
struct box *box;
356355

357356
if (!line)
@@ -363,21 +362,34 @@ diff_common_read(struct view *view, const char *data, struct diff_state *state)
363362
box->cell[box->cells++].type = LINE_DIFF_STAT;
364363
state->combined_diff = (len > 2);
365364
state->reading_diff_chunk = true;
366-
return true;
365+
goto set_tab_width;
367366

368367
} else if (type == LINE_COMMIT) {
369368
state->reading_diff_chunk = false;
370369

371370
} else if (state->highlight && strchr(data, 0x1b)) {
372-
return diff_common_highlight(view, data, type);
373-
371+
if (!(line = diff_common_highlight(view, data, type)))
372+
return false;
373+
goto set_tab_width;
374374
} else if (opt_word_diff && state->reading_diff_chunk &&
375375
/* combined diff format is not using word diff */
376376
!state->combined_diff) {
377-
return diff_common_read_diff_wdiff(view, data);
377+
if (!(line = diff_common_read_diff_wdiff(view, data)))
378+
return false;
379+
goto set_tab_width;
378380
}
379381

380-
return pager_common_read(view, data, type, NULL);
382+
return pager_common_read(view, data, type, true, &line);
383+
384+
set_tab_width:
385+
#if defined HAVE_EDITORCONFIG
386+
if (type == LINE_DIFF_CHUNK || type == LINE_DEFAULT ||
387+
type == LINE_DIFF_ADD || type == LINE_DIFF_ADD2 ||
388+
type == LINE_DIFF_DEL || type == LINE_DIFF_DEL2) {
389+
line->tab_size = state->common.tab_size;
390+
}
391+
#endif
392+
return true;
381393
}
382394

383395
static bool

src/draw.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,12 @@ view_column_draw(struct view *view, struct line *line, unsigned int lineno)
471471
{
472472
struct view_column *column = view->columns;
473473
struct view_column_data column_data = {0};
474+
int tab_size;
475+
#if defined HAVE_EDITORCONFIG
476+
tab_size = line->tab_size ? line->tab_size : opt_tab_size;
477+
#else
478+
tab_size = opt_tab_size;
479+
#endif
474480

475481
if (!view->ops->get_column_data(view, line, &column_data))
476482
return true;
@@ -582,13 +588,13 @@ view_column_draw(struct view *view, struct line *line, unsigned int lineno)
582588
indent = 0;
583589
}
584590

585-
if (draw_textn(view, cell->type, text, length, opt_tab_size))
591+
if (draw_textn(view, cell->type, text, length, tab_size))
586592
return true;
587593

588594
text += length;
589595
}
590596

591-
} else if (draw_text(view, type, text, opt_tab_size)) {
597+
} else if (draw_text(view, type, text, tab_size)) {
592598
return true;
593599
}
594600
}

src/log.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#include "tig/pager.h"
2020

2121
struct log_state {
22+
#if defined HAVE_EDITORCONFIG
23+
struct diff_common_state common;
24+
#endif
2225
/* Used for tracking when we need to recalculate the previous
2326
* commit, for example when the user scrolls up or uses the page
2427
* up/down in the log view. */
@@ -145,7 +148,7 @@ log_read(struct view *view, struct buffer *buf, bool force_stop)
145148
state->reading_diff_stat = false;
146149
}
147150

148-
if (!pager_common_read(view, data, type, &line))
151+
if (!pager_common_read(view, data, type, true, &line))
149152
return false;
150153
if (line && state->graph_indent)
151154
line->graph_indent = 1;

0 commit comments

Comments
 (0)