From: Wincent Colaiuta <win@wincent.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, dzwell@gmail.com, peff@peff.net,
Matthieu.Moy@imag.fr, Wincent Colaiuta <win@wincent.com>
Subject: [PATCH] Highlight keyboard shortcuts in git-add--interactive
Date: Thu, 29 Nov 2007 13:00:38 +0100 [thread overview]
Message-ID: <1196337638-45972-1-git-send-email-win@wincent.com> (raw)
In-Reply-To: <7vmysx2ac8.fsf@gitster.siamese.dyndns.org>
The user interface provided by the command loop in git-add--interactive
gives the impression that subcommands can only be launched by entering
an integer identifier from 1 through 8.
A "hidden" feature is that any string can be entered, and an anchored
regex search is used to find the first matching option.
This patch makes this feature a little more obvious by highlighting the
first character of each subcommand (for example "patch" is displayed as
"[p]atch").
A new function is added to detect the shortest unique prefix and this
is used to decide what to highlight. Highlighting is also applied when
choosing files.
In the case where the common prefix may be unreasonably large
highlighting is omitted; in this patch the soft limit (above which the
highlighting will be omitted for a particular item) is 0 (in other words,
there is no soft limit) and the hard limit (above which highlighting will
be omitted for all items) is 3, but this can be tweaked.
The actual highlighting is done by the highlight_prefix function, which
will enable us to implement ANSI color code-based highlighting (most
likely using underline or boldface) in the future.
Signed-off-by: Wincent Colaiuta <win@wincent.com>
---
git-add--interactive.perl | 87 ++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 82 insertions(+), 5 deletions(-)
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index fb1e92a..6e5781b 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -44,7 +44,6 @@ my $status_fmt = '%12s %12s %s';
my $status_head = sprintf($status_fmt, 'staged', 'unstaged', 'path');
# Returns list of hashes, contents of each of which are:
-# PRINT: print message
# VALUE: pathname
# BINARY: is a binary path
# INDEX: is index different from HEAD?
@@ -122,8 +121,6 @@ sub list_modified {
}
push @return, +{
VALUE => $_,
- PRINT => (sprintf $status_fmt,
- $it->{INDEX}, $it->{FILE}, $_),
%$it,
};
}
@@ -159,10 +156,82 @@ sub find_unique {
return $found;
}
+# inserts string into trie and updates count for each character
+sub update_trie {
+ my ($trie, $string) = @_;
+ foreach (split //, $string) {
+ $trie = $trie->{$_} ||= {COUNT => 0};
+ $trie->{COUNT}++;
+ }
+}
+
+# returns an array of tuples (prefix, remainder)
+sub find_unique_prefixes {
+ my @stuff = @_;
+ my @return = ();
+
+ # any single prefix exceeding the soft limit is omitted
+ # if any prefix exceeds the hard limit all are omitted
+ # 0 indicates no limit
+ my $soft_limit = 0;
+ my $hard_limit = 3;
+
+ # build a trie modelling all possible options
+ my %trie;
+ foreach my $print (@stuff) {
+ if ((ref $print) eq 'ARRAY') {
+ $print = $print->[0];
+ }
+ else {
+ $print = $print->{VALUE};
+ }
+ update_trie(\%trie, $print);
+ push @return, $print;
+ }
+
+ # use the trie to find the unique prefixes
+ for (my $i = 0; $i < @return; $i++) {
+ my $ret = $return[$i];
+ my @letters = split //, $ret;
+ my %search = %trie;
+ my ($prefix, $remainder);
+ my $j;
+ for ($j = 0; $j < @letters; $j++) {
+ my $letter = $letters[$j];
+ if ($search{$letter}{COUNT} == 1) {
+ $prefix = substr $ret, 0, $j + 1;
+ $remainder = substr $ret, $j + 1;
+ last;
+ }
+ else {
+ my $prefix = substr $ret, 0, $j;
+ return ()
+ if ($hard_limit && $j + 1 > $hard_limit);
+ }
+ %search = %{$search{$letter}};
+ }
+ if ($soft_limit && $j + 1 > $soft_limit) {
+ $prefix = undef;
+ $remainder = $ret;
+ }
+ $return[$i] = [$prefix, $remainder];
+ }
+ return @return;
+}
+
+# given a prefix/remainder tuple return a string with the prefix highlighted
+# for now use square brackets; later might use ANSI colors (underline, bold)
+sub highlight_prefix {
+ my $prefix = shift;
+ my $remainder = shift;
+ $prefix ? "[$prefix]$remainder" : $remainder;
+}
+
sub list_and_choose {
my ($opts, @stuff) = @_;
my (@chosen, @return);
my $i;
+ my @prefixes = find_unique_prefixes(@stuff) unless $opts->{LIST_ONLY};
TOPLOOP:
while (1) {
@@ -179,10 +248,18 @@ sub list_and_choose {
my $print = $stuff[$i];
if (ref $print) {
if ((ref $print) eq 'ARRAY') {
- $print = $print->[0];
+ $print = @prefixes ?
+ highlight_prefix(@{$prefixes[$i]}) :
+ $print->[0];
}
else {
- $print = $print->{PRINT};
+ my $value = @prefixes ?
+ highlight_prefix(@{$prefixes[$i]}) :
+ $print->{VALUE};
+ $print = sprintf($status_fmt,
+ $print->{INDEX},
+ $print->{FILE},
+ $value);
}
}
printf("%s%2d: %s", $chosen, $i+1, $print);
--
1.5.3.6.953.gdffc
next prev parent reply other threads:[~2007-11-29 12:03 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-21 14:27 [PATCH] Highlight keyboard shortcuts in git-add--interactive Wincent Colaiuta
2007-11-21 14:32 ` Matthieu Moy
2007-11-21 15:28 ` Jeff King
2007-11-21 23:00 ` Dan Zwell
2007-11-28 23:56 ` Junio C Hamano
2007-11-29 1:08 ` Wincent Colaiuta
2007-11-29 12:00 ` Wincent Colaiuta [this message]
2007-11-29 14:51 ` Jeff King
2007-12-01 2:36 ` Junio C Hamano
2007-12-01 13:58 ` Wincent Colaiuta
2007-12-01 14:07 ` [PATCH 1/2] " Wincent Colaiuta
2007-12-01 14:07 ` [PATCH 2/2] Teach git-add--interactive to highlight untracked file prefixes Wincent Colaiuta
2007-12-01 14:15 ` [PATCH 1/2] Highlight keyboard shortcuts in git-add--interactive Wincent Colaiuta
2007-12-01 14:29 ` [REPLACEMENT PATCH] " Wincent Colaiuta
2007-12-02 14:11 ` [PATCH] " Wincent Colaiuta
2007-12-02 19:06 ` Junio C Hamano
2007-12-03 8:09 ` Wincent Colaiuta
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1196337638-45972-1-git-send-email-win@wincent.com \
--to=win@wincent.com \
--cc=Matthieu.Moy@imag.fr \
--cc=dzwell@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).