Vim Tips Wiki
Register
(→‎Comments: sign properly)
(→‎Comments: Reply.)
 
(10 intermediate revisions by 5 users not shown)
Line 1: Line 1:
  +
{{TipNew
'''<tt>gm</tt>''' would usually go to the middle of the screen.
 
  +
|id=1671
  +
|previous=1670
  +
|next=1672
  +
|created=March 15, 2011
  +
|complexity=basic
  +
|author=Kurkale6ka
  +
|version=7.0
  +
|subpage=/201103
  +
|category1=Moving
  +
|category2=
  +
}}
  +
In normal mode, typing <code>gm</code> moves the cursor to the middle of the current ''screen'' line. With <code>'wrap'</code> on, a long line may be wrapped so it appears on several screen lines. Typing <code>gm</code> moves the cursor to the middle of the current line on the screen (or to the end of the line, if it ends before the middle of the screen).
   
'''<tt>gm</tt>''' using '''<tt><sid>Gm()</tt>''' will go to the middle of the text comprised between the first and the last
+
This tips remaps <code>gm</code> so the cursor is moved to the middle of the current physical line. Any leading or trailing whitespace is ignored: the cursor moves to the middle of the text between the first and last non-whitespace characters.
non white space characters.
 
 
==gm redefined==
 
   
  +
==Code==
 
<pre>
 
<pre>
 
function! s:Gm()
 
function! s:Gm()
 
execute 'normal! ^'
 
 
let first_col = virtcol('.')
execute 'normal! ^'
 
  +
execute 'normal! g_'
 
let first_col = virtcol('.')
+
let last_col = virtcol('.')
 
execute 'normal! ' . (first_col + last_col) / 2 . '|'
 
call search('[^[:space:]]\ze[[:space:]]*$', 'c', line('.'))
 
 
let last_col = virtcol('.')
 
 
execute 'normal! ' . (first_col + last_col) / 2 . '|'
 
 
 
endfunction
 
endfunction
  +
nnoremap <silent> gm :call <SID>Gm()<CR>
 
noremap <silent> gm :call <sid>Gm()<cr>
+
onoremap <silent> gm :call <SID>Gm()<CR>
 
</pre>
 
</pre>
   
Line 28: Line 32:
   
 
==Comments==
 
==Comments==
  +
I have removed the following from the tip because I can't make it do anything useful. If an explanation or fix is available, please restore it.
The only tip we have that mentions <tt>gm</tt> is [[Accelerated motion]]. The idea in this script is probably worth keeping in a tip somewhere, although I'm not sure that it warrants a separate tip (the problem with having a separate tip for every neat idea is the maintenance factor, and the complexity for readers). We'll discuss that in due course. Meanwhile, the search() should be {{tt|search('\S\ze\s*$', 'c', line('.'))}}. However, the normal-mode command <tt>g_</tt> does the job, so no search is needed. [[User:JohnBeckett|JohnBeckett]] 06:32, March 16, 2011 (UTC)
 
  +
<pre>
 
  +
onoremap <silent> gm :call <SID>Gm()<CR>
----
 
  +
" xmap <silent> gm :call <SID>Gm()<CR>
 
  +
</pre>
Hi,
 
 
[[User:JohnBeckett|JohnBeckett]] 08:22, March 31, 2012 (UTC)
 
  +
:: onoremap makes sense, xmap doesn't work, because visual mode is exited. One could possibly get around it by using an <expr> mapping.[[User:Chrisbra|Chrisbra]] ([[User talk:Chrisbra|talk]]) 09:53, July 1, 2013 (UTC)
I had missed the subtle distinction between <tt>'''$'''</tt> and <tt>'''g_'''</tt> but you're absolutely right.
 
  +
:::Thanks, but I think I meant that we should give an example of where the onoremap does something useful. For example, I just tried it again with a long line that was wrapped over several screen lines. Typing gm went to the middle of the physical line, but going back to the same starting position and typing vgm does ''not'' select the text that the first command moved over. Instead, the gm goes to the middle of the screen line. [[User:JohnBeckett|JohnBeckett]] ([[User talk:JohnBeckett|talk]]) 11:09, July 2, 2013 (UTC)
I still disagree however on the <tt>'''\S'''</tt>, <tt>'''[^[:space:]]'''</tt> stuff :)
 
 
Yes, I am aware it is a very short tip but I thought it was quite useful and I wanted to share it...
 
dunno where we should put it
 
 
Ta
 
 
----
 
 
This is cute. Does it work in operator pending and visual modes, too?
 
 
I worry that it completely changes the meaning of the command when 'wrap' is on. To me, 'gm' is mostly meant for this case (although I don't know of any alternate command for the 'nowrap' case). This should at least be mentioned. Or we could fix it by using :normal! g$ and a backwards search for a non-blank character (rather than g_).
 
 
For now, unless we find a good merge candidate, I think it should remain its own tip. It's not quite as complicated as our [[Remap join to merge comment lines]] tip but along the same vein&ndash;remapping a specific built-in command to perform a related or enhanced function.
 
 
--[[User:Fritzophrenic|Fritzophrenic]] 14:38, March 16, 2011 (UTC)
 

Latest revision as of 11:09, 2 July 2013

Tip 1671 Printable Monobook Previous Next

created March 15, 2011 · complexity basic · author Kurkale6ka · version 7.0


In normal mode, typing gm moves the cursor to the middle of the current screen line. With 'wrap' on, a long line may be wrapped so it appears on several screen lines. Typing gm moves the cursor to the middle of the current line on the screen (or to the end of the line, if it ends before the middle of the screen).

This tips remaps gm so the cursor is moved to the middle of the current physical line. Any leading or trailing whitespace is ignored: the cursor moves to the middle of the text between the first and last non-whitespace characters.

Code[]

function! s:Gm()
  execute 'normal! ^'
  let first_col = virtcol('.')
  execute 'normal! g_'
  let last_col  = virtcol('.')
  execute 'normal! ' . (first_col + last_col) / 2 . '|'
endfunction
nnoremap <silent> gm :call <SID>Gm()<CR>
onoremap <silent> gm :call <SID>Gm()<CR>

References[]

Comments[]

I have removed the following from the tip because I can't make it do anything useful. If an explanation or fix is available, please restore it.

onoremap <silent> gm :call <SID>Gm()<CR>
" xmap <silent> gm :call <SID>Gm()<CR>

JohnBeckett 08:22, March 31, 2012 (UTC)

onoremap makes sense, xmap doesn't work, because visual mode is exited. One could possibly get around it by using an <expr> mapping.Chrisbra (talk) 09:53, July 1, 2013 (UTC)
Thanks, but I think I meant that we should give an example of where the onoremap does something useful. For example, I just tried it again with a long line that was wrapped over several screen lines. Typing gm went to the middle of the physical line, but going back to the same starting position and typing vgm does not select the text that the first command moved over. Instead, the gm goes to the middle of the screen line. JohnBeckett (talk) 11:09, July 2, 2013 (UTC)