8

My vim plugin has a command to jump to a different location (just like tags).

I use the cursor function for that.

How do I record the previous location in the jumplist, so that Ctrl+O works as expected?

Roman Cheplyaka
  • 37,738
  • 7
  • 72
  • 121

3 Answers3

13

I myself also wanted to this, and what works for me was mark ` before cursor move.

normal! m`
call cursor(l, c)

As help indicate, both setpos() and cursor() don't modify jumplist, so what's the difference of setpos() and cursor(), strange!

t9md
  • 156
  • 3
  • 1
    This is the correct to the question. I knew m' stored the previous location, but didn't know it was also added to the jump list. Good to know. – Robert Webb Feb 20 '20 at 13:03
5

:help cursor() can't be clearer:

[…]
Does not change the jumplist.
[…]

(EDIT)

This means that cursor() jumps are not recorded in the jumplist and therefore, that cursor() is an inappropriate tool, here.

(ENDEDIT)

As an alternative, you could use something like

execute "normal " . target_line . "G" . target_col . "|"

which is perfectly compatible with <C-o> and <C-i> and just as idiomatic as

call cursor(target_line,target_col)

even if it gives the chills to JavaScripters ;-)

romainl
  • 186,200
  • 21
  • 280
  • 313
  • 2
    It's clear indeed, but it doesn't answer my question. I didn't ask how *not* to change the jumplist! Regarding your second suggestion, I'll keep it in mind, although I'd prefer a proper API call. – Roman Cheplyaka Oct 05 '13 at 08:54
  • You are simply using the wrong tool for the job: `cursor()` *never* changes the jumplist (as clearly stated in `:help cursor()`) and can't be forced to do so. Your problem is "jumping to a pair of coordinates in the buffer while having this jump recorded in the jumplist" but `cursor()` jumps *are not* added to the jumplist. If you want your motions to be recorded in the jumplist, use the right commands. My proposal positions the cursor just like `cursor()` but the jump is added to the jumplist. Win! – romainl Oct 05 '13 at 09:09
  • @RomanCheplyaka You have a too narrow view; the `:normal` command as given by romainl _is_ a proper API call. – Ingo Karkat Oct 05 '13 at 10:34
  • 1
    It doesn't make `cursor` a wrong tool for the job. It does half of the job, after all. I would simply expect there to be another function that would allow me to add to the jumplist. That would be a good API design, in my opinion. If there's no such function, then yes, I'll have to use `:normal`. – Roman Cheplyaka Oct 05 '13 at 11:14
  • 1
    cursor() is the wrong tool because it doesn't do what you want so you must find a better tool and :normal is that tool. Don't waste your time looking for a screwdriver adapted to that nail... take the hammer ;-) – romainl Oct 05 '13 at 14:10
  • 1
    The OP did not ask how to make cursor() behave differently, they asked how to force-record the previous location, and this answer didn't answer the question. This is a useful thing to do, and why my Google search got me here even though "cursor()" wasn't part of my search. Using more readable code, even for vim experts, is also not such a bad thing. – Robert Webb Feb 20 '20 at 13:07
2

Simply mark that position before moving your cursor by setting the ' mark. This could be done by either using the normal mode m command, or even a call to setpos(), e.g. call setpos("''", getpos(".")) would add the current cursor position to the jump list.

Christian Brabandt
  • 8,038
  • 1
  • 28
  • 32
  • I don't think `setpos` works that way (it's documentation explicitly says that it doesn't change the jumplist, and my experiments confirm that). – Roman Cheplyaka Oct 05 '13 at 13:52
  • What is meant with _setpos doesn't change the jumplist_ is if you use setpos() to set the cursor position, it won't be added to the jumplist. You can however successfully set the **'** mark, as is suggested by the help for `:h jump-list` and that position will be added to the jump-list (and it certainly does for me as tested with vim -u NONE -N -i NONE). – Christian Brabandt Oct 06 '13 at 12:17
  • So here's what I do: 1. Launch vim with `vim -u NONE -N -i NONE SOMEFILE`; 2. Go somewhere in the file and execute `:call setpos("''", getpos("."))`; 3. Execute `:jumps` and don't see the current position being there. 4. Go somewhere else in the file, press Ctrl+O, and vim throws me to the beginning of the file, and not to the previous location. Am I doing something wrong? – Roman Cheplyaka Oct 06 '13 at 15:09
  • 1
    Hm, now that I retry it one more time, it doesn't seem to work using `setpos("''", getpos('.'))`, I wonder what I did wrong this time... You can however still set the mark using the normal mode `m` command or even the `:k '` ex command. This successfully adds the current position to the jumplist. – Christian Brabandt Oct 08 '13 at 05:45