Browse Source

VimL support for py3

Val Markovic 9 years ago
parent
commit
b04870c824
2 changed files with 72 additions and 43 deletions
  1. 70 41
      autoload/youcompleteme.vim
  2. 2 2
      plugin/youcompleteme.vim

+ 70 - 41
autoload/youcompleteme.vim

@@ -29,6 +29,26 @@ let s:cursor_moved = 0
 let s:moved_vertically_in_insert_mode = 0
 let s:previous_num_chars_on_current_line = strlen( getline('.') )
 
+function! s:UsingPython2()
+  " I'm willing to bet quite a bit that sooner or later, somebody will ask us to
+  " make it configurable which version of Python we use.
+  if has('python')
+    return 1
+  endif
+  return 0
+endfunction
+
+let s:using_python2 = s:UsingPython2()
+let s:python_until_eof = s:using_python2 ? "python << EOF" : "python3 << EOF"
+let s:python_command = s:using_python2 ? "py " : "py3 "
+
+function! s:Pyeval( eval_string )
+  if s:using_python2
+    return pyeval( a:eval_string )
+  endif
+  return py3eval( a:eval_string )
+endfunction
+
 
 function! youcompleteme#Enable()
   " When vim is in diff mode, don't run
@@ -120,17 +140,22 @@ endfunction
 
 
 function! youcompleteme#GetErrorCount()
-  return pyeval( 'ycm_state.GetErrorCount()' )
+  return s:Pyeval( 'ycm_state.GetErrorCount()' )
 endfunction
 
 
 function! youcompleteme#GetWarningCount()
-  return pyeval( 'ycm_state.GetWarningCount()' )
+  return s:Pyeval( 'ycm_state.GetWarningCount()' )
 endfunction
 
 
 function! s:SetUpPython() abort
-python << EOF
+  exec s:python_until_eof
+from __future__ import unicode_literals
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
 import os
 import sys
 import traceback
@@ -340,7 +365,7 @@ function! s:SetUpCpoptions()
 
   " This prevents the display of "Pattern not found" & similar messages during
   " completion. This is only available since Vim 7.4.314
-  if pyeval( 'vimsupport.VimVersionAtLeast("7.4.314")' )
+  if s:Pyeval( 'vimsupport.VimVersionAtLeast("7.4.314")' )
     set shortmess+=c
   endif
 endfunction
@@ -383,12 +408,12 @@ endfunction
 
 
 function! s:OnVimLeave()
-  py ycm_state.OnVimLeave()
+  exec s:python_command "ycm_state.OnVimLeave()"
 endfunction
 
 
 function! s:OnCompleteDone()
-  py ycm_state.OnCompleteDone()
+  exec s:python_command "ycm_state.OnCompleteDone()"
 endfunction
 
 
@@ -421,7 +446,7 @@ function! s:OnBufferVisit()
     call s:SetOmnicompleteFunc()
   endif
 
-  py ycm_state.OnBufferVisit()
+  exec s:python_command "ycm_state.OnBufferVisit()"
   call s:OnFileReadyToParse()
 endfunction
 
@@ -431,7 +456,8 @@ function! s:OnBufferUnload( deleted_buffer_file )
     return
   endif
 
-  py ycm_state.OnBufferUnload( vim.eval( 'a:deleted_buffer_file' ) )
+  exec s:python_command "ycm_state.OnBufferUnload("
+        \ "vim.eval( 'a:deleted_buffer_file' ) )"
 endfunction
 
 
@@ -454,11 +480,11 @@ function! s:OnFileReadyToParse()
   " reparsing the file again. If we sent the new parse request first, then
   " the response would always be pending when we called
   " HandleFileParseRequest.
-  py ycm_state.HandleFileParseRequest()
+  exec s:python_command "ycm_state.HandleFileParseRequest()"
 
   let buffer_changed = b:changedtick != b:ycm_changedtick.file_ready_to_parse
   if buffer_changed
-    py ycm_state.OnFileReadyToParse()
+    exec s:python_command "ycm_state.OnFileReadyToParse()"
   endif
   let b:ycm_changedtick.file_ready_to_parse = b:changedtick
 endfunction
@@ -471,7 +497,7 @@ endfunction
 
 
 function! s:SetOmnicompleteFunc()
-  if pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
+  if s:Pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
     let &omnifunc = 'youcompleteme#OmniComplete'
     let &l:omnifunc = 'youcompleteme#OmniComplete'
 
@@ -489,7 +515,7 @@ function! s:OnCursorMovedInsertMode()
     return
   endif
 
-  py ycm_state.OnCursorMoved()
+  exec s:python_command "ycm_state.OnCursorMoved()"
   call s:UpdateCursorMoved()
 
   " Basically, we need to only trigger the completion menu when the user has
@@ -515,7 +541,7 @@ function! s:OnCursorMovedInsertMode()
   " We have to make sure we correctly leave omnifunc mode even when the user
   " inserts something like a "operator[]" candidate string which fails
   " CurrentIdentifierFinished check.
-  if s:omnifunc_mode && !pyeval( 'base.LastEnteredCharIsIdentifierChar()')
+  if s:omnifunc_mode && !s:Pyeval( 'base.LastEnteredCharIsIdentifierChar()')
     let s:omnifunc_mode = 0
   endif
 endfunction
@@ -527,7 +553,7 @@ function! s:OnCursorMovedNormalMode()
   endif
 
   call s:OnFileReadyToParse()
-  py ycm_state.OnCursorMoved()
+  exec s:python_command "ycm_state.OnCursorMoved()"
 endfunction
 
 
@@ -538,7 +564,7 @@ function! s:OnInsertLeave()
 
   let s:omnifunc_mode = 0
   call s:OnFileReadyToParse()
-  py ycm_state.OnInsertLeave()
+  exec s:python_command "ycm_state.OnInsertLeave()"
   if g:ycm_autoclose_preview_window_after_completion ||
         \ g:ycm_autoclose_preview_window_after_insertion
     call s:ClosePreviewWindowIfNeeded()
@@ -601,10 +627,10 @@ endfunction
 
 
 function! s:IdentifierFinishedOperations()
-  if !pyeval( 'base.CurrentIdentifierFinished()' )
+  if !s:Pyeval( 'base.CurrentIdentifierFinished()' )
     return
   endif
-  py ycm_state.OnCurrentIdentifierFinished()
+  exec s:python_command "ycm_state.OnCurrentIdentifierFinished()"
   let s:omnifunc_mode = 0
 endfunction
 
@@ -613,7 +639,8 @@ endfunction
 function! s:InsideCommentOrString()
   " Has to be col('.') -1 because col('.') doesn't exist at this point. We are
   " in insert mode when this func is called.
-  let syntax_group = synIDattr( synIDtrans( synID( line( '.' ), col( '.' ) - 1, 1 ) ), 'name')
+  let syntax_group = synIDattr(
+        \ synIDtrans( synID( line( '.' ), col( '.' ) - 1, 1 ) ), 'name')
 
   if stridx(syntax_group, 'Comment') > -1
     return 1
@@ -642,7 +669,7 @@ endfunction
 
 
 function! s:OnBlankLine()
-  return pyeval( 'not vim.current.line or vim.current.line.isspace()' )
+  return s:Pyeval( 'not vim.current.line or vim.current.line.isspace()' )
 endfunction
 
 
@@ -678,7 +705,7 @@ function! s:InvokeCompletion()
 endfunction
 
 
-python << EOF
+exec s:python_until_eof
 def GetCompletionsInner():
   request = ycm_state.GetCurrentCompletionRequest()
   request.Start()
@@ -692,8 +719,8 @@ EOF
 
 
 function! s:GetCompletions()
-  py results = GetCompletionsInner()
-  let results = pyeval( 'results' )
+  exec s:python_command "results = GetCompletionsInner()"
+  let results = s:Pyeval( 'results' )
   return results
 endfunction
 
@@ -718,11 +745,11 @@ function! youcompleteme#Complete( findstart, base )
       return -2
     endif
 
-    if !pyeval( 'ycm_state.IsServerAlive()' )
+    if !s:Pyeval( 'ycm_state.IsServerAlive()' )
       return -2
     endif
-    py ycm_state.CreateCompletionRequest()
-    return pyeval( 'base.CompletionStartColumn()' )
+    exec s:python_command "ycm_state.CreateCompletionRequest()"
+    return s:Pyeval( 'base.CompletionStartColumn()' )
   else
     return s:GetCompletions()
   endif
@@ -731,12 +758,13 @@ endfunction
 
 function! youcompleteme#OmniComplete( findstart, base )
   if a:findstart
-    if !pyeval( 'ycm_state.IsServerAlive()' )
+    if !s:Pyeval( 'ycm_state.IsServerAlive()' )
       return -2
     endif
     let s:omnifunc_mode = 1
-    py ycm_state.CreateCompletionRequest( force_semantic = True )
-    return pyeval( 'base.CompletionStartColumn()' )
+    exec s:python_command "ycm_state.CreateCompletionRequest("
+          \ "force_semantic = True )"
+    return s:Pyeval( 'base.CompletionStartColumn()' )
   else
     return s:GetCompletions()
   endif
@@ -744,23 +772,23 @@ endfunction
 
 
 function! youcompleteme#ServerPid()
-  return pyeval( 'ycm_state.ServerPid()' )
+  return s:Pyeval( 'ycm_state.ServerPid()' )
 endfunction
 
 
 function! s:RestartServer()
-  py ycm_state.RestartServer()
+  exec s:python_command "ycm_state.RestartServer()"
 endfunction
 
 
 function! s:ShowDetailedDiagnostic()
-  py ycm_state.ShowDetailedDiagnostic()
+  exec s:python_command "ycm_state.ShowDetailedDiagnostic()"
 endfunction
 
 
 function! s:DebugInfo()
   echom "Printing YouCompleteMe debug information..."
-  let debug_info = pyeval( 'ycm_state.DebugInfo()' )
+  let debug_info = s:Pyeval( 'ycm_state.DebugInfo()' )
   for line in split( debug_info, "\n" )
     echom '-- ' . line
   endfor
@@ -770,8 +798,9 @@ endfunction
 function! s:ToggleLogs(...)
   let stderr = a:0 == 0 || a:1 !=? 'stdout'
   let stdout = a:0 == 0 || a:1 !=? 'stderr'
-  py ycm_state.ToggleLogs( stdout = vimsupport.GetBoolValue( 'l:stdout' ),
-                         \ stderr = vimsupport.GetBoolValue( 'l:stderr' ) )
+  exec s:python_command "ycm_state.ToggleLogs("
+        \ "stdout = vimsupport.GetBoolValue( 'l:stdout' ),"
+        \ "stderr = vimsupport.GetBoolValue( 'l:stderr' ) )"
 endfunction
 
 
@@ -793,8 +822,8 @@ function! s:CompleterCommand(...)
     let arguments = arguments[1:]
   endif
 
-  py ycm_state.SendCommandRequest( vim.eval( 'l:arguments' ),
-        \                          vim.eval( 'l:completer' ) )
+  exec s:python_command "ycm_state.SendCommandRequest("
+        \ "vim.eval( 'l:arguments' ), vim.eval( 'l:completer' ) ) "
 endfunction
 
 
@@ -814,21 +843,21 @@ endfunction
 
 
 function! youcompleteme#SubCommandsComplete( arglead, cmdline, cursorpos )
-  return join( pyeval( 'ycm_state.GetDefinedSubcommands()' ),
+  return join( s:Pyeval( 'ycm_state.GetDefinedSubcommands()' ),
     \ "\n")
 endfunction
 
 
 function! s:ForceCompile()
-  if !pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
+  if !s:Pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
     echom "Native filetype completion not supported for current file, "
           \ . "cannot force recompilation."
     return 0
   endif
 
   echom "Forcing compilation, this will block Vim until done."
-  py ycm_state.OnFileReadyToParse()
-  py ycm_state.HandleFileParseRequest( True )
+  exec s:python_command "ycm_state.OnFileReadyToParse()"
+  exec s:python_command "ycm_state.HandleFileParseRequest( True )"
 
   return 1
 endfunction
@@ -849,7 +878,7 @@ function! s:ShowDiagnostics()
     return
   endif
 
-  if pyeval( 'ycm_state.PopulateLocationListWithLatestDiagnostics()' )
+  if s:Pyeval( 'ycm_state.PopulateLocationListWithLatestDiagnostics()' )
     if g:ycm_open_loclist_on_ycm_diags
       lopen
     endif

+ 2 - 2
plugin/youcompleteme.vim

@@ -33,10 +33,10 @@ elseif v:version < 703 || (v:version == 703 && !has('patch598'))
         \ echohl None
   call s:restore_cpo()
   finish
-elseif !has( 'python' )
+elseif !has( 'python' ) && !has( 'python3' )
   echohl WarningMsg |
         \ echomsg "YouCompleteMe unavailable: requires Vim compiled with " .
-        \ "Python 2.x support" |
+        \ "Python (2.6+ or 3.3+) support" |
         \ echohl None
   call s:restore_cpo()
   finish