GithubHelp home page GithubHelp logo

rmdgh's Introduction

rmdgh

What if there exists an alternate timeline where (R)markdown is their HTML?

Imagine the overbearing richness of the modern web pared back to glorious responsive plain text interfaces... And how the inhabitants of this brave world would interact with their favourite centralised decentralised version control repository?

We can't yet go to this utopia, but we can:

install.packages(
   "rmdgh", 
   repos = c(mm = "https://milesmcbain.r-universe.dev", getOption("repos")))

To get an R <-> GitHub productivity tool powered by Rmarkdown that works in VSCode or RStudio via {rstudioapi}.

Search Operations

  • my_issues() issues by author (defaults to you)
  • issues_with_me() issues referring to author (defaults to you)
  • issues_for_me() issues created on an user's repositories (defaults to you)
  • repo_issues() issues for a given repo or repos (defaults to current repo)
  • my_prs() pr threads by an author (defaults to you)
  • prs_with_me() pr threads referring to author (defaults to you)
  • prs_for_me() pr threads for user's repos (defaults to you)
  • repo_prs() prs for a given repo or repos (defaults to current repo)
  • gh_for_me() prs and issues for user's repos (defaults to you)

You can change who 'me' or 'my' is. It defaults to you but if you do:

  my_issues(
    repos = "tidyverse/dplyr",
    author = "hadley"
  )

And you'll get Hadley's issues for {dplyr}.

repos accepts multiple repos.

All of these are built on top of issues() which takes various arguments for searching and filtering issues and PRs to return to you.

Search with text queries

All search operations support search_query which is text to search in the title and body of issues to filter search results. You can use this to find issues relating to problems you may be having. e.g.:

repo_issues(
  repos = "rdatatable/data.table", 
  search_query = "names(DT) reference semantics"
  )

Search Options

  • issue_search_results_per_page Defines the search results per page. Defaults to 30. Max is 100.

Navigation Operations

You want to bind most of these to keys:

  • issue_seach_results_forward()
    • get the next page of issue search results
  • issue_search_results_backward()
    • get the previous page of search results
  • issue_search_results_expand()
    • search forward on the current line for the identifier of an issue and if found preview the issue body inline with search results.
  • jump_to_issue_thread()
    • Search as per 'expand', but go to the issue thread rendered as an Rmd document. You can submit updates to the issue, comments to the thread, or close the issue.
  • jump_to_issue_webpage()
    • Search as per expand, but go to the issue thread on GitHub
  • refresh_issue_thread()
    • refresh the issue thread referred to by the current Rmd.

There is also gh_thread() to open issue threads as Rmarkdown documents, which is designed for console use. E.g.

gh_thread("capsule#12") 
gh_thread("milesmcbain/capusle#12")
gh_thread() # read url from the clipboard
gh_thread(1) # issue 1 in the current repo

GitHub issue thread RMarkdown output

We have an Rmarkdown output format called github_issue that can be used to submit issues, issue updates, and issue comments to GitHub when the document is rendered with rmarkdown::render(), the knit button in RStudio, or the Knit Rmd command in VSCode.

Drafting issues

  • draft_issue() Will create a new RMarkdown GitHub issue, defaulting to the current repo. By default issues are created in a temporary directory but the path can be changed with option rmdgh_issue_draft_path.

Config you can use looks something like this:

---
title: Example
author: MilesMcBain
output:
  rmdgh::github_issue:
    repo: MilesMcBain/rmdgh
    number: 8
    labels: ~
    action: comment
    draft: no
    close_with_comment: no
---
  • action is one of 'create', 'update', 'comment'
    • number is only valid with 'update' or 'comment'
    • action: update lets you update the issue title, body, and labels. Comments cannot be updated.
  • labels can be a single label or yaml list of labels. Only used on 'create' and 'update'.

Commenting on Issues (and PRs)

You can type in the necessary metadata to make a comment in the draft you're given above. But it's much nicer to navigate to the issue thread with jump_to_issue_thread() described above. Metadata is automatically set up for to submit a comment on render in this case.

Making a reprex

reprex::reprex() doesn't really work well inside a code chunk. You may not even need it though, since rendering a github_issue() does a similar thing to {reprex} so long as you render it in a fresh session.

You can use error = TRUE in the chunk options to display error output instead of stopping.

However, I decided to make a {reprex} {knitr} engine, since I think the specific output from the {reprex} package is expected in some communities, and could cause confusion if it is absent.

So with the new engine you can make a code chunk that uses {reprex} instead of {r}. The output will be as if you had called reprex::reprex() on the code in that chunk. Code in these chunks is self-contained, as per regular reprexes.

Uploading images

By default github_issue uses the same strategy as {reprex} for images, which is to upload them to Imgur with knitr::imgur_upload(). Note these images are public.

Another image service can be used by configuring an alternative function in knitr::opts_chunk$get(upload.fun =). See Publish images from chunks in the web.

Saving Issues

If you'd like to create a workflow where you stash some issues locally to work through checkout save_issue() for saving issues in a configurable location - defaulting to ./issues. The location is configurable in the rmdgh_issue_location option.

FAQ

Why? Why have you done this?

I find typing into little text input boxes on GitHub.com a bit of a buzz kill when drafting issues. My text editor feels so much nicer to draft technical communications with.

There's also a bit of jankyness that comes from the fact that most of the time when drafting issues I'll want a reprex, which has to be coded up in R, rendered, and then pasted into the issue. But sometimes as the issue evolves the reprex needs to also, and there's awkward iterative back and forth involving context switching between applications.

This is exactly the kind of source-output synchronisation and context switching pain that {knitr} and {rmarkdown} take away. Why wouldn't we draft GitHub issues and comments that mash up code and prose in RMarkdown?!

Will you port this to Quarto at some point?

Possibly. I like the idea of being able to author issues that use multiple languages. However much of this package works via the {rstudioapi} which means it's not likely to appeal to quarto users from other languages.

Probably a Quarto version should be implemented as VSCode extension? But then the potential user base is much smaller at present. Let's see what Posit does with extensions in the stand-alone Quarto editor that must surely be coming.

rmdgh's People

Contributors

milesmcbain avatar rmflight avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

rmflight icodein

rmdgh's Issues

Not clear how to actually create or update an existing issue?

This is very, very cool.

However, what I can't figure out is the actual command to actually create a new issue.

If I do:

  • rmdgh::draft_issue("user/repo")
  • That opens a new file for me to fill out the specifics, I save it.
  • What command is next? rmdgh::github_issue(..., action = "create")?? But it doesn't take a filename argument ...

There really needs to be one more step noted in the README, what do you do after you've updated the Rmd file.

Actually should text wrap be "preserve" after all?

This text is weirdly cropped:

Yeah I was aware of that one. Theres a risk there, but I think it’s
small. I’ve used the same strategy as {reprex} in {rmdgh} now. You
can override where the images are uploaded to in knitr options, but I
think you’re always going to end up with something basically public.
I’ve put notes about this in the documentation.

If we wanted private images, the only way I can think of doing it ATM
would be to upload the image to the repo, this would mean comitting it.
It would work for our own repos, but not those owned by others. So it
would be a bit messy.

It’s probably something I’d only bite off if I wanted it or someone else
made a decent PR for it.

Thanks for raising this!

Jump and expand for local repo issue references

It would be cool to have the jump and expand navigation options work for regular
issue references. eg: #123. In this case the repo context would have to be
retrieved from the yaml. Not too hard to do.

`use_rmdgh`?

Hi Miles, love the idea!

It reminds me of https://github.com/mattduck/gh2md but this is a whole lot more powerful, and focusses on writing issues (rather than saving them to read in contexts without internet access).

My first question when using gh2md was 'where do I put stuff' and the same question applies here. Worth considering a use_rmdgh function to

  • Create a folder for saving and editing issues, e.g. issues
  • Adding that to the buildignore
  • Anything else...

Default keybindings config

For the navigation commands that you really want bound to keys, it would be nice
to be able to distribute some default keybinding config for VSCode and RStudio.

RStudio config should use shrtcts.

Don't swallow gh::gh errors in try catch

I had bad credentials which gh::gh gives a nice error for but instead I was seeing:

 could not find repository on GitHub: milesmcbain/paint

When attempting to create an issue.

Upload images using imgur_upload

The trick is where to set:
knitr::opts_knit$set("upload.fun", knitr::imgur_upload).

Probably needs to be done in the preprocessor.

Add ability to update issue title and body

I had convinced myself I wasn’t going to support updates, since they can
cause problems with thread readability. I think there are a couple of
valid exceptions to this though:

  • Changing the issue title to better reflect what it’s about
  • Updating checkboxes in todo lists in the issue body

Luckily these only require updating the issue content, not all thread
comments, and that feels like a good compromise. Updating check lists
won’t be supported in thread comments.

Some kind of new option for the github_issue format can probably cover
it off. E.g. update: yes and then the content representing the issue
body is scraped out and fed through as an update. Content entered after
the last separator for comments is ignored.

It might make sense to introduce another comment separator like the
current footer, to delineate issue body vs issue comment content.

  • update works!

Your issue title

Here is my reprex:

  library(issuecreep)
  issuecreep:::repo_issues("doesnt/exist")
## Error in value[[3L]](cond): could not find repository on GitHub: doesnt/exist

open_thread() to view an issue thread

A quick way to open an issue you thread you want to view.

Consider some user-friendly defaults:

  • Search the clipboard for a url if no reference provided
  • Allow a number only reference and assume it applies to the current git repo in
    the working directory
  • Allow shorthand reference package#number or owner/repo#number where a repo
    is attempted to be found for a package name as per repo_issues()

Rename package?

‘issuecreep’ was meant to be a placeholder. New ideas:

  • ‘issueflow’
  • ‘rmdgh’

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.