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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Features
* Add many CLI flags to startup tips.
* Accept all special commands without trailing semicolons in multi-line mode.
* Add prompt format strings for socket connections.
* Optionally defer auto-completions until a minimum number of characters is typed.


Bug Fixes
Expand Down
40 changes: 38 additions & 2 deletions mycli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@
import click
from configobj import ConfigObj
import keyring
from prompt_toolkit.application.current import get_app
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.completion import Completion, DynamicCompleter
from prompt_toolkit.document import Document
from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
from prompt_toolkit.filters import HasFocus, IsDone
from prompt_toolkit.filters import Condition, HasFocus, IsDone
from prompt_toolkit.formatted_text import ANSI, AnyFormattedText
from prompt_toolkit.key_binding.bindings.named_commands import register as prompt_register
from prompt_toolkit.key_binding.key_processor import KeyPressEvent
Expand Down Expand Up @@ -84,6 +85,36 @@
SUPPORT_INFO = "Home: http://mycli.net\nBug tracker: https://github.com/dbcli/mycli/issues"
DEFAULT_WIDTH = 80
DEFAULT_HEIGHT = 25
MIN_COMPLETION_TRIGGER = 1


@Condition
def complete_while_typing_filter() -> bool:
"""Whether enough characters have been typed to trigger completion.

Written in a verbose way, with a string slice, for efficiency."""
if MIN_COMPLETION_TRIGGER <= 1:
return True
app = get_app()
text = app.current_buffer.text.lstrip()
text_len = len(text)
if text_len < MIN_COMPLETION_TRIGGER:
return False
last_word = text[-MIN_COMPLETION_TRIGGER:]
if len(last_word) == text_len:
return text_len >= MIN_COMPLETION_TRIGGER
if text[:6].lower() in ['source', r'\.']:
# Different word characters for paths; see comment below.
# In fact, it might be nice if paths had a different threshold.
return not bool(re.search(r'[\s!-,:-@\[-^\{\}-]', last_word))
else:
# This is "whitespace and all punctuation except underscore and backtick"
# acting as word breaks, but it would be neat if we could complete differently
# when inside a backtick, accepting all legal characters towards the trigger
# limit. We would have to parse the statement, or at least go back more
# characters, costing performance. This still works within a backtick! So
# long as there are three trailing non-punctuation characters.
return not bool(re.search(r'[\s!-/:-@\[-^\{-~]', last_word))


class MyCli:
Expand Down Expand Up @@ -122,6 +153,8 @@ def __init__(
warn: bool | None = None,
myclirc: str = "~/.myclirc",
) -> None:
global MIN_COMPLETION_TRIGGER

self.sqlexecute = sqlexecute
self.logfile = logfile
self.defaults_suffix = defaults_suffix
Expand Down Expand Up @@ -222,6 +255,9 @@ def __init__(
)
self._completer_lock = threading.Lock()

self.min_completion_trigger = c["main"].as_int("min_completion_trigger")
MIN_COMPLETION_TRIGGER = self.min_completion_trigger

# Register custom special commands.
self.register_special_commands()

Expand Down Expand Up @@ -1147,7 +1183,7 @@ def one_iteration(text: str | None = None) -> None:
completer=DynamicCompleter(lambda: self.completer),
history=history,
auto_suggest=AutoSuggestFromHistory(),
complete_while_typing=True,
complete_while_typing=complete_while_typing_filter,
multiline=cli_is_multiline(self),
style=style_factory(self.syntax_style, self.cli_style),
include_default_pygments_style=False,
Expand Down
4 changes: 4 additions & 0 deletions mycli/myclirc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ show_warnings = False
# possible completions will be listed.
smart_completion = True

# Minimum characters typed before offering completion suggestions.
# Suggestion: 3.
min_completion_trigger = 1

# Multi-line mode allows breaking up the sql statements into multiple lines. If
# this is set to True, then the end of the statements must have a semi-colon.
# If this is set to False then sql statements can't be split into multiple
Expand Down
4 changes: 4 additions & 0 deletions test/myclirc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ show_warnings = False
# possible completions will be listed.
smart_completion = True

# Minimum characters typed before offering completion suggestions.
# Suggestion: 3.
min_completion_trigger = 1

# Multi-line mode allows breaking up the sql statements into multiple lines. If
# this is set to True, then the end of the statements must have a semi-colon.
# If this is set to False then sql statements can't be split into multiple
Expand Down