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 { |