summaryrefslogtreecommitdiffstats
path: root/autoload/fsharp.vim
diff options
context:
space:
mode:
authorAdam Stankiewicz <sheerun@sher.pl>2021-07-28 17:54:35 +0200
committerAdam Stankiewicz <sheerun@sher.pl>2021-07-28 17:54:35 +0200
commitce31cd1d2f4e8eee9fd91325e4599f15cb9566fd (patch)
tree2306b79bdae6846233214734753be86ca6a13d7f /autoload/fsharp.vim
parent554a6ac7575f87b5b85d1b2bf60e7071c4164cbc (diff)
downloadvim-polyglot-ce31cd1d2f4e8eee9fd91325e4599f15cb9566fd.tar.gz
vim-polyglot-ce31cd1d2f4e8eee9fd91325e4599f15cb9566fd.zip
Update
Diffstat (limited to 'autoload/fsharp.vim')
-rw-r--r--autoload/fsharp.vim171
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