aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/compose.go3
-rw-r--r--app/exline.go3
-rw-r--r--config/binds.conf1
-rw-r--r--config/binds.go32
-rw-r--r--doc/aerc-binds.5.scd6
-rw-r--r--lib/ui/textinput.go30
6 files changed, 47 insertions, 28 deletions
diff --git a/app/compose.go b/app/compose.go
index 9ab8206b..bf1d32cb 100644
--- a/app/compose.go
+++ b/app/compose.go
@@ -245,6 +245,7 @@ func (c *Composer) buildComposeHeader(cmpl *completer.Completer) {
cmpl.ForHeader(h),
uiConfig.CompletionDelay,
uiConfig.CompletionMinChars,
+ &config.Binds.Compose.CompleteKey,
)
}
c.editors[h] = e
@@ -277,6 +278,7 @@ func (c *Composer) buildComposeHeader(cmpl *completer.Completer) {
cmpl.ForHeader(h),
uiConfig.CompletionDelay,
uiConfig.CompletionMinChars,
+ &config.Binds.Compose.CompleteKey,
)
}
c.editors[h] = e
@@ -1420,6 +1422,7 @@ func (c *Composer) addEditor(header string, value string, appendHeader bool) str
c.completer.ForHeader(header),
uiConfig.CompletionDelay,
uiConfig.CompletionMinChars,
+ &config.Binds.Compose.CompleteKey,
)
}
c.editors[header] = e
diff --git a/app/exline.go b/app/exline.go
index b941b100..61fc340a 100644
--- a/app/exline.go
+++ b/app/exline.go
@@ -26,6 +26,7 @@ func NewExLine(cmd string, commit func(cmd string), finish func(),
tabcomplete,
config.Ui.CompletionDelay,
config.Ui.CompletionMinChars,
+ &config.Binds.Global.CompleteKey,
)
}
exline := &ExLine{
@@ -43,6 +44,7 @@ func (x *ExLine) TabComplete(tabComplete func(string) ([]string, string)) {
tabComplete,
config.Ui.CompletionDelay,
config.Ui.CompletionMinChars,
+ &config.Binds.Global.CompleteKey,
)
}
@@ -55,6 +57,7 @@ func NewPrompt(prompt string, commit func(text string),
tabcomplete,
config.Ui.CompletionDelay,
config.Ui.CompletionMinChars,
+ &config.Binds.Global.CompleteKey,
)
}
exline := &ExLine{
diff --git a/config/binds.conf b/config/binds.conf
index a38795d5..58d81508 100644
--- a/config/binds.conf
+++ b/config/binds.conf
@@ -115,6 +115,7 @@ $ex = <C-x>
# view
$noinherit = true
$ex = <C-x>
+$complete = <C-o>
<C-k> = :prev-field<Enter>
<C-Up> = :prev-field<Enter>
<C-j> = :next-field<Enter>
diff --git a/config/binds.go b/config/binds.go
index 4552030d..1ea36a2d 100644
--- a/config/binds.go
+++ b/config/binds.go
@@ -57,6 +57,8 @@ type KeyBindings struct {
Globals bool
// Which key opens the ex line (default is :)
ExKey KeyStroke
+ // Which key triggers completion (default is <tab>)
+ CompleteKey KeyStroke
// private
contextualBinds []*BindingConfigContext
@@ -154,7 +156,8 @@ func parseBinds(root string) error {
func LoadBindingSection(sec *ini.Section) (*KeyBindings, error) {
bindings := NewKeyBindings()
for key, value := range sec.KeysHash() {
- if key == "$ex" {
+ switch key {
+ case "$ex":
strokes, err := ParseKeyStrokes(value)
if err != nil {
return nil, err
@@ -163,9 +166,7 @@ func LoadBindingSection(sec *ini.Section) (*KeyBindings, error) {
return nil, errors.New("Invalid binding")
}
bindings.ExKey = strokes[0]
- continue
- }
- if key == "$noinherit" {
+ case "$noinherit":
if value == "false" {
continue
}
@@ -173,13 +174,22 @@ func LoadBindingSection(sec *ini.Section) (*KeyBindings, error) {
return nil, errors.New("Invalid binding")
}
bindings.Globals = false
- continue
- }
- binding, err := ParseBinding(key, value)
- if err != nil {
- return nil, err
+ case "$complete":
+ strokes, err := ParseKeyStrokes(value)
+ if err != nil {
+ return nil, err
+ }
+ if len(strokes) != 1 {
+ return nil, errors.New("Invalid binding")
+ }
+ bindings.CompleteKey = strokes[0]
+ default:
+ binding, err := ParseBinding(key, value)
+ if err != nil {
+ return nil, err
+ }
+ bindings.Add(binding)
}
- bindings.Add(binding)
}
return bindings, nil
}
@@ -266,6 +276,7 @@ func LoadBinds(binds *ini.File, baseName string, baseGroup **KeyBindings) error
func NewKeyBindings() *KeyBindings {
return &KeyBindings{
ExKey: KeyStroke{tcell.ModNone, tcell.KeyRune, ':'},
+ CompleteKey: KeyStroke{tcell.ModNone, tcell.KeyTab, 0},
Globals: true,
contextualCache: make(map[bindsContextKey]*KeyBindings),
contextualCounts: make(map[bindsContextType]int),
@@ -329,6 +340,7 @@ func MergeBindings(bindings ...*KeyBindings) *KeyBindings {
}
merged.Bindings = filterAndCleanBindings(merged.Bindings)
merged.ExKey = bindings[0].ExKey
+ merged.CompleteKey = bindings[0].CompleteKey
merged.Globals = bindings[0].Globals
return merged
}
diff --git a/doc/aerc-binds.5.scd b/doc/aerc-binds.5.scd
index 228c6cd1..99ef1188 100644
--- a/doc/aerc-binds.5.scd
+++ b/doc/aerc-binds.5.scd
@@ -122,6 +122,12 @@ available in each binding context:
Default: _:_
+*$complete* = _<key-stroke>_
+ This can be set to a keystroke which will trigger command completion in
+ this context for text inputs that support it.
+
+ Default: _<tab>_
+
# SUPPORTED KEYS
In addition to letters and some characters (e.g. *a*, *RR*, *gu*, *?*, *!*,
diff --git a/lib/ui/textinput.go b/lib/ui/textinput.go
index dd946aec..4b051d88 100644
--- a/lib/ui/textinput.go
+++ b/lib/ui/textinput.go
@@ -35,6 +35,7 @@ type TextInput struct {
completeDelay time.Duration
completeDebouncer *time.Timer
completeMinChars int
+ completeKey *config.KeyStroke
uiConfig *config.UIConfig
}
@@ -62,12 +63,12 @@ func (ti *TextInput) Prompt(prompt string) *TextInput {
func (ti *TextInput) TabComplete(
tabcomplete func(s string) ([]string, string),
- d time.Duration,
- minChars int,
+ d time.Duration, minChars int, key *config.KeyStroke,
) *TextInput {
ti.tabcomplete = tabcomplete
ti.completeDelay = d
ti.completeMinChars = minChars
+ ti.completeKey = key
return ti
}
@@ -344,55 +345,48 @@ func (ti *TextInput) Event(event tcell.Event) bool {
ti.Lock()
defer ti.Unlock()
if event, ok := event.(*tcell.EventKey); ok {
+ c := ti.completeKey
+ if c != nil && c.Key == event.Key() && c.Modifiers == event.Modifiers() {
+ ti.showCompletions()
+ return true
+ }
+
+ ti.invalidateCompletions()
+
switch event.Key() {
case tcell.KeyBackspace, tcell.KeyBackspace2:
- ti.invalidateCompletions()
ti.backspace()
case tcell.KeyCtrlD, tcell.KeyDelete:
- ti.invalidateCompletions()
ti.deleteChar()
case tcell.KeyCtrlB, tcell.KeyLeft:
- ti.invalidateCompletions()
if ti.index > 0 {
ti.index--
ti.ensureScroll()
ti.Invalidate()
}
case tcell.KeyCtrlF, tcell.KeyRight:
- ti.invalidateCompletions()
if ti.index < len(ti.text) {
ti.index++
ti.ensureScroll()
ti.Invalidate()
}
case tcell.KeyCtrlA, tcell.KeyHome:
- ti.invalidateCompletions()
ti.index = 0
ti.ensureScroll()
ti.Invalidate()
case tcell.KeyCtrlE, tcell.KeyEnd:
- ti.invalidateCompletions()
ti.index = len(ti.text)
ti.ensureScroll()
ti.Invalidate()
case tcell.KeyCtrlK:
- ti.invalidateCompletions()
ti.deleteLineForward()
case tcell.KeyCtrlW:
- ti.invalidateCompletions()
ti.deleteWord()
case tcell.KeyCtrlU:
- ti.invalidateCompletions()
ti.deleteLineBackward()
case tcell.KeyESC:
- if ti.completions != nil {
- ti.invalidateCompletions()
- ti.Invalidate()
- }
- case tcell.KeyTab:
- ti.showCompletions()
+ ti.Invalidate()
case tcell.KeyRune:
- ti.invalidateCompletions()
ti.insert(event.Rune())
}
}