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  }