aboutsummaryrefslogtreecommitdiffstats
path: root/vim-mode/vim_mode.pl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--vim-mode/vim_mode.pl219
1 files changed, 128 insertions, 91 deletions
diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl
index 5f4a201..becf13b 100644
--- a/vim-mode/vim_mode.pl
+++ b/vim-mode/vim_mode.pl
@@ -969,18 +969,21 @@ my $should_ignore = 0;
# buffer to keep track of the last N keystrokes, used for Esc detection and
# insert mode mappings
-my @input_buf;
-my $input_buf_timer;
-my $input_buf_enabled = 0;
+my @escape_buf;
+my $escape_buf_timer;
+my $escape_buf_enabled = 0;
+
+# mode-related input buffers
+# --------------------------
# insert mode repeat buffer, used to repeat (.) last insert
-my @insert_buf;
+my @insert_mode_buf;
+my @cmd_mode_buf;
+my @ex_mode_buf;
-# Ex-mode input related vars
-# --------------------------
+# Ex-mode related vars
+# --------------------
-# ex mode buffer
-my @ex_buf;
# ex mode history storage.
my @ex_history;
my $ex_history_index = 0;
@@ -1856,7 +1859,7 @@ sub cmd_A {
# Add @insert_buf to _input() at the given position.
sub _insert_buffer {
my ($count, $pos) = @_;
- return _insert_at_position(join('', @insert_buf), $count, $pos);
+ return _insert_at_position(join('', @insert_mode_buf), $count, $pos);
}
sub _insert_at_position {
@@ -2079,7 +2082,7 @@ sub _fix_input_pos {
################################################################
sub cmd_ex_command {
- my $arg_str = join '', @ex_buf;
+ my $arg_str = join '', @ex_mode_buf;
if ($arg_str !~ /^(\d*)?([a-z]+)/) {
return _warn("Invalid Ex-mode command!");
@@ -2523,7 +2526,7 @@ sub _parse_mapping_reverse {
my ($string) = @_;
if (not defined $string) {
- _warn("Unable to reverse-map command: " . join('', @ex_buf));
+ _warn("Unable to reverse-map command: " . join('', @ex_mode_buf));
return;
}
@@ -2897,7 +2900,7 @@ sub vim_buffer_windows_string {
# A little code duplication of cmd_ex_command(), but \s+ instead of \s* so
# :bd doesn't display buffers matching d.
- my $arg_str = join '', @ex_buf;
+ my $arg_str = join '', @ex_mode_buf;
if ($arg_str =~ m|^b(?:uffer)?\s+(.+)$|) {
my $buffer = $1;
if ($buffer !~ /^[0-9]$/ and $buffer ne '#') {
@@ -3247,7 +3250,7 @@ sub _update_mode {
if ($mode == M_INS) {
$history_index = undef;
$register = '"';
- @insert_buf = ();
+ @insert_mode_buf = ();
# Reset every command mode related status as a fallback in case something
# goes wrong.
} elsif ($mode == M_CMD) {
@@ -3259,7 +3262,7 @@ sub _update_mode {
$pending_map = undef;
# Also clear ex-mode buffer.
- @ex_buf = ();
+ @ex_mode_buf = ();
}
Irssi::statusbar_items_redraw("vim_mode");
@@ -3366,7 +3369,7 @@ sub ex_history_fwd {
_debug("Ex history line: $line");
- @ex_buf = split '', $line;
+ @ex_mode_buf = split '', $line;
handle_command_ex(-1);
}
@@ -3383,7 +3386,7 @@ sub ex_history_back {
$line = '' if not defined $line;
_debug("Ex history line: $line");
- @ex_buf = split '', $line;
+ @ex_mode_buf = split '', $line;
handle_command_ex(-1);
}
@@ -3414,7 +3417,7 @@ sub sig_gui_keypress {
my $should_stop = process_input_key($key, $char);
- _stop() if ($should_stop == SIG_STOP);
+ _stop() if (defined $should_stop and $should_stop == SIG_STOP);
}
@@ -3426,20 +3429,102 @@ sub sig_gui_keypress {
sub process_input_key {
my ($key, $char) = @_;
+ # no matter what mode we're in, we need to deal with escape (and escape
+ # sequences) specially. So do them first.
+
+ # First,
if ($key == KEY_ESC) {
- print "Esc seen, starting buffer" if DEBUG;
- $input_buf_enabled = 1;
+ _debug("Escape seen, beginning escape_buf collection");
+ $escape_buf_enabled = 1;
+
+ push @escape_buf, $key;
# NOTE: this timeout might be too low on laggy systems, but
# it comes at the cost of keystroke latency for things that
# contain escape sequences (arrow keys, etc)
my $esc_buf_timeout = $settings->{esc_buf_timeout}->{value};
- $input_buf_timer
- = Irssi::timeout_add_once($esc_buf_timeout,
- \&handle_input_buffer, undef);
+ $escape_buf_timer =
+ Irssi::timeout_add_once($esc_buf_timeout,
+ \&escape_buffer_timeout, undef);
+
+ _debug("Buffer Timer tag: $escape_buf_timer");
+
+ } elsif ($escape_buf_enabled) {
+ attempt_escape_buffer_parse($key, $char);
+ # we can check at this point if we recognise the sequence, and cancel
+ # the timeout if we do.
+ }
+}
+sub attempt_escape_buffer_parse {
+ my ($key, $char) = @_;
+
+ if ($char eq '[') {
+ _debug("Spotted CSI");
+ } elsif ($char eq ']') {
+ _debug ("Spotted OSC");
+ } else {
+ push @escape_buf, $key;
+ }
+}
+
+sub escape_buffer_timeout {
+
+ $escape_buf_timer = undef;
+ $escape_buf_enabled = 0;
+
+ _debug("Escape buffer contains: ", join(", ", @escape_buf));
+
+ if (@escape_buf == 1 && $escape_buf[0] == KEY_ESC) {
+
+ _debug("escape only, Enter Command Mode");
+ _update_mode(M_CMD);
+
+ } else {
+ # we have more than a single esc, implying an escape sequence
+ # (meta-* or esc-*)
+
+ # currently, we only extract escape sequences if:
+ # a) we're in ex mode
+ # b) they're arrow keys (for history control)
- print "Buffer Timer tag: $input_buf_timer" if DEBUG;
+ if ($mode == M_EX) {
+ # ex mode
+ my $key_str = join '', map { chr } @escape_buf;
+ if ($key_str =~ m/^\e\[([ABCD])/) {
+ my $arrow = $1;
+ _debug( "Arrow key: $arrow");
+ if ($arrow eq 'A') { # up
+ ex_history_back();
+ } elsif ($arrow eq 'B') { # down
+ ex_history_fwd();
+ } else {
+ $arrow =~ s/C/right/;
+ $arrow =~ s/D/left/;
+ _debug("Arrow key $arrow not supported");
+ }
+ }
+ } else {
+ # otherwise, we just forward them to irssi.
+ _emulate_keystrokes(@escape_buf);
+ }
+
+ # Clear insert buffer, pressing "special" keys (like arrow keys)
+ # resets it.
+ @escape_buf = ();
+ }
+
+ @escape_buf = ();
+ $escape_buf_enabled = 0;
+}
+
+
+
+
+
+# work slowly incorporating stuff back in.
+
+=pod
} elsif ($mode == M_INS) {
@@ -3487,12 +3572,12 @@ sub process_input_key {
# TODO: maybe allow it
} elsif ($key == KEY_DEL or $key == KEY_BS) {
- @insert_buf = ();
+ @insert_mode_buf = ();
# All other entered characters need to be stored to allow repeat of
# insert mode. Ignore delete and control characters.
} elsif ($key > 31) {
- push @insert_buf, chr($key);
+ push @insert_mode_buf, chr($key);
}
}
@@ -3522,72 +3607,24 @@ sub process_input_key {
return SIG_CONT;
}
+=cut
# TODO: merge this with 'flush_input_buffer' below.
-sub handle_input_buffer {
-
- #Irssi::timeout_remove($input_buf_timer);
- $input_buf_timer = undef;
- # see what we've collected.
- print "Input buffer contains: ", join(", ", @input_buf) if DEBUG;
-
- if (@input_buf == 1 && $input_buf[0] == KEY_ESC) {
-
- print "Enter Command Mode" if DEBUG;
- _update_mode(M_CMD);
-
- } else {
- # we have more than a single esc, implying an escape sequence
- # (meta-* or esc-*)
-
- # currently, we only extract escape sequences if:
- # a) we're in ex mode
- # b) they're arrow keys (for history control)
-
- if ($mode == M_EX) {
- # ex mode
- my $key_str = join '', map { chr } @input_buf;
- if ($key_str =~ m/^\e\[([ABCD])/) {
- my $arrow = $1;
- _debug( "Arrow key: $arrow");
- if ($arrow eq 'A') { # up
- ex_history_back();
- } elsif ($arrow eq 'B') { # down
- ex_history_fwd();
- } else {
- $arrow =~ s/C/right/;
- $arrow =~ s/D/left/;
- _debug("Arrow key $arrow not supported");
- }
- }
- } else {
- # otherwise, we just forward them to irssi.
- _emulate_keystrokes(@input_buf);
- }
-
- # Clear insert buffer, pressing "special" keys (like arrow keys)
- # resets it.
- @insert_buf = ();
- }
-
- @input_buf = ();
- $input_buf_enabled = 0;
-}
sub flush_input_buffer {
- Irssi::timeout_remove($input_buf_timer) if defined $input_buf_timer;
- $input_buf_timer = undef;
+ Irssi::timeout_remove($escape_buf_timer) if defined $escape_buf_timer;
+ $escape_buf_timer = undef;
# see what we've collected.
- print "Input buffer flushed" if DEBUG;
+ _debug("Escape buffer flushed");
- # Add the characters to @insert_buf so they can be repeated.
- push @insert_buf, map chr, @input_buf;
+ # Add the characters to @escape_buf so they can be repeated.
+ push @escape_buf, map chr, @escape_buf;
- _emulate_keystrokes(@input_buf);
+ _emulate_keystrokes(@escape_buf);
- @input_buf = ();
- $input_buf_enabled = 0;
+ @escape_buf = ();
+ $escape_buf_enabled = 0;
$imap = undef;
}
@@ -3908,9 +3945,9 @@ sub handle_command_ex {
# BS key (8) or DEL key (127) - remove last character.
if ($key == 8 || $key == 127) {
print "Delete" if DEBUG;
- if (@ex_buf > 0) {
- pop @ex_buf;
- _set_prompt(':' . join '', @ex_buf);
+ if (@ex_mode_buf > 0) {
+ pop @ex_mode_buf;
+ _set_prompt(':' . join '', @ex_mode_buf);
# Backspacing over : exits ex-mode.
} else {
_update_mode(M_CMD);
@@ -3924,12 +3961,12 @@ sub handle_command_ex {
} elsif ($key == 9) { # TAB
print "Tab pressed" if DEBUG;
- print "Ex buf contains: " . join('', @ex_buf) if DEBUG;
- @tab_candidates = _tab_complete(join('', @ex_buf), [keys %$commands_ex]);
+ print "Ex buf contains: " . join('', @ex_mode_buf) if DEBUG;
+ @tab_candidates = _tab_complete(join('', @ex_mode_buf), [keys %$commands_ex]);
_debug("Candidates: " . join(", ", @tab_candidates));
if (@tab_candidates == 1) {
- @ex_buf = ( split('', $tab_candidates[0]), ' ');
- _set_prompt(':' . join '', @ex_buf);
+ @ex_mode_buf = ( split('', $tab_candidates[0]), ' ');
+ _set_prompt(':' . join '', @ex_mode_buf);
}
# Ignore control characters for now.
} elsif ($key > 0 && $key < 32) {
@@ -3939,9 +3976,9 @@ sub handle_command_ex {
} else {
if ($key != -1) {
# check we're not called from an ex_history_* function
- push @ex_buf, chr $key;
+ push @ex_mode_buf, chr $key;
}
- _set_prompt(':' . join '', @ex_buf);
+ _set_prompt(':' . join '', @ex_mode_buf);
}
Irssi::statusbar_items_redraw("vim_windows");