Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions examples/autocompletion-with-cursor-position.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python
"""
Autocompletion example with cursor position not at the end of the completion.

Press [Tab] to complete the current word.
- The first Tab press fills in the common part of all completions
and shows all the completions. (In the menu)
- Any following tab press cycles through all the possible completions.
"""
from __future__ import unicode_literals
from collections import namedtuple

from prompt_toolkit import prompt, completion
from prompt_toolkit.completion import Completer, Completion

CompletionWithCursorPosition = namedtuple('CompletionWithCursorPosition',
'text cursor_position')

class CursorPositionCompleter(Completer):
"""
Simple autocompletion on a list of words with associated cursor positions.

:param completions: List of CompletionWithCursorPosition namedtuples.
"""
def __init__(self, completions):
self.completions = completions

def get_completions(self, document, complete_event):
before_cursor = document.get_word_before_cursor()
return (Completion(c.text, -len(before_cursor), cursor_position=c.cursor_position)
for c in self.completions
if c.text.startswith(before_cursor))

completions = {
CompletionWithCursorPosition('upper_case()', 1),
CompletionWithCursorPosition('lower_case()', 1),
CompletionWithCursorPosition('list_add(list:=, element:=)', len(', element:=)')),
CompletionWithCursorPosition('<html></html>', len('</html>'))
}

comp = CursorPositionCompleter(completions)

def main():
text = prompt('Input: ', completer=comp,
complete_while_typing=False)
print('You said: %s' % text)


if __name__ == '__main__':
main()
2 changes: 1 addition & 1 deletion prompt_toolkit/buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def new_text_and_position(self):
before = original_text_before_cursor[:c.start_position]

new_text = before + c.text + original_text_after_cursor
new_cursor_position = len(before) + len(c.text)
new_cursor_position = len(before) + len(c.text) - c.cursor_position
return new_text, new_cursor_position

@property
Expand Down
4 changes: 3 additions & 1 deletion prompt_toolkit/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ class Completion(object):
completion, e.g. the path or source where it's coming from.
:param get_display_meta: Lazy `display_meta`. Retrieve meta information
only when meta is displayed.
:param cursor_position: Cursor position after completion, from end
"""
def __init__(self, text, start_position=0, display=None, display_meta=None,
get_display_meta=None):
get_display_meta=None, cursor_position=0):
self.text = text
self.start_position = start_position
self._display_meta = display_meta
self._get_display_meta = get_display_meta
self.cursor_position = cursor_position

if display is None:
self.display = text
Expand Down
2 changes: 2 additions & 0 deletions prompt_toolkit/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,8 @@ def callback():
if common_part:
# Insert + run completer again.
buffer.insert_text(common_part)
if len(completions) == 1:
buffer.cursor_position -= completions[0].cursor_position
async_completer()
set_completions = False
else:
Expand Down