Browse Source

Allow completion on a buffer without filetype

Introduce "fake" filetype `ycm_nofiletype` that is used to handle all
buffers without filetype.
Maxim Kim 4 years ago
parent
commit
4adf469e0f

+ 4 - 1
autoload/youcompleteme.vim

@@ -478,6 +478,9 @@ function! s:AllowedToCompleteInBuffer( buffer )
   endif
 
   let filetype = getbufvar( a:buffer, '&filetype' )
+  if empty( filetype )
+    let filetype = 'ycm_nofiletype'
+  endif
 
   let whitelist_allows = type( g:ycm_filetype_whitelist ) != v:t_dict ||
         \ has_key( g:ycm_filetype_whitelist, '*' ) ||
@@ -487,7 +490,7 @@ function! s:AllowedToCompleteInBuffer( buffer )
 
   let allowed = whitelist_allows && blacklist_allows
 
-  if empty( filetype ) || !allowed || s:DisableOnLargeFile( a:buffer )
+  if !allowed || s:DisableOnLargeFile( a:buffer )
     return 0
   endif
 

+ 8 - 2
python/ycm/vimsupport.py

@@ -715,7 +715,10 @@ def EscapeForVim( text ):
 
 
 def CurrentFiletypes():
-  return ToUnicode( vim.eval( "&filetype" ) ).split( '.' )
+  filetypes = vim.eval( "&filetype" )
+  if not filetypes:
+    filetypes = 'ycm_nofiletype'
+  return ToUnicode( filetypes ).split( '.' )
 
 
 def CurrentFiletypesEnabled( disabled_filetypes ):
@@ -729,7 +732,10 @@ def CurrentFiletypesEnabled( disabled_filetypes ):
 
 def GetBufferFiletypes( bufnr ):
   command = f'getbufvar({ bufnr }, "&ft")'
-  return ToUnicode( vim.eval( command ) ).split( '.' )
+  filetypes = vim.eval( command )
+  if not filetypes:
+    filetypes = 'ycm_nofiletype'
+  return ToUnicode( filetypes ).split( '.' )
 
 
 def FiletypesForBuffer( buffer_object ):

+ 70 - 0
test/completion.common.vim

@@ -203,6 +203,76 @@ function! Test_Enter_Delete_Chars_Updates_Filter()
   %bwipeout!
 endfunction
 
+function! Test_Compl_No_Filetype()
+  enew
+  call setline( '.', 'hello this is some text ' )
+
+  " Even when fileytpe is set to '', the filetype autocommand is triggered, but
+  " apparently, _not_ within this function.
+  doautocmd FileType
+  call assert_equal( 1, b:ycm_completing )
+
+  " Required to trigger TextChangedI
+  " https://github.com/vim/vim/issues/4665#event-2480928194
+  call test_override( 'char_avail', 1 )
+
+  " Must do the checks in a timer callback because we need to stay in insert
+  " mode until done.
+  function! Check( id ) closure
+    call assert_equal( getline( '2' ), 'hell' )
+    call WaitForCompletion()
+    let items = complete_info().items
+    call map( items, {index, value -> value.word} )
+    call assert_equal( [ 'hello' ], items )
+    call feedkeys( "\<ESC>" )
+  endfunction
+
+  call FeedAndCheckMain( 'ohell', funcref( 'Check' ) )
+  " Checks run in insert mode, then exit insert mode.
+  call assert_false( pumvisible(), 'pumvisible()' )
+
+  call test_override( 'ALL', 0 )
+  delfunc! Check
+  %bwipeout!
+endfunction
+
+function! SetUp_Test_Compl_No_Filetype_Blacklisted()
+  let g:ycm_filetype_blacklist = { 'ycm_nofiletype': 1 }
+endfunction
+
+function! TearDown__Test_Compl_No_Filetype_Blacklisted()
+  unlet! g:ycm_filetype_blacklist
+endfunction
+
+function! Test_Compl_No_Filetype_Blacklisted()
+  enew
+  call setline( '.', 'hello this is some text ' )
+
+  " Even when fileytpe is set to '', the filetype autocommand is triggered, but
+  " apparently, _not_ within this function.
+  doautocmd FileType
+  call assert_false( exists( 'b:ycm_completing' ) )
+
+  " Required to trigger TextChangedI
+  " https://github.com/vim/vim/issues/4665#event-2480928194
+  call test_override( 'char_avail', 1 )
+
+  " Must do the checks in a timer callback because we need to stay in insert
+  " mode until done.
+  function! Check( id ) closure
+    call assert_false( pumvisible() )
+    call feedkeys( "\<ESC>" )
+  endfunction
+
+  call FeedAndCheckMain( 'ohell', funcref( 'Check' ) )
+  " Checks run in insert mode, then exit insert mode.
+  call assert_false( pumvisible(), 'pumvisible()' )
+
+  call test_override( 'ALL', 0 )
+  delfunc! Check
+  %bwipeout!
+endfunction
+
 function! OmniFuncTester( findstart, query )
   if a:findstart
     return s:omnifunc_start_col

+ 5 - 5
test/completion_info.test.vim

@@ -55,9 +55,9 @@ function! Test_ResolveCompletion_OnChange()
   " Only the java completer actually uses the completion resolve
   call youcompleteme#test#setup#OpenFile(
         \ '/third_party/ycmd/ycmd/tests/java/testdata/simple_eclipse_project' .
-        \ '/src/com/test/MethodsWithDocumentation.java', { 'delay': 15 } )
+        \ '/src/com/test/TestWithDocumentation.java', { 'delay': 15 } )
 
-  call setpos( '.', [ 0, 33, 20 ] )
+  call setpos( '.', [ 0, 6, 21 ] )
   " Required to trigger TextChangedI
   " https://github.com/vim/vim/issues/4665#event-2480928194
   call test_override( 'char_avail', 1 )
@@ -106,7 +106,7 @@ function! Test_ResolveCompletion_OnChange()
     endif
   endfunction
 
-  call FeedAndCheckMain( 'C.', funcref( 'Check1' ) )
+  call FeedAndCheckMain( 'cw', funcref( 'Check1' ) )
 
   call assert_false( pumvisible(), 'pumvisible()' )
   call assert_equal( 1, found_getAString )
@@ -121,9 +121,9 @@ function! Test_DontResolveCompletion_AlreadyResolved()
   " Only the java completer actually uses the completion resolve
   call youcompleteme#test#setup#OpenFile(
         \ '/third_party/ycmd/ycmd/tests/java/testdata/simple_eclipse_project' .
-        \ '/src/com/test/MethodsWithDocumentation.java', { 'delay': 15 } )
+        \ '/src/com/test/TestWithDocumentation.java', { 'delay': 15 } )
 
-  call setpos( '.', [ 0, 34, 12 ] )
+  call setpos( '.', [ 0, 7, 12 ] )
   " Required to trigger TextChangedI
   " https://github.com/vim/vim/issues/4665#event-2480928194
   call test_override( 'char_avail', 1 )

+ 3 - 0
test/filesize.test.vim

@@ -4,6 +4,9 @@ function! SetUp()
   let g:ycm_auto_trigger = 1
   let g:ycm_keep_logfiles = 1
   let g:ycm_always_populate_location_list = 1
+  let g:ycm_filetype_blacklist = {
+        \ 'ycm_nofiletype': 1
+        \ }
 
   " diagnostics take ages
   let g:ycm_test_min_delay = 7 

+ 1 - 1
third_party/ycmd

@@ -1 +1 @@
-Subproject commit 9fb138b3ce9b2d269fd273850551087146bdf838
+Subproject commit 34a1566d563149093bed8a751b74c34db365a98a