From 5e7e1f4b9cdfbf47ec4a3ad48c6e56bb560dbfc7 Mon Sep 17 00:00:00 2001
From: Ben Jackson <puremourning@gmail.com>
Date: Tue, 17 Jan 2023 12:49:53 +0000
Subject: [PATCH] Don't change the cursor position if GoTo doesnt have one

This fixes the behavour of GoToAlternate file to keep the buffer's
cursor position.
---
 python/ycm/client/command_request.py |   6 ++
 python/ycm/tests/vimsupport_test.py  | 118 +++++++++++++++++++++++++++
 python/ycm/vimsupport.py             |  22 ++---
 3 files changed, 136 insertions(+), 10 deletions(-)

diff --git a/python/ycm/client/command_request.py b/python/ycm/client/command_request.py
index 565bf80c..508a2dda 100644
--- a/python/ycm/client/command_request.py
+++ b/python/ycm/client/command_request.py
@@ -138,6 +138,12 @@ class CommandRequest( BaseRequest ):
       vimsupport.SetQuickFixList(
         [ vimsupport.BuildQfListItem( x ) for x in self._response ] )
       vimsupport.OpenQuickFixList( focus = True, autoclose = True )
+    elif self._response.get( 'file_only' ):
+      vimsupport.JumpToLocation( self._response[ 'filepath' ],
+                                 None,
+                                 None,
+                                 modifiers,
+                                 buffer_command )
     else:
       vimsupport.JumpToLocation( self._response[ 'filepath' ],
                                  self._response[ 'line_num' ],
diff --git a/python/ycm/tests/vimsupport_test.py b/python/ycm/tests/vimsupport_test.py
index 24c0cfc8..4b934091 100644
--- a/python/ycm/tests/vimsupport_test.py
+++ b/python/ycm/tests/vimsupport_test.py
@@ -1728,6 +1728,124 @@ class VimsupportTest( TestCase ):
       ] )
 
 
+  @patch( 'vim.command', new_callable = ExtendedMock )
+  def test_JumpToLocation_SameFile_NoLineCol( self, vim_command ):
+    current_buffer = VimBuffer( 'uni¢𐍈d€' )
+    with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+      vim.current.window.cursor = ( 99, 99 )
+
+      target_name = os.path.realpath( 'uni¢𐍈d€' )
+      vimsupport.JumpToLocation( target_name,
+                                 None,
+                                 None,
+                                 'belowright',
+                                 'same-buffer' )
+
+      assert_that( vim.current.window.cursor, equal_to( ( 99, 99 ) ) )
+      vim_command.assert_has_exact_calls( [
+        call( 'normal! m\'' ),
+      ] )
+
+
+  @patch( 'vim.command', new_callable = ExtendedMock )
+  def test_JumpToLocation_SameFile_NoLine( self, vim_command ):
+    current_buffer = VimBuffer( 'uni¢𐍈d€' )
+    with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+      vim.current.window.cursor = ( 99, 99 )
+
+      target_name = os.path.realpath( 'uni¢𐍈d€' )
+      vimsupport.JumpToLocation( target_name,
+                                 None,
+                                 1,
+                                 'belowright',
+                                 'same-buffer' )
+
+      assert_that( vim.current.window.cursor, equal_to( ( 99, 99 ) ) )
+      vim_command.assert_has_exact_calls( [
+        call( 'normal! m\'' ),
+      ] )
+
+
+  @patch( 'vim.command', new_callable = ExtendedMock )
+  def test_JumpToLocation_SameFile_NoCol( self, vim_command ):
+    current_buffer = VimBuffer( 'uni¢𐍈d€' )
+    with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+      vim.current.window.cursor = ( 99, 99 )
+
+      target_name = os.path.realpath( 'uni¢𐍈d€' )
+      vimsupport.JumpToLocation( target_name,
+                                 1,
+                                 None,
+                                 'belowright',
+                                 'same-buffer' )
+
+      assert_that( vim.current.window.cursor, equal_to( ( 99, 99 ) ) )
+      vim_command.assert_has_exact_calls( [
+        call( 'normal! m\'' ),
+      ] )
+
+
+  @patch( 'vim.command', new_callable = ExtendedMock )
+  def test_JumpToLocation_DifferentFile_NoLineCol( self, vim_command ):
+    current_buffer = VimBuffer( 'uni¢𐍈d€' )
+    with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+      vim.current.window.cursor = ( 99, 99 )
+
+      target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+      vimsupport.JumpToLocation( target_name,
+                                 None,
+                                 None,
+                                 'belowright',
+                                 'same-buffer' )
+
+      assert_that( vim.current.window.cursor, equal_to( ( 99, 99 ) ) )
+      vim_command.assert_has_exact_calls( [
+        call( 'normal! m\'' ),
+        call( f'keepjumps belowright edit { target_name }' ),
+      ] )
+
+
+  @patch( 'vim.command', new_callable = ExtendedMock )
+  def test_JumpToLocation_DifferentFile_NoLine( self, vim_command ):
+    current_buffer = VimBuffer( 'uni¢𐍈d€' )
+    with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+      vim.current.window.cursor = ( 99, 99 )
+
+      target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+      vimsupport.JumpToLocation( target_name,
+                                 None,
+                                 1,
+                                 'belowright',
+                                 'same-buffer' )
+
+      assert_that( vim.current.window.cursor, equal_to( ( 99, 99 ) ) )
+      vim_command.assert_has_exact_calls( [
+        call( 'normal! m\'' ),
+        call( f'keepjumps belowright edit { target_name }' ),
+      ] )
+
+
+  @patch( 'vim.command', new_callable = ExtendedMock )
+  def test_JumpToLocation_DifferentFile_NoCol( self, vim_command ):
+    current_buffer = VimBuffer( 'uni¢𐍈d€' )
+    with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+      vim.current.window.cursor = ( 99, 99 )
+
+      target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+      vimsupport.JumpToLocation( target_name,
+                                 1,
+                                 None,
+                                 'belowright',
+                                 'same-buffer' )
+
+      assert_that( vim.current.window.cursor, equal_to( ( 99, 99 ) ) )
+      vim_command.assert_has_exact_calls( [
+        call( 'normal! m\'' ),
+        call( f'keepjumps belowright edit { target_name }' ),
+      ] )
+
+
+
   @patch( 'vim.command', new_callable = ExtendedMock )
   def test_JumpToLocation_DifferentFile_SameBuffer_Modified_CannotHide(
       self, vim_command ):
diff --git a/python/ycm/vimsupport.py b/python/ycm/vimsupport.py
index 56de1aa8..d93a6886 100644
--- a/python/ycm/vimsupport.py
+++ b/python/ycm/vimsupport.py
@@ -631,12 +631,13 @@ def TryJumpLocationInTab( tab, filename, line, column ):
     if ComparePaths( GetBufferFilepath( win.buffer ), filename ):
       vim.current.tabpage = tab
       vim.current.window = win
-      vim.current.window.cursor = ( line, column - 1 )
+      if line is not None and column is not None:
+        vim.current.window.cursor = ( line, column - 1 )
+        # Open possible folding at location
+        vim.command( 'normal! zv' )
+        # Center the screen on the jumped-to location
+        vim.command( 'normal! zz' )
 
-      # Open possible folding at location
-      vim.command( 'normal! zv' )
-      # Center the screen on the jumped-to location
-      vim.command( 'normal! zz' )
       return True
   # 'filename' is not opened in this tab page
   return False
@@ -710,12 +711,13 @@ def JumpToLocation( filename, line, column, modifiers, command ):
     if not JumpToFile( filename, command, modifiers ):
       return
 
-  vim.current.window.cursor = ( line, column - 1 )
+  if line is not None and column is not None:
+    vim.current.window.cursor = ( line, column - 1 )
 
-  # Open possible folding at location
-  vim.command( 'normal! zv' )
-  # Center the screen on the jumped-to location
-  vim.command( 'normal! zz' )
+    # Open possible folding at location
+    vim.command( 'normal! zv' )
+    # Center the screen on the jumped-to location
+    vim.command( 'normal! zz' )
 
 
 def NumLinesInBuffer( buffer_object ):
-- 
2.39.1

