github.com/elves/elvish@v0.15.0/pkg/edit/navigation.go (about) 1 package edit 2 3 import ( 4 "strings" 5 6 "github.com/elves/elvish/pkg/cli" 7 "github.com/elves/elvish/pkg/cli/addons/navigation" 8 "github.com/elves/elvish/pkg/eval" 9 "github.com/elves/elvish/pkg/eval/vals" 10 "github.com/elves/elvish/pkg/eval/vars" 11 "github.com/elves/elvish/pkg/parse" 12 ) 13 14 //elvdoc:var selected-file 15 // 16 // Name of the currently selected file in navigation mode. $nil if not in 17 // navigation mode. 18 19 //elvdoc:var navigation:binding 20 // 21 // Keybinding for the navigation mode. 22 23 //elvdoc:fn navigation:start 24 // 25 // Start the navigation mode. 26 27 //elvdoc:fn navigation:insert-selected 28 // 29 // Inserts the selected filename. 30 31 func navInsertSelected(app cli.App) { 32 fname := navigation.SelectedName(app) 33 if fname == "" { 34 // User pressed Alt-Enter or Enter in an empty directory with nothing 35 // selected; don't do anything. 36 return 37 } 38 39 app.CodeArea().MutateState(func(s *cli.CodeAreaState) { 40 dot := s.Buffer.Dot 41 if dot != 0 && !strings.ContainsRune(" \n", rune(s.Buffer.Content[dot-1])) { 42 // The dot is not at the beginning of a buffer, and the previous 43 // character is not a space or newline. Insert a space. 44 s.Buffer.InsertAtDot(" ") 45 } 46 // Insert the selected filename. 47 s.Buffer.InsertAtDot(parse.Quote(fname)) 48 }) 49 } 50 51 //elvdoc:fn navigation:insert-selected-and-quit 52 // 53 // Inserts the selected filename and closes the navigation addon. 54 55 func navInsertSelectedAndQuit(app cli.App) { 56 navInsertSelected(app) 57 closeListing(app) 58 } 59 60 //elvdoc:fn navigation:trigger-filter 61 // 62 // Toggles the filtering status of the navigation addon. 63 64 func navToggleFilter(app cli.App) { 65 navigation.MutateFiltering(app, func(b bool) bool { return !b }) 66 } 67 68 //elvdoc:fn navigation:trigger-shown-hidden 69 // 70 // Toggles whether the navigation addon should be showing hidden files. 71 72 func navToggleShowHidden(app cli.App) { 73 navigation.MutateShowHidden(app, func(b bool) bool { return !b }) 74 } 75 76 //elvdoc:var navigation:width-ratio 77 // 78 // A list of 3 integers, used for specifying the width ratio of the 3 columns in 79 // navigation mode. 80 81 func convertNavWidthRatio(v interface{}) [3]int { 82 var ( 83 numbers []int 84 hasErr bool 85 ) 86 vals.Iterate(v, func(elem interface{}) bool { 87 var i int 88 err := vals.ScanToGo(elem, &i) 89 if err != nil { 90 hasErr = true 91 return false 92 } 93 numbers = append(numbers, i) 94 return true 95 }) 96 if hasErr || len(numbers) != 3 { 97 // TODO: Handle the error. 98 return [3]int{1, 3, 4} 99 } 100 var ret [3]int 101 copy(ret[:], numbers) 102 return ret 103 } 104 105 func initNavigation(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) { 106 bindingVar := newBindingVar(EmptyBindingMap) 107 binding := newMapBinding(ed, ev, bindingVar) 108 widthRatioVar := newListVar(vals.MakeList(1.0, 3.0, 4.0)) 109 110 selectedFileVar := vars.FromGet(func() interface{} { 111 name := navigation.SelectedName(ed.app) 112 if name == "" { 113 return nil 114 } 115 return name 116 }) 117 118 app := ed.app 119 nb.Add("selected-file", selectedFileVar) 120 nb.AddNs("navigation", 121 eval.NsBuilder{ 122 "binding": bindingVar, 123 "width-ratio": widthRatioVar, 124 }.AddGoFns("<edit:navigation>", map[string]interface{}{ 125 "start": func() { 126 navigation.Start(app, navigation.Config{ 127 Binding: binding, 128 WidthRatio: func() [3]int { 129 return convertNavWidthRatio(widthRatioVar.Get()) 130 }, 131 }) 132 }, 133 "left": func() { navigation.Ascend(app) }, 134 "right": func() { navigation.Descend(app) }, 135 "up": func() { navigation.Select(app, cli.Prev) }, 136 "down": func() { navigation.Select(app, cli.Next) }, 137 "page-up": func() { navigation.Select(app, cli.PrevPage) }, 138 "page-down": func() { navigation.Select(app, cli.NextPage) }, 139 140 "file-preview-up": func() { navigation.ScrollPreview(app, -1) }, 141 "file-preview-down": func() { navigation.ScrollPreview(app, 1) }, 142 143 "insert-selected": func() { navInsertSelected(app) }, 144 "insert-selected-and-quit": func() { navInsertSelectedAndQuit(app) }, 145 146 "trigger-filter": func() { navToggleFilter(app) }, 147 "trigger-shown-hidden": func() { navToggleShowHidden(app) }, 148 }).Ns()) 149 }