0

I have installed tern_for_vim and setted complete in .vimrc.

autocmd FileType javascript setlocal omnifunc=tern#Complete
autocmd FileType php set omnifunc=phpcomplete#CompletePHP

Now i can call javascript complete when editing html file via ctrl+x and ctrl+o.
The php completion can pop up when editing a php file (vim test.php) via ctrl+x and ctrl+o.
Many php and javascript code snippets are embeded in a html file.

What i can do now:
During editing my html file(vim test.html), when javascript complete needed ,it can call via ctrl+x and ctrl+o; when php complete needed ,it can't call via ctrl+x and ctrl+o.

What i expect:
During editing my html file(vim test.html), when javascript complete needed ,it can call via ctrl+x and ctrl+o; when php complete needed ,it can call via ctrl+x and ctrl+o.
YouCompleteMe and tern_for_vim installed.

cat  .tern-project
{
    "ecmaVersion": 6,
    "libs": [
        "browser",
        "underscore",
        "jquery"
    ],
    "plugins": {
        "node": {}
    }
}  

I reset my .vimrc according to Rich's code.

cat .vimrc
set nobackup
set nowritebackup    
set tabstop=4
set sts=4
set expandtab
set softtabstop=4
set shiftwidth=4    
set number    
execute pathogen#infect()
execute pathogen#helptags()

filetype plugin on    
autocmd FileType html setlocal omnifunc=MyHTMLComplete
function! MyHTMLComplete(findstart, base)
    if search('<?php', 'bnW') > search('<script>', 'bnW')
        return phpcomplete#CompletePHP(a:findstart, a:base)
    else
        return tern#Complete(a:findstart,a:base)
    endif
endfunction

ls .vim/bundle
phpcomplete.vim  tabular  tern_for_vim  webapi-vim  YouCompleteMe


vim test.html
<script>
    document.get 
</script>  

js complete in html file called by ctrl-x + ctrl-o

Add php code snippet to test complete.

php complete in html file can't called by ctrl-x + ctrl-o

Edit a single test.php file. php complete in php file called by ctrl-x + ctrl-o

How to achieve my target?

Setting .vimrc as setting1 :

execute pathogen#infect()
execute pathogen#helptags()

filetype plugin on    
autocmd FileType html setlocal omnifunc=MyHTMLComplete
function! MyHTMLComplete(findstart, base)
    if search('<?php', 'bnW') > search('<script>', 'bnW')
        return phpcomplete#CompletePHP(a:findstart, a:base)
    else
        return tern#Complete(a:findstart,a:base)
    endif
endfunction

Setting .vimrc as setting2 :

execute pathogen#infect()
execute pathogen#helptags()
autocmd FileType javascript setlocal omnifunc=tern#Complete
autocmd FileType php set omnifunc=phpcomplete#CompletePHP
filetype plugin on    
autocmd FileType html setlocal omnifunc=MyHTMLComplete
function! MyHTMLComplete(findstart, base)
    if search('<?php', 'bnW') > search('<script>', 'bnW')
        return phpcomplete#CompletePHP(a:findstart, a:base)
    else
        return tern#Complete(a:findstart,a:base)
    endif
endfunction

It is tested that both setting1 and setting2 take the same effect.

verbose :set omnifunc?
  omnifunc=MyHTMLComplete
        Last set from ~/.vimrc
4
  • What happens if you add the line throw "PHP" before the line return phpcomplete...?
    – Rich
    Apr 1 '18 at 21:30
  • Also, what is the result of verbose :set omnifunc? when run in an HTML file?
    – Rich
    Apr 1 '18 at 21:33
  • Your new pasted vimrc doesn't seem to include the lines you said you were using to set up completion. Are these actually set up by the plugins themselves?
    – Rich
    Apr 1 '18 at 21:34
  • You sort of addressed my third question, but not the first two.
    – Rich
    Apr 2 '18 at 5:58
2

Here's some rough code to start you off. Create the file .vim/after/ftplugin/html.vim and add the following code:

setlocal omnifunc=MyHTMLComplete 

function! MyHTMLComplete(findstart, base)
    if search('<?php', 'bnW') > search('<script>', 'bnW')
        return phpcomplete#CompletePHP(a:findstart, a:base)
    else
        return tern#Complete(a:findstart,a:base)
    endif
endfunction

It first uses the search() function to look for the nearest php and script section starts, passing the following flags:

  • b - search backwards,
  • n - don't move the cursor,
  • W - don't wrap around at the start of the file,

It then passes on the call to the corresponding existing complete function, depending on which section starts later.

This is obviously an exceedingly imprecise check of the current context. Hopefully this is enough to start you off, but you'll need to improve this quite a lot for this to be a robust solution!

Possibly a better technique for discerning what type of code you are in would be to use synstack() and its related functions to interrogate Vim's syntax highlighting information. Something like the following might work:

for id in synstack(line('.'), col('.'))
    if synIDattr(id, 'name') =~? 'javascript'
        echom "In Javascript!"
        break
    endif
endfor

For more details, see:

  • :help complete-functions
  • :help search()
  • :help synstack()
0

It works as following.

filetype plugin indent on
autocmd FileType html setlocal omnifunc=MyHTMLComplete
function! MyHTMLComplete(findstart, base)
    autocmd FileType javascript setlocal omnifunc=tern#Complete
    autocmd FileType php set omnifunc=phpcomplete#CompletePHP
    if search('<?php', 'bnW') > search('<script>', 'bnW')
        return phpcomplete#CompletePHP(a:findstart, a:base)
    else
        return tern#Complete(a:findstart,a:base)
    endif
endfunction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.