From 6c5bdddbb5e7f79a04a0ee2bd7a9252035151812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Thu, 11 Sep 2014 15:52:32 +0200 Subject: Add :edit command --- config.def.h | 1 + editor.c | 23 +++++++++++++++++++++++ editor.h | 2 ++ vis.c | 38 +++++++++++++++++++++++++++++++------- window.c | 6 ++++++ window.h | 2 ++ 6 files changed, 65 insertions(+), 7 deletions(-) diff --git a/config.def.h b/config.def.h index d26045d..4b5bf79 100644 --- a/config.def.h +++ b/config.def.h @@ -50,6 +50,7 @@ enum { */ static Command cmds[] = { { "^[0-9]+", cmd_gotoline }, + { "^e(dit)?", cmd_edit }, { "^o(pen)?", cmd_open }, { "^qa(ll)?", cmd_qall }, { "^q(quit)?", cmd_quit }, diff --git a/editor.c b/editor.c index a7ef802..455f3ae 100644 --- a/editor.c +++ b/editor.c @@ -85,6 +85,29 @@ static void editor_windows_arrange_vertical(Editor *ed) { } } +bool editor_window_reload(EditorWin *win) { + const char *filename = text_filename(win->text); + /* can't reload unsaved file */ + if (!filename) + return false; + Text *text = text_load(filename); + if (!text) + return false; + /* check wether the text is displayed in another window */ + bool needed = false; + for (EditorWin *w = win->editor->windows; w; w = w->next) { + if (w != win && w->text == win->text) { + needed = true; + break; + } + } + if (!needed) + text_free(win->text); + win->text = text; + window_reload(win->win, text); + return true; +} + static void editor_window_split_internal(Editor *ed, const char *filename) { EditorWin *sel = ed->win; if (filename) { diff --git a/editor.h b/editor.h index 8ca1a79..f7030b0 100644 --- a/editor.h +++ b/editor.h @@ -128,6 +128,8 @@ void editor_syntax_unload(Editor*); /* creates a new window, and loads the given file. if filename is NULL * an unamed / empty buffer is created */ 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 diff --git a/vis.c b/vis.c index 29ffe9e..8ca33bd 100644 --- a/vis.c +++ b/vis.c @@ -383,6 +383,9 @@ static void quit(const Arg *arg); static bool cmd_gotoline(const char *argv[]); /* for each argument create a new window and open the corresponding file */ static bool cmd_open(const char *argv[]); +/* close current window (discard modifications if argv[0] contains '!') + * and open argv[1], if no argv[1] is given re-read to current file from disk */ +static bool cmd_edit(const char *argv[]); /* close the current window, if argv[0] contains a '!' discard modifications */ static bool cmd_quit(const char *argv[]); /* close all windows, exit editor, if argv[0] contains a '!' discard modifications */ @@ -864,18 +867,39 @@ static bool cmd_gotoline(const char *argv[]) { } static bool cmd_open(const char *argv[]) { - for (const char **file = &argv[1]; *file; file++) - editor_window_new(vis, *file); + for (const char **file = &argv[1]; *file; file++) { + if (!editor_window_new(vis, *file)) + return false; + } + return true; +} + +static bool is_window_closeable(EditorWin *win) { + if (!text_modified(win->text)) + return true; + for (EditorWin *w = vis->windows; w; w = w->next) { + if (w != win && w->text == win->text) + return true; + } + return false; +} + +static bool cmd_edit(const char *argv[]) { + EditorWin *oldwin = vis->win; + bool force = strchr(argv[0], '!') != NULL; + if (!force && !is_window_closeable(oldwin)) + return false; + if (!argv[1]) + return editor_window_reload(oldwin); + if (!editor_window_new(vis, argv[1])) + return false; + editor_window_close(oldwin); return true; } static bool cmd_quit(const char *argv[]) { bool force = strchr(argv[0], '!') != NULL; - for (EditorWin *win = vis->windows; !force && win; win = win->next) { - if (win != vis->win && win->text == vis->win->text) - force = true; - } - if (!force && text_modified(vis->win->text)) + if (!force && !is_window_closeable(vis->win)) return false; editor_window_close(vis->win); if (!vis->windows) diff --git a/window.c b/window.c index 931c4dc..4a80331 100644 --- a/window.c +++ b/window.c @@ -463,6 +463,12 @@ void window_free(Win *win) { free(win); } +void window_reload(Win *win, Text *text) { + win->text = text; + window_selection_clear(win); + window_cursor_to(win, 0); +} + Win *window_new(Text *text) { if (!text) return NULL; diff --git a/window.h b/window.h index f7016b5..e7d5b0b 100644 --- a/window.h +++ b/window.h @@ -9,6 +9,8 @@ typedef struct Win Win; Win *window_new(Text*); +/* change associated text displayed in this window */ +void window_reload(Win*, Text*); void window_free(Win*); /* keyboard input at cursor position */ -- cgit v1.2.3