RStudio Addin Support#408
Conversation
+ handler for active_editor_context
|
Just did minor fixes to comfort eslint. It would be very nice if you put some minimal examples about what will be achieved in this PR and how we could test against what has been done. Looks very promising! Cheers! |
|
Thanks for the nice work! I play with |
|
Oh sorry that list of add-ins was aspirational. As you can see from the trace there's a fair few functions that need implementation yet. I only have those 4 listed above. This is going to take a while! |
|
Also that trace highlights a problem with my |
+ support for lists of mixed range/position objects
* verify_available * is_available
Edits applied as part of one resolution have positions updated as the transaction proceeds so that they always refer to the same text (in so far as that is possible), irrespective of other earlier edits.
defaulting to current range or position
|
It's milestone time! @andycraig @renkun-ken Currently only works with the GitHub dev version of I think what I have in the PR so far will cover all the addins I've written. Not sure about the others on that list. Still a ways to go probably. |
|
Working through the eslint stuff now |
|
@MilesMcBain Great stuff, that screencap is a joy to watch! I'm totally okay with only supporting a subset of plugins initially. Would it be possible/practical to give the user a message if a plugin tries to use a function that isn't supported yet? When you want some testing done let us know! |
|
Yep I think a 'not implemented' message is a good way to go. Shouldn't be hard to do. From here:
|
|
To get the list of addins and their bindings, I tried the following code: pkgs <- .packages(all.available = TRUE)
addin_files <- vapply(pkgs, function(pkg) {
system.file("rstudio/addins.dcf", package = pkg)
}, character(1L))
addin_files <- addin_files[file.exists(addin_files)]
descs <- lapply(addin_files, function(file) {
desc <- read.dcf(file)
as.data.frame(desc)
})
jsonlite::toJSON(descs)which outputs all addins information from the library so that vscode-R could read it easily: Click to expand!{
"blogdown": [
{
"Name": "Serve Site",
"Description": "Run blogdown::serve_site() to live preview a website locally.",
"Binding": "serve_site",
"Interactive": "true"
},
{
"Name": "New Post",
"Description": "Create a new post with blogdown::new_post().",
"Binding": "new_post_addin",
"Interactive": "true"
},
{
"Name": "Update Metadata",
"Description": "Update the title, author, date, categories, and tags of the current blog post.",
"Binding": "update_meta_addin",
"Interactive": "true"
},
{
"Name": "Insert Image",
"Description": "Insert an external image into a blog post.",
"Binding": "insert_image_addin",
"Interactive": "true"
},
{
"Name": "Touch File",
"Description": "Change the timestamp of the current file in the editor.",
"Binding": "touch_file_rstudio",
"Interactive": "false"
},
{
"Name": "Quote Poem",
"Description": "Add > to the beginning of selected paragraphs and two trailing spaces to selected lines.",
"Binding": "quote_poem_addin",
"Interactive": "false"
}
],
"bookdown": [
{
"Name": "Preview Book",
"Description": "Run bookdown::serve_book() to live preview a book.",
"Binding": "serve_book",
"Interactive": "true"
},
{
"Name": "Input LaTeX Math",
"Description": "Input math expressions via the MathQuill library.",
"Binding": "mathquill",
"Interactive": "true"
}
],
"clipr": [
{
"Name": "Value to clipboard",
"Description": "Copies the results of a selected expression to the system clipboard",
"Binding": "clipr_result",
"Interactive": "false"
},
{
"Name": "Output to clipboard",
"Description": "Copies the console output of a selected expression to the system clipboard",
"Binding": "clipr_output",
"Interactive": "false"
}
],
"covr": [
{
"Name": "Calculate package test coverage",
"Description": "Calculates the package test coverage and opens a report, using `covr::report()`",
"Binding": "addin_report",
"Interactive": "false"
}
],
"datapasta": [
{
"Name": "Paste as tribble",
"Description": "Pastes a table from the clipboard to the editor as a tribble definition",
"Binding": "tribble_paste",
"Interactive": "false"
},
{
"Name": "Paste as vector",
"Description": "Pastes data from the clipboard to the editor as character vector, formatted horizontally on a single line.",
"Binding": "vector_paste",
"Interactive": "false"
},
{
"Name": "Paste as vector (vertical)",
"Description": "Pastes data from the clipboard to the editor as character vector, formatted vertically, one element per line.",
"Binding": "vector_paste_vertical",
"Interactive": "false"
},
{
"Name": "Paste as data.frame",
"Description": "Pastes a table from the clipboard to the editor as a data.frame definition",
"Binding": "df_paste",
"Interactive": "false"
},
{
"Name": "Paste as data.table",
"Description": "Pastes a table from the clipboard to the editor as a data.table definition",
"Binding": "dt_paste",
"Interactive": "false"
},
{
"Name": "Fiddle Selection",
"Description": "Take a selection and fiddle it to something better (maybe).",
"Binding": "zzz_rs_dfiddle",
"Interactive": "false"
},
{
"Name": "Toggle Vector Quotes",
"Description": "Toggle quotes in a vector defintion",
"Binding": "zzz_rs_toggle_quotes",
"Interactive": "false"
}
],
"devtools": [
{
"Name": "Run a test file",
"Description": "Run the current test file, using `devtools::test_file()`.",
"Binding": "test_file",
"Interactive": "false"
},
{
"Name": "Report test coverage for a file",
"Description": "Calculate and report test coverage for the current test file, using `devtools::test_coverage_file()`.",
"Binding": "test_coverage_file",
"Interactive": "false"
},
{
"Name": "Report test coverage for a package",
"Description": "Calculate and report the test coverage for the current package, using `devtools::test_coverage()`.",
"Binding": "test_coverage",
"Interactive": "false"
},
{
"Name": "Document a package",
"Description": "A wrapper for `roxygen`'s `roxygen2::roxygenize()`",
"Binding": "document",
"Interactive": "false"
}
],
"lintr": [
{
"Name": "Lint current file",
"Description": "Runs lintr::lint on the current file",
"Binding": "addin_lint",
"Interative": "false"
},
{
"Name": "Lint current package",
"Description": "Runs lintr::lint_package",
"Binding": "addin_lint_package",
"Interative": "false"
}
],
"reprex": [
{
"Name": "Render reprex...",
"Description": "Run `reprex::reprex()` to prepare a reproducible example for sharing.",
"Binding": "reprex_addin",
"Interactive": "true"
},
{
"Name": "Reprex selection",
"Description": "Prepare reprex from current selection",
"Binding": "reprex_selection",
"Interactive": "false"
}
],
"styler": [
{
"Name": "Set style",
"Description": "Prompt for and set the style transformers used by all styler addins",
"Binding": "set_style_transformers",
"Interactive": "true"
},
{
"Name": "Style selection",
"Description": "Pretty-print selection",
"Binding": "style_selection",
"Interactive": "true"
},
{
"Name": "Style active file",
"Description": "Pretty-print active file",
"Binding": "style_active_file",
"Interactive": "true"
},
{
"Name": "Style active package",
"Description": "Pretty-print active package",
"Binding": "style_active_pkg",
"Interactive": "true"
}
]
}We could add it to session watcher or addins init script so that the addins could be written to a JSON file in |
The QuickPick API might be the way to go here. It's not used in vscode-R at the moment but here's an example extension that does use it: https://github.com/microsoft/vscode-extension-samples/tree/master/quickinput-sample |
|
Thankyou both @renkun-ken and @andycraig, between the two of you, most of the research for the menu feature is done! |
+ setCursorPosition = setSelectionRanges
introduced by refactor, hopefully staying working now.
+ the request_response from R remains generic + rstuioapi_call wraps request_response to send commands of type "rstudioapi" + rstudioapi commands are handled in updateRequest and dispatched to an api specific request dispatcher + dispatchRStudioAPICall dispatches requests based on 'action' with action arument passed in 'args'
|
Okay I think the rebase was successful. Sorry about the mess. This is only the 2nd time I've done that. Probably what I should have done was squashed everything into one new commit? I'll know for next time. 😬 |
|
Perfect! I'll release a new version this week. |
|
Cheers! |
I think, just change a line https://github.com/Ikuyadeu/vscode-R/pull/408/files#diff-8b19336fd34c052a83b852dc7aeac4b2a2b56f17c783c2480ca6948ae648330fR320 without rebasing/merge/cherrypick was the easiest change. |
|
@MilesMcBain Sorry, work has been super busy lately and I fell off the face of the planet for a bit. Thank you very much for this huge piece of work. There was a lot more required for this than I'd assumed when I created that Issue about supporting these addins. Thank you so much for taking it on! This is a massive new feature that people (including myself of course!) are really going to enjoy and appreciate. Thank you again! |

Addressing issue #302. Support for addins in VSCode via
rstudioapiemulation.Capability Added
This PR would add an
rstudioapiemulation layer to the extension. This would allow R functions that call therstudioapito be run, and behave as expected from within VSCode. Typically therstudioapiis used by user-created RStudio addins to add functionality to the RStudio IDE.One such example is the package
{datapasta}which, among many things, formats data.frames on the clipboard astibble::tribble()calls and inserts them into the active source editor or terminal. This relies on only a small subset ofrstudioapifunctionality for getting document context and inserting text.It would also be possible to use existing RStudio addins to bridge functionality gaps. E.g. Users have requested a Roxygen skeleton generator in #405. With
rstudioapiemulation in play we could recommend they make bindings (or ship them) to addin functions in{docthis}or{sinew}.Implemented functions:
getActiveDocumentContextgetSourceEditorContextisAvailableverifyAvailableinsertTextmodifyRangereadPreferencereadRStudioPreferencehasFunfindFunshowDialognavigateToFilesetSelectionRangessetCursorPositionsetDocumentContentsdocumentSavedocumentIddocumentPathdocumentSaveAlldocumentNewgetActiveProjectrestartSessionviewerTesting It
This is challenging since most packages that do test rstudioapi stuff end up mocking the api anyway. I have sought feedback from R users on Twitter as to popular addins. We could make a short list and manually confirm the addins work. The list would contain (WIP):
{reprex}{datapasta}{fnmate}{equisse}{remedy}{citr}{blogdown}{AlignAssign}{prefixer}