diff options
Diffstat (limited to 'vim-mode')
| -rw-r--r-- | vim-mode/vim_mode.pl | 75 | 
1 files changed, 58 insertions, 17 deletions
| diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index b0dfe6a..7503aea 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -234,6 +234,15 @@ my $movements_multiple =  sub cmd_undo {      print "Undo!" if DEBUG; +    if ($undo_index > $#undo_buffer) { +        $undo_index = $#undo_buffer; +        print "No further undo."; +    } elsif ($undo_index != $#undo_buffer) { +        $undo_index++; +    } +    print "Undoing entry $undo_index of " . $#undo_buffer; +     +    _restore_undo_entry($undo_index);  }  sub cmd_redo { @@ -745,10 +754,11 @@ sub got_key {              _stop();              return;          } elsif ($key == 10) { # enter. +            _stop();              _commit_line(_input());              @undo_buffer = ();              $undo_index = undef; -            _stop(); +          } elsif ($input_buf_enabled and $imap) {              print "Imap $imap active" if DEBUG;              my $map = $imaps->{$imap}; @@ -1015,6 +1025,7 @@ sub handle_command {          # Enter key sends the current input line in command mode as well.          } elsif ($key == 10) { +            _stop();              _commit_line(_input());          } @@ -1044,36 +1055,66 @@ sub setup_changed {      }  } +sub UNLOAD { +    Irssi::signal_remove('gui key pressed' => \&got_key); +    Irssi::statusbar_item_unregister ('vim_mode'); + +} + +sub _add_undo_entry { +    my ($line, $pos) = @_; +    # add to the front of the buffer +    print "adding $line to undo list"; +    unshift @undo_buffer, [$line, $pos]; +    $undo_index = 0; +} + +sub _restore_undo_entry { +    my $entry = $undo_buffer[$undo_index]; +    _input($entry->[0], 1); +    _input_pos($entry->[1]); +} + +sub _clear_undo_buffer { +    print "Clearing undo buffer"; +    @undo_buffer = (['', 0]); +    $undo_index = 0; +} + +  sub _commit_line {      my ($line) = @_;      my $cmdchars = Irssi::settings_get_str('cmdchars'); -    my $signal; +    _input(''); +    _update_mode(M_INS); +    _clear_undo_buffer(); +      if ($line =~ /^[\Q$cmdchars\E]/) { -        $signal = 'send command'; +        print "Committing line as command" if DEBUG; +        Irssi::command($line); +      } else { -        $signal = 'send text'; +        print "Committing line as text" if DEBUG; +        Irssi::command("/say $line");      } - -    print "Committing line as $signal" if DEBUG; - -    # TODO: don't try to send this signal unless server and win are -    # defined (At least for 'send text' signals. There's no reason -    # to send text to an empty window anyway(?) -    Irssi::signal_emit $signal, $line, Irssi::active_server(), -        Irssi::active_win()->{active}; -    _input(''); -    _update_mode(M_INS);  }  sub _input { -    my ($data) = @_; +    my ($data, $ignore) = @_; + +    my $current_data = Irssi::parse_special('$L', 0, 0); +      if (defined $data) { +        if (!$ignore && ($data ne $current_data)) { +            _add_undo_entry($current_data, _input_pos()); +        }          Irssi::gui_input_set($data);      } else { -        $data = Irssi::parse_special('$L', 0, 0) +        $data = $current_data;      } +      return $data;  } @@ -1104,7 +1145,7 @@ sub _emulate_keystrokes {  }  sub _stop() { -    Irssi::signal_stop(); +    Irssi::signal_stop_by_name('gui key pressed');  }  sub _update_mode { | 
