config.def.h (27156B)
1 /* A simplified way to customize */ 2 #define USE_TERM_STATUS 1 3 #define BOTTOM_TITLE 0 4 #define HILIGHT_CURRENT 1 5 #define HILIGHT_SYNTAX 1 6 #define SHOW_NONPRINT 0 7 #define HANDLE_MOUSE 1 8 #define VIM_BINDINGS 1 9 10 /* Things unlikely to be changed, yet still in the config.h file */ 11 static const bool isutf8 = TRUE; 12 static const char fifobase[] = "/tmp/sandyfifo."; 13 static int tabstop = 8; /* Not const, as it may be changed via param */ 14 /* static const char systempath[] = "/etc/sandy"; */ 15 /* static const char userpath[] = ".sandy"; */ /* Relative to $HOME */ 16 17 #if SHOW_NONPRINT /* TODO: show newline character too (as $) */ 18 static const char tabstr[3] = { (char)0xC2, (char)0xBB, 0x00 }; /* Double right arrow */ 19 static const char spcstr[3] = { (char)0xC2, (char)0xB7, 0x00 }; /* Middle dot */ 20 static const char nlstr[2] = { '$', 0x00 }; /* '$' is tradition for EOL */ 21 #else 22 static const char tabstr[2] = { ' ', 0 }; 23 static const char spcstr[2] = { ' ', 0 }; 24 static const char nlstr[1] = { 0 }; 25 #endif 26 27 /* Helper config functions, not used in main code */ 28 static void f_pipeai(const Arg*); 29 static void f_pipeline(const Arg*); 30 static void f_pipenull(const Arg*); 31 32 /* Args to f_spawn */ 33 #define PROMPT(prompt, default, cmd) { .v = (const char *[]){ "/bin/sh", "-c", \ 34 "dmenu -v >/dev/null 2>&1 || DISPLAY=\"\";"\ 35 "if [ -n \"$DISPLAY\" ]; then arg=\"`echo \\\"" default "\\\" | dmenu $DMENU_OPTS -p '" prompt "'`\";" \ 36 "else if slmenu -v >/dev/null 2>&1; then arg=\"`echo \\\"" default "\\\" | slmenu -t -p '" prompt "'`\";" \ 37 "else printf \"\033[0;0H\033[7m"prompt"\033[K\033[0m \" >&2; read -r arg; fi; fi &&" \ 38 "echo " cmd "\"$arg\" > ${SANDY_FIFO}", NULL } } 39 40 #define FIND PROMPT("Find:", "${SANDY_FIND}", "/") 41 #define FINDBW PROMPT("Find (back):", "${SANDY_FIND}", "?") 42 #define PIPE PROMPT("Pipe:", "${SANDY_PIPE}", "!") 43 #define SAVEAS PROMPT("Save as:", "${SANDY_FILE}", "w") 44 #define REPLACE PROMPT("Replace:", "", "!echo -n ") 45 #define SED PROMPT("Sed:", "", "!sed ") 46 #define CMD_P PROMPT("Command:", "/\n?\nw\nq\n!\nsyntax\noffset\nicase\nro\nai\ndump", "") 47 48 /* Args to f_pipe and friends, simple examples are inlined instead */ 49 #define TOCLIP "tee /tmp/.sandy.clipboard.$USER | xsel -ib 2>/dev/null" 50 #define FROMCLIP "xsel -ob 2>/dev/null || cat /tmp/.sandy.clipboard.$USER" 51 #define TOSEL "tee /tmp/.sandy.selection.$USER | xsel -i 2>/dev/null" 52 #define FROMSEL "xsel -o 2>/dev/null || cat /tmp/.sandy.selection.$USER" 53 #define AUTOINDENT "awk 'BEGIN{ l=\"\\n\" }; \ 54 { if(match($0, \"^[\t ]+[^\t ]\")) l=substr($0, RSTART, RLENGTH-1); \ 55 else l=\"\"; \ 56 if(FNR==NR && $0 ~ /^[\t ]+$/) print \"\"; \ 57 else print }; \ 58 END{ ORS=\"\"; print l }' 2>/dev/null" 59 #define CAPITALIZE "awk 'BEGIN{ ORS=\"\" }; \ 60 { for ( i=1; i <= NF; i++) { $i=tolower($i) ; sub(\".\", substr(toupper($i),1,1) , $i) } \ 61 if(FNR==NF) print $0; \ 62 else print $0\"\\n\" }' 2>/dev/null" 63 64 /* Hooks are launched from the main code */ 65 #define HOOK_SAVE_NO_FILE f_spawn (&(const Arg)SAVEAS) 66 #undef HOOK_DELETE_ALL /* This affects every delete */ 67 #undef HOOK_SELECT_ALL /* This affects every selection */ 68 69 /* Key-bindings and stuff */ 70 /* WARNING: use CONTROL(ch) ONLY with '@', (caps)A-Z, '[', '\', ']', '^', '_' or '?' */ 71 /* otherwise it may not mean what you think. See man 7 ascii for more info */ 72 #define CONTROL(ch) {(ch ^ 0x40)} 73 #define META(ch) { 0x1B, ch } 74 75 static const Key curskeys[] = { /* Plain keys here, no CONTROL or META */ 76 /* keyv.i, tests, func, arg */ 77 { .keyv.i = KEY_BACKSPACE, { t_rw, t_ins,0, 0 }, f_delete, { .m = m_prevchar } }, 78 { .keyv.i = KEY_BACKSPACE, { 0, 0, 0, 0 }, f_move, { .m = m_prevchar } }, 79 { .keyv.i = KEY_DC, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, 80 { .keyv.i = KEY_DC, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, 81 { .keyv.i = KEY_SDC, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, 82 { .keyv.i = KEY_SDC, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, 83 { .keyv.i = KEY_IC, { t_sel, 0, 0, 0 }, f_pipero, { .v = TOCLIP } }, 84 { .keyv.i = KEY_SIC, { t_rw, 0, 0, 0 }, f_pipenull, { .v = FROMCLIP } }, 85 { .keyv.i = KEY_HOME, { t_ai, 0, 0, 0 }, f_move, { .m = m_smartbol } }, 86 { .keyv.i = KEY_HOME, { 0, 0, 0, 0 }, f_move, { .m = m_bol } }, 87 { .keyv.i = KEY_END, { 0, 0, 0, 0 }, f_move, { .m = m_eol } }, 88 { .keyv.i = KEY_SHOME, { 0, 0, 0, 0 }, f_move, { .m = m_bof } }, 89 { .keyv.i = KEY_SEND, { 0, 0, 0, 0 }, f_move, { .m = m_eof } }, 90 { .keyv.i = KEY_PPAGE, { 0, 0, 0, 0 }, f_move, { .m = m_prevscr } }, 91 { .keyv.i = KEY_NPAGE, { 0, 0, 0, 0 }, f_move, { .m = m_nextscr } }, 92 { .keyv.i = KEY_UP, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevline } }, 93 { .keyv.i = KEY_UP, { 0, 0, 0, 0 }, f_move, { .m = m_prevline } }, 94 { .keyv.i = KEY_DOWN, { t_sent,0, 0, 0 }, f_adjective, { .m = m_nextline } }, 95 { .keyv.i = KEY_DOWN, { 0, 0, 0, 0 }, f_move, { .m = m_nextline } }, 96 { .keyv.i = KEY_LEFT, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevchar } }, 97 { .keyv.i = KEY_LEFT, { 0, 0, 0, 0 }, f_move, { .m = m_prevchar } }, 98 { .keyv.i = KEY_RIGHT, { t_sent,0, 0, 0 }, f_adjective, { .m = m_nextchar } }, 99 { .keyv.i = KEY_RIGHT, { 0, 0, 0, 0 }, f_move, { .m = m_nextchar } }, 100 { .keyv.i = KEY_SLEFT, { 0, 0, 0, 0 }, f_move, { .m = m_prevword } }, 101 { .keyv.i = KEY_SRIGHT, { 0, 0, 0, 0 }, f_move, { .m = m_nextword } }, 102 }; 103 104 static const Key stdkeys[] = { 105 /* keyv.c, test, func, arg */ 106 { .keyv.c = CONTROL('@'), { 0, 0, 0, 0 }, f_move, { .m = m_tomark } }, 107 { .keyv.c = META(' '), { 0, 0, 0, 0 }, f_mark, { 0 } }, 108 { .keyv.c = META('`'), { 0, 0, 0, 0 }, f_mark, { 0 } }, 109 { .keyv.c = CONTROL('A'), { t_ai, 0, 0, 0 }, f_move, { .m = m_smartbol } }, 110 { .keyv.c = CONTROL('A'), { 0, 0, 0, 0 }, f_move, { .m = m_bol } }, 111 { .keyv.c = CONTROL('B'), { 0, 0, 0, 0 }, f_move, { .m = m_prevchar } }, 112 { .keyv.c = META('b'), { 0, 0, 0, 0 }, f_move, { .m = m_prevword } }, 113 { .keyv.c = CONTROL('C'), { t_warn,t_mod,0, 0 }, f_toggle, { .i = S_Running } }, 114 { .keyv.c = CONTROL('C'), { t_mod, 0, 0, 0 }, f_toggle, { .i = S_Warned } }, 115 { .keyv.c = CONTROL('C'), { 0, 0, 0, 0 }, f_toggle, { .i = S_Running } }, 116 { .keyv.c = META('c'), { t_sel, t_rw, 0, 0 }, f_pipe, { .v = CAPITALIZE } }, 117 { .keyv.c = CONTROL('D'), { t_sel, t_rw, 0, 0 }, f_pipe, { .v = TOCLIP } }, 118 { .keyv.c = CONTROL('D'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, 119 { .keyv.c = META('d'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextword } }, 120 { .keyv.c = CONTROL('E'), { 0, 0, 0, 0 }, f_move, { .m = m_eol } }, 121 { .keyv.c = CONTROL('F'), { 0, 0, 0, 0 }, f_move, { .m = m_nextchar } }, 122 { .keyv.c = META('f'), { 0, 0, 0, 0 }, f_move, { .m = m_nextword } }, 123 { .keyv.c = CONTROL('G'), { t_sel, 0, 0, 0 }, f_select, { .m = m_stay } }, 124 { .keyv.c = CONTROL('H'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevchar } }, 125 { .keyv.c = CONTROL('I'), { t_rw, t_ins,0, 0 }, f_insert, { .v = "\t" } }, 126 { .keyv.c = CONTROL('J'), { t_rw, t_ai, 0, 0 }, f_pipeai, { .v = AUTOINDENT } }, 127 { .keyv.c = CONTROL('J'), { t_rw, t_ins,0, 0 }, f_insert, { .v = "\n" } }, 128 { .keyv.c = CONTROL('J'), { 0, 0, 0, 0 }, f_move, { .m = m_nextline } }, 129 { .keyv.c = CONTROL('K'), { t_eol, t_rw, 0, 0 }, f_delete, { .m = m_nextchar } }, 130 { .keyv.c = CONTROL('K'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_eol } }, 131 { .keyv.c = CONTROL('L'), { 0, 0, 0, 0 }, f_center, { 0 } }, 132 { .keyv.c = META('l'), { t_sel, t_rw, 0, 0 }, f_pipe, { .v = "tr [A-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ] [a-zàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ]" } }, /* Lowercase */ 133 { .keyv.c = CONTROL('M'), { t_rw, t_ai, 0, 0 }, f_pipeai, { .v = AUTOINDENT } } , 134 { .keyv.c = CONTROL('M'), { t_rw, t_ins,0, 0 }, f_insert, { .v = "\n" } }, 135 { .keyv.c = CONTROL('M'), { 0, 0, 0, 0 }, f_move, { .m = m_nextline } }, 136 { .keyv.c = CONTROL('N'), { 0, 0, 0, 0 }, f_move, { .m = m_nextline } }, 137 { .keyv.c = CONTROL('O'), { t_sel, 0, 0, 0 }, f_select, { .m = m_tosel } }, /* Swap fsel and fcur */ 138 { .keyv.c = CONTROL('P'), { 0, 0, 0, 0 }, f_move, { .m = m_prevline } }, 139 { .keyv.c = CONTROL('Q'), { t_rw, 0, 0, 0 }, f_toggle, { .i = S_InsEsc } }, 140 { .keyv.c = CONTROL('R'), { t_redo,t_rw, 0, 0 }, f_undo, { .i = -1 } }, 141 { .keyv.c = META('r'), { 0, 0, 0, 0 }, f_findbw, { 0 } }, 142 { .keyv.c = CONTROL('S'), { t_sel, 0, 0, 0 }, f_findfw, { 0 } }, 143 { .keyv.c = CONTROL('S'), { 0, 0, 0, 0 }, f_spawn, FIND }, 144 { .keyv.c = META('s'), { 0, 0, 0, 0 }, f_findfw, { 0 } }, 145 { .keyv.c = CONTROL('T'), { 0, 0, 0, 0 }, f_pipero , { .v = TOCLIP } }, 146 { .keyv.c = CONTROL('U'), { t_bol, t_rw, 0, 0 }, f_delete, { .m = m_prevchar } }, 147 { .keyv.c = CONTROL('U'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_bol } }, 148 { .keyv.c = META('u'), { t_sel, t_rw, 0, 0 }, f_pipe, { .v = "tr [a-zàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ] [A-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ] | sed 's/ß/SS/g'" } }, /* Uppercase */ 149 { .keyv.c = CONTROL('V'), { 0, 0, 0, 0 }, f_move, { .m = m_prevscr } }, 150 { .keyv.c = META('v'), { 0, 0, 0, 0 }, f_move, { .m = m_nextscr } }, 151 { .keyv.c = CONTROL('W'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevword } }, 152 { .keyv.c = CONTROL('X'), { t_mod, t_rw, 0, 0 }, f_save, { 0 } }, 153 { .keyv.c = CONTROL('X'), { 0, 0, 0, 0 }, f_toggle, { .i = S_Running } }, 154 { .keyv.c = META('x'), { 0, 0, 0, 0 }, f_spawn, CMD_P }, 155 { .keyv.c = CONTROL('Y'), { t_rw, 0, 0, 0 }, f_pipenull, { .v = FROMCLIP } }, 156 { .keyv.c = CONTROL('Z'), { 0, 0, 0, 0 }, f_suspend, { 0 } }, 157 { .keyv.c = CONTROL('['), { t_vis, 0, 0, 0 }, f_toggle, { .i = S_Visual } }, 158 #if VIM_BINDINGS 159 { .keyv.c = CONTROL('['), { t_ins, 0, 0, 0 }, f_toggle, { .i = S_Command } }, 160 #else 161 { .keyv.c = CONTROL('['), { 0, 0, 0, 0 }, f_spawn, CMD_P }, 162 #endif 163 { .keyv.c = CONTROL('\\'),{ t_rw, 0, 0, 0 }, f_spawn, PIPE }, 164 { .keyv.c = META('\\'), { t_rw, 0, 0, 0 }, f_spawn, SED }, 165 { .keyv.c = CONTROL(']'), { 0, 0, 0, 0 }, f_extsel, { .i = ExtDefault } }, 166 { .keyv.c = CONTROL('^'), { t_redo,t_rw, 0, 0 }, f_undo, { .i = -1 } }, 167 { .keyv.c = CONTROL('^'), { t_rw, 0, 0, 0 }, f_repeat, { 0 } }, 168 { .keyv.c = META('6'), { t_rw, 0, 0, 0 }, f_pipeline, { .v = "tr '\n' ' '" } }, /* Join lines */ 169 { .keyv.c = META('5'), { t_sel, t_rw, 0, 0 }, f_spawn, REPLACE }, 170 { .keyv.c = CONTROL('?'), { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevchar } }, 171 { .keyv.c = META(','), { 0, 0, 0, 0 }, f_move, { .m = m_bof } }, 172 { .keyv.c = META('.'), { 0, 0, 0, 0 }, f_move, { .m = m_eof } }, 173 }; 174 175 #if VIM_BINDINGS 176 /* TODO: add better paste support (if whole line was yanked, append above, 177 * not where you are) */ 178 static const Key commkeys[] = { /* Command mode keys here */ 179 /* keyv.c, tests, func, arg */ 180 { .keyv.c = { '$' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_eol } }, 181 { .keyv.c = { '$' }, { 0, 0, 0, 0 }, f_move, { .m = m_eol } }, 182 { .keyv.c = { '^' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_bol } }, 183 { .keyv.c = { '^' }, { 0, 0, 0, 0 }, f_move, { .m = m_bol } }, 184 { .keyv.c = { 'A' }, { 0, 0, 0, 0 }, f_move, { .m = m_eol } }, 185 { .keyv.c = { 'A' }, { 0, 0, 0, 0 }, f_toggle, { .i = S_Command } }, 186 { .keyv.c = { 'a' }, { t_eol, 0, 0, 0 }, f_toggle, { .i = S_Command } }, 187 { .keyv.c = { 'a' }, { 0, 0, 0, 0 }, f_move, { .m = m_nextchar } }, 188 { .keyv.c = { 'a' }, { 0, 0, 0, 0 }, f_toggle, { .i = S_Command } }, 189 { .keyv.c = { 'b' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevword } }, 190 { .keyv.c = { 'b' }, { 0, 0, 0, 0 }, f_move, { .m = m_prevword } }, 191 { .keyv.c = { 'c' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_sentence } }, 192 { .keyv.c = { 'c' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, 193 { .keyv.c = { 'C' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_eol } }, 194 { .keyv.c = { 'C' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, 195 { .keyv.c = { 'd' }, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, 196 { .keyv.c = { 'd' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_sentence } }, 197 /*{ .keyv.c = { 'd' }, { t_rw, 0, 0, 0 }, f_pipe, { .m = m_sentence, .v = TOCLIP } }, */ 198 { .keyv.c = { 'D' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_eol } }, 199 { .keyv.c = { 'g' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_bof } }, 200 { .keyv.c = { 'g' }, { 0, 0, 0, 0 }, f_move, { .m = m_bof } }, 201 { .keyv.c = { 'G' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_eof } }, 202 { .keyv.c = { 'G' }, { 0, 0, 0, 0 }, f_move, { .m = m_eof } }, 203 { .keyv.c = { 'h' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevchar } }, 204 { .keyv.c = { 'h' }, { 0, 0, 0, 0 }, f_move, { .m = m_prevchar } }, 205 { .keyv.c = { 'i' }, { 0, 0, 0, 0 }, f_toggle, { .i = S_Command } }, 206 { .keyv.c = { 'j' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_nextline } }, 207 { .keyv.c = { 'j' }, { 0, 0, 0, 0 }, f_move, { .m = m_nextline } }, 208 { .keyv.c = { 'k' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevline } }, 209 { .keyv.c = { 'k' }, { 0, 0, 0, 0 }, f_move, { .m = m_prevline } }, 210 { .keyv.c = { 'l' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_nextchar } }, 211 { .keyv.c = { 'l' }, { 0, 0, 0, 0 }, f_move, { .m = m_nextchar } }, 212 { .keyv.c = { 'm' }, { 0, 0, 0, 0 }, f_mark, { .i = 0 } }, 213 { .keyv.c = { 'n' }, { 0, 0, 0, 0 }, f_findfw, { .i = 0 } }, 214 { .keyv.c = { 'N' }, { 0, 0, 0, 0 }, f_findbw, { .i = 0 } }, 215 { .keyv.c = { 'o' }, { t_rw, t_ai, 0, 0 }, f_move, { .m = m_eol } }, 216 { .keyv.c = { 'o' }, { t_rw, t_ai, 0, 0 }, f_pipeai, { .v = AUTOINDENT } }, 217 { .keyv.c = { 'o' }, { t_rw, t_ai, 0, 0 }, f_toggle, { .i = S_Command } }, 218 { .keyv.c = { 'o' }, { t_rw, 0, 0, 0 }, f_move, { .m = m_eol } }, 219 { .keyv.c = { 'o' }, { t_rw, 0, 0, 0 }, f_insert, { .v = "\n" } }, 220 { .keyv.c = { 'o' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, 221 { .keyv.c = { 'O' }, { t_rw, t_ai, 0, 0 }, f_move, { .m = m_bol } }, 222 { .keyv.c = { 'O' }, { t_rw, t_ai, 0, 0 }, f_pipeai, { .v = AUTOINDENT } }, 223 { .keyv.c = { 'O' }, { t_rw, t_ai, 0, 0 }, f_move, { .m = m_prevline } }, 224 { .keyv.c = { 'O' }, { t_rw, t_ai, 0, 0 }, f_toggle, { .i = S_Command } }, 225 { .keyv.c = { 'O' }, { t_rw, 0, 0, 0 }, f_move, { .m = m_bol } }, 226 { .keyv.c = { 'O' }, { t_rw, 0, 0, 0 }, f_insert, { .v = "\n" } }, 227 { .keyv.c = { 'O' }, { t_rw, 0, 0, 0 }, f_move, { .m = m_prevline } }, 228 { .keyv.c = { 'O' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, 229 { .keyv.c = { 'p' }, { t_rw, 0, 0, 0 }, f_pipenull, { .v = FROMCLIP } }, 230 { .keyv.c = { 's' }, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, 231 { .keyv.c = { 's' }, { t_sel, t_rw, 0, 0 }, f_toggle, { .i = S_Command } }, 232 { .keyv.c = { 's' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, 233 { .keyv.c = { 's' }, { t_rw, 0, 0, 0 }, f_toggle, { .i = S_Command } }, 234 { .keyv.c = { 'u' }, { t_undo,t_rw, 0, 0 }, f_undo, { .i = 1 } }, 235 { .keyv.c = { 'v' }, { 0, 0, 0, 0 }, f_toggle, { .i = S_Visual } }, 236 { .keyv.c = { 'w' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_nextword } }, 237 { .keyv.c = { 'w' }, { 0, 0, 0, 0 }, f_move, { .m = m_nextword } }, 238 { .keyv.c = { 'x' }, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, 239 { .keyv.c = { 'x' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_nextchar } }, 240 { .keyv.c = { 'X' }, { t_sel, t_rw, 0, 0 }, f_delete, { .m = m_tosel } }, 241 { .keyv.c = { 'X' }, { t_rw, 0, 0, 0 }, f_delete, { .m = m_prevchar } }, 242 /* TODO: won't work since Arg is a union */ 243 /*{ .keyv.c = { 'y' }, { t_rw, 0, 0, 0 }, f_pipero, { .m = m_sentence, .v = TOCLIP } },*/ 244 { .keyv.c = { 'y' }, { t_rw, 0, 0, 0 }, f_pipero, { .v = TOCLIP } }, 245 { .keyv.c = { ';' }, { 0, 0, 0, 0 }, f_spawn, CMD_P }, 246 { .keyv.c = { ':' }, { 0, 0, 0, 0 }, f_spawn, CMD_P }, 247 { .keyv.c = { '\'' }, { 0, 0, 0, 0 }, f_move, { .m = m_tomark } }, 248 { .keyv.c = { '.' }, { t_rw, 0, 0, 0 }, f_repeat, { 0 } }, 249 { .keyv.c = { '/' }, { 0, 0, 0, 0 }, f_spawn, FIND }, 250 { .keyv.c = { ' ' }, { 0, 0, 0, 0 }, f_move, { .m = m_nextchar } }, 251 /* TODO: Keybindings left: 252 * e/E go to the end of the word (adj) (?) 253 * r replace char (verb) 254 * t/T do until char (adj) 255 * i do inside (adj) (ex. diw deletes current word) 256 * </> ident 257 */ 258 }; 259 #endif 260 261 #if HANDLE_MOUSE 262 /*Mouse clicks */ 263 static const Click clks[] = { 264 /* mouse mask, fcur / fsel, tests, func, arg */ 265 {BUTTON1_CLICKED, { TRUE , TRUE }, { 0, 0, 0 }, 0, { 0 } }, 266 {BUTTON3_CLICKED, { TRUE , FALSE }, { t_sel, 0, 0 }, f_pipero, { .v = TOSEL } }, 267 {BUTTON2_CLICKED, { FALSE, FALSE }, { t_rw, 0, 0 }, f_pipenull, { .v = FROMSEL } }, 268 {BUTTON4_CLICKED, { FALSE, FALSE }, { 0, 0, 0 }, f_move, { .m = m_prevscr } }, 269 #ifdef BUTTON5_CLICKED 270 {BUTTON5_CLICKED, { FALSE, FALSE }, { 0, 0, 0 }, f_move, { .m = m_nextscr } }, 271 #endif 272 /* ^^ NCurses is a sad old library.... it does not include button 5 nor 273 * cursor movement in its mouse declaration by default */ 274 {BUTTON1_DOUBLE_CLICKED, { TRUE , TRUE }, { 0, 0, 0 }, f_extsel, { .i = ExtWord } }, 275 {BUTTON1_TRIPLE_CLICKED, { TRUE , TRUE }, { 0, 0, 0 }, f_extsel, { .i = ExtLines } }, 276 }; 277 #endif /* HANDLE_MOUSE */ 278 279 /* Commands read at the fifo */ 280 static const Command cmds[] = { /* REMEMBER: if(arg == 0) arg.v=regex_match */ 281 /* regex, tests, func arg */ 282 {"^([0-9]+)$", { 0, 0, 0 }, f_line , { 0 } }, 283 {"^/(.*)$", { 0, 0, 0 }, f_findfw, { 0 } }, 284 {"^\\?(.*)$", { 0, 0, 0 }, f_findbw, { 0 } }, 285 {"^![ \t]*(.*)$", { t_rw, 0, 0 }, f_pipe, { 0 } }, 286 {"^![ /t]*(.*)$", { 0, 0, 0 }, f_pipero, { 0 } }, 287 {"^w[ \t]*(.*)$", { t_mod, t_rw, 0 }, f_save, { 0 } }, 288 {"^syntax (.*)$", { 0, 0, 0 }, f_syntax, { 0 } }, 289 {"^offset (.*)$", { 0, 0, 0 }, f_offset, { 0 } }, 290 {"^icase$", { 0, 0, 0 }, f_toggle, { .i = S_CaseIns } }, 291 {"^ro$", { 0, 0, 0 }, f_toggle, { .i = S_Readonly } }, 292 {"^ai$", { 0, 0, 0 }, f_toggle, { .i = S_AutoIndent } }, 293 {"^dump$", { 0, 0, 0 }, f_toggle, { .i = S_DumpStdout } }, 294 {"^q$", { t_mod, 0, 0 }, f_toggle, { .i = S_Warned } }, 295 {"^q$", { 0, 0, 0 }, f_toggle, { .i = S_Running } }, 296 {"^q!$", { 0, 0, 0 }, f_toggle, { .i = S_Running } }, 297 }; 298 299 /* Syntax color definition */ 300 #define B "\\b" 301 /* #define B "^| |\t|\\(|\\)|\\[|\\]|\\{|\\}|\\||$" -- Use this if \b is not in your libc's regex implementation */ 302 303 static const Syntax syntaxes[] = { 304 #if HILIGHT_SYNTAX 305 {"c", "\\.([ch](pp|xx)?|cc)$", { 306 /* HiRed */ "$^", 307 /* HiGreen */ B"(for|if|while|do|else|case|default|switch|try|throw|catch|operator|new|delete)"B, 308 /* LoGreen */ B"(float|double|bool|char|int|short|long|sizeof|enum|void|static|const|struct|union|typedef|extern|(un)?signed|inline|((s?size)|((u_?)?int(8|16|32|64|ptr)))_t|class|namespace|template|public|protected|private|typename|this|friend|virtual|using|mutable|volatile|register|explicit)"B, 309 /* HiMag */ B"(goto|continue|break|return)"B, 310 /* LoMag */ "(^#(define|include(_next)?|(un|ifn?)def|endif|el(if|se)|if|warning|error|pragma))|"B"[A-Z_][0-9A-Z_]+"B"", 311 /* HiBlue */ "(\\(|\\)|\\{|\\}|\\[|\\])", 312 /* LoRed */ "(\"(\\\\.|[^\"])*\")", 313 /* LoBlue */ "(//.*|/\\*([^*]|\\*[^/])*\\*/|/\\*([^*]|\\*[^/])*$|^([^/]|/[^*])*\\*/)", 314 } }, 315 316 {"sh", "\\.sh$", { 317 /* HiRed */ "$^", 318 /* HiGreen */ "^[0-9A-Z_]+\\(\\)", 319 /* LoGreen */ B"(case|do|done|elif|else|esac|exit|fi|for|function|if|in|local|read|return|select|shift|then|time|until|while)"B, 320 /* HiMag */ "$^", 321 /* LoMag */ "\"(\\\\.|[^\"])*\"", 322 /* HiBlue */ "(\\{|\\}|\\(|\\)|\\;|\\]|\\[|`|\\\\|\\$|<|>|!|=|&|\\|)", 323 /* LoRed */ "\\$\\{?[0-9A-Z_!@#$*?-]+\\}?", 324 /* LoBlue */ "#.*$", 325 } }, 326 327 {"makefile", "(Makefile[^/]*|\\.mk)$", { 328 /* HiRed */ "$^", 329 /* HiGreen */ "$^", 330 /* LoGreen */ "\\$+[{(][a-zA-Z0-9_-]+[})]", 331 /* HiMag */ B"(if|ifeq|else|endif)"B, 332 /* LoMag */ "$^", 333 /* HiBlue */ "^[^ ]+:", 334 /* LoRed */ "[:=]", 335 /* LoBlue */ "#.*$", 336 } }, 337 338 {"man", "\\.[1-9]x?$", { 339 /* HiRed */ "\\.(BR?|I[PR]?).*$", 340 /* HiGreen */ "$^", 341 /* LoGreen */ "\\.(S|T)H.*$", 342 /* HiMag */ "\\.(br|DS|RS|RE|PD)", 343 /* LoMag */ "(\\.(S|T)H|\\.TP)", 344 /* HiBlue */ "\\.(BR?|I[PR]?|PP)", 345 /* LoRed */ "$^", 346 /* LoBlue */ "\\\\f[BIPR]", 347 } }, 348 349 {"vala", "\\.(vapi|vala)$", { 350 /* HiRed */ B"[A-Z_][0-9A-Z_]+"B, 351 /* HiGreen */ B"(for|if|while|do|else|case|default|switch|get|set|value|out|ref|enum)"B, 352 /* LoGreen */ B"(uint|uint8|uint16|uint32|uint64|bool|byte|ssize_t|size_t|char|double|string|float|int|long|short|this|base|transient|void|true|false|null|unowned|owned)"B, 353 /* HiMag */ B"(try|catch|throw|finally|continue|break|return|new|sizeof|signal|delegate)"B, 354 /* LoMag */ B"(abstract|class|final|implements|import|instanceof|interface|using|private|public|static|strictfp|super|throws)"B, 355 /* HiBlue */ "(\\(|\\)|\\{|\\}|\\[|\\])", 356 /* LoRed */ "\"(\\\\.|[^\"])*\"", 357 /* LoBlue */ "(//.*|/\\*([^*]|\\*[^/])*\\*/|/\\*([^*]|\\*[^/])*$|^([^/]|/[^*])*\\*/)", 358 } }, 359 {"java", "\\.java$", { 360 /* HiRed */ B"[A-Z_][0-9A-Z_]+"B, 361 /* HiGreen */ B"(for|if|while|do|else|case|default|switch)"B, 362 /* LoGreen */ B"(boolean|byte|char|double|float|int|long|short|transient|void|true|false|null)"B, 363 /* HiMag */ B"(try|catch|throw|finally|continue|break|return|new)"B, 364 /* LoMag */ B"(abstract|class|extends|final|implements|import|instanceof|interface|native|package|private|protected|public|static|strictfp|this|super|synchronized|throws|volatile)"B, 365 /* HiBlue */ "(\\(|\\)|\\{|\\}|\\[|\\])", 366 /* LoRed */ "\"(\\\\.|[^\"])*\"", 367 /* LoBlue */ "(//.*|/\\*([^*]|\\*[^/])*\\*/|/\\*([^*]|\\*[^/])*$|^([^/]|/[^*])*\\*/)", 368 } }, 369 {"ruby", "\\.rb$", { 370 /* HiRed */ "(\\$|@|@@)?"B"[A-Z]+[0-9A-Z_a-z]*", 371 /* HiGreen */ B"(__FILE__|__LINE__|BEGIN|END|alias|and|begin|break|case|class|def|defined\?|do|else|elsif|end|ensure|false|for|if|in|module|next|nil|not|or|redo|rescue|retry|return|self|super|then|true|undef|unless|until|when|while|yield)"B, 372 /* LoGreen */ "([ ]|^):[0-9A-Z_]+"B, 373 /* HiMag */ "(/([^/]|(\\/))*/[iomx]*|%r\\{([^}]|(\\}))*\\}[iomx]*)", 374 /* LoMag */ "(`[^`]*`|%x\\{[^}]*\\})", 375 /* HiBlue */ "(\"([^\"]|(\\\\\"))*\"|%[QW]?\\{[^}]*\\}|%[QW]?\\([^)]*\\)|%[QW]?<[^>]*>|%[QW]?\\[[^]]*\\]|%[QW]?\\$[^$]*\\$|%[QW]?\\^[^^]*\\^|%[QW]?![^!]*!|\'([^\']|(\\\\\'))*\'|%[qw]\\{[^}]*\\}|%[qw]\\([^)]*\\)|%[qw]<[^>]*>|%[qw]\\[[^]]*\\]|%[qw]\\$[^$]*\\$|%[qw]\\^[^^]*\\^|%[qw]![^!]*!)", 376 /* LoRed */ "#\\{[^}]*\\}", 377 /* LoBlue */ "(#[^{].*$|#$)", 378 } }, 379 #else /* HILIGHT_SYNTAX */ 380 {"", "\0", { "\0", "\0", "\0", "\0", "\0", "\0", "\0", "\0" } } 381 #endif /* HILIGHT_SYNTAX */ 382 }; 383 384 /* Colors */ 385 static const short fgcolors[LastFG] = { 386 [DefFG] = -1, 387 [CurFG] = (HILIGHT_CURRENT?COLOR_BLACK : -1), 388 [SelFG] = COLOR_BLACK, 389 [SpcFG] = COLOR_WHITE, 390 [CtrlFG] = COLOR_RED, 391 [Syn0FG] = COLOR_RED, 392 [Syn1FG] = COLOR_GREEN, 393 [Syn2FG] = COLOR_GREEN, 394 [Syn3FG] = COLOR_MAGENTA, 395 [Syn4FG] = COLOR_MAGENTA, 396 [Syn5FG] = COLOR_BLUE, 397 [Syn6FG] = COLOR_RED, 398 [Syn7FG] = COLOR_BLUE, 399 }; 400 401 static const int colorattrs[LastFG] = { 402 [DefFG] = 0, 403 [CurFG] = 0, 404 [SelFG] = 0, 405 [SpcFG] = A_DIM, 406 [CtrlFG] = A_DIM, 407 [Syn0FG] = A_BOLD, 408 [Syn1FG] = A_BOLD, 409 [Syn2FG] = 0, 410 [Syn3FG] = A_BOLD, 411 [Syn4FG] = 0, 412 [Syn5FG] = A_BOLD, 413 [Syn6FG] = 0, 414 [Syn7FG] = 0, 415 }; 416 417 static const int bwattrs[LastFG] = { 418 [DefFG] = 0, 419 [CurFG] = 0, 420 [SelFG] = A_REVERSE, 421 [SpcFG] = A_DIM, 422 [CtrlFG] = A_DIM, 423 [Syn0FG] = A_BOLD, 424 [Syn1FG] = A_BOLD, 425 [Syn2FG] = A_BOLD, 426 [Syn3FG] = A_BOLD, 427 [Syn4FG] = A_BOLD, 428 [Syn5FG] = A_BOLD, 429 [Syn6FG] = A_BOLD, 430 [Syn7FG] = A_BOLD, 431 }; 432 433 static const short bgcolors[LastBG] = { 434 [DefBG] = -1, 435 [CurBG] = (HILIGHT_CURRENT ? COLOR_CYAN : -1), 436 [SelBG] = COLOR_YELLOW, 437 }; 438 439 /* Helper config functions implementation */ 440 void /* Pipe selection from bol, then select last line only, special for autoindenting */ 441 f_pipeai(const Arg *arg) { 442 i_sortpos(&fsel, &fcur); 443 fsel.o = 0; 444 f_pipe(arg); 445 fsel = fcur; 446 } 447 448 void /* Pipe full lines including the selection */ 449 f_pipeline(const Arg *arg) { 450 f_extsel(&(const Arg){ .i = ExtLines }); 451 f_pipe(arg); 452 } 453 454 void /* Pipe empty text */ 455 f_pipenull(const Arg *arg) { 456 fsel = fcur; 457 f_pipe(arg); 458 }