diff options
| -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 */ |
