documentHighlight should not show references in other files

documentHighlight was highlighting symbols that were defined in other
files (incorrectly, because the response only contains ranges, not
locations), but this feature is meant for the current document only.
This commit is contained in:
Michele Campeotto 2025-03-02 09:31:29 +01:00 committed by Phil Hagelberg
parent 2c71c403d4
commit 0b979f1e78
2 changed files with 27 additions and 17 deletions

View File

@ -100,19 +100,19 @@ Every time the client sends a message, it gets handled by a function in the corr
(local documentHighlightKind {:Text 1 :Read 2 :Write 3})
(λ requests.textDocument/documentHighlight [server _send {: position
:textDocument {: uri}}]
(let [file (files.get-by-uri server uri)
byte (utils.position->byte file.text position server.position-encoding)]
(case-try (analyzer.find-symbol file.ast byte)
:textDocument {: uri}}]
(let [this-file (files.get-by-uri server uri)
byte (utils.position->byte this-file.text position server.position-encoding)]
(case-try (analyzer.find-symbol this-file.ast byte)
symbol
(analyzer.find-nearest-definition server file symbol byte)
{: referenced-by : file : binding}
(icollect [_ {: symbol} (ipairs referenced-by)
&into [{:range (message.ast->range server file binding)
:kind documentHighlightKind.Write}]]
;; TODO don't include duplicates
{:range (message.ast->range server file symbol)
:kind documentHighlightKind.Read})
(analyzer.find-nearest-definition server this-file symbol byte)
(where {: referenced-by : file : binding} (= file.uri uri))
(let [result (icollect [_ {:symbol reference} (ipairs referenced-by)]
{:range (message.ast->range server file reference)
:kind documentHighlightKind.Read})]
(table.insert result {:range (message.ast->range server file binding)
:kind documentHighlightKind.Write})
result)
(catch _ nil))))
(λ requests.textDocument/references [server _send {: position

View File

@ -22,14 +22,13 @@
(table.sort response.result range-comparator)
;; Override kind in the result because utils.parse-markup doesn't have
;; a way to express it. The ranges are more important.
(each [i v (ipairs response.result)]
(set v.kind 1)
(set (. response.result i) v))
(each [_ v (ipairs response.result)]
(set v.kind 1))
(faith.= highlights response.result
(view file-contents)))
(faith.= highlights []))))
(fn test-references []
(fn test-document-highlights []
(check "(let [==x== 10] ==x==|)")
(check "(let [==x==| 10] ==x==)")
(check "(let [==x==| 10] ==x== ==x== ==x==)")
@ -46,4 +45,15 @@
(let [x :shadowed] x))")
nil)
{: test-references}
(fn test-multiple-files []
(check
{:foo.fnl "(fn target []
nil)
{: target}"
:main.fnl "(local foo (require :foo))
(foo.targe|t)"})
nil)
{: test-document-highlights
: test-multiple-files}