lyuts / vim-rtags

Vim bindings for rtags, llvm/clang based c++ code indexer.
BSD 2-Clause "Simplified" License
282 stars 56 forks source link

no function to jumpback #26

Open pangchol opened 8 years ago

pangchol commented 8 years ago

hi, I am test you plugin in my project with rtags, it running nice. but I find that there is no a way to jumpback . Although the vim's C-o can jump to the before editer point. but this no the simon-pure jumpback function for rtags. I see at Elisp api in rtags github project page. like this: (rtags-location-stack-back) (rtags-location-stack-forward) Whenever RTags jumps somewhere it pushes a location onto its stack. Jump back and forward in this stack this mean rtags can support jumps stack just like the vim's ctags stack (using with C-t). so I suggest to add a jumpback fucntion to using stack like the rtags-location-stack-back. I think this will be a very useful function to the vim-rtags user. best regards

lyuts commented 8 years ago

I don't see any jump back related functionality in rc. If i'm reading it correctly location stack is managed by emacs.

pangchol commented 8 years ago

er... it seem realy no jump back functionality in rc. but I realize a jumpback function yesterday. to get a stack to save the position before jump, I find another vim plugin specialized to realize a stack objection by using vim's list. this plugin can find by the link bleow:

https://github.com/dahu/vim-stack

here is my modiy to realize a simple jumpback funciton:

let s:JumpStack = Stack()

function! rtags#SaveLocaltion() normal! mZ call s:JumpStack.push(getpos("'Z")) endfunction

function! rtags#JumpBack() if s:JumpStack.empty() echohl ErrorMsg echo "At the bottom of rtags stack" echohl None else call setpos("'Z", s:JumpStack.pop()) normal! 'Z endif endfunction

function! rtags#JumpTo(...) let args = {} let args.f = rtags#getCurrentLocation() let results = rtags#ExecuteRC(args)

if len(results) >= 0 && a:0 > 0
    call rtags#cloneCurrentBuffer(a:1)
endif

if len(results) > 1
    call rtags#DisplayResults(results)
elseif len(results) == 1
    let [location; symbol_detail] = split(results[0], '\s\+')
    let [jump_file, lnum, col; rest] = split(location, ':')

    " Add location to the jumpstack
    call rtags#SaveLocaltion()
    call rtags#jumpToLocation(jump_file, lnum, col)
    normal zz
endif

endfunction

because I am not too good at vimscript, I am using the golbal mark to get the postion include buffer number. I think there is a better way to get postion include buffer number in vimscript maybe. I suggest you can re-implement the jumpback function by a good way and add it in you plugin. it realy a very importation function that give a convenient way to jump back to where we jump from.

mkwork commented 8 years ago

May be it'll be useful.

:help jumplist
....
You can explicitly add a jump by setting the ' mark with "m'".  Note 
that calling setpos() does not do this.
....
lyuts commented 8 years ago

Right now, once you jump to some location you can go back with <C-o> and if needed go forward with <C-i>. How someone's workflow will look like if we manage jump location in the pluing itself, by having JumpBack() function? If you need to jump back, should I use <C-o> or have a mapping that calls JumpBack()?

pangchol commented 8 years ago

of course, key mapping is needed.

lyuts commented 8 years ago

In my opinion having a custom mapping for jumping back which differs from <C-o> breaks vim workflow by having 2 different ways to jump back. But I can certainly add such function and mapping.

lyuts commented 8 years ago

Are you ok with this mapping:

noremap <Leader>rjb <C-o>

rajukv commented 8 years ago

If we have a feature similar to vim's ctags pop from tagstack(CTRL-T), that would be very nice. One good feature of that is that at any given level in the tag stack, we can visit all the matches and then press CTRL-T to go back to where we started.

lyuts commented 8 years ago

Didn't mean to close it.

lyuts commented 8 years ago

@rajukv , it doesn't look like tagstack is writable by anything other than vim. I'm not sure if it makes sense to reimplement tagstack on our own, as it technically a replica and not an integration with vim's feature.

rajukv commented 8 years ago

@lyuts : I agree that we would be replicating vim code. It is unfortunate that vim doesn't allow plugins to access the tag stack. When I have some time, I can see if this can be implemented.

lastorset commented 8 years ago

The \rjb mapping makes Vim by default pause for one second after typing \rj. (This is the timeout feature. In my personal configuration, with notimeout, it actually waits forever or until the next keypress.) A bit annoying.

I can easily :unmap \rjb in my .vimrc, but I wonder whether the change in commit d625002 really does anyone good? I must admit I have trouble understanding the feature request in this ticket, but I don't imagine merely adding a duplicate mapping for Ctrl+o helps much?

lyuts commented 8 years ago

@lastorset , I personally think Ctrl+o is the one that should be used as it naturally comes from Vim's workflow. However, it looks like some users are advocating for a dedicated mapping, and that's why it has been added. I guess it is a miss on my side to start a mapping with an overlapping \rj sequence that now causes problems. Couple of options are (a) wrap that mapping with a variable, so that users who really need it will have that mapping, or (b) change the mapping to some other sequence that will not lead to that freeze. Downside for (a) is that limits the issue to users who want that mapping, and downside for (b) is breaking someone's habbit (otoh, it has been introduced just about a month ago, so maybe not a problem). Do you have a suggestion on what should we map that to?

lastorset commented 8 years ago

Hm. Like I said I'm not sure I understand this ticket, but as far as I can tell @pangchol and @rajukv are requesting a separate stack. Without that stack the mapping seems meaningless; it's UI without an underlying feature. So I'd say just revert the addition of this mapping—and add a (different) mapping if/when you implement a separate stack.

It's true that reverting may confuse some users, but has there been feedback indicating the mapping is popular? Besides, like you say, it's a recent change. Also, adding map <Leader>rjb <C-o> to .vimrc is easy and reliable, while unmapping is slightly more difficult if you have a complex setup. (You need to ensure that the unmap happens after the map, for example using au VimEnter :unmap <Leader>rjb.)

lyuts commented 8 years ago

I totally got the request for a separate jumpstack, but aside from it, I got an impression that @pangchol wanted the mapping. Now that you question that I wonder if I got that wrong. So, I think I'd agree that we should revert that change for now, at least until we have clarity on the subject. If anyone needs it now, the suggestion would be to add mapping to their's vimrc.

lastorset commented 8 years ago

👍

yarray commented 8 years ago

Is there any progress now? When working with cscope/ctags, using ctrl-t to jump back is better than ctrl-o. After jumping to an callee, it is natural to navigate a bit within that function and then jump back, which may involves multiple ctrl-o but only requires one ctrl-t. Besides, I think it is better to be compatible with cscope/ctags for reusing muscle memory :)

For implementation, I recently saw an interesting method: https://github.com/LucHermitte/lh-tags/blob/a681f0c1b6fd85ccc0c2bc55a0abcfe347e0be61/autoload/lh/tags.vim (line 330-349), where the author:

  1. creates a temp tags file and add it to "tags"
  2. when jumping, manually adds a tag with a generated name and the line number
  3. push the generated name into tagstack

As these have been done, ctrl-t will automatically work without other tweaks. It differs from the original ctrl-t with a pro and a con:

+ when jumping back, it will go to exactly where we jumped (I think it is even better than jumping back to the last jumped tag)

Unfortunately I am not familiar so may not be able to provide direct help... The plugin is fantastic and greatly releases the pain to investigate complex C++ projects. Hope it'd be improved to be a complete replacement of cscope/ctags for C/C++.

pdavydov108 commented 8 years ago

I've created a pull request with a simple jump back function implementation, mapped to <leader>rb. Can you please provide some feedback about it? Does it work for you, are you ok with mapping? Please see pull request #34.

lyuts commented 8 years ago

@yarray , I like the referenced way of accomplishing it. However, due to time constraint, I'm tempted to go with an implementation that @pdavydov108 is proposing. In the short term it allows us to have desired functionality. In the long term, I'd like to implement the method you mentioned as it stays within vim's "way of doing thing". Though it seems to me we want to make it as a separate plugin as I don't want to mix rtags related functionality with managing jump stacks within one plugin.

yarray commented 8 years ago

@pdavydov108 The implementation seems great! I will test it in detail later.

@lyuts A separate plugin seems reasonable, since the referenced method is a bit hacky and surely introduces extra complexity. The ideal vim way may only exists when vim (or neovim) itself exposes tagstack APIs, as your previous comments suggest. For me, the current implementation is good enough without noticeable harm to the simplicity.

pdavydov108 commented 8 years ago

One issue with my approach is that I haven't yet found a way how to implement it for the case when jump to other location is done from location list. For example if I execute <leader>rf, it shows me a list of all locations were symbol is used, then if I choose one of them, this new location is opened, but if I want to go to previous one with the new function, <leader>rb, I can't. I thought that maybe <leader>rb can fall back to ctrl-o in case if there are no elements in stack, but I'm not sure if it is convinient and clear.. Another issue is that if jump stack already have some locations from previous jumps, and I want to return from a jump from location list, <leader>rb will take me to some other previous location, which is not what I expect (however I think that even vim's native ctrl-t feature have this issue). One way to fix this issues is to set a callback on buffer open event, and check if it's name is in current location list, and if so, save previous location to a stack. This approach looks quite complex to me, it would be cool to find an easier way to do it. Please let me know if you have any ideas how to overcome this issues.

mckellyln commented 6 years ago

Having \rb or ctrl-t go back to where I was before I jumped to a location from a list would be awesome, because as said above there is often some navigation and ctrl-o includes all of those.

mckellyln commented 6 years ago

update - I have some "execute normal .." keybindings in my .vimrc that I didn't realize appended to the jumplist. I have added keepjumps to those and now I would say ctrl-o/i works much better for me. I am thinking of something like this in my rtags.vim -

function! rtags#JumpBack()
    if len(g:rtagsJumpStack) > 0
        let [jump_file, lnum, col] = remove(g:rtagsJumpStack, -1)
        call rtags#jumpToLocationInternal(jump_file, lnum, col)
    else
        " echo "rtags: jump stack is empty"
        execute "normal" "\<C-o>"
    endif
endfunction