The attached patches on top of current git HEAD should provide the same
functionality you provided. 

Not sure whether they should be merged. Could be useful when displaying
grep search results in a window as in:

 :| grep something *.c

-- 
 Marc André Tanner >< http://www.brain-dump.org/ >< GPG key: 10C93617
>From 76426e46fe2936e22f517385d057a9445d3fe67c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= <m...@brain-dump.org>
Date: Sun, 7 Feb 2016 16:06:31 +0100
Subject: [PATCH 1/2] vis: export vis_window_closable

---
 vis-cmds.c | 10 ++--------
 vis.c      | 10 ++++++++++
 vis.h      |  3 +++
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/vis-cmds.c b/vis-cmds.c
index 3f612f4..b3dad5b 100644
--- a/vis-cmds.c
+++ b/vis-cmds.c
@@ -429,19 +429,13 @@ static bool cmd_open(Vis *vis, Filerange *range, enum CmdOpt opt, const char *ar
 	return openfiles(vis, &argv[1]);
 }
 
-static bool is_view_closeable(Win *win) {
-	if (!text_modified(win->file->text))
-		return true;
-	return win->file->refcount > 1;
-}
-
 static void info_unsaved_changes(Vis *vis) {
 	vis_info_show(vis, "No write since last change (add ! to override)");
 }
 
 static bool cmd_edit(Vis *vis, Filerange *range, enum CmdOpt opt, const char *argv[]) {
 	Win *oldwin = vis->win;
-	if (!(opt & CMD_OPT_FORCE) && !is_view_closeable(oldwin)) {
+	if (!(opt & CMD_OPT_FORCE) && !vis_window_closable(oldwin)) {
 		info_unsaved_changes(vis);
 		return false;
 	}
@@ -463,7 +457,7 @@ static bool has_windows(Vis *vis) {
 }
 
 static bool cmd_quit(Vis *vis, Filerange *range, enum CmdOpt opt, const char *argv[]) {
-	if (!(opt & CMD_OPT_FORCE) && !is_view_closeable(vis->win)) {
+	if (!(opt & CMD_OPT_FORCE) && !vis_window_closable(vis->win)) {
 		info_unsaved_changes(vis);
 		return false;
 	}
diff --git a/vis.c b/vis.c
index b65724c..42bc0a0 100644
--- a/vis.c
+++ b/vis.c
@@ -284,6 +284,12 @@ bool vis_window_new(Vis *vis, const char *filename) {
 	return true;
 }
 
+bool vis_window_closable(Win *win) {
+	if (!text_modified(win->file->text))
+		return true;
+	return win->file->refcount > 1;
+}
+
 void vis_window_close(Win *win) {
 	Vis *vis = win->vis;
 	if (vis->event && vis->event->win_close)
@@ -1090,6 +1096,10 @@ View *vis_view(Vis *vis) {
 	return vis->win->view;
 }
 
+Win *vis_window(Vis *vis) {
+	return vis->win;
+}
+
 Text *vis_file_text(File *file) {
 	return file->text;
 }
diff --git a/vis.h b/vis.h
index 3bcd9c7..eb84695 100644
--- a/vis.h
+++ b/vis.h
@@ -67,6 +67,8 @@ void vis_suspend(Vis*);
 bool vis_window_new(Vis*, const char *filename);
 /* reload the file currently displayed in the window from disk */
 bool vis_window_reload(Win*);
+/* check whether closing the window would loose unsaved changes */
+bool vis_window_closable(Win*);
 /* close window, redraw user interface */
 void vis_window_close(Win*);
 /* split the given window. changes to the displayed text will be reflected
@@ -405,6 +407,7 @@ bool vis_signal_handler(Vis*, int signum, const siginfo_t *siginfo, const void *
 /* TODO: expose proper API to iterate through files etc */
 Text *vis_text(Vis*);
 View *vis_view(Vis*);
+Win *vis_window(Vis*);
 Text *vis_file_text(File*);
 const char *vis_file_name(File*);
 
-- 
2.1.4

>From b02aff69f90ffb5fe214d10e11386cadab2df55c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= <m...@brain-dump.org>
Date: Sun, 7 Feb 2016 16:07:44 +0100
Subject: [PATCH 2/2] vis: implement gf and <C-w>gf to open filename under
 cursor

Based on a patch by Silvan Jegen.
---
 config.def.h |  2 ++
 main.c       | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/config.def.h b/config.def.h
index 47ed326..774871b 100644
--- a/config.def.h
+++ b/config.def.h
@@ -233,6 +233,8 @@ static const KeyBinding bindings_normal[] = {
 	{ "gP",                 ACTION(PUT_BEFORE_END)                      },
 	{ "~",                  ALIAS("<vis-operator-case-swap>l")          },
 	{ "<End>",              ALIAS("$")                                  },
+	{ "gf",                 ACTION(OPEN_FILE_UNDER_CURSOR)              },
+	{ "<C-w>gf",            ACTION(OPEN_FILE_UNDER_CURSOR_NEW_WINDOW)   },
 	{ 0 /* empty last element, array terminator */                      },
 };
 
diff --git a/main.c b/main.c
index c3ae7a3..21a1066 100644
--- a/main.c
+++ b/main.c
@@ -111,6 +111,8 @@ static const char *unicode_info(Vis*, const char *keys, const Arg *arg);
 static const char *percent(Vis*, const char *keys, const Arg *arg);
 /* either increment (arg->i > 0) or decrement (arg->i < 0) number under cursor */
 static const char *number_increment_decrement(Vis*, const char *keys, const Arg *arg);
+/* open a filename under cursor in same (!arg->b) or new (arg->b) window */
+static const char *open_file_under_cursor(Vis*, const char *keys, const Arg *arg);
 
 enum {
 	VIS_ACTION_EDITOR_SUSPEND,
@@ -272,6 +274,8 @@ enum {
 	VIS_ACTION_UNICODE_INFO,
 	VIS_ACTION_NUMBER_INCREMENT,
 	VIS_ACTION_NUMBER_DECREMENT,
+	VIS_ACTION_OPEN_FILE_UNDER_CURSOR,
+	VIS_ACTION_OPEN_FILE_UNDER_CURSOR_NEW_WINDOW,
 	VIS_ACTION_NOP,
 };
 
@@ -1071,6 +1075,16 @@ static KeyAction vis_action[] = {
 		"Decrement number under cursor",
 		number_increment_decrement, { .i = -1 }
 	},
+	[VIS_ACTION_OPEN_FILE_UNDER_CURSOR] = {
+		"open-file-under-cursor",
+		"Open file under the cursor",
+		open_file_under_cursor, { .b = false }
+	},
+	[VIS_ACTION_OPEN_FILE_UNDER_CURSOR_NEW_WINDOW] = {
+		"open-file-under-cursor-new-cursor",
+		"Open file under the cursor in a new window",
+		open_file_under_cursor, { .b = true }
+	},
 	[VIS_ACTION_NOP] = {
 		"nop",
 		"Ignore key, do nothing",
@@ -1677,6 +1691,32 @@ static const char *number_increment_decrement(Vis *vis, const char *keys, const
 	return keys;
 }
 
+static const char *open_file_under_cursor(Vis *vis, const char *keys, const Arg *arg) {
+	Win *win = vis_window(vis);
+	View *view = vis_view(vis);
+	Text *txt = vis_text(vis);
+
+	if (!arg->b && !vis_window_closable(win)) {
+		vis_info_show(vis, "No write since last change");
+		return keys;
+	}
+
+	for (Cursor *c = view_cursors(view); c; c = view_cursors_next(c)) {
+		Filerange r = text_object_filename(txt, view_cursors_pos(c));
+		if (!text_range_valid(&r))
+			continue;
+		char *name = text_bytes_alloc0(txt, r.start, text_range_size(&r));
+		if (name && vis_window_new(vis, name) && !arg->b) {
+			vis_window_close(win);
+			free(name);
+			return keys;
+		}
+		free(name);
+	}
+
+	return keys;
+}
+
 static Vis *vis;
 
 static void signal_handler(int signum, siginfo_t *siginfo, void *context) {
-- 
2.1.4

Reply via email to