Home

Awesome

Travis build status AppVeyor build status

Your fnmate

Type a call to a function and have a definition for that function appear with a keystroke. Lay the planks with your fnmate but leave the hammering til after smoko.

fnmate

Installation

remotes::install_github("milesmcbain/fnmate")

Usage

RStudio

There are three addins that do pretty much what their names suggest:

You can bind these to key combinations of your choosing, see here.

The function to be generated is determined by the cursor position. The function call at the most nested scope that encloses the cursor is the one that fnmate will generate a definition for.

There's another helper addin:

Emacs (ESS)

There is some Emacs lisp you can use to create bindings to fnmate contained in the vignette Using fnmate with ESS. If you have better ideas about how to distribute ESS 'addins' please let me know!

VSCode

The RStudio addin is supported in VSCode via {rstudioapi} emulation (needs to be turned on with option).

With emulation turned on, configure a keybinding like:

    {
        "description": "create function defintion",
        "key": "ctrl+;",
        "command": "r.runCommand",
        "when": "editorTextFocus",
        "args": "fnmate::rs_fnmate()"
    },
    {
        "description": "jump to function defintion",
        "key": "ctrl+shift+;",
        "command": "r.runCommand",
        "when": "editorTextFocus",
        "args": "fnmate::rs_fn_defn_jump()"
    }

Options

There are some options that affect how fnmate works:

You can modify any of these options by running, for example, options(fnmate_quote_jump_regex = TRUE) in your R session or in your .Rprofile.

Why does this exist?

A lot of the time when I attack a problem I find it helps to cruise over the gnarly bits requiring fiddly code by just claiming a function exits that will magically resolve that fiddly bit for me. After I have a high level solution described, I go back and fill in the blanks. This tool helps me clearly mark out the blanks without breaking my flow on the higher level algorithm.

Recently when developing R workflow plans with drake I've found myself wanting a tool like this so that my sketch of the workflow plan can be built, even though some of the targets are just placeholders.

Also realising this idea in a robust way turned out to be way more challenging than I anticipated and necessitated coopting the R parser and its parseData output. So it became a learning exercise.