aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editor.c81
-rw-r--r--editor.h14
-rw-r--r--vis.c34
3 files changed, 75 insertions, 54 deletions
diff --git a/editor.c b/editor.c
index 97d59f2..967bcfa 100644
--- a/editor.c
+++ b/editor.c
@@ -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);
diff --git a/editor.h b/editor.h
index bb20fdb..3b750e9 100644
--- a/editor.h
+++ b/editor.h
@@ -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*);
diff --git a/vis.c b/vis.c
index 93b32b9..48f89c7 100644
--- a/vis.c
+++ b/vis.c
@@ -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[]) {