aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editor.c25
-rw-r--r--editor.h1
-rw-r--r--ui-curses.c28
-rw-r--r--ui.h5
-rw-r--r--window.c28
-rw-r--r--window.h8
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
@@ -10,6 +10,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
character which use more than 1 column to display, their lenght
@@ -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*);