Open erezsh opened 4 years ago
There are several ways right now to achieve this:
Install one key binding for the enter key, but without filter, that handles both cases. Then in the key binding check whether it's multiline or not and act accordingly.
get_app
always returns the currently curring application. From there you can get the buffer named DEFAULT_BUFFER.
text = get_app().layout.get_buffer_by_name('DEFAULT_BUFFER').text
You can create a new filter that uses this and according to this value evaluates to true or false.
Expose the PromptSession into the scope where the key bindings are created. Something like this:
def main():
kb = Keybindings()
@kb.add('enter')
def handle_enter(event):
print(prompt_session.default_buffer.text)
prompt_session = PromptSession(key_bindings=kb...)
prompt_session.prompt()
Thanks! One more question (I searched the docs but couldn't find it)
In option 3, How do I tell the event to continue as usual?
Good question!
Right now, we have two options, I think:
Create a filter that activates this key binding only if the "usual" binding should never be executed. Of course, the filter is not supposed to change state. It should only observe state. This means that you can't add functionality to an existing key binding, this way.
Call the original key binding from within the new key binding, passing along the event
object. For PromptSession
, the function for the enter
binding is not exposed publicly, so you can't call that function. In this case however, the implementation is only one line: self.default_buffer.validate_and_handle()
. If we add that to the above snippet, this becomes:
from prompt_toolkit.filters import has_focus
from prompt_toolkit.enums import DEFAULT_BUFFER
def main():
kb = Keybindings()
@kb.add('enter', filter=has_focus(DEFAULT_BUFFER))
def handle_enter(event):
# Your stuff.
print(prompt_session.default_buffer.text)
# Call the original handler.
prompt_session.default_buffer.validate_and_handle()
prompt_session = PromptSession(key_bindings=kb...)
prompt_session.prompt()
I think it would be a nice addition to prompt_toolkit, to do stuff like:
event.call_other_handlers()
Something which is similar to a super()
call. I'll think about that.
Yes, I believe that would be helpful. Javascript goes the other way around, always calling super() unless you call event.stopPropagation()
. Might be too much, but it's an indicator that it's a common pattern in ui.
Right now there's no simple way to decide whether
Enter
should accept or open a new line based on the content of the text.It seems like a very useful feature in general. For example, to write something like ptpython (that doesn't seem to use this feature)
Please correct me if I'm wrong about that.
Also, right now
is_true(self.multiline)
is called about 10 times for each character pressed. You really only need to call it once.