mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-14 11:17:52 +08:00
edit: Manage completion binding in its own struct.
This commit is contained in:
parent
d30826d02d
commit
ce76f493b2
|
@ -160,8 +160,6 @@ func makeNs(ed *Editor) eval.Ns {
|
|||
}
|
||||
ns.AddBuiltinFns("edit:", fns)
|
||||
|
||||
ns.AddNs("completion",
|
||||
initModeAPI("completion:", completionFns, &ed.completionBinding))
|
||||
ns.AddNs("navigation",
|
||||
initModeAPI("navigation:", navigationFns, &ed.navigationBinding))
|
||||
|
||||
|
|
|
@ -15,21 +15,14 @@ import (
|
|||
|
||||
// Interface.
|
||||
|
||||
var completionFns = map[string]func(*Editor){
|
||||
"smart-start": complSmartStart,
|
||||
"start": complStart,
|
||||
"up": complUp,
|
||||
"up-cycle": complUpCycle,
|
||||
"down": complDown,
|
||||
"down-cycle": complDownCycle,
|
||||
"left": complLeft,
|
||||
"right": complRight,
|
||||
"accept": complAccept,
|
||||
"trigger-filter": complTriggerFilter,
|
||||
"default": complDefault,
|
||||
}
|
||||
var completionFns = map[string]func(*Editor){}
|
||||
|
||||
type completion struct {
|
||||
binding BindingMap
|
||||
completionState
|
||||
}
|
||||
|
||||
type completionState struct {
|
||||
complSpec
|
||||
completer string
|
||||
|
||||
|
@ -42,8 +35,37 @@ type completion struct {
|
|||
height int
|
||||
}
|
||||
|
||||
func (*completion) Binding(ed *Editor, k ui.Key) eval.Callable {
|
||||
return ed.completionBinding.GetOrDefault(k)
|
||||
func init() { atEditorInit(initCompletion) }
|
||||
|
||||
func initCompletion(ed *Editor, ns eval.Ns) {
|
||||
c := &completion{binding: EmptyBindingMap}
|
||||
ed.completion = c
|
||||
|
||||
subns := eval.Ns{
|
||||
"binding": eval.NewVariableFromPtr(&c.binding),
|
||||
}
|
||||
subns.AddBuiltinFns("edit:completion:", map[string]interface{}{
|
||||
"start": func() { startCompletionInner(ed, false) },
|
||||
"smart-start": func() { startCompletionInner(ed, true) },
|
||||
"up": func() { c.prev(false) },
|
||||
"up-cycle": func() { c.prev(true) },
|
||||
"down": func() { c.next(false) },
|
||||
"down-cycle": func() { c.next(true) },
|
||||
"left": c.left,
|
||||
"right": c.right,
|
||||
"accept": func() { complAccept(ed) },
|
||||
"trigger-filter": c.triggerFilter,
|
||||
"default": func() { complDefault(ed) },
|
||||
})
|
||||
ns.AddNs("completion", subns)
|
||||
}
|
||||
|
||||
func (c *completion) Deinit() {
|
||||
c.completionState = completionState{}
|
||||
}
|
||||
|
||||
func (c *completion) Binding(ed *Editor, k ui.Key) eval.Callable {
|
||||
return c.binding.GetOrDefault(k)
|
||||
}
|
||||
|
||||
func (c *completion) needScrollbar() bool {
|
||||
|
@ -63,42 +85,18 @@ func (c *completion) CursorOnModeLine() bool {
|
|||
return c.filtering
|
||||
}
|
||||
|
||||
func complStart(ed *Editor) {
|
||||
startCompletionInner(ed, false)
|
||||
}
|
||||
|
||||
func complSmartStart(ed *Editor) {
|
||||
startCompletionInner(ed, true)
|
||||
}
|
||||
|
||||
func complUp(ed *Editor) {
|
||||
ed.completion.prev(false)
|
||||
}
|
||||
|
||||
func complDown(ed *Editor) {
|
||||
ed.completion.next(false)
|
||||
}
|
||||
|
||||
func complLeft(ed *Editor) {
|
||||
if c := ed.completion.selected - ed.completion.height; c >= 0 {
|
||||
ed.completion.selected = c
|
||||
func (c *completion) left() {
|
||||
if x := c.selected - c.height; x >= 0 {
|
||||
c.selected = x
|
||||
}
|
||||
}
|
||||
|
||||
func complRight(ed *Editor) {
|
||||
if c := ed.completion.selected + ed.completion.height; c < len(ed.completion.filtered) {
|
||||
ed.completion.selected = c
|
||||
func (c *completion) right() {
|
||||
if x := c.selected + c.height; x < len(c.filtered) {
|
||||
c.selected = x
|
||||
}
|
||||
}
|
||||
|
||||
func complUpCycle(ed *Editor) {
|
||||
ed.completion.prev(true)
|
||||
}
|
||||
|
||||
func complDownCycle(ed *Editor) {
|
||||
ed.completion.next(true)
|
||||
}
|
||||
|
||||
// acceptCompletion accepts currently selected completion candidate.
|
||||
func complAccept(ed *Editor) {
|
||||
c := ed.completion
|
||||
|
@ -110,7 +108,7 @@ func complAccept(ed *Editor) {
|
|||
|
||||
func complDefault(ed *Editor) {
|
||||
k := ed.lastKey
|
||||
c := &ed.completion
|
||||
c := ed.completion
|
||||
if c.filtering && likeChar(k) {
|
||||
c.changeFilter(c.filter + string(k.Rune))
|
||||
} else if c.filtering && k == (ui.Key{ui.Backspace, 0}) {
|
||||
|
@ -124,8 +122,7 @@ func complDefault(ed *Editor) {
|
|||
}
|
||||
}
|
||||
|
||||
func complTriggerFilter(ed *Editor) {
|
||||
c := &ed.completion
|
||||
func (c *completion) triggerFilter() {
|
||||
if c.filtering {
|
||||
c.filtering = false
|
||||
c.changeFilter("")
|
||||
|
@ -215,12 +212,12 @@ func startCompletionInner(ed *Editor, acceptPrefix bool) {
|
|||
return
|
||||
}
|
||||
}
|
||||
ed.completion = completion{
|
||||
ed.completion.completionState = completionState{
|
||||
completer: completer,
|
||||
complSpec: *complSpec,
|
||||
filtered: complSpec.candidates,
|
||||
}
|
||||
ed.mode = &ed.completion
|
||||
ed.SetMode(ed.completion)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ type Editor struct {
|
|||
active bool
|
||||
activeMutex sync.Mutex
|
||||
|
||||
completionBinding BindingMap
|
||||
navigationBinding BindingMap
|
||||
|
||||
listingBinding BindingMap
|
||||
|
@ -66,9 +65,10 @@ type Editor struct {
|
|||
maxHeight float64
|
||||
|
||||
// Modes.
|
||||
insert *insert
|
||||
command *command
|
||||
hist *hist
|
||||
insert *insert
|
||||
command *command
|
||||
hist *hist
|
||||
completion *completion
|
||||
|
||||
editorState
|
||||
}
|
||||
|
@ -94,7 +94,6 @@ type editorState struct {
|
|||
|
||||
mode Mode
|
||||
|
||||
completion completion
|
||||
navigation navigation
|
||||
|
||||
// A cache of external commands, used in stylist.
|
||||
|
|
|
@ -226,7 +226,7 @@ func (er *editorRenderer) Render(buf *ui.Buffer) {
|
|||
// modify the text (and mark their part as modified).
|
||||
switch mode := es.mode.(type) {
|
||||
case *completion:
|
||||
c := es.completion
|
||||
c := mode
|
||||
clr.setComp(c.begin, c.end, c.selectedCandidate().code)
|
||||
case *hist:
|
||||
begin := len(mode.walker.Prefix())
|
||||
|
|
Loading…
Reference in New Issue
Block a user