Skip to content

Commit

Permalink
Use tab-size from EditorConfig
Browse files Browse the repository at this point in the history
For projects that use tab width != 8, we need to set the "tab-size"
config option.  Many projects these days 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 wait 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
  • Loading branch information
krobelus committed Oct 20, 2022
1 parent 86ae9cf commit e1fd636
Show file tree
Hide file tree
Showing 15 changed files with 182 additions and 23 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@ jobs:
export LANG=en_US.utf8
sudo apt update
sudo DEBIAN_FRONTEND=noninteractive apt -yq install --no-install-recommends \
asciidoc valgrind xmlto
asciidoc \
libeditorconfig-dev \
valgrind \
xmlto
CC=${{ matrix.compiler }} TIG_BUILD=${{ matrix.tig_build }} tools/travis.sh
10 changes: 9 additions & 1 deletion .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,13 @@ jobs:
- name: Test Tig
shell: 'script -q typescript sh {0}' # Workaround to get a TTY, see https://github.com/gfx/example-github-actions-with-tty
run: |
brew install asciidoc autoconf automake coreutils gnu-sed ncurses xmlto
brew install \
asciidoc \
autoconf \
automake \
coreutils \
editorconfig \
gnu-sed \
ncurses \
xmlto
TIG_BUILD=autoconf tools/travis.sh
2 changes: 2 additions & 0 deletions INSTALL.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ configure script and building documentation:
search and command prompts.
|PCRE |Adds support for Perl Compatible Regular
Expressions in searches.
|EditorConfig core library |Adds support for setting tab-size based on
an .editorconfig file.
|autoconf |Contains autoreconf for generating configure
from configure.ac.
|asciidoc (>= 8.4) |Generates HTML and (DocBook) XML from text.
Expand Down
7 changes: 7 additions & 0 deletions NEWS.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Release notes
=============

master
------

Improvements:

- Honor tab width from EditorConfig by linking against the EditorConfig core library. (#1239)
tig-2.5.7
---------

Expand Down
10 changes: 10 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ AS_IF([test "x$with_pcre" != xno], [
])
])

dnl Check for EditorConfig library
AC_ARG_WITH(editorconfig, [AS_HELP_STRING([--without-editorconfig], [do not use the EditorConfig library])])
AS_IF([test "x$with_editorconfig" != xno], [
AC_CHECK_HEADERS([editorconfig/editorconfig.h])
AS_IF([test "x$ac_cv_header_editorconfig_editorconfig_h" = xyes], [
AC_DEFINE([HAVE_EDITORCONFIG], [1], [Define if you have EditorConfig])
LIBS="$LIBS -leditorconfig"
])
])

dnl OS-specific
case $(uname -s 2>/dev/null || echo unknown) in "OS400")
AC_CHECK_LIB(util, main, [LIBS="$LIBS -lutil"], AC_MSG_ERROR([Please install the libutil-devel package]))
Expand Down
1 change: 1 addition & 0 deletions doc/tigrc.5.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ The following variables can be set:
'tab-size' (int)::
Number of spaces per tab. The default is 8 spaces.
This may be overridden by an EditorConfig file.
'diff-context' (int)::
Expand Down
9 changes: 9 additions & 0 deletions include/tig/diff.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@

#include "tig/view.h"

#if defined HAVE_EDITORCONFIG
struct diff_common_state {
uint8_t tab_size;
};
#endif

struct diff_state {
#if defined HAVE_EDITORCONFIG
struct diff_common_state common;
#endif
bool after_commit_title;
bool after_diff;
bool reading_diff_chunk;
Expand Down
4 changes: 3 additions & 1 deletion include/tig/pager.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@

bool pager_get_column_data(struct view *view, const struct line *line, struct view_column_data *column_data);
bool pager_read(struct view *view, struct buffer *buf, bool force_stop);
bool pager_common_read(struct view *view, const char *data, enum line_type type, struct line **line);
bool pager_common_read(struct view *view, const char *data, enum line_type type, bool is_diff, struct line **line);
enum request pager_request(struct view *view, enum request request, struct line *line);
void pager_select(struct view *view, struct line *line);

uint8_t editorconfig_tab_size(const char file[]);

extern struct view pager_view;

static inline void
Expand Down
3 changes: 3 additions & 0 deletions include/tig/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ struct box {
struct line {
enum line_type type;
unsigned int lineno:24;
#if defined HAVE_EDITORCONFIG
unsigned int tab_size:8;
#endif

/* State flags */
unsigned int selected:1;
Expand Down
10 changes: 9 additions & 1 deletion src/blob.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "tig/refdb.h"
#include "tig/parse.h"
#include "tig/repo.h"
#include "tig/diff.h"
#include "tig/display.h"
#include "tig/draw.h"
#include "tig/ui.h"
Expand All @@ -22,6 +23,9 @@
#include "tig/blob.h"

struct blob_state {
#if defined HAVE_EDITORCONFIG
struct diff_common_state common;
#endif
char commit[SIZEOF_REF];
const char *file;
};
Expand Down Expand Up @@ -90,6 +94,10 @@ blob_open(struct view *view, enum open_flags flags)
else
string_copy_rev(view->ref, view->ops->id);

#if defined HAVE_EDITORCONFIG
state->common.tab_size = editorconfig_tab_size(view->env->file);
#endif

return begin_update(view, NULL, argv, flags);
}

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

return pager_common_read(view, buf->data, LINE_DEFAULT, NULL);
return pager_common_read(view, buf->data, LINE_DEFAULT, false, NULL);
}

static void
Expand Down
36 changes: 24 additions & 12 deletions src/diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ diff_common_read_diff_wdiff_group(struct diff_stat_context *context)
return true;
}

static bool
static struct line *
diff_common_read_diff_wdiff(struct view *view, const char *text)
{
struct diff_stat_context context = { text, LINE_DEFAULT };
Expand All @@ -282,7 +282,7 @@ diff_common_read_diff_wdiff(struct view *view, const char *text)
return diff_common_add_line(view, text, LINE_DEFAULT, &context);
}

static bool
static struct line *
diff_common_highlight(struct view *view, const char *text, enum line_type type)
{
struct diff_stat_context context = { text, type, true };
Expand All @@ -303,6 +303,7 @@ bool
diff_common_read(struct view *view, const char *data, struct diff_state *state)
{
enum line_type type = get_line_type(data);
struct line *line;

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

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

if (line)
line->commit_title = 1;
Expand All @@ -345,13 +346,11 @@ diff_common_read(struct view *view, const char *data, struct diff_state *state)
if (type == LINE_DIFF_HEADER) {
state->after_diff = true;
state->reading_diff_chunk = false;

} else if (type == LINE_DIFF_CHUNK) {
const int len = chunk_header_marker_length(data);
const char *context = strstr(data + len, "@@");
struct line *line =
context ? add_line_text_at(view, view->lines, data, LINE_DIFF_CHUNK, len)
: NULL;
line = context ? add_line_text_at(view, view->lines, data, LINE_DIFF_CHUNK, len)
: NULL;
struct box *box;

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

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

} else if (state->highlight && strchr(data, 0x1b)) {
return diff_common_highlight(view, data, type);

if (!(line = diff_common_highlight(view, data, type)))
return false;
goto set_tab_width;
} else if (opt_word_diff && state->reading_diff_chunk &&
/* combined diff format is not using word diff */
!state->combined_diff) {
return diff_common_read_diff_wdiff(view, data);
if (!(line = diff_common_read_diff_wdiff(view, data)))
return false;
goto set_tab_width;
}

return pager_common_read(view, data, type, NULL);
return pager_common_read(view, data, type, true, &line);

set_tab_width:
#if defined HAVE_EDITORCONFIG
if (type == LINE_DIFF_CHUNK || type == LINE_DEFAULT ||
type == LINE_DIFF_ADD || type == LINE_DIFF_ADD2 ||
type == LINE_DIFF_DEL || type == LINE_DIFF_DEL2) {
line->tab_size = state->common.tab_size;
}
#endif
return true;
}

static bool
Expand Down
10 changes: 8 additions & 2 deletions src/draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,12 @@ view_column_draw(struct view *view, struct line *line, unsigned int lineno)
{
struct view_column *column = view->columns;
struct view_column_data column_data = {0};
int tab_size;
#if defined HAVE_EDITORCONFIG
tab_size = line->tab_size ? line->tab_size : opt_tab_size;
#else
tab_size = opt_tab_size;
#endif

if (!view->ops->get_column_data(view, line, &column_data))
return true;
Expand Down Expand Up @@ -582,13 +588,13 @@ view_column_draw(struct view *view, struct line *line, unsigned int lineno)
indent = 0;
}

if (draw_textn(view, cell->type, text, length, opt_tab_size))
if (draw_textn(view, cell->type, text, length, tab_size))
return true;

text += length;
}

} else if (draw_text(view, type, text, opt_tab_size)) {
} else if (draw_text(view, type, text, tab_size)) {
return true;
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#include "tig/pager.h"

struct log_state {
#if defined HAVE_EDITORCONFIG
struct diff_common_state common;
#endif
/* Used for tracking when we need to recalculate the previous
* commit, for example when the user scrolls up or uses the page
* up/down in the log view. */
Expand Down Expand Up @@ -142,7 +145,7 @@ log_read(struct view *view, struct buffer *buf, bool force_stop)
state->reading_diff_stat = false;
}

if (!pager_common_read(view, data, type, &line))
if (!pager_common_read(view, data, type, true, &line))
return false;
if (line && state->graph_indent)
line->graph_indent = 1;
Expand Down
Loading

0 comments on commit e1fd636

Please sign in to comment.