diff options
| -rw-r--r-- | editor.c | 44 | ||||
| -rw-r--r-- | editor.h | 6 | ||||
| -rw-r--r-- | text.c | 14 | ||||
| -rw-r--r-- | text.h | 4 | ||||
| -rw-r--r-- | ui-curses.c | 32 | ||||
| -rw-r--r-- | ui.h | 6 | ||||
| -rw-r--r-- | view.c | 2 | ||||
| -rw-r--r-- | vis.c | 15 |
8 files changed, 58 insertions, 65 deletions
@@ -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; @@ -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*); @@ -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) @@ -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; @@ -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); }; @@ -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) { @@ -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; |
