-
Notifications
You must be signed in to change notification settings - Fork 168
Working with older .csproj Projects
Update: This functionality is now part of the vim-sharpenup plugin, which includes commands :SharpenUpAddToProject
and :SharpenUpRenameInProject <newname>
.
OmniSharp-vim does not have any notion of .csproj files, and OmniSharp-roslyn has no options for editing them. This means that adding a new file or renaming an existing one can break your project if you are using an older-style .csproj project, which lists all .cs files.
There is an open issue with OmniSharp-roslyn to alter the .csproj file, but it seems unlikely that this will be addressed, as the newer .csproj files don't need this functionality.
However, for OmniSharp-vim users stuck for the time being on older .csproj files, here are some functions which can be used to add and rename the current file in a .csproj. Please note that these are naiive and hacky functions, use at your own risk!
Put these functions in a ~/.vim/autoload/myomnisharp.vim
script (create the ~/.vim/autoload
directory if it doesn't already exist).
" ~/.vim/autoload/myomnisharp.vim
" Search from the current directory up to the solution directory for a .csproj
" file, and return the first one found. Note that this may return the wrong
" .csproj file if two .csproj files are found in the same directory.
function! s:FindProject() abort
let l:base = fnamemodify(OmniSharp#FindSolutionOrDir(), ':h')
let l:dir = expand('%:p:h')
while 1
let l:projects = split(globpath(l:dir, '*.csproj'), '\n')
if len(l:projects)
return l:projects[0]
endif
let l:parent = fnamemodify(l:dir, ':h')
if l:dir ==# l:parent || l:dir ==# l:base
echohl WarningMsg | echomsg 'Project not found' | echohl None
return ''
endif
let l:dir = l:parent
endwhile
endfunction
" Add the current file to the .csproj. The .csproj must be found in an ancestor
" directory and must already contain at least one .cs file.
function! myomnisharp#AddToProject() abort
let l:filename = expand('%:p')
let l:project = s:FindProject()
if !len(l:project) | return | endif
execute 'silent tabedit' l:project
call cursor(1, 1)
if !search('^\s*<compile include=".*\.cs"', '')
tabclose
echohl WarningMsg | echomsg 'Could not find a .cs entry' | echohl None
return
endif
normal! yypk
if fnamemodify(l:project, ':h') !=# getcwd()
execute 'lcd' fnamemodify(l:project, ':h')
endif
execute 's/".*\.cs"/"' . fnamemodify(l:filename, ':.:gs?/?\\/?') . '"/'
if g:OmniSharp_translate_cygwin_wsl || has('win32')
s?/?\\?g
s?\\>?/>?g
endif
write
tabclose
endfunction
" Find the current file in the .csproj file and rename it to a:newname.
" Do not pass in a full path - just the new filename.cs
function! myomnisharp#RenameInProject(newname) abort
let l:filepath = expand('%:p')
let l:filename = expand('%:t')
let l:project = s:FindProject()
if !len(l:project) | return | endif
execute 'silent tabedit' l:project
call cursor(1, 1)
if fnamemodify(l:project, ':h') !=# getcwd()
execute 'lcd' fnamemodify(l:project, ':h')
endif
let l:filepath = fnamemodify(l:filepath, ':.')
if g:OmniSharp_translate_cygwin_wsl || has('win32')
let l:filepath = substitute(l:filepath, '/', '\\\\', 'g')
endif
" Search for the full file path, relative to the .csproj
if !search(l:filepath, '')
" If not found, try just the file name (without the path)
if !search(fnamemodify(l:filepath, ':t'), '')
tabclose
echohl WarningMsg | echomsg 'Could not find ' . l:filepath | echohl None
return
endif
endif
execute 's/' . fnamemodify(l:filename, ':t') . '/' . a:newname . '/'
write
tabclose
endfunction
These mappings should be in a ~/.vim/after/ftplugin/cs.vim
script, or in ~/.vimrcin
autocmd FileType cs ...` autocommands like the ones in the suggested .vimrc in the README:
" ~/.vim/after/ftplugin/cs.vim
nnoremap <buffer> <Leader>add :call myomnisharp#AddToProject()<CR>
nnoremap <buffer> <Leader>ren :call myomnisharp#RenameInProject()<Left>