Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions autoload/lsp/symbol.vim
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ export def WorkspaceSymbolPopup(lspserver: dict<any>, query: string,
endif

# interface SymbolInformation
fileName = util.LspUriToFile(symbol.location.uri)
fileName = util.LspUriToRealFile(symbol.location.uri, lspserver)

symName = symbol.name
if symbol->has_key('containerName') && symbol.containerName != ''
Expand Down Expand Up @@ -291,7 +291,7 @@ def UpdatePeekFilePopup(lspserver: dict<any>, locations: list<dict<any>>)

var n = line('.', lspserver.peekSymbolPopup) - 1
var [uri, range] = util.LspLocationParse(locations[n])
var fname: string = util.LspUriToFile(uri)
var fname: string = util.LspUriToRealFile(uri, lspserver)

var bnr: number = fname->bufnr()
if bnr == -1
Expand Down Expand Up @@ -374,7 +374,7 @@ def PeekLocations(lspserver: dict<any>, locations: list<dict<any>>,
var menuItems: list<string> = []
for loc in locations
var [uri, range] = util.LspLocationParse(loc)
var fname: string = util.LspUriToFile(uri)
var fname: string = util.LspUriToRealFile(uri, lspserver)
var bnr: number = fname->bufnr()
if bnr == -1
bnr = fname->bufadd()
Expand Down Expand Up @@ -426,7 +426,7 @@ export def ShowLocations(lspserver: dict<any>, locations: list<dict<any>>,
var qflist: list<dict<any>> = []
for loc in locations
var [uri, range] = util.LspLocationParse(loc)
var fname: string = util.LspUriToFile(uri)
var fname: string = util.LspUriToRealFile(uri, lspserver)
var bnr: number = fname->bufnr()
if bnr == -1
bnr = fname->bufadd()
Expand Down Expand Up @@ -489,7 +489,7 @@ enddef
# highlight the range in "location".
def PeekSymbolLocation(lspserver: dict<any>, location: dict<any>)
var [uri, range] = util.LspLocationParse(location)
var fname = util.LspUriToFile(uri)
var fname = util.LspUriToRealFile(uri, lspserver)
var bnum = fname->bufadd()
if bnum == 0
# Failed to create or find a buffer
Expand Down Expand Up @@ -547,7 +547,7 @@ export def GotoSymbol(lspserver: dict<any>, location: dict<any>,
else
# Save the current cursor location in the tag stack.
util.PushCursorToTagStack()
util.JumpToLspLocation(location, cmdmods)
util.JumpToLspLocation(location, cmdmods, lspserver)
endif
enddef

Expand All @@ -563,7 +563,7 @@ export def TagFunc(lspserver: dict<any>,
tagitem.name = pat

var [uri, range] = util.LspLocationParse(tagloc)
tagitem.filename = util.LspUriToFile(uri)
tagitem.filename = util.LspUriToRealFile(uri, lspserver)
var bnr = util.LspUriToBufnr(uri)
var rstart = range.start
var startByteIdx = util.GetLineByteFromPos(bnr, rstart)
Expand Down Expand Up @@ -592,7 +592,7 @@ def ProcessSymbolInfoTable(lspserver: dict<any>,
var symInfo: dict<any>

for syminfo in symbolInfoTable
fname = util.LspUriToFile(syminfo.location.uri)
fname = util.LspUriToRealFile(syminfo.location.uri, lspserver)
symbolType = SymbolKindToName(syminfo.kind)
name = syminfo.name
if syminfo->has_key('containerName')
Expand Down
55 changes: 51 additions & 4 deletions autoload/lsp/util.vim
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ export def LspUriToFile(uri: string): string
# Replace all the %xx numbers (e.g. %20 for space) in the URI to character
var uri_decoded: string = UriDecode(uri)

# csharp:/... is a virtual document URI; leave it alone here so callers can
# materialize it through the server before opening a real buffer.
if uri_decoded =~# '^csharp:'
return uri_decoded
endif

# File URIs on MS-Windows start with file:///[a-zA-Z]:'
if uri_decoded =~? '^file:///\a:'
# MS-Windows URI
Expand All @@ -175,11 +181,51 @@ export def LspUriToFile(uri: string): string
return uri_decoded
enddef

var csharpMetadataCache: dict<string> = {}

# csharp-ls emits virtual document URIs like:
# csharp:/.../decompiled/RimWorld.Plant.cs
# Those must be materialized with the csharp/metadata request before Vim can
# open them as a regular file.
export def LspUriToRealFile(uri: string, lspserver: dict<any> = {}): string
var file = LspUriToFile(uri)
if uri !~# '^csharp:'
return file
endif

if csharpMetadataCache->has_key(uri)
return csharpMetadataCache[uri]
endif
if lspserver->empty()
return file
endif

var response = lspserver.rpc('csharp/metadata',
{textDocument: {uri: uri}},
{handleError: false})
if response->empty() || !response->has_key('result')
return file
endif

var metadata = response.result
if metadata->type() != v:t_dict || !metadata->has_key('source')
return file
endif

var path = tempname() .. '.cs'
if writefile(metadata.source->split("\n", true), path) != 0
return file
endif

csharpMetadataCache[uri] = path
return path
enddef

# Convert a LSP file URI (file://<absolute_path>) to a Vim buffer number.
# If the file is not in a Vim buffer, then adds the buffer.
# Returns 0 on error.
export def LspUriToBufnr(uri: string): number
return LspUriToFile(uri)->bufadd()
export def LspUriToBufnr(uri: string, lspserver: dict<any> = {}): number
return LspUriToRealFile(uri, lspserver)->bufadd()
enddef

# Returns if the URI refers to a remote file (e.g. ssh://)
Expand Down Expand Up @@ -337,9 +383,10 @@ enddef
# Jump to the LSP "location". The "location" contains the file name, line
# number and character number. The user specified window command modifiers
# (e.g. topleft) are in "cmdmods".
export def JumpToLspLocation(location: dict<any>, cmdmods: string)
export def JumpToLspLocation(location: dict<any>, cmdmods: string,
lspserver: dict<any> = {})
var [uri, range] = LspLocationParse(location)
var fname = LspUriToFile(uri)
var fname = LspUriToRealFile(uri, lspserver)

# jump to the file and line containing the symbol
var bnr: number = fname->bufnr()
Expand Down