--- deliantra/Deliantra-Client/DC/MapWidget.pm 2012/11/09 22:53:57 1.165 +++ deliantra/Deliantra-Client/DC/MapWidget.pm 2012/11/26 13:14:43 1.171 @@ -35,27 +35,6 @@ $self } -sub add_command { - my ($self, $command, $tooltip, $widget, $cb) = @_; - - (my $data = $command) =~ s/\\//g; - - $tooltip =~ s/^\s+//; - $tooltip = "$data\n\n$tooltip"; - $tooltip =~ s/\s+$//; - - $::COMPLETER->{command}{$command} = [$data, $tooltip, $widget, $cb, ++$self->{command_id}]; -} - -sub clr_commands { - my ($self) = @_; - - %{$::COMPLETER->{command}} = (); - - $::COMPLETER->hide - if $::COMPLETER; -} - sub server_login { my ($server) = @_; @@ -724,6 +703,7 @@ my $class = shift; my $self = $class->SUPER::new ( + min_w => $::WIDTH * 0.25, # workaround for layout problems #d# bg => [0, 0, 0, 0.8], @_, ); @@ -820,6 +800,14 @@ $self } +sub reset { + my ($self) = @_; + + $self->hide; + delete $self->{command_lists}; + delete $self->{command_list}; +} + sub set_prefix { my ($self, $prefix) = @_; @@ -861,17 +849,27 @@ sub update_labels { my ($self) = @_; + use sort qw(stable); + my $text = $self->{entry}->get_text; length $text or return $self->hide; + return unless $::CONN; + + # regenerate spell list if necessary + $self->{command_list}{spells} ||= [ + map { ("cast $_->{name}", "invoke $_->{name}") } + values %{ $::CONN->{spell} } + ]; + if ($text ne $self->{last_search}) { my @match; if ($text =~ /^(.*?)\s+$/) { my ($cmd, $arg) = $text =~ /^\s*([^[:space:]]*)(.*)$/; - @match = ([[$cmd,'(appended whitespace suppresses completion)'],$text]); + @match = ([[$cmd,' (appended whitespace suppresses completion)'], $text]); } else { # @match is [command, penalty, command with arguments] until sort @@ -887,7 +885,7 @@ # - the more characters the parentheses match, the less attractive # is the match. my $regexp = "^\Q$beg\E" - . join "", map "(?:.*?[ \\\\]|(.*?))\Q$_\E", @chr; + . join "", map "(?:.*?[ _\-]|(.*?))\Q$_\E", @chr; qr<$regexp> }; @@ -896,55 +894,52 @@ qr<$regexp> }; - for (keys %{$self->{command}}) { - # we only match and score if the first character matches, - # so quickly rule out all others first. - next unless $first_char = substr $_, 0, 1; - - my @scores; - - # 1. Complete command [with args] - # command is a prefix of the text - # score is length of complete command matched - # e.g. "invoke summon pet monster bat" - # "invoke" "summon pet monster bat" = 6 - # "invoke summon pet monster" "bat" = 25 - if ((substr $text, 0, length $_) eq $_) { - push @scores, [$_, length $_, $text]; - } + for my $list (@{ $self->{command_lists} }, "spells") { + for (@{ $self->{command_list}{$list} }) { + # we only match and score if the first character matches, + # so quickly rule out all others first. + next unless $first_char = substr $_, 0, 1; + + my @scores; + + # 1. Complete command [with args] + # command is a prefix of the text + # score is length of complete command matched + # e.g. "invoke summon pet monster bat" + # "invoke" "summon pet monster bat" = 6 + # "invoke summon pet monster" "bat" = 25 + if ((substr $text, 0, length $_) eq $_) { + push @scores, [$_, length $_, $text]; + } - # 2. Partial command - # text is a prefix of the full command - # score is the length of the input text - # e.g. "invoke s" - # "invoke small fireball" = 8 - # "invoke summon pet monster" = 8 + # 2. Partial command + # text is a prefix of the full command + # score is the length of the input text + # e.g. "invoke s" + # "invoke small fireball" = 8 + # "invoke summon pet monster" = 8 - if ($_ =~ $regexp_partial) { - push @scores, [$_, length $text, $_]; - } + if ($_ =~ $regexp_partial) { + push @scores, [$_, length $text, $_]; + } - # 3. Abbreviation match - # attempts to use first word of text as an abbreviated command - # score is length of word + 1 - 3 per non-word-initial character + # 3. Abbreviation match + # attempts to use first word of text as an abbreviated command + # score is length of word + 1 - 3 per non-word-initial character - if (my @penalty = $_ =~ $regexp_abbrev) { - push @scores, [$_, (length $cmd) + 1 - (length join "", map "::$_", grep defined, @penalty), "$_$arg"]; - } + if (my @penalty = $_ =~ $regexp_abbrev) { + push @scores, [$_, (length $cmd) + 1 - (length join "", map "::$_", grep defined, @penalty), "$_$arg"]; + } - # Pick the best option for this command - push @match, (sort { - $b->[1] <=> $a->[1] - } @scores)[0]; + # Pick the best option for this command + push @match, (sort { $b->[1] <=> $a->[1] } @scores)[0]; + } } # @match is now [command object, command with arguments] - @match = map [$self->{command}{$_->[0]}, $_->[2]], - sort { - $b->[1] <=> $a->[1] - or $self->{command}{$a->[0]}[4] <=> $self->{command}{$b->[0]}[4] - or (length $b->[0]) <=> (length $a->[0]) - } @match; + @match = map [$_->[0], $_->[2]], + sort { $b->[1] <=> $a->[1] } + @match; } $self->{last_search} = $text; @@ -983,7 +978,7 @@ if (@labels) { $label->set_text ("$match->[1]"); - $label->set_tooltip ("$match->[0][1]"); + $label->set_tooltip ("#(command/$match->[1])"); } else { $label->set_text ("..."); $label->set_tooltip ("Use Cursor-Down to view more matches");