github.com/hoop33/elvish@v0.0.0-20160801152013-6d25485beab4/edit/builtins.go (about) 1 package edit 2 3 import "fmt" 4 5 // Line editor builtins. 6 7 // Builtin records an editor builtin. 8 type Builtin struct { 9 name string 10 impl func(ed *Editor) 11 } 12 13 var builtins = []Builtin{ 14 // Command and insert mode 15 {"start-insert", startInsert}, 16 {"start-command", startCommand}, 17 {"kill-line-left", killLineLeft}, 18 {"kill-line-right", killLineRight}, 19 {"kill-word-left", killWordLeft}, 20 {"kill-small-word-left", killSmallWordLeft}, 21 {"kill-rune-left", killRuneLeft}, 22 {"kill-rune-right", killRuneRight}, 23 {"move-dot-left", moveDotLeft}, 24 {"move-dot-right", moveDotRight}, 25 {"move-dot-left-word", moveDotLeftWord}, 26 {"move-dot-right-word", moveDotRightWord}, 27 {"move-dot-sol", moveDotSOL}, 28 {"move-dot-eol", moveDotEOL}, 29 {"move-dot-up", moveDotUp}, 30 {"move-dot-down", moveDotDown}, 31 {"insert-last-word", insertLastWord}, 32 {"insert-key", insertKey}, 33 {"return-line", returnLine}, 34 {"smart-enter", smartEnter}, 35 {"return-eof", returnEOF}, 36 {"toggle-quote-paste", toggleQuotePaste}, 37 {"end-of-history", endOfHistory}, 38 {"default-command", defaultCommand}, 39 {"insert-default", defaultInsert}, 40 41 // Completion mode 42 {"compl-prefix-or-start-compl", complPrefixOrStartCompl}, 43 {"start-compl", startCompl}, 44 {"compl-up", complUp}, 45 {"compl-down", complDown}, 46 {"compl-down-cycle", complDownCycle}, 47 {"compl-left", complLeft}, 48 {"compl-right", complRight}, 49 {"compl-accept", complAccept}, 50 {"compl-trigger-filter", complTriggerFilter}, 51 {"compl-default", complDefault}, 52 53 // Navigation mode 54 {"start-nav", startNav}, 55 {"nav-up", navUp}, 56 {"nav-down", navDown}, 57 {"nav-page-up", navPageUp}, 58 {"nav-page-down", navPageDown}, 59 {"nav-left", navLeft}, 60 {"nav-right", navRight}, 61 {"nav-trigger-shown-hidden", navTriggerShowHidden}, 62 {"nav-trigger-filter", navTriggerFilter}, 63 {"nav-insert-selected", navInsertSelected}, 64 {"navigation-default", navigationDefault}, 65 66 // History mode 67 {"start-history", startHistory}, 68 {"history-up", historyUp}, 69 {"history-down", historyDown}, 70 {"history-down-or-quit", historyDownOrQuit}, 71 {"history-switch-to-histlist", historySwitchToHistlist}, 72 {"history-default", historyDefault}, 73 74 // History listing mode 75 {"start-histlist", startHistlist}, 76 77 // Bang mode 78 {"start-bang", startBang}, 79 {"bang-alt-default", bangAltDefault}, 80 81 // Location mode 82 {"start-location", startLocation}, 83 84 // Misc 85 {"redraw", redraw}, 86 } 87 88 var defaultBindings = map[ModeType]map[Key]string{ 89 modeInsert: map[Key]string{ 90 // Moving. 91 Key{Left, 0}: "move-dot-left", 92 Key{Right, 0}: "move-dot-right", 93 Key{Up, Alt}: "move-dot-up", 94 Key{Down, Alt}: "move-dot-down", 95 Key{Left, Ctrl}: "move-dot-left-word", 96 Key{Right, Ctrl}: "move-dot-right-word", 97 Key{Home, 0}: "move-dot-sol", 98 Key{End, 0}: "move-dot-eol", 99 // Killing. 100 Key{'U', Ctrl}: "kill-line-left", 101 Key{'K', Ctrl}: "kill-line-right", 102 Key{'W', Ctrl}: "kill-word-left", 103 Key{Backspace, 0}: "kill-rune-left", 104 // Some terminal send ^H on backspace 105 // Key{'H', Ctrl}: "kill-rune-left", 106 Key{Delete, 0}: "kill-rune-right", 107 // Inserting. 108 Key{'.', Alt}: "insert-last-word", 109 Key{Enter, Alt}: "insert-key", 110 // Controls. 111 Key{Enter, 0}: "smart-enter", 112 Key{'D', Ctrl}: "return-eof", 113 Key{F2, 0}: "toggle-quote-paste", 114 // Key{'[', Ctrl}: "startCommand", 115 Key{Tab, 0}: "compl-prefix-or-start-compl", 116 Key{Up, 0}: "start-history", 117 Key{Down, 0}: "end-of-history", 118 Key{'N', Ctrl}: "start-nav", 119 Key{'R', Ctrl}: "start-histlist", 120 Key{',', Alt}: "start-bang", 121 Key{'L', Ctrl}: "start-location", 122 Default: "insert-default", 123 }, 124 modeCommand: map[Key]string{ 125 // Moving. 126 Key{'h', 0}: "move-dot-left", 127 Key{'l', 0}: "move-dot-right", 128 Key{'k', 0}: "move-dot-up", 129 Key{'j', 0}: "move-dot-down", 130 Key{'b', 0}: "move-dot-left-word", 131 Key{'w', 0}: "move-dot-right-word", 132 Key{'0', 0}: "move-dot-sol", 133 Key{'$', 0}: "move-dot-eol", 134 // Killing. 135 Key{'x', 0}: "kill-rune-right", 136 Key{'D', 0}: "kill-line-right", 137 // Controls. 138 Key{'i', 0}: "start-insert", 139 Default: "default-command", 140 }, 141 modeCompletion: map[Key]string{ 142 Key{Up, 0}: "compl-up", 143 Key{Down, 0}: "compl-down", 144 Key{Tab, 0}: "compl-down-cycle", 145 Key{Left, 0}: "compl-left", 146 Key{Right, 0}: "compl-right", 147 Key{Enter, 0}: "compl-accept", 148 Key{'F', Ctrl}: "compl-trigger-filter", 149 Key{'[', Ctrl}: "start-insert", 150 Default: "compl-default", 151 }, 152 modeNavigation: map[Key]string{ 153 Key{Up, 0}: "nav-up", 154 Key{Down, 0}: "nav-down", 155 Key{PageUp, 0}: "nav-page-up", 156 Key{PageDown, 0}: "nav-page-down", 157 Key{Left, 0}: "nav-left", 158 Key{Right, 0}: "nav-right", 159 Key{Tab, 0}: "nav-insert-selected", 160 Key{'H', Ctrl}: "nav-trigger-shown-hidden", 161 Key{'F', Ctrl}: "nav-trigger-filter", 162 Key{'[', Ctrl}: "start-insert", 163 Default: "navigation-default", 164 }, 165 modeHistory: map[Key]string{ 166 Key{Up, 0}: "history-up", 167 Key{Down, 0}: "history-down-or-quit", 168 Key{'[', Ctrl}: "start-insert", 169 Key{'R', Ctrl}: "history-switch-to-histlist", 170 Default: "history-default", 171 }, 172 modeHistoryListing: map[Key]string{}, 173 modeBang: map[Key]string{ 174 Default: "bang-alt-default", 175 }, 176 modeLocation: map[Key]string{}, 177 } 178 179 var ( 180 builtinMap = map[string]Builtin{} 181 keyBindings = map[ModeType]map[Key]BoundFunc{} 182 ) 183 184 func init() { 185 addListingBuiltins("loc-", func(ed *Editor) *listing { return &ed.location.listing }) 186 addListingDefaultBindings("loc-", modeLocation) 187 addListingBuiltins("histlist-", func(ed *Editor) *listing { return &ed.histlist.listing }) 188 addListingDefaultBindings("histlist-", modeHistoryListing) 189 addListingBuiltins("bang-", func(ed *Editor) *listing { return &ed.bang.listing }) 190 addListingDefaultBindings("bang-", modeBang) 191 192 for _, b := range builtins { 193 builtinMap[b.name] = b 194 } 195 for mode, table := range defaultBindings { 196 keyBindings[mode] = map[Key]BoundFunc{} 197 for key, name := range table { 198 caller, ok := builtinMap[name] 199 if !ok { 200 fmt.Println("bad name " + name) 201 } else { 202 keyBindings[mode][key] = caller 203 } 204 } 205 } 206 } 207 208 type action struct { 209 typ actionType 210 returnLine string 211 returnErr error 212 } 213 214 type actionType int 215 216 const ( 217 noAction actionType = iota 218 reprocessKey 219 exitReadLine 220 ) 221 222 func redraw(ed *Editor) { 223 ed.refresh(true, true) 224 } 225 226 func endOfHistory(ed *Editor) { 227 ed.notify("End of history") 228 }