diff options
Diffstat (limited to 'vim-mode')
-rw-r--r-- | vim-mode/vim_mode.pl | 92 |
1 files changed, 77 insertions, 15 deletions
diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 6fd88cd..495bc48 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -7,8 +7,8 @@ # * cursor word motion with: w, b # * delete at cursor: x # * Insert mode at pos: i -# * Insert mode at end: I -# * insert mode at start: A +# * Insert mode at start: I +# * insert mode at end: A # Installation: # @@ -69,6 +69,7 @@ my $should_ignore = 0; my $pending_command; # argument handling. + my @args_buf; my $collecting_args = 0; # if we're actively collecting them. my $args_type = A_NON; # what type of args (constants above) @@ -107,13 +108,13 @@ my $commands params => {pos => sub { _input_pos() }}, }, - 'I' => { command => 'insert at end', + 'A' => { command => 'insert at end', func => \&cmd_insert, args => { type => A_NON }, params => {pos => sub { _input_len() }}, }, - 'A' => { command => 'insert at start', + 'I' => { command => 'insert at start', func => \&cmd_insert, args => { type => A_NON }, params => { pos => sub { 0 } }, @@ -144,6 +145,11 @@ my $commands 'pos' => sub { _input_pos() } }, }, + 'd' => { command => 'delete', + func => \&cmd_delete, + args => { type => A_NUM, num => 1 }, + params => { 'pos' => sub { _input_pos() } }, + }, 'x' => { command => 'delete char forward', func => \&cmd_delete_char, @@ -152,22 +158,61 @@ my $commands 'pos' => sub { _input_pos() } }, }, - ':' => { command => 'search/replace', - func => \&cmd_replace, + ':' => { command => 'Ex command', + func => \&cmd_ex_command, args => { type => A_RET }, - params => { 'dir' => 'fwd', - 'pos' => sub { _input_pos() } - }, - } + params => { 'pos' => sub { _input_pos() } }, + }, }; + +sub cmd_delete { + my ($params) = @_; + my @args = @{$params->{args}}; + my $arg = $args[0] // ''; + + if ($arg eq '$') { # end of line + } elsif ($arg eq '^') { #start of line + } else { + # dunno + } +} sub cmd_replace { my ($params) = @_; } -sub cmd_ex_mode { +sub cmd_ex_command { my ($params) = @_; - _set_prompt(":"); + my $args = $params->{arg_buf}; + my $arg_str = join '', @$args; + if ($arg_str =~ m|s/(.+)/(.*)/([ig]*)|) { + my ($search, $replace, $flags) = ($1, $2, $3); + print "Searching for $search, replace: $replace, flags; $flags" + if DEBUG; + + my $rep_fun = sub { $replace }; + + my $line = _input(); + my @re_flags = split '', $flags // ''; + + if (scalar grep { $_ eq 'i' } @re_flags) { + $search = '(?i)' . $search; + } + + print "Search is $search"; + + my $re_pattern = qr/$search/; + + if (scalar grep { $_ eq 'g' } @re_flags) { + $line =~ s/$re_pattern/$rep_fun->()/eg; + } else { + print "Single replace: $replace"; + $line =~ s/$re_pattern/$rep_fun->()/e; + } + + print "New line is: $line"; + _input($line); + } } sub cmd_delete_char { @@ -219,7 +264,8 @@ sub cmd_move { } else { push @buf, 67; } - _emulate_keystrokes(@buf); + my $count = $params->{prefix} // 1; + _emulate_keystrokes(@buf) for 1..$count; } sub vim_mode_cb { @@ -307,8 +353,15 @@ sub collect_args { print "Collecting arguments" if DEBUG; + if ($key == 127) { # DEL key - remove last argument + print "Delete" if DEBUG; + pop @args_buf; + _set_prompt(':' . join '', @args_buf); + return; + } + if ($args_type == A_NUM) { - push @args_buf, $key; + push @args_buf, chr $key; print "numbered args, expect: $args_num, got: " .scalar(@args_buf) if DEBUG; @@ -322,7 +375,8 @@ sub collect_args { if ($key == 10) { dispatch_command($pending_command, @args_buf); } else { - push @args_buf, $key; + push @args_buf, chr $key; + _set_prompt(':' . join '', @args_buf); } } } @@ -389,6 +443,9 @@ sub handle_command { sub dispatch_command { my ($cmd, @args) = @_; $collecting_args = 0; + $pending_command = undef; + @args_buf = (); + _set_prompt(''); if (defined $numeric_prefix) { $cmd->{params}->{prefix} = $numeric_prefix; @@ -398,6 +455,8 @@ sub dispatch_command { print "Dispatchign command with args: " . join(", ", @args) if DEBUG; $cmd->{params}->{arg_buf} = \@args; + + # actually call the function $cmd->{func}->($cmd->{params} ); } @@ -456,3 +515,6 @@ sub _set_prompt { $msg = ' ' . $msg if length $msg; Irssi::signal_emit('change prompt', $msg); } +# TODO: +# 10gg -> go to window 10 (prefix.gg -> win <prefix>) + |