diff options
| -rw-r--r-- | main.c | 1 | ||||
| -rw-r--r-- | ui-curses.c | 42 | ||||
| -rw-r--r-- | ui.h | 1 | ||||
| -rw-r--r-- | view.c | 4 | ||||
| -rw-r--r-- | view.h | 2 | ||||
| -rw-r--r-- | vis-lua.c | 52 | ||||
| -rw-r--r-- | vis-lua.h | 1 | ||||
| -rw-r--r-- | vis-modes.c | 12 | ||||
| -rw-r--r-- | vis.c | 18 | ||||
| -rw-r--r-- | vis.h | 3 | ||||
| -rw-r--r-- | vis.lua | 51 |
11 files changed, 125 insertions, 62 deletions
@@ -2190,6 +2190,7 @@ int main(int argc, char *argv[]) { .win_close = vis_lua_win_close, .win_highlight = vis_lua_win_highlight, .win_syntax = vis_lua_win_syntax, + .win_status = vis_lua_win_status, }; vis = vis_new(ui_curses_new(), &event); diff --git a/ui-curses.c b/ui-curses.c index ce4ef03..d4131da 100644 --- a/ui-curses.c +++ b/ui-curses.c @@ -631,44 +631,6 @@ static bool ui_window_draw_sidebar(UiCursesWin *win) { } } -static void ui_window_draw_status(UiWin *w) { - UiCursesWin *win = (UiCursesWin*)w; - if (!win->winstatus) - return; - UiCurses *uic = win->ui; - Vis *vis = uic->vis; - bool focused = uic->selwin == win; - const char *filename = win->file->name; - const char *status = vis_mode_status(vis); - wattrset(win->winstatus, focused ? A_REVERSE|A_BOLD : A_REVERSE); - mvwhline(win->winstatus, 0, 0, ' ', win->width); - mvwprintw(win->winstatus, 0, 0, "%s %s %s %s", - focused && status ? status : "", - filename ? filename : "[No Name]", - text_modified(win->file->text) ? "[+]" : "", - vis_macro_recording(vis) ? "recording": ""); - - char buf[4*32] = "", *msg = buf; - int cursor_count = view_cursors_count(win->view); - if (cursor_count > 1) { - Cursor *c = view_cursors_primary_get(win->view); - int cursor_number = view_cursors_number(c) + 1; - msg += sprintf(msg, "[%d/%d] ", cursor_number, cursor_count); - } - - if (!(win->options & UI_OPTION_LARGE_FILE)) { - Cursor *cur = view_cursors_primary_get(win->view); - size_t line = view_cursors_line(cur); - size_t col = view_cursors_col(cur); - if (col > UI_LARGE_FILE_LINE_SIZE) - win->options |= UI_OPTION_LARGE_FILE; - msg += sprintf(msg, "%zu, %zu", line, col); - } - - if (buf[0]) - mvwaddstr(win->winstatus, 0, win->width - (msg - buf) - 1, buf); -} - static void ui_window_status(UiWin *w, const char *status) { UiCursesWin *win = (UiCursesWin*)w; if (!win->winstatus) @@ -745,9 +707,6 @@ static void ui_window_draw(UiWin *w) { } wclrtobot(win->win); - - if (win->winstatus) - ui_window_draw_status(w); } static void ui_window_reload(UiWin *w, File *file) { @@ -996,7 +955,6 @@ static UiWin *ui_window_new(Ui *ui, View *view, File *file, enum UiOption option win->uiwin = (UiWin) { .draw = ui_window_draw, - .draw_status = ui_window_draw_status, .status = ui_window_status, .options_set = ui_window_options_set, .options_get = ui_window_options_get, @@ -75,7 +75,6 @@ struct Ui { struct UiWin { void (*draw)(UiWin*); - void (*draw_status)(UiWin*); void (*status)(UiWin*, const char *txt); void (*reload)(UiWin*, File*); void (*options_set)(UiWin*, enum UiOption); @@ -439,8 +439,8 @@ void view_update(View *view) { if (!view->need_update) return; - if (view->events->highlight) - view->events->highlight(view->events->data); + if (view->events->draw) + view->events->draw(view->events->data); if (view->colorcolumn > 0) { size_t lineno = 0; @@ -14,7 +14,7 @@ typedef struct Selection Selection; typedef struct { void *data; - void (*highlight)(void *data); + void (*draw)(void *data); } ViewEvent; typedef struct { @@ -32,6 +32,48 @@ void vis_lua_win_highlight(Vis *vis, Win *win, size_t horizon) { } bool vis_lua_win_syntax(Vis *vis, Win *win, const char *syntax) { return true; } bool vis_theme_load(Vis *vis, const char *name) { return true; } +void vis_lua_win_status(Vis *vis, Win *win) { + char status[1024], left[256], right[256], cursors[32] = "", pos[32] = ""; + int width = vis_window_width_get(win); + int delim_len = 1, delim_count = 0; + enum UiOption options = view_options_get(win->view); + const char *filename = win->file->name; + const char *mode = vis->mode->status; + + int left_len = snprintf(left, sizeof(left)-1, "%s%s%s%s%s", + mode ? mode : "", + mode && ++delim_count ? " » " : "", + filename ? filename : "[No Name]", + text_modified(win->file->text) ? " [+]" : "", + vis_macro_recording(vis) ? " @": ""); + + int cursor_count = view_cursors_count(win->view); + if (cursor_count > 1) { + Cursor *c = view_cursors_primary_get(win->view); + int cursor_number = view_cursors_number(c) + 1; + snprintf(cursors, sizeof(cursors)-1, "%d/%d", cursor_number, cursor_count); + } + + if (!(options & UI_OPTION_LARGE_FILE)) { + Cursor *cur = view_cursors_primary_get(win->view); + size_t line = view_cursors_line(cur); + size_t col = view_cursors_col(cur); + if (col > UI_LARGE_FILE_LINE_SIZE) { + options |= UI_OPTION_LARGE_FILE; + view_options_set(win->view, options); + } + snprintf(pos, sizeof(pos)-1, "%zu, %zu", line, col); + } + + int right_len = snprintf(right, sizeof(right)-1, "%s%s%s", + cursors, cursors[0] && pos[0] && ++delim_count ? " « " : "", pos); + int spaces = width - left_len - right_len - 2 + delim_count*delim_len; + if (spaces < 1) + spaces = 1; + snprintf(status, sizeof(status)-1, " %s%*s%s ", left, spaces, " ", right); + vis_window_status(win, status); +} + #else #if 0 @@ -1332,6 +1374,16 @@ bool vis_lua_win_syntax(Vis *vis, Win *win, const char *syntax) { return ret; } +void vis_lua_win_status(Vis *vis, Win *win) { + lua_State *L = vis->lua; + vis_lua_event_get(L, "win_status"); + if (lua_isfunction(L, -1)) { + obj_ref_new(L, win, "vis.window"); + pcall(vis, L, 1, 0); + } + lua_pop(L, 1); +} + bool vis_theme_load(Vis *vis, const char *name) { lua_State *L = vis->lua; vis_lua_event_get(L, "theme_change"); @@ -27,5 +27,6 @@ void vis_lua_win_open(Vis*, Win*); void vis_lua_win_close(Vis*, Win*); void vis_lua_win_highlight(Vis*, Win*, size_t horizon); bool vis_lua_win_syntax(Vis*, Win*, const char *syntax); +void vis_lua_win_status(Vis*, Win*); #endif diff --git a/vis-modes.c b/vis-modes.c index ad866f7..eb4bfb0 100644 --- a/vis-modes.c +++ b/vis-modes.c @@ -18,7 +18,8 @@ void mode_set(Vis *vis, Mode *new_mode) { vis->mode = new_mode; if (new_mode->enter) new_mode->enter(vis, vis->mode_prev); - vis->win->ui->draw_status(vis->win->ui); + if (vis->event && vis->event->win_status) + vis->event->win_status(vis, vis->win); } void vis_mode_switch(Vis *vis, enum VisMode mode) { @@ -166,13 +167,12 @@ Mode vis_modes[] = { [VIS_MODE_NORMAL] = { .id = VIS_MODE_NORMAL, .name = "NORMAL", - .status = "", .help = "", }, [VIS_MODE_VISUAL] = { .id = VIS_MODE_VISUAL, .name = "VISUAL", - .status = "--VISUAL--", + .status = "VISUAL", .help = "", .enter = vis_mode_visual_enter, .leave = vis_mode_visual_leave, @@ -182,7 +182,7 @@ Mode vis_modes[] = { .id = VIS_MODE_VISUAL_LINE, .name = "VISUAL LINE", .parent = &vis_modes[VIS_MODE_VISUAL], - .status = "--VISUAL LINE--", + .status = "VISUAL-LINE", .help = "", .enter = vis_mode_visual_line_enter, .leave = vis_mode_visual_line_leave, @@ -191,7 +191,7 @@ Mode vis_modes[] = { [VIS_MODE_INSERT] = { .id = VIS_MODE_INSERT, .name = "INSERT", - .status = "--INSERT--", + .status = "INSERT", .help = "", .enter = vis_mode_insert_enter, .leave = vis_mode_insert_leave, @@ -203,7 +203,7 @@ Mode vis_modes[] = { .id = VIS_MODE_REPLACE, .name = "REPLACE", .parent = &vis_modes[VIS_MODE_INSERT], - .status = "--REPLACE--", + .status = "REPLACE", .help = "", .enter = vis_mode_replace_enter, .leave = vis_mode_replace_leave, @@ -157,11 +157,17 @@ static void window_free(Win *win) { free(win); } -static void window_highlight(void *ctx) { +static void window_draw(void *ctx) { Win *win = ctx; + if (!win->ui) + return; Vis *vis = win->vis; - if (!win->file->internal && vis->event && vis->event->win_highlight) - vis->event->win_highlight(vis, win, win->horizon); + if (!win->file->internal && vis->event) { + if (win->lexer_name && vis->event->win_highlight) + vis->event->win_highlight(vis, win, win->horizon); + if (vis->event->win_status) + vis->event->win_status(vis, win); + } } Win *window_new_file(Vis *vis, File *file) { @@ -172,6 +178,7 @@ Win *window_new_file(Vis *vis, File *file) { win->file = file; win->jumplist = ringbuf_alloc(31); win->event.data = win; + win->event.draw = window_draw; win->horizon = 1 << 15; win->view = view_new(file->text, &win->event); win->ui = vis->ui->window_new(vis->ui, win->view, file, UI_OPTION_STATUSBAR); @@ -268,7 +275,6 @@ bool vis_window_syntax_set(Win *win, const char *syntax) { } free(win->lexer_name); win->lexer_name = syntax ? strdup(syntax) : NULL; - win->event.highlight = syntax ? window_highlight : NULL; return !syntax || win->lexer_name; } @@ -1133,10 +1139,6 @@ void vis_exit(Vis *vis, int status) { vis->exit_status = status; } -const char *vis_mode_status(Vis *vis) { - return vis->mode->status; -} - void vis_insert_tab(Vis *vis) { if (!vis->expandtab) { vis_insert_key(vis, "\t", 1); @@ -35,6 +35,7 @@ typedef struct { void (*win_close)(Vis*, Win*); void (*win_highlight)(Vis*, Win*, size_t horizon); bool (*win_syntax)(Vis*, Win*, const char *syntax); + void (*win_status)(Vis*, Win*); } VisEvent; typedef union { /* various types of arguments passed to key action functions */ @@ -162,8 +163,6 @@ bool vis_window_mode_map(Win*, enum VisMode, bool force, const char *key, const /* in the specified mode: unmap a given key, fails if the key is not currently mapped */ bool vis_mode_unmap(Vis*, enum VisMode, const char *key); bool vis_window_mode_unmap(Win*, enum VisMode, const char *key); -/* get the current mode's status line indicator */ -const char *vis_mode_status(Vis*); /* associates the special pseudo key <keyaction->name> with the given key action. * after successfull registration the pseudo key can be used key binding aliases */ bool vis_action_register(Vis*, const KeyAction*); @@ -282,3 +282,54 @@ vis.events.win_highlight = function(win, horizon_max) token_start = token_end end end + +local modes = { + [vis.MODE_NORMAL] = '', + [vis.MODE_OPERATOR_PENDING] = '', + [vis.MODE_VISUAL] = 'VISUAL', + [vis.MODE_VISUAL_LINE] = 'VISUAL-LINE', + [vis.MODE_INSERT] = 'INSERT', + [vis.MODE_REPLACE] = 'REPLACE', +} + +vis.events.win_status = function(win) + local left = {} + local right = {} + local file = win.file + local cursor = win.cursor + local delim_len = 1 + + local mode = modes[vis.mode] + if mode ~= '' then + table.insert(left, mode) + end + + table.insert(left, (file.name or '[No Name]') .. + (file.modified and ' [+]' or '') .. (vis.recording and ' @' or '')) + + if file.newlines ~= "nl" then + table.insert(right, "␊") + end + + if #win.cursors > 1 then + table.insert(right, cursor.number..'/'..#win.cursors) + end + + local size = file.size + table.insert(right, (size == 0 and "0" or math.ceil(cursor.pos/size*100)).."%") + + if not win.large then + local col = cursor.col + table.insert(right, cursor.line..', '..col) + if size > 33554432 or col > 65536 then + win.large = true + end + end + + local left_str = ' ' .. table.concat(left, " » ") .. ' ' + local right_str = ' ' .. table.concat(right, " « ") .. ' ' + local delim_count = math.max(#left-1, 0) + math.max(#right-1, 0) + local spaces = string.rep(' ', win.width - #left_str - #right_str + delim_count*delim_len) + local status = left_str .. spaces .. right_str + win:status(status) +end |
