Thursday, January 23, 2014

Re: Avoid switching files with ctrl-o

On Thu, January 23, 2014 02:05, Paul wrote:
> On Wednesday, January 22, 2014 8:00:09 PM UTC-5, Gary Johnson wrote:
>>On 2014-01-22, Paul wrote:
>>> I like navigating through old cursor positions with ctrl-o and
>>> ctrl-i. However, I don't necessarily like the way it switches
>>> files sometimes. I end up writing the current file before
>>> switching files, and when I go back to the original file, Undo no
>>> longer works. Is there a way to prevent ctrl-o from switching
>>> files? How about preventing this only when ctrl-o is invoked from
>>> a macro such as one defined using one of the :map variations?
>>
>> It sounds like the problem may not be that Ctrl-O switches files but
>> that switching files loses your undo history. If that's the case,
>> then see
>>
>> :help undo-persistence
>
> Actually, I want to avoid switching files as well. That's the main
> problem for me, the undo is just icing on the problem. Is that possible
> (avoiding the file switch, preferrably selectively, such as in a macro)?

In that case, you need to write your own map function. Unfortunately,
it is not really easy, since there is no viml function for querying the
jump list (I think, I still have some vim patches flying around, to
add a changelist() and jumplist() function) besides parsing the output
of :jumps.

I have actually also recently just thought about adding a
g<C-O>/g<C-I> command to Vim, that would jump by file steps which
means there would be a built-in way to do what you want.

Here is a first working copy. Put the script below into a file into
your ~/.vim/plugin/ directory:

--------------- start here ---------------
let s:escape = "\<esc>"

fu! <sid>UpdIdx(idx, fwd)
return a:fwd ? a:idx-1 : a:idx+1
endfu

fu! <sid>JumpInFile(forward)
redir => a |exe ":sil jumps"|redir end
let b = split(a, '\n')[1:]
let idx = match(b, '^>.*')
if idx == -1
return s:escape
endif
let idx = <sid>UpdIdx(idx, a:forward)
let i = 0
while get(b, idx, -1) != -1
let entry = matchlist(get(b, idx),
\ '^\s*\(\d\+\)\s\+\(\d\+\)\s\+\(\d\+\)'.
\ '\s\+\(.*\)')
if empty(entry)
return s:escape
endif
if !empty(entry[4])
let line = matchstr(getline(entry[2]+0), '^\s*\zs.\{'.
\ strdisplaywidth(entry[4]).'}')
else
let line = getline(entry[2]+0)
endif
if line ==# entry[4]
let idx = <sid>UpdIdx(idx, a:forward)
continue
else
if a:forward && entry[1] > 1
return (entry[1]-1) . "\<C-O>"
elseif !a:forward && entry[1] > 1
return (entry[1]-1) . "\<C-I>"
else
return s:escape
endif
endw
return s:escape
endfu

nnoremap <expr> g<C-O> <sid>JumpInFile(1)
nnoremap <expr> g<C-I> <sid>JumpInFile(0)
--------------- end here ---------------

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

No comments:

Post a Comment