From 515c3e272950e88be6e6d24b147d3f82ffb2d99a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Tue, 7 Apr 2015 13:05:18 +0200 Subject: Set '< and '> marks --- editor.c | 25 ++++++++++++++++++++----- editor.h | 1 + ui-curses.c | 28 ++++++++++------------------ ui.h | 5 ++--- window.c | 28 +++++++++++++++++----------- window.h | 8 +++++++- 6 files changed, 57 insertions(+), 38 deletions(-) diff --git a/editor.c b/editor.c index 93f347f..4b9b47e 100644 --- a/editor.c +++ b/editor.c @@ -11,6 +11,15 @@ 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); + +static void editor_window_selection_changed(void *data, Filerange *sel) { + VisText *text = ((EditorWin*)data)->text; + if (text_range_valid(sel)) { + text->marks[MARK_SELECTION_START] = text_mark_set(text->data, sel->start); + text->marks[MARK_SELECTION_END] = text_mark_set(text->data, sel->end); + } +} + void editor_windows_arrange(Editor *ed, enum UiLayout layout) { ed->ui->arrange(ed->ui, layout); } @@ -214,6 +223,7 @@ static void editor_window_free(EditorWin *win) { Editor *ed = win->editor; if (ed && ed->ui) ed->ui->window_free(win->ui); + window_free(win->win); ringbuf_free(win->jumplist); free(win); } @@ -224,13 +234,17 @@ static EditorWin *editor_window_new_text(Editor *ed, VisText *text) { return NULL; win->editor = ed; win->text = text; + win->events = (ViewEvent) { + .data = win, + .selection = editor_window_selection_changed, + }; win->jumplist = ringbuf_alloc(31); - win->ui = ed->ui->window_new(ed->ui, text->data); - if (!win->jumplist || !win->ui) { + win->win = window_new(text->data, &win->events); + win->ui = ed->ui->window_new(ed->ui, win->win, text->data); + if (!win->jumplist || !win->win || !win->ui) { editor_window_free(win); return NULL; } - win->win = win->ui->view_get(win->ui); window_tabwidth_set(win->win, ed->tabwidth); if (ed->windows) ed->windows->prev = win; @@ -371,11 +385,12 @@ Editor *editor_new(Ui *ui) { 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->data))) + if (!(ed->prompt->win = window_new(ed->prompt->text->data, NULL))) + goto err; + if (!(ed->prompt->ui = ed->ui->prompt_new(ed->ui, ed->prompt->win, ed->prompt->text->data))) goto err; if (!(ed->search_pattern = text_regex_new())) goto err; - ed->prompt->win = ed->prompt->ui->view_get(ed->prompt->ui); return ed; err: editor_free(ed); diff --git a/editor.h b/editor.h index c78a5ee..b83fd13 100644 --- a/editor.h +++ b/editor.h @@ -98,6 +98,7 @@ struct EditorWin { UiWin *ui; VisText *text; /* underlying text management */ Win *win; /* window for the text area */ + ViewEvent events; RingBuffer *jumplist; /* LRU jump management */ ChangeList changelist; /* state for iterating through least recently changes */ EditorWin *prev, *next; /* neighbouring windows */ diff --git a/ui-curses.c b/ui-curses.c index ec92173..6012dc1 100644 --- a/ui-curses.c +++ b/ui-curses.c @@ -341,15 +341,9 @@ static void ui_window_free(UiWin *w) { delwin(win->winside); if (win->win) delwin(win->win); - window_free(win->view); free(win); } -static Win *ui_window_view_get(UiWin *win) { - UiCursesWin *cwin = (UiCursesWin*)win; - return cwin->view; -} - static void ui_window_cursor_to(UiWin *w, int x, int y) { UiCursesWin *win = (UiCursesWin*)w; wmove(win->win, y, x); @@ -409,7 +403,7 @@ static void ui_window_options(UiWin *w, enum UiOption options) { ui_window_draw(w); } -static UiWin *ui_window_new(Ui *ui, Text *text) { +static UiWin *ui_window_new(Ui *ui, Win *view, Text *text) { UiCurses *uic = (UiCurses*)ui; UiCursesWin *win = calloc(1, sizeof(UiCursesWin)); if (!win) @@ -420,20 +414,20 @@ static UiWin *ui_window_new(Ui *ui, Text *text) { .draw_status = ui_window_draw_status, .draw_text = ui_window_draw_text, .cursor_to = ui_window_cursor_to, - .view_get = ui_window_view_get, .options = ui_window_options, .reload = ui_window_reload, }; - if (!(win->view = window_new(text, &win->uiwin, uic->width, uic->height)) || - !(win->win = newwin(0, 0, 0, 0)) || - !(win->winstatus = newwin(1, 0, 0, 0))) { + if (!(win->win = newwin(0, 0, 0, 0)) || !(win->winstatus = newwin(1, 0, 0, 0))) { ui_window_free((UiWin*)win); return NULL; } win->ui = uic; + win->view = view; win->text = text; + window_ui(view, &win->uiwin); + if (uic->windows) uic->windows->prev = win; win->next = uic->windows; @@ -456,11 +450,11 @@ static void info_hide(Ui *ui) { } } -static UiWin *prompt_new(Ui *ui, Text *text) { +static UiWin *prompt_new(Ui *ui, Win *view, Text *text) { UiCurses *uic = (UiCurses*)ui; if (uic->prompt_win) return (UiWin*)uic->prompt_win; - UiWin *uiwin = ui_window_new(ui, text); + UiWin *uiwin = ui_window_new(ui, view, text); UiCursesWin *win = (UiCursesWin*)uiwin; if (!win) return NULL; @@ -483,9 +477,11 @@ static void prompt(Ui *ui, const char *title, const char *text) { return; size_t text_len = strlen(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); - window_cursor_to(uic->prompt_win->view, text_len); + window_cursor_to(uic->prompt_win->view, 0); ui_resize_to(ui, uic->width, uic->height); + window_cursor_to(uic->prompt_win->view, text_len); } static char *prompt_input(Ui *ui) { @@ -504,10 +500,6 @@ static char *prompt_input(Ui *ui) { static void prompt_hide(Ui *ui) { UiCurses *uic = (UiCurses*)ui; uic->prompt_title[0] = '\0'; - if (uic->prompt_win) { - while (text_undo(uic->prompt_win->text) != EPOS); - window_cursor_to(uic->prompt_win->view, 0); - } ui_resize_to(ui, uic->width, uic->height); } diff --git a/ui.h b/ui.h index 62a79dd..073bd09 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*, Text*); + UiWin* (*window_new)(Ui*, Win*, Text*); void (*window_free)(UiWin*); void (*window_focus)(UiWin*); - UiWin* (*prompt_new)(Ui*, Text*); + UiWin* (*prompt_new)(Ui*, Win*, Text*); void (*prompt)(Ui*, const char *title, const char *value); char* (*prompt_input)(Ui*); void (*prompt_hide)(Ui*); @@ -53,7 +53,6 @@ struct UiWin { void (*cursor_to)(UiWin*, int x, int y); void (*reload)(UiWin*, Text*); void (*options)(UiWin*, enum UiOption); - Win* (*view_get)(UiWin*); }; #endif diff --git a/window.c b/window.c index 9784b22..dbe4bed 100644 --- a/window.c +++ b/window.c @@ -35,6 +35,7 @@ typedef struct { /* cursor position */ struct Win { /* window showing part of a file */ Text *text; /* underlying text management */ UiWin *ui; + ViewEvent *events; int width, height; /* window text area size */ Filepos start, end; /* currently displayed area [start, end] in bytes from the start of the file */ size_t lines_size; /* number of allocated bytes for lines (grows only) */ @@ -115,9 +116,6 @@ Filerange window_selection_get(Win *win) { if (!text_range_valid(&sel)) return text_range_empty(); sel.end = text_char_next(win->text, 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; } @@ -241,7 +239,8 @@ static size_t window_cursor_update(Win *win) { win->sel.end = cursor->pos; window_draw(win); } - win->ui->cursor_to(win->ui, cursor->col, cursor->row); + if (win->ui) + win->ui->cursor_to(win->ui, cursor->col, cursor->row); return cursor->pos; } @@ -434,7 +433,10 @@ void window_draw(Win *win) { win->lastline = win->line ? win->line : win->bottomline; win->lastline->next = NULL; window_cursor_sync(win); - win->ui->draw_text(win->ui, win->topline); + if (win->ui) + win->ui->draw_text(win->ui, win->topline); + if (sel.start != EPOS && win->events && win->events->selection) + win->events->selection(win->events->data, &sel); } bool window_resize(Win *win, int width, int height) { @@ -469,20 +471,21 @@ void window_reload(Win *win, Text *text) { win->text = text; window_selection_clear(win); window_cursor_to(win, 0); - win->ui->reload(win->ui, text); + if (win->ui) + win->ui->reload(win->ui, text); } -Win *window_new(Text *text, UiWin *ui, int width, int height) { - if (!text || !ui) +Win *window_new(Text *text, ViewEvent *events) { + if (!text) return NULL; Win *win = calloc(1, sizeof(Win)); if (!win) return NULL; - win->text = text; - win->ui = ui; + win->events = events; win->tabwidth = 8; - if (!window_resize(win, width, height)) { + + if (!window_resize(win, 1, 1)) { window_free(win); return NULL; } @@ -492,6 +495,9 @@ Win *window_new(Text *text, UiWin *ui, int width, int height) { return win; } +void window_ui(Win *win, UiWin* ui) { + win->ui = ui; +} size_t window_char_prev(Win *win) { Cursor *cursor = &win->cursor; Line *line = cursor->line; diff --git a/window.h b/window.h index 5c8cf18..e1e2080 100644 --- a/window.h +++ b/window.h @@ -9,6 +9,11 @@ typedef struct Win Win; +typedef struct { + void *data; + void (*selection)(void *data, Filerange*); +} ViewEvent; + typedef struct { int width; /* display width i.e. number of columns ocupied by this character */ size_t len; /* number of bytes the character displayed in this cell uses, for @@ -35,7 +40,8 @@ typedef struct { size_t col; } CursorPos; -Win *window_new(Text*, UiWin*, int width, int height); +Win *window_new(Text*, ViewEvent*); +void window_ui(Win*, UiWin*); /* change associated text displayed in this window */ void window_reload(Win*, Text*); void window_free(Win*); -- cgit v1.2.3