aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-09-11 15:52:32 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-09-11 15:52:32 +0200
commit6c5bdddbb5e7f79a04a0ee2bd7a9252035151812 (patch)
tree128f04c8f39aac526414056fda2c4ac11eb46ea1
parent89c99d64005f9e31b70f7eae8c0f6a76b24f4b14 (diff)
downloadvis-6c5bdddbb5e7f79a04a0ee2bd7a9252035151812.tar.gz
vis-6c5bdddbb5e7f79a04a0ee2bd7a9252035151812.tar.xz
Add :edit command
-rw-r--r--config.def.h1
-rw-r--r--editor.c23
-rw-r--r--editor.h2
-rw-r--r--vis.c38
-rw-r--r--window.c6
-rw-r--r--window.h2
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 */