sandy

text editor
git clone git://git.suckless.org/sandy
Log | Files | Refs | README | LICENSE

commit 9236b212b8d2252deebc1ae5d7447021a6623a5f
parent aa1450de7036134ee2e0986ec044933b9e75b39b
Author: Dimitris Zervas <dzervas@dzervas.gr>
Date:   Thu, 10 Jul 2014 12:57:03 +0300

Added more keybindings

Diffstat:
TODO | 4+++-
config.h | 252++++++++++++++++++++++++++++++++++++++++---------------------------------------
sandy.c | 12++++--------
3 files changed, 136 insertions(+), 132 deletions(-)

diff --git a/TODO b/TODO @@ -2,7 +2,6 @@ In no particular order, at sandy.c: - Update manpage - Create m_*vline - Bracket matching? -- Number modifier? - Smart end? is it really needed? - BUG: high CPU usage on continuous resize - BUG: Deal with the bigger-than-window line @@ -11,6 +10,9 @@ In no particular order, at sandy.c: - Group delete undos? - Show line numbers - Show some documentation when you press tab in command mode +- FINDBW prompt? is it needed? +- Support multiple marks (with S_Parameter) +- Instead of delete, just cut At config.def.h: - Bindings! diff --git a/config.h b/config.h @@ -45,20 +45,20 @@ static void f_pipenull(const Arg*); #define CMD_P PROMPT("Command:", "/\n?\nw\nq\n!\nsyntax\noffset\nicase\nro\nai\ndump", "") /* Args to f_pipe and friends, simple examples are inlined instead */ -#define TOCLIP { .v = "tee /tmp/.sandy.clipboard.$USER | xsel -ib 2>/dev/null" } -#define FROMCLIP { .v = "xsel -ob 2>/dev/null || cat /tmp/.sandy.clipboard.$USER" } -#define TOSEL { .v = "tee /tmp/.sandy.selection.$USER | xsel -i 2>/dev/null" } -#define FROMSEL { .v = "xsel -o 2>/dev/null || cat /tmp/.sandy.selection.$USER" } -#define AUTOINDENT { .v = "awk 'BEGIN{ l=\"\\n\" }; \ +#define TOCLIP "tee /tmp/.sandy.clipboard.$USER | xsel -ib 2>/dev/null" +#define FROMCLIP "xsel -ob 2>/dev/null || cat /tmp/.sandy.clipboard.$USER" +#define TOSEL "tee /tmp/.sandy.selection.$USER | xsel -i 2>/dev/null" +#define FROMSEL "xsel -o 2>/dev/null || cat /tmp/.sandy.selection.$USER" +#define AUTOINDENT "awk 'BEGIN{ l=\"\\n\" }; \ { if(match($0, \"^[\t ]+[^\t ]\")) l=substr($0, RSTART, RLENGTH-1); \ else l=\"\"; \ if(FNR==NR && $0 ~ /^[\t ]+$/) print \"\"; \ else print }; \ - END{ ORS=\"\"; print l }' 2>/dev/null" } -#define CAPITALIZE { .v = "awk 'BEGIN{ ORS=\"\" }; \ + END{ ORS=\"\"; print l }' 2>/dev/null" +#define CAPITALIZE "awk 'BEGIN{ ORS=\"\" }; \ { for ( i=1; i <= NF; i++) { $i=tolower($i) ; sub(\".\", substr(toupper($i),1,1) , $i) } \ if(FNR==NF) print $0; \ - else print $0\"\\n\" }' 2>/dev/null" } + else print $0\"\\n\" }' 2>/dev/null" /* Hooks are launched from the main code */ #define HOOK_SAVE_NO_FILE f_spawn (&(const Arg)SAVEAS) @@ -73,144 +73,150 @@ static void f_pipenull(const Arg*); static const Key curskeys[] = { /* Plain keys here, no CONTROL or META */ /* keyv.i, tests, func, arg */ -{ .keyv.i = KEY_BACKSPACE, { t_rw, t_nocomm,0,0 }, f_delete, { .m = m_prevchar } }, -{ .keyv.i = KEY_BACKSPACE, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevchar } }, -{ .keyv.i = KEY_DC, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, -{ .keyv.i = KEY_DC, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, -{ .keyv.i = KEY_SDC, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, -{ .keyv.i = KEY_SDC, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, -{ .keyv.i = KEY_IC, { t_sel, 0, 0, 0 }, f_pipero, TOCLIP }, -{ .keyv.i = KEY_SIC, { t_rw, 0, 0, 0 }, f_pipenull, FROMCLIP }, -{ .keyv.i = KEY_HOME, { t_ai, 0, 0, 0 }, f_moveboth, { .m = m_smartbol } }, -{ .keyv.i = KEY_HOME, { 0, 0, 0, 0 }, f_moveboth, { .m = m_bol } }, -{ .keyv.i = KEY_END, { 0, 0, 0, 0 }, f_moveboth, { .m = m_eol } }, -{ .keyv.i = KEY_SHOME, { 0, 0, 0, 0 }, f_moveboth, { .m = m_bof } }, -{ .keyv.i = KEY_SEND, { 0, 0, 0, 0 }, f_moveboth, { .m = m_eof } }, -{ .keyv.i = KEY_PPAGE, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevscr } }, -{ .keyv.i = KEY_NPAGE, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextscr } }, -{ .keyv.i = KEY_UP, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevline } }, -{ .keyv.i = KEY_DOWN, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextline } }, -{ .keyv.i = KEY_LEFT, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevchar } }, -{ .keyv.i = KEY_RIGHT, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextchar } }, -{ .keyv.i = KEY_SLEFT, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevword } }, -{ .keyv.i = KEY_SRIGHT, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextword } }, +{ .keyv.i = KEY_BACKSPACE, { t_rw, t_nocomm,0,0 }, f_delete, { .m = m_prevchar } }, +{ .keyv.i = KEY_BACKSPACE, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevchar } }, +{ .keyv.i = KEY_DC, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, +{ .keyv.i = KEY_DC, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, +{ .keyv.i = KEY_SDC, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, +{ .keyv.i = KEY_SDC, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, +{ .keyv.i = KEY_IC, { t_sel, 0, 0, 0 }, f_pipero, { .v = TOCLIP } }, +{ .keyv.i = KEY_SIC, { t_rw, 0, 0, 0 }, f_pipenull, { .v = FROMCLIP } }, +{ .keyv.i = KEY_HOME, { t_ai, 0, 0, 0 }, f_moveboth, { .m = m_smartbol } }, +{ .keyv.i = KEY_HOME, { 0, 0, 0, 0 }, f_moveboth, { .m = m_bol } }, +{ .keyv.i = KEY_END, { 0, 0, 0, 0 }, f_moveboth, { .m = m_eol } }, +{ .keyv.i = KEY_SHOME, { 0, 0, 0, 0 }, f_moveboth, { .m = m_bof } }, +{ .keyv.i = KEY_SEND, { 0, 0, 0, 0 }, f_moveboth, { .m = m_eof } }, +{ .keyv.i = KEY_PPAGE, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevscr } }, +{ .keyv.i = KEY_NPAGE, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextscr } }, +{ .keyv.i = KEY_UP, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevline } }, +{ .keyv.i = KEY_UP, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevline } }, +{ .keyv.i = KEY_DOWN, { t_sent,0, 0, 0 }, f_adjective, { .m = m_nextline } }, +{ .keyv.i = KEY_DOWN, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextline } }, +{ .keyv.i = KEY_LEFT, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevchar } }, +{ .keyv.i = KEY_LEFT, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevchar } }, +{ .keyv.i = KEY_RIGHT, { t_sent,0, 0, 0 }, f_adjective, { .m = m_nextchar } }, +{ .keyv.i = KEY_RIGHT, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextchar } }, +{ .keyv.i = KEY_SLEFT, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevword } }, +{ .keyv.i = KEY_SRIGHT, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextword } }, }; static const Key stdkeys[] = { /* keyv.c, test, func, arg */ -{ .keyv.c = CONTROL('C'), { t_warn,t_mod,0, 0 }, f_toggle, { .i = S_Running } }, -{ .keyv.c = CONTROL('C'), { t_mod, 0, 0, 0 }, f_toggle, { .i = S_Warned } }, -{ .keyv.c = CONTROL('C'), { 0, 0, 0, 0 }, f_toggle, { .i = S_Running } }, -{ .keyv.c = META('c'), { t_sel, t_rw, 0, 0 }, f_pipe, CAPITALIZE }, -{ .keyv.c = CONTROL('D'), { t_sel, t_rw, 0, 0 }, f_pipe, TOCLIP }, -{ .keyv.c = CONTROL('D'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, -{ .keyv.c = META('d'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextword } }, -{ .keyv.c = CONTROL('E'), { 0, 0, 0, 0 }, f_move, { .m = m_eol } }, -{ .keyv.c = CONTROL('F'), { 0, 0, 0, 0 }, f_move, { .m = m_nextchar } }, -{ .keyv.c = META('f'), { 0, 0, 0, 0 }, f_move, { .m = m_nextword } }, -{ .keyv.c = CONTROL('G'), { t_sel, 0, 0, 0 }, f_select, { .m = m_stay } }, -{ .keyv.c = CONTROL('H'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevchar } }, -{ .keyv.c = CONTROL('I'), { t_rw, t_nocomm,0,0 }, f_insert, { .v = "\t" } }, -{ .keyv.c = CONTROL('J'), { t_rw, t_ai, 0, 0 }, f_pipeai, AUTOINDENT } , -{ .keyv.c = CONTROL('J'), { t_rw, t_nocomm,0,0 }, f_insert, { .v = "\n" } }, -{ .keyv.c = CONTROL('J'), { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextline } }, -{ .keyv.c = CONTROL('K'), { t_eol, t_rw, 0, 0 }, f_delete, { .m = m_nextchar } }, -{ .keyv.c = CONTROL('K'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_eol } }, -{ .keyv.c = CONTROL('L'), { 0, 0, 0, 0 }, f_center, { 0 } }, +{ .keyv.c = CONTROL('C'), { t_warn,t_mod,0, 0 }, f_toggle, { .i = S_Running } }, +{ .keyv.c = CONTROL('C'), { t_mod, 0, 0, 0 }, f_toggle, { .i = S_Warned } }, +{ .keyv.c = CONTROL('C'), { 0, 0, 0, 0 }, f_toggle, { .i = S_Running } }, +{ .keyv.c = META('c'), { t_sel, t_rw, 0, 0 }, f_pipe, { .v = CAPITALIZE } }, +{ .keyv.c = CONTROL('D'), { t_sel, t_rw, 0, 0 }, f_pipe, { .v = TOCLIP } }, +{ .keyv.c = CONTROL('D'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, +{ .keyv.c = META('d'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextword } }, +{ .keyv.c = CONTROL('E'), { 0, 0, 0, 0 }, f_move, { .m = m_eol } }, +{ .keyv.c = CONTROL('F'), { 0, 0, 0, 0 }, f_move, { .m = m_nextchar } }, +{ .keyv.c = META('f'), { 0, 0, 0, 0 }, f_move, { .m = m_nextword } }, +{ .keyv.c = CONTROL('G'), { t_sel, 0, 0, 0 }, f_select, { .m = m_stay } }, +{ .keyv.c = CONTROL('H'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevchar } }, +{ .keyv.c = CONTROL('I'), { t_rw, t_nocomm,0,0 }, f_insert, { .v = "\t" } }, +{ .keyv.c = CONTROL('J'), { t_rw, t_ai, 0, 0 }, f_pipeai, { .v = AUTOINDENT } }, +{ .keyv.c = CONTROL('J'), { t_rw, t_nocomm,0,0 }, f_insert, { .v = "\n" } }, +{ .keyv.c = CONTROL('J'), { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextline } }, +{ .keyv.c = CONTROL('K'), { t_eol, t_rw, 0, 0 }, f_delete, { .m = m_nextchar } }, +{ .keyv.c = CONTROL('K'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_eol } }, +{ .keyv.c = CONTROL('L'), { 0, 0, 0, 0 }, f_center, { 0 } }, { .keyv.c = META('l'), { t_sel, t_rw, 0, 0 }, f_pipe, { .v = "tr [A-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ] [a-zàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ]" } }, /* Lowercase */ -{ .keyv.c = CONTROL('M'), { t_rw, t_ai, 0, 0 }, f_pipeai, AUTOINDENT } , -{ .keyv.c = CONTROL('M'), { t_rw, t_nocomm,0,0 }, f_insert, { .v = "\n" } }, -{ .keyv.c = CONTROL('M'), { 0, 0, 0, 0 }, f_move, { .m = m_nextline } }, -{ .keyv.c = CONTROL('N'), { 0, 0, 0, 0 }, f_move, { .m = m_nextline } }, -{ .keyv.c = CONTROL('O'), { t_sel, 0, 0, 0 }, f_select, { .m = m_tosel } }, /* Swap fsel and fcur */ -{ .keyv.c = CONTROL('P'), { 0, 0, 0, 0 }, f_move, { .m = m_prevline } }, -{ .keyv.c = CONTROL('Q'), { t_rw, 0, 0, 0 }, f_toggle, { .i = S_InsEsc } }, -//{ .keyv.c = CONTROL('R'), { t_sel, 0, 0, 0 }, f_findbw, { 0 } }, -//{ .keyv.c = CONTROL('R'), { 0, 0, 0, 0 }, f_spawn, FINDBW }, -{ .keyv.c = CONTROL('R'), { t_redo,t_rw, 0, 0 }, f_undo, { .i = -1 } }, -{ .keyv.c = META('r'), { 0, 0, 0, 0 }, f_findbw, { 0 } }, -{ .keyv.c = CONTROL('S'), { t_sel, 0, 0, 0 }, f_findfw, { 0 } }, -{ .keyv.c = META('s'), { 0, 0, 0, 0 }, f_findfw, { 0 } }, -{ .keyv.c = CONTROL('T'), { 0, 0, 0, 0 }, f_pipero , TOCLIP }, -{ .keyv.c = CONTROL('U'), { t_bol, t_rw, 0, 0 }, f_delete, { .m = m_prevchar } }, -{ .keyv.c = CONTROL('U'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_bol } }, +{ .keyv.c = CONTROL('M'), { t_rw, t_ai, 0, 0 }, f_pipeai, { .v = AUTOINDENT } } , +{ .keyv.c = CONTROL('M'), { t_rw, t_nocomm,0,0 }, f_insert, { .v = "\n" } }, +{ .keyv.c = CONTROL('M'), { 0, 0, 0, 0 }, f_move, { .m = m_nextline } }, +{ .keyv.c = CONTROL('N'), { 0, 0, 0, 0 }, f_move, { .m = m_nextline } }, +{ .keyv.c = CONTROL('O'), { t_sel, 0, 0, 0 }, f_select, { .m = m_tosel } }, /* Swap fsel and fcur */ +{ .keyv.c = CONTROL('P'), { 0, 0, 0, 0 }, f_move, { .m = m_prevline } }, +{ .keyv.c = CONTROL('Q'), { t_rw, 0, 0, 0 }, f_toggle, { .i = S_InsEsc } }, +{ .keyv.c = CONTROL('R'), { t_redo,t_rw, 0, 0 }, f_undo, { .i = -1 } }, +{ .keyv.c = META('r'), { 0, 0, 0, 0 }, f_findbw, { 0 } }, +{ .keyv.c = CONTROL('S'), { t_sel, 0, 0, 0 }, f_findfw, { 0 } }, +{ .keyv.c = META('s'), { 0, 0, 0, 0 }, f_findfw, { 0 } }, +{ .keyv.c = CONTROL('T'), { 0, 0, 0, 0 }, f_pipero , { .v = TOCLIP } }, +{ .keyv.c = CONTROL('U'), { t_bol, t_rw, 0, 0 }, f_delete, { .m = m_prevchar } }, +{ .keyv.c = CONTROL('U'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_bol } }, { .keyv.c = META('u'), { t_sel, t_rw, 0, 0 }, f_pipe, { .v = "tr [a-zàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ] [A-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ] | sed 's/ß/SS/g'" } }, /* Uppercase */ -{ .keyv.c = CONTROL('V'), { 0, 0, 0, 0 }, f_move, { .m = m_prevscr } }, -{ .keyv.c = META('v'), { 0, 0, 0, 0 }, f_move, { .m = m_nextscr } }, -{ .keyv.c = CONTROL('W'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevword } }, -{ .keyv.c = CONTROL('Z'), { 0 ,0, 0, 0 }, f_suspend, { 0 } }, +{ .keyv.c = CONTROL('V'), { 0, 0, 0, 0 }, f_move, { .m = m_prevscr } }, +{ .keyv.c = META('v'), { 0, 0, 0, 0 }, f_move, { .m = m_nextscr } }, +{ .keyv.c = CONTROL('W'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevword } }, +{ .keyv.c = CONTROL('Z'), { 0 ,0, 0, 0 }, f_suspend, { 0 } }, #if VIM_BINDINGS -{ .keyv.c = CONTROL('['), { t_nocomm,0, 0, 0 }, f_toggle, { .i = S_Command } }, +{ .keyv.c = CONTROL('['), { t_nocomm,0, 0, 0 }, f_toggle, { .i = S_Command } }, #endif //{ .keyv.c = CONTROL('['), { 0, 0, 0, 0 }, 0, { 0 } }, -{ .keyv.c = CONTROL('\\'),{ t_rw, 0, 0, 0 }, f_spawn, PIPE }, -{ .keyv.c = META('\\'), { t_rw, 0, 0, 0 }, f_spawn, SED }, -{ .keyv.c = CONTROL(']'), { 0, 0, 0, 0 }, f_extsel, { .i = ExtDefault } }, +{ .keyv.c = CONTROL('\\'),{ t_rw, 0, 0, 0 }, f_spawn, PIPE }, +{ .keyv.c = META('\\'), { t_rw, 0, 0, 0 }, f_spawn, SED }, +{ .keyv.c = CONTROL(']'), { 0, 0, 0, 0 }, f_extsel, { .i = ExtDefault } }, { .keyv.c = META('6'), { t_rw, 0, 0, 0 }, f_pipeline, { .v = "tr '\n' ' '" } }, /* Join lines */ { .keyv.c = META('5'), { t_sel, t_rw, 0, 0 }, f_spawn, REPLACE }, -{ .keyv.c = CONTROL('?'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevchar } }, -{ .keyv.c = META(','), { 0, 0, 0, 0 }, f_move, { .m = m_bof } }, -{ .keyv.c = META('.'), { 0, 0, 0, 0 }, f_move, { .m = m_eof } }, +{ .keyv.c = CONTROL('?'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevchar } }, +{ .keyv.c = META(','), { 0, 0, 0, 0 }, f_move, { .m = m_bof } }, +{ .keyv.c = META('.'), { 0, 0, 0, 0 }, f_move, { .m = m_eof } }, }; #if VIM_BINDINGS /* In order for a key to execute more than 1 function, add consecutive definitions of the key with the exact same tests */ +// TODO: add better paste support (if whole line was yanked, append above, not where you are) static const Key commkeys[] = { /* Command mode keys here */ /* keyv.c, tests, func, arg */ -{ .keyv.c = { '$' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_eol } }, -{ .keyv.c = { '^' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_bol } }, -{ .keyv.c = { 'a' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextchar } }, -{ .keyv.c = { 'a' }, { 0, 0, 0, 0 }, f_toggle, { .i = S_Command } }, -{ .keyv.c = { 'b' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevword } }, -{ .keyv.c = { 'd' }, { t_rw, 0, 0, 0 }, f_delete, { .i = 0 } }, -{ .keyv.c = { 'g' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_bof } }, -{ .keyv.c = { 'G' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_eof } }, -{ .keyv.c = { 'i' }, { 0, 0, 0, 0 }, f_toggle, { .i = S_Command } }, -{ .keyv.c = { 'm' }, { 0, 0, 0, 0 }, f_mark, { 0 } }, -{ .keyv.c = { 'n' }, { t_sel, 0, 0, 0 }, f_findfw, { 0 } }, -{ .keyv.c = { 'N' }, { t_sel, 0, 0, 0 }, f_findbw, { 0 } }, -{ .keyv.c = { 'o' }, { t_rw, 0, 0, 0 }, f_moveboth, { .m = m_eol } }, -{ .keyv.c = { 'o' }, { t_rw, 0, 0, 0 }, f_insert, { .v = "\n" } }, -{ .keyv.c = { 'o' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, -{ .keyv.c = { 'O' }, { t_rw, 0, 0, 0 }, f_moveboth, { .m = m_bol } }, -{ .keyv.c = { 'O' }, { t_rw, 0, 0, 0 }, f_insert, { .v = "\n" } }, -{ .keyv.c = { 'O' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, -// TODO: add better paste support and P -{ .keyv.c = { 'p' }, { t_rw, 0, 0, 0 }, f_pipenull, FROMCLIP }, -{ .keyv.c = { 's' }, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, -{ .keyv.c = { 's' }, { t_sel, t_rw, 0, 0 }, f_toggle, { .i = S_Command } }, -{ .keyv.c = { 's' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, -{ .keyv.c = { 's' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, -{ .keyv.c = { 'u' }, { t_undo,t_rw, 0, 0 }, f_undo, { .i = 1 } }, -{ .keyv.c = { 'w' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextword } }, -{ .keyv.c = { 'x' }, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, -{ .keyv.c = { 'x' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, -{ .keyv.c = { 'X' }, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, -{ .keyv.c = { 'X' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevchar } }, -{ .keyv.c = { ';' }, { 0, 0, 0, 0 }, f_spawn, CMD_P }, -{ .keyv.c = { ':' }, { 0, 0, 0, 0 }, f_spawn, CMD_P }, -{ .keyv.c = { '\'' }, { 0, 0, 0, 0 }, f_move, { .m = m_tomark } }, -{ .keyv.c = { '.' }, { t_rw, 0, 0, 0 }, f_repeat, { 0 } }, -{ .keyv.c = { '/' }, { 0, 0, 0, 0 }, f_spawn, FIND }, -{ .keyv.c = { ' ' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextchar } }, +{ .keyv.c = { '$' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_eol } }, +{ .keyv.c = { '^' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_bol } }, +{ .keyv.c = { 'a' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextchar } }, +{ .keyv.c = { 'a' }, { 0, 0, 0, 0 }, f_toggle, { .i = S_Command } }, +{ .keyv.c = { 'b' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevword } }, +{ .keyv.c = { 'b' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevword } }, +{ .keyv.c = { 'c' }, { t_rw, 0, 0, 0 }, f_delete, { .i = 0 } }, +{ .keyv.c = { 'd' }, { t_rw, 0, 0, 0 }, f_delete, { .i = 0 } }, +{ .keyv.c = { 'g' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_bof } }, +{ .keyv.c = { 'G' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_eof } }, +{ .keyv.c = { 'h' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevchar } }, +{ .keyv.c = { 'h' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevchar } }, +{ .keyv.c = { 'i' }, { 0, 0, 0, 0 }, f_toggle, { .i = S_Command } }, +{ .keyv.c = { 'j' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_nextline } }, +{ .keyv.c = { 'j' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextline } }, +{ .keyv.c = { 'k' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevline } }, +{ .keyv.c = { 'k' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_prevline } }, +{ .keyv.c = { 'l' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_nextchar } }, +{ .keyv.c = { 'l' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextchar } }, +{ .keyv.c = { 'm' }, { 0, 0, 0, 0 }, f_mark, { 0 } }, +{ .keyv.c = { 'n' }, { t_sel, 0, 0, 0 }, f_findfw, { 0 } }, +{ .keyv.c = { 'N' }, { t_sel, 0, 0, 0 }, f_findbw, { 0 } }, +{ .keyv.c = { 'o' }, { t_rw, 0, 0, 0 }, f_moveboth, { .m = m_eol } }, +{ .keyv.c = { 'o' }, { t_rw, 0, 0, 0 }, f_insert, { .v = "\n" } }, +{ .keyv.c = { 'o' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, +{ .keyv.c = { 'O' }, { t_rw, 0, 0, 0 }, f_moveboth, { .m = m_bol } }, +{ .keyv.c = { 'O' }, { t_rw, 0, 0, 0 }, f_insert, { .v = "\n" } }, +{ .keyv.c = { 'O' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, +{ .keyv.c = { 'p' }, { t_rw, 0, 0, 0 }, f_pipenull, { .v = FROMCLIP } }, +{ .keyv.c = { 's' }, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, +{ .keyv.c = { 's' }, { t_sel, t_rw, 0, 0 }, f_toggle, { .i = S_Command } }, +{ .keyv.c = { 's' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, +{ .keyv.c = { 's' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, +{ .keyv.c = { 'u' }, { t_undo,t_rw, 0, 0 }, f_undo, { .i = 1 } }, +{ .keyv.c = { 'w' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_nextword } }, +{ .keyv.c = { 'w' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextword } }, +{ .keyv.c = { 'x' }, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, +{ .keyv.c = { 'x' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, +{ .keyv.c = { 'X' }, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, +{ .keyv.c = { 'X' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevchar } }, +{ .keyv.c = { 'y' }, { t_rw, 0, 0, 0 }, f_pipero, { .i = 0, .v = TOCLIP } }, +{ .keyv.c = { ';' }, { 0, 0, 0, 0 }, f_spawn, CMD_P }, +{ .keyv.c = { ':' }, { 0, 0, 0, 0 }, f_spawn, CMD_P }, +{ .keyv.c = { '\'' }, { 0, 0, 0, 0 }, f_move, { .m = m_tomark } }, +{ .keyv.c = { '.' }, { t_rw, 0, 0, 0 }, f_repeat, { 0 } }, +{ .keyv.c = { '/' }, { 0, 0, 0, 0 }, f_spawn, FIND }, +{ .keyv.c = { ' ' }, { 0, 0, 0, 0 }, f_moveboth, { .m = m_nextchar } }, /* TODO: Keybindings left: - * numbers and arrows do various things (ex. 5s delete the next 5 chars) (adj) - * ^ until bol (adj) * q record macro (?) - * w/W go to next word (adj) - * e/E go to the end of the word (adj) + * e/E go to the end of the word (adj) (?) * r replace char (verb) * t/T do until char (adj) - * y yank things (verb) + * i do inside (adj) (ex. diw deletes current word) * {/} start/end of paragraph (?) - * hjkl movement (adj) - * c replace things (verb) * v visual mode. may not be implemented. - * b go to previous word (adj) - * m set mark (verb) - * ' go to mark (verb) and (adj) * </> ident */ }; @@ -221,8 +227,8 @@ static const Key commkeys[] = { /* Command mode keys here */ static const Click clks[] = { /* mouse mask, fcur / fsel, tests, func, arg */ {BUTTON1_CLICKED, { TRUE , TRUE }, { 0, 0, 0 }, 0, { 0 } }, -{BUTTON3_CLICKED, { TRUE , FALSE }, { t_sel, 0, 0 }, f_pipero, TOSEL }, -{BUTTON2_CLICKED, { FALSE, FALSE }, { 0, 0, 0 }, f_pipenull, FROMSEL }, +{BUTTON3_CLICKED, { TRUE , FALSE }, { t_sel, 0, 0 }, f_pipero, { .v = TOSEL } }, +{BUTTON2_CLICKED, { FALSE, FALSE }, { 0, 0, 0 }, f_pipenull, { .v = FROMSEL } }, //{BUTTON4_CLICKED, { FALSE, FALSE }, { 0, 0, 0 }, f_move, { .m = m_prevscr } }, //{BUTTON5_CLICKED, { FALSE, FALSE }, { 0, 0, 0 }, f_move, { .m = m_nextscr } }, /* ^^ NCurses is a sad old library.... it does not include button 5 nor cursor movement in its mouse declaration by default */ diff --git a/sandy.c b/sandy.c @@ -760,7 +760,6 @@ i_edit(void) { char c[7]; fd_set fds; Filepos oldsel, oldcur; - Arg param = { 0 }; oldsel.l=oldcur.l=fstline; oldsel.o=oldcur.o=0; @@ -855,7 +854,7 @@ i_edit(void) { #if VIM_BINDINGS if(t_rw() && t_nocomm()) f_insert(&(const Arg){ .v = c }); else if(!t_nocomm()) { - if(ch >= '0' && ch <= '9') { + if(ch >= '0' && ch <= '9' && !(statusflags & S_Parameter)) { if(statusflags & S_Multiply) { multiply*=10; multiply+=(int)ch-'0'; @@ -870,10 +869,8 @@ i_edit(void) { /* Handle sentences */ // FIXME: Find a better way to tell if a func is a verb or parameter if(t_sent()) { - if(commkeys[i].func == verb) { - param.m=m_nextline; - verb(&param); - } + if(commkeys[i].func == verb) + verb(&(const Arg){ .m = m_nextline }); if(commkeys[i].func != f_adjective) { statusflags&=~S_Sentence; @@ -888,8 +885,7 @@ i_edit(void) { /* Handle parameter sentences (verb is used here to define the command to execute) */ if(statusflags & S_Parameter) { statusflags&=~S_Parameter; - param.v=c; - verb(&param); + verb(&(const Arg){ .v = c }); break; } else if(commkeys[i].arg.m == 0) { statusflags|=(long)S_Parameter;