-
Notifications
You must be signed in to change notification settings - Fork 54
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
Numerous improvements to rlang autocomplete, tooltips & annotations #66
Conversation
improvements to rlang completer, tooltips, annotations, hotkeys
…icating javascript.
Just a quick note, there is some Javascript that is added to handle the tooltip callbacks and the rlang completion insertion behavior. Right now I believe it would be applied regardless of completer, so it might be necessary to retool it a bit to that it only enables that behavior when the rlang completer is used. My Javascript is pretty shaky, so I really just got it working before trying to engineer a more language agnostic solution. There are two behaviors that are applied generally, and should probably only affect the R language:
|
Right you are, edited my comment
I'm unclear on which part you'd like to revert. I think it already works the way you're expecting. To enable each of the new features, you must create a new observer (from tooltip example): # Enable/Disable R code completion / annotation
ace_completer <- aceAutocomplete("ace_editor")
ace_annotator <- aceAnnotate("ace_editor")
ace_tooltip <- aceTooltip("ace_editor") To disable the annotator or tooltips, you'd just remove that line which creates the observer, or suspend the observation, just like you already would with the autocompleter: shinyAce/inst/examples/06-autocomplete/server.R Lines 40 to 48 in 92aa941
Perhaps I'm misunderstanding. I'm happy to refactor to fit your needs, I'm just unclear of the goal. |
Thanks for the clarification @dgkf. What I meant in my previous comment was to revert the change that requires
|
I see, thanks for clarifying @vnijs. I moved the |
Thanks @dgkf but I'm not getting this to work. After changing datasets, the below works only if "rlang" is added as a completer. Could you take a look? FYI this is the adapted 07 example I mentioned earlier.
|
That code is working for me. Is it possible that you didn't rest on a completion item long enough for the tooltip to pop up? The tooltips are set up to only show after an item in the dropdown has been hovered over for 1s. This is to prevent some jankyness when switching completion fields (showing the last completion hover until the R process completes) and to minimize the overhead imposed on the R process for parsing help docs. editor.__tooltipTimerCall = lang.delayedCall(
function() {
if (this.completer.activated)
this.completer.showDocTooltip(data.docTooltip);
}.bind(editor), 1000); If you aren't already, make sure once the completions list pops up that you linger on an item in the dropdown list for that 1s delay to wait for the tooltip to show. The tooltip text for the dataset column names isn't particularly helpful and will just show the name of the column. For functions as shown in the screenshot it should pull up the documentation entry. |
@dgkf That part does indeed work. Thanks. I was looking at argument completion inside brackets that activates after pressing the tab key within brackets. That still only seems to work when "rlang" is set. |
The argument completions are handled in the Lines 24 to 43 in 92aa941
If it's preferred to have this behavior globally it would probably require a pretty extensive rewrite of the way the rlang completer is currently set up. I think this is probably beyond the scope of the additions I've made and might warrant a separate pull request. |
@dgkf I'm starting to figure out how to use your additions a bit better now. Thanks again for the clarification. If possible I'd still prefer to fully remove any changes related to modules from this PR and submit any changes you deem necessary for use of shinyAce with modules as a separate PR so @detule can review this in detail. That said, I'm very excited about what you have been able to do with autocompletions! These are substantial improvements indeed. Below some initial questions and comments that I think could help improve the setup further. Is there a way to avoid an "=" sign when not needed? For example: Is it possible to escape quotes in the argument list that? For example, "independent" should be shown with quotes as that is the default value. I noticed that Rstudio doesn't seem to show default values at all so perhaps this is tricker than it seems at first glance? If you have In example 12-tooltips you have a checkbox to allow completion of variable names linked to a dataset. I assume this is supposed to work with "static" but there is no dataset and no custom completion list specified. Perhaps you could use "mtcars" as the example dataset and add "varnames(mtcars)" as the custom completion list? |
@vnijs - Thanks for taking a close look at some of the edge cases. I took a look at the way I was building the tooltip info to try to make it a bit more consistent. I think the code is in a better place now. I was able to address most, but not all of your suggestions.
The only step taken for addressing this is that the return(session$sendCustomMessage('shinyAce', list(
id = session$ns(inputId), # only change was to add `session$ns()`
codeCompletions = jsonlite::toJSON(completions, auto_unbox = TRUE)
)))
Yes! Done - and now the package description is displayed for packages instead of just the name. In the same vein, I also added the ability to dig up dataset documentation (e.g.
Yes! Good eye. I hadn't noticed that. I added checking for the edge case where the formal argument default is a character vector of length 1.
Possibly... I'd have to think on this one a bit. This is a bit tricky because it's handled at the Javascript level given the different completers that have been added. The two lists of completions (the arguments provided by the rlangCompleter and the local values provided by the textCompleter) are handled independently and then merged. I'm sure there's a way, but it would probably be quite challenging to get it working. I would consider this out of scope for a first pass at the argument autocompletion.
This was laziness on my part. I just copied another example as a quick testing grounds and didn't realize I never went back to clean it up. I reworked it to just showcase the tooltips and annotation features as an example of how to disable them reactively. |
Thanks for the updates @dgkf. These changes are great ... but there seems to be some corner cases related to tooltips. I'm seeing a lot of messages related to You might want to use In general, printing errors and warnings for autocompletion is great for debugging but should be shown in the final version of the upcoming release with your changes. |
Thanks again for your diligence on this front @vnijs I've been able to reproduce the first issue trying to autocomplete I'll follow up once I've fixed those cases. |
I tried my best to address these issues but had troubles reproducing a couple of them.
I don't have an
I think this was coming from the way the
Agreed - I added a I haven't been able to reproduce this error message. I think it might be related to packages that don't have documentation or treating environments as packages before. If you see this again, please document some steps to reproduce it. That would help me a lot for drilling into the problem. |
Thanks @dgkf. Looking much more solid already. I'm able to reproduce the error below using the shiny app code below. There are other examples where this happened but I expect this will cover most (or all) cases of this warning. You'll need to install "radiant.data". In the ace editor type https://github.com/radiant-rstats/radiant.data/blob/master/R/visualize.R Warning in if (!file.exists(dirpath)) stop(gettextf("invalid %s argument", :
the condition has length > 1 and only the first element will be used
Warning in if (!file.exists(paste0(RdDB, ".rdx"))) stop(gettextf("package %s exists but was not installed under R >= 2.10.0 so help cannot be accessed", :
the condition has length > 1 and only the first element will be used library(shiny)
library(shinyAce)
library(radiant.data)
ui <- fluidPage(
titlePanel("shinyAce auto completion demo"),
sidebarLayout(
sidebarPanel(
checkboxInput("enableAutocomplete", "Enable R AutoComplete", TRUE),
checkboxInput("enableTooltips", "Enable R Tooltips", TRUE),
checkboxInput("enableAnnotations", "Enable R Annotations", TRUE)),
mainPanel(
aceEditor("ace_editor",
mode = "r",
autoComplete = "live",
autoCompleters = "rlang",
value = "# Tooltips:
# linger over an autocomplete option to view some documentation. See
# - Function descriptions
# data.fra # <autocomplete>
# - Argument descriptions
# data.frame( # <autocomplete>
# - Package descriptions
# shinyAc # <autocomplete>
# Annotations:
# gutter annotations used to indicate syntax errors, try uncommenting this line
# with an incomplete string
# '''
"
)))
)
server <- function(input, output, session) {
# Enable/Disable R code completion / annotation
ace_completer <- aceAutocomplete("ace_editor")
ace_annotator <- aceAnnotate("ace_editor")
ace_tooltip <- aceTooltip("ace_editor")
# Enabling and Disabling Autocompletion Observer
observe({
if (input$enableAutocomplete) ace_completer$resume()
else ace_completer$suspend()
})
# Enabling and Disabling Tooltips Observer
observe({
if (input$enableTooltips) ace_tooltip$resume()
else ace_tooltip$suspend()
})
# Enabling and Disabling Annotations Observer
observe({
if (input$enableAnnotations) ace_annotator$resume()
else ace_annotator$suspend()
})
}
shinyApp(ui = ui, server = server) |
Ah! This is perfect. It's because there are multiple documentation files for Or programmatically, it's being thrown from This helps a ton. I'm sure we can find a way around this. I'll follow up once I've got something working. |
I see. Well spotted @dgkf. Could the lookup be restricted to packages that are in |
We can figure out which package the function is being pulled from (the same way we do when we do the function name completion and generate the package name on the right of the dropdown). With this info we can prevent the ambiguity in the help search. I had just forgotten to collect and pass this extra data back to the tooltip handler. It's now been added and the way the help files are searched has been cleaned up. I think we might still see the message if there are redundant help names in base. I don't think that's the case, but I'm not intimately familiar with everything in base. The number of situations when someone may see it in the debug output should be much reduced. |
Nice! @detule Could you try out the dev branch @ https://github.com/dgkf/shinyAce to see if there are any issues with modules? If that seems to work as expected I'd like to merge this PR into master. Again, great work @dgkf! |
@dgkf It seems the same error we saw with |
I see. It turns out this because there is both a Instead, the function I use to pull up the help content now will take only the first available help file (the most recently attached). I think this is the preferred behavior. To try to keep some of these various testing scenarios embedded with the software, I also added a handful of unit tests to check for some of these edge cases. |
FYI shinyAce 0.4.1 is being built on CRAN now. Thanks again @dgkf for your contributions! |
In an effort to bring shinyAce closer to expected behaviors of an IDE, I've made quite a few changes to the rlang autocompleter, added help dialog tooltips, gutter annotations for syntax errors and additional keybinds.
shinyAce
rlang
updatesrlang autocomplete
I drew inspiration from the
learnr
package's autocomplete code (which has its own, non-shiny wrapper around Ace) to take advantage of some autocomplete edge cases that are better handled in that implementation.Feature updates:
()
, inserting cursor between the parenthesis::
.
and:
charactersrlang tooltips
To bring this autocompletion more in line with expected behaviors from the RStudio IDE, lingering on an autocomplete option will also show the help dialogue, rendered as html-formatted markdown.
rlang annotations
To improve immediate feedback about code issues, I also added gutter annotations for syntax errors. Upon update, after a small delay, the annotator will attempt to parse the full block of code and return annotation information back to Ace.
Hotkey Improvements
Tab completion was added, trying to intelligently kick off a new autocompletion, select available completions or indent the current code. This behavior is meant to mimic the RStudio IDE more closely.
General
shinyAce
UpdatesshinyAce
in ashiny
moduleKnown Bugs
It was my intention to make this pull request quite a while ago and was just recently reminded of the work. Seeing that I was already accruing merge conflicts, I wanted to open the pull request before trying to resolve any known issues so that you're aware of this work. That said, there are still some known minor bugs.
data.fr_
<TAB>
data.frame(_))
. I think this happens when I hit tab twice, but I haven't dug into it to be sure.