diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2015-04-05 10:10:47 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2015-04-05 19:58:45 +0200 |
| commit | 164527b74aa6cd04bd50c36399bc14ab90073bcf (patch) | |
| tree | 53d61af1dc32bb5bfaaa94d06c02bfd521df2de8 | |
| parent | 1304c0680b8db9d8526eb36f0b563d534703338b (diff) | |
| download | vis-164527b74aa6cd04bd50c36399bc14ab90073bcf.tar.gz vis-164527b74aa6cd04bd50c36399bc14ab90073bcf.tar.xz | |
Introduce new struct VisText
This adds yet another layer of indirection and stores vi related
stuff which is associated with a given text but shared among all
windows displaying it (e.g. marks).
This will also help if one wants to keep texts arround which
aren't currently displayed.
| -rw-r--r-- | config.def.h | 8 | ||||
| -rw-r--r-- | editor.c | 151 | ||||
| -rw-r--r-- | editor.h | 43 | ||||
| -rw-r--r-- | text.c | 24 | ||||
| -rw-r--r-- | text.h | 6 | ||||
| -rw-r--r-- | vis.c | 109 | ||||
| -rw-r--r-- | window.c | 7 |
7 files changed, 178 insertions, 170 deletions
diff --git a/config.def.h b/config.def.h index b8657a4..48feb08 100644 --- a/config.def.h +++ b/config.def.h @@ -457,7 +457,7 @@ static KeyBinding vis_mode_visual_line[] = { static void vis_mode_visual_line_enter(Mode *old) { Win *win = vis->win->win; - window_cursor_to(win, text_line_begin(vis->win->text, window_cursor_get(win))); + window_cursor_to(win, text_line_begin(vis->win->text->data, window_cursor_get(win))); if (!old->visual) { window_selection_start(vis->win->win); vis_modes[VIS_MODE_OPERATOR].parent = &vis_modes[VIS_MODE_TEXTOBJ]; @@ -559,11 +559,11 @@ static KeyBinding vis_mode_insert[] = { static void vis_mode_insert_leave(Mode *old) { /* make sure we can recover the current state after an editing operation */ - text_snapshot(vis->win->text); + text_snapshot(vis->win->text->data); } static void vis_mode_insert_idle(void) { - text_snapshot(vis->win->text); + text_snapshot(vis->win->text->data); } static void vis_mode_insert_input(const char *str, size_t len) { @@ -585,7 +585,7 @@ static KeyBinding vis_mode_replace[] = { static void vis_mode_replace_leave(Mode *old) { /* make sure we can recover the current state after an editing operation */ - text_snapshot(vis->win->text); + text_snapshot(vis->win->text->data); } static void vis_mode_replace_input(const char *str, size_t len) { @@ -5,7 +5,9 @@ #include "editor.h" #include "util.h" -static EditorWin *editor_window_new_text(Editor *ed, Text *text); +static void vis_text_free(Editor *ed, VisText *text); +static VisText *vis_text_new(Editor *ed, const char *filename); +static EditorWin *editor_window_new_text(Editor *ed, VisText *text); static void editor_window_free(EditorWin *win); static void editor_windows_invalidate(Editor *ed, size_t start, size_t end); @@ -14,25 +16,16 @@ void editor_windows_arrange(Editor *ed, enum UiLayout layout) { } bool editor_window_reload(EditorWin *win) { - const char *filename = text_filename_get(win->text); + const char *filename = text_filename_get(win->text->data); /* can't reload unsaved file */ if (!filename) return false; - Text *text = text_load(filename); + VisText *text = vis_text_new(win->editor, 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); + vis_text_free(win->editor, win->text); win->text = text; - window_reload(win->win, text); + window_reload(win->win, text->data); return true; } @@ -41,6 +34,7 @@ bool editor_window_split(EditorWin *original) { if (!win) return false; win->text = original->text; + win->text->refcount++; window_syntax_set(win->win, window_syntax_get(original->win)); window_cursor_to(win->win, window_cursor_get(original->win)); editor_draw(win->editor); @@ -48,7 +42,7 @@ bool editor_window_split(EditorWin *original) { } void editor_window_jumplist_add(EditorWin *win, size_t pos) { - Mark mark = text_mark_set(win->text, pos); + Mark mark = text_mark_set(win->text->data, pos); if (mark && win->jumplist) ringbuf_add(win->jumplist, mark); } @@ -59,7 +53,7 @@ size_t editor_window_jumplist_prev(EditorWin *win) { Mark mark = ringbuf_prev(win->jumplist); if (!mark) return cur; - size_t pos = text_mark_get(win->text, mark); + size_t pos = text_mark_get(win->text->data, mark); if (pos != EPOS && pos != cur) return pos; } @@ -72,7 +66,7 @@ size_t editor_window_jumplist_next(EditorWin *win) { Mark mark = ringbuf_next(win->jumplist); if (!mark) return cur; - size_t pos = text_mark_get(win->text, mark); + size_t pos = text_mark_get(win->text->data, mark); if (pos != EPOS && pos != cur) return pos; } @@ -90,7 +84,7 @@ size_t editor_window_changelist_prev(EditorWin *win) { win->changelist.index = 0; else win->changelist.index++; - size_t newpos = text_history_get(win->text, win->changelist.index); + size_t newpos = text_history_get(win->text->data, win->changelist.index); if (newpos == EPOS) win->changelist.index--; else @@ -104,7 +98,7 @@ size_t editor_window_changelist_next(EditorWin *win) { win->changelist.index = 0; else if (win->changelist.index > 0) win->changelist.index--; - size_t newpos = text_history_get(win->text, win->changelist.index); + size_t newpos = text_history_get(win->text->data, win->changelist.index); if (newpos == EPOS) win->changelist.index++; else @@ -221,26 +215,17 @@ static void editor_window_free(EditorWin *win) { if (ed && ed->ui) ed->ui->window_free(win->ui); ringbuf_free(win->jumplist); - bool needed = false; - for (EditorWin *w = ed ? ed->windows : NULL; w; w = w->next) { - if (w->text == win->text) { - needed = true; - break; - } - } - if (!needed) - text_free(win->text); free(win); } -static EditorWin *editor_window_new_text(Editor *ed, Text *text) { +static EditorWin *editor_window_new_text(Editor *ed, VisText *text) { EditorWin *win = calloc(1, sizeof(EditorWin)); if (!win) return NULL; win->editor = ed; win->text = text; win->jumplist = ringbuf_alloc(31); - win->ui = ed->ui->window_new(ed->ui, text); + win->ui = ed->ui->window_new(ed->ui, text->data); if (!win->jumplist || !win->ui) { editor_window_free(win); return NULL; @@ -250,47 +235,79 @@ static EditorWin *editor_window_new_text(Editor *ed, Text *text) { if (ed->windows) ed->windows->prev = win; win->next = ed->windows; - win->prev = NULL; ed->windows = win; ed->win = win; ed->ui->window_focus(win->ui); return win; } -bool editor_window_new(Editor *ed, const char *filename) { - 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; +static void vis_text_free(Editor *ed, VisText *text) { + if (!text) + return; + if (--text->refcount > 0) + return; + + text_free(text->data); + + if (text->prev) + text->prev->next = text->next; + if (text->next) + text->next->prev = text->prev; + if (ed->texts == text) + ed->texts = text->next; + free(text); +} + +static VisText *vis_text_new_text(Editor *ed, Text *data) { + VisText *text = calloc(1, sizeof(*text)); + if (!text) + return NULL; + text->data = data; + text->refcount++; + if (ed->texts) + ed->texts->prev = text; + text->next = ed->texts; + ed->texts = text; + return text; +} + +static VisText *vis_text_new(Editor *ed, const char *filename) { if (filename) { - for (EditorWin *win = ed->windows; win; win = win->next) { - const char *f = text_filename_get(win->text); + /* try to detect whether the same file is already open in another window + * TODO: do this based on inodes */ + for (VisText *txt = ed->texts; txt; txt = txt->next) { + const char *f = text_filename_get(txt->data); if (f && strcmp(f, filename) == 0) { - original = win; - break; + txt->refcount++; + return txt; } } } - if (original) - text = original->text; - else - text = text_load(filename && access(filename, F_OK) == 0 ? filename : NULL); + Text *data = text_load(filename && access(filename, F_OK) == 0 ? filename : NULL); + if (filename) + text_filename_set(data, filename); + + VisText *text = vis_text_new_text(ed, data); + if (!text) { + text_free(data); + return NULL; + } + + return text; +} + +bool editor_window_new(Editor *ed, const char *filename) { + VisText *text = vis_text_new(ed, filename); if (!text) return false; - EditorWin *win = editor_window_new_text(ed, text); if (!win) { - if (!original) - text_free(text); + vis_text_free(ed, text); return false; } - if (original) { - window_syntax_set(win->win, window_syntax_get(original->win)); - window_cursor_to(win->win, window_cursor_get(original->win)); - } else if (filename) { - text_filename_set(text, filename); + if (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); @@ -305,18 +322,25 @@ bool editor_window_new(Editor *ed, const char *filename) { } bool editor_window_new_fd(Editor *ed, int fd) { - Text *txt = text_load_fd(fd); - if (!txt) + Text *data = text_load_fd(fd); + if (!data) return false; - EditorWin *win = editor_window_new_text(ed, txt); - if (!win) + VisText *text = vis_text_new_text(ed, data); + if (!text) { + vis_text_free(ed, text); return false; - editor_draw(ed); + } + EditorWin *win = editor_window_new_text(ed, text); + if (!win) { + vis_text_free(ed, text); + return false; + } return true; } void editor_window_close(EditorWin *win) { Editor *ed = win->editor; + vis_text_free(ed, win->text); if (win->prev) win->prev->next = win->next; if (win->next) @@ -325,9 +349,9 @@ void editor_window_close(EditorWin *win) { ed->windows = win->next; if (ed->win == win) ed->win = win->next ? win->next : win->prev; + editor_window_free(win); if (ed->win) ed->ui->window_focus(ed->win->ui); - editor_window_free(win); editor_draw(ed); } @@ -343,9 +367,11 @@ Editor *editor_new(Ui *ui) { ed->expandtab = false; if (!(ed->prompt = calloc(1, sizeof(EditorWin)))) goto err; - if (!(ed->prompt->text = text_load(NULL))) + if (!(ed->prompt->text = calloc(1, sizeof(VisText)))) + goto err; + if (!(ed->prompt->text->data = text_load(NULL))) goto err; - if (!(ed->prompt->ui = ed->ui->prompt_new(ed->ui, ed->prompt->text))) + if (!(ed->prompt->ui = ed->ui->prompt_new(ed->ui, ed->prompt->text->data))) goto err; if (!(ed->search_pattern = text_regex_new())) goto err; @@ -361,6 +387,7 @@ void editor_free(Editor *ed) { return; while (ed->windows) editor_window_close(ed->windows); + vis_text_free(ed, ed->prompt->text); editor_window_free(ed->prompt); text_regex_free(ed->search_pattern); for (int i = 0; i < REG_LAST; i++) @@ -397,12 +424,12 @@ void editor_delete_key(Editor *ed) { } void editor_insert(Editor *ed, size_t pos, const char *c, size_t len) { - text_insert(ed->win->text, pos, c, len); + text_insert(ed->win->text->data, pos, c, len); editor_windows_invalidate(ed, pos, pos + len); } void editor_delete(Editor *ed, size_t pos, size_t len) { - text_delete(ed->win->text, pos, len); + text_delete(ed->win->text->data, pos, len); editor_windows_invalidate(ed, pos, pos + len); } @@ -15,22 +15,6 @@ typedef struct EditorWin EditorWin; #include "syntax.h" #include "ring-buffer.h" - -typedef struct { - size_t index; /* #number of changes */ - size_t pos; /* where the current change occured */ -} ChangeList; - -struct EditorWin { - Editor *editor; /* editor instance to which this window belongs */ - UiWin *ui; - Text *text; /* underlying text management */ - Win *win; /* window for the text area */ - RingBuffer *jumplist; /* LRU jump management */ - ChangeList changelist; /* state for iterating through least recently changes */ - EditorWin *prev, *next; /* neighbouring windows */ -}; - enum Reg { REG_a, REG_b, @@ -91,10 +75,37 @@ enum Mark { MARK_z, MARK_SELECTION_START, MARK_SELECTION_END, + MARK_LAST, +}; + + +typedef struct VisText VisText; + +struct VisText { + Text *data; + int refcount; + Mark marks[MARK_LAST]; + VisText *next, *prev; +}; + +typedef struct { + size_t index; /* #number of changes */ + size_t pos; /* where the current change occured */ +} ChangeList; + +struct EditorWin { + Editor *editor; /* editor instance to which this window belongs */ + UiWin *ui; + VisText *text; /* underlying text management */ + Win *win; /* window for the text area */ + RingBuffer *jumplist; /* LRU jump management */ + ChangeList changelist; /* state for iterating through least recently changes */ + EditorWin *prev, *next; /* neighbouring windows */ }; struct Editor { Ui *ui; + VisText *texts; EditorWin *windows; /* list of windows */ EditorWin *win; /* currently active window */ Syntax *syntaxes; /* NULL terminated array of syntax definitions */ @@ -118,7 +118,6 @@ struct Text { 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 */ - Mark marks[32]; /* a mark is a pointer into an underlying buffer */ int newlines; /* 0: unknown, 1: \n, -1: \r\n */ }; @@ -1159,29 +1158,6 @@ size_t text_mark_get(Text *txt, Mark mark) { return EPOS; } -void text_mark_intern_set(Text *txt, MarkIntern mark, size_t pos) { - if (mark < 0 || mark >= LENGTH(txt->marks)) - return; - txt->marks[mark] = text_mark_set(txt, pos); -} - -size_t text_mark_intern_get(Text *txt, MarkIntern mark) { - if (mark < 0 || mark >= LENGTH(txt->marks)) - return EPOS; - return text_mark_get(txt, txt->marks[mark]); -} - -void text_mark_intern_clear(Text *txt, MarkIntern mark) { - if (mark < 0 || mark >= LENGTH(txt->marks)) - return; - txt->marks[mark] = NULL; -} - -void text_mark_intern_clear_all(Text *txt) { - for (MarkIntern mark = 0; mark < LENGTH(txt->marks); mark++) - text_mark_intern_clear(txt, mark); -} - size_t text_history_get(Text *txt, size_t index) { for (Action *a = txt->current_action ? txt->current_action : txt->undo; a; a = a->next) { if (index-- == 0) { @@ -77,12 +77,6 @@ typedef const char* Mark; Mark text_mark_set(Text*, size_t pos); size_t text_mark_get(Text*, Mark); -typedef int MarkIntern; -void text_mark_intern_set(Text*, MarkIntern, size_t pos); -size_t text_mark_intern_get(Text*, MarkIntern); -void text_mark_intern_clear(Text*, MarkIntern); -void text_mark_intern_clear_all(Text*); - /* get position of change denoted by index, where 0 indicates the most recent */ size_t text_history_get(Text*, size_t index); @@ -127,7 +127,7 @@ typedef struct { /** collects all information until an operator is e const Movement *movement; const TextObject *textobj; Register *reg; - MarkIntern mark; + int mark; Key key; Arg arg; } Action; @@ -546,7 +546,7 @@ static bool exec_command(char type, const char *cmdline); static void op_delete(OperatorContext *c) { size_t len = c->range.end - c->range.start; c->reg->linewise = c->linewise; - register_put(c->reg, vis->win->text, &c->range); + register_put(c->reg, vis->win->text->data, &c->range); editor_delete(vis, c->range.start, len); window_cursor_to(vis->win->win, c->range.start); } @@ -558,11 +558,11 @@ static void op_change(OperatorContext *c) { static void op_yank(OperatorContext *c) { c->reg->linewise = c->linewise; - register_put(c->reg, vis->win->text, &c->range); + register_put(c->reg, vis->win->text->data, &c->range); } static void op_put(OperatorContext *c) { - Text *txt = vis->win->text; + Text *txt = vis->win->text->data; size_t pos = window_cursor_get(vis->win->win); if (c->arg->i > 0) { if (c->reg->linewise) @@ -591,7 +591,7 @@ static const char *expand_tab(void) { } static void op_shift_right(OperatorContext *c) { - Text *txt = vis->win->text; + Text *txt = vis->win->text->data; size_t pos = text_line_begin(txt, c->range.end), prev_pos; const char *tab = expand_tab(); size_t tablen = strlen(tab); @@ -610,7 +610,7 @@ static void op_shift_right(OperatorContext *c) { } static void op_shift_left(OperatorContext *c) { - Text *txt = vis->win->text; + Text *txt = vis->win->text->data; size_t pos = text_line_begin(txt, c->range.end), prev_pos; size_t tabwidth = editor_tabwidth_get(vis), tablen; @@ -642,7 +642,7 @@ static void op_case_change(OperatorContext *c) { char *buf = malloc(len); if (!buf) return; - len = text_bytes_get(vis->win->text, c->range.start, len, buf); + len = text_bytes_get(vis->win->text->data, c->range.start, len, buf); size_t rem = len; for (char *cur = buf; rem > 0; cur++, rem--) { int ch = (unsigned char)*cur; @@ -656,14 +656,14 @@ static void op_case_change(OperatorContext *c) { } } - text_delete(vis->win->text, c->range.start, len); - text_insert(vis->win->text, c->range.start, buf, len); + text_delete(vis->win->text->data, c->range.start, len); + text_insert(vis->win->text->data, c->range.start, buf, len); editor_draw(vis); free(buf); } static void op_join(OperatorContext *c) { - Text *txt = vis->win->text; + Text *txt = vis->win->text->data; size_t pos = text_line_begin(txt, c->range.end), prev_pos; Filerange sel = window_selection_get(vis->win->win); /* if a selection ends at the begin of a line, skip line break */ @@ -703,7 +703,7 @@ static void op_repeat_replace(OperatorContext *c) { chars++; } - Iterator it = text_iterator_get(vis->win->text, c->pos); + Iterator it = text_iterator_get(vis->win->text->data, c->pos); while (chars-- > 0) text_iterator_char_next(&it, NULL); editor_delete(vis, c->pos, it.pos - c->pos); @@ -713,14 +713,14 @@ static void op_repeat_replace(OperatorContext *c) { /** movement implementations of type: size_t (*move)(const Arg*) */ static char *get_word_under_cursor() { - Filerange word = text_object_word(vis->win->text, window_cursor_get(vis->win->win)); + Filerange word = text_object_word(vis->win->text->data, window_cursor_get(vis->win->win)); if (!text_range_valid(&word)) return NULL; size_t len = word.end - word.start; char *buf = malloc(len+1); if (!buf) return NULL; - len = text_bytes_get(vis->win->text, word.start, len, buf); + len = text_bytes_get(vis->win->text->data, word.start, len, buf); buf[len] = '\0'; return buf; } @@ -729,7 +729,7 @@ static size_t search_word_forward(const Arg *arg) { size_t pos = window_cursor_get(vis->win->win); char *word = get_word_under_cursor(); if (word && !text_regex_compile(vis->search_pattern, word, REG_EXTENDED)) - pos = text_search_forward(vis->win->text, pos, vis->search_pattern); + pos = text_search_forward(vis->win->text->data, pos, vis->search_pattern); free(word); return pos; } @@ -738,58 +738,59 @@ static size_t search_word_backward(const Arg *arg) { size_t pos = window_cursor_get(vis->win->win); char *word = get_word_under_cursor(); if (word && !text_regex_compile(vis->search_pattern, word, REG_EXTENDED)) - pos = text_search_backward(vis->win->text, pos, vis->search_pattern); + pos = text_search_backward(vis->win->text->data, pos, vis->search_pattern); free(word); return pos; } static size_t search_forward(const Arg *arg) { size_t pos = window_cursor_get(vis->win->win); - return text_search_forward(vis->win->text, pos, vis->search_pattern); + return text_search_forward(vis->win->text->data, pos, vis->search_pattern); } static size_t search_backward(const Arg *arg) { size_t pos = window_cursor_get(vis->win->win); - return text_search_backward(vis->win->text, pos, vis->search_pattern); + return text_search_backward(vis->win->text->data, pos, vis->search_pattern); } static void mark_set(const Arg *arg) { - text_mark_intern_set(vis->win->text, arg->i, window_cursor_get(vis->win->win)); + size_t pos = window_cursor_get(vis->win->win); + vis->win->text->marks[arg->i] = text_mark_set(vis->win->text->data, pos); } static size_t mark_goto(const Arg *arg) { - return text_mark_intern_get(vis->win->text, action.mark); + return text_mark_get(vis->win->text->data, vis->win->text->marks[action.mark]); } static size_t mark_line_goto(const Arg *arg) { - return text_line_start(vis->win->text, mark_goto(arg)); + return text_line_start(vis->win->text->data, mark_goto(arg)); } static size_t to(const Arg *arg) { - return text_find_char_next(vis->win->text, window_cursor_get(vis->win->win) + 1, + return text_find_char_next(vis->win->text->data, window_cursor_get(vis->win->win) + 1, action.key.str, strlen(action.key.str)); } static size_t till(const Arg *arg) { - return text_char_prev(vis->win->text, to(arg)); + return text_char_prev(vis->win->text->data, to(arg)); } static size_t to_left(const Arg *arg) { - return text_find_char_prev(vis->win->text, window_cursor_get(vis->win->win) - 1, + return text_find_char_prev(vis->win->text->data, window_cursor_get(vis->win->win) - 1, action.key.str, strlen(action.key.str)); } static size_t till_left(const Arg *arg) { - return text_char_next(vis->win->text, to_left(arg)); + return text_char_next(vis->win->text->data, to_left(arg)); } static size_t line(const Arg *arg) { - return text_pos_by_lineno(vis->win->text, action.count); + return text_pos_by_lineno(vis->win->text->data, action.count); } static size_t column(const Arg *arg) { size_t pos = window_cursor_get(vis->win->win); - return text_line_offset(vis->win->text, pos, action.count); + return text_line_offset(vis->win->text->data, pos, action.count); } static size_t window_lines_top(const Arg *arg) { @@ -881,7 +882,7 @@ static void replace(const Arg *arg) { buffer_put(&buffer_repeat, k.str, strlen(k.str)); editor_delete_key(vis); editor_insert_key(vis, k.str, strlen(k.str)); - text_snapshot(vis->win->text); + text_snapshot(vis->win->text->data); window_cursor_to(vis->win->win, pos); } @@ -969,10 +970,10 @@ static void selection_end(const Arg *arg) { size_t pos = window_cursor_get(vis->win->win); Filerange sel = window_selection_get(vis->win->win); if (pos == sel.start) { - pos = text_char_prev(vis->win->text, sel.end); + pos = text_char_prev(vis->win->text->data, sel.end); } else { pos = sel.start; - sel.start = text_char_prev(vis->win->text, sel.end); + sel.start = text_char_prev(vis->win->text->data, sel.end); sel.end = pos; } window_selection_set(vis->win->win, &sel); @@ -996,7 +997,7 @@ static void mark_line(const Arg *arg) { } static void undo(const Arg *arg) { - size_t pos = text_undo(vis->win->text); + size_t pos = text_undo(vis->win->text->data); if (pos != EPOS) { window_cursor_to(vis->win->win, pos); /* redraw all windows in case some display the same file */ @@ -1005,7 +1006,7 @@ static void undo(const Arg *arg) { } static void redo(const Arg *arg) { - size_t pos = text_redo(vis->win->text); + size_t pos = text_redo(vis->win->text->data); if (pos != EPOS) { window_cursor_to(vis->win->win, pos); /* redraw all windows in case some display the same file */ @@ -1166,10 +1167,10 @@ static void copy_indent_from_previous_line(Win *win, Text *text) { static void insert_newline(const Arg *arg) { insert(&(const Arg){ .s = - text_newlines_crnl(vis->win->text) ? "\r\n" : "\n" }); + text_newlines_crnl(vis->win->text->data) ? "\r\n" : "\n" }); if (vis->autoindent) - copy_indent_from_previous_line(vis->win->win, vis->win->text); + copy_indent_from_previous_line(vis->win->win, vis->win->text->data); } static void put(const Arg *arg) { @@ -1202,7 +1203,7 @@ static void switchmode(const Arg *arg) { /** action processing: execut the operator / movement / text object */ static void action_do(Action *a) { - Text *txt = vis->win->text; + Text *txt = vis->win->text->data; Win *win = vis->win->win; size_t pos = window_cursor_get(win); int count = MAX(1, a->count); @@ -1507,13 +1508,9 @@ static bool cmd_open(Filerange *range, enum CmdOpt opt, const char *argv[]) { } static bool is_window_closeable(EditorWin *win) { - if (!text_modified(win->text)) + if (!text_modified(win->text->data)) return true; - for (EditorWin *w = vis->windows; w; w = w->next) { - if (w != win && w->text == win->text) - return true; - } - return false; + return win->text->refcount > 1; } static void info_unsaved_changes(void) { @@ -1546,7 +1543,7 @@ static bool cmd_quit(Filerange *range, enum CmdOpt opt, const char *argv[]) { } static bool cmd_xit(Filerange *range, enum CmdOpt opt, const char *argv[]) { - if (text_modified(vis->win->text) && !cmd_write(range, opt, argv)) { + if (text_modified(vis->win->text->data) && !cmd_write(range, opt, argv)) { if (!(opt & CMD_OPT_FORCE)) return false; } @@ -1554,14 +1551,14 @@ static bool cmd_xit(Filerange *range, enum CmdOpt opt, const char *argv[]) { } static bool cmd_bdelete(Filerange *range, enum CmdOpt opt, const char *argv[]) { - Text *txt = vis->win->text; + Text *txt = vis->win->text->data; if (text_modified(txt) && !(opt & CMD_OPT_FORCE)) { info_unsaved_changes(); return false; } for (EditorWin *next, *win = vis->windows; win; win = next) { next = win->next; - if (win->text == txt) + if (win->text->data == txt) editor_window_close(win); } if (!vis->windows) @@ -1572,7 +1569,7 @@ static bool cmd_bdelete(Filerange *range, enum CmdOpt opt, const char *argv[]) { static bool cmd_qall(Filerange *range, enum CmdOpt opt, const char *argv[]) { for (EditorWin *next, *win = vis->windows; win; win = next) { next = win->next; - if (!text_modified(vis->win->text) || (opt & CMD_OPT_FORCE)) + if (!text_modified(vis->win->text->data) || (opt & CMD_OPT_FORCE)) editor_window_close(win); } if (!vis->windows) @@ -1599,7 +1596,7 @@ static bool cmd_read(Filerange *range, enum CmdOpt opt, const char *argv[]) { if (data == MAP_FAILED) goto err; - text_insert(vis->win->text, pos, data, info.st_size); + text_insert(vis->win->text->data, pos, data, info.st_size); pos += info.st_size; err: if (fd != -1) @@ -1659,7 +1656,7 @@ 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->text; + Text *text = vis->win->text->data; if (!argv[1]) argv[1] = text_filename_get(text); if (!argv[1]) { @@ -1683,7 +1680,7 @@ static bool cmd_write(Filerange *range, enum CmdOpt opt, const char *argv[]) { static bool cmd_saveas(Filerange *range, enum CmdOpt opt, const char *argv[]) { if (cmd_write(range, opt, argv)) { - text_filename_set(vis->win->text, argv[1]); + text_filename_set(vis->win->text->data, argv[1]); return true; } return false; @@ -1691,8 +1688,9 @@ static bool cmd_saveas(Filerange *range, enum CmdOpt opt, const char *argv[]) { static Filepos parse_pos(char **cmd) { size_t pos = EPOS; - Text *txt = vis->win->text; Win *win = vis->win->win; + Text *txt = vis->win->text->data; + Mark *marks = vis->win->text->marks; switch (**cmd) { case '.': pos = text_line_begin(txt, window_cursor_get(win)); @@ -1705,11 +1703,11 @@ static Filepos parse_pos(char **cmd) { case '\'': (*cmd)++; if ('a' <= **cmd && **cmd <= 'z') - pos = text_mark_intern_get(txt, **cmd - 'a'); + pos = text_mark_get(txt, marks[**cmd - 'a']); else if (**cmd == '<') - pos = text_mark_intern_get(txt, MARK_SELECTION_START); + pos = text_mark_get(txt, marks[MARK_SELECTION_START]); else if (**cmd == '>') - pos = text_mark_intern_get(txt, MARK_SELECTION_END); + pos = text_mark_get(txt, marks[MARK_SELECTION_END]); (*cmd)++; break; case '/': @@ -1747,8 +1745,9 @@ static Filepos parse_pos(char **cmd) { } static Filerange parse_range(char **cmd) { - Text *txt = vis->win->text; + Text *txt = vis->win->text->data; Filerange r = text_range_empty(); + Mark *marks = vis->win->text->marks; switch (**cmd) { case '%': r.start = 0; @@ -1756,8 +1755,8 @@ static Filerange parse_range(char **cmd) { (*cmd)++; break; case '*': - r.start = text_mark_intern_get(txt, MARK_SELECTION_START); - r.end = text_mark_intern_get(txt, MARK_SELECTION_END); + r.start = text_mark_get(txt, marks[MARK_SELECTION_START]); + r.end = text_mark_get(txt, marks[MARK_SELECTION_END]); (*cmd)++; break; default: @@ -1791,7 +1790,7 @@ static bool exec_cmdline_command(const char *cmdline) { free(line); return false; } - range = (Filerange){ .start = 0, .end = text_size(vis->win->text) }; + range = (Filerange){ .start = 0, .end = text_size(vis->win->text->data) }; } /* skip leading white space */ while (*name == ' ') @@ -115,8 +115,9 @@ Filerange window_selection_get(Win *win) { if (!text_range_valid(&sel)) return text_range_empty(); sel.end = text_char_next(win->text, sel.end); - text_mark_intern_set(win->text, MARK_SELECTION_START, sel.start); - text_mark_intern_set(win->text, MARK_SELECTION_END, sel.end); + // TODO + //text_mark_intern_set(win->text, MARK_SELECTION_START, sel.start); + //text_mark_intern_set(win->text, MARK_SELECTION_END, sel.end); return sel; } @@ -439,7 +440,7 @@ void window_draw(Win *win) { bool window_resize(Win *win, int width, int height) { size_t lines_size = height*(sizeof(Line) + width*sizeof(Cell)); if (lines_size > win->lines_size) { - Line *lines = malloc(lines_size); + Line *lines = realloc(win->lines, lines_size); if (!lines) return false; win->lines = lines; |
