Merge #2660 'generalize mode-change API and support replace-mode cursor'

This commit is contained in:
Justin M. Keyes 2015-07-26 23:50:55 -04:00
commit ccebc1f8d3
5 changed files with 52 additions and 45 deletions

View File

@ -86,8 +86,7 @@ static Object remote_ui_attach(uint64_t channel_id, uint64_t request_id,
ui->busy_stop = remote_ui_busy_stop;
ui->mouse_on = remote_ui_mouse_on;
ui->mouse_off = remote_ui_mouse_off;
ui->insert_mode = remote_ui_insert_mode;
ui->normal_mode = remote_ui_normal_mode;
ui->mode_change = remote_ui_mode_change;
ui->set_scroll_region = remote_ui_set_scroll_region;
ui->scroll = remote_ui_scroll;
ui->highlight_set = remote_ui_highlight_set;
@ -214,16 +213,18 @@ static void remote_ui_mouse_off(UI *ui)
push_call(ui, "mouse_off", args);
}
static void remote_ui_insert_mode(UI *ui)
static void remote_ui_mode_change(UI *ui, int mode)
{
Array args = ARRAY_DICT_INIT;
push_call(ui, "insert_mode", args);
}
static void remote_ui_normal_mode(UI *ui)
{
Array args = ARRAY_DICT_INIT;
push_call(ui, "normal_mode", args);
if (mode == INSERT) {
ADD(args, STRING_OBJ(cstr_to_string("insert")));
} else if (mode == REPLACE) {
ADD(args, STRING_OBJ(cstr_to_string("replace")));
} else {
assert(mode == NORMAL);
ADD(args, STRING_OBJ(cstr_to_string("normal")));
}
push_call(ui, "mode_change", args);
}
static void remote_ui_set_scroll_region(UI *ui, int top, int bot, int left,

View File

@ -57,10 +57,11 @@ typedef struct {
bool busy;
HlAttrs attrs, print_attrs;
Cell **screen;
int showing_mode;
struct {
int enable_mouse, disable_mouse;
int enable_bracketed_paste, disable_bracketed_paste;
int enter_insert_mode, exit_insert_mode;
int enter_insert_mode, enter_replace_mode, exit_insert_mode;
int set_rgb_foreground, set_rgb_background;
} unibi_ext;
} TUIData;
@ -98,11 +99,13 @@ UI *tui_start(void)
data->can_use_terminal_scroll = true;
data->bufpos = 0;
data->bufsize = sizeof(data->buf) - CNORM_COMMAND_MAX_SIZE;
data->showing_mode = 0;
data->unibi_ext.enable_mouse = -1;
data->unibi_ext.disable_mouse = -1;
data->unibi_ext.enable_bracketed_paste = -1;
data->unibi_ext.disable_bracketed_paste = -1;
data->unibi_ext.enter_insert_mode = -1;
data->unibi_ext.enter_replace_mode = -1;
data->unibi_ext.exit_insert_mode = -1;
// write output to stderr if stdout is not a tty
@ -148,8 +151,7 @@ UI *tui_start(void)
ui->busy_stop = tui_busy_stop;
ui->mouse_on = tui_mouse_on;
ui->mouse_off = tui_mouse_off;
ui->insert_mode = tui_insert_mode;
ui->normal_mode = tui_normal_mode;
ui->mode_change = tui_mode_change;
ui->set_scroll_region = tui_set_scroll_region;
ui->scroll = tui_scroll;
ui->highlight_set = tui_highlight_set;
@ -178,7 +180,7 @@ static void tui_stop(UI *ui)
// Destroy input stuff
term_input_destroy(data->input);
// Destroy output stuff
tui_normal_mode(ui);
tui_mode_change(ui, NORMAL);
tui_mouse_off(ui);
unibi_out(ui, unibi_exit_attribute_mode);
// cursor should be set to normal before exiting alternate screen
@ -404,16 +406,25 @@ static void tui_mouse_off(UI *ui)
data->mouse_enabled = false;
}
static void tui_insert_mode(UI *ui)
static void tui_mode_change(UI *ui, int mode)
{
TUIData *data = ui->data;
unibi_out(ui, data->unibi_ext.enter_insert_mode);
}
static void tui_normal_mode(UI *ui)
{
TUIData *data = ui->data;
unibi_out(ui, data->unibi_ext.exit_insert_mode);
if (mode == INSERT) {
if (data->showing_mode != INSERT) {
unibi_out(ui, data->unibi_ext.enter_insert_mode);
}
} else if (mode == REPLACE) {
if (data->showing_mode != REPLACE) {
unibi_out(ui, data->unibi_ext.enter_replace_mode);
}
} else {
assert(mode == NORMAL);
if (data->showing_mode != NORMAL) {
unibi_out(ui, data->unibi_ext.exit_insert_mode);
}
}
data->showing_mode = mode;
}
static void tui_set_scroll_region(UI *ui, int top, int bot, int left,
@ -804,12 +815,16 @@ static void fix_terminfo(TUIData *data)
// iterm
data->unibi_ext.enter_insert_mode = (int)unibi_add_ext_str(ut, NULL,
TMUX_WRAP("\x1b]50;CursorShape=1;BlinkingCursorEnabled=1\x07"));
data->unibi_ext.enter_replace_mode = (int)unibi_add_ext_str(ut, NULL,
TMUX_WRAP("\x1b]50;CursorShape=2;BlinkingCursorEnabled=1\x07"));
data->unibi_ext.exit_insert_mode = (int)unibi_add_ext_str(ut, NULL,
TMUX_WRAP("\x1b]50;CursorShape=0;BlinkingCursorEnabled=0\x07"));
} else {
// xterm-like sequences for blinking bar and solid block
data->unibi_ext.enter_insert_mode = (int)unibi_add_ext_str(ut, NULL,
TMUX_WRAP("\x1b[5 q"));
data->unibi_ext.enter_replace_mode = (int)unibi_add_ext_str(ut, NULL,
TMUX_WRAP("\x1b[3 q"));
data->unibi_ext.exit_insert_mode = (int)unibi_add_ext_str(ut, NULL,
TMUX_WRAP("\x1b[2 q"));
}

View File

@ -121,7 +121,7 @@ void ui_update_encoding(void)
// May update the shape of the cursor.
void ui_cursor_shape(void)
{
ui_change_mode();
ui_mode_change();
}
void ui_refresh(void)
@ -469,25 +469,20 @@ static void flush_cursor_update(void)
// Notify that the current mode has changed. Can be used to change cursor
// shape, for example.
static void ui_change_mode(void)
static void ui_mode_change(void)
{
static int showing_insert_mode = MAYBE;
int mode;
if (!full_screen) {
return;
}
if (State & INSERT) {
if (showing_insert_mode != TRUE) {
UI_CALL(insert_mode);
}
showing_insert_mode = TRUE;
} else {
if (showing_insert_mode != FALSE) {
UI_CALL(normal_mode);
}
showing_insert_mode = FALSE;
}
/* Get a simple UI mode out of State. */
if ((State & REPLACE) == REPLACE)
mode = REPLACE;
else if (State & INSERT)
mode = INSERT;
else
mode = NORMAL;
UI_CALL(mode_change, mode);
conceal_check_cursur_line();
}

View File

@ -24,8 +24,7 @@ struct ui_t {
void (*busy_stop)(UI *ui);
void (*mouse_on)(UI *ui);
void (*mouse_off)(UI *ui);
void (*insert_mode)(UI *ui);
void (*normal_mode)(UI *ui);
void (*mode_change)(UI *ui, int mode);
void (*set_scroll_region)(UI *ui, int top, int bot, int left, int right);
void (*scroll)(UI *ui, int count);
void (*highlight_set)(UI *ui, HlAttrs attrs);

View File

@ -340,12 +340,9 @@ function Screen:_handle_mouse_off()
self._mouse_enabled = false
end
function Screen:_handle_insert_mode()
self._mode = 'insert'
end
function Screen:_handle_normal_mode()
self._mode = 'normal'
function Screen:_handle_mode_change(mode)
assert(mode == 'insert' or mode == 'replace' or mode == 'normal')
self._mode = mode
end
function Screen:_handle_set_scroll_region(top, bot, left, right)