diff --git a/R/folding.R b/R/folding.R index 92d6185a..6d6a9e82 100644 --- a/R/folding.R +++ b/R/folding.R @@ -4,21 +4,29 @@ FoldingRangeKind <- list( Region = "region" ) -get_expr_folding_ranges <- function(xdoc) { - exprs <- xml_find_all(xdoc, "//expr[@line2 > @line1]") - if (length(exprs) == 0) { +get_block_folding_ranges <- function(xdoc) { + blocks <- xml_find_all(xdoc, "//expr[@line1 < @line2 and + (OP-LEFT-PAREN | OP-LEFT-BRACKET | OP-LEFT-BRACE)/@line1 < + (OP-RIGHT-PAREN | OP-RIGHT-BRACKET | OP-RIGHT-BRACE)/@line1]" + ) + if (length(blocks) == 0) { return(NULL) } - expr_line1 <- as.integer(xml_attr(exprs, "line1")) - expr_line2 <- as.integer(xml_attr(exprs, "line2")) - expr_folding_ranges <- .mapply(function(line1, line2) { + + block_start <- xml_find_first(blocks, "OP-LEFT-PAREN | OP-LEFT-BRACKET | OP-LEFT-BRACE") + block_end <- xml_find_first(blocks, "OP-RIGHT-PAREN | OP-RIGHT-BRACKET | OP-RIGHT-BRACE") + + block_start_line <- as.integer(xml_attr(block_start, "line1")) + block_end_line <- as.integer(xml_attr(block_end, "line1")) + + block_folding_ranges <- .mapply(function(start_line, end_line) { list( - startLine = line1 - 1, - endLine = line2 - 1, + startLine = start_line - 1, + endLine = end_line - 2, kind = FoldingRangeKind$Region ) - }, list(expr_line1, expr_line2), NULL) - expr_folding_ranges + }, list(block_start_line, block_end_line), NULL) + block_folding_ranges } get_comment_folding_ranges <- function(xdoc) { @@ -56,7 +64,7 @@ get_comment_folding_ranges <- function(xdoc) { comm_folding_ranges } -get_document_section_folding_ranges <- function(uri, document) { +get_section_folding_ranges <- function(uri, document) { sections <- get_document_sections(uri, document, type = c("section", "chunk")) if (length(sections) == 0) { return(NULL) @@ -85,12 +93,12 @@ document_folding_range_reply <- function(id, uri, workspace, document) { xdoc <- parse_data$xml_doc if (!is.null(xdoc)) { result <- c(result, - get_expr_folding_ranges(xdoc), + get_block_folding_ranges(xdoc), get_comment_folding_ranges(xdoc) ) } - result <- c(result, get_document_section_folding_ranges(uri, document)) + result <- c(result, get_section_folding_ranges(uri, document)) result <- unique(result) if (length(result) == 0) { diff --git a/tests/testthat/test-folding.R b/tests/testthat/test-folding.R index 13a2cad4..a11d6f83 100644 --- a/tests/testthat/test-folding.R +++ b/tests/testthat/test-folding.R @@ -18,7 +18,7 @@ test_that("Expression folding rage works", { expect_equal(length(result), 1) expect_equivalent(result[[1]]$startLine, 0) - expect_equivalent(result[[1]]$endLine, 2) + expect_equivalent(result[[1]]$endLine, 1) }) test_that("Section folding range works", { @@ -48,7 +48,7 @@ test_that("Section folding range works", { expect_equal(result[[1]]$startLine, 0) expect_equal(result[[1]]$endLine, 6) expect_equal(result[[2]]$startLine, 1) - expect_equal(result[[2]]$endLine, 6) + expect_equal(result[[2]]$endLine, 5) expect_equal(result[[3]]$startLine, 7) expect_equal(result[[3]]$endLine, 8) }) @@ -119,9 +119,9 @@ test_that("Folding range works in Rmarkdown", { expect_equal(result[[3]]$startLine, 3) expect_equal(result[[3]]$endLine, 12) expect_equal(result[[4]]$startLine, 4) - expect_equal(result[[4]]$endLine, 6) + expect_equal(result[[4]]$endLine, 5) expect_equal(result[[5]]$startLine, 7) expect_equal(result[[5]]$endLine, 8) expect_equal(result[[6]]$startLine, 9) - expect_equal(result[[6]]$endLine, 11) + expect_equal(result[[6]]$endLine, 10) })