From 5378fbcc55dc94c81f504a8033c9e262fbd16088 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Mon, 4 Oct 2010 23:23:55 +0200 Subject: vim_mode: Remove outdated TODO. --- vim-mode/vim_mode.pl | 3 --- 1 file changed, 3 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 3631a1d..c141114 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -2139,6 +2139,3 @@ sub _warn { print '%_vim_mode: ', $warning, '%_'; } - -# TODO: -# 10gg -> go to window 10 (prefix.gg -> win ) -- cgit v1.2.3 From bf636147a15e12383beaf60e1ec5d0f5013b6be1 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Wed, 6 Oct 2010 21:35:36 +0200 Subject: vim_mode: Simplify handle_command_cmd() a little. --- vim-mode/vim_mode.pl | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index c141114..30bab6a 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -1560,7 +1560,10 @@ sub got_key { } if ($mode == M_CMD) { - handle_command_cmd($key); + my $should_stop = handle_command_cmd($key); + _stop() if $should_stop; + Irssi::statusbar_items_redraw("vim_mode"); + } elsif ($mode == M_EX) { handle_command_ex($key); } @@ -1635,8 +1638,6 @@ sub handle_numeric_prefix { sub handle_command_cmd { my ($key) = @_; - my $should_stop = 1; - my $char = chr($key); # We need to treat $movements_multiple specially as they need another @@ -1661,9 +1662,11 @@ sub handle_command_cmd { ($numeric_prefix && $char =~ m/[0-9]/))) { print "Processing numeric prefix: $char" if DEBUG; handle_numeric_prefix($char); + return 1; # call _stop() + } # text-objects (i a) are simulated with $movement - } elsif (!$movement && (exists $movements_multiple->{$char} + if (!$movement && (exists $movements_multiple->{$char} or $operator and ($char eq 'i' or $char eq 'a'))) { print "Processing movement: $char" if DEBUG; $movement = $char; @@ -1845,13 +1848,11 @@ sub handle_command_cmd { # Enter key sends the current input line in command mode as well. } elsif ($key == 10) { - $should_stop = 0; _commit_line(); + return 0; # don't call _stop() } - Irssi::statusbar_items_redraw("vim_mode"); - - _stop() if $should_stop; + return 1; # call _stop() } sub handle_command_ex { -- cgit v1.2.3 From a0896e03e25e716c1c3ef76df8feee603dd5d488 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Wed, 6 Oct 2010 21:37:33 +0200 Subject: vim_mode: More cleanup of handle_command_cmd(). --- vim-mode/vim_mode.pl | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 30bab6a..cf53735 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -1644,6 +1644,12 @@ sub handle_command_cmd { # argument. if ($movement) { $movement .= $char; + + # Counts + } elsif ($char =~ m/[1-9]/ || ($numeric_prefix && $char =~ m/[0-9]/)) { + print "Processing numeric prefix: $char" if DEBUG; + handle_numeric_prefix($char); + return 1; # call _stop() } # s is an alias for cl. @@ -1658,13 +1664,6 @@ sub handle_command_cmd { $operator = 'c'; } - if (!$movement && ($char =~ m/[1-9]/ || - ($numeric_prefix && $char =~ m/[0-9]/))) { - print "Processing numeric prefix: $char" if DEBUG; - handle_numeric_prefix($char); - return 1; # call _stop() - } - # text-objects (i a) are simulated with $movement if (!$movement && (exists $movements_multiple->{$char} or $operator and ($char eq 'i' or $char eq 'a'))) { -- cgit v1.2.3 From 4ead077f1e58f486133a82dc09d18aa1323f4200 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 03:03:22 +0200 Subject: vim_mode: Add support for complex command mode mappings. Also some internal cleanup of handle_command_cmd(). --- vim-mode/vim_mode.pl | 617 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 367 insertions(+), 250 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index cf53735..051cfd3 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -186,10 +186,135 @@ sub M_CMD() { 1 } # command mode sub M_INS() { 0 } # insert mode sub M_EX () { 2 } # extended mode (after a :?) +# operator command +sub C_OPERATOR () { 0 } +# normal commmand +sub C_NORMAL () { 1 } +# command taking another key as argument +sub C_NEEDSKEY () { 2 } +# text-object commmand (i a) +sub C_TEXTOBJECT () { 3 } +# commands entering insert mode +sub C_INSERT () { 4 } + # word and non-word regex, keep in sync with setup_changed()! my $word = qr/[\w_]/o; my $non_word = qr/[^\w_\s]/o; +# COMMANDS + +# All available commands in command mode, they are stored with a char as key, +# but this is not necessarily the key the command is currently mapped to. +my $commands + = { + # operators + c => { char => 'c', func => \&cmd_operator_c, type => C_OPERATOR, + repeatable => 1 }, + d => { char => 'd', func => \&cmd_operator_d, type => C_OPERATOR, + repeatable => 1 }, + y => { char => 'y', func => \&cmd_operator_y, type => C_OPERATOR, + repeatable => 1 }, + + # arrow like movement + h => { char => 'h', func => \&cmd_movement_h, type => C_NORMAL }, + l => { char => 'l', func => \&cmd_movement_l, type => C_NORMAL }, + ' ' => { char => '', func => \&cmd_movement_space, type => C_NORMAL }, + # history movement + j => { char => 'j', func => \&cmd_movement_j, type => C_NORMAL }, + k => { char => 'k', func => \&cmd_movement_k, type => C_NORMAL }, + gg => { char => 'gg', func => \&cmd_movement_gg, type => C_NORMAL }, + G => { char => 'G', func => \&cmd_movement_G, type => C_NORMAL, + needs_count => 1 }, + # char movement, take an additional parameter and use $movement + f => { char => 'f', func => \&cmd_movement_f, type => C_NEEDSKEY }, + t => { char => 't', func => \&cmd_movement_t, type => C_NEEDSKEY }, + F => { char => 'F', func => \&cmd_movement_F, type => C_NEEDSKEY }, + T => { char => 'T', func => \&cmd_movement_T, type => C_NEEDSKEY }, + ';' => { char => ';', func => \&cmd_movement_semicolon, type => C_NORMAL }, + ',' => { char => ',', func => \&cmd_movement_comma, type => C_NORMAL }, + # word movement + w => { char => 'w', func => \&cmd_movement_w, type => C_NORMAL }, + b => { char => 'b', func => \&cmd_movement_b, type => C_NORMAL }, + e => { char => 'e', func => \&cmd_movement_e, type => C_NORMAL }, + ge => { char => 'ge', func => \&cmd_movement_ge, type => C_NORMAL }, + W => { char => 'W', func => \&cmd_movement_W, type => C_NORMAL }, + B => { char => 'B', func => \&cmd_movement_B, type => C_NORMAL }, + E => { char => 'E', func => \&cmd_movement_E, type => C_NORMAL }, + gE => { char => 'gE', func => \&cmd_movement_gE, type => C_NORMAL }, + # text-objects, leading _ means can't be mapped! + _i => { char => '_i', func => \&cmd_movement__i, type => C_TEXTOBJECT }, + _a => { char => '_a', func => \&cmd_movement__a, type => C_TEXTOBJECT }, + # line movement + '0' => { char => '0', func => \&cmd_movement_0, type => C_NORMAL }, + '^' => { char => '^', func => \&cmd_movement_caret, type => C_NORMAL }, + '$' => { char => '$', func => \&cmd_movement_dollar, type => C_NORMAL }, + # delete chars + x => { char => 'x', func => \&cmd_movement_x, type => C_NORMAL, + repeatable => 1 }, + X => { char => 'X', func => \&cmd_movement_X, type => C_NORMAL, + repeatable => 1 }, + s => { char => 's', func => \&cmd_movement_s, type => C_NORMAL, + repeatable => 1 }, # operator c takes care of insert mode + S => { char => 'S', func => \&cmd_movement_S, type => C_NORMAL, + repeatable => 1 }, # operator c takes care of insert mode + # insert mode + i => { char => 'i', func => \&cmd_movement_i, type => C_INSERT }, + I => { char => 'I', func => \&cmd_movement_I, type => C_INSERT }, + a => { char => 'a', func => \&cmd_movement_a, type => C_INSERT }, + A => { char => 'A', func => \&cmd_movement_A, type => C_INSERT }, + # replace + r => { char => 'r', func => \&cmd_movement_r, type => C_NEEDSKEY, + repeatable => 1 }, + # paste + p => { char => 'p', func => \&cmd_movement_p, type => C_NORMAL, + repeatable => 1 }, + P => { char => 'P', func => \&cmd_movement_P, type => C_NORMAL, + repeatable => 1 }, + # to end of line + C => { char => 'C', func => \&cmd_movement_C, type => C_NORMAL, + repeatable => 1 }, + D => { char => 'D', func => \&cmd_movement_D, type => C_NORMAL, + repeatable => 1 }, + # scrolling + "\x04" => { char => '', func => \&cmd_movement_ctrl_d, type => C_NORMAL, + repeatable => 1 }, # half screen down + "\x15" => { char => '', func => \&cmd_movement_ctrl_u, type => C_NORMAL, + repeatable => 1 }, # half screen up + "\x06" => { char => '', func => \&cmd_movement_ctrl_f, type => C_NORMAL, + repeatable => 1 }, # screen down + "\x02" => { char => '', func => \&cmd_movement_ctrl_b, type => C_NORMAL, + repeatable => 1 }, # screen up + # window switching + "\x17j" => { char => 'j', func => \&cmd_movement_ctrl_wj, type => C_NORMAL, + needs_count => 1 }, + "\x17k" => { char => 'k', func => \&cmd_movement_ctrl_wk, type => C_NORMAL, + needs_count => 1 }, + "\x1e" => { char => '', func => \&cmd_movement_ctrl_6, type => C_NORMAL, + needs_count => 1 }, + # misc + '~' => { char => '~', func => \&cmd_movement_tilde, type => C_NORMAL, + repeatable => 1 }, + '"' => { char => '"', func => \&cmd_movement_register, type => C_NEEDSKEY }, + '.' => { char => '.', type => C_NORMAL, repeatable => 1 }, + ':' => { char => ':', type => C_NORMAL }, + "\n" => { char => '', type => C_NORMAL }, # return + # undo + 'u' => { char => 'u', func => \&cmd_undo, type => C_NORMAL }, + "\x12" => { char => '', func => \&cmd_redo, type => C_NORMAL }, + }; + + +# MAPPINGS + +# default command mode mappings +my $maps = {}; + +# Add all default mappings. +foreach my $char (keys %$commands) { + next if $char =~ /^_/; # skip private commands (text-objects for now) + add_map($char, $commands->{$char}); +} + # GLOBAL VARIABLES my $DEBUG_ENABLED = 0; @@ -214,16 +339,20 @@ my $should_ignore = 0; # ex mode buffer my @ex_buf; +# we are waiting for another mapped key (e.g. g pressed, but there are +# multiple mappings like gg gE etc.) +my $pending_map = undef; + # for commands like 10x my $numeric_prefix = undef; -# vi operators like d, c, .. +# current operator as $command hash my $operator = undef; # vi movements, only used when a movement needs more than one key (like f t). my $movement = undef; # last vi command, used by . my $last = { - 'char' => 'i', # = i to support . when loading the script + 'cmd' => $commands->{i}, # = i to support . when loading the script 'numeric_prefix' => undef, 'operator' => undef, 'movement' => undef, @@ -288,117 +417,6 @@ sub script_is_loaded { vim_mode_init(); -# vi-operators like d, c, y -my $operators - = { - 'c' => { func => \&cmd_operator_c }, - 'd' => { func => \&cmd_operator_d }, - 'y' => { func => \&cmd_operator_y }, - }; - -# vi-moves like w,b; they move the cursor and may get combined with an -# operator; also things like i/I are listed here, not entirely correct but -# they work in a similar way -# -# Each function returns two values, an updated $cur_pos (see -# handle_command_cmd()) and the new cursor position. If undef is returned in -# either place, the position isn't changed. -my $movements - = { - # arrow like movement - 'h' => { func => \&cmd_movement_h }, - 'l' => { func => \&cmd_movement_l }, - ' ' => { func => \&cmd_movement_space }, - # history movement - 'j' => { func => \&cmd_movement_j }, - 'k' => { func => \&cmd_movement_k }, - 'G' => { func => \&cmd_movement_G }, - # char movement, take an additional parameter and use $movement - 'f' => { func => \&cmd_movement_f }, - 't' => { func => \&cmd_movement_t }, - 'F' => { func => \&cmd_movement_F }, - 'T' => { func => \&cmd_movement_T }, - ';' => { func => \&cmd_movement_semicolon }, - ',' => { func => \&cmd_movement_comma }, - # word movement - 'w' => { func => \&cmd_movement_w }, - 'b' => { func => \&cmd_movement_b }, - 'e' => { func => \&cmd_movement_e }, - 'W' => { func => \&cmd_movement_W }, - 'B' => { func => \&cmd_movement_B }, - 'E' => { func => \&cmd_movement_E }, - # text-objects - 'i_' => { func => \&cmd_movement_i_ }, - 'a_' => { func => \&cmd_movement_a_ }, - # line movement - '0' => { func => \&cmd_movement_0 }, - '^' => { func => \&cmd_movement_caret }, - '$' => { func => \&cmd_movement_dollar }, - # delete chars - 'x' => { func => \&cmd_movement_x }, - 'X' => { func => \&cmd_movement_X }, - # insert mode - 'i' => { func => \&cmd_movement_i }, - 'I' => { func => \&cmd_movement_I }, - 'a' => { func => \&cmd_movement_a }, - 'A' => { func => \&cmd_movement_A }, - # replace mode - 'r' => { func => \&cmd_movement_r }, - # paste - 'p' => { func => \&cmd_movement_p }, - 'P' => { func => \&cmd_movement_P }, - # to end of line - 'C' => { func => \&cmd_movement_dollar }, - 'D' => { func => \&cmd_movement_dollar }, - # scrolling - "\x04" => { func => \&cmd_movement_ctrl_d }, # half screen down - "\x15" => { func => \&cmd_movement_ctrl_u }, # half screen up - "\x06" => { func => \&cmd_movement_ctrl_f }, # screen down - "\x02" => { func => \&cmd_movement_ctrl_b }, # screen up - # window switching - "\x17" => { func => \&cmd_movement_ctrl_w }, - "\x1e" => { func => \&cmd_movement_ctrl_6 }, - # misc - '~' => { func => \&cmd_movement_tilde }, - '.' => {}, - '"' => { func => \&cmd_movement_register }, - 'g' => { func => \&cmd_movement_g }, # g does many things - # undo - 'u' => { func => \&cmd_undo }, - "\x12" => { func => \&cmd_redo }, # ctrl-r - }; - -# special movements which take an additional key -my $movements_multiple = - { - 'f' => undef, - 't' => undef, - 'F' => undef, - 'T' => undef, - 'r' => undef, - '"' => undef, - 'g' => undef, - "\x17" => undef, # ctrl-w - }; - -# "movements" which can be repeated (additional to operators of course). -my $movements_repeatable - = { - 'x' => undef, - 'X' => undef, - 'i' => undef, - 'a' => undef, - 'I' => undef, - 'A' => undef, - 'r' => undef, - 'p' => undef, - 'P' => undef, - 'C' => undef, - 'D' => undef, - '~' => undef, - }; - - sub cmd_insert_ctrl_r { my ($key) = @_; @@ -484,8 +502,8 @@ sub _get_pos_and_length { $length *= -1; } - # Strip leading a_ or i_ if a text-object was used. - if ($move =~ /^[ai]_(.)/) { + # Strip leading _a or _i if a text-object was used. + if ($move =~ /^_[ai](.)/) { $move = $1; } @@ -628,6 +646,11 @@ sub cmd_movement_G { return (undef, undef); } +sub cmd_movement_gg { + my ($count, $pos, $repeat) = @_; + + return cmd_movement_G(1, $pos, $repeat); +} sub cmd_movement_f { my ($count, $pos, $repeat, $char) = @_; @@ -691,8 +714,8 @@ sub cmd_movement_semicolon { return (undef, undef) if not defined $last_ftFT->{type}; (undef, $pos) - = $movements->{$last_ftFT->{type}} - ->{func}($count, $pos, $repeat, $last_ftFT->{char}); + = $commands->{$last_ftFT->{type}} + ->{func}($count, $pos, $repeat, $last_ftFT->{char}); return (undef, $pos); } sub cmd_movement_comma { @@ -706,8 +729,8 @@ sub cmd_movement_comma { $type =~ tr/ftFT/FTft/; (undef, $pos) - = $movements->{$type} - ->{func}($count, $pos, $repeat, $last_ftFT->{char}); + = $commands->{$type} + ->{func}($count, $pos, $repeat, $last_ftFT->{char}); # Restore type as the move functions overwrites it. $last_ftFT->{type} = $save; return (undef, $pos); @@ -741,6 +764,19 @@ sub cmd_movement_e { $pos = _fix_input_pos($pos, length $input); return (undef, $pos); } +sub cmd_movement_ge { + my ($count, $pos, $repeat, $char) = @_; + + my $input = reverse _input(); + $pos = length($input) - $pos - 1; + $pos = 0 if ($pos < 0); + + $pos = _beginning_of_word($input, $count, $pos); + $pos = length($input) - $pos - 1; + $pos = 0 if ($pos < 0); + + return (undef, $pos); +} # Go to the beginning of $count-th word, like vi's w. sub _beginning_of_word { my ($input, $count, $pos) = @_; @@ -825,6 +861,19 @@ sub cmd_movement_E { return (undef, $pos); } } +sub cmd_movement_gE { + my ($count, $pos, $repeat, $char) = @_; + + my $input = reverse _input(); + $pos = _beginning_of_WORD($input, $count, length($input) - $pos - 1); + if ($pos == -1 or length($input) - $pos - 1 == -1) { + return cmd_movement_0(); + } else { + $pos = length($input) - $pos - 1; + } + + return (undef, $pos); +} # Go to beginning of $count-th WORD, like vi's W. sub _beginning_of_WORD { my ($input, $count, $pos) = @_; @@ -866,13 +915,13 @@ sub _end_of_WORD { return $pos; } -sub cmd_movement_i_ { +sub cmd_movement__i { my ($count, $pos, $repeat, $char) = @_; _warn("i_ not implemented yet"); return (undef, undef); } -sub cmd_movement_a_ { +sub cmd_movement__a { my ($count, $pos, $repeat, $char) = @_; my $cur_pos; @@ -1026,6 +1075,18 @@ sub cmd_movement_X { cmd_operator_d($pos, $new, 'X'); return (undef, undef); } +sub cmd_movement_s { + my ($count, $pos, $repeat) = @_; + + $operator = $commands->{c}; + return (undef, $pos + 1); +} +sub cmd_movement_S { + my ($count, $pos, $repeat) = @_; + + $operator = $commands->{c}; + return (0, _input_len()); +} sub cmd_movement_i { my ($count, $pos, $repeat) = @_; @@ -1129,6 +1190,19 @@ sub _paste_at_position { return _insert_at_position($registers->{$register}, $count, $pos); } +sub cmd_movement_C { + my ($count, $pos, $repeat) = @_; + + $operator = $commands->{c}; + return (undef, _input_len()); +} +sub cmd_movement_D { + my ($count, $pos, $repeat) = @_; + + $operator = $commands->{d}; + return (undef, _input_len()); +} + sub cmd_movement_ctrl_d { my ($count, $pos, $repeat) = @_; @@ -1165,18 +1239,22 @@ sub cmd_movement_ctrl_b { return (undef, undef); } -sub cmd_movement_ctrl_w { - my ($count, $pos, $repeat, $char) = @_; +sub cmd_movement_ctrl_wj { + my ($count, $pos, $repeat) = @_; - if ($char eq 'j') { - while ($count -- > 0) { - Irssi::command('window down'); - } - } elsif ($char eq 'k') { - while ($count -- > 0) { - Irssi::command('window up'); - } + while ($count -- > 0) { + Irssi::command('window down'); + } + + return (undef, undef); +} +sub cmd_movement_ctrl_wk { + my ($count, $pos, $repeat) = @_; + + while ($count -- > 0) { + Irssi::command('window up'); } + return (undef, undef); } sub cmd_movement_ctrl_6 { @@ -1221,37 +1299,6 @@ sub cmd_movement_register { return (undef, undef); } -sub cmd_movement_g { - my ($count, $pos, $repeat, $char) = @_; - - my $input = _input(); - # ge - if ($char eq 'e') { - $input = reverse $input; - $pos = length($input) - $pos - 1; - $pos = 0 if ($pos < 0); - - $pos = _beginning_of_word($input, $count, $pos); - $pos = length($input) - $pos - 1; - $pos = 0 if ($pos < 0); - # gE - } elsif ($char eq 'E') { - $input = reverse $input; - $pos = _beginning_of_WORD($input, $count, length($input) - $pos - 1); - if ($pos == -1 or length($input) - $pos - 1 == -1) { - return cmd_movement_0(); - } else { - $pos = length($input) - $pos - 1; - } - # gg - } elsif ($char eq 'g') { - cmd_movement_G(1, $pos, $repeat); - $pos = undef; - } - - return (undef, $pos); -} - sub cmd_undo { print "Undo!" if DEBUG; @@ -1456,10 +1503,10 @@ sub vim_mode_cb { $mode_str .= $numeric_prefix; } if ($operator) { - $mode_str .= $operator; + $mode_str .= $operator->{char}; } if ($movement) { - $mode_str .= $movement; + $mode_str .= $movement->{char}; } $mode_str .= ')'; } @@ -1623,6 +1670,18 @@ sub flush_input_buffer { $imap = undef; } +sub flush_pending_map { + my ($old_pending_map) = @_; + + print "flush_pending_map(): ", $pending_map, ' ', $old_pending_map + if DEBUG; + + return if not defined $pending_map or + $pending_map ne $old_pending_map; + + handle_command_cmd(undef); +} + sub handle_numeric_prefix { my ($char) = @_; my $num = 0+$char; @@ -1638,50 +1697,96 @@ sub handle_numeric_prefix { sub handle_command_cmd { my ($key) = @_; - my $char = chr($key); + my $pending_map_flushed = 0; - # We need to treat $movements_multiple specially as they need another - # argument. - if ($movement) { - $movement .= $char; + my $char; + if (defined $key) { + $char = chr($key); + # We were called from flush_pending_map(). + } else { + $char = $pending_map; + $key = 0; + $pending_map_flushed = 1; + } # Counts - } elsif ($char =~ m/[1-9]/ || ($numeric_prefix && $char =~ m/[0-9]/)) { + if (!$movement and ($char =~ m/[1-9]/ or + ($numeric_prefix && $char =~ m/[0-9]/))) { print "Processing numeric prefix: $char" if DEBUG; handle_numeric_prefix($char); return 1; # call _stop() } - # s is an alias for cl. - if (!$movement and !$operator and $char eq 's') { - print "Changing s to cl" if DEBUG; - $char = 'l'; - $operator = 'c'; - # S is an alias for cc. - } elsif (!$movement and !$operator and $char eq 'S') { - print "Changing S to cc" if DEBUG; - $char = 'c'; - $operator = 'c'; + if (defined $pending_map and not $pending_map_flushed) { + $pending_map = $pending_map . $char; + $char = $pending_map; } - # text-objects (i a) are simulated with $movement - if (!$movement && (exists $movements_multiple->{$char} - or $operator and ($char eq 'i' or $char eq 'a'))) { - print "Processing movement: $char" if DEBUG; - $movement = $char; + my $map; + if ($movement) { + $map = { char => $movement->{char}, + cmd => $movement, + maps => {}, + }; + + } elsif (exists $maps->{$char}) { + $map = $maps->{$char}; + + # We have multiple mappings starting with this key sequence. + if (!$pending_map_flushed and scalar keys %{$map->{maps}} > 0) { + if (not defined $pending_map) { + $pending_map = $char; + } - } elsif (!$movement && exists $operators->{$char}) { - print "Processing operator: $char" if DEBUG; + # The current key sequence has a command mapped to it, run if + # after a timeout. + if (defined $map->{cmd}) { + Irssi::timeout_add_once(1000, \&flush_pending_map, + $pending_map); + } + return 1; # call _stop() + } + + } else { + print "No mapping found for $char" if DEBUG; + $pending_map = undef; + return 1; # call _stop() + } + + $pending_map = undef; + my $cmd = $map->{cmd}; + + # Make sure we have a valid $cmd. + if (not defined $cmd) { + print "Bug in pending_map_flushed() $map->{char}" if DEBUG; + return 1; # call _stop() + } + + # text-objects (i a) are simulated with $movement + if (!$movement and ($cmd->{type} == C_NEEDSKEY or + ($operator and ($char eq 'i' or $char eq 'a')))) { + print "Processing movement: $map->{char} ($cmd->{char})" if DEBUG; + if ($char eq 'i') { + $movement = $commands->{_i}; + } elsif ($char eq 'a') { + $movement = $commands->{_a}; + } else { + $movement = $cmd; + } + + } elsif (!$movement and $cmd->{type} == C_OPERATOR) { + print "Processing operator: $map->{char} ($cmd->{char})" if DEBUG; # Abort operator if we already have one pending. if ($operator) { # But allow cc/dd/yy. - if ($operator eq $char) { - print "Processing operator: ", $operator, $char if DEBUG; + if ($operator == $cmd) { + print "Processing line operator: $map->{char} ($cmd->{char})" + if DEBUG; my $pos = _input_pos(); - $operators->{$operator}->{func}->(0, _input_len(), '', 0); + $cmd->{func}->(0, _input_len(), '', 0); # Restore position for yy. - if ($char eq 'y') { + if ($cmd == $commands->{y}) { _input_pos($pos); } if ($register ne '"') { @@ -1694,18 +1799,34 @@ sub handle_command_cmd { $movement = undef; # Set new operator. } else { - $operator = $char; + $operator = $cmd; } - } elsif ($movement || exists $movements->{$char}) { - print "Processing movement command: $char" if DEBUG; + # Start Ex mode. + } elsif ($cmd == $commands->{':'}) { + if (not script_is_loaded('prompt_info')) { + _warn("Warning: Ex mode requires the 'prompt_info' script. " . + "Please load it and try again."); + } else { + _update_mode(M_EX); + _set_prompt(':'); + } + + # Enter key sends the current input line in command mode as well. + } elsif ($key == 10) { + _commit_line(); + return 0; # don't call _stop() + + } else { #if ($movement || exists $movements->{$char}) { + print "Processing command: $map->{char} ($cmd->{char})" if DEBUG; my $skip = 0; my $repeat = 0; if (!$movement) { # . repeats the last command. - if ($char eq '.' and defined $last->{char}) { + if ($cmd == $commands->{'.'} and defined $last->{cmd}) { + $cmd = $last->{cmd}; $char = $last->{char}; # If . is given a count then it replaces original count. if (not defined $numeric_prefix) { @@ -1715,19 +1836,9 @@ sub handle_command_cmd { $movement = $last->{movement}; $register = $last->{register}; $repeat = 1; - } elsif ($char eq '.') { + } elsif ($cmd == $commands->{'.'}) { print '. pressed but $last->{char} not set' if DEBUG; $skip = 1; - - # Ignore invalid operator/char combinations. - } elsif ($operator and ($char eq 'j' or $char eq 'k')) { - print "Invalid operator/char: $operator $char" if DEBUG; - $skip = 1; - # C and D force the matching operator - } elsif ($char eq 'C') { - $operator = 'c'; - } elsif ($char eq 'D') { - $operator = 'd'; } } @@ -1736,9 +1847,7 @@ sub handle_command_cmd { } else { # Make sure count is at least 1 except for functions which need to # know if no count was used. - if (not $numeric_prefix and $char ne "\x04" # ctrl-d - and $char ne "\x15" # ctrl-u - and $char ne 'G') { + if (not $numeric_prefix and not $cmd->{needs_count}) { $numeric_prefix = 1; } @@ -1751,20 +1860,11 @@ sub handle_command_cmd { # Execute the movement (multiple times). if (not $movement) { ($old_pos, $new_pos) - = $movements->{$char}->{func} - ->($numeric_prefix, $cur_pos, $repeat); + = $cmd->{func}->($numeric_prefix, $cur_pos, $repeat); } else { - # Use the real movement command (like t or f) for operator - # below. - $char = substr $movement, 0, 1; - # i_ and a_ represent text-objects. - if ($char eq 'i' or $char eq 'a') { - $char .= '_'; - } ($old_pos, $new_pos) - = $movements->{$char}->{func} - ->($numeric_prefix, $cur_pos, $repeat, - substr $movement, 1); + = $cmd->{func}->($numeric_prefix, $cur_pos, $repeat, + $char); } if (defined $old_pos) { print "Changing \$cur_pos from $cur_pos to $old_pos" if DEBUG; @@ -1779,8 +1879,8 @@ sub handle_command_cmd { # Update input position of last undo entry so that undo/redo # restores correct position. if (@undo_buffer and _input() eq $undo_buffer[0]->[0] and - ((defined $operator and $operator eq 'd') or - exists $movements_repeatable->{$char} or $char eq '.')) { + ((defined $operator and $operator == $commands->{d}) or + $cmd->{repeatable})) { print "Updating history position: $undo_buffer[0]->[0]" if DEBUG; $undo_buffer[0]->[1] = $cur_pos; @@ -1790,21 +1890,20 @@ sub handle_command_cmd { # But only if the movement changed the position (this prevents # problems with e.g. f when the search string doesn't exist). if ($operator and $cur_pos != $new_pos) { - print "Processing operator: ", $operator if DEBUG; + print "Processing operator: ", $operator->{char} if DEBUG; # If text-objects are used the real move character must also # be passed to the operator. - my $tmp_char = $char; - if ($char eq 'i_' or $char eq 'a_') { - $tmp_char .= substr $movement, 1; + my $tmp_char = $cmd->{char}; + if ($tmp_char eq '_i' or $tmp_char eq '_a') { + $tmp_char .= $char; } - $operators->{$operator}->{func}->($cur_pos, $new_pos, - $tmp_char, $repeat); + $operator->{func}->($cur_pos, $new_pos, $tmp_char, $repeat); } # Save an undo checkpoint here for operators, all repeatable # movements, operators and repetition. - if ((defined $operator and $operator eq 'd') or - exists $movements_repeatable->{$char} or $char eq '.') { + if ((defined $operator and $operator == $commands->{d}) or + $cmd->{repeatable}) { # TODO: why do histpry entries still show up in undo # buffer? Is avoiding the commands here insufficient? @@ -1812,7 +1911,8 @@ sub handle_command_cmd { } # Store command, necessary for . - if ($operator or exists $movements_repeatable->{$char}) { + if ($operator or $cmd->{repeatable}) { + $last->{cmd} = $cmd; $last->{char} = $char; $last->{numeric_prefix} = $numeric_prefix; $last->{operator} = $operator; @@ -1824,31 +1924,17 @@ sub handle_command_cmd { # Reset the count unless we go into insert mode, _update_mode() needs # to know it when leaving insert mode to support insert with counts # (like 3i). - if ($repeat or ($char ne 'i' and $char ne 'I' and $char ne 'a' and $char ne 'A')) { + if ($repeat or $cmd->{type} != C_INSERT) { $numeric_prefix = undef; } $operator = undef; $movement = undef; - if ($char ne '"' and $register ne '"') { + if ($cmd != $commands->{'"'} and $register ne '"') { print 'Changing register to "' if DEBUG; $register = '"'; } - # Start Ex mode. - } elsif ($char eq ':') { - if (not script_is_loaded('prompt_info')) { - _warn("Warning: Ex mode requires the 'prompt_info' script. " . - "Please load it and try again."); - } else { - _update_mode(M_EX); - _set_prompt(':'); - } - - # Enter key sends the current input line in command mode as well. - } elsif ($key == 10) { - _commit_line(); - return 0; # don't call _stop() } return 1; # call _stop() @@ -2008,6 +2094,35 @@ sub _reset_undo_buffer { } +sub add_map { + my ($keys, $command) = @_; + + # To allow multiple mappings starting with the same key (like gg, ge, gE) + # also create maps for the keys "leading" to this key (g in this case, but + # can be longer for this like ,ls). When looking for the mapping these + # "leading" maps are followed. + my $tmp = $keys; + while (length $tmp > 1) { + my $map = substr $tmp, -1, 1, ''; + if (not exists $maps->{$tmp}) { + $maps->{$tmp} = { cmd => undef, maps => {} }; + } + if (not exists $maps->{$tmp}->{maps}->{$tmp . $map}) { + $maps->{$tmp}->{maps}->{$tmp . $map} = undef; + } + } + + if (not exists $maps->{$keys}) { + $maps->{$keys} = { char => $keys, + cmd => $command, + maps => {} + }; + } else { + $maps->{$keys}->{cmd} = $command; + } +} + + sub _commit_line { _update_mode(M_INS); _reset_undo_buffer('', 0); @@ -2098,10 +2213,10 @@ sub _update_mode { _add_undo_entry(_input(), _input_pos()); # Change mode to i to support insert mode repetition. This doesn't affect - # commands like i/a/I/A because handle_command_cmd() sets $last->{char}. + # commands like i/a/I/A because handle_command_cmd() sets $last->{cmd}. # It's necessary when pressing enter. } elsif ($mode == M_CMD and $new_mode == M_INS) { - $last->{char} = 'i'; + $last->{cmd} = $commands->{i}; # Make sure prompt is cleared when leaving ex mode. } elsif ($mode == M_EX and $new_mode != M_EX) { _set_prompt(''); @@ -2120,6 +2235,8 @@ sub _update_mode { $movement = undef; $register = '"'; + $pending_map = undef; + # Also clear ex-mode buffer. @ex_buf = (); } -- cgit v1.2.3 From 6f8e199be69122bb34767b0f996562d1f82efcd2 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 03:44:56 +0200 Subject: vim_mode: Fix function names. --- vim-mode/vim_mode.pl | 214 +++++++++++++++++++++++++-------------------------- 1 file changed, 107 insertions(+), 107 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 051cfd3..e1bfcca 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -216,85 +216,85 @@ my $commands repeatable => 1 }, # arrow like movement - h => { char => 'h', func => \&cmd_movement_h, type => C_NORMAL }, - l => { char => 'l', func => \&cmd_movement_l, type => C_NORMAL }, - ' ' => { char => '', func => \&cmd_movement_space, type => C_NORMAL }, + h => { char => 'h', func => \&cmd_h, type => C_NORMAL }, + l => { char => 'l', func => \&cmd_l, type => C_NORMAL }, + ' ' => { char => '', func => \&cmd_space, type => C_NORMAL }, # history movement - j => { char => 'j', func => \&cmd_movement_j, type => C_NORMAL }, - k => { char => 'k', func => \&cmd_movement_k, type => C_NORMAL }, - gg => { char => 'gg', func => \&cmd_movement_gg, type => C_NORMAL }, - G => { char => 'G', func => \&cmd_movement_G, type => C_NORMAL, + j => { char => 'j', func => \&cmd_j, type => C_NORMAL }, + k => { char => 'k', func => \&cmd_k, type => C_NORMAL }, + gg => { char => 'gg', func => \&cmd_gg, type => C_NORMAL }, + G => { char => 'G', func => \&cmd_G, type => C_NORMAL, needs_count => 1 }, # char movement, take an additional parameter and use $movement - f => { char => 'f', func => \&cmd_movement_f, type => C_NEEDSKEY }, - t => { char => 't', func => \&cmd_movement_t, type => C_NEEDSKEY }, - F => { char => 'F', func => \&cmd_movement_F, type => C_NEEDSKEY }, - T => { char => 'T', func => \&cmd_movement_T, type => C_NEEDSKEY }, - ';' => { char => ';', func => \&cmd_movement_semicolon, type => C_NORMAL }, - ',' => { char => ',', func => \&cmd_movement_comma, type => C_NORMAL }, + f => { char => 'f', func => \&cmd_f, type => C_NEEDSKEY }, + t => { char => 't', func => \&cmd_t, type => C_NEEDSKEY }, + F => { char => 'F', func => \&cmd_F, type => C_NEEDSKEY }, + T => { char => 'T', func => \&cmd_T, type => C_NEEDSKEY }, + ';' => { char => ';', func => \&cmd_semicolon, type => C_NORMAL }, + ',' => { char => ',', func => \&cmd_comma, type => C_NORMAL }, # word movement - w => { char => 'w', func => \&cmd_movement_w, type => C_NORMAL }, - b => { char => 'b', func => \&cmd_movement_b, type => C_NORMAL }, - e => { char => 'e', func => \&cmd_movement_e, type => C_NORMAL }, - ge => { char => 'ge', func => \&cmd_movement_ge, type => C_NORMAL }, - W => { char => 'W', func => \&cmd_movement_W, type => C_NORMAL }, - B => { char => 'B', func => \&cmd_movement_B, type => C_NORMAL }, - E => { char => 'E', func => \&cmd_movement_E, type => C_NORMAL }, - gE => { char => 'gE', func => \&cmd_movement_gE, type => C_NORMAL }, + w => { char => 'w', func => \&cmd_w, type => C_NORMAL }, + b => { char => 'b', func => \&cmd_b, type => C_NORMAL }, + e => { char => 'e', func => \&cmd_e, type => C_NORMAL }, + ge => { char => 'ge', func => \&cmd_ge, type => C_NORMAL }, + W => { char => 'W', func => \&cmd_W, type => C_NORMAL }, + B => { char => 'B', func => \&cmd_B, type => C_NORMAL }, + E => { char => 'E', func => \&cmd_E, type => C_NORMAL }, + gE => { char => 'gE', func => \&cmd_gE, type => C_NORMAL }, # text-objects, leading _ means can't be mapped! - _i => { char => '_i', func => \&cmd_movement__i, type => C_TEXTOBJECT }, - _a => { char => '_a', func => \&cmd_movement__a, type => C_TEXTOBJECT }, + _i => { char => '_i', func => \&cmd__i, type => C_TEXTOBJECT }, + _a => { char => '_a', func => \&cmd__a, type => C_TEXTOBJECT }, # line movement - '0' => { char => '0', func => \&cmd_movement_0, type => C_NORMAL }, - '^' => { char => '^', func => \&cmd_movement_caret, type => C_NORMAL }, - '$' => { char => '$', func => \&cmd_movement_dollar, type => C_NORMAL }, + '0' => { char => '0', func => \&cmd_0, type => C_NORMAL }, + '^' => { char => '^', func => \&cmd_caret, type => C_NORMAL }, + '$' => { char => '$', func => \&cmd_dollar, type => C_NORMAL }, # delete chars - x => { char => 'x', func => \&cmd_movement_x, type => C_NORMAL, + x => { char => 'x', func => \&cmd_x, type => C_NORMAL, repeatable => 1 }, - X => { char => 'X', func => \&cmd_movement_X, type => C_NORMAL, + X => { char => 'X', func => \&cmd_X, type => C_NORMAL, repeatable => 1 }, - s => { char => 's', func => \&cmd_movement_s, type => C_NORMAL, + s => { char => 's', func => \&cmd_s, type => C_NORMAL, repeatable => 1 }, # operator c takes care of insert mode - S => { char => 'S', func => \&cmd_movement_S, type => C_NORMAL, + S => { char => 'S', func => \&cmd_S, type => C_NORMAL, repeatable => 1 }, # operator c takes care of insert mode # insert mode - i => { char => 'i', func => \&cmd_movement_i, type => C_INSERT }, - I => { char => 'I', func => \&cmd_movement_I, type => C_INSERT }, - a => { char => 'a', func => \&cmd_movement_a, type => C_INSERT }, - A => { char => 'A', func => \&cmd_movement_A, type => C_INSERT }, + i => { char => 'i', func => \&cmd_i, type => C_INSERT }, + I => { char => 'I', func => \&cmd_I, type => C_INSERT }, + a => { char => 'a', func => \&cmd_a, type => C_INSERT }, + A => { char => 'A', func => \&cmd_A, type => C_INSERT }, # replace - r => { char => 'r', func => \&cmd_movement_r, type => C_NEEDSKEY, + r => { char => 'r', func => \&cmd_r, type => C_NEEDSKEY, repeatable => 1 }, # paste - p => { char => 'p', func => \&cmd_movement_p, type => C_NORMAL, + p => { char => 'p', func => \&cmd_p, type => C_NORMAL, repeatable => 1 }, - P => { char => 'P', func => \&cmd_movement_P, type => C_NORMAL, + P => { char => 'P', func => \&cmd_P, type => C_NORMAL, repeatable => 1 }, # to end of line - C => { char => 'C', func => \&cmd_movement_C, type => C_NORMAL, + C => { char => 'C', func => \&cmd_C, type => C_NORMAL, repeatable => 1 }, - D => { char => 'D', func => \&cmd_movement_D, type => C_NORMAL, + D => { char => 'D', func => \&cmd_D, type => C_NORMAL, repeatable => 1 }, # scrolling - "\x04" => { char => '', func => \&cmd_movement_ctrl_d, type => C_NORMAL, + "\x04" => { char => '', func => \&cmd_ctrl_d, type => C_NORMAL, repeatable => 1 }, # half screen down - "\x15" => { char => '', func => \&cmd_movement_ctrl_u, type => C_NORMAL, + "\x15" => { char => '', func => \&cmd_ctrl_u, type => C_NORMAL, repeatable => 1 }, # half screen up - "\x06" => { char => '', func => \&cmd_movement_ctrl_f, type => C_NORMAL, + "\x06" => { char => '', func => \&cmd_ctrl_f, type => C_NORMAL, repeatable => 1 }, # screen down - "\x02" => { char => '', func => \&cmd_movement_ctrl_b, type => C_NORMAL, + "\x02" => { char => '', func => \&cmd_ctrl_b, type => C_NORMAL, repeatable => 1 }, # screen up # window switching - "\x17j" => { char => 'j', func => \&cmd_movement_ctrl_wj, type => C_NORMAL, + "\x17j" => { char => 'j', func => \&cmd_ctrl_wj, type => C_NORMAL, needs_count => 1 }, - "\x17k" => { char => 'k', func => \&cmd_movement_ctrl_wk, type => C_NORMAL, + "\x17k" => { char => 'k', func => \&cmd_ctrl_wk, type => C_NORMAL, needs_count => 1 }, - "\x1e" => { char => '', func => \&cmd_movement_ctrl_6, type => C_NORMAL, + "\x1e" => { char => '', func => \&cmd_ctrl_6, type => C_NORMAL, needs_count => 1 }, # misc - '~' => { char => '~', func => \&cmd_movement_tilde, type => C_NORMAL, + '~' => { char => '~', func => \&cmd_tilde, type => C_NORMAL, repeatable => 1 }, - '"' => { char => '"', func => \&cmd_movement_register, type => C_NEEDSKEY }, + '"' => { char => '"', func => \&cmd_register, type => C_NEEDSKEY }, '.' => { char => '.', type => C_NORMAL, repeatable => 1 }, ':' => { char => ':', type => C_NORMAL }, "\n" => { char => '', type => C_NORMAL }, # return @@ -390,7 +390,7 @@ my $imap = undef; my $imaps = { # ctrl-r, insert register - "\x12" => { map => undef, func => \&cmd_insert_ctrl_r }, + "\x12" => { map => undef, func => \&insert_ctrl_r }, }; # index into the history list (for j,k) @@ -417,7 +417,7 @@ sub script_is_loaded { vim_mode_init(); -sub cmd_insert_ctrl_r { +sub insert_ctrl_r { my ($key) = @_; my $char = chr($key); @@ -519,14 +519,14 @@ sub _get_pos_and_length { } -sub cmd_movement_h { +sub cmd_h { my ($count, $pos, $repeat) = @_; $pos -= $count; $pos = 0 if $pos < 0; return (undef, $pos); } -sub cmd_movement_l { +sub cmd_l { my ($count, $pos, $repeat) = @_; my $length = _input_len(); @@ -534,13 +534,13 @@ sub cmd_movement_l { $pos = _fix_input_pos($pos, $length); return (undef, $pos); } -sub cmd_movement_space { +sub cmd_space { my ($count, $pos, $repeat) = @_; - return cmd_movement_l($count, $pos); + return cmd_l($count, $pos); } # later history (down) -sub cmd_movement_j { +sub cmd_j { my ($count, $pos, $repeat) = @_; if (Irssi::version < 20090117) { @@ -579,7 +579,7 @@ sub cmd_movement_j { return (undef, undef); } # earlier history (up) -sub cmd_movement_k { +sub cmd_k { my ($count, $pos, $repeat) = @_; if (Irssi::version < 20090117) { @@ -610,7 +610,7 @@ sub cmd_movement_k { } return (undef, undef); } -sub cmd_movement_G { +sub cmd_G { my ($count, $pos, $repeat) = @_; if (Irssi::version < 20090117) { @@ -646,13 +646,13 @@ sub cmd_movement_G { return (undef, undef); } -sub cmd_movement_gg { +sub cmd_gg { my ($count, $pos, $repeat) = @_; - return cmd_movement_G(1, $pos, $repeat); + return cmd_G(1, $pos, $repeat); } -sub cmd_movement_f { +sub cmd_f { my ($count, $pos, $repeat, $char) = @_; $pos = _next_occurrence(_input(), $char, $count, $pos); @@ -660,7 +660,7 @@ sub cmd_movement_f { $last_ftFT = { type => 'f', char => $char }; return (undef, $pos); } -sub cmd_movement_t { +sub cmd_t { my ($count, $pos, $repeat, $char) = @_; $pos = _next_occurrence(_input(), $char, $count, $pos); @@ -671,7 +671,7 @@ sub cmd_movement_t { $last_ftFT = { type => 't', char => $char }; return (undef, $pos); } -sub cmd_movement_F { +sub cmd_F { my ($count, $pos, $repeat, $char) = @_; my $input = reverse _input(); @@ -683,7 +683,7 @@ sub cmd_movement_F { $last_ftFT = { type => 'F', char => $char }; return (undef, $pos); } -sub cmd_movement_T { +sub cmd_T { my ($count, $pos, $repeat, $char) = @_; my $input = reverse _input(); @@ -708,7 +708,7 @@ sub _next_occurrence { return $pos; } -sub cmd_movement_semicolon { +sub cmd_semicolon { my ($count, $pos, $repeat) = @_; return (undef, undef) if not defined $last_ftFT->{type}; @@ -718,7 +718,7 @@ sub cmd_movement_semicolon { ->{func}($count, $pos, $repeat, $last_ftFT->{char}); return (undef, $pos); } -sub cmd_movement_comma { +sub cmd_comma { my ($count, $pos, $repeat) = @_; return (undef, undef) if not defined $last_ftFT->{type}; @@ -736,7 +736,7 @@ sub cmd_movement_comma { return (undef, $pos); } -sub cmd_movement_w { +sub cmd_w { my ($count, $pos, $repeat) = @_; my $input = _input(); @@ -744,7 +744,7 @@ sub cmd_movement_w { $pos = _fix_input_pos($pos, length $input); return (undef, $pos); } -sub cmd_movement_b { +sub cmd_b { my ($count, $pos, $repeat) = @_; my $input = reverse _input(); @@ -756,7 +756,7 @@ sub cmd_movement_b { $pos = 0 if ($pos < 0); return (undef, $pos); } -sub cmd_movement_e { +sub cmd_e { my ($count, $pos, $repeat) = @_; my $input = _input(); @@ -764,7 +764,7 @@ sub cmd_movement_e { $pos = _fix_input_pos($pos, length $input); return (undef, $pos); } -sub cmd_movement_ge { +sub cmd_ge { my ($count, $pos, $repeat, $char) = @_; my $input = reverse _input(); @@ -832,7 +832,7 @@ sub _end_of_word { return $pos; } -sub cmd_movement_W { +sub cmd_W { my ($count, $pos, $repeat) = @_; my $input = _input(); @@ -840,34 +840,34 @@ sub cmd_movement_W { $pos = _fix_input_pos($pos, length $input); return (undef, $pos); } -sub cmd_movement_B { +sub cmd_B { my ($count, $pos, $repeat) = @_; my $input = reverse _input(); $pos = _end_of_WORD($input, $count, length($input) - $pos - 1); if ($pos == -1) { - return cmd_movement_0(); + return cmd_0(); } else { return (undef, length($input) - $pos - 1); } } -sub cmd_movement_E { +sub cmd_E { my ($count, $pos, $repeat) = @_; $pos = _end_of_WORD(_input(), $count, $pos); if ($pos == -1) { - return cmd_movement_dollar(); + return cmd_dollar(); } else { return (undef, $pos); } } -sub cmd_movement_gE { +sub cmd_gE { my ($count, $pos, $repeat, $char) = @_; my $input = reverse _input(); $pos = _beginning_of_WORD($input, $count, length($input) - $pos - 1); if ($pos == -1 or length($input) - $pos - 1 == -1) { - return cmd_movement_0(); + return cmd_0(); } else { $pos = length($input) - $pos - 1; } @@ -915,13 +915,13 @@ sub _end_of_WORD { return $pos; } -sub cmd_movement__i { +sub cmd__i { my ($count, $pos, $repeat, $char) = @_; _warn("i_ not implemented yet"); return (undef, undef); } -sub cmd_movement__a { +sub cmd__a { my ($count, $pos, $repeat, $char) = @_; my $cur_pos; @@ -1036,10 +1036,10 @@ sub _find_regex_before { } } -sub cmd_movement_0 { +sub cmd_0 { return (undef, 0); } -sub cmd_movement_caret { +sub cmd_caret { my $input = _input(); my $pos; # No whitespace at all. @@ -1054,18 +1054,18 @@ sub cmd_movement_caret { } return (undef, $pos); } -sub cmd_movement_dollar { +sub cmd_dollar { my $length = _input_len(); return (undef, _fix_input_pos($length, $length)); } -sub cmd_movement_x { +sub cmd_x { my ($count, $pos, $repeat) = @_; cmd_operator_d($pos, $pos + $count, 'x'); return (undef, undef); } -sub cmd_movement_X { +sub cmd_X { my ($count, $pos, $repeat) = @_; return (undef, undef) if $pos == 0; @@ -1075,20 +1075,20 @@ sub cmd_movement_X { cmd_operator_d($pos, $new, 'X'); return (undef, undef); } -sub cmd_movement_s { +sub cmd_s { my ($count, $pos, $repeat) = @_; $operator = $commands->{c}; return (undef, $pos + 1); } -sub cmd_movement_S { +sub cmd_S { my ($count, $pos, $repeat) = @_; $operator = $commands->{c}; return (0, _input_len()); } -sub cmd_movement_i { +sub cmd_i { my ($count, $pos, $repeat) = @_; if (!$repeat) { @@ -1098,10 +1098,10 @@ sub cmd_movement_i { } return (undef, $pos); } -sub cmd_movement_I { +sub cmd_I { my ($count, $pos, $repeat) = @_; - $pos = cmd_movement_caret(); + $pos = cmd_caret(); if (!$repeat) { _update_mode(M_INS); } else { @@ -1109,11 +1109,11 @@ sub cmd_movement_I { } return (undef, $pos); } -sub cmd_movement_a { +sub cmd_a { my ($count, $pos, $repeat) = @_; - # Move after current character. Can't use cmd_movement_l() because we need - # to mover after last character at the end of the line. + # Move after current character. Can't use cmd_l() because we need to mover + # after last character at the end of the line. my $length = _input_len(); $pos += 1; $pos = $length if $pos > $length; @@ -1125,7 +1125,7 @@ sub cmd_movement_a { } return (undef, $pos); } -sub cmd_movement_A { +sub cmd_A { my ($count, $pos, $repeat) = @_; $pos = _input_len(); @@ -1160,7 +1160,7 @@ sub _insert_at_position { return $pos - 1 + length $string; } -sub cmd_movement_r { +sub cmd_r { my ($count, $pos, $repeat, $char) = @_; my $input = _input(); @@ -1173,12 +1173,12 @@ sub cmd_movement_r { return (undef, $pos + $count - 1); } -sub cmd_movement_p { +sub cmd_p { my ($count, $pos, $repeat) = @_; $pos = _paste_at_position($count, $pos + 1); return (undef, $pos); } -sub cmd_movement_P { +sub cmd_P { my ($count, $pos, $repeat) = @_; $pos = _paste_at_position($count, $pos); return (undef, $pos); @@ -1190,20 +1190,20 @@ sub _paste_at_position { return _insert_at_position($registers->{$register}, $count, $pos); } -sub cmd_movement_C { +sub cmd_C { my ($count, $pos, $repeat) = @_; $operator = $commands->{c}; return (undef, _input_len()); } -sub cmd_movement_D { +sub cmd_D { my ($count, $pos, $repeat) = @_; $operator = $commands->{d}; return (undef, _input_len()); } -sub cmd_movement_ctrl_d { +sub cmd_ctrl_d { my ($count, $pos, $repeat) = @_; my $window = Irssi::active_win(); @@ -1214,7 +1214,7 @@ sub cmd_movement_ctrl_d { $window->view()->scroll($count); return (undef, undef); } -sub cmd_movement_ctrl_u { +sub cmd_ctrl_u { my ($count, $pos, $repeat) = @_; my $window = Irssi::active_win(); @@ -1225,21 +1225,21 @@ sub cmd_movement_ctrl_u { $window->view()->scroll($count * -1); return (undef, undef); } -sub cmd_movement_ctrl_f { +sub cmd_ctrl_f { my ($count, $pos, $repeat) = @_; my $window = Irssi::active_win(); $window->view()->scroll($count * $window->{height}); return (undef, undef); } -sub cmd_movement_ctrl_b { +sub cmd_ctrl_b { my ($count, $pos, $repeat) = @_; - cmd_movement_ctrl_f($count * -1, $pos, $repeat); + cmd_ctrl_f($count * -1, $pos, $repeat); return (undef, undef); } -sub cmd_movement_ctrl_wj { +sub cmd_ctrl_wj { my ($count, $pos, $repeat) = @_; while ($count -- > 0) { @@ -1248,7 +1248,7 @@ sub cmd_movement_ctrl_wj { return (undef, undef); } -sub cmd_movement_ctrl_wk { +sub cmd_ctrl_wk { my ($count, $pos, $repeat) = @_; while ($count -- > 0) { @@ -1257,13 +1257,13 @@ sub cmd_movement_ctrl_wk { return (undef, undef); } -sub cmd_movement_ctrl_6 { +sub cmd_ctrl_6 { # like :b# Irssi::command('window last'); return (undef, undef); } -sub cmd_movement_tilde { +sub cmd_tilde { my ($count, $pos, $repeat) = @_; my $input = _input(); @@ -1275,7 +1275,7 @@ sub cmd_movement_tilde { return (undef, _fix_input_pos($pos + $count, length $input)); } -sub cmd_movement_register { +sub cmd_register { my ($count, $pos, $repeat, $char) = @_; if (not exists $registers->{$char} and not exists $registers->{lc $char}) { -- cgit v1.2.3 From ba13b09ac6112f9d6c69705b1783fd5ffdf9503b Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 03:51:13 +0200 Subject: vim_mode: Add comments before each code section. --- vim-mode/vim_mode.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index e1bfcca..fe155e2 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -417,6 +417,8 @@ sub script_is_loaded { vim_mode_init(); +# INSERT MODE COMMANDS + sub insert_ctrl_r { my ($key) = @_; @@ -428,6 +430,8 @@ sub insert_ctrl_r { } +# COMMAND MODE OPERATORS + sub cmd_operator_c { my ($old_pos, $new_pos, $move, $repeat) = @_; @@ -518,6 +522,7 @@ sub _get_pos_and_length { return ($old_pos, $length); } +# COMMAND MODE COMMANDS sub cmd_h { my ($count, $pos, $repeat) = @_; @@ -1343,6 +1348,8 @@ sub _fix_input_pos { } +# EX MODE COMMANDS + sub cmd_ex_command { my $arg_str = join '', @ex_buf; if ($arg_str =~ m|^s/(.+)/(.*)/([ig]*)|) { @@ -1484,6 +1491,8 @@ sub _matching_windows { } +# STATUS ITEMS + # vi mode status item. sub vim_mode_cb { my ($sb_item, $get_size_only) = @_; @@ -1535,6 +1544,8 @@ sub b_windows_cb { } +# INPUT HANDLING + sub got_key { my ($key) = @_; -- cgit v1.2.3 From 69fe95c5c37a4b68115a340e8292bb2d693d4e4b Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 04:11:52 +0200 Subject: vim_mode: Separate Ex-mode commands. --- vim-mode/vim_mode.pl | 90 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 16 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index fe155e2..3cb141a 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -303,6 +303,24 @@ my $commands "\x12" => { char => '', func => \&cmd_redo, type => C_NORMAL }, }; +# All available commands in Ex-Mode. +my $commands_ex + = { + s => \&ex_substitute, + bn => \&ex_bnext, + bp => \&ex_bprev, + bd => \&ex_bdelete, + buffer => \&ex_buffer, + b => \&ex_buffer, + registers => \&ex_registers, + reg => \&ex_registers, + display => \&ex_registers, + di => \&ex_registers, + buffers => \&ex_buffers, + ls => \&ex_buffers, + undolist => \&ex_undolist, + undol => \&ex_undolist, + }; # MAPPINGS @@ -1352,6 +1370,21 @@ sub _fix_input_pos { sub cmd_ex_command { my $arg_str = join '', @ex_buf; + + if ($arg_str !~ /^([a-z]+)/) { + return _warn("Invalid Ex-mode command!"); + } + + if (not exists $commands_ex->{$1}) { + return _warn("Ex-mode $1 doesn't exist!"); + } + + $commands_ex->{$1}($arg_str); +} + +sub ex_substitute { + my ($arg_str) = @_; + if ($arg_str =~ m|^s/(.+)/(.*)/([ig]*)|) { my ($search, $replace, $flags) = ($1, $2, $3); print "Searching for $search, replace: $replace, flags; $flags" @@ -1379,17 +1412,25 @@ sub cmd_ex_command { print "New line is: $line" if DEBUG; _input($line); - # :bn - } elsif ($arg_str eq 'bn') { - Irssi::command('window next'); - # :bp - } elsif ($arg_str eq 'bp') { - Irssi::command('window previous'); - # :bd - } elsif ($arg_str eq 'bd') { - Irssi::command('window close'); + } else { + _warn_ex('s'); + } +} + +sub ex_bnext { + Irssi::command('window next'); +} +sub ex_bprev { + Irssi::command('window previous'); +} +sub ex_bdelete { + Irssi::command('window close'); +} +sub ex_buffer { + my ($arg_str) = @_; + # :b[buffer] {args} - } elsif ($arg_str =~ m|^b(?:uffer)?\s*(.+)$|) { + if ($arg_str =~ m|^b(?:uffer)?\s*(.+)$|) { my $window; my $item; my $buffer = $1; @@ -1415,9 +1456,16 @@ sub cmd_ex_command { $item->set_active(); } } + } else { + _warn_ex('buffer'); + } +} + +sub ex_registers { + my ($arg_str) = @_; # :reg[isters] {arg} and :di[splay] {arg} - } elsif ($arg_str =~ /^(?:reg(?:isters)?|di(?:splay)?)(?:\s+(.+)$)?/) { + if ($arg_str =~ /^(?:reg(?:isters)?|di(?:splay)?)(?:\s+(.+)$)?/) { my @regs; if ($1) { my $regs = $1; @@ -1433,14 +1481,24 @@ sub cmd_ex_command { $active_window->print("register $key: $registers->{$key}"); } } - # :ls and :buffers - } elsif ($arg_str eq 'ls' or $arg_str eq 'buffers') { - Irssi::command('window list'); - } elsif ($arg_str eq 'undol' or $arg_str eq 'undolist') { - _print_undo_buffer(); + } else { + _warn_ex(':reigsters'); } } +sub ex_buffers { + Irssi::command('window list'); +} + +sub ex_undolist { + _print_undo_buffer(); +} + +sub _warn_ex { + my ($command) = @_; + _warn("Error in ex-mode command $command"); +} + sub _matching_windows { my ($buffer) = @_; -- cgit v1.2.3 From 2ce2c7d227eeba6315259ab579f29f1570797e3f Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 04:13:45 +0200 Subject: vim_mode: Add :bnext, :bprev and :bdelete. --- vim-mode/vim_mode.pl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 3cb141a..28ceaf7 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -59,9 +59,9 @@ # :b # :b / # :buffer {args} (same as :b) -# :bn - switch to next window -# :bp - switch to previous window -# * Close window: :bd +# :bn[ext] - switch to next window +# :bp[rev] - switch to previous window +# * Close window: :bd[elete] # * Display windows: :ls :buffers # * Display registers: :reg[isters] :di[splay] {args} # * Display undolist: :undol[ist] (mostly used for debugging) @@ -307,8 +307,11 @@ my $commands my $commands_ex = { s => \&ex_substitute, + bnext => \&ex_bnext, bn => \&ex_bnext, + bprev => \&ex_bprev, bp => \&ex_bprev, + bdelete => \&ex_bdelete, bd => \&ex_bdelete, buffer => \&ex_buffer, b => \&ex_buffer, -- cgit v1.2.3 From 3e129bab4162fc6a00bcd0f0149b4dcca46504bd Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 04:19:01 +0200 Subject: vim_mode: Fix minor typo. --- vim-mode/vim_mode.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 28ceaf7..302100e 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -1485,7 +1485,7 @@ sub ex_registers { } } } else { - _warn_ex(':reigsters'); + _warn_ex(':registers'); } } -- cgit v1.2.3 From b73959e84198b677dd81b42b63e0b54689ac761c Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 04:27:09 +0200 Subject: vim_mode: Add internal support to bind ex-mode commands in command mode. --- vim-mode/vim_mode.pl | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 302100e..0daff6d 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -196,6 +196,8 @@ sub C_NEEDSKEY () { 2 } sub C_TEXTOBJECT () { 3 } # commands entering insert mode sub C_INSERT () { 4 } +# ex-mode commands +sub C_EX () { 5 } # word and non-word regex, keep in sync with setup_changed()! my $word = qr/[\w_]/o; @@ -306,23 +308,23 @@ my $commands # All available commands in Ex-Mode. my $commands_ex = { - s => \&ex_substitute, - bnext => \&ex_bnext, - bn => \&ex_bnext, - bprev => \&ex_bprev, - bp => \&ex_bprev, - bdelete => \&ex_bdelete, - bd => \&ex_bdelete, - buffer => \&ex_buffer, - b => \&ex_buffer, - registers => \&ex_registers, - reg => \&ex_registers, - display => \&ex_registers, - di => \&ex_registers, - buffers => \&ex_buffers, - ls => \&ex_buffers, - undolist => \&ex_undolist, - undol => \&ex_undolist, + s => { func => \&ex_substitute => type => C_EX }, + bnext => { func => \&ex_bnext => type => C_EX }, + bn => { func => \&ex_bnext => type => C_EX }, + bprev => { func => \&ex_bprev => type => C_EX }, + bp => { func => \&ex_bprev => type => C_EX }, + bdelete => { func => \&ex_bdelete => type => C_EX }, + bd => { func => \&ex_bdelete => type => C_EX }, + buffer => { func => \&ex_buffer => type => C_EX }, + b => { func => \&ex_buffer => type => C_EX }, + registers => { func => \&ex_registers => type => C_EX }, + reg => { func => \&ex_registers => type => C_EX }, + display => { func => \&ex_registers => type => C_EX }, + di => { func => \&ex_registers => type => C_EX }, + buffers => { func => \&ex_buffers => type => C_EX }, + ls => { func => \&ex_buffers => type => C_EX }, + undolist => { func => \&ex_undolist => type => C_EX }, + undol => { func => \&ex_undolist => type => C_EX }, }; # MAPPINGS @@ -1835,6 +1837,13 @@ sub handle_command_cmd { return 1; # call _stop() } + # Ex-mode commands can also be bound in command mode. Works only if the + # ex-mode command doesn't take any arguments. + if ($cmd->{type} == C_EX) { + $cmd->{func}->(); + return 1; # call _stop() + } + # text-objects (i a) are simulated with $movement if (!$movement and ($cmd->{type} == C_NEEDSKEY or ($operator and ($char eq 'i' or $char eq 'a')))) { -- cgit v1.2.3 From 8b9fa9038758291517a1ced01ebbe45bbd957821 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 18:44:08 +0200 Subject: vim_mode: Fix ex-mode broken in last commit. --- vim-mode/vim_mode.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 0daff6d..f6ba516 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -1384,7 +1384,7 @@ sub cmd_ex_command { return _warn("Ex-mode $1 doesn't exist!"); } - $commands_ex->{$1}($arg_str); + $commands_ex->{$1}->{func}($arg_str); } sub ex_substitute { -- cgit v1.2.3 From dda9e7519366508cebaf08fd820937b636698dd6 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 18:49:52 +0200 Subject: vim_mode: Fix Ctrl-W j, Ctrl-W k. --- vim-mode/vim_mode.pl | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index f6ba516..6f779bb 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -287,12 +287,9 @@ my $commands "\x02" => { char => '', func => \&cmd_ctrl_b, type => C_NORMAL, repeatable => 1 }, # screen up # window switching - "\x17j" => { char => 'j', func => \&cmd_ctrl_wj, type => C_NORMAL, - needs_count => 1 }, - "\x17k" => { char => 'k', func => \&cmd_ctrl_wk, type => C_NORMAL, - needs_count => 1 }, - "\x1e" => { char => '', func => \&cmd_ctrl_6, type => C_NORMAL, - needs_count => 1 }, + "\x17j" => { char => 'j', func => \&cmd_ctrl_wj, type => C_NORMAL }, + "\x17k" => { char => 'k', func => \&cmd_ctrl_wk, type => C_NORMAL }, + "\x1e" => { char => '', func => \&cmd_ctrl_6, type => C_NORMAL }, # misc '~' => { char => '~', func => \&cmd_tilde, type => C_NORMAL, repeatable => 1 }, @@ -1270,7 +1267,7 @@ sub cmd_ctrl_b { sub cmd_ctrl_wj { my ($count, $pos, $repeat) = @_; - while ($count -- > 0) { + while ($count-- > 0) { Irssi::command('window down'); } @@ -1279,7 +1276,7 @@ sub cmd_ctrl_wj { sub cmd_ctrl_wk { my ($count, $pos, $repeat) = @_; - while ($count -- > 0) { + while ($count-- > 0) { Irssi::command('window up'); } -- cgit v1.2.3 From 79141f0d78f0c9d3655e3b07c44b77d3e1658d7c Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 21:14:46 +0200 Subject: vim_mode: Fix i/I/a/A repeat. --- vim-mode/vim_mode.pl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 6f779bb..17cbdad 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -260,10 +260,14 @@ my $commands S => { char => 'S', func => \&cmd_S, type => C_NORMAL, repeatable => 1 }, # operator c takes care of insert mode # insert mode - i => { char => 'i', func => \&cmd_i, type => C_INSERT }, - I => { char => 'I', func => \&cmd_I, type => C_INSERT }, - a => { char => 'a', func => \&cmd_a, type => C_INSERT }, - A => { char => 'A', func => \&cmd_A, type => C_INSERT }, + i => { char => 'i', func => \&cmd_i, type => C_INSERT, + repeatable => 1 }, + I => { char => 'I', func => \&cmd_I, type => C_INSERT, + repeatable => 1 }, + a => { char => 'a', func => \&cmd_a, type => C_INSERT, + repeatable => 1 }, + A => { char => 'A', func => \&cmd_A, type => C_INSERT, + repeatable => 1 }, # replace r => { char => 'r', func => \&cmd_r, type => C_NEEDSKEY, repeatable => 1 }, -- cgit v1.2.3 From 267eed1b9eebd91e6541a3a9d747fffbc28de339 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 21:15:22 +0200 Subject: vim_mode: Minor documentation updates. --- vim-mode/vim_mode.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 17cbdad..ea43169 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -5,6 +5,9 @@ # 5.8.1 is recommended for UTF-8 support (which can be disabled if necessary). # Please report bugs in older versions as well, we'll try to fix them. # +# Any behavior different from Vim (unless explicitly documented) should be +# considered a bug and reported. +# # NOTE: This script is still under heavy development, and there may be bugs. # Please submit reproducible sequences to the bug-tracker at: # http://github.com/shabble/irssi-scripts/issues @@ -2296,7 +2299,7 @@ sub _update_mode { # Change mode to i to support insert mode repetition. This doesn't affect # commands like i/a/I/A because handle_command_cmd() sets $last->{cmd}. - # It's necessary when pressing enter. + # It's necessary when pressing enter so the next line can be repeated. } elsif ($mode == M_CMD and $new_mode == M_INS) { $last->{cmd} = $commands->{i}; # Make sure prompt is cleared when leaving ex mode. -- cgit v1.2.3 From 30e704c5305844bd789e6a36d5103b379e96cc18 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 22:00:01 +0200 Subject: vim_mode: Fix yank movement and behavior. Reported by estragib. --- vim-mode/vim_mode.pl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index ea43169..ce9dc2a 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -510,6 +510,12 @@ sub cmd_operator_y { my ($pos, $length) = _get_pos_and_length($old_pos, $new_pos, $move); + # When yanking left of the current char, the current char is not included + # in the yank. + if ($old_pos > $new_pos) { + $length--; + } + # Extract the selected string and put it in the " register. my $input = _input(); my $string = substr $input, $pos, $length; @@ -521,7 +527,12 @@ sub cmd_operator_y { print "Yanked into $register: ", $registers->{$register} if DEBUG; } - _input_pos($old_pos); + # Always move to the lower position. + if ($old_pos > $new_pos) { + _input_pos($new_pos); + } else { + _input_pos($old_pos); + } } sub _get_pos_and_length { my ($old_pos, $new_pos, $move) = @_; -- cgit v1.2.3 From e1ac5729e88eb1841464b26ae29a580cbe032a0f Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 22:36:17 +0200 Subject: vim_mode: Add warning for irssi < 0.8.13 for g and GG. --- vim-mode/vim_mode.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index ce9dc2a..0be1f13 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -657,6 +657,7 @@ sub cmd_G { my ($count, $pos, $repeat) = @_; if (Irssi::version < 20090117) { + _warn("G and gg not supported in irssi < 0.8.13"); return; } -- cgit v1.2.3 From b7dbdbfa1685778c1b77a991ed37db7980b3d6c9 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 22:45:33 +0200 Subject: vim_mode: Increase insert mode timeout to one second. --- vim-mode/vim_mode.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 0be1f13..0c64a91 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -1674,7 +1674,7 @@ sub got_key { $input_buf_enabled = 1; push @input_buf, $key; $input_buf_timer - = Irssi::timeout_add_once(500, \&flush_input_buffer, undef); + = Irssi::timeout_add_once(1000, \&flush_input_buffer, undef); _stop(); return; -- cgit v1.2.3 From a35a8436a7cc8fe37db0bb5c8462e45e988c80af Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 22:50:17 +0200 Subject: vim_mode: Fix :registers' display of "+ and "*. Reported by estragib. --- vim-mode/vim_mode.pl | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 0c64a91..134874d 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -1495,6 +1495,11 @@ sub ex_registers { } else { @regs = keys %$registers; } + + # Update "+ and "* registers so correct values are displayed. + $registers->{'+'} = Irssi::parse_special('$U'); + $registers->{'*'} = $registers->{'+'}; + my $active_window = Irssi::active_win; foreach my $key (sort @regs) { next if $key eq '_'; # skip black hole -- cgit v1.2.3 From b2bec6638cde0f2f6a64298572bafd0126bcda32 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 7 Oct 2010 23:16:11 +0200 Subject: vim_mode: Add "0, last yank. --- vim-mode/vim_mode.pl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 134874d..52424ce 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -37,9 +37,10 @@ # * Switch case: ~ # * Repeat change: . # * Repeat ftFT: ; , -# * Registers: "a-"z "" "* "+ "_ (black hole) +# * Registers: "a-"z "" "0 "* "+ "_ (black hole) # Appending to register with "A-"Z # "" is the default yank/delete register. +# "0 contains the last yank (if no register was specified). # The special registers "* "+ contain both irssi's cut-buffer. # * Line-wise shortcuts: dd cc yy # * Shortcuts: s S C D @@ -402,6 +403,7 @@ my $register = '"'; my $registers = { '"' => '', # default register + '0' => '', # yank register '+' => '', # contains irssi's cut buffer '*' => '', # same '_' => '', # black hole register, always empty @@ -525,6 +527,10 @@ sub cmd_operator_y { } else { $registers->{$register} = $string; print "Yanked into $register: ", $registers->{$register} if DEBUG; + if ($register eq '"') { + $registers->{0} = $string; + print "Yanked into 0: ", $registers->{0} if DEBUG; + } } # Always move to the lower position. -- cgit v1.2.3 From 76b1897c629061ae5438da67fa6ad87682427726 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 01:38:50 +0200 Subject: vim_mode: Use Vim-like char representation. --- vim-mode/vim_mode.pl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 52424ce..a64df1e 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -224,7 +224,7 @@ my $commands # arrow like movement h => { char => 'h', func => \&cmd_h, type => C_NORMAL }, l => { char => 'l', func => \&cmd_l, type => C_NORMAL }, - ' ' => { char => '', func => \&cmd_space, type => C_NORMAL }, + ' ' => { char => '', func => \&cmd_space, type => C_NORMAL }, # history movement j => { char => 'j', func => \&cmd_j, type => C_NORMAL }, k => { char => 'k', func => \&cmd_k, type => C_NORMAL }, @@ -286,28 +286,28 @@ my $commands D => { char => 'D', func => \&cmd_D, type => C_NORMAL, repeatable => 1 }, # scrolling - "\x04" => { char => '', func => \&cmd_ctrl_d, type => C_NORMAL, + "\x04" => { char => '', func => \&cmd_ctrl_d, type => C_NORMAL, repeatable => 1 }, # half screen down - "\x15" => { char => '', func => \&cmd_ctrl_u, type => C_NORMAL, + "\x15" => { char => '', func => \&cmd_ctrl_u, type => C_NORMAL, repeatable => 1 }, # half screen up - "\x06" => { char => '', func => \&cmd_ctrl_f, type => C_NORMAL, + "\x06" => { char => '', func => \&cmd_ctrl_f, type => C_NORMAL, repeatable => 1 }, # screen down - "\x02" => { char => '', func => \&cmd_ctrl_b, type => C_NORMAL, + "\x02" => { char => '', func => \&cmd_ctrl_b, type => C_NORMAL, repeatable => 1 }, # screen up # window switching - "\x17j" => { char => 'j', func => \&cmd_ctrl_wj, type => C_NORMAL }, - "\x17k" => { char => 'k', func => \&cmd_ctrl_wk, type => C_NORMAL }, - "\x1e" => { char => '', func => \&cmd_ctrl_6, type => C_NORMAL }, + "\x17j" => { char => 'j', func => \&cmd_ctrl_wj, type => C_NORMAL }, + "\x17k" => { char => 'k', func => \&cmd_ctrl_wk, type => C_NORMAL }, + "\x1e" => { char => '', func => \&cmd_ctrl_6, type => C_NORMAL }, # misc '~' => { char => '~', func => \&cmd_tilde, type => C_NORMAL, repeatable => 1 }, '"' => { char => '"', func => \&cmd_register, type => C_NEEDSKEY }, '.' => { char => '.', type => C_NORMAL, repeatable => 1 }, ':' => { char => ':', type => C_NORMAL }, - "\n" => { char => '', type => C_NORMAL }, # return + "\n" => { char => '', type => C_NORMAL }, # return # undo 'u' => { char => 'u', func => \&cmd_undo, type => C_NORMAL }, - "\x12" => { char => '', func => \&cmd_redo, type => C_NORMAL }, + "\x12" => { char => '', func => \&cmd_redo, type => C_NORMAL }, }; # All available commands in Ex-Mode. -- cgit v1.2.3 From 8da515880c62744571ac31fa4ccb9e24c0f63e2a Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 01:45:12 +0200 Subject: vim_mode: Fix error in $commands_ex hash. --- vim-mode/vim_mode.pl | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index a64df1e..8e3a41d 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -313,23 +313,23 @@ my $commands # All available commands in Ex-Mode. my $commands_ex = { - s => { func => \&ex_substitute => type => C_EX }, - bnext => { func => \&ex_bnext => type => C_EX }, - bn => { func => \&ex_bnext => type => C_EX }, - bprev => { func => \&ex_bprev => type => C_EX }, - bp => { func => \&ex_bprev => type => C_EX }, - bdelete => { func => \&ex_bdelete => type => C_EX }, - bd => { func => \&ex_bdelete => type => C_EX }, - buffer => { func => \&ex_buffer => type => C_EX }, - b => { func => \&ex_buffer => type => C_EX }, - registers => { func => \&ex_registers => type => C_EX }, - reg => { func => \&ex_registers => type => C_EX }, - display => { func => \&ex_registers => type => C_EX }, - di => { func => \&ex_registers => type => C_EX }, - buffers => { func => \&ex_buffers => type => C_EX }, - ls => { func => \&ex_buffers => type => C_EX }, - undolist => { func => \&ex_undolist => type => C_EX }, - undol => { func => \&ex_undolist => type => C_EX }, + s => { func => \&ex_substitute, type => C_EX }, + bnext => { func => \&ex_bnext, type => C_EX }, + bn => { func => \&ex_bnext, type => C_EX }, + bprev => { func => \&ex_bprev, type => C_EX }, + bp => { func => \&ex_bprev, type => C_EX }, + bdelete => { func => \&ex_bdelete, type => C_EX }, + bd => { func => \&ex_bdelete, type => C_EX }, + buffer => { func => \&ex_buffer, type => C_EX }, + b => { func => \&ex_buffer, type => C_EX }, + registers => { func => \&ex_registers, type => C_EX }, + reg => { func => \&ex_registers, type => C_EX }, + display => { func => \&ex_registers, type => C_EX }, + di => { func => \&ex_registers, type => C_EX }, + buffers => { func => \&ex_buffers, type => C_EX }, + ls => { func => \&ex_buffers, type => C_EX }, + undolist => { func => \&ex_undolist, type => C_EX }, + undol => { func => \&ex_undolist, type => C_EX }, }; # MAPPINGS -- cgit v1.2.3 From bca1951421952978b11e4c4cf741a83dbd5cfc2a Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 01:50:17 +0200 Subject: vim_mode: Add char to $commands_ex hash. --- vim-mode/vim_mode.pl | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 8e3a41d..042fc34 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -313,23 +313,23 @@ my $commands # All available commands in Ex-Mode. my $commands_ex = { - s => { func => \&ex_substitute, type => C_EX }, - bnext => { func => \&ex_bnext, type => C_EX }, - bn => { func => \&ex_bnext, type => C_EX }, - bprev => { func => \&ex_bprev, type => C_EX }, - bp => { func => \&ex_bprev, type => C_EX }, - bdelete => { func => \&ex_bdelete, type => C_EX }, - bd => { func => \&ex_bdelete, type => C_EX }, - buffer => { func => \&ex_buffer, type => C_EX }, - b => { func => \&ex_buffer, type => C_EX }, - registers => { func => \&ex_registers, type => C_EX }, - reg => { func => \&ex_registers, type => C_EX }, - display => { func => \&ex_registers, type => C_EX }, - di => { func => \&ex_registers, type => C_EX }, - buffers => { func => \&ex_buffers, type => C_EX }, - ls => { func => \&ex_buffers, type => C_EX }, - undolist => { func => \&ex_undolist, type => C_EX }, - undol => { func => \&ex_undolist, type => C_EX }, + s => { char => 's', func => \&ex_substitute, type => C_EX }, + bnext => { char => 'bnext', func => \&ex_bnext, type => C_EX }, + bn => { char => 'bn', func => \&ex_bnext, type => C_EX }, + bprev => { char => 'bprev', func => \&ex_bprev, type => C_EX }, + bp => { char => 'bp', func => \&ex_bprev, type => C_EX }, + bdelete => { char => 'bdelete', func => \&ex_bdelete, type => C_EX }, + bd => { char => 'bd', func => \&ex_bdelete, type => C_EX }, + buffer => { char => 'buffer', func => \&ex_buffer, type => C_EX }, + b => { char => 'b', func => \&ex_buffer, type => C_EX }, + registers => { char => 'registers', func => \&ex_registers, type => C_EX }, + reg => { char => 'reg', func => \&ex_registers, type => C_EX }, + display => { char => 'display', func => \&ex_registers, type => C_EX }, + di => { char => 'di', func => \&ex_registers, type => C_EX }, + buffers => { char => 'buffer', func => \&ex_buffers, type => C_EX }, + ls => { char => 'ls', func => \&ex_buffers, type => C_EX }, + undolist => { char => 'undolist', func => \&ex_undolist, type => C_EX }, + undol => { char => 'undol', func => \&ex_undolist, type => C_EX }, }; # MAPPINGS -- cgit v1.2.3 From 8f84f6e57c31085dcf5cc5a987d44debc11860d5 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 02:23:43 +0200 Subject: vim_mode: Add :map to allow custom mappings. --- vim-mode/vim_mode.pl | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 2 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 042fc34..e941d07 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -69,6 +69,20 @@ # * Display windows: :ls :buffers # * Display registers: :reg[isters] :di[splay] {args} # * Display undolist: :undol[ist] (mostly used for debugging) +# * Mappings: :map - display custom mappings +# :map {lhs} {rhs} - add mapping +# +# Mappings: +# +# {lhs} is the key combination to be mapped, {rhs} the target. The <> notation +# is used (e.g. is Ctrl-F), case is ignored. Supported <> keys: +# -, , , , . Mapping ex-mode command is +# supported. Only default mappings can be used in {rhs}. +# Examples: +# :map gb :bnext # to map gb to call :bnext +# :map gB :bprev +# :map w W # to remap w to work like W +# # # The following irssi settings are available: # @@ -330,6 +344,7 @@ my $commands_ex ls => { char => 'ls', func => \&ex_buffers, type => C_EX }, undolist => { char => 'undolist', func => \&ex_undolist, type => C_EX }, undol => { char => 'undol', func => \&ex_undolist, type => C_EX }, + map => { char => 'map', func => \&ex_map, type => C_EX }, }; # MAPPINGS @@ -1526,9 +1541,113 @@ sub ex_undolist { _print_undo_buffer(); } +sub ex_map { + my ($arg_str) = @_; + + # :map {lhs} {rhs} + if ($arg_str =~ /^map (\S+) (\S+)$/) { + my $lhs = _parse_mapping($1); + my $rhs = $2; + + if (not defined $lhs) { + return _warn_ex('map', 'invalid {lhs}'); + } + + # Add new mapping. + my $command; + if (index($rhs, ':') == 0) { + $rhs = substr $rhs, 1; + if (not exists $commands_ex->{$rhs}) { + return _warn_ex('map', "$2 not found"); + } else { + $command = $commands_ex->{$rhs}; + } + } else { + $rhs = _parse_mapping($2); + if (not defined $rhs) { + return _warn_ex('map', 'invalid {rhs}'); + } elsif (not exists $commands->{$rhs}) { + return _warn_ex('map', "$2 not found"); + } else { + $command = $commands->{$rhs}; + } + } + add_map($lhs, $command); + + # :map + } elsif ($arg_str eq 'map') { + my $active_window = Irssi::active_win(); + foreach my $key (sort keys %$maps) { + my $map = $maps->{$key}; + my $cmd = $map->{cmd}; + if (defined $map->{char}) { + my $char = _parse_mapping_reverse($map->{char}); + next if $char eq $cmd->{char}; # skip default mappings + + my $cmdc = _parse_mapping_reverse($cmd->{char}); + if ($cmd->{type} == C_EX) { + $cmdc = ":$cmdc"; + } + $active_window->print(sprintf "%-15s %s", $char, $cmdc); + } + } + } else { + _warn_ex('map'); + } +} +sub _parse_mapping { + my ($string) = @_; + + $string =~ s/<([^>]+)>/_parse_mapping_bracket($1)/ge; + if (index($string, '') != -1) { + return undef; + } + return $string; +} +sub _parse_mapping_bracket { + my ($string) = @_; + + $string = lc $string; + + # , get corresponding CTRL char. + if ($string =~ /^c-([a-z])$/i) { + $string = chr(ord($1) - 96); + # and + } elsif ($string =~ /^c-[6^]$/i) { + $string = chr(30); + # + } elsif ($string eq 'space') { + $string = ' '; + # + } elsif ($string eq 'cr') { + $string = "\n"; + # Invalid char, return special string to recognize the error. + } else { + $string = ''; + } + return $string; +} +sub _parse_mapping_reverse { + my ($string) = @_; + + # Convert char to . + $string =~ s/ //g; + $string =~ s/\n//g; + # Convert Ctrl-X to . + $string =~ s/([\x01-\x1A])/""/ge; + # Convert Ctrl-6 and Ctrl-^ to . + $string =~ s/\x1E//g; + + return $string; +} + sub _warn_ex { - my ($command) = @_; - _warn("Error in ex-mode command $command"); + my ($command, $description) = @_; + my $message = "Error in ex-mode command $command"; + if (defined $description) { + $message .= ": $description"; + } + _warn($message); } sub _matching_windows { -- cgit v1.2.3 From 95cd31d1cc46c0e8128941862f19015f2f50af62 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 02:31:57 +0200 Subject: vim_mode: Fix :map on a placeholder mapping. Like mapping something to g when no g is used yet (but there are gg G). --- vim-mode/vim_mode.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index e941d07..5e33bf4 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -2345,6 +2345,7 @@ sub add_map { maps => {} }; } else { + $maps->{$keys}->{char} = $keys; $maps->{$keys}->{cmd} = $command; } } -- cgit v1.2.3 From 89f947bf57f0515fca7b9777b77fb032a9479f01 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 03:00:00 +0200 Subject: vim_mode: Add ~/.irssi/vim_moderc as vimrc-like configuration file. --- vim-mode/vim_mode.pl | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 5e33bf4..4a58273 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -69,6 +69,8 @@ # * Display windows: :ls :buffers # * Display registers: :reg[isters] :di[splay] {args} # * Display undolist: :undol[ist] (mostly used for debugging) +# * Source files :so[urce] - only sources vim_moderc at the moment, +# {file} not supported # * Mappings: :map - display custom mappings # :map {lhs} {rhs} - add mapping # @@ -96,6 +98,19 @@ # * vim_windows: displays windows selected with :b # # +# Configuration +# +# Additionally to the irssi settings described above vim_mode can be +# configured through an external configuration file named "vim_moderc" located +# in ~/.irssi/vim_moderc. If available it's loaded on startup and every +# supported ex-command is run. It's syntax is similar to "vimrc". To (re)load +# it while vim_mode is running use :so[urce]. +# +# Supported ex-commands: +# +# * :map +# +# # Installation: # # As always copy the script into .irssi/scripts and load it with @@ -345,6 +360,8 @@ my $commands_ex undolist => { char => 'undolist', func => \&ex_undolist, type => C_EX }, undol => { char => 'undol', func => \&ex_undolist, type => C_EX }, map => { char => 'map', func => \&ex_map, type => C_EX }, + source => { char => 'source', func => \&ex_source, type => C_EX }, + so => { char => 'so', func => \&ex_source, type => C_EX }, }; # MAPPINGS @@ -1641,6 +1658,24 @@ sub _parse_mapping_reverse { return $string; } +sub ex_source { + # so[urce], but only loads the vim_moderc file at the moment + + open my $file, '<', Irssi::get_irssi_dir() . '/vim_moderc' or return; + + while (my $line = <$file>) { + next if $line =~ /^\s*$/ or $line =~ /^\s*"/; + + chomp $line; + # :map {lhs} {rhs} + if ($line =~ /^\s*map (\S+) (\S+)$/) { + ex_map($line); + } else { + _warn_ex('source', "command not supported: $line"); + } + } +} + sub _warn_ex { my ($command, $description) = @_; my $message = "Error in ex-mode command $command"; @@ -2205,6 +2240,9 @@ sub vim_mode_init { Irssi::settings_add_bool('vim_mode', 'vim_mode_utf8', 1); Irssi::settings_add_int('vim_mode', 'vim_mode_max_undo_lines', 50); + # Load the vim_moderc file if it exists. + ex_source('source'); + setup_changed(); _reset_undo_buffer(); } -- cgit v1.2.3 From c71714608583203fe07b8b5e866a1defba2c3d2a Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 16:20:40 +0200 Subject: vim_mode: $map->{char} is always in <> notation. Not control characters. --- vim-mode/vim_mode.pl | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 4a58273..aacaed5 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -1597,15 +1597,14 @@ sub ex_map { foreach my $key (sort keys %$maps) { my $map = $maps->{$key}; my $cmd = $map->{cmd}; - if (defined $map->{char}) { - my $char = _parse_mapping_reverse($map->{char}); - next if $char eq $cmd->{char}; # skip default mappings + if (defined $cmd) { + next if $map->{char} eq $cmd->{char}; # skip default mappings - my $cmdc = _parse_mapping_reverse($cmd->{char}); + my $cmdc = $cmd->{char}; if ($cmd->{type} == C_EX) { $cmdc = ":$cmdc"; } - $active_window->print(sprintf "%-15s %s", $char, $cmdc); + $active_window->print(sprintf "%-15s %s", $map->{char}, $cmdc); } } } else { @@ -2370,7 +2369,10 @@ sub add_map { while (length $tmp > 1) { my $map = substr $tmp, -1, 1, ''; if (not exists $maps->{$tmp}) { - $maps->{$tmp} = { cmd => undef, maps => {} }; + $maps->{$tmp} = { char => _parse_mapping_reverse($tmp), + cmd => undef, + maps => {} + }; } if (not exists $maps->{$tmp}->{maps}->{$tmp . $map}) { $maps->{$tmp}->{maps}->{$tmp . $map} = undef; @@ -2378,14 +2380,13 @@ sub add_map { } if (not exists $maps->{$keys}) { - $maps->{$keys} = { char => $keys, - cmd => $command, + $maps->{$keys} = { char => undef, + cmd => undef, maps => {} }; - } else { - $maps->{$keys}->{char} = $keys; - $maps->{$keys}->{cmd} = $command; } + $maps->{$keys}->{char} = _parse_mapping_reverse($keys); + $maps->{$keys}->{cmd} = $command; } -- cgit v1.2.3 From 0997134c03e0ce1b97739296d56c4eb5ab8e9edb Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 16:22:46 +0200 Subject: vim_mode: Add debug print when calling an ex-command. --- vim-mode/vim_mode.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index aacaed5..6eaf644 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -2020,6 +2020,7 @@ sub handle_command_cmd { # Ex-mode commands can also be bound in command mode. Works only if the # ex-mode command doesn't take any arguments. if ($cmd->{type} == C_EX) { + print "Processing ex-command: $map->{char} ($cmd->{char})" if DEBUG; $cmd->{func}->(); return 1; # call _stop() } -- cgit v1.2.3 From 625b341fd99be2166ec5ab12f1df4e1360090eb1 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 17:32:51 +0200 Subject: vim_mode: Fix operators when moving left of current position. --- vim-mode/vim_mode.pl | 64 +++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 38 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 6eaf644..38847e8 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -261,8 +261,10 @@ my $commands G => { char => 'G', func => \&cmd_G, type => C_NORMAL, needs_count => 1 }, # char movement, take an additional parameter and use $movement - f => { char => 'f', func => \&cmd_f, type => C_NEEDSKEY }, - t => { char => 't', func => \&cmd_t, type => C_NEEDSKEY }, + f => { char => 'f', func => \&cmd_f, type => C_NEEDSKEY, + selection_needs_move_left => 1 }, + t => { char => 't', func => \&cmd_t, type => C_NEEDSKEY, + selection_needs_move_left => 1 }, F => { char => 'F', func => \&cmd_F, type => C_NEEDSKEY }, T => { char => 'T', func => \&cmd_T, type => C_NEEDSKEY }, ';' => { char => ';', func => \&cmd_semicolon, type => C_NORMAL }, @@ -270,12 +272,16 @@ my $commands # word movement w => { char => 'w', func => \&cmd_w, type => C_NORMAL }, b => { char => 'b', func => \&cmd_b, type => C_NORMAL }, - e => { char => 'e', func => \&cmd_e, type => C_NORMAL }, - ge => { char => 'ge', func => \&cmd_ge, type => C_NORMAL }, + e => { char => 'e', func => \&cmd_e, type => C_NORMAL, + selection_needs_move_left => 1 }, + ge => { char => 'ge', func => \&cmd_ge, type => C_NORMAL, + selection_needs_move_left => 1 }, W => { char => 'W', func => \&cmd_W, type => C_NORMAL }, - B => { char => 'B', func => \&cmd_B, type => C_NORMAL }, + B => { char => 'B', func => \&cmd_B, type => C_NORMAL, + selection_needs_move_left => 1 }, E => { char => 'E', func => \&cmd_E, type => C_NORMAL }, - gE => { char => 'gE', func => \&cmd_gE, type => C_NORMAL }, + gE => { char => 'gE', func => \&cmd_gE, type => C_NORMAL, + selection_needs_move_left => 1 }, # text-objects, leading _ means can't be mapped! _i => { char => '_i', func => \&cmd__i, type => C_TEXTOBJECT }, _a => { char => '_a', func => \&cmd__a, type => C_TEXTOBJECT }, @@ -494,11 +500,12 @@ sub insert_ctrl_r { # COMMAND MODE OPERATORS sub cmd_operator_c { - my ($old_pos, $new_pos, $move, $repeat) = @_; + my ($old_pos, $new_pos, $move_cmd, $repeat) = @_; # Changing a word or WORD doesn't delete the last space before a word, but # not if we are on that whitespace before the word. - if ($move eq 'w' or $move eq 'W') { + if ($move_cmd and ($move_cmd == $commands->{w} or + $move_cmd == $commands->{W})) { my $input = _input(); if ($new_pos - $old_pos > 1 and substr($input, $new_pos - 1, 1) =~ /\s/) { @@ -506,7 +513,7 @@ sub cmd_operator_c { } } - cmd_operator_d($old_pos, $new_pos, $move, $repeat, 1); + cmd_operator_d($old_pos, $new_pos, $move_cmd, $repeat, 1); if (!$repeat) { _update_mode(M_INS); @@ -517,9 +524,9 @@ sub cmd_operator_c { } } sub cmd_operator_d { - my ($old_pos, $new_pos, $move, $repeat, $change) = @_; + my ($old_pos, $new_pos, $move_cmd, $repeat, $change) = @_; - my ($pos, $length) = _get_pos_and_length($old_pos, $new_pos, $move); + my ($pos, $length) = _get_pos_and_length($old_pos, $new_pos, $move_cmd); # Remove the selected string from the input. my $input = _input(); @@ -540,15 +547,9 @@ sub cmd_operator_d { _input_pos($pos); } sub cmd_operator_y { - my ($old_pos, $new_pos, $move, $repeat) = @_; + my ($old_pos, $new_pos, $move_cmd, $repeat) = @_; - my ($pos, $length) = _get_pos_and_length($old_pos, $new_pos, $move); - - # When yanking left of the current char, the current char is not included - # in the yank. - if ($old_pos > $new_pos) { - $length--; - } + my ($pos, $length) = _get_pos_and_length($old_pos, $new_pos, $move_cmd); # Extract the selected string and put it in the " register. my $input = _input(); @@ -573,7 +574,7 @@ sub cmd_operator_y { } } sub _get_pos_and_length { - my ($old_pos, $new_pos, $move) = @_; + my ($old_pos, $new_pos, $move_cmd) = @_; my $length = $new_pos - $old_pos; # We need a positive length and $old_pos must be smaller. @@ -582,16 +583,9 @@ sub _get_pos_and_length { $length *= -1; } - # Strip leading _a or _i if a text-object was used. - if ($move =~ /^_[ai](.)/) { - $move = $1; - } - - # Most movement commands don't move one character after the deletion area - # (which is what we need). For those increase length to support proper - # selection/deletion. - if ($move ne 'w' and $move ne 'W' and $move ne 'x' and $move ne 'X' and - $move ne 'B' and $move ne 'h' and $move ne 'l') { + # Some commands don't move one character after the deletion area which is + # necessary for all commands moving to the right. Fix it. + if ($move_cmd->{selection_needs_move_left}) { $length += 1; } @@ -2046,7 +2040,7 @@ sub handle_command_cmd { print "Processing line operator: $map->{char} ($cmd->{char})" if DEBUG; my $pos = _input_pos(); - $cmd->{func}->(0, _input_len(), '', 0); + $cmd->{func}->(0, _input_len(), undef, 0); # Restore position for yy. if ($cmd == $commands->{y}) { _input_pos($pos); @@ -2153,13 +2147,7 @@ sub handle_command_cmd { # problems with e.g. f when the search string doesn't exist). if ($operator and $cur_pos != $new_pos) { print "Processing operator: ", $operator->{char} if DEBUG; - # If text-objects are used the real move character must also - # be passed to the operator. - my $tmp_char = $cmd->{char}; - if ($tmp_char eq '_i' or $tmp_char eq '_a') { - $tmp_char .= $char; - } - $operator->{func}->($cur_pos, $new_pos, $tmp_char, $repeat); + $operator->{func}->($cur_pos, $new_pos, $cmd, $repeat); } # Save an undo checkpoint here for operators, all repeatable -- cgit v1.2.3 From 983da67499dd29ad6ea688ca20bc307a0a37b67d Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 17:37:11 +0200 Subject: vim_mode: Fix typo. --- vim-mode/vim_mode.pl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 38847e8..8b8e4ef 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -262,9 +262,9 @@ my $commands needs_count => 1 }, # char movement, take an additional parameter and use $movement f => { char => 'f', func => \&cmd_f, type => C_NEEDSKEY, - selection_needs_move_left => 1 }, + selection_needs_move_right => 1 }, t => { char => 't', func => \&cmd_t, type => C_NEEDSKEY, - selection_needs_move_left => 1 }, + selection_needs_move_right => 1 }, F => { char => 'F', func => \&cmd_F, type => C_NEEDSKEY }, T => { char => 'T', func => \&cmd_T, type => C_NEEDSKEY }, ';' => { char => ';', func => \&cmd_semicolon, type => C_NORMAL }, @@ -273,15 +273,15 @@ my $commands w => { char => 'w', func => \&cmd_w, type => C_NORMAL }, b => { char => 'b', func => \&cmd_b, type => C_NORMAL }, e => { char => 'e', func => \&cmd_e, type => C_NORMAL, - selection_needs_move_left => 1 }, + selection_needs_move_right => 1 }, ge => { char => 'ge', func => \&cmd_ge, type => C_NORMAL, - selection_needs_move_left => 1 }, + selection_needs_move_right => 1 }, W => { char => 'W', func => \&cmd_W, type => C_NORMAL }, B => { char => 'B', func => \&cmd_B, type => C_NORMAL, - selection_needs_move_left => 1 }, + selection_needs_move_right => 1 }, E => { char => 'E', func => \&cmd_E, type => C_NORMAL }, gE => { char => 'gE', func => \&cmd_gE, type => C_NORMAL, - selection_needs_move_left => 1 }, + selection_needs_move_right => 1 }, # text-objects, leading _ means can't be mapped! _i => { char => '_i', func => \&cmd__i, type => C_TEXTOBJECT }, _a => { char => '_a', func => \&cmd__a, type => C_TEXTOBJECT }, @@ -585,7 +585,7 @@ sub _get_pos_and_length { # Some commands don't move one character after the deletion area which is # necessary for all commands moving to the right. Fix it. - if ($move_cmd->{selection_needs_move_left}) { + if ($move_cmd->{selection_needs_move_right}) { $length += 1; } -- cgit v1.2.3 From f2eeea1f085cd74e3a84cfeb665e3bf36f06de8f Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 18:00:03 +0200 Subject: vim_mode: Fix x and X broken in last commit. --- vim-mode/vim_mode.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 8b8e4ef..45b84a6 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -1138,7 +1138,7 @@ sub cmd_dollar { sub cmd_x { my ($count, $pos, $repeat) = @_; - cmd_operator_d($pos, $pos + $count, 'x'); + cmd_operator_d($pos, $pos + $count, $commands->{x}, $repeat); return (undef, undef); } sub cmd_X { @@ -1148,7 +1148,7 @@ sub cmd_X { my $new = $pos - $count; $new = 0 if $new < 0; - cmd_operator_d($pos, $new, 'X'); + cmd_operator_d($pos, $new, $commands->{X}, $repeat); return (undef, undef); } sub cmd_s { -- cgit v1.2.3 From d6238f38be11ca65f77a1c02324972e6da4519bf Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 18:07:21 +0200 Subject: vim_mode: Fix mapping ex-commands which take an argument. Reported by estragib. --- vim-mode/vim_mode.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 45b84a6..a3d9723 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -2012,10 +2012,10 @@ sub handle_command_cmd { } # Ex-mode commands can also be bound in command mode. Works only if the - # ex-mode command doesn't take any arguments. + # ex-mode command doesn't need any additional arguments. if ($cmd->{type} == C_EX) { print "Processing ex-command: $map->{char} ($cmd->{char})" if DEBUG; - $cmd->{func}->(); + $cmd->{func}->($cmd->{char}); return 1; # call _stop() } -- cgit v1.2.3 From 654983c7259fa68c3d4fd3392fbf95a3eab2509d Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 18:18:02 +0200 Subject: vim_mode: Scroll commands are not repeatable. --- vim-mode/vim_mode.pl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index a3d9723..089af2e 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -321,14 +321,10 @@ my $commands D => { char => 'D', func => \&cmd_D, type => C_NORMAL, repeatable => 1 }, # scrolling - "\x04" => { char => '', func => \&cmd_ctrl_d, type => C_NORMAL, - repeatable => 1 }, # half screen down - "\x15" => { char => '', func => \&cmd_ctrl_u, type => C_NORMAL, - repeatable => 1 }, # half screen up - "\x06" => { char => '', func => \&cmd_ctrl_f, type => C_NORMAL, - repeatable => 1 }, # screen down - "\x02" => { char => '', func => \&cmd_ctrl_b, type => C_NORMAL, - repeatable => 1 }, # screen up + "\x04" => { char => '', func => \&cmd_ctrl_d, type => C_NORMAL }, + "\x15" => { char => '', func => \&cmd_ctrl_u, type => C_NORMAL }, + "\x06" => { char => '', func => \&cmd_ctrl_f, type => C_NORMAL }, + "\x02" => { char => '', func => \&cmd_ctrl_b, type => C_NORMAL }, # window switching "\x17j" => { char => 'j', func => \&cmd_ctrl_wj, type => C_NORMAL }, "\x17k" => { char => 'k', func => \&cmd_ctrl_wk, type => C_NORMAL }, -- cgit v1.2.3 From 919b1af9675e653ec9bac8e67d9568e53045f4e3 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 18:19:58 +0200 Subject: vim_mode: Fix / only scrolling one line. Reported by estragib. --- vim-mode/vim_mode.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 089af2e..0f56639 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -321,8 +321,10 @@ my $commands D => { char => 'D', func => \&cmd_D, type => C_NORMAL, repeatable => 1 }, # scrolling - "\x04" => { char => '', func => \&cmd_ctrl_d, type => C_NORMAL }, - "\x15" => { char => '', func => \&cmd_ctrl_u, type => C_NORMAL }, + "\x04" => { char => '', func => \&cmd_ctrl_d, type => C_NORMAL, + needs_count => 1 }, + "\x15" => { char => '', func => \&cmd_ctrl_u, type => C_NORMAL, + needs_count => 1 }, "\x06" => { char => '', func => \&cmd_ctrl_f, type => C_NORMAL }, "\x02" => { char => '', func => \&cmd_ctrl_b, type => C_NORMAL }, # window switching -- cgit v1.2.3 From c98389640a0d4c6f5bf1668d338ce22ca8e3bfd0 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 18:27:22 +0200 Subject: vim_mode: Add and . --- vim-mode/vim_mode.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 0f56639..88c4bfb 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -44,7 +44,7 @@ # The special registers "* "+ contain both irssi's cut-buffer. # * Line-wise shortcuts: dd cc yy # * Shortcuts: s S C D -# * Scroll the scrollback buffer: Ctrl-D Ctrl-U Ctrl-F Ctrl-B +# * Scroll the scrollback buffer: Ctrl-E Ctrl-D Ctrl-Y Ctrl-U Ctrl-F Ctrl-B # * Switch to last active window: Ctrl-6/Ctrl-^ # * Switch split windows: Ctrl-W j Ctrl-W k # * Undo/Redo: u Ctrl-R @@ -321,8 +321,10 @@ my $commands D => { char => 'D', func => \&cmd_D, type => C_NORMAL, repeatable => 1 }, # scrolling + "\x05" => { char => '', func => \&cmd_ctrl_d, type => C_NORMAL }, "\x04" => { char => '', func => \&cmd_ctrl_d, type => C_NORMAL, needs_count => 1 }, + "\x19" => { char => '', func => \&cmd_ctrl_u, type => C_NORMAL }, "\x15" => { char => '', func => \&cmd_ctrl_u, type => C_NORMAL, needs_count => 1 }, "\x06" => { char => '', func => \&cmd_ctrl_f, type => C_NORMAL }, -- cgit v1.2.3 From 65938fc59dd2c41751f6a05e8c823cf52b5f3750 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 18:31:26 +0200 Subject: vim_mode: Backspacing over : in ex-mode exists it. Suggested by estragib. --- vim-mode/vim_mode.pl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 88c4bfb..34460f8 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -2196,8 +2196,13 @@ sub handle_command_ex { # DEL key - remove last character if ($key == 127) { print "Delete" if DEBUG; - pop @ex_buf; - _set_prompt(':' . join '', @ex_buf); + if (scalar @ex_buf > 0) { + pop @ex_buf; + _set_prompt(':' . join '', @ex_buf); + # Backspacing over : exists ex-mode. + } else { + _update_mode(M_CMD); + } # Return key - execute command } elsif ($key == 10) { -- cgit v1.2.3 From 6eda12ac8b4c0ed2122bf35e2d6e6f4a7e30db62 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 18:34:51 +0200 Subject: vim_mode: Ignore control characters in ex-mode for now. Reported by estragib. --- vim-mode/vim_mode.pl | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 34460f8..ed348e4 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -2210,6 +2210,10 @@ sub handle_command_ex { cmd_ex_command(); _update_mode(M_CMD); + # Ignore control characters for now. + } elsif ($key < 32) { + # TODO: use them later, e.g. completion + # Append entered key } else { push @ex_buf, chr $key; -- cgit v1.2.3 From 061009db47d267772db1c95b8bfdcf31de97d343 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 19:08:57 +0200 Subject: vim_mode: :map can map irssi commands. --- vim-mode/vim_mode.pl | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index ed348e4..fe54173 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -78,12 +78,13 @@ # # {lhs} is the key combination to be mapped, {rhs} the target. The <> notation # is used (e.g. is Ctrl-F), case is ignored. Supported <> keys: -# -, , , , . Mapping ex-mode command is -# supported. Only default mappings can be used in {rhs}. +# -, , , , . Mapping ex-mode and irssi commands +# is supported. Only default mappings can be used in {rhs}. # Examples: +# :map w W # to remap w to work like W # :map gb :bnext # to map gb to call :bnext # :map gB :bprev -# :map w W # to remap w to work like W +# :map /clear # map Ctrl-L to irssi command /clear # # # The following irssi settings are available: @@ -231,6 +232,8 @@ sub C_TEXTOBJECT () { 3 } sub C_INSERT () { 4 } # ex-mode commands sub C_EX () { 5 } +# irssi commands +sub C_IRSSI () { 6 } # word and non-word regex, keep in sync with setup_changed()! my $word = qr/[\w_]/o; @@ -1566,6 +1569,7 @@ sub ex_map { # Add new mapping. my $command; + # Ex-mode command if (index($rhs, ':') == 0) { $rhs = substr $rhs, 1; if (not exists $commands_ex->{$rhs}) { @@ -1573,6 +1577,13 @@ sub ex_map { } else { $command = $commands_ex->{$rhs}; } + # Irssi command + } elsif (index($rhs, '/') == 0) { + $command = { char => $rhs, + func => substr($rhs, 1), + type => C_IRSSI, + }; + # command-mode command } else { $rhs = _parse_mapping($2); if (not defined $rhs) { @@ -2017,6 +2028,11 @@ sub handle_command_cmd { print "Processing ex-command: $map->{char} ($cmd->{char})" if DEBUG; $cmd->{func}->($cmd->{char}); return 1; # call _stop() + # As can irssi commands. + } elsif ($cmd->{type} == C_IRSSI) { + print "Processing irssi-command: $map->{char} ($cmd->{char})" if DEBUG; + Irssi::command($cmd->{func}); + return 1; # call _stop(); } # text-objects (i a) are simulated with $movement -- cgit v1.2.3 From a1e94e9867c6ddb3f8c9c8900007c91c35ef8030 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 20:12:59 +0200 Subject: vim_mode: :map supports {rhs} with spaces. --- vim-mode/vim_mode.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index fe54173..9ac7e1a 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -85,6 +85,7 @@ # :map gb :bnext # to map gb to call :bnext # :map gB :bprev # :map /clear # map Ctrl-L to irssi command /clear +# :map /window goto 1 # # # The following irssi settings are available: @@ -1559,7 +1560,7 @@ sub ex_map { my ($arg_str) = @_; # :map {lhs} {rhs} - if ($arg_str =~ /^map (\S+) (\S+)$/) { + if ($arg_str =~ /^map (\S+) (\S.+)$/) { my $lhs = _parse_mapping($1); my $rhs = $2; @@ -1671,8 +1672,8 @@ sub ex_source { next if $line =~ /^\s*$/ or $line =~ /^\s*"/; chomp $line; - # :map {lhs} {rhs} - if ($line =~ /^\s*map (\S+) (\S+)$/) { + # :map {lhs} {rhs}, keep in sync with ex_map() + if ($line =~ /^\s*map (\S+) (\S.+)$/) { ex_map($line); } else { _warn_ex('source', "command not supported: $line"); -- cgit v1.2.3 From 67d2b80e972b5c516f80c020cd4bd49f77444194 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 20:22:35 +0200 Subject: vim_mode: Minor source comment fixes. --- vim-mode/vim_mode.pl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 9ac7e1a..2ad0154 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -223,11 +223,11 @@ sub M_EX () { 2 } # extended mode (after a :?) # operator command sub C_OPERATOR () { 0 } -# normal commmand +# normal command, no special handling necessary sub C_NORMAL () { 1 } # command taking another key as argument sub C_NEEDSKEY () { 2 } -# text-object commmand (i a) +# text-object command (i a) sub C_TEXTOBJECT () { 3 } # commands entering insert mode sub C_INSERT () { 4 } @@ -460,7 +460,7 @@ my $imap = undef; # maps for insert mode my $imaps = { - # ctrl-r, insert register + # CTRL-R, insert register "\x12" => { map => undef, func => \&insert_ctrl_r }, }; @@ -1442,6 +1442,7 @@ sub cmd_ex_command { sub ex_substitute { my ($arg_str) = @_; + # :s/// if ($arg_str =~ m|^s/(.+)/(.*)/([ig]*)|) { my ($search, $replace, $flags) = ($1, $2, $3); print "Searching for $search, replace: $replace, flags; $flags" @@ -1664,7 +1665,7 @@ sub _parse_mapping_reverse { } sub ex_source { - # so[urce], but only loads the vim_moderc file at the moment + # :so[urce], but only loads the vim_moderc file at the moment open my $file, '<', Irssi::get_irssi_dir() . '/vim_moderc' or return; @@ -1854,7 +1855,7 @@ sub got_key { } elsif ($key == 127) { @insert_buf = (); # All other entered characters need to be stored to allow repeat of - # insert mode. Ignore delete and ctrl characters. + # insert mode. Ignore delete and control characters. } elsif ($key > 31) { push @insert_buf, chr($key); } @@ -2171,7 +2172,7 @@ sub handle_command_cmd { # movements, operators and repetition. if ((defined $operator and $operator == $commands->{d}) or $cmd->{repeatable}) { - # TODO: why do histpry entries still show up in undo + # TODO: why do history entries still show up in undo # buffer? Is avoiding the commands here insufficient? _add_undo_entry(_input(), _input_pos()); @@ -2216,7 +2217,7 @@ sub handle_command_ex { if (scalar @ex_buf > 0) { pop @ex_buf; _set_prompt(':' . join '', @ex_buf); - # Backspacing over : exists ex-mode. + # Backspacing over : exits ex-mode. } else { _update_mode(M_CMD); } -- cgit v1.2.3 From 666df44d96c515520936e4af35c87dd15cfc718c Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 20:33:00 +0200 Subject: vim_mode: Document :s///. --- vim-mode/vim_mode.pl | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 2ad0154..9dab0aa 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -73,6 +73,10 @@ # {file} not supported # * Mappings: :map - display custom mappings # :map {lhs} {rhs} - add mapping +# * Substitute: :s/// - i and g are supported as flags, only /// can be +# used as separator, uses Perl regex instead of +# Vim regex +# # # Mappings: # -- cgit v1.2.3 From b0975cfc7ef0fd32089a1296f0280639c3d759cc Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 20:34:34 +0200 Subject: vim_mode: Minor code cleanup. --- vim-mode/vim_mode.pl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 9dab0aa..08d8a7c 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -221,9 +221,12 @@ $VERSION = "1.0.1"; # CONSTANTS -sub M_CMD() { 1 } # command mode -sub M_INS() { 0 } # insert mode -sub M_EX () { 2 } # extended mode (after a :?) +# command mode +sub M_CMD () { 1 } +# insert mode +sub M_INS () { 0 } +# extended mode (after a :?) +sub M_EX () { 2 } # operator command sub C_OPERATOR () { 0 } @@ -317,7 +320,7 @@ my $commands repeatable => 1 }, # replace r => { char => 'r', func => \&cmd_r, type => C_NEEDSKEY, - repeatable => 1 }, + repeatable => 1 }, # paste p => { char => 'p', func => \&cmd_p, type => C_NORMAL, repeatable => 1 }, @@ -2095,7 +2098,7 @@ sub handle_command_cmd { _commit_line(); return 0; # don't call _stop() - } else { #if ($movement || exists $movements->{$char}) { + } else { print "Processing command: $map->{char} ($cmd->{char})" if DEBUG; my $skip = 0; -- cgit v1.2.3 From d736f605126e368124b3ff8ed4db5b28f83b650f Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 20:40:52 +0200 Subject: vim_mode: Add : to $commands_ex's {char}. --- vim-mode/vim_mode.pl | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 08d8a7c..bbc71e6 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -359,26 +359,26 @@ my $commands # All available commands in Ex-Mode. my $commands_ex = { - s => { char => 's', func => \&ex_substitute, type => C_EX }, - bnext => { char => 'bnext', func => \&ex_bnext, type => C_EX }, - bn => { char => 'bn', func => \&ex_bnext, type => C_EX }, - bprev => { char => 'bprev', func => \&ex_bprev, type => C_EX }, - bp => { char => 'bp', func => \&ex_bprev, type => C_EX }, - bdelete => { char => 'bdelete', func => \&ex_bdelete, type => C_EX }, - bd => { char => 'bd', func => \&ex_bdelete, type => C_EX }, - buffer => { char => 'buffer', func => \&ex_buffer, type => C_EX }, - b => { char => 'b', func => \&ex_buffer, type => C_EX }, - registers => { char => 'registers', func => \&ex_registers, type => C_EX }, - reg => { char => 'reg', func => \&ex_registers, type => C_EX }, - display => { char => 'display', func => \&ex_registers, type => C_EX }, - di => { char => 'di', func => \&ex_registers, type => C_EX }, - buffers => { char => 'buffer', func => \&ex_buffers, type => C_EX }, - ls => { char => 'ls', func => \&ex_buffers, type => C_EX }, - undolist => { char => 'undolist', func => \&ex_undolist, type => C_EX }, - undol => { char => 'undol', func => \&ex_undolist, type => C_EX }, - map => { char => 'map', func => \&ex_map, type => C_EX }, - source => { char => 'source', func => \&ex_source, type => C_EX }, - so => { char => 'so', func => \&ex_source, type => C_EX }, + s => { char => ':s', func => \&ex_substitute, type => C_EX }, + bnext => { char => ':bnext', func => \&ex_bnext, type => C_EX }, + bn => { char => ':bn', func => \&ex_bnext, type => C_EX }, + bprev => { char => ':bprev', func => \&ex_bprev, type => C_EX }, + bp => { char => ':bp', func => \&ex_bprev, type => C_EX }, + bdelete => { char => ':bdelete', func => \&ex_bdelete, type => C_EX }, + bd => { char => ':bd', func => \&ex_bdelete, type => C_EX }, + buffer => { char => ':buffer', func => \&ex_buffer, type => C_EX }, + b => { char => ':b', func => \&ex_buffer, type => C_EX }, + registers => { char => ':registers', func => \&ex_registers, type => C_EX }, + reg => { char => ':reg', func => \&ex_registers, type => C_EX }, + display => { char => ':display', func => \&ex_registers, type => C_EX }, + di => { char => ':di', func => \&ex_registers, type => C_EX }, + buffers => { char => ':buffer', func => \&ex_buffers, type => C_EX }, + ls => { char => ':ls', func => \&ex_buffers, type => C_EX }, + undolist => { char => ':undolist', func => \&ex_undolist, type => C_EX }, + undol => { char => ':undol', func => \&ex_undolist, type => C_EX }, + map => { char => ':map', func => \&ex_map, type => C_EX }, + source => { char => ':source', func => \&ex_source, type => C_EX }, + so => { char => ':so', func => \&ex_source, type => C_EX }, }; # MAPPINGS @@ -1613,12 +1613,8 @@ sub ex_map { my $cmd = $map->{cmd}; if (defined $cmd) { next if $map->{char} eq $cmd->{char}; # skip default mappings - - my $cmdc = $cmd->{char}; - if ($cmd->{type} == C_EX) { - $cmdc = ":$cmdc"; - } - $active_window->print(sprintf "%-15s %s", $map->{char}, $cmdc); + $active_window->print(sprintf "%-15s %s", $map->{char}, + $cmd->{char}); } } } else { -- cgit v1.2.3 From 829bc9334ea1527fac426ecdee51810a7609227d Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 20:54:51 +0200 Subject: vim_mode: Add undo/redo positions to known bugs. --- vim-mode/vim_mode.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index bbc71e6..28e254d 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -156,6 +156,7 @@ # Known bugs: # # * count before register doesn't work: e.g. 3"ap doesn't work, but "a3p does +# * undo/redo positions are mostly wrong # # # TODO: -- cgit v1.2.3 From 7a8b3aa0ea4571c278d68cea51c4ccd10fc7a011 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 8 Oct 2010 21:22:24 +0200 Subject: vim_mode: Fix display of 'more' statusbar when scrolling. Reported by estragib. --- vim-mode/vim_mode.pl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'vim-mode') diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 28e254d..feea4c6 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -1300,6 +1300,8 @@ sub cmd_ctrl_d { $count = $window->{height} / 2; } $window->view()->scroll($count); + + Irssi::statusbar_items_redraw('more'); return (undef, undef); } sub cmd_ctrl_u { @@ -1311,6 +1313,8 @@ sub cmd_ctrl_u { $count = $window->{height} / 2; } $window->view()->scroll($count * -1); + + Irssi::statusbar_items_redraw('more'); return (undef, undef); } sub cmd_ctrl_f { @@ -1318,13 +1322,14 @@ sub cmd_ctrl_f { my $window = Irssi::active_win(); $window->view()->scroll($count * $window->{height}); + + Irssi::statusbar_items_redraw('more'); return (undef, undef); } sub cmd_ctrl_b { my ($count, $pos, $repeat) = @_; - cmd_ctrl_f($count * -1, $pos, $repeat); - return (undef, undef); + return cmd_ctrl_f($count * -1, $pos, $repeat); } sub cmd_ctrl_wj { -- cgit v1.2.3