aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editor.c44
-rw-r--r--editor.h6
-rw-r--r--text.c14
-rw-r--r--text.h4
-rw-r--r--ui-curses.c32
-rw-r--r--ui.h6
-rw-r--r--view.c2
-rw-r--r--vis.c15
8 files changed, 58 insertions, 65 deletions
diff --git a/editor.c b/editor.c
index ae2bc2d..11704e9 100644
--- a/editor.c
+++ b/editor.c
@@ -21,21 +21,35 @@ static void window_selection_changed(void *win, Filerange *sel) {
}
}
+void editor_window_name(Win *win, const char *filename) {
+ File *file = win->file;
+ free((char*)file->name);
+ file->name = filename ? strdup(filename) : NULL;
+
+ if (filename) {
+ for (Syntax *syn = win->editor->syntaxes; syn && syn->name; syn++) {
+ if (!regexec(&syn->file_regex, filename, 0, NULL, 0)) {
+ view_syntax_set(win->view, syn);
+ break;
+ }
+ }
+ }
+}
+
void editor_windows_arrange(Editor *ed, enum UiLayout layout) {
ed->ui->arrange(ed->ui, layout);
}
bool editor_window_reload(Win *win) {
- const char *filename = text_filename_get(win->file->text);
/* can't reload unsaved file */
- if (!filename)
+ if (!win->file->name)
return false;
- File *file = file_new(win->editor, filename);
+ File *file = file_new(win->editor, win->file->name);
if (!file)
return false;
file_free(win->editor, win->file);
win->file = file;
- view_reload(win->view, file->text);
+ win->ui->reload(win->ui, file);
return true;
}
@@ -241,7 +255,7 @@ static Win *window_new_file(Editor *ed, File *file) {
};
win->jumplist = ringbuf_alloc(31);
win->view = view_new(file->text, &win->events);
- win->ui = ed->ui->window_new(ed->ui, win->view, file->text);
+ win->ui = ed->ui->window_new(ed->ui, win->view, file);
if (!win->jumplist || !win->view || !win->ui) {
window_free(win);
return NULL;
@@ -263,6 +277,7 @@ static void file_free(Editor *ed, File *file) {
return;
text_free(file->text);
+ free((char*)file->name);
if (file->prev)
file->prev->next = file->next;
@@ -291,8 +306,7 @@ static File *file_new(Editor *ed, const char *filename) {
/* try to detect whether the same file is already open in another window
* TODO: do this based on inodes */
for (File *file = ed->files; file; file = file->next) {
- const char *name = text_filename_get(file->text);
- if (name && strcmp(name, filename) == 0) {
+ if (file->name && strcmp(file->name, filename) == 0) {
file->refcount++;
return file;
}
@@ -304,8 +318,6 @@ static File *file_new(Editor *ed, const char *filename) {
text = text_load(NULL);
if (!text)
return NULL;
- if (filename)
- text_filename_set(text, filename);
File *file = file_new_text(ed, text);
if (!file) {
@@ -313,6 +325,8 @@ static File *file_new(Editor *ed, const char *filename) {
return NULL;
}
+ if (filename)
+ file->name = strdup(filename);
return file;
}
@@ -326,15 +340,7 @@ bool editor_window_new(Editor *ed, const char *filename) {
return false;
}
- if (filename) {
- for (Syntax *syn = ed->syntaxes; syn && syn->name; syn++) {
- if (!regexec(&syn->file_regex, filename, 0, NULL, 0)) {
- view_syntax_set(win->view, syn);
- break;
- }
- }
- }
-
+ editor_window_name(win, filename);
editor_draw(ed);
return true;
@@ -392,7 +398,7 @@ Editor *editor_new(Ui *ui) {
goto err;
if (!(ed->prompt->view = view_new(ed->prompt->file->text, NULL)))
goto err;
- if (!(ed->prompt->ui = ed->ui->prompt_new(ed->ui, ed->prompt->view, ed->prompt->file->text)))
+ if (!(ed->prompt->ui = ed->ui->prompt_new(ed->ui, ed->prompt->view, ed->prompt->file)))
goto err;
if (!(ed->search_pattern = text_regex_new()))
goto err;
diff --git a/editor.h b/editor.h
index 3fd130a..5a288b6 100644
--- a/editor.h
+++ b/editor.h
@@ -7,6 +7,7 @@
#include <stdbool.h>
typedef struct Editor Editor;
+typedef struct File File;
typedef struct Win Win;
#include "ui.h"
@@ -17,8 +18,6 @@ typedef struct Win Win;
#include "ring-buffer.h"
#include "map.h"
-typedef struct File File;
-
typedef union {
bool b;
int i;
@@ -194,6 +193,7 @@ enum Mark {
struct File {
Text *text;
+ const char *name;
int refcount;
Mark marks[MARK_LAST];
File *next, *prev;
@@ -291,6 +291,8 @@ bool editor_window_split(Win*);
/* focus the next / previous window */
void editor_window_next(Editor*);
void editor_window_prev(Editor*);
+/* set the filename of the file displayed in this window */
+void editor_window_name(Win*, const char *filename);
void editor_window_jumplist_add(Win*, size_t pos);
size_t editor_window_jumplist_prev(Win*);
diff --git a/text.c b/text.c
index e013979..d131adc 100644
--- a/text.c
+++ b/text.c
@@ -131,7 +131,6 @@ struct Text {
Action *last_action; /* the last action added to the tree, chronologically */
Action *saved_action; /* the last action at the time of the save operation */
size_t size; /* current file content size in bytes */
- char *filename; /* filename of which data was loaded */
struct stat info; /* stat as proped on load time */
int fd; /* the file descriptor of the original mmap-ed data */
LineCache lines; /* mapping between absolute pos in bytes and logical line breaks */
@@ -960,8 +959,6 @@ bool text_range_save(Text *txt, Filerange *range, const char *filename) {
ok:
txt->saved_action = txt->history;
text_snapshot(txt);
- if (!txt->filename)
- text_filename_set(txt, filename);
return true;
err:
if (fd != -1)
@@ -1008,7 +1005,6 @@ Text *text_load(const char *filename) {
piece_init(&txt->end, &txt->begin, NULL, NULL, 0);
lineno_cache_invalidate(&txt->lines);
if (filename) {
- text_filename_set(txt, filename);
txt->fd = open(filename, O_RDONLY);
if (txt->fd == -1)
goto out;
@@ -1189,7 +1185,6 @@ void text_free(Text *txt) {
buffer_free(buf);
}
- free(txt->filename);
free(txt);
}
@@ -1475,15 +1470,6 @@ int text_fd_get(Text *txt) {
return txt->fd;
}
-const char *text_filename_get(Text *txt) {
- return txt->filename;
-}
-
-void text_filename_set(Text *txt, const char *filename) {
- free(txt->filename);
- txt->filename = filename ? strdup(filename) : NULL;
-}
-
Regex *text_regex_new(void) {
Regex *r = calloc(1, sizeof(Regex));
if (!r)
diff --git a/text.h b/text.h
index 9c2b09e..2c847d1 100644
--- a/text.h
+++ b/text.h
@@ -39,10 +39,6 @@ Text *text_load_fd(int fd);
/* return the fd from which this text was loaded or -1 if it was
* loaded from a filename */
int text_fd_get(Text*);
-/* the filename from which this text was loaded or first saved to */
-const char *text_filename_get(Text*);
-/* associate a filename with the yet unnamed buffer */
-void text_filename_set(Text*, const char *filename);
bool text_insert(Text*, size_t pos, const char *data, size_t len);
bool text_delete(Text*, size_t pos, size_t len);
void text_snapshot(Text*);
diff --git a/ui-curses.c b/ui-curses.c
index 5dfb299..619524b 100644
--- a/ui-curses.c
+++ b/ui-curses.c
@@ -65,7 +65,7 @@ typedef struct {
struct UiCursesWin {
UiWin uiwin; /* generic interface, has to be the first struct member */
UiCurses *ui; /* ui which manages this window */
- Text *text; /* underlying text management */
+ File *file; /* file being displayed in this window */
View *view; /* current viewport */
WINDOW *win; /* curses window for the text area */
WINDOW *winstatus; /* curses window for the status bar */
@@ -167,14 +167,14 @@ static void ui_window_draw_status(UiWin *w) {
UiCurses *uic = win->ui;
Editor *vis = uic->ed;
bool focused = uic->selwin == win;
- const char *filename = text_filename_get(win->text);
+ const char *filename = win->file->name;
CursorPos pos = view_cursor_getpos(win->view);
wattrset(win->winstatus, focused ? A_REVERSE|A_BOLD : A_REVERSE);
mvwhline(win->winstatus, 0, 0, ' ', win->width);
mvwprintw(win->winstatus, 0, 0, "%s %s %s %s",
vis->mode->name && vis->mode->name[0] == '-' ? vis->mode->name : "",
filename ? filename : "[No Name]",
- text_modified(win->text) ? "[+]" : "",
+ text_modified(win->file->text) ? "[+]" : "",
vis->recording ? "recording": "");
char buf[win->width + 1];
int len = snprintf(buf, win->width, "%zd, %zd", pos.line, pos.col);
@@ -192,10 +192,11 @@ static void ui_window_draw(UiWin *w) {
view_cursor_to(win->view, view_cursor_get(win->view));
}
-static void ui_window_reload(UiWin *w, Text *text) {
+static void ui_window_reload(UiWin *w, File *file) {
UiCursesWin *win = (UiCursesWin*)w;
- win->text = text;
+ win->file = file;
win->sidebar_width = 0;
+ view_reload(win->view, file->text);
ui_window_draw(w);
}
@@ -415,7 +416,7 @@ static void ui_window_options(UiWin *w, enum UiOption options) {
ui_window_draw(w);
}
-static UiWin *ui_window_new(Ui *ui, View *view, Text *text) {
+static UiWin *ui_window_new(Ui *ui, View *view, File *file) {
UiCurses *uic = (UiCurses*)ui;
UiCursesWin *win = calloc(1, sizeof(UiCursesWin));
if (!win)
@@ -437,7 +438,7 @@ static UiWin *ui_window_new(Ui *ui, View *view, Text *text) {
win->ui = uic;
win->view = view;
- win->text = text;
+ win->file = file;
view_ui(view, &win->uiwin);
if (uic->windows)
@@ -462,11 +463,11 @@ static void info_hide(Ui *ui) {
}
}
-static UiWin *prompt_new(Ui *ui, View *view, Text *text) {
+static UiWin *prompt_new(Ui *ui, View *view, File *file) {
UiCurses *uic = (UiCurses*)ui;
if (uic->prompt_win)
return (UiWin*)uic->prompt_win;
- UiWin *uiwin = ui_window_new(ui, view, text);
+ UiWin *uiwin = ui_window_new(ui, view, file);
UiCursesWin *win = (UiCursesWin*)uiwin;
if (!win)
return NULL;
@@ -483,24 +484,25 @@ static UiWin *prompt_new(Ui *ui, View *view, Text *text) {
return uiwin;
}
-static void prompt(Ui *ui, const char *title, const char *text) {
+static void prompt(Ui *ui, const char *title, const char *data) {
UiCurses *uic = (UiCurses*)ui;
if (uic->prompt_title[0])
return;
- size_t text_len = strlen(text);
+ size_t len = strlen(data);
+ Text *text = uic->prompt_win->file->text;
strncpy(uic->prompt_title, title, sizeof(uic->prompt_title)-1);
- while (text_undo(uic->prompt_win->text) != EPOS);
- text_insert(uic->prompt_win->text, 0, text, text_len);
+ while (text_undo(text) != EPOS);
+ text_insert(text, 0, data, len);
view_cursor_to(uic->prompt_win->view, 0);
ui_resize_to(ui, uic->width, uic->height);
- view_cursor_to(uic->prompt_win->view, text_len);
+ view_cursor_to(uic->prompt_win->view, len);
}
static char *prompt_input(Ui *ui) {
UiCurses *uic = (UiCurses*)ui;
if (!uic->prompt_win)
return NULL;
- Text *text = uic->prompt_win->text;
+ Text *text = uic->prompt_win->file->text;
char *buf = malloc(text_size(text) + 1);
if (!buf)
return NULL;
diff --git a/ui.h b/ui.h
index 7c3ec7e..732c618 100644
--- a/ui.h
+++ b/ui.h
@@ -26,10 +26,10 @@ struct Ui {
void (*free)(Ui*);
short (*color_get)(short fg, short bg);
void (*resize)(Ui*);
- UiWin* (*window_new)(Ui*, View*, Text*);
+ UiWin* (*window_new)(Ui*, View*, File*);
void (*window_free)(UiWin*);
void (*window_focus)(UiWin*);
- UiWin* (*prompt_new)(Ui*, View*, Text*);
+ UiWin* (*prompt_new)(Ui*, View*, File*);
void (*prompt)(Ui*, const char *title, const char *value);
char* (*prompt_input)(Ui*);
void (*prompt_hide)(Ui*);
@@ -51,7 +51,7 @@ struct UiWin {
void (*draw_text)(UiWin*, const Line*);
void (*draw_status)(UiWin*);
void (*cursor_to)(UiWin*, int x, int y);
- void (*reload)(UiWin*, Text*);
+ void (*reload)(UiWin*, File*);
void (*options)(UiWin*, enum UiOption);
};
diff --git a/view.c b/view.c
index c418a65..3a131f0 100644
--- a/view.c
+++ b/view.c
@@ -527,8 +527,6 @@ void view_reload(View *view, Text *text) {
view->text = text;
view_selection_clear(view);
view_cursor_to(view, 0);
- if (view->ui)
- view->ui->reload(view->ui, text);
}
View *view_new(Text *text, ViewEvent *events) {
diff --git a/vis.c b/vis.c
index e0ba9e6..aa40fee 100644
--- a/vis.c
+++ b/vis.c
@@ -1658,11 +1658,12 @@ static bool cmd_wq(Filerange *range, enum CmdOpt opt, const char *argv[]) {
}
static bool cmd_write(Filerange *range, enum CmdOpt opt, const char *argv[]) {
- Text *text = vis->win->file->text;
+ File *file = vis->win->file;
+ Text *text = file->text;
if (!text_range_valid(range))
*range = (Filerange){ .start = 0, .end = text_size(text) };
if (!argv[1])
- argv[1] = text_filename_get(text);
+ argv[1] = file->name;
if (!argv[1]) {
if (text_fd_get(text) == STDIN_FILENO) {
if (strchr(argv[0], 'q'))
@@ -1673,18 +1674,20 @@ static bool cmd_write(Filerange *range, enum CmdOpt opt, const char *argv[]) {
editor_info_show(vis, "Filename expected");
return false;
}
- for (const char **file = &argv[1]; *file; file++) {
- if (!text_range_save(text, range, *file)) {
- editor_info_show(vis, "Can't write `%s'", *file);
+ for (const char **name = &argv[1]; *name; name++) {
+ if (!text_range_save(text, range, *name)) {
+ editor_info_show(vis, "Can't write `%s'", *name);
return false;
}
+ if (!file->name)
+ editor_window_name(vis->win, *name);
}
return true;
}
static bool cmd_saveas(Filerange *range, enum CmdOpt opt, const char *argv[]) {
if (cmd_write(range, opt, argv)) {
- text_filename_set(vis->win->file->text, argv[1]);
+ editor_window_name(vis->win, argv[1]);
return true;
}
return false;