1*eda6f593SDavid van Moolenbroek /* $Id: mode-key.c,v 1.1.1.2 2011/08/17 18:40:05 jmmv Exp $ */ 2*eda6f593SDavid van Moolenbroek 3*eda6f593SDavid van Moolenbroek /* 4*eda6f593SDavid van Moolenbroek * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> 5*eda6f593SDavid van Moolenbroek * 6*eda6f593SDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any 7*eda6f593SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above 8*eda6f593SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies. 9*eda6f593SDavid van Moolenbroek * 10*eda6f593SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11*eda6f593SDavid van Moolenbroek * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12*eda6f593SDavid van Moolenbroek * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13*eda6f593SDavid van Moolenbroek * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14*eda6f593SDavid van Moolenbroek * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15*eda6f593SDavid van Moolenbroek * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16*eda6f593SDavid van Moolenbroek * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17*eda6f593SDavid van Moolenbroek */ 18*eda6f593SDavid van Moolenbroek 19*eda6f593SDavid van Moolenbroek #include <sys/types.h> 20*eda6f593SDavid van Moolenbroek 21*eda6f593SDavid van Moolenbroek #include <string.h> 22*eda6f593SDavid van Moolenbroek 23*eda6f593SDavid van Moolenbroek #include "tmux.h" 24*eda6f593SDavid van Moolenbroek 25*eda6f593SDavid van Moolenbroek /* 26*eda6f593SDavid van Moolenbroek * Mode keys. These are the key bindings used when editing (status prompt), and 27*eda6f593SDavid van Moolenbroek * in the modes. They are split into two sets of three tables, one set of three 28*eda6f593SDavid van Moolenbroek * for vi and the other for emacs key bindings. The three tables are for 29*eda6f593SDavid van Moolenbroek * editing, for menu-like modes (choice, more), and for copy modes (copy, 30*eda6f593SDavid van Moolenbroek * scroll). 31*eda6f593SDavid van Moolenbroek * 32*eda6f593SDavid van Moolenbroek * The fixed tables of struct mode_key_entry below are the defaults: they are 33*eda6f593SDavid van Moolenbroek * built into a tree of struct mode_key_binding by mode_key_init_trees, which 34*eda6f593SDavid van Moolenbroek * can then be modified. 35*eda6f593SDavid van Moolenbroek * 36*eda6f593SDavid van Moolenbroek * vi command mode is handled by having a mode flag in the struct which allows 37*eda6f593SDavid van Moolenbroek * two sets of bindings to be swapped between. A couple of editing commands 38*eda6f593SDavid van Moolenbroek * (MODEKEYEDIT_SWITCHMODE and MODEKEYEDIT_SWITCHMODEAPPEND) are special-cased 39*eda6f593SDavid van Moolenbroek * to do this. 40*eda6f593SDavid van Moolenbroek */ 41*eda6f593SDavid van Moolenbroek 42*eda6f593SDavid van Moolenbroek /* Edit keys command strings. */ 43*eda6f593SDavid van Moolenbroek const struct mode_key_cmdstr mode_key_cmdstr_edit[] = { 44*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_BACKSPACE, "backspace" }, 45*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_CANCEL, "cancel" }, 46*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_COMPLETE, "complete" }, 47*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_CURSORLEFT, "cursor-left" }, 48*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_CURSORRIGHT, "cursor-right" }, 49*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_DELETE, "delete" }, 50*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_DELETELINE, "delete-line" }, 51*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_DELETETOENDOFLINE, "delete-end-of-line" }, 52*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_ENDOFLINE, "end-of-line" }, 53*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_ENTER, "enter" }, 54*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_HISTORYDOWN, "history-down" }, 55*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_HISTORYUP, "history-up" }, 56*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_PASTE, "paste" }, 57*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_STARTOFLINE, "start-of-line" }, 58*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_SWITCHMODE, "switch-mode" }, 59*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_SWITCHMODEAPPEND, "switch-mode-append" }, 60*eda6f593SDavid van Moolenbroek { MODEKEYEDIT_TRANSPOSECHARS, "transpose-chars" }, 61*eda6f593SDavid van Moolenbroek 62*eda6f593SDavid van Moolenbroek { 0, NULL } 63*eda6f593SDavid van Moolenbroek }; 64*eda6f593SDavid van Moolenbroek 65*eda6f593SDavid van Moolenbroek /* Choice keys command strings. */ 66*eda6f593SDavid van Moolenbroek const struct mode_key_cmdstr mode_key_cmdstr_choice[] = { 67*eda6f593SDavid van Moolenbroek { MODEKEYCHOICE_CANCEL, "cancel" }, 68*eda6f593SDavid van Moolenbroek { MODEKEYCHOICE_CHOOSE, "choose" }, 69*eda6f593SDavid van Moolenbroek { MODEKEYCHOICE_DOWN, "down" }, 70*eda6f593SDavid van Moolenbroek { MODEKEYCHOICE_PAGEDOWN, "page-down" }, 71*eda6f593SDavid van Moolenbroek { MODEKEYCHOICE_PAGEUP, "page-up" }, 72*eda6f593SDavid van Moolenbroek { MODEKEYCHOICE_SCROLLDOWN, "scroll-down" }, 73*eda6f593SDavid van Moolenbroek { MODEKEYCHOICE_SCROLLUP, "scroll-up" }, 74*eda6f593SDavid van Moolenbroek { MODEKEYCHOICE_UP, "up" }, 75*eda6f593SDavid van Moolenbroek 76*eda6f593SDavid van Moolenbroek { 0, NULL } 77*eda6f593SDavid van Moolenbroek }; 78*eda6f593SDavid van Moolenbroek 79*eda6f593SDavid van Moolenbroek /* Copy keys command strings. */ 80*eda6f593SDavid van Moolenbroek const struct mode_key_cmdstr mode_key_cmdstr_copy[] = { 81*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_BACKTOINDENTATION, "back-to-indentation" }, 82*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_BOTTOMLINE, "bottom-line" }, 83*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_CANCEL, "cancel" }, 84*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_CLEARSELECTION, "clear-selection" }, 85*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_COPYLINE, "copy-line" }, 86*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_COPYENDOFLINE, "copy-end-of-line" }, 87*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_COPYSELECTION, "copy-selection" }, 88*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_DOWN, "cursor-down" }, 89*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_ENDOFLINE, "end-of-line" }, 90*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_GOTOLINE, "goto-line" }, 91*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_HISTORYBOTTOM, "history-bottom" }, 92*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_HISTORYTOP, "history-top" }, 93*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_JUMP, "jump-forward" }, 94*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_JUMPAGAIN, "jump-again" }, 95*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_JUMPREVERSE, "jump-reverse" }, 96*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_JUMPBACK, "jump-backward" }, 97*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_LEFT, "cursor-left" }, 98*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_RECTANGLETOGGLE, "rectangle-toggle" }, 99*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_MIDDLELINE, "middle-line" }, 100*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_NEXTPAGE, "page-down" }, 101*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_NEXTSPACE, "next-space" }, 102*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_NEXTSPACEEND, "next-space-end" }, 103*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_NEXTWORD, "next-word" }, 104*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_NEXTWORDEND, "next-word-end" }, 105*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_PREVIOUSPAGE, "page-up" }, 106*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_PREVIOUSSPACE, "previous-space" }, 107*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_PREVIOUSWORD, "previous-word" }, 108*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_RIGHT, "cursor-right" }, 109*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_SCROLLDOWN, "scroll-down" }, 110*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_SCROLLUP, "scroll-up" }, 111*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_SEARCHAGAIN, "search-again" }, 112*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_SEARCHDOWN, "search-forward" }, 113*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_SEARCHREVERSE, "search-reverse" }, 114*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_SEARCHUP, "search-backward" }, 115*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_SELECTLINE, "select-line" }, 116*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_STARTNUMBERPREFIX, "start-number-prefix" }, 117*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_STARTOFLINE, "start-of-line" }, 118*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_STARTSELECTION, "begin-selection" }, 119*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_TOPLINE, "top-line" }, 120*eda6f593SDavid van Moolenbroek { MODEKEYCOPY_UP, "cursor-up" }, 121*eda6f593SDavid van Moolenbroek 122*eda6f593SDavid van Moolenbroek { 0, NULL } 123*eda6f593SDavid van Moolenbroek }; 124*eda6f593SDavid van Moolenbroek 125*eda6f593SDavid van Moolenbroek /* vi editing keys. */ 126*eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_vi_edit[] = { 127*eda6f593SDavid van Moolenbroek { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL }, 128*eda6f593SDavid van Moolenbroek { '\010' /* C-h */, 0, MODEKEYEDIT_BACKSPACE }, 129*eda6f593SDavid van Moolenbroek { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE }, 130*eda6f593SDavid van Moolenbroek { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE }, 131*eda6f593SDavid van Moolenbroek { '\033' /* Escape */, 0, MODEKEYEDIT_SWITCHMODE }, 132*eda6f593SDavid van Moolenbroek { '\r', 0, MODEKEYEDIT_ENTER }, 133*eda6f593SDavid van Moolenbroek { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE }, 134*eda6f593SDavid van Moolenbroek { KEYC_DC, 0, MODEKEYEDIT_DELETE }, 135*eda6f593SDavid van Moolenbroek 136*eda6f593SDavid van Moolenbroek { '$', 1, MODEKEYEDIT_ENDOFLINE }, 137*eda6f593SDavid van Moolenbroek { '0', 1, MODEKEYEDIT_STARTOFLINE }, 138*eda6f593SDavid van Moolenbroek { 'D', 1, MODEKEYEDIT_DELETETOENDOFLINE }, 139*eda6f593SDavid van Moolenbroek { '\003' /* C-c */, 1, MODEKEYEDIT_CANCEL }, 140*eda6f593SDavid van Moolenbroek { '\010' /* C-h */, 1, MODEKEYEDIT_BACKSPACE }, 141*eda6f593SDavid van Moolenbroek { '\r', 1, MODEKEYEDIT_ENTER }, 142*eda6f593SDavid van Moolenbroek { '^', 1, MODEKEYEDIT_STARTOFLINE }, 143*eda6f593SDavid van Moolenbroek { 'a', 1, MODEKEYEDIT_SWITCHMODEAPPEND }, 144*eda6f593SDavid van Moolenbroek { 'd', 1, MODEKEYEDIT_DELETELINE }, 145*eda6f593SDavid van Moolenbroek { 'h', 1, MODEKEYEDIT_CURSORLEFT }, 146*eda6f593SDavid van Moolenbroek { 'i', 1, MODEKEYEDIT_SWITCHMODE }, 147*eda6f593SDavid van Moolenbroek { 'j', 1, MODEKEYEDIT_HISTORYDOWN }, 148*eda6f593SDavid van Moolenbroek { 'k', 1, MODEKEYEDIT_HISTORYUP }, 149*eda6f593SDavid van Moolenbroek { 'l', 1, MODEKEYEDIT_CURSORRIGHT }, 150*eda6f593SDavid van Moolenbroek { 'p', 1, MODEKEYEDIT_PASTE }, 151*eda6f593SDavid van Moolenbroek { KEYC_BSPACE, 1, MODEKEYEDIT_BACKSPACE }, 152*eda6f593SDavid van Moolenbroek { KEYC_DC, 1, MODEKEYEDIT_DELETE }, 153*eda6f593SDavid van Moolenbroek { KEYC_DOWN, 1, MODEKEYEDIT_HISTORYDOWN }, 154*eda6f593SDavid van Moolenbroek { KEYC_LEFT, 1, MODEKEYEDIT_CURSORLEFT }, 155*eda6f593SDavid van Moolenbroek { KEYC_RIGHT, 1, MODEKEYEDIT_CURSORRIGHT }, 156*eda6f593SDavid van Moolenbroek { KEYC_UP, 1, MODEKEYEDIT_HISTORYUP }, 157*eda6f593SDavid van Moolenbroek 158*eda6f593SDavid van Moolenbroek { 0, -1, 0 } 159*eda6f593SDavid van Moolenbroek }; 160*eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_vi_edit; 161*eda6f593SDavid van Moolenbroek 162*eda6f593SDavid van Moolenbroek /* vi choice selection keys. */ 163*eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_vi_choice[] = { 164*eda6f593SDavid van Moolenbroek { '\002' /* C-b */, 0, MODEKEYCHOICE_PAGEUP }, 165*eda6f593SDavid van Moolenbroek { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, 166*eda6f593SDavid van Moolenbroek { '\005' /* C-e */, 0, MODEKEYCHOICE_SCROLLDOWN }, 167*eda6f593SDavid van Moolenbroek { '\006' /* C-f */, 0, MODEKEYCHOICE_PAGEDOWN }, 168*eda6f593SDavid van Moolenbroek { '\031' /* C-y */, 0, MODEKEYCHOICE_SCROLLUP }, 169*eda6f593SDavid van Moolenbroek { '\r', 0, MODEKEYCHOICE_CHOOSE }, 170*eda6f593SDavid van Moolenbroek { 'j', 0, MODEKEYCHOICE_DOWN }, 171*eda6f593SDavid van Moolenbroek { 'k', 0, MODEKEYCHOICE_UP }, 172*eda6f593SDavid van Moolenbroek { 'q', 0, MODEKEYCHOICE_CANCEL }, 173*eda6f593SDavid van Moolenbroek { KEYC_DOWN | KEYC_CTRL,0, MODEKEYCHOICE_SCROLLDOWN }, 174*eda6f593SDavid van Moolenbroek { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, 175*eda6f593SDavid van Moolenbroek { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, 176*eda6f593SDavid van Moolenbroek { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, 177*eda6f593SDavid van Moolenbroek { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, 178*eda6f593SDavid van Moolenbroek { KEYC_UP, 0, MODEKEYCHOICE_UP }, 179*eda6f593SDavid van Moolenbroek 180*eda6f593SDavid van Moolenbroek { 0, -1, 0 } 181*eda6f593SDavid van Moolenbroek }; 182*eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_vi_choice; 183*eda6f593SDavid van Moolenbroek 184*eda6f593SDavid van Moolenbroek /* vi copy mode keys. */ 185*eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_vi_copy[] = { 186*eda6f593SDavid van Moolenbroek { ' ', 0, MODEKEYCOPY_STARTSELECTION }, 187*eda6f593SDavid van Moolenbroek { '$', 0, MODEKEYCOPY_ENDOFLINE }, 188*eda6f593SDavid van Moolenbroek { ',', 0, MODEKEYCOPY_JUMPREVERSE }, 189*eda6f593SDavid van Moolenbroek { ';', 0, MODEKEYCOPY_JUMPAGAIN }, 190*eda6f593SDavid van Moolenbroek { '/', 0, MODEKEYCOPY_SEARCHDOWN }, 191*eda6f593SDavid van Moolenbroek { '0', 0, MODEKEYCOPY_STARTOFLINE }, 192*eda6f593SDavid van Moolenbroek { '1', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 193*eda6f593SDavid van Moolenbroek { '2', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 194*eda6f593SDavid van Moolenbroek { '3', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 195*eda6f593SDavid van Moolenbroek { '4', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 196*eda6f593SDavid van Moolenbroek { '5', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 197*eda6f593SDavid van Moolenbroek { '6', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 198*eda6f593SDavid van Moolenbroek { '7', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 199*eda6f593SDavid van Moolenbroek { '8', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 200*eda6f593SDavid van Moolenbroek { '9', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 201*eda6f593SDavid van Moolenbroek { ':', 0, MODEKEYCOPY_GOTOLINE }, 202*eda6f593SDavid van Moolenbroek { '?', 0, MODEKEYCOPY_SEARCHUP }, 203*eda6f593SDavid van Moolenbroek { 'B', 0, MODEKEYCOPY_PREVIOUSSPACE }, 204*eda6f593SDavid van Moolenbroek { 'D', 0, MODEKEYCOPY_COPYENDOFLINE }, 205*eda6f593SDavid van Moolenbroek { 'E', 0, MODEKEYCOPY_NEXTSPACEEND }, 206*eda6f593SDavid van Moolenbroek { 'F', 0, MODEKEYCOPY_JUMPBACK }, 207*eda6f593SDavid van Moolenbroek { 'G', 0, MODEKEYCOPY_HISTORYBOTTOM }, 208*eda6f593SDavid van Moolenbroek { 'H', 0, MODEKEYCOPY_TOPLINE }, 209*eda6f593SDavid van Moolenbroek { 'J', 0, MODEKEYCOPY_SCROLLDOWN }, 210*eda6f593SDavid van Moolenbroek { 'K', 0, MODEKEYCOPY_SCROLLUP }, 211*eda6f593SDavid van Moolenbroek { 'L', 0, MODEKEYCOPY_BOTTOMLINE }, 212*eda6f593SDavid van Moolenbroek { 'M', 0, MODEKEYCOPY_MIDDLELINE }, 213*eda6f593SDavid van Moolenbroek { 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, 214*eda6f593SDavid van Moolenbroek { 'W', 0, MODEKEYCOPY_NEXTSPACE }, 215*eda6f593SDavid van Moolenbroek { '\002' /* C-b */, 0, MODEKEYCOPY_PREVIOUSPAGE }, 216*eda6f593SDavid van Moolenbroek { '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL }, 217*eda6f593SDavid van Moolenbroek { '\004' /* C-d */, 0, MODEKEYCOPY_HALFPAGEDOWN }, 218*eda6f593SDavid van Moolenbroek { '\005' /* C-e */, 0, MODEKEYCOPY_SCROLLDOWN }, 219*eda6f593SDavid van Moolenbroek { '\006' /* C-f */, 0, MODEKEYCOPY_NEXTPAGE }, 220*eda6f593SDavid van Moolenbroek { '\010' /* C-h */, 0, MODEKEYCOPY_LEFT }, 221*eda6f593SDavid van Moolenbroek { '\025' /* C-u */, 0, MODEKEYCOPY_HALFPAGEUP }, 222*eda6f593SDavid van Moolenbroek { '\031' /* C-y */, 0, MODEKEYCOPY_SCROLLUP }, 223*eda6f593SDavid van Moolenbroek { '\033' /* Escape */, 0, MODEKEYCOPY_CLEARSELECTION }, 224*eda6f593SDavid van Moolenbroek { '\r', 0, MODEKEYCOPY_COPYSELECTION }, 225*eda6f593SDavid van Moolenbroek { '^', 0, MODEKEYCOPY_BACKTOINDENTATION }, 226*eda6f593SDavid van Moolenbroek { 'b', 0, MODEKEYCOPY_PREVIOUSWORD }, 227*eda6f593SDavid van Moolenbroek { 'e', 0, MODEKEYCOPY_NEXTWORDEND }, 228*eda6f593SDavid van Moolenbroek { 'f', 0, MODEKEYCOPY_JUMP }, 229*eda6f593SDavid van Moolenbroek { 'g', 0, MODEKEYCOPY_HISTORYTOP }, 230*eda6f593SDavid van Moolenbroek { 'h', 0, MODEKEYCOPY_LEFT }, 231*eda6f593SDavid van Moolenbroek { 'j', 0, MODEKEYCOPY_DOWN }, 232*eda6f593SDavid van Moolenbroek { 'k', 0, MODEKEYCOPY_UP }, 233*eda6f593SDavid van Moolenbroek { 'l', 0, MODEKEYCOPY_RIGHT }, 234*eda6f593SDavid van Moolenbroek { 'n', 0, MODEKEYCOPY_SEARCHAGAIN }, 235*eda6f593SDavid van Moolenbroek { 'q', 0, MODEKEYCOPY_CANCEL }, 236*eda6f593SDavid van Moolenbroek { 'v', 0, MODEKEYCOPY_RECTANGLETOGGLE }, 237*eda6f593SDavid van Moolenbroek { 'w', 0, MODEKEYCOPY_NEXTWORD }, 238*eda6f593SDavid van Moolenbroek { KEYC_BSPACE, 0, MODEKEYCOPY_LEFT }, 239*eda6f593SDavid van Moolenbroek { KEYC_DOWN | KEYC_CTRL,0, MODEKEYCOPY_SCROLLDOWN }, 240*eda6f593SDavid van Moolenbroek { KEYC_DOWN, 0, MODEKEYCOPY_DOWN }, 241*eda6f593SDavid van Moolenbroek { KEYC_LEFT, 0, MODEKEYCOPY_LEFT }, 242*eda6f593SDavid van Moolenbroek { KEYC_NPAGE, 0, MODEKEYCOPY_NEXTPAGE }, 243*eda6f593SDavid van Moolenbroek { KEYC_PPAGE, 0, MODEKEYCOPY_PREVIOUSPAGE }, 244*eda6f593SDavid van Moolenbroek { KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT }, 245*eda6f593SDavid van Moolenbroek { KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP }, 246*eda6f593SDavid van Moolenbroek { KEYC_UP, 0, MODEKEYCOPY_UP }, 247*eda6f593SDavid van Moolenbroek 248*eda6f593SDavid van Moolenbroek { 0, -1, 0 } 249*eda6f593SDavid van Moolenbroek }; 250*eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_vi_copy; 251*eda6f593SDavid van Moolenbroek 252*eda6f593SDavid van Moolenbroek /* emacs editing keys. */ 253*eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_emacs_edit[] = { 254*eda6f593SDavid van Moolenbroek { '\001' /* C-a */, 0, MODEKEYEDIT_STARTOFLINE }, 255*eda6f593SDavid van Moolenbroek { '\002' /* C-b */, 0, MODEKEYEDIT_CURSORLEFT }, 256*eda6f593SDavid van Moolenbroek { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL }, 257*eda6f593SDavid van Moolenbroek { '\004' /* C-d */, 0, MODEKEYEDIT_DELETE }, 258*eda6f593SDavid van Moolenbroek { '\005' /* C-e */, 0, MODEKEYEDIT_ENDOFLINE }, 259*eda6f593SDavid van Moolenbroek { '\006' /* C-f */, 0, MODEKEYEDIT_CURSORRIGHT }, 260*eda6f593SDavid van Moolenbroek { '\010' /* C-H */, 0, MODEKEYEDIT_BACKSPACE }, 261*eda6f593SDavid van Moolenbroek { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE }, 262*eda6f593SDavid van Moolenbroek { '\013' /* C-k */, 0, MODEKEYEDIT_DELETETOENDOFLINE }, 263*eda6f593SDavid van Moolenbroek { '\016' /* C-n */, 0, MODEKEYEDIT_HISTORYDOWN }, 264*eda6f593SDavid van Moolenbroek { '\020' /* C-p */, 0, MODEKEYEDIT_HISTORYUP }, 265*eda6f593SDavid van Moolenbroek { '\024' /* C-t */, 0, MODEKEYEDIT_TRANSPOSECHARS }, 266*eda6f593SDavid van Moolenbroek { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE }, 267*eda6f593SDavid van Moolenbroek { '\031' /* C-y */, 0, MODEKEYEDIT_PASTE }, 268*eda6f593SDavid van Moolenbroek { '\033' /* Escape */, 0, MODEKEYEDIT_CANCEL }, 269*eda6f593SDavid van Moolenbroek { '\r', 0, MODEKEYEDIT_ENTER }, 270*eda6f593SDavid van Moolenbroek { 'm' | KEYC_ESCAPE, 0, MODEKEYEDIT_STARTOFLINE }, 271*eda6f593SDavid van Moolenbroek { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE }, 272*eda6f593SDavid van Moolenbroek { KEYC_DC, 0, MODEKEYEDIT_DELETE }, 273*eda6f593SDavid van Moolenbroek { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN }, 274*eda6f593SDavid van Moolenbroek { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT }, 275*eda6f593SDavid van Moolenbroek { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT }, 276*eda6f593SDavid van Moolenbroek { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP }, 277*eda6f593SDavid van Moolenbroek 278*eda6f593SDavid van Moolenbroek { 0, -1, 0 } 279*eda6f593SDavid van Moolenbroek }; 280*eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_emacs_edit; 281*eda6f593SDavid van Moolenbroek 282*eda6f593SDavid van Moolenbroek /* emacs choice selection keys. */ 283*eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_emacs_choice[] = { 284*eda6f593SDavid van Moolenbroek { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, 285*eda6f593SDavid van Moolenbroek { '\016' /* C-n */, 0, MODEKEYCHOICE_DOWN }, 286*eda6f593SDavid van Moolenbroek { '\020' /* C-p */, 0, MODEKEYCHOICE_UP }, 287*eda6f593SDavid van Moolenbroek { '\026' /* C-v */, 0, MODEKEYCHOICE_PAGEDOWN }, 288*eda6f593SDavid van Moolenbroek { '\033' /* Escape */, 0, MODEKEYCHOICE_CANCEL }, 289*eda6f593SDavid van Moolenbroek { '\r', 0, MODEKEYCHOICE_CHOOSE }, 290*eda6f593SDavid van Moolenbroek { 'q', 0, MODEKEYCHOICE_CANCEL }, 291*eda6f593SDavid van Moolenbroek { 'v' | KEYC_ESCAPE, 0, MODEKEYCHOICE_PAGEUP }, 292*eda6f593SDavid van Moolenbroek { KEYC_DOWN | KEYC_CTRL,0, MODEKEYCHOICE_SCROLLDOWN }, 293*eda6f593SDavid van Moolenbroek { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, 294*eda6f593SDavid van Moolenbroek { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, 295*eda6f593SDavid van Moolenbroek { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, 296*eda6f593SDavid van Moolenbroek { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, 297*eda6f593SDavid van Moolenbroek { KEYC_UP, 0, MODEKEYCHOICE_UP }, 298*eda6f593SDavid van Moolenbroek 299*eda6f593SDavid van Moolenbroek { 0, -1, 0 } 300*eda6f593SDavid van Moolenbroek }; 301*eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_emacs_choice; 302*eda6f593SDavid van Moolenbroek 303*eda6f593SDavid van Moolenbroek /* emacs copy mode keys. */ 304*eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_emacs_copy[] = { 305*eda6f593SDavid van Moolenbroek { ' ', 0, MODEKEYCOPY_NEXTPAGE }, 306*eda6f593SDavid van Moolenbroek { ',', 0, MODEKEYCOPY_JUMPREVERSE }, 307*eda6f593SDavid van Moolenbroek { ';', 0, MODEKEYCOPY_JUMPAGAIN }, 308*eda6f593SDavid van Moolenbroek { '1' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 309*eda6f593SDavid van Moolenbroek { '2' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 310*eda6f593SDavid van Moolenbroek { '3' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 311*eda6f593SDavid van Moolenbroek { '4' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 312*eda6f593SDavid van Moolenbroek { '5' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 313*eda6f593SDavid van Moolenbroek { '6' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 314*eda6f593SDavid van Moolenbroek { '7' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 315*eda6f593SDavid van Moolenbroek { '8' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 316*eda6f593SDavid van Moolenbroek { '9' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, 317*eda6f593SDavid van Moolenbroek { '<' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYTOP }, 318*eda6f593SDavid van Moolenbroek { '>' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYBOTTOM }, 319*eda6f593SDavid van Moolenbroek { 'F', 0, MODEKEYCOPY_JUMPBACK }, 320*eda6f593SDavid van Moolenbroek { 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, 321*eda6f593SDavid van Moolenbroek { 'R' | KEYC_ESCAPE, 0, MODEKEYCOPY_TOPLINE }, 322*eda6f593SDavid van Moolenbroek { 'R', 0, MODEKEYCOPY_RECTANGLETOGGLE }, 323*eda6f593SDavid van Moolenbroek { '\000' /* C-Space */, 0, MODEKEYCOPY_STARTSELECTION }, 324*eda6f593SDavid van Moolenbroek { '\001' /* C-a */, 0, MODEKEYCOPY_STARTOFLINE }, 325*eda6f593SDavid van Moolenbroek { '\002' /* C-b */, 0, MODEKEYCOPY_LEFT }, 326*eda6f593SDavid van Moolenbroek { '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL }, 327*eda6f593SDavid van Moolenbroek { '\005' /* C-e */, 0, MODEKEYCOPY_ENDOFLINE }, 328*eda6f593SDavid van Moolenbroek { '\006' /* C-f */, 0, MODEKEYCOPY_RIGHT }, 329*eda6f593SDavid van Moolenbroek { '\007' /* C-g */, 0, MODEKEYCOPY_CLEARSELECTION }, 330*eda6f593SDavid van Moolenbroek { '\013' /* C-k */, 0, MODEKEYCOPY_COPYENDOFLINE }, 331*eda6f593SDavid van Moolenbroek { '\016' /* C-n */, 0, MODEKEYCOPY_DOWN }, 332*eda6f593SDavid van Moolenbroek { '\020' /* C-p */, 0, MODEKEYCOPY_UP }, 333*eda6f593SDavid van Moolenbroek { '\022' /* C-r */, 0, MODEKEYCOPY_SEARCHUP }, 334*eda6f593SDavid van Moolenbroek { '\023' /* C-s */, 0, MODEKEYCOPY_SEARCHDOWN }, 335*eda6f593SDavid van Moolenbroek { '\026' /* C-v */, 0, MODEKEYCOPY_NEXTPAGE }, 336*eda6f593SDavid van Moolenbroek { '\027' /* C-w */, 0, MODEKEYCOPY_COPYSELECTION }, 337*eda6f593SDavid van Moolenbroek { '\033' /* Escape */, 0, MODEKEYCOPY_CANCEL }, 338*eda6f593SDavid van Moolenbroek { 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, 339*eda6f593SDavid van Moolenbroek { 'b' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSWORD }, 340*eda6f593SDavid van Moolenbroek { 'f', 0, MODEKEYCOPY_JUMP }, 341*eda6f593SDavid van Moolenbroek { 'f' | KEYC_ESCAPE, 0, MODEKEYCOPY_NEXTWORDEND }, 342*eda6f593SDavid van Moolenbroek { 'g', 0, MODEKEYCOPY_GOTOLINE }, 343*eda6f593SDavid van Moolenbroek { 'm' | KEYC_ESCAPE, 0, MODEKEYCOPY_BACKTOINDENTATION }, 344*eda6f593SDavid van Moolenbroek { 'n', 0, MODEKEYCOPY_SEARCHAGAIN }, 345*eda6f593SDavid van Moolenbroek { 'q', 0, MODEKEYCOPY_CANCEL }, 346*eda6f593SDavid van Moolenbroek { 'r' | KEYC_ESCAPE, 0, MODEKEYCOPY_MIDDLELINE }, 347*eda6f593SDavid van Moolenbroek { 'v' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSPAGE }, 348*eda6f593SDavid van Moolenbroek { 'w' | KEYC_ESCAPE, 0, MODEKEYCOPY_COPYSELECTION }, 349*eda6f593SDavid van Moolenbroek { KEYC_DOWN | KEYC_CTRL,0, MODEKEYCOPY_SCROLLDOWN }, 350*eda6f593SDavid van Moolenbroek { KEYC_DOWN | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEDOWN }, 351*eda6f593SDavid van Moolenbroek { KEYC_DOWN, 0, MODEKEYCOPY_DOWN }, 352*eda6f593SDavid van Moolenbroek { KEYC_LEFT, 0, MODEKEYCOPY_LEFT }, 353*eda6f593SDavid van Moolenbroek { KEYC_NPAGE, 0, MODEKEYCOPY_NEXTPAGE }, 354*eda6f593SDavid van Moolenbroek { KEYC_PPAGE, 0, MODEKEYCOPY_PREVIOUSPAGE }, 355*eda6f593SDavid van Moolenbroek { KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT }, 356*eda6f593SDavid van Moolenbroek { KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP }, 357*eda6f593SDavid van Moolenbroek { KEYC_UP | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEUP }, 358*eda6f593SDavid van Moolenbroek { KEYC_UP, 0, MODEKEYCOPY_UP }, 359*eda6f593SDavid van Moolenbroek 360*eda6f593SDavid van Moolenbroek { 0, -1, 0 } 361*eda6f593SDavid van Moolenbroek }; 362*eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_emacs_copy; 363*eda6f593SDavid van Moolenbroek 364*eda6f593SDavid van Moolenbroek /* Table mapping key table names to default settings and trees. */ 365*eda6f593SDavid van Moolenbroek const struct mode_key_table mode_key_tables[] = { 366*eda6f593SDavid van Moolenbroek { "vi-edit", mode_key_cmdstr_edit, 367*eda6f593SDavid van Moolenbroek &mode_key_tree_vi_edit, mode_key_vi_edit }, 368*eda6f593SDavid van Moolenbroek { "vi-choice", mode_key_cmdstr_choice, 369*eda6f593SDavid van Moolenbroek &mode_key_tree_vi_choice, mode_key_vi_choice }, 370*eda6f593SDavid van Moolenbroek { "vi-copy", mode_key_cmdstr_copy, 371*eda6f593SDavid van Moolenbroek &mode_key_tree_vi_copy, mode_key_vi_copy }, 372*eda6f593SDavid van Moolenbroek { "emacs-edit", mode_key_cmdstr_edit, 373*eda6f593SDavid van Moolenbroek &mode_key_tree_emacs_edit, mode_key_emacs_edit }, 374*eda6f593SDavid van Moolenbroek { "emacs-choice", mode_key_cmdstr_choice, 375*eda6f593SDavid van Moolenbroek &mode_key_tree_emacs_choice, mode_key_emacs_choice }, 376*eda6f593SDavid van Moolenbroek { "emacs-copy", mode_key_cmdstr_copy, 377*eda6f593SDavid van Moolenbroek &mode_key_tree_emacs_copy, mode_key_emacs_copy }, 378*eda6f593SDavid van Moolenbroek 379*eda6f593SDavid van Moolenbroek { NULL, NULL, NULL, NULL } 380*eda6f593SDavid van Moolenbroek }; 381*eda6f593SDavid van Moolenbroek 382*eda6f593SDavid van Moolenbroek SPLAY_GENERATE(mode_key_tree, mode_key_binding, entry, mode_key_cmp); 383*eda6f593SDavid van Moolenbroek 384*eda6f593SDavid van Moolenbroek int 385*eda6f593SDavid van Moolenbroek mode_key_cmp(struct mode_key_binding *mbind1, struct mode_key_binding *mbind2) 386*eda6f593SDavid van Moolenbroek { 387*eda6f593SDavid van Moolenbroek if (mbind1->mode != mbind2->mode) 388*eda6f593SDavid van Moolenbroek return (mbind1->mode - mbind2->mode); 389*eda6f593SDavid van Moolenbroek return (mbind1->key - mbind2->key); 390*eda6f593SDavid van Moolenbroek } 391*eda6f593SDavid van Moolenbroek 392*eda6f593SDavid van Moolenbroek const char * 393*eda6f593SDavid van Moolenbroek mode_key_tostring(const struct mode_key_cmdstr *cmdstr, enum mode_key_cmd cmd) 394*eda6f593SDavid van Moolenbroek { 395*eda6f593SDavid van Moolenbroek for (; cmdstr->name != NULL; cmdstr++) { 396*eda6f593SDavid van Moolenbroek if (cmdstr->cmd == cmd) 397*eda6f593SDavid van Moolenbroek return (cmdstr->name); 398*eda6f593SDavid van Moolenbroek } 399*eda6f593SDavid van Moolenbroek return (NULL); 400*eda6f593SDavid van Moolenbroek } 401*eda6f593SDavid van Moolenbroek 402*eda6f593SDavid van Moolenbroek enum mode_key_cmd 403*eda6f593SDavid van Moolenbroek mode_key_fromstring(const struct mode_key_cmdstr *cmdstr, const char *name) 404*eda6f593SDavid van Moolenbroek { 405*eda6f593SDavid van Moolenbroek for (; cmdstr->name != NULL; cmdstr++) { 406*eda6f593SDavid van Moolenbroek if (strcasecmp(cmdstr->name, name) == 0) 407*eda6f593SDavid van Moolenbroek return (cmdstr->cmd); 408*eda6f593SDavid van Moolenbroek } 409*eda6f593SDavid van Moolenbroek return (MODEKEY_NONE); 410*eda6f593SDavid van Moolenbroek } 411*eda6f593SDavid van Moolenbroek 412*eda6f593SDavid van Moolenbroek const struct mode_key_table * 413*eda6f593SDavid van Moolenbroek mode_key_findtable(const char *name) 414*eda6f593SDavid van Moolenbroek { 415*eda6f593SDavid van Moolenbroek const struct mode_key_table *mtab; 416*eda6f593SDavid van Moolenbroek 417*eda6f593SDavid van Moolenbroek for (mtab = mode_key_tables; mtab->name != NULL; mtab++) { 418*eda6f593SDavid van Moolenbroek if (strcasecmp(name, mtab->name) == 0) 419*eda6f593SDavid van Moolenbroek return (mtab); 420*eda6f593SDavid van Moolenbroek } 421*eda6f593SDavid van Moolenbroek return (NULL); 422*eda6f593SDavid van Moolenbroek } 423*eda6f593SDavid van Moolenbroek 424*eda6f593SDavid van Moolenbroek void 425*eda6f593SDavid van Moolenbroek mode_key_init_trees(void) 426*eda6f593SDavid van Moolenbroek { 427*eda6f593SDavid van Moolenbroek const struct mode_key_table *mtab; 428*eda6f593SDavid van Moolenbroek const struct mode_key_entry *ment; 429*eda6f593SDavid van Moolenbroek struct mode_key_binding *mbind; 430*eda6f593SDavid van Moolenbroek 431*eda6f593SDavid van Moolenbroek for (mtab = mode_key_tables; mtab->name != NULL; mtab++) { 432*eda6f593SDavid van Moolenbroek SPLAY_INIT(mtab->tree); 433*eda6f593SDavid van Moolenbroek for (ment = mtab->table; ment->mode != -1; ment++) { 434*eda6f593SDavid van Moolenbroek mbind = xmalloc(sizeof *mbind); 435*eda6f593SDavid van Moolenbroek mbind->key = ment->key; 436*eda6f593SDavid van Moolenbroek mbind->mode = ment->mode; 437*eda6f593SDavid van Moolenbroek mbind->cmd = ment->cmd; 438*eda6f593SDavid van Moolenbroek SPLAY_INSERT(mode_key_tree, mtab->tree, mbind); 439*eda6f593SDavid van Moolenbroek } 440*eda6f593SDavid van Moolenbroek } 441*eda6f593SDavid van Moolenbroek } 442*eda6f593SDavid van Moolenbroek 443*eda6f593SDavid van Moolenbroek void 444*eda6f593SDavid van Moolenbroek mode_key_init(struct mode_key_data *mdata, struct mode_key_tree *mtree) 445*eda6f593SDavid van Moolenbroek { 446*eda6f593SDavid van Moolenbroek mdata->tree = mtree; 447*eda6f593SDavid van Moolenbroek mdata->mode = 0; 448*eda6f593SDavid van Moolenbroek } 449*eda6f593SDavid van Moolenbroek 450*eda6f593SDavid van Moolenbroek enum mode_key_cmd 451*eda6f593SDavid van Moolenbroek mode_key_lookup(struct mode_key_data *mdata, int key) 452*eda6f593SDavid van Moolenbroek { 453*eda6f593SDavid van Moolenbroek struct mode_key_binding *mbind, mtmp; 454*eda6f593SDavid van Moolenbroek 455*eda6f593SDavid van Moolenbroek mtmp.key = key; 456*eda6f593SDavid van Moolenbroek mtmp.mode = mdata->mode; 457*eda6f593SDavid van Moolenbroek if ((mbind = SPLAY_FIND(mode_key_tree, mdata->tree, &mtmp)) == NULL) { 458*eda6f593SDavid van Moolenbroek if (mdata->mode != 0) 459*eda6f593SDavid van Moolenbroek return (MODEKEY_NONE); 460*eda6f593SDavid van Moolenbroek return (MODEKEY_OTHER); 461*eda6f593SDavid van Moolenbroek } 462*eda6f593SDavid van Moolenbroek 463*eda6f593SDavid van Moolenbroek switch (mbind->cmd) { 464*eda6f593SDavid van Moolenbroek case MODEKEYEDIT_SWITCHMODE: 465*eda6f593SDavid van Moolenbroek case MODEKEYEDIT_SWITCHMODEAPPEND: 466*eda6f593SDavid van Moolenbroek mdata->mode = 1 - mdata->mode; 467*eda6f593SDavid van Moolenbroek /* FALLTHROUGH */ 468*eda6f593SDavid van Moolenbroek default: 469*eda6f593SDavid van Moolenbroek return (mbind->cmd); 470*eda6f593SDavid van Moolenbroek } 471*eda6f593SDavid van Moolenbroek } 472