aboutsummaryrefslogtreecommitdiff
path: root/editor.c
diff options
context:
space:
mode:
Diffstat (limited to 'editor.c')
-rw-r--r--editor.c388
1 files changed, 59 insertions, 329 deletions
diff --git a/editor.c b/editor.c
index a8330d6..668062c 100644
--- a/editor.c
+++ b/editor.c
@@ -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);
}
+