DelugeFirmware icon indicating copy to clipboard operation
DelugeFirmware copied to clipboard

Create a standard for describing shortcuts

Open handeyeco opened this issue 1 year ago • 7 comments

Please describe the problem:

Hey yo 👋 We were talking on the Discord about making a standard for describing shortcuts/actions. The idea is that we'd have this description (likely as JSON) that could be used to auto generate documentation - something like JSDoc. I made something that roughly does this on my deluge-shortcuts site, but it'd be nice if we worked together to make a standard so the community as a whole could benefit.

Anyway, people on the Discord told me to file this so we can converse.


Talking with the people on the Deluge Discord, there's an interest in creating a standard for the syntax that describes user interactions. The goals:

  • Have a syntax that's computer readable and human maintainable
  • Require all features to use this syntax as a form of documentation
  • Use this syntax to create user-facing documentation

The deluge-shortcuts site

This is basically what I've done on the deluge-shortcuts site. For instance:

    {
      title: "Cycle default scales",
      command: "hold(SHIFT) press(SCALE)",
      views: ["synth", "midi", "cv"],
    }
  • Pros:
    • Easy to write and maintain (the command itself is just a string)
    • Easy to render: each step is a control + action, relationship between steps is implied
  • Cons:
    • Ambiguity: "hold(SHIFT) press(SCALE) turn(SELECT)" should I still be holding shift when I turn select?

Discord proposal

Another solution was proposed on the Discord:

{
    "features": [
        {
            "name": "In-Key layout",
            "description": "Play notes only in scale",
            "keywords": ["keyboard", "performance"],
            "video": "https://youtube.com/video/kQmqdpUeciY"
        }
    ],
    "ux": [
        {
            "name": "Scroll through layouts",
            "context": "keyboard_screen",
            "actions": [
                {
                    "name": "Scroll negatively",
                    "modifier": {
                        "button": "SCALE",
                        "type": "hold"
                    },
                    "actionKey": "SelectionScrollLeft"
                }
            ]
        }
    ]
}
  • Pros
    • Able to be much more specific with the order of controls
  • Cons
    • More complex to write and maintain
    • More complex to render: steps can now be interrelated

The manual

The manual takes somewhat of a middle ground:

Screenshot 2023-12-18 at 9 08 58 AM

Notes on the screenshot:

  • The + sign indicates a combo
  • There's contextual notes for the combo: "Left most grid button"
  • There's an additional description

What is the expected behavior?

My proposal

I think wook's suggestion makes sense, although I might suggest something like:

const feature = {
  name: "Load sample (Silent)",
  description: "Load a sample into a kit of synth silently",
  views: [Views.Synth, Views.Kit],
  note: "Scroll to sample and press select. Also, Shift + Browse grid shortcut on an existing row to open browser.",
  steps: [
    {
      substeps: [
        {
          action: Actions.Hold,
          control: Controls.Shift,
        },
        {
          action: Actions.Hold,
          control: Controls.Audition,
        }
        {
          action: Actions.Press,
          control: Controls.Load,
        }
      ]
    },
    {
      action: Actions.Turn,
      control: Controls.Select,
    },
    {
      action: Actions.Press,
      control: Controls.Select,
    },
  ]
}

So I guess:

enum Action {
  PRESS,
  HOLD,
  TURN,
  TURN_LEFT,
  TURN_RIGHT,
  RELEASE, // not sure if we need this, but some guides have "release"
  SELECT, // maybe for menu options
}

enum Control {
  MENU, // when selecting things from the menu
  SELECT,
  SHIFT,
  AUDITION,
  X,
  Y,
  PARAMETER,
  LOWER_PARAMETER,
  UPPER_PARAMETER,
  AFFECT_ENTIRE,
  SONG,
  CLIP,
  SYNTH,
  KIT,
  MIDI,
  CV,
  KEYBOARD,
  SCALE,
  CROSS_SCREEN,
  BACK,
  LOAD,
  SAVE,
  LEARN,
  TAP,
  SYNC_SCALING,
  TEMPO,
  PLAY,
  RECORD,
  LAUNCH,
  AUDITION,
  EXTERNAL,
  // maybe don't need all of these
  GRID,
  GRID_PAD,
  GRID_PAD_LIT,
  GRID_PAD_UNLIT,
  GRID_ROW,
  GRID_COLUMN,
  // not sure about these if we have GRID_COLUMN
  WAVE_START,
  WAVE_END,
  WAVE_LOOP_START,
  WAVE_LOOP_END,
}

enum View {
  GLOBAL,
  SONG,
  ARRANGER,
  KIT,
  MIDI,
  CV,
  SYNTH,
  CLIP,
  AUDIO,
  WAVEFORM,
}

type GridPad = {
  x: number,
  y: number,
};

type Step = {
  action: Action,
  control: Control | GridPad,
  note?: string,
}

type Combo = {
  substeps: Array<Step>,
  note?: string,
}

type Feature = {
  name: string,
  views: Array<View>,
  steps: Array<Step | Combo>,
  description?: string,
  note?: string
}

I'm a little worried about the added complexity, but I think as long as combos can't contain combos it should be fine.

Steps

  • [x] Discuss and agree on a standard
  • [x] Pick a couple of the more complex combos
  • [x] Prototype a renderer that can handle the complex cases as a POC
  • [ ] Introduce the requirement to the firmware code base
  • [ ] Use the JSON from the firmware code base in the shortcut site

Is there a relevant Pull request?

No response

What hardware did you reproduce it with?

OLED

What firmware did you reproduce it with?

Release 1.0/Amadeus

What is the firmware name:

No response

If possible provide the steps to reproduce the issue and upload additional media:

No response

handeyeco avatar Dec 18 '23 19:12 handeyeco

Link to the discussion: https://discord.com/channels/608916579421257728/1181642842075058251/1186390844006207709

handeyeco avatar Dec 18 '23 19:12 handeyeco

Seems like a pretty perfect fit for JSON Schema.

trappar avatar Dec 18 '23 22:12 trappar

would be thrilled to see these icons i made for the discord used in some way on the shortcut site and/or in the documentation in some way. i'd be open to adding/iterating them where needed.

~deluge_icons_v1 1

ok-reza avatar Dec 19 '23 00:12 ok-reza

@PaulFreund Since the proposal is a tweak on your suggestion, I'm going to hold on starting until I get a thumbs up from you; that way I don't go down the wrong path.

handeyeco avatar Dec 21 '23 16:12 handeyeco

Hey :) Looks good I think! I propose we go with it and adapt if we see it's necessary during creation. Thank you for the great initiative!

PaulFreund avatar Dec 23 '23 22:12 PaulFreund

@PaulFreund I've updated the shortcut site with the new syntax.

Now it puts a "+" sign between steps for combos and generates more human-readable text.

Screenshot 2024-01-09 at 4 22 00 PM

It might not be the prettiest, but it works. Now I just need the new commands from the community firmware and I can add a switch between that and the official firmware.

handeyeco avatar Jan 09 '24 22:01 handeyeco

I agree with @PaulFreund start and the it can be iterated on. I started a Woovebox guide that uses a very simple notation standard it can be found here for interest https://docs.google.com/spreadsheets/d/1WmLYNVm-X8n1uwVZDU6j74C1CA56JChZIGH7ORkVmQA/edit#gid=1072776752

In short the notation for a Deluge task might look something like:

Task: Load synth to track in a kit clip Workflow:

  1. hAud+spSynth
  2. tSel (to find desired synth)
  3. spSel (on desired synth)

The Woovebox also has contexts like the Deluge (although it is better at maintaining cross context shortcut consistency than the Deluge). So for the above workflow I would describe the context as:

Mode: Song Page: Kit X

MichaelinVic avatar Apr 08 '24 01:04 MichaelinVic

  • Have a syntax that's … human maintainable

imo that would rather suggest to use YAML as format for human input.

funkyfuture avatar Jun 09 '24 10:06 funkyfuture

For the sake of avoiding confusion I might replace the SELECT action with something else depending on what you mean. Perhaps ENTER and HIGHLIGHT or similar.

As someone who has written a lot of it over the last 20 years, I would say please not YAML. From my research it seems that configuration languages are all generally pretty trash for one reason or another. KDL is probably the only one that is both nice and well supported. But JSON continues to be "good enough" for most things and enjoys ubiquity, however, so I would stick with that.

acook avatar Jun 18 '24 08:06 acook

As noticed in the PR where I'm working on the Performance View documentation, there are actually 4 different PRESS values distinct from HOLD.

  1. A configurable cutoff between a short and long press as used by Performance View, Sticky Shift, and Keyboard Sidebar
  2. A fixed half-a-second split for short and long presses used by other functions

I'm not totally sure how to distinguish them, but I think it's important to be able to do so.

  • QUICK_TAP / SLOW_TAP ? (performance)
  • SHORT_PRESS / LONG_PRESS (standard)

acook avatar Jun 20 '24 23:06 acook

I'm not using the Deluge much these days, so I'm going to bail on this issue. Y'all are welcome to adapt the work I've already done if it'll work for your needs!

handeyeco avatar Jun 21 '24 03:06 handeyeco