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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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/vim_mode.pl') 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