Skip to content

Commit

Permalink
Use /projects endpoint as part of load process
Browse files Browse the repository at this point in the history
  • Loading branch information
nickspoons committed Jun 28, 2020
1 parent b09b00d commit de51104
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 22 deletions.
39 changes: 39 additions & 0 deletions autoload/OmniSharp/actions/workspace.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
let s:save_cpo = &cpoptions
set cpoptions&vim

let s:attempts = 0

function! OmniSharp#actions#workspace#Get(job) abort
let opts = {
\ 'ResponseHandler': function('s:ProjectsRH', [a:job]),
\ 'AllowUnloaded': 1
\}
let s:attempts += 1
call OmniSharp#stdio#RequestGlobal(a:job, '/projects', opts)
endfunction

function! s:ProjectsRH(job, response) abort
" If this request fails, retry up to 5 times
if !a:response.Success
if s:attempts < 5
call OmniSharp#actions#workspace#Get(a:job)
endif
return
endif
" If no projects have been loaded by the time this callback is reached, there
" are no projects and the job can be marked as ready
let projects = get(get(a:response.Body, 'MsBuild', {}), 'Projects', {})
let a:job.projects = map(projects,
\ {_,project -> {"name": project.AssemblyName, "path": project.Path}})
if get(a:job, 'projects_total', 0) > 0
call OmniSharp#log#Log(a:job, 'Workspace complete: ' . a:job.projects_total . ' project(s)')
else
call OmniSharp#log#Log(a:job, 'Workspace complete: no projects')
call OmniSharp#project#RegisterLoaded(a:job)
endif
endfunction

let &cpoptions = s:save_cpo
unlet s:save_cpo

" vim:et:sw=2:sts=2
46 changes: 25 additions & 21 deletions autoload/OmniSharp/project.vim
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,38 @@ function! OmniSharp#project#CountTotal() abort
return get(OmniSharp#proc#GetJob(host.sln_or_dir), 'projects_total', 0)
endfunction

function! OmniSharp#project#RegisterLoaded(job) abort
if a:job.loaded | return | endif
if g:OmniSharp_server_display_loading
let elapsed = reltimefloat(reltime(a:job.start_time))
echomsg printf('Loaded server for %s in %.1fs',
\ a:job.sln_or_dir, elapsed)
endif
let a:job.loaded = 1
silent doautocmd <nomodeline> User OmniSharpReady

" TODO: Remove this delay once we have better information about
" when the server is completely initialised:
" https://github.com/OmniSharp/omnisharp-roslyn/issues/1521
call timer_start(1000, function('OmniSharp#stdio#ReplayRequests', [a:job]))
" call OmniSharp#stdio#ReplayRequests(a:job)
endfunction

" Listen for stdio server-loaded events
function! OmniSharp#project#ParseEvent(job, event, eventBody) abort
if g:OmniSharp_server_stdio_quickload

" Quick load: Mark server as loaded as soon as configuration is finished
" Quick load: Mark server as ready as soon as configuration is finished.
" WARNING: This will _not_ result in fully functional server interaction.
if a:job.loaded | return | endif
let message = get(a:eventBody, 'Message', '')
if message ==# 'Configuration finished.'
let a:job.loaded = 1
silent doautocmd <nomodeline> User OmniSharpReady
call OmniSharp#stdio#ReplayRequests()
call OmniSharp#project#RegisterLoaded(a:job)
endif

else

" Complete load: Wait for all projects to be loaded before marking server as
" loaded
" Full load: Wait for all projects to load before marking server as ready
let projects_loaded = get(a:job, 'projects_loaded', 0)
let projects_total = get(a:job, 'projects_total', 0)
if a:job.loaded && projects_loaded == projects_total | return | endif
Expand All @@ -46,7 +61,9 @@ function! OmniSharp#project#ParseEvent(job, event, eventBody) abort
endif
let name = get(a:eventBody, 'Name', '')
let message = get(a:eventBody, 'Message', '')
if name ==# 'OmniSharp.MSBuild.ProjectManager'
if a:event ==# 'started'
call OmniSharp#actions#workspace#Get(a:job)
elseif name ==# 'OmniSharp.MSBuild.ProjectManager'
let project = matchstr(message, '''\zs.*\ze''')
if message =~# '^Queue project'
call add(a:job.loading, project)
Expand All @@ -64,20 +81,7 @@ function! OmniSharp#project#ParseEvent(job, event, eventBody) abort
let a:job.projects_loaded = projects_loaded + 1
silent doautocmd <nomodeline> User OmniSharpProjectUpdated
if len(a:job.loading) == 0
if g:OmniSharp_server_display_loading
let elapsed = reltimefloat(reltime(a:job.start_time))
echomsg printf('Loaded server for %s in %.1fs',
\ a:job.sln_or_dir, elapsed)
endif
let a:job.loaded = 1
silent doautocmd <nomodeline> User OmniSharpReady

" TODO: Remove this delay once we have better information about
" when the server is completely initialised:
" https://github.com/OmniSharp/omnisharp-roslyn/issues/1521
call timer_start(1000, function('OmniSharp#stdio#ReplayRequests'))
" call OmniSharp#stdio#ReplayRequests()

call OmniSharp#project#RegisterLoaded(a:job)
unlet a:job.loading
call timer_stop(a:job.loading_timeout)
unlet a:job.loading_timeout
Expand Down
3 changes: 2 additions & 1 deletion autoload/OmniSharp/stdio.vim
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ function! s:Request(job, body, command, opts, ...) abort
return 1
endfunction

function! OmniSharp#stdio#ReplayRequests(...) abort
function! OmniSharp#stdio#ReplayRequests(job, ...) abort
call OmniSharp#log#Log(a:job, 'Replaying requests')
for key in keys(s:pendingRequests)
call OmniSharp#stdio#Request(key, s:pendingRequests[key])
unlet s:pendingRequests[key]
Expand Down

0 comments on commit de51104

Please sign in to comment.