diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2014-09-18 14:34:33 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2014-09-18 17:37:37 +0200 |
| commit | a9fb53c81cec2008acc0ff3fc808ca5bd32f317e (patch) | |
| tree | 7f3692a8105bda4844ac232ebf248ec3268bd315 | |
| parent | 3eaa312c0babe1264d5f4408f82310cd1458dd02 (diff) | |
| download | vis-a9fb53c81cec2008acc0ff3fc808ca5bd32f317e.tar.gz vis-a9fb53c81cec2008acc0ff3fc808ca5bd32f317e.tar.xz | |
Clean up window splitting API
| -rw-r--r-- | editor.c | 81 | ||||
| -rw-r--r-- | editor.h | 14 | ||||
| -rw-r--r-- | vis.c | 34 |
3 files changed, 75 insertions, 54 deletions
@@ -20,7 +20,7 @@ static EditorWin *editor_window_new_text(Editor *ed, Text *text); static void editor_window_free(Editor *ed, EditorWin *win); -static void editor_window_split_internal(Editor *ed, const char *filename); +static bool editor_window_split_internal(EditorWin *original); static void editor_windows_invalidate(Editor *ed, size_t start, size_t end); static void editor_window_draw(EditorWin *win); static void editor_windows_arrange_horizontal(Editor *ed); @@ -111,41 +111,30 @@ bool editor_window_reload(EditorWin *win) { return true; } -static void editor_window_split_internal(Editor *ed, const char *filename) { - EditorWin *sel = ed->win; - if (filename) { - // TODO? move this to editor_window_new - sel = NULL; - for (EditorWin *w = ed->windows; w; w = w->next) { - const char *f = text_filename_get(w->text); - if (f && strcmp(f, filename) == 0) { - sel = w; - break; - } - } - } - if (sel) { - EditorWin *win = editor_window_new_text(ed, sel->text); - if (!win) - return; - win->text = sel->text; - window_syntax_set(win->win, window_syntax_get(sel->win)); - window_cursor_to(win->win, window_cursor_get(sel->win)); - } else { - editor_window_new(ed, filename); - } +static bool editor_window_split_internal(EditorWin *original) { + EditorWin *win = editor_window_new_text(original->editor, original->text); + if (!win) + return false; + win->text = original->text; + window_syntax_set(win->win, window_syntax_get(original->win)); + window_cursor_to(win->win, window_cursor_get(original->win)); + return true; } -void editor_window_split(Editor *ed, const char *filename) { - editor_window_split_internal(ed, filename); - ed->windows_arrange = editor_windows_arrange_horizontal; - editor_draw(ed); +bool editor_window_split(EditorWin *win) { + if (!editor_window_split_internal(win)) + return false; + win->editor->windows_arrange = editor_windows_arrange_horizontal; + editor_draw(win->editor); + return true; } -void editor_window_vsplit(Editor *ed, const char *filename) { - editor_window_split_internal(ed, filename); - ed->windows_arrange = editor_windows_arrange_vertical; - editor_draw(ed); +bool editor_window_vsplit(EditorWin *win) { + if (!editor_window_split_internal(win)) + return false; + win->editor->windows_arrange = editor_windows_arrange_vertical; + editor_draw(win->editor); + return true; } void editor_resize(Editor *ed, int width, int height) { @@ -317,25 +306,45 @@ static EditorWin *editor_window_new_text(Editor *ed, Text *text) { } bool editor_window_new(Editor *ed, const char *filename) { - Text *text = text_load(filename && access(filename, R_OK) == 0 ? filename : NULL); + Text *text = NULL; + /* try to detect whether the same file is already open in another window + * TODO: do this based on inodes */ + EditorWin *original = NULL; + if (filename) { + for (EditorWin *win = ed->windows; win; win = win->next) { + const char *f = text_filename_get(win->text); + if (f && strcmp(f, filename) == 0) { + original = win; + break; + } + } + } + + if (original) + text = original->text; + else + text = text_load(filename && access(filename, R_OK) == 0 ? filename : NULL); if (!text) return false; - if (filename) - text_filename_set(text, filename); EditorWin *win = editor_window_new_text(ed, text); if (!win) { - text_free(text); + if (!original) + text_free(text); return false; } if (filename) { + text_filename_set(text, filename); for (Syntax *syn = ed->syntaxes; syn && syn->name; syn++) { if (!regexec(&syn->file_regex, filename, 0, NULL, 0)) { window_syntax_set(win->win, syn); break; } } + } else if (original) { + window_syntax_set(win->win, window_syntax_get(original->win)); + window_cursor_to(win->win, window_cursor_get(original->win)); } editor_draw(ed); @@ -125,17 +125,17 @@ bool editor_syntax_load(Editor*, Syntax *syntaxes, Color *colors); void editor_syntax_unload(Editor*); /* creates a new window, and loads the given file. if filename is NULL - * an unamed / empty buffer is created */ + * an unamed / empty buffer is created. If the given file is already opened + * in another window, share the underlying text that is changes will be + * visible in both windows */ bool editor_window_new(Editor*, const char *filename); /* reload the file currently displayed in the window from disk */ bool editor_window_reload(EditorWin*); void editor_window_close(EditorWin*); -/* if filename is non NULL it is equivalent to window_new call above. - * if however filename is NULL a new window is created and linked to the - * same underlying text as the currently selected one. changes will - * thus be visible in both windows. */ -void editor_window_split(Editor*, const char *filename); -void editor_window_vsplit(Editor*, const char *filename); +/* split the given window either horizontally or vertically, changes to + * the displayed text will be reflected in both windows */ +bool editor_window_split(EditorWin*); +bool editor_window_vsplit(EditorWin*); /* focus the next / previous window */ void editor_window_next(Editor*); void editor_window_prev(Editor*); @@ -793,9 +793,9 @@ static void winclose(const Arg *arg) { static void winsplit(const Arg *arg) { if (arg->b) - editor_window_vsplit(vis, NULL); + editor_window_vsplit(vis->win); else - editor_window_split(vis, NULL); + editor_window_split(vis->win); } static int argi2lines(const Arg *arg) { @@ -995,7 +995,9 @@ static bool cmd_gotoline(const char *argv[]) { static bool cmd_open(const char *argv[]) { for (const char **file = &argv[1]; *file; file++) { if (!editor_window_new(vis, *file)) { - editor_info_show(vis, "Can't open `%s'"); + errno = 0; + editor_info_show(vis, "Can't open `%s' %s", *file, + errno ? strerror(errno) : ""); return false; } } @@ -1090,18 +1092,28 @@ static bool cmd_substitute(const char *argv[]) { return true; } -static bool cmd_split(const char *argv[]) { - editor_window_split(vis, argv[1]); - for (const char **file = &argv[2]; *file; file++) - editor_window_split(vis, *file); +static bool openfiles(const char **files) { + for (; *files; files++) { + errno = 0; + if (!editor_window_new(vis, *files)) { + editor_info_show(vis, "Could not open `%s' %s", *files, + errno ? strerror(errno) : ""); + return false; + } + } return true; } +static bool cmd_split(const char *argv[]) { + if (!argv[1]) + return editor_window_split(vis->win); + return openfiles(&argv[1]); +} + static bool cmd_vsplit(const char *argv[]) { - editor_window_vsplit(vis, argv[1]); - for (const char **file = &argv[2]; *file; file++) - editor_window_vsplit(vis, *file); - return true; + if (!argv[1]) + return editor_window_vsplit(vis->win); + return openfiles(&argv[1]); } static bool cmd_wq(const char *argv[]) { |
