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 *motiontype(Vis *vis, const char *keys, const Arg *arg) { vis_motion_type(vis, arg->i); return keys; }