ReaFruit reference
For scripters and integrators: the ReaScript API, script parameter boxes, the MCP server, REAPER action ids, settings keys and the files ReaFruit reads and writes. The Manual covers the editor itself.
ReaScript API #
The extension exports a ReaFruit_* family to ReaScript. Lua and EEL2 call reaper.ReaFruit_CountNotes() and friends; REAPER's IDE completes them and Help › ReaScript documentation lists them. Scripts are ordinary ReaScripts: they run from the Actions list, keys, toolbars and gear › Scripts. Python reaches extension functions only through a generated ctypes module, which this version does not ship.
Conventions #
- Times are absolute project quarter notes (QN). Pitches are MIDI note numbers (60 = C4).
- A note's identity is its index, 0 to
CountNotes() - 1, stable between writes.DeleteNoteshifts later indices down; a write that rebuilds the model (EndEditreports it,Refresh, an undo) may reorder them. - Failures return
falseor-1;ReaFruit_GetLastError()says why. Out-parameters become extra return values in Lua. - Calls that write refuse while a mouse gesture, a parameter-box session or a batch is in progress; the error names the reason.
Editor and info #
| Function | Returns | Notes |
|---|---|---|
ReaFruit_IsOpen() | bool | True while the editor window is open. |
ReaFruit_GetTake(), ReaFruit_GetTrack() | MediaItem_Take*, MediaTrack* | The editor's take and its track. Use REAPER's MIDI_* on the take freely, then call Refresh. |
ReaFruit_OpenTake(take) | bool | Opens the editor on a take; nil = the selected item's active take. |
ReaFruit_Refresh() | int | Re-reads the take: 1 reloaded, 0 unchanged, -1 failed. |
ReaFruit_GetVersion(), ReaFruit_GetLastError() | string | The extension's version; why the last call failed. |
ReaFruit_GetInfo_Value(key) | number | Keys: api_version open batch tempo cursor_qn cursor_s play_state play_qn ts_num ts_den snap_index grid_qn sheet_mode track_clips px_per_qn scroll_qn key_h def_vel def_chan def_color def_len scale_root scale_idx scale_lock tune_hz bend_range mpe notes selected clips clip_cur item_qn0 item_qn1 track_index. |
ReaFruit_GetInfo_String(key) | bool, string | Keys: version reaper_version tool snap_name scripts_dir lane_key lane_name artmap nn_map model_version take_name track_name. |
ReaFruit_GetMousePosition() | bool, qn, pitch | The grid cell under the mouse in the last frame; a script run from a key knows where the mouse is. |
Notes #
| Function | Returns | Notes |
|---|---|---|
ReaFruit_CountNotes() | int | |
ReaFruit_GetNote(idx) | ok, sel, mute, startqn, endqn, chan, pitch, vel | The MIDI_GetNote shape, times in QN. |
ReaFruit_SetNote(idx, sel, mute, startqn, endqn, chan, pitch, vel) | bool | nil leaves a field unchanged. |
ReaFruit_InsertNote(sel, mute, startqn, endqn, chan, pitch, vel) | int | The new note's index. |
ReaFruit_DeleteNote(idx) | bool | Later indices shift down. |
ReaFruit_GetNoteInfo_Value(idx, parm), ReaFruit_SetNoteInfo_Value(idx, parm, value) | number / bool | Fields: B_SEL B_MUTE D_START D_END D_LEN I_PITCH I_VEL I_CHAN I_COLOR B_SLIDE B_VIB I_VSCALE I_TENSION D_VIBMS; read-only I_SWING I_CLIP D_HEAD D_TAIL I_BAR D_BEAT. Values are clamped. |
ReaFruit_GetSetNoteInfo_String(idx, parm, str, set) | bool, string | P_ARTICULATION (settable, by slot name), P_NAME, P_KEYNAME. |
ReaFruit_CountSelectedNotes(), ReaFruit_EnumSelectedNotes(idx) | int | Enum returns the next selected note after idx; start at -1. |
ReaFruit_SelectAllNotes(select) | bool | No undo step. |
Batches #
Every edit above writes the take at once as its own undo step. ReaFruit_BeginEdit() … ReaFruit_EndEdit(desc) makes them one write and one undo step named desc; EndEdit also returns whether the model reloaded. Inside a batch indices stay put, and actions that write the take are refused until it ends. Finish a batch in the same pass: one left open is written at the editor's next frame as "script edit". Per-note automation of moved notes follows; deleted notes' points are cleaned.
Clips, actions, settings #
| Function | Returns | Notes |
|---|---|---|
ReaFruit_CountClips(), ReaFruit_GetClip(idx), ReaFruit_GetClipTake(idx) | int; ok, startqn, endqn, current, name; take | The track-level clips. |
ReaFruit_RunAction(name) | bool | Runs an editor action by its ini name (the list plus copy, cut, paste, help). |
ReaFruit_EnumActions(idx) | ok, name, label, mutating | Lists the actions RunAction accepts. |
ReaFruit_GetSetting(key), ReaFruit_SetSetting(key, text), ReaFruit_EnumSettings(idx) | bool, string; bool; ok, key, type, desc | The settings keys, as text. |
The JSON gateway #
ReaFruit_CallTool(name, argsJson) runs any of the 30 MCP tools and returns the result's length (and whether it is an error); ReaFruit_GetResult(offset) hands the JSON text back in chunks. Unlike the MCP client, a script may place and move notes, and these calls never count against the license trial.
The helper library #
At load, the extension writes Scripts/ReaFruit/reafruit.lua into the resource folder: a JSON codec and wrappers. rf.notes(), rf.selected(), rf.targets() (the selection, or every note), rf.set(idx, {vel=, slide=, …}), rf.insert{qs=, len=, pitch=}, rf.delete, rf.select, rf.edit(fn, desc) (one undo step with error safety), rf.run, rf.setting, rf.tool(name, args) with Lua tables, rf.status(), rf.mouse(), rf.snap(qn), rf.boxes(title, defs, apply, done), and the automation wrappers rf.set_note_auto, rf.note_auto, rf.set_auto_points, rf.auto_points, rf.delete_auto_points, rf.lane_key(). A shipped file's first line is a marker; files with the marker are updated when a new version ships, files without it are yours.
package.path = reaper.GetResourcePath() .. '/Scripts/ReaFruit/?.lua;' .. package.path
local rf = require('reafruit')
rf.require_open()
rf.edit(function()
for _, n in ipairs(rf.selected()) do rf.set(n.idx, { vel = math.min(127, n.vel + 10) }) end
end, 'Louder')
Script parameter boxes #
A script can put up its own parameter boxes, at most eight, with the keep and discard pair, and preview its edits live as the user turns them, like Humanize.
Box definitions #
ReaFruit_BoxesBegin(title, boxesJson) opens them from a JSON array. Each box has a name, a type and an optional picture: bar (a range's default), knob, text (a choice's default), switch (a toggle's), die (a seed's).
| Type | Fields | Value |
|---|---|---|
range | min max default decimals unit | A number. |
choice | options (strings), wrap | The option's index from 0. |
toggle | default | 0 or 1. |
seed | default (optional) | A die: a click, its key or the wheel rolls a new number for math.randomseed. |
Kept values come back the next time boxes with the same title open; "remember": false opts a box out, and a seed rolls anew each time unless it has a default.
The poll loop #
The script polls ReaFruit_BoxesPoll() from a defer loop.
| Result | Meaning |
|---|---|
changed | The notes and automation are back as the boxes found them (the first poll too): read ReaFruit_BoxesGetValue(box) and apply the edits again as a preview. |
open | Nothing new. |
kept | Enter or the tick wrote everything as one undo step named after the title. |
cancelled | Escape or the X put everything back. |
none | No boxes are open. |
Automation previews too: what CallTool writes with the automation tools lands in REAPER at once and is restored on every changed and on a cancel. ReaFruit_BoxesSetValue(box, value) moves a box; ReaFruit_BoxesEnd(keep) closes them from the script. A script that stops polling for 1.5 s has its boxes cancelled; closing the editor or switching clips drops them. The helper wraps the whole loop as rf.boxes(title, defs, apply, done).
Native MIDI editor scripts #
gear › Scripts › Run as native MIDI editor script…, or a key slot assigned "as native", runs a script written for REAPER's MIDI editor against ReaFruit's take. reafruit_compat.lua redefines MIDIEditor_GetActive, MIDIEditor_GetTake, MIDIEditor_EnumTakes and MIDIEditor_GetMode around the editor's take, maps MIDIEditor_OnCommand to the editor's actions where one exists (select all, unselect, delete, copy, paste, cut, undo, redo, semitone and octave moves, grid nudges) and refreshes the editor afterwards.
MCP server #
An embedded Model Context Protocol server lets an LLM client read and edit the notes and settings of the running editor. It is off by default and listens only on localhost. It is the editor's one paid feature: the first 100 tool calls are free, status calls never count, and a license removes the limit. Enable it under gear › Advanced › MCP server (LLM access on localhost); the port submenu offers 7323 (the default), 7324, 7325, 8765 and 9765.
Client setup #
# Claude Code
claude mcp add --transport http reafruit http://127.0.0.1:7323/mcp
# stdio-only clients (Claude Desktop)
npx mcp-remote http://127.0.0.1:7323/mcp --allow-http
Tools #
Positions are project QN, pitches MIDI note numbers. Every note row carries its name, its clip and the bar and beat the ruler shows. status, list_tracks and the settings answer while the editor is closed; the note tools need it open on a MIDI take. Required parameters are in bold.
| Tool | Does | Parameters |
|---|---|---|
status | Editor and project state: defaults for new notes, MPE and bend range, the track's articulations and note names, the lane target, version and license, editable / blocked. | |
list_tracks | Tracks, their items and FX. | |
open_editor | Opens the editor on a track's MIDI item. | track_index, item_index |
get_notes | Notes, filtered and paged. | selected_only, pitch_min, pitch_max, from_qn, to_qn, chan, color, offset, limit |
add_notes | Refused over MCP (notes are the user's); available to scripts through CallTool. | notes[] {qs, qe or len, pitch, vel, chan, color or articulation, mute, slide, vib, vscale, ten, vib_ms}, select |
edit_notes | Edits note parameters by id; refuses qs, qe, len and pitch over MCP. | version, edits[] {id, …} |
delete_notes | Deletes by id or the selection. | version, ids[], selected |
select_notes | Changes the selection. | ids[], filter{}, mode (set, add, remove), all, none |
list_actions, run_action | The actions below; the note-moving ones are refused over MCP. | name |
get_settings, set_setting | The settings with ranges, choices and descriptions; change one. | key, value |
list_articulation_maps, get_articulation_map, set_articulation_map, create_articulation_map | The .txt maps and ReaBank banks; read one; put one on the track; write a new map from names with keyswitches or CC values and load it. | name; create: name, articulations[], overwrite, activate |
get_note_names, set_note_names | A track's note and CC names; write them as one undo step. | track_index; names[], replace |
list_note_name_maps, get_note_name_map, load_note_name_map, create_note_name_map | The files under MIDINoteNames; read, load, or write a new one in REAPER's format. | name; create: name, names[], overwrite, load |
list_automation_params | A track's automatable controls, FX parameters and MIDI CC lanes. | track_index, fx, automated_only, cc, offset, limit |
get_automation | An envelope's or CC lane's points, and the curve sampled on a QN grid. | track_index, param, from_qn, to_qn, step_qn, at_qn[] |
set_automation_points, edit_automation_points, delete_automation_points | Write, change or remove points on any track. | track_index, param, points[] / edits[] / a range, indices or all |
copy_automation | Reproduces one control's curve on another, by lane fraction. | from, to, from_qn, to_qn, offset_qn, replace, visible |
get_note_automation, set_note_automation | The editor's per-note lane values. | param, ids[]; values[], version, show_lane |
Controls are keyed by the lane target: track envelopes by name, FX parameters by plugin and parameter, MIDI controllers as cc:<n> or cc:bend (@<chan> for one channel, /<item> for another item), or by the names mod, expression, breath, sustain and bend. Lanes the editor writes itself come back locked.
run_action names #
Names marked * change notes and are refused over MCP; scripts may run them.
play_stop go_to_start select_all deselect clear_selection select_color toggle_ghosts follow bass_line pan_left pan_right pan_up pan_down zoom_in zoom_out tool_draw tool_paint tool_delete tool_mute tool_slice tool_select
duplicate* glue* legato* legato_slide* chop* undo* redo* redo_alt* octave_up* octave_down* transpose_up* transpose_down* nudge_left* nudge_right* recolor* quantize_quick* delete_notes* delete_notes_alt* slide_mode* vibrato_mode*
set_setting keys #
| Key | Type | Meaning |
|---|---|---|
tool | enum | draw, paint, delete, mute, slice, select |
snap_idx | int | The snap grid, by index into the snap names |
follow, follow_pin | bool, int | Scroll with playback; where the playhead sits, percent of the view (-1 = page) |
smooth_scroll, note_anim | bool | Eased scrolling; note animations |
ghosts, ghost_colors | bool | Ghost notes; in their track's colour |
bendlines, bass_line, tempo_flags | bool | Slide curves; the bass threshold line; the tempo flags |
lasso_grid, lasso_vel | bool | The magic lasso on the grid and on the lane |
preview_chord, art_labels | bool | Chord preview while dragging; articulation labels |
mpe_default, legslide_lead | bool | New takes start in MPE; legato slides lead into the next chord |
vel_closed, lane_pts, vel_h | bool, bool, number | The lane shut; edited as points; its height in px (36 to 500) |
pb_scale | int | Parameter box size: 100, 125 or 150 |
track_clips | bool | Track-level clips (the model reloads) |
scale_root, scale_idx, scale_lock, scale_flats | int, int, bool, bool | Root pitch class (0 = C); scale index (0 = off); lock; flats |
cur_color, bend_range | int | The colour slot new notes get (0 to 15); default bend range (1 to 48) |
last_vel, last_len | int, number | The velocity and length new notes get |
px_per_qn, key_h | number | Horizontal zoom (6 to 900 px per QN); row height (6 to 30 px) |
autofollow | bool | The background helper |
mcp_on, mcp_port | bool, int | Read-only: the server itself |
Rules and refusals #
- Notes are the user's. The server never creates or moves notes:
add_notesis refused,edit_notesrefuses position and pitch fields,run_actionrefuses the actions marked above. The model edits note parameters (velocity, channel, colour and articulation, mute, selection, slide and vibrato with depth, tension and rate), deletes, selects, and shapes automation, CC lanes and the maps. - Note ids are indices valid only for the
versionthey came with; a stale version is refused, naming the current one. A reply sayingreloaded: truemeans every id may have changed. - One undo step per mutating call.
- Refusals are tool errors with the reason: the editor is closed, a mouse gesture or a box session is in progress, an edit is still being written.
statusreports the same aseditableandblocked. - The handshake explains slide and vibrato notes as the editor renders them, and asks the model to use them where the music calls for it;
statuscarriesmpeandbend_rangeso slides stay within reach.
Transport #
A loopback listener thread reads each request and hands it to REAPER's main thread, which runs it against the editor's model between frames, never inside one. A request the main thread does not reach within 5 s (REAPER busy, a modal dialog up) gets 504. POST one JSON-RPC message to /mcp and read application/json back; no SSE stream (GET answers 405), stateless, protocol version 2025-06-18.
REAPER actions #
Main section #
Named command ids, for reaper.NamedCommandLookup("_REAFRUIT_MIDI_EDITOR") and the like. Each is listed as ReaFruit MIDI Editor: ….
| Command id | Action |
|---|---|
_REAFRUIT_MIDI_EDITOR | Open/toggle editor (reports its toggle state) |
_REAFRUIT_MIDI_EDITOR_OPEN | Open editor or media item properties (mouse modifier) |
_REAFRUIT_MIDI_EDITOR_RECENTER | Move window to the mouse cursor |
_REAFRUIT_TB_SHEET, _REAFRUIT_TB_SNAP, _REAFRUIT_TB_SCALE | Toggle Sheet Music Mode; Snap menu; Toggle Scale Lock |
_REAFRUIT_TB_TOOL_DRAW, _PAINT, _DELETE, _MUTE, _SLICE, _SELECT | The six tools |
_REAFRUIT_TB_CHOP, _REAFRUIT_TB_SLIDE, _REAFRUIT_TB_VIBRATO, _REAFRUIT_TB_CHORD_STAMP | Chop; Toggle slide mode; Toggle vibrato mode; Chord stamp menu |
_REAFRUIT_TB_HUMANIZE, _REAFRUIT_TB_STRUM, _REAFRUIT_TB_QUANTIZE, _REAFRUIT_TB_SWING | The box sessions |
_REAFRUIT_TB_TARGET, _REAFRUIT_TB_WAVEFORM | Toggle toolbar target name; Toggle waveform background |
Scripts run from gear › Scripts are registered in the main section the first time they run.
The editor section #
The Actions window's section ReaFruit MIDI Editor (section id 0x52464D45) holds one command per editor action. The command id is 42000 plus the action's index below; the name is what reafruit_keys.ini and ReaFruit_RunAction use. Scope: A = anywhere, R = piano roll only, S = Sheet Music Mode, I = sheet note input only.
| Id | Name | Label | Default | Scope |
|---|---|---|---|---|
| 42000 | play_stop | Play/stop transport | Space | A |
| 42001 to 42002 | select_all, deselect | Select all / Deselect all notes | Ctrl+A, Ctrl+D | A |
| 42003 to 42006 | copy, cut, paste, duplicate | Copy / Cut / Paste at playhead / Duplicate notes | Ctrl+C, Ctrl+X, Ctrl+V, Ctrl+B | A |
| 42007 to 42009 | glue, legato, chop | Glue notes / merge clips; Legato; Chop notes to grid | Ctrl+G, Ctrl+L, Ctrl+U | A |
| 42010 to 42012 | undo, redo, redo_alt | Undo; Redo; Redo (alternate) | Ctrl+Z, Ctrl+Y, Ctrl+Shift+Z | A |
| 42013 to 42018 | octave_up, octave_down, transpose_up, transpose_down, nudge_left, nudge_right | Octave; transpose; nudge | Ctrl+Up/Down, Shift+Up/Down, Shift+Left/Right | A |
| 42019 to 42020 | toggle_ghosts, recolor | Toggle ghost notes; Recolor with picked color | Alt+V, Alt+C | A |
| 42021 to 42026 | tool_draw, tool_paint, tool_delete, tool_mute, tool_slice, tool_select | Tool: … | P, B, D, T, C, E | R |
| 42027 to 42029 | slide_mode, vibrato_mode, follow | Slide notes; Vibrato notes; Scroll with playback | S, V, F | R, R, A |
| 42030 to 42033 | delete_notes, delete_notes_alt, clear_selection, go_to_start | Delete selected notes / points; Clear selection; Go to project start | Delete, Backspace, Escape, Home | A |
| 42034 to 42039 | pan_left, pan_right, pan_up, pan_down, zoom_in, zoom_out | Pan the view; zoom the timeline | Left, Right, Up, Down, PageUp, PageDown | A (pan up / down: R) |
| 42040 to 42044 | humanize, strum, select_color, quantize_quick, quantize | Humanize; Strum; Select notes of the picked color; Quick quantize; Quantize | Alt+H, Alt+S, Shift+C, Ctrl+Q, Alt+Q | A |
| 42045 to 42046 | sheet_mode, sheet_input | Sheet music mode; Sheet: note input mode | Tab, N | A, S |
| 42047 to 42056 | sheet_dur_whole … sheet_dur_32nd, sheet_dot, sheet_tie, sheet_tie_alt, sheet_rest | Durations; dotted; tie; rest | 7 6 5 4 3 2, ., Shift+=, keypad +, 0 | S (ties: I) |
| 42057 to 42070 | sheet_pitch_a … g, sheet_chord_a … g | Enter a pitch; add it to the chord | A to G, Shift+A to G | I |
| 42071 to 42080 | sheet_pitch_up/down, sheet_diat_up/down, sheet_octave_up/down, sheet_prev/next, sheet_bar_prev/next | Pitch by semitone, scale step, octave; previous / next note, measure | Up/Down, Alt+Shift+Up/Down, Ctrl+Up/Down, Left/Right, Ctrl+Left/Right | S |
| 42081 to 42089 | sheet_halve, sheet_double, sheet_repeat, sheet_respell, sheet_flat, sheet_natural, sheet_sharp, sheet_voice1, sheet_voice2 | Halve / double duration; repeat; respell; accidentals; voices | Q, W, R, J, -, \, =, Ctrl+Alt+1, Ctrl+Alt+2 | S |
| 42090 to 42094 | sheet_staccato, sheet_accent, sheet_tenuto, sheet_marcato, sheet_input_exit | Articulations; leave note input | Shift+S, Shift+V, Shift+N, Shift+O, Escape | S, exit: I |
| 42095 to 42097 | sheet_dur_64th, sheet_stem_flip, sheet_slur | 64th note; flip stems; slur | 1, X, S | S |
| 42098 to 42105 | sheet_tuplet2 … 7, sheet_insert, sheet_remove_time | Duplet to septuplet; insert mode; remove time | Ctrl+2 to Ctrl+7, Ctrl+Shift+I, Ctrl+Delete | S |
| 42106 to 42110 | legato_slide, lasso_show, pattern_mode, lane_last_touched, bass_line | Legato with slides; lasso path (hold); pattern mode (hold); last touched FX parameter; bass threshold line | Ctrl+Alt+L, L, `, Alt+A, Alt+B | A, R, R, R, R |
| 42111 to 42115, 42117 to 42120 | param_box_1 … 9 | Parameter box N (hold + wheel, or press) | 1 to 9 | R |
| 42116, 42121, 42122 | arpeggiator, arp_glue, chord_stamp | Arpeggiator boxes; glue the pattern; Chord stamp boxes | Alt+R, Ctrl+Enter, Alt+T | R |
| 42123 to 42130 | script_1 … 8 | Run script slot N | unbound | A |
| 42131 to 42133 | swing, warp, tempo_change | Swing boxes; Time warp; Tempo change at the edit cursor | Alt+Shift+S, Alt+W, unbound | R, R, A |
| 42134 | help | Open the manual for the item under the mouse | F1 | A |
Settings and files #
reaper-extstate.ini #
Settings persist in REAPER's reaper-extstate.ini under the section [FL_PianoRoll]. The keys below are the user-facing ones; lic_*, upd_*, note_done, defaults_v and script_boxes:* are the extension's own bookkeeping.
| Keys | Meaning |
|---|---|
follow follow_pin smooth_scroll pb_scale ghosts ghost_colors track_clips wave wave_pitch bendlines bass_line tempo_flags note_anim sheet_ghost_grand sheet_min64 sheet_extend hirate hirate_fps no_dock | The View menu |
lasso_grid lasso_vel preview_chord | The Edit menu |
mxl_tempo mxl_rename mxl_piano mxl_noslur mxl_nodyn mxl_dedup a2m_quantize a2m_* | The File menu and the audio-import boxes |
legslide_lead art_labels artmap_last groove_last | The Tools menu |
toolbar_hide toolbar_src | The Toolbar menu |
autofollow hirate_split mac_click_guard mcp_on mcp_port upd_enabled | The Advanced menu |
tool snap_idx cur_color scale_root scale_idx scale_lock scale_flats scale_cmask scale_cname detect_favor_builtin bend_range mpe_default | The toolbar's state |
last_vel last_vibvel last_vibscale last_vibms last_len | The defaults new notes get |
vel_h vel_closed lane_pts px_per_qn key_h sheet_mode sheet_dur | The lane, the zoom, the sheet |
stamp_type stamp_add stamp_inv stamp_inv_auto stamp_bass | The chord stamp boxes |
mouse_map | The mouse modifier table (non-default cells only) |
script_slot_1 … script_slot_8 | The key slots (a native: prefix marks a native MIDI editor script) |
docs_url | Where the help key finds the manual: a web address or a local folder |
ix_bridge_dir | The Instrument X bridge folder |
Track and clip data #
| Key | On | Holds |
|---|---|---|
P_EXT:flpr_lane | track | The lane's target: vel, swing, fx:<guid>:<param>, env:<chunk>, cc:<n>, tempo |
P_EXT:flpr_lanes | track | The extra lanes: <target>;<points>;<height>|… |
P_EXT:flpr_mpe | track | MPE on for this track |
P_EXT:flpr_ghost | take | Ghostable (this clip) |
P_EXT:flpr_ends | take | The drawn ends of slide and vibrato notes nested in their host |
The scale is also saved per project. Note colours, slides, vibrato and per-note automation are stored as tags in the take, so a project opened without the extension keeps playing.
Data folders #
| Folder (in the REAPER resource path) | Holds |
|---|---|
Data\ReaFruit Articulations\*.txt, Data\**\*.reabank | Articulation maps and ReaBank banks |
Data\Grooves\*.rgt | Swing grooves |
Data\ReaFruit Shapes | Saved lane shapes |
MIDINoteNames | Note-name maps in REAPER's format |
Scripts\ReaFruit | The helper, the compat shim, the examples, your scripts |
Data\reafruit_keys.ini | Fallback key bindings |
reafruit_keys.ini #
One line per action, action = [ctrl+][shift+][alt+]key, for example duplicate = ctrl+shift+d. ctrl means Cmd on macOS; cmd and option are accepted as aliases for ctrl and alt; none unbinds. Key names: letters, digits, f1 to f24, up down left right space enter tab escape backspace delete insert home end pageup pagedown comma period slash semicolon apostrophe minus equals leftbracket rightbracket backslash grave and the keypad. Missing lines keep their defaults; a shortcut set in REAPER's Actions window always wins. The file is created with the defaults when missing and re-read when the editor opens.
ReaFruit MIDI Editor v0.9.6-beta · Manual