From a6c1bc1d4af94ca88f50e05ebef4be873dcbb3b5 Mon Sep 17 00:00:00 2001 From: Asmageddon Date: Sun, 4 Mar 2012 15:25:27 +0100 Subject: [PATCH] Modified autocompletion to only list a limited amount of matches(use info for full list), color coded it, modified to show both torrent names and ID as well as highlight matching part, show green 'Autocompletion matches' text for more than 4 matches so it's more readable. Depends on previous commit --- deluge/ui/console/modes/legacy.py | 78 +++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/deluge/ui/console/modes/legacy.py b/deluge/ui/console/modes/legacy.py index 2151f7888..bc29514f7 100644 --- a/deluge/ui/console/modes/legacy.py +++ b/deluge/ui/console/modes/legacy.py @@ -46,13 +46,19 @@ from twisted.internet import defer, reactor from deluge.ui.client import client import deluge.component as component +from deluge.ui.console.modes import format_utils + import logging,os log = logging.getLogger(__name__) +import re LINES_BUFFER_SIZE = 5000 INPUT_HISTORY_SIZE = 500 +AUTOCOMPLETE_MAX_TORRENTS = 20 +AUTOCOMPLETE_MAX_TORRENTS_WITH_PATTERN = 10 + class Legacy(BaseMode): def __init__(self, stdscr, console_config, encoding=None): @@ -509,6 +515,11 @@ class Legacy(BaseMode): """ # First check to see if there is no space, this will mean that it's a # command that needs to be completed. + + #We don't want to split by escaped spaces + def split(string): + return re.split(r"(?= 4: + self.write("{!green!}Autocompletion matches:") + #Only list some of the matching torrents as there can be hundreds of them + if len(possible_matches) > AUTOCOMPLETE_MAX_TORRENTS: + for i in range(0, AUTOCOMPLETE_MAX_TORRENTS): + match = possible_matches[i] + self.write(match.replace(r"\ ", " ")) + diff = len(possible_matches) - AUTOCOMPLETE_MAX_TORRENTS + self.write("{!error!}And %i more, use the 'info ' command to view more" % diff ) + else: + for match in possible_matches: + self.write(match.replace(r"\ ", " ")) else: p = " ".join(line.split(" ")[:-1]) new_line = " ".join([p, os.path.commonprefix(possible_matches)]).lstrip() if len(new_line) > len(line): line = new_line cursor = len(line) + #We only want to print eventual colors or other control characters, not return them + line = format_utils.remove_formatting(line) + cursor = len(line) return (line, cursor) @@ -561,14 +588,49 @@ class Legacy(BaseMode): :returns: list of matches """ + + if len(line) == 0: + empty = True + else: + empty = False + + raw_line = line + line = line.replace("\\ ", " ") + possible_matches = [] - # Find all possible matches + match_count = 0 for torrent_id, torrent_name in self.torrents: if torrent_id.startswith(line): - possible_matches.append(torrent_id) + match_count += 1 if torrent_name.startswith(line): - possible_matches.append(torrent_name) + match_count += 1 + # Find all possible matches + for torrent_id, torrent_name in self.torrents: + #Escape spaces to avoid, for example, expanding "Doc" into "Doctor Who" and removing everything containing one of these words + escaped_name = torrent_name.replace(" ","\\ ") + #If we only matched one torrent, don't add the full name or it'll also get autocompleted + if match_count == 1: + if torrent_id.startswith(line): + possible_matches.append(torrent_id + " ") + break + if torrent_name.startswith(line): + self.write(escaped_name) + possible_matches.append(escaped_name + " ") + break + else: + l = len(raw_line) + + #Let's avoid listing all torrents twice if there's no pattern + if not empty and torrent_id.startswith(line): + #Highlight the matching part + text = "{!info!}%s{!input!}%s - '%s'" % (torrent_id[:l], torrent_id[l:], torrent_name) + possible_matches.append(text) + if torrent_name.startswith(line): + #TODO - Fix this and stuff above + text = "{!info!}%s{!input!}%s ({!cyan!}%s{!input!})" % (escaped_name[:l], escaped_name[l:], torrent_id) + #text = "%s (%s) " % (escaped_name, torrent_id) + possible_matches.append(text) return possible_matches