diff --git a/autoload/OmniSharp.vim b/autoload/OmniSharp.vim index 3eff7e28b..6379aeee3 100644 --- a/autoload/OmniSharp.vim +++ b/autoload/OmniSharp.vim @@ -62,6 +62,20 @@ function! OmniSharp#CompleteRunningSln(arglead, cmdline, cursorpos) abort return filter(jobs, {_,job -> job =~? a:arglead}) endfunction +function! OmniSharp#CompleteOtherRunningSlnOrDirCoveringCurrentFile(arglead, cmdline, cursorpos) abort + let slnsOrDirsCoveringCurrentFile = [] + let filePath = fnamemodify(expand('%'), ':p') + let currentlyAssignedJob = get(OmniSharp#GetHost(), 'sln_or_dir') + for runningJob in filter(OmniSharp#proc#ListRunningJobs(), {_,x -> x != currentlyAssignedJob}) + for runningJobProjectPath in map(copy(OmniSharp#proc#GetJob(runningJob).projects), "fnamemodify(v:val.path, ':p:h')") + if stridx(filePath, runningJobProjectPath) == 0 + call add(slnsOrDirsCoveringCurrentFile, runningJob) + break + endif + endfor + endfor + return filter(slnsOrDirsCoveringCurrentFile, {_,sln_or_dir -> sln_or_dir =~? a:arglead}) +endfunction function! OmniSharp#IsAnyServerRunning() abort return !empty(OmniSharp#proc#ListRunningJobs()) @@ -106,10 +120,13 @@ endfunction function! OmniSharp#FindSolutionOrDir(...) abort let interactive = a:0 ? a:1 : 1 let bufnr = a:0 > 1 ? a:2 : bufnr('%') - if empty(getbufvar(bufnr, 'OmniSharp_buf_server')) + let cache = getbufvar(bufnr, 'OmniSharp_buf_server') + if empty(cache) || index(OmniSharp#proc#ListJobs(), cache) < 0 try let sln = s:FindSolution(interactive, bufnr) + if sln != cache call setbufvar(bufnr, 'OmniSharp_buf_server', sln) + endif catch return '' endtry @@ -245,13 +262,17 @@ function! OmniSharp#RestartAllServers() abort endfor endfunction +function! OmniSharp#PickRunningServer(server) abort + let host = get(b:, 'OmniSharp_host', {}) + let host.sln_or_dir = a:server +endfunction function! s:FindSolution(interactive, bufnr) abort - let solution_files = s:FindSolutionsFiles(a:bufnr) - if empty(solution_files) - " This file has no parent solution, so check for running solutions - return s:FindRunningServerForBuffer(a:bufnr) + let running_server_for_buffer = s:FindRunningServerForBuffer(a:bufnr) + if !empty(running_server_for_buffer) + return running_server_for_buffer endif + let solution_files = s:FindSolutionsFiles(a:bufnr) if len(solution_files) == 1 return solution_files[0] diff --git a/autoload/OmniSharp/actions/workspace.vim b/autoload/OmniSharp/actions/workspace.vim index 4cad4ae21..8bd5b4bfa 100644 --- a/autoload/OmniSharp/actions/workspace.vim +++ b/autoload/OmniSharp/actions/workspace.vim @@ -30,6 +30,41 @@ function! s:ProjectsRH(job, response) abort call OmniSharp#log#Log(a:job, 'Workspace complete: no projects') call OmniSharp#project#RegisterLoaded(a:job) endif + + let projectFolders = map(copy(projects), {_,p -> fnamemodify(p.path, ':p:h') }) + for i in filter(range(1, bufnr('$')), {_,x -> bufexists(x) && !empty(getbufvar(x, "OmniSharp_host")) && getbufvar(x, "OmniSharp_host").sln_or_dir != a:job.sln_or_dir}) + let host = getbufvar(i, "OmniSharp_host") + let filePath = fnamemodify(bufname(i), ':p') + for projectFolder in projectFolders + if stridx(filePath, projectFolder) == 0 + let host.sln_or_dir = a:job.sln_or_dir + break + endif + endfor + endfor + + if a:job.sln_or_dir =~ '\.sln$' && get(g:, 'OmniSharp_stop_redundant_servers', 1) + for runningJob in OmniSharp#proc#ListRunningJobs() + let isCompletelyCoveredByNewestSolution = 1 + let runningJobProjectsPaths = map(copy(OmniSharp#proc#GetJob(runningJob).projects), "fnamemodify(v:val.path, ':p:h')") + for i in range(len(runningJobProjectsPaths)) + let isProjectCoveredByNewestSolution = 0 + for j in range(len(projects)) + if runningJobProjectsPaths[i] == projects[j].path + let isProjectCoveredByNewestSolution = 1 + break + endif + endfor + if !isProjectCoveredByNewestSolution + let isCompletelyCoveredByNewestSolution = 0 + break + endif + endfor + if isCompletelyCoveredByNewestSolution + call OmniSharp#StopServer(runningJob) + endif + endfor + endif endfunction let &cpoptions = s:save_cpo diff --git a/ftplugin/cs/OmniSharp.vim b/ftplugin/cs/OmniSharp.vim index 404a2a982..85203f189 100644 --- a/ftplugin/cs/OmniSharp.vim +++ b/ftplugin/cs/OmniSharp.vim @@ -25,6 +25,7 @@ command! -buffer -bar OmniSharpRestartServer call OmniSharp#RestartServer() command! -buffer -bar -nargs=? -complete=file OmniSharpStartServer call OmniSharp#StartServer() command! -buffer -bar OmniSharpStopAllServers call OmniSharp#StopAllServers() command! -buffer -bar -nargs=? -bang -complete=customlist,OmniSharp#CompleteRunningSln OmniSharpStopServer call OmniSharp#StopServer(0, ) +command! -buffer -bar -nargs=? -complete=customlist,OmniSharp#CompleteOtherRunningSlnOrDirCoveringCurrentFile OmniSharpPickRunningServer call OmniSharp#PickRunningServer() command! -buffer -bar OmniSharpCodeFormat call OmniSharp#actions#format#Format() command! -buffer -bar OmniSharpDocumentation call OmniSharp#actions#documentation#Documentation() @@ -68,6 +69,7 @@ nnoremap (omnisharp_go_to_definition) :OmniSharpGotoDefinition (omnisharp_highlight) :OmniSharpHighlight nnoremap (omnisharp_navigate_up) :OmniSharpNavigateUp nnoremap (omnisharp_navigate_down) :OmniSharpNavigateDown +nnoremap (omnisharp_pick_running_server) :OmniSharpPickRunningServer nnoremap (omnisharp_preview_definition) :OmniSharpPreviewDefinition nnoremap (omnisharp_preview_implementation) :OmniSharpPreviewImplementation nnoremap (omnisharp_rename) :OmniSharpRename @@ -114,6 +116,7 @@ let b:undo_ftplugin .= ' \| delcommand OmniSharpHighlightTypes \| delcommand OmniSharpNavigateUp \| delcommand OmniSharpNavigateDown +\| delcommand OmniSharpPickRunningServer \| delcommand OmniSharpPreviewDefinition \| delcommand OmniSharpPreviewImplementation \| delcommand OmniSharpRename diff --git a/plugin/OmniSharp.vim b/plugin/OmniSharp.vim index 2e1d84ba9..bb7751bfd 100644 --- a/plugin/OmniSharp.vim +++ b/plugin/OmniSharp.vim @@ -46,6 +46,8 @@ let g:OmniSharp_completion_without_overloads = get(g:, 'OmniSharp_completion_wit let g:omnicomplete_fetch_full_documentation = get(g:, 'omnicomplete_fetch_full_documentation', 1) +let g:OmniSharp_stop_redundant_servers = get(g:, 'OmniSharp_stop_redundant_servers', 1) + command! -bar -nargs=? OmniSharpInstall call OmniSharp#Install() command! -bar -nargs=? OmniSharpOpenLog call OmniSharp#log#Open() command! -bar -bang OmniSharpStatus call OmniSharp#Status(0)