diff options
Diffstat (limited to 'editor.c')
| -rw-r--r-- | editor.c | 388 |
1 files changed, 59 insertions, 329 deletions
@@ -5,91 +5,12 @@ #include "editor.h" #include "util.h" -#ifdef NCURSES_VERSION -# ifndef NCURSES_EXT_COLORS -# define NCURSES_EXT_COLORS 0 -# endif -# if !NCURSES_EXT_COLORS -# define MAX_COLOR_PAIRS 256 -# endif -#endif -#ifndef MAX_COLOR_PAIRS -# define MAX_COLOR_PAIRS COLOR_PAIRS -#endif - static EditorWin *editor_window_new_text(Editor *ed, Text *text); -static void editor_window_free(Editor *ed, EditorWin *win); +static void editor_window_free(EditorWin *win); static void editor_windows_invalidate(Editor *ed, size_t start, size_t end); -static void editor_window_draw(EditorWin *win); -static void windows_arrange_horizontal(Editor *ed); -static void windows_arrange_vertical(Editor *ed); - -static Prompt *editor_prompt_new(); -static void editor_prompt_free(Prompt *prompt); -static void editor_prompt_clear(Prompt *prompt); -static void editor_prompt_resize(Prompt *prompt, int width, int height); -static void editor_prompt_move(Prompt *prompt, int x, int y); -static void editor_prompt_draw(Prompt *prompt); -static void editor_prompt_update(Prompt *prompt); -static void editor_info_draw(Editor *ed); - -static void editor_window_resize(EditorWin *win, int width, int height) { - window_resize(win->win, width, win->statuswin ? height - 1 : height); - if (win->statuswin) - wresize(win->statuswin, 1, width); - win->width = width; - win->height = height; -} - -static void editor_window_move(EditorWin *win, int x, int y) { - window_move(win->win, x, y); - if (win->statuswin) - mvwin(win->statuswin, y + win->height - 1, x); -} - -static void editor_window_statusbar_draw(EditorWin *win) { - if (win->statuswin && win->editor->statusbar) - win->editor->statusbar(win); -} - -static void editor_window_cursor_moved(Win *winwin, void *data) { - EditorWin *win = data; - Filerange sel = window_selection_get(winwin); - if (text_range_valid(&sel) && sel.start != sel.end) { - text_mark_intern_set(win->text, MARK_SELECTION_START, sel.start); - text_mark_intern_set(win->text, MARK_SELECTION_END, sel.end); - } - editor_window_statusbar_draw(win); -} -void editor_statusbar_set(Editor *ed, void (*statusbar)(EditorWin*)) { - ed->statusbar = statusbar; -} - -static void windows_arrange_horizontal(Editor *ed) { - int n = 0, x = 0, y = 0; - for (EditorWin *win = ed->windows; win; win = win->next) - n++; - int height = ed->height / MAX(1, n); - for (EditorWin *win = ed->windows; win; win = win->next) { - editor_window_resize(win, ed->width, win->next ? height : ed->height - y); - editor_window_move(win, x, y); - y += height; - } -} - -static void windows_arrange_vertical(Editor *ed) { - int n = 0, x = 0, y = 0; - for (EditorWin *win = ed->windows; win; win = win->next) - n++; - int width = (ed->width / MAX(1, n)) - 1; - for (EditorWin *win = ed->windows; win; win = win->next) { - editor_window_resize(win, win->next ? width : ed->width - x, ed->height); - editor_window_move(win, x, y); - x += width; - if (win->next) - mvvline(0, x++, ACS_VLINE, ed->height); - } +void editor_windows_arrange(Editor *ed, enum UiLayout layout) { + ed->ui->arrange(ed->ui, layout); } bool editor_window_reload(EditorWin *win) { @@ -115,16 +36,6 @@ bool editor_window_reload(EditorWin *win) { return true; } -void editor_windows_arrange_vertical(Editor *ed) { - ed->windows_arrange = windows_arrange_vertical; - editor_draw(ed); -} - -void editor_windows_arrange_horizontal(Editor *ed) { - ed->windows_arrange = windows_arrange_horizontal; - editor_draw(ed); -} - bool editor_window_split(EditorWin *original) { EditorWin *win = editor_window_new_text(original->editor, original->text); if (!win) @@ -201,18 +112,8 @@ size_t editor_window_changelist_next(EditorWin *win) { return win->changelist.pos; } -void editor_resize(Editor *ed, int width, int height) { - ed->width = width; - ed->height = height; - if (ed->info[0]) { - ed->height--; - } else if (ed->prompt->active) { - ed->height--; - editor_prompt_resize(ed->prompt, ed->width, 1); - editor_prompt_move(ed->prompt, 0, ed->height); - editor_prompt_draw(ed->prompt); - } - editor_draw(ed); +void editor_resize(Editor *ed) { + ed->ui->resize(ed->ui); } void editor_window_next(Editor *ed) { @@ -222,8 +123,7 @@ void editor_window_next(Editor *ed) { ed->win = ed->win->next; if (!ed->win) ed->win = ed->windows; - editor_window_statusbar_draw(sel); - editor_window_statusbar_draw(ed->win); + ed->ui->window_focus(ed->win->ui); } void editor_window_prev(Editor *ed) { @@ -233,8 +133,7 @@ void editor_window_prev(Editor *ed) { ed->win = ed->win->prev; if (!ed->win) for (ed->win = ed->windows; ed->win->next; ed->win = ed->win->next); - editor_window_statusbar_draw(sel); - editor_window_statusbar_draw(ed->win); + ed->ui->window_focus(ed->win->ui); } static void editor_windows_invalidate(Editor *ed, size_t start, size_t end) { @@ -243,10 +142,10 @@ static void editor_windows_invalidate(Editor *ed, size_t start, size_t end) { Filerange view = window_viewport_get(win->win); if ((view.start <= start && start <= view.end) || (view.start <= end && end <= view.end)) - editor_window_draw(win); + win->ui->draw(win->ui); } } - editor_window_draw(ed->win); + ed->win->ui->draw(ed->win->ui); } int editor_tabwidth_get(Editor *ed) { @@ -268,7 +167,7 @@ bool editor_syntax_load(Editor *ed, Syntax *syntaxes, Color *colors) { for (Color *color = colors; color && color->fg; color++) { if (color->attr == 0) color->attr = A_NORMAL; - color->attr |= COLOR_PAIR(editor_color_get(color->fg, color->bg)); + color->attr |= COLOR_PAIR(ed->ui->color_get(color->fg, color->bg)); } for (Syntax *syn = syntaxes; syn && syn->name; syn++) { @@ -303,49 +202,24 @@ void editor_syntax_unload(Editor *ed) { ed->syntaxes = NULL; } -static void editor_window_draw(EditorWin *win) { - // TODO window_draw draw should restore cursor position - window_draw(win->win); - window_cursor_to(win->win, window_cursor_get(win->win)); -} - void editor_draw(Editor *ed) { - erase(); - if (ed->windows) { - ed->windows_arrange(ed); - for (EditorWin *win = ed->windows; win; win = win->next) { - if (ed->win != win) - editor_window_draw(win); - } - editor_window_draw(ed->win); - } - if (ed->info[0]) - editor_info_draw(ed); - wnoutrefresh(stdscr); + ed->ui->draw(ed->ui); } void editor_update(Editor *ed) { - for (EditorWin *win = ed->windows; win; win = win->next) { - if (ed->win != win) { - if (win->statuswin) - wnoutrefresh(win->statuswin); - window_update(win->win); - } - } + ed->ui->update(ed->ui); +} - if (ed->win->statuswin) - wnoutrefresh(ed->win->statuswin); - if (ed->prompt && ed->prompt->active) - editor_prompt_update(ed->prompt); - window_update(ed->win->win); +void editor_suspend(Editor *ed) { + ed->ui->suspend(ed->ui); } -static void editor_window_free(Editor *ed, EditorWin *win) { +static void editor_window_free(EditorWin *win) { if (!win) return; - window_free(win->win); - if (win->statuswin) - delwin(win->statuswin); + Editor *ed = win->editor; + 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) { @@ -365,14 +239,13 @@ static EditorWin *editor_window_new_text(Editor *ed, Text *text) { return NULL; win->editor = ed; win->text = text; - win->win = window_new(win->text); - win->statuswin = newwin(1, ed->width, 0, 0); win->jumplist = ringbuf_alloc(31); - if (!win->win || !win->statuswin) { - editor_window_free(ed, win); + win->ui = ed->ui->window_new(ed->ui, text); + if (!win->jumplist || !win->ui) { + editor_window_free(win); return NULL; } - window_cursor_watch(win->win, editor_window_cursor_moved, win); + win->win = win->ui->view_get(win->ui); window_tabwidth_set(win->win, ed->tabwidth); if (ed->windows) ed->windows->prev = win; @@ -380,6 +253,7 @@ static EditorWin *editor_window_new_text(Editor *ed, Text *text) { win->prev = NULL; ed->windows = win; ed->win = win; + ed->ui->window_focus(win->ui); return win; } @@ -441,38 +315,41 @@ bool editor_window_new_fd(Editor *ed, int fd) { return true; } -static void editor_window_detach(Editor *ed, EditorWin *win) { +void editor_window_close(EditorWin *win) { + Editor *ed = win->editor; if (win->prev) win->prev->next = win->next; if (win->next) win->next->prev = win->prev; if (ed->windows == win) ed->windows = win->next; - win->next = win->prev = NULL; -} - -void editor_window_close(EditorWin *win) { - Editor *ed = win->editor; if (ed->win == win) ed->win = win->next ? win->next : win->prev; - editor_window_detach(ed, win); - editor_window_free(ed, win); + if (ed->win) + ed->ui->window_focus(ed->win->ui); + editor_window_free(win); editor_draw(ed); } -Editor *editor_new(int width, int height) { +Editor *editor_new(Ui *ui) { + if (!ui) + return NULL; Editor *ed = calloc(1, sizeof(Editor)); if (!ed) return NULL; - if (!(ed->prompt = editor_prompt_new())) + ed->ui = ui; + ed->ui->init(ed->ui, ed); + ed->tabwidth = 8; + ed->expandtab = false; + if (!(ed->prompt = calloc(1, sizeof(EditorWin)))) + goto err; + if (!(ed->prompt->text = text_load(NULL))) + goto err; + if (!(ed->prompt->ui = ed->ui->prompt_new(ed->ui, ed->prompt->text))) goto err; if (!(ed->search_pattern = text_regex_new())) goto err; - ed->width = width; - ed->height = height; - ed->tabwidth = 8; - ed->expandtab = false; - ed->windows_arrange = windows_arrange_horizontal; + ed->prompt->win = ed->prompt->ui->view_get(ed->prompt->ui); return ed; err: editor_free(ed); @@ -484,11 +361,12 @@ void editor_free(Editor *ed) { return; while (ed->windows) editor_window_close(ed->windows); - editor_prompt_free(ed->prompt); + editor_window_free(ed->prompt); text_regex_free(ed->search_pattern); for (int i = 0; i < REG_LAST; i++) register_free(&ed->registers[i]); editor_syntax_unload(ed); + ed->ui->free(ed->ui); free(ed); } @@ -528,187 +406,39 @@ void editor_delete(Editor *ed, size_t pos, size_t len) { editor_windows_invalidate(ed, pos, pos + len); } -static void editor_prompt_free(Prompt *prompt) { - if (!prompt) - return; - editor_window_free(NULL, prompt->win); - if (prompt->titlewin) - delwin(prompt->titlewin); - free(prompt->title); - free(prompt); -} - -static Prompt *editor_prompt_new() { - Text *text = text_load(NULL); - if (!text) - return NULL; - Prompt *prompt = calloc(1, sizeof(Prompt)); - if (!prompt) - goto err; - - if (!(prompt->win = calloc(1, sizeof(EditorWin)))) - goto err; - - if (!(prompt->win->win = window_new(text))) - goto err; - - prompt->win->text = text; - - if (!(prompt->titlewin = newwin(0, 0, 0, 0))) - goto err; - - return prompt; -err: - if (!prompt || !prompt->win) - text_free(text); - editor_prompt_free(prompt); - return NULL; -} - -static void editor_prompt_resize(Prompt *prompt, int width, int height) { - size_t title_width = strlen(prompt->title); - wresize(prompt->titlewin, height, title_width); - editor_window_resize(prompt->win, width - title_width, height); -} - -static void editor_prompt_move(Prompt *prompt, int x, int y) { - size_t title_width = strlen(prompt->title); - mvwin(prompt->titlewin, y, x); - editor_window_move(prompt->win, x + title_width, y); -} - void editor_prompt_show(Editor *ed, const char *title, const char *text) { - Prompt *prompt = ed->prompt; - if (prompt->active) + if (ed->prompt_window) return; - prompt->active = true; - prompt->editor = ed->win; - free(prompt->title); - prompt->title = strdup(title); - text_insert(prompt->win->text, 0, text, strlen(text)); - window_cursor_to(prompt->win->win, text_size(prompt->win->text)); - ed->win = prompt->win; - editor_resize(ed, ed->width, ed->height); -} - -static void editor_prompt_draw(Prompt *prompt) { - mvwaddstr(prompt->titlewin, 0, 0, prompt->title); -} - -static void editor_prompt_update(Prompt *prompt) { - wnoutrefresh(prompt->titlewin); -} - -static void editor_prompt_clear(Prompt *prompt) { - Text *text = prompt->win->text; - while (text_undo(text) != EPOS); - window_cursor_to(prompt->win->win, 0); + ed->prompt_window = ed->win; + ed->win = ed->prompt; + ed->prompt_type = title[0]; + ed->ui->prompt(ed->ui, title, text); } void editor_prompt_hide(Editor *ed) { - Prompt *prompt = ed->prompt; - if (!prompt->active) + if (!ed->prompt_window) return; - prompt->active = false; - ed->win = prompt->editor; - prompt->editor = NULL; - ed->height++; - editor_prompt_clear(prompt); - editor_draw(ed); -} - -void editor_prompt_set(Editor *ed, const char *line) { - Text *text = ed->prompt->win->text; - editor_prompt_clear(ed->prompt); - text_insert(text, 0, line, strlen(line)); - editor_window_draw(ed->prompt->win); + ed->ui->prompt_hide(ed->ui); + ed->win = ed->prompt_window; + ed->prompt_window = NULL; } char *editor_prompt_get(Editor *ed) { - Text *text = ed->prompt->win->text; - char *buf = malloc(text_size(text) + 1); - if (!buf) - return NULL; - size_t len = text_bytes_get(text, 0, text_size(text), buf); - buf[len] = '\0'; - return buf; + return ed->ui->prompt_input(ed->ui); } void editor_info_show(Editor *ed, const char *msg, ...) { va_list ap; va_start(ap, msg); - vsnprintf(ed->info, sizeof(ed->info), msg, ap); + ed->ui->info(ed->ui, msg, ap); va_end(ap); - editor_resize(ed, ed->width, ed->height); } void editor_info_hide(Editor *ed) { - if (!ed->info[0]) - return; - ed->info[0] = '\0'; - ed->height++; - editor_draw(ed); + ed->ui->info_hide(ed->ui); } -static void editor_info_draw(Editor *ed) { - attrset(A_BOLD); - mvaddstr(ed->height, 0, ed->info); -} - -static unsigned int color_hash(short fg, short bg) -{ - if (fg == -1) - fg = COLORS; - if (bg == -1) - bg = COLORS + 1; - return fg * (COLORS + 2) + bg; -} - -short editor_color_get(short fg, short bg) -{ - static bool has_default_colors; - static short *color2palette, default_fg, default_bg; - static short color_pairs_max, color_pair_current; - - if (!color2palette) { - pair_content(0, &default_fg, &default_bg); - if (default_fg == -1) - default_fg = COLOR_WHITE; - if (default_bg == -1) - default_bg = COLOR_BLACK; - has_default_colors = (use_default_colors() == OK); - color_pairs_max = MIN(COLOR_PAIRS, MAX_COLOR_PAIRS); - if (COLORS) - color2palette = calloc((COLORS + 2) * (COLORS + 2), sizeof(short)); - } - - if (fg >= COLORS) - fg = default_fg; - if (bg >= COLORS) - bg = default_bg; - - if (!has_default_colors) { - if (fg == -1) - fg = default_fg; - if (bg == -1) - bg = default_bg; - } - - if (!color2palette || (fg == -1 && bg == -1)) - return 0; - - unsigned int index = color_hash(fg, bg); - if (color2palette[index] == 0) { - short oldfg, oldbg; - if (++color_pair_current >= color_pairs_max) - color_pair_current = 1; - pair_content(color_pair_current, &oldfg, &oldbg); - unsigned int old_index = color_hash(oldfg, oldbg); - if (init_pair(color_pair_current, fg, bg) == OK) { - color2palette[old_index] = 0; - color2palette[index] = color_pair_current; - } - } - - return color2palette[index]; +void editor_window_options(EditorWin *win, enum UiOption options) { + win->ui->options(win->ui, options); } + |
