-
Notifications
You must be signed in to change notification settings - Fork 73
Addin to style highlighted region #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
fa679c7
to
d85a54d
Compare
Codecov Report
@@ Coverage Diff @@
## master #143 +/- ##
==========================================
- Coverage 93.85% 93.26% -0.59%
==========================================
Files 19 20 +1
Lines 748 802 +54
==========================================
+ Hits 702 748 +46
- Misses 46 54 +8
Continue to review full report at Codecov.
|
d85a54d
to
fadc3c3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the addin should operate in interactive mode, because there seems to be no feedback otherwise, e.g., when styling the entire package.
Also, styling the active region doesn't seem to work if an incomplete expression is selected. We could search for the sub-tibble that fully contains the selected region and style only this, but that's worth a separate issue.
Yes, I thought about that too. I think it gives feedback, e.g. "No files changed" appears on the console but I think the problem is also that the error handling is not very good. Same with the other Addins, although I think the "style active file"-Addin is the most important one. The reason I have not explored interactive Addins is that I can't do that as part of Milestone CRAN due to time constraints. Should we leave it as is or should we keep all Addins for a future CRAN release? |
"Interactive" just means that it runs in the active R session, and blocks it -- a simple change to |
Ok, I see. Let's do that then. |
It actually does not work the way I thought because we use the RStudio API to get the active document. If we set |
|
Oh now it works, had to restart RStudio also, not just rebuild the package and restart R. With regard to tests, do you think we should make |
You could implement: style_active_region <- function() {
context <- find_active_context()
all_text <- utf8::read_lines_enc(context$path)
...
}
get_rstudio_context <- function() {
rstudioapi::getActiveDocumentContext()
} and then in the test ask test_that("...", {
result <- mockr::with_mock(
get_rstudio_context = function() structure(list(...), class = "document_context"),
style_active_region()
)
expect...(result, ...)
}) |
edbae6b
to
b65296d
Compare
I tried to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with postponing automated tests. Maybe split this PR so that the testing is added in a separate commit/branch?
R/addins.R
Outdated
#' | ||
#' Helper function for RStudio Addin. | ||
style_active_file <- function() { | ||
file <- rstudioapi::getActiveDocumentContext()$path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need to call find_active_context()
here to allow mocking?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want I guess so. So far, only style_actige_region is tested but we can add a test here too to increase coverage.
R/addins.R
Outdated
path <- context$path | ||
start <- context$selection[[1]]$range$start | ||
end <- context$selection[[1]]$range$end | ||
if (all(start == end)) return() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... and then return a list with only one component here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should rather be stop("No region selected")
instead of return()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if we want to call this for getting the active file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No then not. But currently, we don't use find_active_context() for styling files. Should we? If yes, then the error message should not be implemented within the function find_active_context, I agree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's currently only used for styling regions within files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I adapted it so it is used in both cases.
tests/testthat/test-public_api.R
Outdated
@@ -17,3 +17,37 @@ test_that("styler can style file", { | |||
}) | |||
|
|||
# style_active_file() must be tested manually. | |||
test_that("...", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops
tests/testthat/test-public_api.R
Outdated
before_styling <- utf8::read_lines_enc(paste0(base, "/xyzaddin/addin_region-in.R")) | ||
reference <- utf8::read_lines_enc(paste0(base, "/xyzaddin/addin_region-out.R")) | ||
result <- expect_error( | ||
testthat::with_mock( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mockr::with_mock()
should really work here, because testthat::with_mock()
might not at some point. Can you please simplify the code (e.g., extract the hard-coded "document_context"
structure to a variable) and try again? For troubleshooting the error message is helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mockr::with_mock()
works using devtools::test()
but not interactively while testthat::with_mock()
works in both sistuations, which is why I have not used mockr
yet. Can you have a look at why that is the case?
What do you mean with extracting hard-coded "document_context"
structure to a variable? Like this?
doc_cont <- structure(...)
testthat("...", {
result <- mockr::with_mock(
get_rstudio_context = function() doc_cont,
...
Unfortunately, there is no way to create the structure with a function call directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, something like this code.
You could try mockr::with_mock(..., envir = asNamespace("styler"))
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so assign the variable elsewhere in the name space? Or should leave the declaration where it is?
R/addins.R
Outdated
#' [rstudioapi::getActiveDocumentContext()]. | ||
#' | ||
find_active_context <- function() { | ||
context <- rstudioapi::getActiveDocumentContext() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we could just create a simple forwarder to rstudioapi::getActiveDocumentContext()
in our package, and mock this forwarder:
get_rstudio_context <- function() {
rstudioapi::getActiveDocumentContext()
}
mockr still works if functions are called indirectly from our package (it patches all functions in our package).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok yes I see. That's what I a say unsure about (see comment above).
Do you need more input here? |
bde246e
to
fc426a9
Compare
Can you review the updated PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks. If you call devtools::release()
, one of the first things it does is a spell check of the documentation, this will find the typos we've missed.
R/styler.R
Outdated
#' according to a style guide. See the INDEX for more information. | ||
#' | ||
#' according to a style guide. | ||
#' The fo,lowing functions can be used for styling: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
tests/testthat/test-public_api.R
Outdated
|
||
before_styling <- utf8::read_lines_enc(paste0(base, "/xyzaddin/addin_region-in.R")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just copy to a temporary directory?
dir <- tempfile("styler")
dir.create(dir)
file.copy(".../addin_region-out.R", dir)
The current approach seems slightly brittle if the tests aborts before the original contents have been written.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, right. So if I understand you right, we copy the *-in.R*
to the temporary directory, style it there and compare it with the -*out
. in the permanent directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
R/addins.R
Outdated
#' | ||
#' Essentially adding the parts before the highlighted area on the line where | ||
#' the higlighted area starts to the styled expression. Also, after the styled | ||
#' expression, the remainer of that line that was not styled is added. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remainder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
688e4a5
to
5516951
Compare
5516951
to
7b556c7
Compare
7b556c7
to
58681c9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, but we might need yet another iteration.
README.md
Outdated
@@ -23,7 +23,7 @@ There are a few variants of `style_text()`: | |||
- `style_file()` styles a single .R file. | |||
- `style_dir()` styles all .R files in a directory. | |||
- `style_pkg()` styles the source files of an R package. | |||
- An RStudio Addin that styles the active file .R file | |||
- RStudio Addins for styling the active file, styling current package and styling the highlighted code region. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the current package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the package which has its root in the current working directory (if any). Could not find a better formulation for it. Any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
styling current package -> styling the current package
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
tests/testthat/test-public_api.R
Outdated
|
||
# style_active_file() must be tested manually. | ||
test_that("styling active region works", { | ||
reference <- utf8::read_lines_enc( paste0(base, "/xyzaddin/addin_region-out.R")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
file.path()
better explains your intentions. Even better, a small function
testthat_file <- function(...) {
file.path(rprojroot::find_testthat_root_file("public-api"), ...)
}
instead of the base
variable. Here and elsewhere.
tests/testthat/test-public_api.R
Outdated
@@ -21,3 +21,39 @@ test_that("styler does not return error when there is no file to style", { | |||
}) | |||
|
|||
|
|||
## ............................................................................ | |||
|
|||
dir <- tempfile("styler") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these variables seem to fit better in the test_that()
block below.
@@ -21,3 +21,39 @@ test_that("styler does not return error when there is no file to style", { | |||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would the preceding tests change the original files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, they should not, because the input is already styled. The tests are only to check whether the call returns an error or not. It's a rather superficial test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These files will then need an update whenever the style guide changes, but that's fine with me.
R/addins.R
Outdated
list( | ||
start = fract_of_line_start, | ||
end = fract_of_line_end, | ||
body = lines_not_to_style |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
body
seems a misnomer if it's
the lines that are not overlapping with the highlighted text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So maybe just lines_not_to_style
?
README.md
Outdated
@@ -23,7 +23,7 @@ There are a few variants of `style_text()`: | |||
- `style_file()` styles a single .R file. | |||
- `style_dir()` styles all .R files in a directory. | |||
- `style_pkg()` styles the source files of an R package. | |||
- An RStudio Addin that styles the active file .R file | |||
- RStudio Addins for styling the active file, styling current package and styling the highlighted code region. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
#' Create the path to a test that file | ||
#' @param ... Arguments passed to [file.path()] to construct the path after | ||
#' ".../tests/testthat/" | ||
testthat_file <- function(...) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be better suited in a tests/testthat/helper-*.R
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- ups, forgot to knit
.Rmd
tomd
. - Ok, but then we won't get
roxygen2
documentation, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I forgot. Let's keep it here.
@krlmlr Do you want to have a final look? I think now we got them all 😄 |
- Hotfix: utf8 should not be verbose (#245). - Allow styling of Rmd files(#233). - Remove duplicate @family (#244). - Fixing token insertion (#242). - Capitalize Addin titles (#241). - Explicit `NULL` creation to make styler compatible with R3.2.0 (#237). - Improve vignettes (#232). - Allow exclusion of files with `style_pkg()` and `style_dir()`. - Correct styling with long strings (#230). - Add tools for re-indenting tokens (#217). - Math token spacing (#221). - Remove outdated line and col information (#218). - Empty input for styling does not cause an error (#227, #228). - Tools to insert tokens + application on `if`-`else` clauses (#212). - Improve example in documentation (#222). - Fix spacing around in (#214). - Maintenance: renaming functions / files, extend helper, documentation, if_else etc. (#204). - Disallow line break after ( for function calls (#210). - Preserve space between `!` and bang (#209). - Simplify RStudio Addin (#208, #211). - Indention based on square brackets (#207). - Add vignette on introducing styler (#203). - Indent function declaration without curly braces correctly (#202). - Fix indention in if-else statement (#200). - Sorting key (#196). - Use safe sequences (#197). - Fix space between two commas (#195). - Keep single-line pipes on one line (#74). - Remove tidyr and dplyr dependency (#182, #183, @jimhester). - Fix parsing inconsistency (#188). - Substitute create filler (#190). - Introducing class vertical (#189). - Adapt line break rules (#172). - Fix `R CMD check` (#185). - Force argument evaluation for proper error handling (#179). - Add nonstrict version of set_space_before_comment (#174). - Add installation instructions to README (#175). - Addin to style highlighted region (#143). - Improve spelling (#168). - Add coverage badge - Change badge from WIP to active - Add the number of files to message (#166). - Improve documentation (#164). - Add informative messages while styling files (#165). - More examples in help file (#161). - No line breaks after pipe if comment is next token (#160). - Fixing spacing around `!` (non-bang-bang) (#157). - Finalize function documentation (#154). - Review vignette (#158). - Update bang-bang rule (#156).
This closes #107. It seems a bit complicated because of the fact that you can highlight also just parts of lines. Did not really know how we could add formal testing to that. One way would be to make
context
an argument ofstyle_active_region()
with defaultfind_active_context()
so we can supply some file region for testing purposes.