hsanson / vim-android

Android development plugin for vim
BSD 2-Clause "Simplified" License
411 stars 40 forks source link

Vim-android compatible with nvim-cmp and jdts #111

Closed JartX closed 2 years ago

JartX commented 2 years ago

After generate classpath vim-android is full compatible with hrsh7th/nvim-cmpm using vim-lsp. Usedl: williamboman/nvim-lsp-installer to install the jdts

@hsanson fine work! any way to do donations to the project??

hsanson commented 2 years ago

Thanks for the interest but I do not have way to accept donations. Just keep the feedback and bugs comming so I can keep improving the plugin.

Also thanks for the heads up since I was planning to remove the classpath generation (see #110) but if this is useful then better keep and improve it instead.

psolyca commented 2 years ago

@JartX could you share your configuration, please ? Are you using nvim-jdtls or the simple jdtls ?

Thanks

hsanson commented 2 years ago

My vim config is here: https://github.com/hsanson/dotvim

I install eclipselsp directly from source, see instructions on my init.vim file.

psolyca commented 2 years ago

I have also managed, just after this comment to use the .classpath file with nvim-jdtls. I have tried to send all libraries with the referencedLibraries settings but elclipse.jdt.ls never take this value. So I have a modified the start of nvim-jdtls to wait until vim-android has finished his job and created the .classpath file. I will provide my dotfiles later. Thanks anyway for your plugin.

EDIT : For nvim-jdtls in ftplugin/java.lua script:

vim.wait(10000, function()
  return vim.g.gradle_set_classpath
end, 1000)
vim.fn['classpath#generateClasspath']()
require('jdtls').start_or_attach(config)

First start could be longer but faster than VSCodium.

alexmaloteaux commented 2 years ago

hi i m using nvim with nvim-lsp, nvim-cmp,nvim-jdtls but without ale i tried to reroduce the suggestions here but i never manage to have completion on android classes. Is it possible at all ?

liuwei031015 commented 2 years ago

I tried using ale + eclipselsp +vim-android, doesn't work. Unable to recognize android related classes.

liuwei031015 commented 2 years ago

function! ale_linters#java#EclipseLspNotifyConfigChange() abort

let l:buffer = bufnr('%')

if s:LoadedAle(l:buffer, 'eclipselsp') let config = \ { \ 'settings': { \ 'java': { \ 'project': { \ 'referencedLibraries': s:LoadDeps() \ } \ } \ } \ }

call ale#lsp_linter#SendRequest(
      \ l:buffer,
      \ 'javalsp',
      \ [ 0, 'workspace/didChangeConfiguration', l:config ])

call ale#lsp_linter#SendRequest(
      \ bufnr('%'),
      \ 'javalsp',
      \ ale#lsp#message#DidChange(l:buffer))

endif

endfunction

I'm trying to use eclipselsp but it doesn't work, Android core and generated classes are not recognized.

Shouldn't this be changed to ale#lsp_linter#SendRequest(....,'eclipselsp', ...)? I changed it but it still doesn't work. Is only neovim supported? version: vim8.2 + ale + eclipselsp +vim-android @hsanson

hsanson commented 2 years ago

Difficult to know what may be wrong in your case. Since you use vim8.2 try adding this to your config:

call ch_logfile(expand('/tmp/chlogfile.log'), 'w')

Then inspect the chlogfile.log file while working on an android project. It may contain insights on what is not properly working.

Also ensure ALE is finding and starting the language server. ALEInfo should show something like:

(executable check - success) /home/username/Apps/java-language-server/dist/lang_server_linux.sh
(started) ['/bin/bash', '-c', '''/home/username/Apps/java-language-server/dist/lang_server_linux.sh''']

Also make sure that you have auto import enabled in ALE since eclipselsp does not provide autocompletions unless this is enabled. Note that it is enable by default but to be sure you can add this to your config:

let g:ale_completion_autoimport = 1
liuwei031015 commented 2 years ago

@hsanson Mine tried looking at the log files, but to no avail. As you said, 'lang_server_linux.sh' works fine. But what I can't understand is, why do I need to run 'lang_server_linux.sh' with my currently configured eclipselsp? 'lang_server_linux.sh' is for javalsp.

hsanson commented 2 years ago

@liuwei031015 sorry about that... pasted the wrong output. For eclipselsp you should see these lines in ALEInfo output:

(executable check - success) java
(finished - exit code 0) ['/bin/bash', '-c', '''java'' -version']
<<<OUTPUT STARTS>>>
openjdk version "17.0.4" 2022-07-19 LTS
OpenJDK Runtime Environment Corretto-17.0.4.8.1 (build 17.0.4+8-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.4.8.1 (build 17.0.4+8-LTS, mixed mode, sharing)
<<<OUTPUT ENDS>>>
(started) ['/bin/bash', '-c', '''java''  -Declipse.application=org.eclipse.jdt.ls.core.id1 -Dosgi.bundles.defaultStartLevel=4
 -Declipse.product=org.eclipse.jdt.ls.core.product -Dlog.level=ALL -noverify -Xmx1G -jar ''/home/ryujin/Apps/eclipse.jdt.ls/o
rg.eclipse.jdt.ls.product/target/products/languageServer.product/linux/gtk/x86_64/plugins/org.eclipse.equinox.launcher_1.6.40
0.v20210924-0641.jar'' -configuration ''/home/ryujin/Apps/eclipse.jdt.ls/org.eclipse.jdt.ls.product/target/products/languageS
erver.product/linux/gtk/x86_64/config_linux'' -data ''/home/ryujin/Projects/HelloWorld'' --add-modules=ALL-SYSTEM --add-opens
 java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED']

Depending on the version of java you have on your system the ouput of "java -version" will differ.

Also note this assumes the "java" binary you want to use is in your PATH or this line would fail:

(executable check - success) java

You can force the java binary location by setting ale_java_eclipselsp_executable to the full path where the binary is located.

liuwei031015 commented 2 years ago

@hsanson The logs output by ALEInfo are normal. Then I added log (ehom) "ale#lsp_linter#StartLSP" and "ale_linters#java#EclipseLspNotifyConfigChange" to these two methods.

Messages maintainer: Bram Moolenaar <Bram@vim.org>
"BtvIotApplication.java" 176L, 6831B
exec ale#lsp_linter#StartLSP : {'output_stream': 'stdout', 'lint_file': 0, 'initialization_options': {'exten
dedClientCapabilities': {'classFileContentsSupport': v:true}}, 'language': 'java', 'name': 'eclipselsp', 'pr
oject_root': function('ale#java#FindProjectRoot'), 'aliases': [], 'executable': function('ale_linters#java#e
clipselsp#Executable'), 'lsp': 'stdio', 'read_buffer': 1, 'command': function('ale_linters#java#eclipselsp#R
unWithVersionCheck')}
gutentags: gtags-cscope job failed, returned: 122
ale_linters#java#EclipseLspNotifyConfigChange workspace/didChangeConfiguration
exec ale#lsp_linter#StartLSP : {'output_stream': 'stdout', 'lint_file': 0, 'initialization_options': {'exten
dedClientCapabilities': {'classFileContentsSupport': v:true}}, 'language': 'java', 'name': 'eclipselsp', 'pr
oject_root': function('ale#java#FindProjectRoot'), 'aliases': [], 'executable': function('ale_linters#java#e
clipselsp#Executable'), 'lsp': 'stdio', 'read_buffer': 1, 'command': function('ale_linters#java#eclipselsp#R
unWithVersionCheck')}
exec ale#lsp_linter#StartLSP : {'output_stream': 'stdout', 'lint_file': 0, 'initialization_options': {'exten
dedClientCapabilities': {'classFileContentsSupport': v:true}}, 'language': 'java', 'name': 'eclipselsp', 'pr
oject_root': function('ale#java#FindProjectRoot'), 'aliases': [], 'executable': function('ale_linters#java#e
clipselsp#Executable'), 'lsp': 'stdio', 'read_buffer': 1, 'command': function('ale_linters#java#eclipselsp#R
unWithVersionCheck')}

I guess before sending the message (didChangeConfiguration), do I need to make sure the service is up.

hsanson commented 2 years ago

I am unable to see the problem. Please post the full ALEInfo here. There is no need to change anything in ALE or vim-android for them to work together.

liuwei031015 commented 2 years ago

@hsanson You can check this method : "vim-android/autoload/ale_linters/java.vim"

function! ale_linters#java#EclipseLspNotifyConfigChange() abort

  let l:buffer = bufnr('%')

  if s:LoadedAle(l:buffer, 'eclipselsp')
    let config =
          \ {
          \  'settings': {
          \    'java': {
          \      'project': {
          \        'referencedLibraries': s:LoadDeps()
          \      }
          \    }
          \  }
          \ }

    call ale#lsp_linter#SendRequest(
          \ l:buffer,
          \ 'javalsp',
          \ [ 0, 'workspace/didChangeConfiguration', l:config ])

    call ale#lsp_linter#SendRequest(
          \ bufnr('%'),
          \ 'javalsp',
          \ ale#lsp#message#DidChange(l:buffer))
  endif

endfunction

Is the parameter of the "ale#lsp_linter#SendRequest" method wrong? "javalsp"?

hsanson commented 2 years ago

Well that is interesting.... that is indeed wrong. Strange thing is I did many more tests and auto-completion works no matter if the linter is set to eclipselsp or javalsp. I changed it to eclipselsp anyways for consistency so please updat to latest version of vim-android.

Try downloading JDT 1.14.0 from here https://download.eclipse.org/jdtls/milestones/1.14.0/ and then set g:ale_java_eclipselsp_path to the path where you uncompressed it:

let g:ale_java_eclipselsp_path = '/path/to/jdt-1.14.0'

Make sure to download Java 17. I use corretto but this should work fine with openjdk too. This is because JDT 1.14.0 won't work with older versions of java. Then set g:ale_java_eclipselsp_executable to the java 17 binary:

let g:ale_java_eclipselsp_executable = '/usr/lib/jvm/java-17-amazon-corretto/bin/java'

Since android projects require Java 8 or 11 make sure to also download that one and make it your system default. This would allow gradle (vim-android) to build android projects using the system java version.

Make sure to have these configs set:

let g:ale_completion_enabled = 1
let g:ale_completion_autoimport = 1
let g:ale_linters = {'java': ['eclipselsp']}
set omnifunc=ale#completion#OmniFunc

Try cloning this simple repo and test auto-completion, go to definition, and import. They all should work:

Notes:

Here is an example showing how it works on my setup: ale-jdt

liuwei031015 commented 2 years ago

@hsanson Thanks a lot, it works. However, I found that using the latest version of Gradle and the latest version of AGP still fails. By looking at the logs, it turns out that the "init.gradle" part of the output is invalid. I will try to fix it. Thank you very much for your work.

liuwei031015 commented 2 years ago

@hsanson Seems to have found the reason why I keep failing. This plugin canceled the generation of ".classpath" files. I tried executing "GradleGenClassPathFile" and everything worked. Everything is great now, thank you.

hsanson commented 2 years ago

That is interesting... I have never used GradleGenClassPathFile and my projects do not have .classpath files in their roots. Need to investigate more. Can you provide more details on you config to see if I can replicate the issue? Gradle version, java version, ALE config, vim-android config, etc...

liuwei031015 commented 2 years ago

@hsanson You can check my full config here: https://github.com/liuwei031015/MyVimrc Gradle:7.5.1 Android Gradle Plugin: 7.2.0 Java: corretto 11 and corretto 17 Also, the .classpath file can be found in the app/ directory.

liuwei031015 commented 2 years ago

Now, both javalsp and eclipselsp work fine. javalsp can support auto-import using this commit: https://github.com/georgewfraser/java-language-server/pull/199

hsanson commented 2 years ago

@liuwei031015 you are aboslutely right... eclipselsp does not work without the .classpath file. I had it inside the app/ folder as you mentioned. Will create an issue to update docs and also set options to automatically generate it after GradleSync.

hsanson commented 2 years ago

Made classpath generation automatic for Android projects. This should help make things just work out of the box. Manipulation of the .classpath file could be improved but that is work for future improvement. Currently that file contents is a mystery to me.