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.AddBuiltinFns("edit:", fns)
|
||||||
|
|
||||||
ns.AddNs("completion",
|
|
||||||
initModeAPI("completion:", completionFns, &ed.completionBinding))
|
|
||||||
ns.AddNs("navigation",
|
ns.AddNs("navigation",
|
||||||
initModeAPI("navigation:", navigationFns, &ed.navigationBinding))
|
initModeAPI("navigation:", navigationFns, &ed.navigationBinding))
|
||||||
|
|
||||||
|
|
|
@ -15,21 +15,14 @@ import (
|
||||||
|
|
||||||
// Interface.
|
// Interface.
|
||||||
|
|
||||||
var completionFns = map[string]func(*Editor){
|
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,
|
|
||||||
}
|
|
||||||
|
|
||||||
type completion struct {
|
type completion struct {
|
||||||
|
binding BindingMap
|
||||||
|
completionState
|
||||||
|
}
|
||||||
|
|
||||||
|
type completionState struct {
|
||||||
complSpec
|
complSpec
|
||||||
completer string
|
completer string
|
||||||
|
|
||||||
|
@ -42,8 +35,37 @@ type completion struct {
|
||||||
height int
|
height int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*completion) Binding(ed *Editor, k ui.Key) eval.Callable {
|
func init() { atEditorInit(initCompletion) }
|
||||||
return ed.completionBinding.GetOrDefault(k)
|
|
||||||
|
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 {
|
func (c *completion) needScrollbar() bool {
|
||||||
|
@ -63,42 +85,18 @@ func (c *completion) CursorOnModeLine() bool {
|
||||||
return c.filtering
|
return c.filtering
|
||||||
}
|
}
|
||||||
|
|
||||||
func complStart(ed *Editor) {
|
func (c *completion) left() {
|
||||||
startCompletionInner(ed, false)
|
if x := c.selected - c.height; x >= 0 {
|
||||||
}
|
c.selected = x
|
||||||
|
|
||||||
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 complRight(ed *Editor) {
|
func (c *completion) right() {
|
||||||
if c := ed.completion.selected + ed.completion.height; c < len(ed.completion.filtered) {
|
if x := c.selected + c.height; x < len(c.filtered) {
|
||||||
ed.completion.selected = c
|
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.
|
// acceptCompletion accepts currently selected completion candidate.
|
||||||
func complAccept(ed *Editor) {
|
func complAccept(ed *Editor) {
|
||||||
c := ed.completion
|
c := ed.completion
|
||||||
|
@ -110,7 +108,7 @@ func complAccept(ed *Editor) {
|
||||||
|
|
||||||
func complDefault(ed *Editor) {
|
func complDefault(ed *Editor) {
|
||||||
k := ed.lastKey
|
k := ed.lastKey
|
||||||
c := &ed.completion
|
c := ed.completion
|
||||||
if c.filtering && likeChar(k) {
|
if c.filtering && likeChar(k) {
|
||||||
c.changeFilter(c.filter + string(k.Rune))
|
c.changeFilter(c.filter + string(k.Rune))
|
||||||
} else if c.filtering && k == (ui.Key{ui.Backspace, 0}) {
|
} else if c.filtering && k == (ui.Key{ui.Backspace, 0}) {
|
||||||
|
@ -124,8 +122,7 @@ func complDefault(ed *Editor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func complTriggerFilter(ed *Editor) {
|
func (c *completion) triggerFilter() {
|
||||||
c := &ed.completion
|
|
||||||
if c.filtering {
|
if c.filtering {
|
||||||
c.filtering = false
|
c.filtering = false
|
||||||
c.changeFilter("")
|
c.changeFilter("")
|
||||||
|
@ -215,12 +212,12 @@ func startCompletionInner(ed *Editor, acceptPrefix bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ed.completion = completion{
|
ed.completion.completionState = completionState{
|
||||||
completer: completer,
|
completer: completer,
|
||||||
complSpec: *complSpec,
|
complSpec: *complSpec,
|
||||||
filtered: complSpec.candidates,
|
filtered: complSpec.candidates,
|
||||||
}
|
}
|
||||||
ed.mode = &ed.completion
|
ed.SetMode(ed.completion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ type Editor struct {
|
||||||
active bool
|
active bool
|
||||||
activeMutex sync.Mutex
|
activeMutex sync.Mutex
|
||||||
|
|
||||||
completionBinding BindingMap
|
|
||||||
navigationBinding BindingMap
|
navigationBinding BindingMap
|
||||||
|
|
||||||
listingBinding BindingMap
|
listingBinding BindingMap
|
||||||
|
@ -66,9 +65,10 @@ type Editor struct {
|
||||||
maxHeight float64
|
maxHeight float64
|
||||||
|
|
||||||
// Modes.
|
// Modes.
|
||||||
insert *insert
|
insert *insert
|
||||||
command *command
|
command *command
|
||||||
hist *hist
|
hist *hist
|
||||||
|
completion *completion
|
||||||
|
|
||||||
editorState
|
editorState
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,6 @@ type editorState struct {
|
||||||
|
|
||||||
mode Mode
|
mode Mode
|
||||||
|
|
||||||
completion completion
|
|
||||||
navigation navigation
|
navigation navigation
|
||||||
|
|
||||||
// A cache of external commands, used in stylist.
|
// 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).
|
// modify the text (and mark their part as modified).
|
||||||
switch mode := es.mode.(type) {
|
switch mode := es.mode.(type) {
|
||||||
case *completion:
|
case *completion:
|
||||||
c := es.completion
|
c := mode
|
||||||
clr.setComp(c.begin, c.end, c.selectedCandidate().code)
|
clr.setComp(c.begin, c.end, c.selectedCandidate().code)
|
||||||
case *hist:
|
case *hist:
|
||||||
begin := len(mode.walker.Prefix())
|
begin := len(mode.walker.Prefix())
|
||||||
|
|
Loading…
Reference in New Issue
Block a user