ycm-core / YouCompleteMe

A code-completion engine for Vim
http://ycm-core.github.io/YouCompleteMe/
GNU General Public License v3.0
25.44k stars 2.81k forks source link

Is the any way to let YCM use tag stack in vim #1675

Closed gngshn closed 9 years ago

gngshn commented 9 years ago

The tag stack is the thing which can be seem by :tags in vim normal mode.

When I use YCM to view some codes, then I have some jump (GoTo cmd) like this a.c:1 ->b.c:1->c.c:1 <-b.c:1 b.c:2->c.c:2->d.c:1

'a.c:1' meas in file a.c position 1 '->' means goto, '<-' means go back by Now, if I want to go back to a.c:1, I can use , it backtracks a long path. The ctags or cscope use tag stack, then it can go back by then it jumps like d.c:1->c.c:2->b.c:2->a.c:1 It's very useful when viewing the code

Maybe It's hard to use the tag stack, because it seemed that the tag stack is owned by vim. If it's like that, that was very regrettable

puremourning commented 9 years ago

Sorry for the lack of answer. I think the short answer is no, there isn't at the moment. I believe that the jump list is updated though. I suspect the tag stack is a vim built-in feature that we can't influence.

Valloric commented 9 years ago

Agreed with @puremourning, I don't think we can do this.

choco commented 7 years ago

Hi, I noticed that Jedi-vim provides this functionality with a slight hack https://github.com/davidhalter/jedi-vim/blob/0844b14866beea3308d615a4d3206a836fee106f/jedi_vim.py#L262 by basically:

Porting the same mechanism to JumpToLocation is pretty easy, but Ycm doesn't seem to provide a way to obtain the tag name or am I wrong? Anyway I think this would be worth implementing, this "hack" in my testing works a lot better than the current jumplist implementation.

gngshn commented 7 years ago

I use vim-kangroo to simulate tags. an simple and nice plugin

choco commented 7 years ago

@gngshn

I use vim-kangroo to simulate tags. an simple and nice plugin

That's cool, thank you for the suggestion.

Right now I'm using this hacky patch ported from jedi-vim codebase


diff --git a/python/ycm/vimsupport.py b/python/ycm/vimsupport.py
index adb8505..cb2581c 100644
--- a/python/ycm/vimsupport.py
+++ b/python/ycm/vimsupport.py
@@ -408,44 +408,32 @@ def GetVimCommand( user_command, default = 'edit' ):

 # Both |line| and |column| need to be 1-based
 def JumpToLocation( filename, line, column ):
-  # Add an entry to the jumplist
-  vim.command( "normal! m'" )
+  # Using this instead of the tempfile module because Windows won't read
+  # from a file not yet written to disk
+  tmp_filename = vim.eval('tempname()')
+  # YCM doesn't retun the identifier on which it inferred the GoTo location
+  # so we guess that is the current word under the cursor
+  tagname = vim.eval( 'expand("<cword>")' )
+  content = '{0}\t{1}\t{2}'.format(tagname,
+      filename,
+      'call cursor({0}, {1})'.format(line, column))

-  if filename != GetCurrentBufferFilepath():
-    # We prefix the command with 'keepjumps' so that opening the file is not
-    # recorded in the jumplist. So when we open the file and move the cursor to
-    # a location in it, the user can use CTRL-O to jump back to the original
-    # location, not to the start of the newly opened file.
-    # Sadly this fails on random occasions and the undesired jump remains in the
-    # jumplist.
-    user_command = user_options_store.Value( 'goto_buffer_command' )
-
-    if user_command == 'new-or-existing-tab':
-      if TryJumpLocationInOpenedTab( filename, line, column ):
-        return
-      user_command = 'new-tab'
-
-    vim_command = GetVimCommand( user_command )
-    try:
-      vim.command( 'keepjumps {0} {1}'.format( vim_command,
-                                               EscapedFilepath( filename ) ) )
-    # When the file we are trying to jump to has a swap file
-    # Vim opens swap-exists-choices dialog and throws vim.error with E325 error,
-    # or KeyboardInterrupt after user selects one of the options.
-    except vim.error as e:
-      if 'E325' not in str( e ):
-        raise
-      # Do nothing if the target file is still not opened (user chose (Q)uit)
-      if filename != GetCurrentBufferFilepath():
-        return
-    # Thrown when user chooses (A)bort in .swp message box
-    except KeyboardInterrupt:
-      return
-  vim.current.window.cursor = ( line, column - 1 )
-
-  # Center the screen on the jumped-to location
-  vim.command( 'normal! zz' )
+  # write location to temporary tagfile
+  with open(tmp_filename, 'w') as f:
+    f.write(content)

+  # add temp tagfile, jump to our tag, restore tags file and delete temp file
+  old_tags = GetVariableValue('&tags')
+  old_wildignore = GetVariableValue('&wildignore')
+  try:
+    # Clear wildignore to ensure tag file isn't ignored
+    SetVariableValue('&wildignore', '')
+    SetVariableValue('&tags', tmp_filename)
+    vim.command('tjump %s' % tagname)
+  finally:
+    SetVariableValue('&tags', old_tags)
+    SetVariableValue('&wildignore', old_wildignore)
+  os.unlink(tmp_filename)

 def NumLinesInBuffer( buffer_object ):
   # This is actually less than obvious, that's why it's wrapped in a function
`