static const char *gotoline(Vis *vis, const char *keys, const Arg *arg) { if (vis_count_get(vis)) vis_motion(vis, VIS_MOVE_LINE); else if (arg->i < 0) vis_motion(vis, VIS_MOVE_FILE_BEGIN); else vis_motion(vis, VIS_MOVE_FILE_END); return keys; }
bool vis_prompt_cmd(Vis *vis, const char *cmd) { if (!cmd || !cmd[0] || !cmd[1]) return true; switch (cmd[0]) { case '/': return vis_motion(vis, VIS_MOVE_SEARCH_FORWARD, cmd+1); case '?': return vis_motion(vis, VIS_MOVE_SEARCH_BACKWARD, cmd+1); case '+': case ':': register_put0(vis, &vis->registers[VIS_REG_COMMAND], cmd+1); return vis_cmd(vis, cmd+1); default: return false; } }
static void vis_mode_visual_line_enter(Vis *vis, Mode *old) { if (!old->visual) { for (Cursor *c = view_cursors(vis->win->view); c; c = view_cursors_next(c)) view_cursors_selection_start(c); } vis_motion(vis, VIS_MOVE_NOP); }
static const char *movement_key(Vis *vis, const char *keys, const Arg *arg) { if (!keys[0]) return NULL; char key[32]; const char *next = vis_keys_next(vis, keys); strncpy(key, keys, next - keys + 1); key[sizeof(key)-1] = '\0'; vis_motion(vis, arg->i, key); return next; }
static const char *count(Vis *vis, const char *keys, const Arg *arg) { int digit = keys[-1] - '0'; int count = vis_count_get(vis); if (0 <= digit && digit <= 9) { if (digit == 0 && count == 0) vis_motion(vis, VIS_MOVE_LINE_BEGIN); vis_count_set(vis, count * 10 + digit); } return keys; }
static const char *prompt_backspace(Vis *vis, const char *keys, const Arg *arg) { Win *prompt = vis->win; Text *txt = prompt->file->text; size_t size = text_size(txt); size_t pos = view_cursor_get(prompt->view); char c; if (pos == size && (pos == 1 || (size >= 2 && text_byte_get(txt, size-2, &c) && c == '\n'))) { prompt_restore(prompt); prompt_hide(prompt); } else { vis_operator(vis, VIS_OP_DELETE); vis_motion(vis, VIS_MOVE_CHAR_PREV); } return keys; }
static const char *replace(Vis *vis, const char *keys, const Arg *arg) { if (!keys[0]) return NULL; const char *next = vis_keys_next(vis, keys); if (!next) return NULL; size_t len = next - keys; char key[len+1]; memcpy(key, keys, len); key[len] = '\0'; vis_operator(vis, VIS_OP_REPLACE); vis_motion(vis, VIS_MOVE_NOP); vis_keys_inject(vis, next, key); vis_keys_inject(vis, next+len, "<Escape>"); return next; }
bool vis_operator(Vis *vis, enum VisOperator id, ...) { va_list ap; va_start(ap, id); switch (id) { case VIS_OP_CASE_LOWER: case VIS_OP_CASE_UPPER: case VIS_OP_CASE_SWAP: vis->action.arg.i = id; id = VIS_OP_CASE_SWAP; break; case VIS_OP_CURSOR_SOL: case VIS_OP_CURSOR_EOL: vis->action.arg.i = id; id = VIS_OP_CURSOR_SOL; break; case VIS_OP_PUT_AFTER: case VIS_OP_PUT_AFTER_END: case VIS_OP_PUT_BEFORE: case VIS_OP_PUT_BEFORE_END: vis->action.arg.i = id; id = VIS_OP_PUT_AFTER; break; case VIS_OP_FILTER: vis->action.arg.s = va_arg(ap, char*); /* fall through */ case VIS_OP_SHIFT_LEFT: case VIS_OP_SHIFT_RIGHT: vis_motion_type(vis, VIS_MOTIONTYPE_LINEWISE); break; default: break; } if (id >= LENGTH(vis_operators)) goto err; const Operator *op = &vis_operators[id]; if (vis->mode->visual) { vis->action.op = op; action_do(vis, &vis->action); goto out; } /* switch to operator mode inorder to make operator options and * text-object available */ vis_mode_switch(vis, VIS_MODE_OPERATOR_PENDING); if (vis->action.op == op) { /* hacky way to handle double operators i.e. things like * dd, yy etc where the second char isn't a movement */ vis->action.type = LINEWISE; vis_motion(vis, VIS_MOVE_LINE_NEXT); } else { vis->action.op = op; } /* put is not a real operator, does not need a range to operate on */ if (id == VIS_OP_PUT_AFTER) vis_motion(vis, VIS_MOVE_NOP); out: va_end(ap); return true; err: va_end(ap); return false; }
static const char *mark_motion(Vis *vis, const char *keys, const Arg *arg) { int mark; keys = key2mark(vis, keys, &mark); vis_motion(vis, arg->i, mark); return keys; }
static const char *movement(Vis *vis, const char *keys, const Arg *arg) { vis_motion(vis, arg->i); return keys; }
static const char *prompt_up(Vis *vis, const char *keys, const Arg *arg) { vis_motion(vis, VIS_MOVE_LINE_UP); vis_window_mode_unmap(vis->win, VIS_MODE_INSERT, "<Up>"); view_options_set(vis->win->view, UI_OPTION_NONE); return keys; }