aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vim-mode/vim_mode.pl75
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 {