Skip to content

Commit 40bda48

Browse files
authored
Merge pull request #416 from renkun-ken/def-path
Definition provider works with file path
2 parents 11add3a + e0620c9 commit 40bda48

8 files changed

Lines changed: 85 additions & 11 deletions

File tree

.github/workflows/coverage.yml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,36 @@ name: coverage
33
on: [push, pull_request]
44

55
jobs:
6-
macos:
6+
linux:
77
if: contains(github.event.head_commit.message, '[ci skip]') == false
88
strategy:
99
matrix:
1010
r: [latest]
1111
# r: [3.5, 3.6, devel]
12-
runs-on: macos-latest
12+
runs-on: ubuntu-latest
13+
container: rocker/tidyverse:${{ matrix.r }}
1314
env:
1415
NOT_CRAN: true
1516
R_LANGSVR_LOG: /tmp/languageserver/coverage-log
1617
R_LANGSVR_POOL_SIZE: 1
1718
R_LANGSVR_TEST_FAST: NO
1819
steps:
1920
- uses: actions/checkout@v1
20-
- uses: r-lib/actions/setup-r@v1
21-
with:
22-
r-version: ${{ matrix.r }}
23-
- name: Install languagesever
21+
- name: Install apt-get dependencies
22+
run: |
23+
apt-get update
24+
apt-get install git ssh curl bzip2 libffi-dev -y
25+
- name: Install packages
2426
run: |
25-
Rscript -e "install.packages(c('remotes'), repos = 'https://cloud.r-project.org')"
27+
Rscript -e "install.packages(c('remotes','covr'), repos = 'https://cloud.r-project.org')"
2628
Rscript -e "remotes::install_deps(dependencies = TRUE)"
2729
Rscript -e "remotes::install_local()"
2830
- name: Codecov
2931
run: |
3032
mkdir -p /tmp/languageserver
3133
Rscript -e "covr::codecov(quiet = FALSE, clean = FALSE)"
34+
shell:
35+
bash
3236
env:
3337
CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
3438
- uses: actions/upload-artifact@v1

R/definition.R

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ definition_xpath <- paste(
1212
#' writes the function definition to a temporary file and returns that
1313
#' as the location.
1414
#' @keywords internal
15-
definition_reply <- function(id, uri, workspace, document, point) {
15+
definition_reply <- function(id, uri, workspace, document, point, rootPath) {
1616

1717
token_result <- document$detect_token(point)
1818
resolved <- FALSE
@@ -56,6 +56,29 @@ definition_reply <- function(id, uri, workspace, document, point) {
5656
resolved <- TRUE
5757
}
5858
}
59+
} else if (token_name == "STR_CONST") {
60+
str_line1 <- as.integer(xml_attr(token, "line1"))
61+
str_line2 <- as.integer(xml_attr(token, "line2"))
62+
if (str_line1 == str_line2) {
63+
str_col1 <- as.integer(xml_attr(token, "col1"))
64+
str_col2 <- as.integer(xml_attr(token, "col2"))
65+
str_expr <- substr(document$content[str_line1], str_col1, str_col2)
66+
str_text <- tryCatch(as.character(parse(text = str_expr, keep.source = FALSE)),
67+
error = function(e) NULL)
68+
if (is.character(str_text)) {
69+
path <- fs::path_abs(str_text, rootPath)
70+
if (file.exists(path) && !dir.exists(path) && is_text_file(path)) {
71+
result <- list(
72+
uri = path_to_uri(path),
73+
range = range(
74+
start = position(0, 0),
75+
end = position(0, 0)
76+
)
77+
)
78+
}
79+
}
80+
}
81+
resolved <- TRUE
5982
} else {
6083
resolved <- TRUE
6184
}

R/handlers-langfeatures.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ text_document_definition <- function(self, id, params) {
5555
uri <- uri_escape_unicode(textDocument$uri)
5656
document <- self$workspace$documents$get(uri)
5757
point <- document$from_lsp_position(params$position)
58-
self$deliver(definition_reply(id, uri, self$workspace, document, point))
58+
rootPath <- if (length(self$rootPath)) self$rootPath else dirname(path_from_uri(uri))
59+
self$deliver(definition_reply(id, uri, self$workspace, document, point, rootPath))
5960
}
6061

6162
#' `textDocument/typeDefinition` request handler

R/link.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#' The response to a textDocument/documentLink Request
2-
#'
2+
#' @param rootPath Path of workspace folder
33
#' @keywords internal
44
document_link_reply <- function(id, uri, workspace, document, rootPath) {
55
result <- NULL

R/utils.R

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,3 +688,18 @@ format_file_size <- function(bytes) {
688688
obj_size <- structure(bytes, class = "object_size")
689689
format(obj_size, units = "auto")
690690
}
691+
692+
is_text_file <- function(path, n = 1000) {
693+
bin <- readBin(path, "raw", n = n)
694+
is_utf8 <- stringi::stri_enc_isutf8(bin)
695+
if (is_utf8) {
696+
return(TRUE)
697+
} else {
698+
result <- stringi::stri_enc_detect(bin)[[1]]
699+
conf <- result$Confidence[1]
700+
if (identical(conf, 1)) {
701+
return(TRUE)
702+
}
703+
}
704+
return(FALSE)
705+
}

man/definition_reply.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/document_link_reply.Rd

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-definition.R

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,31 @@ test_that("Go to Definition in Rmarkdown works", {
261261

262262
expect_equal(length(result), 0)
263263
})
264+
265+
test_that("Go to Definition works for file paths", {
266+
skip_on_cran()
267+
268+
dir <- tempdir()
269+
client <- language_client(dir)
270+
271+
defn_file <- withr::local_tempfile(tmpdir = dir, fileext = ".R")
272+
query_file <- withr::local_tempfile(tmpdir = dir, fileext = ".R")
273+
274+
defn_file <- format(fs::path(defn_file))
275+
query_file <- format(fs::path(query_file))
276+
277+
writeLines(c("my_fn <- function(x) {", " x + 1", "}"), defn_file)
278+
writeLines(c(
279+
sprintf("source('%s')", defn_file),
280+
sprintf("source('%s')", basename(defn_file))
281+
), query_file)
282+
283+
client %>% did_save(defn_file)
284+
client %>% did_save(query_file)
285+
286+
result <- client %>% respond_definition(query_file, c(0, 9))
287+
expect_equal(result$uri, path_to_uri(defn_file))
288+
289+
result <- client %>% respond_definition(query_file, c(1, 9))
290+
expect_equal(result$uri, path_to_uri(defn_file))
291+
})

0 commit comments

Comments
 (0)