diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2021-07-28 17:54:35 +0200 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2021-07-28 17:54:35 +0200 |
commit | ce31cd1d2f4e8eee9fd91325e4599f15cb9566fd (patch) | |
tree | 2306b79bdae6846233214734753be86ca6a13d7f /autoload/fsharp.vim | |
parent | 554a6ac7575f87b5b85d1b2bf60e7071c4164cbc (diff) | |
download | vim-polyglot-ce31cd1d2f4e8eee9fd91325e4599f15cb9566fd.tar.gz vim-polyglot-ce31cd1d2f4e8eee9fd91325e4599f15cb9566fd.zip |
Update
Diffstat (limited to 'autoload/fsharp.vim')
-rw-r--r-- | autoload/fsharp.vim | 171 |
1 files changed, 136 insertions, 35 deletions
diff --git a/autoload/fsharp.vim b/autoload/fsharp.vim index 67f56495..8567a037 100644 --- a/autoload/fsharp.vim +++ b/autoload/fsharp.vim @@ -12,6 +12,15 @@ let g:loaded_autoload_fsharp = 1 let s:cpo_save = &cpo set cpo&vim + +" basic setups + +let s:script_root_dir = expand('<sfile>:p:h') . "/../" + +if has('nvim-0.5') + lua ionide = require("ionide") +endif + function! s:prompt(msg) let height = &cmdheight if height < 2 @@ -21,6 +30,9 @@ function! s:prompt(msg) let &cmdheight = height endfunction + +" FSAC payload interfaces + function! s:PlainNotification(content) return { 'Content': a:content } endfunction @@ -80,8 +92,24 @@ function! s:FsdnRequest(query) return { 'Query': a:query } endfunction + +" LSP functions + function! s:call(method, params, cont) - call LanguageClient#Call(a:method, a:params, a:cont) + if g:fsharp#backend == 'languageclient-neovim' + call LanguageClient#Call(a:method, a:params, a:cont) + elseif g:fsharp#backend == 'nvim' + let key = fsharp#register_callback(a:cont) + call luaeval('ionide.call(_A[1], _A[2], _A[3])', [a:method, a:params, key]) + endif +endfunction + +function! s:notify(method, params) + if g:fsharp#backend == 'languageclient-neovim' + call LanguageClient#Notify(a:method, a:params) + elseif g:fsharp#backend == 'nvim' + call luaeval('ionide.notify(_A[1], _A[2])', [a:method, a:params]) + endif endfunction function! s:signature(filePath, line, character, cont) @@ -121,6 +149,9 @@ function! s:documentationSymbol(xmlSig, assembly, cont) return s:call('fsharp/documentationSymbol', s:DocumentationForSymbolRequest(a:xmlSig, a:assembly), a:cont) endfunction + +" FSAC configuration + " FSharpConfigDto from https://github.com/fsharp/FsAutoComplete/blob/master/src/FsAutoComplete/LspHelpers.fs " " * The following options seems not working with workspace/didChangeConfiguration @@ -160,7 +191,7 @@ let s:config_keys_camel = \ ] let s:config_keys = [] -function! fsharp#toSnakeCase(str) +function! s:toSnakeCase(str) let sn = substitute(a:str, '\(\<\u\l\+\|\l\+\)\(\u\)', '\l\1_\l\2', 'g') if sn == a:str | return tolower(a:str) | endif return sn @@ -170,7 +201,7 @@ function! s:buildConfigKeys() if len(s:config_keys) == 0 for key_camel in s:config_keys_camel let key = {} - let key.snake = fsharp#toSnakeCase(key_camel.key) + let key.snake = s:toSnakeCase(key_camel.key) let key.camel = key_camel.key if has_key(key_camel, 'default') let key.default = key_camel.default @@ -180,7 +211,7 @@ function! s:buildConfigKeys() endif endfunction -function! g:fsharp#getServerConfig() +function! fsharp#getServerConfig() let fsharp = {} call s:buildConfigKeys() for key in s:config_keys @@ -196,12 +227,76 @@ function! g:fsharp#getServerConfig() return fsharp endfunction -function! g:fsharp#updateServerConfig() +function! fsharp#updateServerConfig() let fsharp = fsharp#getServerConfig() let settings = {'settings': {'FSharp': fsharp}} - call LanguageClient#Notify('workspace/didChangeConfiguration', settings) + call s:notify('workspace/didChangeConfiguration', settings) +endfunction + + +" handlers for notifications + +let s:handlers = { + \ 'fsharp/notifyWorkspace': 'fsharp#handle_notifyWorkspace', + \ } + +function! s:registerAutocmds() + if g:fsharp#backend == 'nvim' && g:fsharp#lsp_codelens + augroup FSharp_AutoRefreshCodeLens + autocmd! + autocmd CursorHold,InsertLeave <buffer> lua vim.lsp.codelens.refresh() + augroup END + endif + if g:fsharp#backend != 'disable' + augroup FSharp_OnCursorMove + autocmd! + autocmd CursorMoved *.fs,*.fsi,*.fsx call fsharp#OnCursorMove() + augroup END + endif +endfunction + +function! fsharp#initialize() + echom '[FSAC] Initialized' + if g:fsharp#backend == 'languageclient-neovim' + call LanguageClient_registerHandlers(s:handlers) + endif + call fsharp#updateServerConfig() + call s:registerAutocmds() +endfunction + + +" nvim-lsp specific functions + +" handlers are picked up by ionide.setup() +function! fsharp#get_handlers() + return s:handlers endfunction +let s:callbacks = {} + +function! fsharp#register_callback(fn) + if g:fsharp#backend != 'nvim' + return -1 + endif + let rnd = reltimestr(reltime()) + let s:callbacks[rnd] = a:fn + return rnd +endfunction + +function! fsharp#resolve_callback(key, arg) + if g:fsharp#backend != 'nvim' + return + endif + if has_key(s:callbacks, a:key) + let Callback = s:callbacks[a:key] + call Callback(a:arg) + call remove(s:callbacks, a:key) + endif +endfunction + + +" .NET/F# specific operations + function! s:findWorkspace(dir, cont) let s:cont_findWorkspace = a:cont function! s:callback_findWorkspace(result) @@ -237,13 +332,20 @@ endfunction let s:workspace = [] +function! fsharp#handle_notifyWorkspace(payload) abort + let content = json_decode(a:payload.content) + if content.Kind == 'projectLoading' + echom "[FSAC] Loading" content.Data.Project + let s:workspace = uniq(sort(add(s:workspace, content.Data.Project))) + elseif content.Kind == 'workspaceLoad' && content.Data.Status == 'finished' + echom printf("[FSAC] Workspace loaded (%d project(s))", len(s:workspace)) + call fsharp#updateServerConfig() + endif +endfunction + + function! s:load(arg) - let s:loading_workspace = a:arg - function! s:callback_load(_) - echo "[FSAC] Workspace loaded: " . join(s:loading_workspace, ', ') - let s:workspace = s:workspace + s:loading_workspace - endfunction - call s:workspaceLoad(a:arg, function("s:callback_load")) + call s:workspaceLoad(a:arg, v:null) endfunction function! fsharp#loadProject(...) @@ -254,23 +356,15 @@ function! fsharp#loadProject(...) call s:load(prjs) endfunction -function! fsharp#loadWorkspaceAuto() - if &ft == 'fsharp' - call fsharp#updateServerConfig() - if g:fsharp#automatic_workspace_init - echom "[FSAC] Loading workspace..." - let bufferDirectory = fnamemodify(resolve(expand('%:p')), ':h') - call s:findWorkspace(bufferDirectory, function("s:load")) - endif - endif +function! fsharp#showLoadedProjects() + for proj in s:workspace + echo "-" proj + endfor endfunction function! fsharp#reloadProjects() if len(s:workspace) > 0 - function! s:callback_reloadProjects(_) - call s:prompt("[FSAC] Workspace reloaded.") - endfunction - call s:workspaceLoad(s:workspace, function("s:callback_reloadProjects")) + call s:workspaceLoad(s:workspace, v:null) else echom "[FSAC] Workspace is empty" endif @@ -288,7 +382,7 @@ function! fsharp#showSignature() if exists('result.result.content') let content = json_decode(result.result.content) if exists('content.Data') - echom substitute(content.Data, '\n\+$', ' ', 'g') + echo substitute(content.Data, '\n\+$', ' ', 'g') endif endif endfunction @@ -306,13 +400,21 @@ function! fsharp#showF1Help() echo result endfunction +function! s:hover() + if g:fsharp#backend == 'languageclient-neovim' + call LanguageClient#textDocument_hover() + elseif g:fsharp#backend == 'nvim' + lua vim.lsp.buf.hover() + endif +endfunction + function! fsharp#showTooltip() function! s:callback_showTooltip(result) let result = a:result if exists('result.result.content') let content = json_decode(result.result.content) if exists('content.Data') - call LanguageClient#textDocument_hover() + call s:hover() endif endif endfunction @@ -320,12 +422,8 @@ function! fsharp#showTooltip() call s:signature(expand('%:p'), line('.') - 1, col('.') - 1, function("s:callback_showTooltip")) endfunction -let s:script_root_dir = expand('<sfile>:p:h') . "/../" -let s:fsac = fnamemodify(s:script_root_dir . "fsac/fsautocomplete.dll", ":p") -let g:fsharp#languageserver_command = - \ ['dotnet', s:fsac, - \ '--background-service-enabled' - \ ] + +" FSAC update utils function! s:update_win() echom "[FSAC] Downloading FSAC. This may take a while..." @@ -357,6 +455,9 @@ function! fsharp#updateFSAC(...) endif endfunction + +" FSI integration + let s:fsi_buffer = -1 let s:fsi_job = -1 let s:fsi_width = 0 @@ -385,7 +486,6 @@ endfunction function! fsharp#openFsi(returnFocus) if bufwinid(s:fsi_buffer) <= 0 let fsi_command = s:get_fsi_command() - " Neovim if exists('*termopen') || exists('*term_start') let current_win = win_getid() execute g:fsharp#fsi_window_command @@ -429,7 +529,7 @@ function! fsharp#openFsi(returnFocus) if a:returnFocus | call s:win_gotoid_safe(current_win) | endif return s:fsi_buffer else - echom "[FSAC] Your Vim does not support terminal". + echom "[FSAC] Your (neo)vim does not support terminal". return 0 endif endif @@ -517,6 +617,7 @@ function! fsharp#sendAllToFsi() return fsharp#sendFsi(text) endfunction + let &cpo = s:cpo_save unlet s:cpo_save |