Skip to content

Commit

Permalink
🔀 Merge pull request #29 from davep/empty-history-suggestions
Browse files Browse the repository at this point in the history
Suggest known commands if there is no history
  • Loading branch information
davep authored Feb 18, 2025
2 parents ff1421e + cc3bd9a commit 7cbf807
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 10 deletions.
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
([#24](https://github.com/davep/hike/pull/24))
- Added `help` as a command that the command line understands.
([#24](https://github.com/davep/hike/pull/24))
- Changed command line completion so that if history is empty, known
commands are suggested. ([#29](https://github.com/davep/hike/pull/29))

## v0.2.0

Expand Down
31 changes: 23 additions & 8 deletions src/hike/widgets/command_line/base_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,38 @@ def split_command(text: str) -> tuple[str, str]:
return command.strip(), tail.strip()

@classmethod
def is_command(cls, command: str) -> bool:
"""Does the given command appear to be a match?
Args:
command: The command to test.
def suggestions(cls) -> tuple[str, ...]:
"""The suggested command matches for this command.
Returns:
`True` if the given command seems to be a match, `False` if not.
A tuple of suggestions for the command.
Notes:
Any commands that look like value placeholders will be filtered
out.
"""
# Build up all the possible matches. These are built from the main
# command and also the aliases. By convention the code will often
# use `code` fences for commands, and the aliases will be a comma
# list, so we clean that up as we go...
return command.strip().lower() in (
candidate.strip().lower().removeprefix("`").removesuffix("`")
return tuple(
candidate.strip().removeprefix("`").removesuffix("`")
for candidate in (cls.COMMAND, *cls.ALIASES.split(","))
# Note that we filter out anything that looks like `<this>`.
if not candidate.startswith("`<")
)

@classmethod
def is_command(cls, command: str) -> bool:
"""Does the given command appear to be a match?
Args:
command: The command to test.
Returns:
`True` if the given command seems to be a match, `False` if not.
"""
return command.strip().lower() in cls.suggestions()


### base_command.py ends here
13 changes: 11 additions & 2 deletions src/hike/widgets/command_line/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
##############################################################################
# Python imports.
from dataclasses import dataclass
from itertools import chain
from typing import Final

##############################################################################
Expand Down Expand Up @@ -149,8 +150,16 @@ class CommandLine(Vertical):

@property
def _history_suggester(self) -> SuggestFromList:
"""A suggester for the history of input."""
return SuggestFromList(reversed(list(self.history)))
"""A suggester for the history of input.
If there us no history yet then a list of commands and aliases will
be used.
"""
return SuggestFromList(
reversed(list(self.history))
if self.history
else chain(*(command.suggestions() for command in COMMANDS))
)

def compose(self) -> ComposeResult:
"""Compose the content of the widget."""
Expand Down

0 comments on commit 7cbf807

Please sign in to comment.