aboutsummaryrefslogtreecommitdiffstats
path: root/vim-mode
diff options
context:
space:
mode:
authorSimon Ruderich <simon@ruderich.org>2010-09-26 13:38:32 +0000
committerSimon Ruderich <simon@ruderich.org>2010-09-26 13:38:32 +0000
commit2c6a2860d78230bea73010471254c8859dd1cf38 (patch)
tree328158c1b3b982e3c3daeb6189805ab2bb1c8397 /vim-mode
parentvim_mode: Update documentation. (diff)
downloadirssi-scripts-2c6a2860d78230bea73010471254c8859dd1cf38.tar.gz
irssi-scripts-2c6a2860d78230bea73010471254c8859dd1cf38.zip
vim_mode: Implement yank/paste: y p P.
Diffstat (limited to 'vim-mode')
-rw-r--r--vim-mode/vim_mode.pl68
1 files changed, 60 insertions, 8 deletions
diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl
index d441afc..4fa4120 100644
--- a/vim-mode/vim_mode.pl
+++ b/vim-mode/vim_mode.pl
@@ -80,6 +80,12 @@ my $movement = undef;
# what Vi mode we're in. We start in insert mode.
my $mode = M_INS;
+# vi registers, at the moment only the default yank register (") is used
+my $registers
+ = {
+ '"' => ''
+ };
+
# index into the history list (for j,k)
my $history_index = undef;
@@ -106,6 +112,7 @@ 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
@@ -137,6 +144,9 @@ my $movements
'I' => { func => \&cmd_movement_I },
'a' => { func => \&cmd_movement_a },
'A' => { func => \&cmd_movement_A },
+ # paste
+ 'p' => { func => \&cmd_movement_p },
+ 'P' => { func => \&cmd_movement_P },
};
# special movements which take an additional key
@@ -154,10 +164,35 @@ sub cmd_operator_c {
cmd_operator_d($old_pos, $new_pos, $move);
_update_mode(M_INS);
}
-
sub cmd_operator_d {
my ($old_pos, $new_pos, $move) = @_;
+ my ($pos, $length) = _get_pos_and_length($old_pos, $new_pos, $move);
+
+ # Remove the selected string from the input.
+ my $input = _input();
+ substr $input, $pos, $length, '';
+ _input($input);
+
+ # Move the cursor at the right position.
+ _input_pos($pos);
+}
+sub cmd_operator_y {
+ my ($old_pos, $new_pos, $move) = @_;
+
+ my ($pos, $length) = _get_pos_and_length($old_pos, $new_pos, $move);
+
+ # Extract the selected string and put it in the " register.
+ my $input = _input();
+ my $string = substr $input, $pos, $length;
+ $registers->{'"'} = $string;
+ print "Yanked: $string" if DEBUG;
+
+ _input_pos($old_pos);
+}
+sub _get_pos_and_length {
+ my ($old_pos, $new_pos, $move) = @_;
+
my $length = $new_pos - $old_pos;
# We need a positive length and $old_pos must be smaller.
if ($length < 0) {
@@ -172,15 +207,10 @@ sub cmd_operator_d {
$length += 1;
}
- # Remove the selected string from the input.
- my $input = _input();
- substr $input, $old_pos, $length, '';
- _input($input);
-
- # Move the cursor at the right position.
- _input_pos($old_pos);
+ return ($old_pos, $length);
}
+
# later history (down)
sub cmd_movement_j {
my ($count, $pos) = @_;
@@ -368,6 +398,28 @@ sub cmd_movement_A {
_update_mode(M_INS);
}
+sub cmd_movement_p {
+ my ($count, $pos) = @_;
+ _paste_at_position($count, $pos + 1);
+}
+sub cmd_movement_P {
+ my ($count, $pos) = @_;
+ _paste_at_position($count, $pos);
+}
+sub _paste_at_position {
+ my ($count, $pos) = @_;
+
+ return if not $registers->{'"'};
+
+ my $string = $registers->{'"'} x $count;
+
+ my $input = _input();
+ substr($input, $pos, 0) = $string;
+ _input($input);
+
+ _input_pos($pos - 1 + length $string);
+}
+
sub cmd_ex_command {
my $arg_str = join '', @ex_buf;
if ($arg_str =~ m|s/(.+)/(.*)/([ig]*)|) {