aboutsummaryrefslogtreecommitdiffstats
path: root/vim-mode/vim_mode.pl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--vim-mode/vim_mode.pl35
1 files changed, 31 insertions, 4 deletions
diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl
index 847ce6e..cf04f35 100644
--- a/vim-mode/vim_mode.pl
+++ b/vim-mode/vim_mode.pl
@@ -397,7 +397,7 @@ sub cmd_movement_l {
my $length = _input_len();
$pos += $count;
- $pos = $length - 1 if $pos > $length - 1;
+ $pos = _fix_input_pos($pos, $length);
_input_pos($pos);
}
sub cmd_movement_space {
@@ -525,6 +525,7 @@ sub cmd_movement_w {
}
}
+ $pos = _fix_input_pos($pos, length $input);
_input_pos($pos);
}
sub cmd_movement_b {
@@ -542,7 +543,9 @@ sub cmd_movement_b {
sub cmd_movement_e {
my ($count, $pos, $repeat) = @_;
- $pos = _end_of_word(_input(), $count, $pos);
+ my $input = _input();
+ $pos = _end_of_word($input, $count, $pos);
+ $pos = _fix_input_pos($pos, length $input);
_input_pos($pos);
}
# Go to the end of $count-th word, like vi's e.
@@ -574,6 +577,11 @@ sub _end_of_word {
}
}
+ # Necessary for correct deletion at the end of the line.
+ if (length $input == $pos + 1) {
+ $pos++;
+ }
+
return $pos;
}
sub cmd_movement_W {
@@ -586,6 +594,7 @@ sub cmd_movement_W {
}
$pos += $+[0] + 1;
}
+ $pos = _fix_input_pos($pos, length $input);
_input_pos($pos);
}
sub cmd_movement_B {
@@ -644,12 +653,14 @@ sub cmd_movement_caret {
$pos = $-[0];
# Only whitespace, go to the end.
} else {
- $pos = _input_len();
+ $pos = _fix_input_pos(_input_len(), length $input);
}
_input_pos($pos);
}
sub cmd_movement_dollar {
- _input_pos(_input_len() - 1);
+ my $input = _input();
+ my $length = length $input;
+ _input_pos(_fix_input_pos($length, $length));
}
sub cmd_movement_x {
@@ -790,6 +801,22 @@ sub cmd_movement_register {
print "Changing register to $register" if DEBUG;
}
+# Adapt the input position depending if an operator is active or not.
+sub _fix_input_pos {
+ my ($pos, $length) = @_;
+
+ # Allow moving past the last character when an operator is active to allow
+ # correct handling of last character in line.
+ if ($operator) {
+ $pos = $length if $pos > $length;
+ # Otherwise forbid it.
+ } else {
+ $pos = $length - 1 if $pos > $length - 1;
+ }
+
+ return $pos;
+}
+
sub cmd_ex_command {
my $arg_str = join '', @ex_buf;
if ($arg_str =~ m|^s/(.+)/(.*)/([ig]*)|) {