aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/index.txt1
-rw-r--r--runtime/doc/motion.txt6
-rw-r--r--runtime/doc/quickref.txt1
-rw-r--r--runtime/doc/usr_25.txt9
-rw-r--r--src/nvim/normal.c16
-rw-r--r--src/nvim/testdir/test_normal.vim24
6 files changed, 52 insertions, 5 deletions
diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt
index be9e25113a..9fd68144bc 100644
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -767,6 +767,7 @@ tag char note action in Normal mode ~
|gn| gn 1,2 find the next match with the last used
search pattern and Visually select it
|gm| gm 1 go to character at middle of the screenline
+|gM| gM 1 go to character at middle of the text line
|go| go 1 cursor to byte N in the buffer
|gp| ["x]gp 2 put the text [from register x] after the
cursor N times, leave the cursor after it
diff --git a/runtime/doc/motion.txt b/runtime/doc/motion.txt
index 97c7d1cc43..9e24ee0320 100644
--- a/runtime/doc/motion.txt
+++ b/runtime/doc/motion.txt
@@ -219,6 +219,12 @@ g^ When lines wrap ('wrap' on): To the first non-blank
gm Like "g0", but half a screenwidth to the right (or as
much as possible).
+ *gM*
+gM Like "g0", but to halfway the text of the line.
+ With a count: to this percentage of text in the line.
+ Thus "10gM" is near the start of the text and "90gM"
+ is near the end of the text.
+
*g$* *g<End>*
g$ or g<End> When lines wrap ('wrap' on): To the last character of
the screen line and [count - 1] screen lines downward
diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt
index 87cb9b54f5..dfa7218bdf 100644
--- a/runtime/doc/quickref.txt
+++ b/runtime/doc/quickref.txt
@@ -47,6 +47,7 @@ N is used to indicate an optional count that can be given before the command.
|g$| N g$ to last character in screen line (differs from "$"
when lines wrap)
|gm| gm to middle of the screen line
+|gM| gM to middle of the line
|bar| N | to column N (default: 1)
|f| N f{char} to the Nth occurrence of {char} to the right
|F| N F{char} to the Nth occurrence of {char} to the left
diff --git a/runtime/doc/usr_25.txt b/runtime/doc/usr_25.txt
index 3a58af6412..2efb67e55f 100644
--- a/runtime/doc/usr_25.txt
+++ b/runtime/doc/usr_25.txt
@@ -346,12 +346,13 @@ scroll:
g0 to first visible character in this line
g^ to first non-blank visible character in this line
- gm to middle of this line
+ gm to middle of screen line
+ gM to middle of the text in this line
g$ to last visible character in this line
- |<-- window -->|
- some long text, part of which is visible ~
- g0 g^ gm g$
+ |<-- window -->|
+ some long text, part of which is visible in one line ~
+ g0 g^ gm gM g$
BREAKING AT WORDS *edit-no-break*
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index d1c6362931..2ef2c3101f 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -6749,6 +6749,22 @@ static void nv_g_cmd(cmdarg_T *cap)
curwin->w_set_curswant = true;
break;
+ case 'M':
+ {
+ const char_u *const ptr = get_cursor_line_ptr();
+
+ oap->motion_type = kMTCharWise;
+ oap->inclusive = false;
+ i = (int)mb_string2cells_len(ptr, STRLEN(ptr));
+ if (cap->count0 > 0 && cap->count0 <= 100) {
+ coladvance((colnr_T)(i * cap->count0 / 100));
+ } else {
+ coladvance((colnr_T)(i / 2));
+ }
+ curwin->w_set_curswant = true;
+ }
+ break;
+
case '_':
/* "g_": to the last non-blank character in the line or <count> lines
* downward. */
diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim
index 07d250cace..eab638d19a 100644
--- a/src/nvim/testdir/test_normal.vim
+++ b/src/nvim/testdir/test_normal.vim
@@ -1895,6 +1895,7 @@ fun! Test_normal33_g_cmd2()
set wrap listchars= sbr=
let lineA='abcdefghijklmnopqrstuvwxyz'
let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ let lineC='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
$put =lineA
$put =lineB
@@ -1928,9 +1929,30 @@ fun! Test_normal33_g_cmd2()
call assert_equal(15, col('.'))
call assert_equal('l', getreg(0))
+ norm! 2ggdd
+ $put =lineC
+
+ " Test for gM
+ norm! gMyl
+ call assert_equal(73, col('.'))
+ call assert_equal('0', getreg(0))
+ " Test for 20gM
+ norm! 20gMyl
+ call assert_equal(29, col('.'))
+ call assert_equal('S', getreg(0))
+ " Test for 60gM
+ norm! 60gMyl
+ call assert_equal(87, col('.'))
+ call assert_equal('E', getreg(0))
+
+ " Test for g Ctrl-G
+ set ff=unix
+ let a=execute(":norm! g\<c-g>")
+ call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
+
" Test for gI
norm! gIfoo
- call assert_equal(['', 'fooabcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
+ call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
" Test for gi
wincmd c