Ignore case when comparing paths on Windows and macOS

This commit is contained in:
micbou 2019-05-04 05:57:44 +02:00
parent d691404ae2
commit 5e3dd1d9b8
No known key found for this signature in database
GPG Key ID: C7E8FD1F3BDA1E05
3 changed files with 79 additions and 14 deletions

View File

@ -34,7 +34,12 @@ import os
import re import re
import sys import sys
from ycmd.utils import GetCurrentDirectory, ToBytes, ToUnicode try:
from unittest import skipIf
except ImportError:
from unittest2 import skipIf
from ycmd.utils import GetCurrentDirectory, OnMac, OnWindows, ToBytes, ToUnicode
BUFNR_REGEX = re.compile( '^bufnr\\(\'(?P<buffer_filename>.+)\', ([01])\\)$' ) BUFNR_REGEX = re.compile( '^bufnr\\(\'(?P<buffer_filename>.+)\', ([01])\\)$' )
@ -102,6 +107,9 @@ REDIR = {
'output': '' 'output': ''
} }
WindowsAndMacOnly = skipIf( not OnWindows() or not OnMac(),
'Windows and macOS only' )
@contextlib.contextmanager @contextlib.contextmanager
def CurrentWorkingDirectory( path ): def CurrentWorkingDirectory( path ):
@ -293,7 +301,7 @@ def _MockVimEval( value ):
if value == REDIR[ 'variable' ]: if value == REDIR[ 'variable' ]:
return REDIR[ 'output' ] return REDIR[ 'output' ]
raise VimError( 'Unexpected evaluation: {0}'.format( value ) ) raise VimError( 'Unexpected evaluation: {}'.format( value ) )
def _MockWipeoutBuffer( buffer_number ): def _MockWipeoutBuffer( buffer_number ):
@ -444,6 +452,11 @@ class VimBuffer( object ):
raise ValueError( 'Unexpected mark: {name}'.format( name = name ) ) raise ValueError( 'Unexpected mark: {name}'.format( name = name ) )
def __repr__( self ):
return "VimBuffer( name = '{}', number = {} )".format( self.name,
self.number )
class VimBuffers( object ): class VimBuffers( object ):
"""An object that looks like a vim.buffers object.""" """An object that looks like a vim.buffers object."""
@ -483,6 +496,13 @@ class VimWindow( object ):
self.options = {} self.options = {}
def __repr__( self ):
return "VimWindow( number = {}, buffer = {}, cursor = {} )".format(
self.number,
self.buffer,
self.cursor )
class VimWindows( object ): class VimWindows( object ):
"""An object that looks like a vim.windows object.""" """An object that looks like a vim.windows object."""
@ -534,7 +554,7 @@ class VimMatch( object ):
def __repr__( self ): def __repr__( self ):
return "VimMatch( group = '{0}', pattern = '{1}' )".format( self.group, return "VimMatch( group = '{}', pattern = '{}' )".format( self.group,
self.pattern ) self.pattern )
@ -562,8 +582,8 @@ class VimSign( object ):
def __repr__( self ): def __repr__( self ):
return ( "VimSign( id = {0}, line = {1}, " return ( "VimSign( id = {}, line = {}, "
"name = '{2}', bufnr = {3} )".format( self.id, "name = '{}', bufnr = {} )".format( self.id,
self.line, self.line,
self.name, self.name,
self.bufnr ) ) self.bufnr ) )
@ -692,7 +712,7 @@ def ExpectedFailure( reason, *exception_matchers ):
# Failed for the right reason # Failed for the right reason
raise nose.SkipTest( reason ) raise nose.SkipTest( reason )
else: else:
raise AssertionError( 'Test was expected to fail: {0}'.format( raise AssertionError( 'Test was expected to fail: {}'.format(
reason ) ) reason ) )
return Wrapper return Wrapper

View File

@ -27,7 +27,7 @@ from builtins import * # noqa
from ycm.tests import PathToTestFile from ycm.tests import PathToTestFile
from ycm.tests.test_utils import ( CurrentWorkingDirectory, ExtendedMock, from ycm.tests.test_utils import ( CurrentWorkingDirectory, ExtendedMock,
MockVimBuffers, MockVimModule, Version, MockVimBuffers, MockVimModule, Version,
VimBuffer, VimError ) VimBuffer, VimError, WindowsAndMacOnly )
MockVimModule() MockVimModule()
from ycm import vimsupport from ycm import vimsupport
@ -1858,6 +1858,35 @@ def JumpToLocation_DifferentFile_Split_CurrentTab_AlreadyOpened_test(
] ) ] )
@WindowsAndMacOnly
@patch( 'vim.command', new_callable = ExtendedMock )
def JumpToLocation_DifferentFile_Split_CurrentTab_AlreadyOpened_Case_test(
vim_command ):
current_buffer = VimBuffer( 'current_buffer' )
different_buffer = VimBuffer( 'AnotHer_buFfeR' )
current_window = MagicMock( buffer = current_buffer )
different_window = MagicMock( buffer = different_buffer )
current_tab = MagicMock( windows = [ current_window, different_window ] )
with MockVimBuffers( [ current_buffer, different_buffer ],
[ current_buffer ] ) as vim:
vim.current.tabpage = current_tab
vimsupport.JumpToLocation( os.path.realpath( 'anOther_BuffEr' ),
4,
1,
'belowright',
'split-or-existing-window' )
assert_that( vim.current.tabpage, equal_to( current_tab ) )
assert_that( vim.current.window, equal_to( different_window ) )
assert_that( vim.current.window.cursor, equal_to( ( 4, 0 ) ) )
vim_command.assert_has_exact_calls( [
call( 'normal! m\'' ),
call( 'normal! zz' )
] )
@patch( 'vim.command', new_callable = ExtendedMock ) @patch( 'vim.command', new_callable = ExtendedMock )
def JumpToLocation_DifferentFile_Split_AllTabs_NotAlreadyOpened_test( def JumpToLocation_DifferentFile_Split_AllTabs_NotAlreadyOpened_test(
vim_command ): vim_command ):

View File

@ -28,8 +28,13 @@ import os
import json import json
import re import re
from collections import defaultdict, namedtuple from collections import defaultdict, namedtuple
from ycmd.utils import ( ByteOffsetToCodepointOffset, GetCurrentDirectory, from ycmd.utils import ( ByteOffsetToCodepointOffset,
JoinLinesAsUnicode, ToBytes, ToUnicode ) GetCurrentDirectory,
JoinLinesAsUnicode,
OnMac,
OnWindows,
ToBytes,
ToUnicode )
BUFFER_COMMAND_MAP = { 'same-buffer' : 'edit', BUFFER_COMMAND_MAP = { 'same-buffer' : 'edit',
'split' : 'split', 'split' : 'split',
@ -460,10 +465,21 @@ def EscapeFilepathForVimCommand( filepath ):
return GetVariableValue( to_eval ) return GetVariableValue( to_eval )
def ComparePaths( path1, path2 ):
# Assume that the file system is case-insensitive on Windows and macOS and
# case-sensitive on other platforms. While this is not necessarily true, being
# completely correct here is not worth the trouble as this assumption
# represents the overwhelming use case and detecting the case sensitivity of a
# file system is tricky.
if OnWindows() or OnMac():
return path1.lower() == path2.lower()
return path1 == path2
# Both |line| and |column| need to be 1-based # Both |line| and |column| need to be 1-based
def TryJumpLocationInTab( tab, filename, line, column ): def TryJumpLocationInTab( tab, filename, line, column ):
for win in tab.windows: for win in tab.windows:
if GetBufferFilepath( win.buffer ) == filename: if ComparePaths( GetBufferFilepath( win.buffer ), filename ):
vim.current.tabpage = tab vim.current.tabpage = tab
vim.current.window = win vim.current.window = win
vim.current.window.cursor = ( line, column - 1 ) vim.current.window.cursor = ( line, column - 1 )