Skip to content

Commit 70425f1

Browse files
authored
Merge pull request #680 from nickspoons/extend-scriptability
Extend scriptability
2 parents 7fd9615 + 6d99a0c commit 70425f1

21 files changed

+391
-233
lines changed

autoload/OmniSharp/actions/codeactions.vim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ set cpoptions&vim
2121
" \ 'CallbackCount': function('PlaceSign')
2222
" \}
2323
function! OmniSharp#actions#codeactions#Count(...) abort
24-
let opts = a:0 && a:1 isnot 0 ? { 'Callback': a:1 } : {}
2524
if a:0 && type(a:1) == type(function('tr'))
2625
let opts = { 'CallbackCleanup': a:1 }
2726
elseif a:0 && type(a:1) == type({})
2827
let opts = a:1
28+
else
29+
let opts = {}
2930
endif
3031
if g:OmniSharp_server_stdio
3132
let Callback = function('s:CBCountCodeActions', [opts])

autoload/OmniSharp/actions/definition.vim

Lines changed: 80 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,45 @@
11
let s:save_cpo = &cpoptions
22
set cpoptions&vim
33

4-
" Accepts a Funcref callback argument, to be called after the response is
5-
" returned (synchronously or asynchronously) with a boolean 'found' result
4+
" Navigate to the definition of the symbol under the cursor.
5+
" Optional arguments:
6+
" Callback: When a callback is passed in, it is called after the response is
7+
" returned (synchronously or asynchronously) with the found
8+
" location and a flag for whether it is in a file in the project or
9+
" from the metadata. This is done instead of navigating to the found
10+
" location.
11+
" editcommand: The command to use to open buffers, e.g. 'split', 'vsplit',
12+
" 'tabedit' or 'edit' (default).
613
function! OmniSharp#actions#definition#Find(...) abort
7-
let opts = a:0 && a:1 isnot 0 ? { 'Callback': a:1 } : {}
8-
if g:OmniSharp_server_stdio
14+
if a:0 && type(a:1) == type(function('tr'))
15+
let Callback = a:1
16+
else
17+
let opts = { 'editcommand': 'edit' }
18+
if a:0 && type(a:1) == type('') && a:1 !=# ''
19+
let opts.editcommand = a:1
20+
endif
921
let Callback = function('s:CBGotoDefinition', [opts])
22+
endif
23+
24+
if g:OmniSharp_server_stdio
1025
call s:StdioFind(Callback)
1126
else
1227
let loc = OmniSharp#py#Eval('gotoDefinition()')
1328
if OmniSharp#py#CheckForError() | return 0 | endif
14-
" Mock metadata info for old server based setups
15-
return s:CBGotoDefinition(opts, loc, { 'MetadataSource': {}})
29+
" We never come from metadata here
30+
return Callback(loc, 0)
1631
endif
1732
endfunction
1833

19-
function! OmniSharp#actions#definition#Preview(...) abort
20-
let opts = a:0 && a:1 isnot 0 ? { 'Callback': a:1 } : {}
34+
function! OmniSharp#actions#definition#Preview() abort
2135
if g:OmniSharp_server_stdio
22-
let Callback = function('s:CBPreviewDefinition', [opts])
36+
let Callback = function('s:CBPreviewDefinition')
2337
call s:StdioFind(Callback)
2438
else
2539
let loc = OmniSharp#py#Eval('gotoDefinition()')
2640
if OmniSharp#py#CheckForError() | return 0 | endif
27-
call s:CBPreviewDefinition({}, loc, {})
41+
" We never come from metadata here
42+
call s:CBPreviewDefinition(loc, 0)
2843
endif
2944
endfunction
3045

@@ -42,45 +57,74 @@ function! s:StdioFindRH(Callback, response) abort
4257
if !a:response.Success | return | endif
4358
let body = a:response.Body
4459
if type(body) == type({}) && get(body, 'FileName', v:null) != v:null
45-
call a:Callback(OmniSharp#locations#Parse([body])[0], body)
60+
call a:Callback(OmniSharp#locations#Parse([body])[0], 0)
4661
else
47-
call a:Callback(0, body)
62+
if g:OmniSharp_lookup_metadata
63+
\ && type(body) == type({})
64+
\ && type(body.MetadataSource) == type({})
65+
let Callback = function('s:CBMetadataFind', [a:Callback])
66+
call s:StdioMetadataFind(Callback, body)
67+
else
68+
call a:Callback(0, 1)
69+
endif
4870
endif
4971
endfunction
5072

51-
function! s:CBGotoDefinition(opts, location, metadata) abort
52-
let went_to_metadata = 0
73+
function! s:StdioMetadataFind(Callback, metadata) abort
74+
let opts = {
75+
\ 'ResponseHandler': function('s:StdioMetadataFindRH', [a:Callback, a:metadata]),
76+
\ 'Parameters': a:metadata.MetadataSource
77+
\}
78+
call OmniSharp#stdio#Request('/metadata', opts)
79+
endfunction
80+
81+
function! s:StdioMetadataFindRH(Callback, metadata, response) abort
82+
if !a:response.Success || a:response.Body.Source == v:null | return 0 | endif
83+
call a:Callback(a:response.Body, a:metadata)
84+
endfunction
85+
86+
function! s:CBMetadataFind(Callback, response, metadata) abort
87+
let host = OmniSharp#GetHost()
88+
let metadata_filename = fnamemodify(
89+
\ OmniSharp#util#TranslatePathForClient(a:response.SourceName), ':t')
90+
let temp_file = OmniSharp#util#TempDir() . '/' . metadata_filename
91+
let lines = split(a:response.Source, "\n", 1)
92+
let lines = map(lines, {i,v -> substitute(v, '\r', '', 'g')})
93+
call writefile(lines, temp_file, 'b')
94+
let bufnr = bufadd(temp_file)
95+
call setbufvar(bufnr, 'OmniSharp_host', host)
96+
call setbufvar(bufnr, 'OmniSharp_metadata_filename', a:response.SourceName)
97+
let location = {
98+
\ 'filename': temp_file,
99+
\ 'lnum': a:metadata.Line,
100+
\ 'col': a:metadata.Column
101+
\}
102+
call a:Callback(location, 1)
103+
endfunction
104+
105+
function! s:CBGotoDefinition(opts, location, fromMetadata) abort
53106
if type(a:location) != type({}) " Check whether a dict was returned
54-
if g:OmniSharp_lookup_metadata
55-
\ && type(a:metadata) == type({})
56-
\ && type(a:metadata.MetadataSource) == type({})
57-
let found = OmniSharp#actions#metadata#Find(0, a:metadata, a:opts)
58-
let went_to_metadata = 1
59-
else
60-
echo 'Not found'
61-
let found = 0
62-
endif
107+
echo 'Not found'
108+
let found = 0
63109
else
64-
let found = OmniSharp#locations#Navigate(a:location, 0)
65-
endif
66-
if has_key(a:opts, 'Callback') && !went_to_metadata
67-
call a:opts.Callback(found)
110+
let found = OmniSharp#locations#Navigate(a:location, get(a:opts, 'editcommand', 'edit'))
111+
if found && a:fromMetadata
112+
setlocal nomodifiable readonly
113+
endif
68114
endif
69115
return found
70116
endfunction
71117

72-
function! s:CBPreviewDefinition(opts, location, metadata) abort
118+
function! s:CBPreviewDefinition(location, fromMetadata) abort
73119
if type(a:location) != type({}) " Check whether a dict was returned
74-
if g:OmniSharp_lookup_metadata
75-
\ && type(a:metadata) == type({})
76-
\ && type(a:metadata.MetadataSource) == type({})
77-
let found = OmniSharp#actions#metadata#Find(1, a:metadata, a:opts)
78-
else
79-
echo 'Not found'
80-
endif
120+
echo 'Not found'
81121
else
122+
let jumped_from_preview = &previewwindow
82123
call OmniSharp#locations#Preview(a:location)
83-
echo fnamemodify(a:location.filename, ':.')
124+
echo OmniSharp#locations#Modify(a:location).filename
125+
if a:fromMetadata && !jumped_from_preview && &previewwindow
126+
silent wincmd p
127+
endif
84128
endif
85129
endfunction
86130

autoload/OmniSharp/actions/implementations.vim

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@ let s:save_cpo = &cpoptions
22
set cpoptions&vim
33

44
" Accepts a Funcref callback argument, to be called after the response is
5-
" returned (synchronously or asynchronously) with the number of implementations
5+
" returned (synchronously or asynchronously) with the list of found locations.
6+
" This is done instead of navigating to them or showing a quick-fix.
67
function! OmniSharp#actions#implementations#Find(...) abort
7-
let opts = a:0 && a:1 isnot 0 ? { 'Callback': a:1 } : {}
8-
let target = expand('<cword>')
8+
if a:0 && a:1 isnot 0
9+
let Callback = a:1
10+
else
11+
let target = expand('<cword>')
12+
let Callback = function('s:CBFindImplementations', [target])
13+
endif
14+
915
if g:OmniSharp_server_stdio
10-
let Callback = function('s:CBFindImplementations', [target, opts])
1116
call s:StdioFind(Callback)
1217
else
1318
let locs = OmniSharp#py#Eval('findImplementations()')
1419
if OmniSharp#py#CheckForError() | return | endif
15-
return s:CBFindImplementations(target, opts, locs)
20+
return Callback(locs)
1621
endif
1722
endfunction
1823

@@ -44,33 +49,31 @@ function! s:StdioFindRH(Callback, response) abort
4449
endif
4550
endfunction
4651

47-
function! s:CBFindImplementations(target, opts, locations) abort
52+
function! s:CBFindImplementations(target, locations) abort
4853
let numImplementations = len(a:locations)
4954
if numImplementations == 0
5055
echo 'No implementations found'
5156
elseif numImplementations == 1
52-
call OmniSharp#locations#Navigate(a:locations[0], 0)
57+
call OmniSharp#locations#Navigate(a:locations[0])
5358
else " numImplementations > 1
54-
call OmniSharp#locations#SetQuickfix(a:locations,
59+
let locations = OmniSharp#locations#Modify(a:locations)
60+
call OmniSharp#locations#SetQuickfix(locations,
5561
\ 'Implementations: ' . a:target)
5662
endif
57-
if has_key(a:opts, 'Callback')
58-
call a:opts.Callback(numImplementations)
59-
endif
6063
return numImplementations
6164
endfunction
6265

63-
function! s:CBPreviewImplementation(locs, ...) abort
64-
let numImplementations = len(a:locs)
66+
function! s:CBPreviewImplementation(locations, ...) abort
67+
let numImplementations = len(a:locations)
6568
if numImplementations == 0
6669
echo 'No implementations found'
6770
else
68-
call OmniSharp#locations#Preview(a:locs[0])
69-
let fname = fnamemodify(a:locs[0].filename, ':.')
71+
call OmniSharp#locations#Preview(a:locations[0])
72+
let filename = OmniSharp#locations#Modify(a:locations[0]).filename
7073
if numImplementations == 1
71-
echo fname
74+
echo filename
7275
else
73-
echo fname . ': Implementation 1 of ' . numImplementations
76+
echo filename . ': Implementation 1 of ' . numImplementations
7477
endif
7578
endif
7679
endfunction

autoload/OmniSharp/actions/members.vim

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,22 @@ let s:save_cpo = &cpoptions
22
set cpoptions&vim
33

44
" Accepts a Funcref callback argument, to be called after the response is
5-
" returned (synchronously or asynchronously) with the number of members
5+
" returned (synchronously or asynchronously) with the list of found locations
6+
" of members.
7+
" This is done instead of showing a quick-fix.
68
function! OmniSharp#actions#members#Find(...) abort
7-
let opts = a:0 && a:1 isnot 0 ? { 'Callback': a:1 } : {}
9+
if a:0 && a:1 isnot 0
10+
let Callback = a:1
11+
else
12+
let Callback = function('s:CBFindMembers')
13+
endif
14+
815
if g:OmniSharp_server_stdio
9-
call s:StdioFind(function('s:CBFindMembers', [opts]))
16+
call s:StdioFind(Callback)
1017
else
1118
let locs = OmniSharp#py#Eval('findMembers()')
1219
if OmniSharp#py#CheckForError() | return | endif
13-
return s:CBFindMembers(opts, locs)
20+
return Callback(locs)
1421
endif
1522
endfunction
1623

@@ -83,14 +90,11 @@ function! ReduceToOneCharacter(textBeforeDisplayName) abort
8390
return s:SingleCharacterSymbolByAccessModifier[accessModifier] . a:textBeforeDisplayName[accessModifierLen:]
8491
endfunction
8592

86-
function! s:CBFindMembers(opts, locations) abort
93+
function! s:CBFindMembers(locations) abort
8794
let numMembers = len(a:locations)
8895
if numMembers > 0
8996
call OmniSharp#locations#SetQuickfixWithVerticalAlign(a:locations, 'Members')
9097
endif
91-
if has_key(a:opts, 'Callback')
92-
call a:opts.Callback(numMembers)
93-
endif
9498
return numMembers
9599
endfunction
96100

autoload/OmniSharp/actions/metadata.vim

Lines changed: 0 additions & 63 deletions
This file was deleted.

autoload/OmniSharp/actions/navigate.vim

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,35 @@
11
let s:save_cpo = &cpoptions
22
set cpoptions&vim
33

4-
function! OmniSharp#actions#navigate#Down() abort
5-
call s:Navigate(1)
4+
" Navigate to the next member definition in the class.
5+
" Optional arguments:
6+
" Callback: When a callback is passed in, it is called after the response is
7+
" returned with the member location. No navigation is performed when a
8+
" callback is passed in.
9+
function! OmniSharp#actions#navigate#Down(...) abort
10+
call s:Navigate(1, a:0 ? a:1 : function('OmniSharp#locations#Navigate'))
611
endfunction
712

8-
function! OmniSharp#actions#navigate#Up() abort
9-
call s:Navigate(0)
13+
" See OmniSharp#actions#navigate#Down
14+
function! OmniSharp#actions#navigate#Up(...) abort
15+
call s:Navigate(0, a:0 ? a:1 : function('OmniSharp#locations#Navigate'))
1016
endfunction
1117

12-
function! s:Navigate(down) abort
18+
function! s:Navigate(down, Callback) abort
1319
if g:OmniSharp_server_stdio
14-
let opts = {
15-
\ 'ResponseHandler': function('s:NavigateRH')
16-
\}
20+
let RH = function('s:StdioNavigateRH', [a:Callback])
21+
let opts = { 'ResponseHandler': RH }
1722
call OmniSharp#stdio#Request(a:down ? '/navigatedown' : '/navigateup', opts)
1823
else
19-
call OmniSharp#py#Eval(a:down ? 'navigateDown()' : 'navigateUp()')
20-
call OmniSharp#py#CheckForError()
24+
let loc = OmniSharp#py#Eval(a:down ? 'navigateDown()' : 'navigateUp()')
25+
if OmniSharp#py#CheckForError() | return | endif
26+
call a:Callback(loc)
2127
endif
2228
endfunction
2329

24-
function! s:NavigateRH(response) abort
30+
function! s:StdioNavigateRH(Callback, response) abort
2531
if !a:response.Success | return | endif
26-
normal! m'
27-
call cursor(a:response.Body.Line, a:response.Body.Column)
32+
call a:Callback(OmniSharp#locations#Parse([a:response.Body])[0])
2833
endfunction
2934

3035
let &cpoptions = s:save_cpo

0 commit comments

Comments
 (0)