aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-05-21 23:45:34 +0200
committerMarc André Tanner <mat@brain-dump.org>2016-05-22 00:05:31 +0200
commit6a7f12527b1d5f562c8e762126719706329aae8b (patch)
tree0c22b2d3b7b4fb5dbf6a12c2d2f171bebaf95d48
parentbadb616c967f78aaae0939d794606599395ae6cc (diff)
downloadvis-6a7f12527b1d5f562c8e762126719706329aae8b.tar.gz
vis-6a7f12527b1d5f562c8e762126719706329aae8b.tar.xz
vis: refactor status line handling
Make window status bar content configurable via Lua.
-rw-r--r--main.c1
-rw-r--r--ui-curses.c42
-rw-r--r--ui.h1
-rw-r--r--view.c4
-rw-r--r--view.h2
-rw-r--r--vis-lua.c52
-rw-r--r--vis-lua.h1
-rw-r--r--vis-modes.c12
-rw-r--r--vis.c18
-rw-r--r--vis.h3
-rw-r--r--vis.lua51
11 files changed, 125 insertions, 62 deletions
diff --git a/main.c b/main.c
index 2bc55de..64d1c07 100644
--- a/main.c
+++ b/main.c
@@ -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,
diff --git a/ui.h b/ui.h
index bd48459..26f2227 100644
--- a/ui.h
+++ b/ui.h
@@ -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);
diff --git a/view.c b/view.c
index e67dc42..4b06d3a 100644
--- a/view.c
+++ b/view.c
@@ -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;
diff --git a/view.h b/view.h
index 2e58593..8cd2ce3 100644
--- a/view.h
+++ b/view.h
@@ -14,7 +14,7 @@ typedef struct Selection Selection;
typedef struct {
void *data;
- void (*highlight)(void *data);
+ void (*draw)(void *data);
} ViewEvent;
typedef struct {
diff --git a/vis-lua.c b/vis-lua.c
index e893885..fdc4fd2 100644
--- a/vis-lua.c
+++ b/vis-lua.c
@@ -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");
diff --git a/vis-lua.h b/vis-lua.h
index 8811f55..644ce73 100644
--- a/vis-lua.h
+++ b/vis-lua.h
@@ -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,
diff --git a/vis.c b/vis.c
index 3fabe5b..a5a2e1b 100644
--- a/vis.c
+++ b/vis.c
@@ -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);
diff --git a/vis.h b/vis.h
index 7dde13f..d699085 100644
--- a/vis.h
+++ b/vis.h
@@ -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*);
diff --git a/vis.lua b/vis.lua
index 297c09e..c47d49f 100644
--- a/vis.lua
+++ b/vis.lua
@@ -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