diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2014-09-19 11:27:55 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2014-09-19 11:27:55 +0200 |
| commit | f212b9d4952c87052e23b5161195917410b7c911 (patch) | |
| tree | 238e6fdefac447230b556779870dde4baa466247 | |
| parent | def913f428365d048ce30d71117421acbf379a75 (diff) | |
| download | vis-f212b9d4952c87052e23b5161195917410b7c911.tar.gz vis-f212b9d4952c87052e23b5161195917410b7c911.tar.xz | |
Implement expand tab functionality, make tabwidth configurable
If expandtab is enabled then inserted tabs are replaced by tabwidth
amount of spaces.
Both settings apply to all windows files and can be changed via:
:set tabwidth n # where 1 <= n <= 8
:set expandtab (1|yes|true)|(0|no|false)
| -rw-r--r-- | config.def.h | 2 | ||||
| -rw-r--r-- | editor.c | 13 | ||||
| -rw-r--r-- | editor.h | 6 | ||||
| -rw-r--r-- | vis.c | 42 | ||||
| -rw-r--r-- | window.c | 7 | ||||
| -rw-r--r-- | window.h | 2 |
6 files changed, 68 insertions, 4 deletions
diff --git a/config.def.h b/config.def.h index c03da71..6e235a0 100644 --- a/config.def.h +++ b/config.def.h @@ -52,6 +52,7 @@ static Command cmds[] = { { "^qa(ll)?!?$", cmd_qall }, { "^q(quit)?!?$", cmd_quit }, { "^r(ead)?$", cmd_read }, + { "^set$", cmd_set }, { "^sp(lit)?$", cmd_split }, { "^s(ubstitute)?$", cmd_substitute }, { "^v(split)?$", cmd_vsplit }, @@ -474,6 +475,7 @@ static KeyBinding vis_mode_insert[] = { { { CONTROL('M') }, insert_newline, { NULL } }, { { CONTROL('O') }, switchmode, { .i = VIS_MODE_OPERATOR } }, { { CONTROL('V') }, insert_verbatim, { NULL } }, + { { NONE('\t') }, insert_tab, { NULL } }, { /* empty last element, array terminator */ }, }; @@ -185,6 +185,16 @@ static void editor_windows_invalidate(Editor *ed, size_t start, size_t end) { editor_window_draw(ed->win); } +int editor_tabwidth_get(Editor *ed) { + return ed->tabwidth; +} + +void editor_tabwidth_set(Editor *ed, int tabwidth) { + if (tabwidth < 1 || tabwidth > 8) + return; + for (EditorWin *win = ed->windows; win; win = win->next) + window_tabwidth_set(win->win, tabwidth); +} bool editor_syntax_load(Editor *ed, Syntax *syntaxes, Color *colors) { bool success = true; @@ -296,6 +306,7 @@ static EditorWin *editor_window_new_text(Editor *ed, Text *text) { return NULL; } window_cursor_watch(win->win, editor_window_cursor_moved, win); + window_tabwidth_set(win->win, ed->tabwidth); if (ed->windows) ed->windows->prev = win; win->next = ed->windows; @@ -381,6 +392,8 @@ Editor *editor_new(int width, int height) { goto err; ed->width = width; ed->height = height; + ed->tabwidth = 8; + ed->expandtab = false; ed->windows_arrange = editor_windows_arrange_horizontal; return ed; err: @@ -99,6 +99,8 @@ struct Editor { Regex *search_pattern; /* last used search pattern */ void (*windows_arrange)(Editor*); /* current layout which places the windows */ void (*statusbar)(EditorWin*); /* configurable user hook to draw statusbar */ + int tabwidth; /* how many spaces should be used to display a tab */ + bool expandtab; /* whether typed tabs should be converted to spaces */ }; Editor *editor_new(int width, int height); @@ -116,6 +118,10 @@ void editor_delete_key(Editor*); void editor_insert(Editor*, size_t pos, const char *data, size_t len); void editor_delete(Editor*, size_t pos, size_t len); +/* set tabwidth (must be in range [1, 8], affects all windows */ +void editor_tabwidth_set(Editor*, int tabwidth); +int editor_tabwidth_get(Editor*); + /* load a set of syntax highlighting definitions which will be associated * to the underlying window based on the file type loaded. * @@ -410,6 +410,8 @@ static void call(const Arg *arg); static void quit(const Arg *arg); /** commands to enter at the ':'-prompt */ +/* set various runtime options */ +static bool cmd_set(const char *argv[]); /* goto line indicated by argv[0] */ static bool cmd_gotoline(const char *argv[]); /* for each argument create a new window and open the corresponding file */ @@ -473,7 +475,13 @@ static void op_put(OperatorContext *c) { } static const char *expand_tab(void) { - return "\t"; + static char spaces[9]; + int tabwidth = editor_tabwidth_get(vis); + tabwidth = MIN(tabwidth, LENGTH(spaces) - 1); + for (int i = 0; i < tabwidth; i++) + spaces[i] = ' '; + spaces[tabwidth] = '\0'; + return vis->expandtab ? spaces : "\t"; } static void op_shift_right(OperatorContext *c) { @@ -497,7 +505,7 @@ static void op_shift_right(OperatorContext *c) { static void op_shift_left(OperatorContext *c) { Text *txt = vis->win->text; size_t pos = text_line_begin(txt, c->range.end), prev_pos; - size_t tabwidth = 8; // TODO: make configurable + size_t tabwidth = editor_tabwidth_get(vis); /* if range ends at the begin of a line, skip line break */ if (pos == c->range.end) @@ -836,7 +844,7 @@ static void insert(const Arg *arg) { } static void insert_tab(const Arg *arg) { - insert(&(const Arg){ .s = "\t" }); + return insert(&(const Arg){ .s = expand_tab() }); } static void insert_newline(const Arg *arg) { @@ -985,6 +993,34 @@ static void switchmode_to(Mode *new_mode) { /** ':'-command implementations */ +static bool cmd_set(const char *argv[]) { + if (!argv[2]) { + editor_info_show(vis, "Expecting: set option value"); + return false; + } + + if (!strcmp("tabwidth", argv[1])) { + editor_tabwidth_set(vis, strtoul(argv[2], NULL, 10)); + } else if (!strcmp("expandtab", argv[1])) { + switch (argv[2][0]) { + case '1': case 't': /* true */ case 'y': /* yes */ + vis->expandtab = true; + break; + case '0': case 'f': /* false */ case 'n': /* no */ + vis->expandtab = false; + break; + default: + editor_info_show(vis, "Expecting: set expandtab [0|1]"); + return false; + } + } else { + editor_info_show(vis, "Unknown option: `%s'", argv[1]); + return false; + } + + return true; +} + static bool cmd_gotoline(const char *argv[]) { action.count = strtoul(argv[0], NULL, 10); movement(&(const Arg){ .i = action.count <= 1 ? MOVE_FILE_BEGIN : MOVE_LINE }); @@ -91,6 +91,11 @@ static void window_cursor_set(Win *win, Line *line, int col); static bool window_viewport_up(Win *win, int n); static bool window_viewport_down(Win *win, int n); +void window_tabwidth_set(Win *win, int tabwidth) { + win->tabwidth = tabwidth; + window_draw(win); +} + void window_selection_clear(Win *win) { win->sel = text_range_empty(); window_draw(win); @@ -489,7 +494,7 @@ Win *window_new(Text *text) { } win->text = text; - win->tabwidth = 8; // TODO make configurable + win->tabwidth = 8; int width, height; getmaxyx(win->win, height, width); @@ -24,6 +24,8 @@ void window_move(Win*, int x, int y); void window_draw(Win*); /* flush all changes made to the ncurses windows to the screen */ void window_update(Win*); +/* changes how many spaces are used for one tab (must be >0), redraws the window */ +void window_tabwidth_set(Win*, int tabwidth); /* cursor movements which also update selection if one is active. * they return new cursor postion */ |
