1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
import logging
from prompt_toolkit.enums import EditingMode
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.filters import (
completion_is_selected,
is_searching,
has_completions,
has_selection,
vi_mode,
)
from .pgbuffer import buffer_should_be_handled, safe_multi_line_mode
_logger = logging.getLogger(__name__)
def pgcli_bindings(pgcli):
"""Custom key bindings for pgcli."""
kb = KeyBindings()
tab_insert_text = " " * 4
@kb.add("f2")
def _(event):
"""Enable/Disable SmartCompletion Mode."""
_logger.debug("Detected F2 key.")
pgcli.completer.smart_completion = not pgcli.completer.smart_completion
@kb.add("f3")
def _(event):
"""Enable/Disable Multiline Mode."""
_logger.debug("Detected F3 key.")
pgcli.multi_line = not pgcli.multi_line
@kb.add("f4")
def _(event):
"""Toggle between Vi and Emacs mode."""
_logger.debug("Detected F4 key.")
pgcli.vi_mode = not pgcli.vi_mode
event.app.editing_mode = EditingMode.VI if pgcli.vi_mode else EditingMode.EMACS
@kb.add("f5")
def _(event):
"""Toggle between Vi and Emacs mode."""
_logger.debug("Detected F5 key.")
pgcli.explain_mode = not pgcli.explain_mode
@kb.add("tab")
def _(event):
"""Force autocompletion at cursor on non-empty lines."""
_logger.debug("Detected <Tab> key.")
buff = event.app.current_buffer
doc = buff.document
if doc.on_first_line or doc.current_line.strip():
if buff.complete_state:
buff.complete_next()
else:
buff.start_completion(select_first=True)
else:
buff.insert_text(tab_insert_text, fire_event=False)
@kb.add("escape", filter=has_completions)
def _(event):
"""Force closing of autocompletion."""
_logger.debug("Detected <Esc> key.")
event.current_buffer.complete_state = None
event.app.current_buffer.complete_state = None
@kb.add("c-space")
def _(event):
"""
Initialize autocompletion at cursor.
If the autocompletion menu is not showing, display it with the
appropriate completions for the context.
If the menu is showing, select the next completion.
"""
_logger.debug("Detected <C-Space> key.")
b = event.app.current_buffer
if b.complete_state:
b.complete_next()
else:
b.start_completion(select_first=False)
@kb.add("enter", filter=completion_is_selected)
def _(event):
"""Makes the enter key work as the tab key only when showing the menu.
In other words, don't execute query when enter is pressed in
the completion dropdown menu, instead close the dropdown menu
(accept current selection).
"""
_logger.debug("Detected enter key during completion selection.")
event.current_buffer.complete_state = None
event.app.current_buffer.complete_state = None
# When using multi_line input mode the buffer is not handled on Enter (a new line is
# inserted instead), so we force the handling if we're not in a completion or
# history search, and one of several conditions are True
@kb.add(
"enter",
filter=~(completion_is_selected | is_searching)
& buffer_should_be_handled(pgcli),
)
def _(event):
_logger.debug("Detected enter key.")
event.current_buffer.validate_and_handle()
@kb.add("escape", "enter", filter=~vi_mode & ~safe_multi_line_mode(pgcli))
def _(event):
"""Introduces a line break regardless of multi-line mode or not."""
_logger.debug("Detected alt-enter key.")
event.app.current_buffer.insert_text("\n")
@kb.add("c-p", filter=~has_selection)
def _(event):
"""Move up in history."""
event.current_buffer.history_backward(count=event.arg)
@kb.add("c-n", filter=~has_selection)
def _(event):
"""Move down in history."""
event.current_buffer.history_forward(count=event.arg)
return kb
|