prompt_toolkit 键 add_binding 不工作
prompt_toolkit Keys add_binding not working
我正在学习 prompt-toolkit 并尝试使用 prompt-toolkit 解决自定义提示(我已经知道有一个 std.prompt 的工作方式不同)。我正在按照 Jonathan for a similar question.
给出的描述进行操作
到目前为止,我从他提供的 ptpython 示例中取出并拼接了建议的部分,并将其拆分成条带,这样它就接近我想要做的了。显然我错过了实现 UP、DOWN 事件和选择选项的东西。有什么想法吗?
from __future__ import unicode_literals
from prompt_toolkit.application import Application
from prompt_toolkit.buffer import Buffer
from prompt_toolkit.document import Document
from prompt_toolkit.enums import DEFAULT_BUFFER
from prompt_toolkit.interface import CommandLineInterface
from prompt_toolkit.key_binding.manager import KeyBindingManager
from prompt_toolkit.keys import Keys
from prompt_toolkit.layout.containers import Window
from prompt_toolkit.layout.controls import BufferControl
from prompt_toolkit.layout.margins import ScrollbarMargin
from prompt_toolkit.shortcuts import create_eventloop
from prompt_toolkit.filters import IsDone
from prompt_toolkit.layout.controls import TokenListControl
from prompt_toolkit.layout.containers import ConditionalContainer, ScrollOffsets, VSplit, HSplit
from prompt_toolkit.layout.screen import Char
from prompt_toolkit.layout.dimension import LayoutDimension
from prompt_toolkit.mouse_events import MouseEventTypes
from pygments.token import Token
# maybe better use TokenListControl mouse_handler?
def if_mousedown(handler):
def handle_if_mouse_down(cli, mouse_event):
if mouse_event.event_type == MouseEventTypes.MOUSE_DOWN:
return handler(cli, mouse_event)
else:
return NotImplemented
return handle_if_mouse_down
class SelIpt(object):
show_sidebar = False
selected_option_index = 0
option_count = 0
select_input = SelIpt()
tokens = []
T = Token.Sidebar
def get_tokens(cli):
return tokens
def append(index, label):
selected = (index == select_input.selected_option_index)
@if_mousedown
def select_item(cli, mouse_event):
# bind option with this index to mouse event
select_input.selected_option_index = index
token = T.Selected if selected else T
tokens.append((T, ' > ' if selected else ' '))
if selected:
tokens.append((Token.SetCursorPosition, ''))
tokens.append((token.Label, '%-24s' % label, select_item))
tokens.append((T, '\n'))
# prepare the select choices
options = ['mini', 'mausi', 'hasi']
for i, option in enumerate(options):
append(i, option)
tokens.pop() # Remove last newline.
select_input.option_count = 3
manager = KeyBindingManager.for_prompt()
class SelectControl(TokenListControl):
# SelectControl implements the key bindings
@manager.registry.add_binding(Keys.Down, eager=True)
def move_cursor_down(self, cli):
select_input.selected_option_index = (
(select_input.selected_option_index + 1) % select_input.option_count)
@manager.registry.add_binding(Keys.Up, eager=True)
def move_cursor_up(self, cli):
select_input.selected_option_index = (
(select_input.selected_option_index - 1) % select_input.option_count)
buffers={
DEFAULT_BUFFER: Buffer(initial_document=Document('my selection', 0)),
'QUESTION': Buffer(initial_document=Document('what do you want to select?', 0))
}
@manager.registry.add_binding(Keys.Enter, eager=True)
def set_answer(event):
print('moin moin')
buffers[DEFAULT_BUFFER].text = option[select_input.selected_option_index]
event.cli.set_return_value(None)
@manager.registry.add_binding(Keys.ControlQ, eager=True)
@manager.registry.add_binding(Keys.ControlC, eager=True)
def _(event):
event.cli.set_return_value(None)
# assemble layout
prompt = VSplit([
Window(content=BufferControl(buffer_name='QUESTION')),
Window(content=BufferControl(buffer_name=DEFAULT_BUFFER)),
])
select = ConditionalContainer(
Window(
SelectControl(get_tokens, Char(token=Token.Sidebar)),
width=LayoutDimension.exact(43),
height=LayoutDimension(min=3),
scroll_offsets=ScrollOffsets(top=1, bottom=1)
),
filter=~IsDone()
)
layout = HSplit([prompt, select])
app = Application(
layout=layout,
buffers=buffers,
key_bindings_registry=manager.registry,
mouse_support=True
#use_alternate_screen=True
)
eventloop = create_eventloop()
try:
cli = CommandLineInterface(application=app, eventloop=eventloop)
cli.run(reset_current_buffer=False)
finally:
eventloop.close()
# TODO
# move selection to DEFAULT_BUFFER
# make select window disapear after CTRL-Q
# colorize '>'
编写您希望能够处理的键的处理程序 Keys.Up
、Keys.Down
等
这是一个例子:
更直接:
class SelectControl(TokenListControl):
@manager.registry.add_binding(Keys.Down, eager=True)
def move_cursor_down(event):
print(event)
@manager.registry.add_binding(Keys.Up, eager=True)
def move_cursor_up(event):
print(event)
我正在学习 prompt-toolkit 并尝试使用 prompt-toolkit 解决自定义提示(我已经知道有一个 std.prompt 的工作方式不同)。我正在按照 Jonathan for a similar question.
给出的描述进行操作到目前为止,我从他提供的 ptpython 示例中取出并拼接了建议的部分,并将其拆分成条带,这样它就接近我想要做的了。显然我错过了实现 UP、DOWN 事件和选择选项的东西。有什么想法吗?
from __future__ import unicode_literals
from prompt_toolkit.application import Application
from prompt_toolkit.buffer import Buffer
from prompt_toolkit.document import Document
from prompt_toolkit.enums import DEFAULT_BUFFER
from prompt_toolkit.interface import CommandLineInterface
from prompt_toolkit.key_binding.manager import KeyBindingManager
from prompt_toolkit.keys import Keys
from prompt_toolkit.layout.containers import Window
from prompt_toolkit.layout.controls import BufferControl
from prompt_toolkit.layout.margins import ScrollbarMargin
from prompt_toolkit.shortcuts import create_eventloop
from prompt_toolkit.filters import IsDone
from prompt_toolkit.layout.controls import TokenListControl
from prompt_toolkit.layout.containers import ConditionalContainer, ScrollOffsets, VSplit, HSplit
from prompt_toolkit.layout.screen import Char
from prompt_toolkit.layout.dimension import LayoutDimension
from prompt_toolkit.mouse_events import MouseEventTypes
from pygments.token import Token
# maybe better use TokenListControl mouse_handler?
def if_mousedown(handler):
def handle_if_mouse_down(cli, mouse_event):
if mouse_event.event_type == MouseEventTypes.MOUSE_DOWN:
return handler(cli, mouse_event)
else:
return NotImplemented
return handle_if_mouse_down
class SelIpt(object):
show_sidebar = False
selected_option_index = 0
option_count = 0
select_input = SelIpt()
tokens = []
T = Token.Sidebar
def get_tokens(cli):
return tokens
def append(index, label):
selected = (index == select_input.selected_option_index)
@if_mousedown
def select_item(cli, mouse_event):
# bind option with this index to mouse event
select_input.selected_option_index = index
token = T.Selected if selected else T
tokens.append((T, ' > ' if selected else ' '))
if selected:
tokens.append((Token.SetCursorPosition, ''))
tokens.append((token.Label, '%-24s' % label, select_item))
tokens.append((T, '\n'))
# prepare the select choices
options = ['mini', 'mausi', 'hasi']
for i, option in enumerate(options):
append(i, option)
tokens.pop() # Remove last newline.
select_input.option_count = 3
manager = KeyBindingManager.for_prompt()
class SelectControl(TokenListControl):
# SelectControl implements the key bindings
@manager.registry.add_binding(Keys.Down, eager=True)
def move_cursor_down(self, cli):
select_input.selected_option_index = (
(select_input.selected_option_index + 1) % select_input.option_count)
@manager.registry.add_binding(Keys.Up, eager=True)
def move_cursor_up(self, cli):
select_input.selected_option_index = (
(select_input.selected_option_index - 1) % select_input.option_count)
buffers={
DEFAULT_BUFFER: Buffer(initial_document=Document('my selection', 0)),
'QUESTION': Buffer(initial_document=Document('what do you want to select?', 0))
}
@manager.registry.add_binding(Keys.Enter, eager=True)
def set_answer(event):
print('moin moin')
buffers[DEFAULT_BUFFER].text = option[select_input.selected_option_index]
event.cli.set_return_value(None)
@manager.registry.add_binding(Keys.ControlQ, eager=True)
@manager.registry.add_binding(Keys.ControlC, eager=True)
def _(event):
event.cli.set_return_value(None)
# assemble layout
prompt = VSplit([
Window(content=BufferControl(buffer_name='QUESTION')),
Window(content=BufferControl(buffer_name=DEFAULT_BUFFER)),
])
select = ConditionalContainer(
Window(
SelectControl(get_tokens, Char(token=Token.Sidebar)),
width=LayoutDimension.exact(43),
height=LayoutDimension(min=3),
scroll_offsets=ScrollOffsets(top=1, bottom=1)
),
filter=~IsDone()
)
layout = HSplit([prompt, select])
app = Application(
layout=layout,
buffers=buffers,
key_bindings_registry=manager.registry,
mouse_support=True
#use_alternate_screen=True
)
eventloop = create_eventloop()
try:
cli = CommandLineInterface(application=app, eventloop=eventloop)
cli.run(reset_current_buffer=False)
finally:
eventloop.close()
# TODO
# move selection to DEFAULT_BUFFER
# make select window disapear after CTRL-Q
# colorize '>'
编写您希望能够处理的键的处理程序 Keys.Up
、Keys.Down
等
这是一个例子:
更直接:
class SelectControl(TokenListControl):
@manager.registry.add_binding(Keys.Down, eager=True)
def move_cursor_down(event):
print(event)
@manager.registry.add_binding(Keys.Up, eager=True)
def move_cursor_up(event):
print(event)