-
Notifications
You must be signed in to change notification settings - Fork 166
Build command with autocomplete for .csproj files
I needed a way to make a specific .csproj instead of every project in the .sln.
So I made it so the <tab>
key should autocomplete to a .csproj.
E.g. typing :Make <tab>
will result in a menu of options, or only one option if only one .csproj was found in the search space:
:Make Content.Shared/Content.Shared.csproj
:Make
BuildChecker/BuildChecker.csproj Content.Shared/Content.Shared.csproj
Content.Server.Database/Content.Server.Database.csproj
See :help wildmenu
.
The only plugin this approach depends on is something which defines asyncdo#run(), either hauleth/asyncdo.vim or an alternative like skywind3000/asyncrun.vim which features real-time population of the QuickFix list.
~/.vim/plugin/asyncdo.vim
:
"First a generalized way to have the makeprg be called async, not just C#.
"I think I found this on ThePrimeagen YouTube channel or other YouTube video.
"Not necessary for C# but is a generalized approach to calling make Async within Vim with args.
"Display status of :AsyncDo (asyncdo#run) in status line:
let &statusline .= "%{exists('g:asyncdo')?'runing':''}"
"Make makeprg (:make) run async
command! -bang -nargs=* -complete=file Make call asyncdo#run(<bang>0, &makeprg, <f-args>)
"Make :grep run async
command! -bang -nargs=* -complete=dir Grep call asyncdo#run(
\ <bang>0,
\ { 'job': &grepprg, 'errorformat': &grepformat },
\ <f-args>)
~/.vim/ftplugin/cs.vim
:
"Reference: https://github.com/OmniSharp/omnisharp-vim/issues/386
compiler dotnet
" automatically open quickfix window after build is completed
augroup QUICKFIX_CS
autocmd!
autocmd QuickFixCmdPost [^l]* nested cwindow
autocmd QuickFixCmdPost l* nested lwindow
augroup END
~/.vim/compiler/dotnet.vim
:
if exists("current_compiler")
finish
endif
let current_compiler = "dotnet"
setlocal makeprg=dotnet\ build\ /v:q\ /property:GenerateFullPaths=true\ /clp:ErrorsOnly
setlocal errorformat=\ %#%f(%l\\\,%c):\ %m
set wildmenu
let s:omnisharp_ready=0
augroup OMNISHARP_READY
autocmd!
autocmd User OmniSharpReady let s:omnisharp_ready=1
augroup END
"Redefines earlier :Make command for .cs files.
command! -bang -nargs=* -complete=customlist,DotNetFileComplete Make call asyncdo#run(<bang>0, &makeprg, <f-args>)
"Find relevant .csproj files to populate autocomplete list
":help command-completion-custom
fun DotNetFileComplete(A,L,P)
"First try to find match from curent file's folder and search up . (cwd)
let searchdir=expand('%:.:h')
let matches=''
"If we're not relative to the cwd (e.g. in :help), don't try to search
if fnamemodify(searchdir,':p:h') !=? searchdir
let matches=split(globpath(searchdir,'*.csproj'),'\n')
while '.' !=# searchdir && empty(matches)
let searchdir=fnamemodify(searchdir,':h')
let matches=split(globpath(searchdir,'*.csproj'),'\n')
endwhile
if empty(matches)
if s:omnisharp_ready
"Query for all .csproj files associated with OmniSharp sln
let csprojs=deepcopy(OmniSharp#proc#GetJob(OmniSharp#GetHost().sln_or_dir).projects)
let matches=map(csprojs, {index, value -> fnamemodify(value['path'],':.')})
else
"Omnisharp-vim not started, try solution directory subdirectories:
let matches=split(globpath('**','*.csproj'),'\n')
endif
endif
endif
return matches
endfun
If you have many .csproj files in your .sln, then maybe setting the vertical option in :help wildmode
may help navigation.
The DotNetFileComplete
function above could use generalized refinement:
- Maybe some caching of the result/selection and any other args for a given directory in a
tempfile()
. So:Make
no args would prefer the cached choice. Such caching the argument to build to a custom directory "-o /tmp/build/bin/"