Reorganize top-level directories with clearer naming convention

app -> app-desktop-macos, presets -> app-presets, server -> remote-server,
daw-config-reaper -> osc-config-daw, plugin-reaper-realearn -> plugin-reaper-relearn.
Updated run.py and presets.py path references accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Paul Lipscomb
2026-07-15 17:51:05 -04:00
parent e58f06d9fa
commit 7ecc718f5d
2256 changed files with 11 additions and 5 deletions
@@ -0,0 +1,4 @@
indent_type = "Spaces"
# This is important. We use Lua primarily for building large data structures and omitting
# the parentheses is what makes this very readable.
call_parentheses = "NoSingleTable"
@@ -0,0 +1,14 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"johnnymorganz.luau-lsp",
"johnnymorganz.stylua"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
]
}
@@ -0,0 +1,4 @@
{
"luau-lsp.types.roblox": false,
"luau-lsp.sourcemap.enabled": false
}
@@ -0,0 +1,192 @@
# Compartment preset workspace
This folder is a ReaLearn compartment preset workspace. It should be a direct sub folder of the
ReaLearn
controller or main preset folder. The purpose of this folder is to contain a set of ReaLearn
compartment presets
and provide you with a convenient workspace to develop those presets.
## Choosing a good folder name
If you have created this workspace via ReaLearn, it will have an auto-generated name. As explained
further below,
the name of the workspace folder becomes part of the preset ID! Therefore, make sure to do one of
the following
things:
- **Either** rename this folder to a proper identifier of your choice (a name with only lowercase
letters and dashes,
e.g. `foo-bar`). A good default choice is to rename it to your operating system login name. If you
have already
saved presets from the ReaLearn user interface, that folder will probably already exist.
- **Or** copy all the files that you need from it to an already existing other workspace folder and
delete this one.
## Sharing presets with other users
Each workspace is completely self-contained, that means you can easily share it with other users
without having to worry about possible name conflicts or missing files:
1. You pass the complete workspace folder to the other user (e.g. by zipping and mailing it or by
using cloud sharing).
2. The other user switches to the correct compartment and presses "Menu → Compartment presets → Open
compartment preset folder" and puts your workspace folder into it.
3. The other user presses "Menu → Compartment presets → Reload all compartment presets from disk".
## Directory structure
The meaning of each file in this folder is determined by its file extension.
### Compartment presets
Compartment preset files within this folder can be arbitrarily nested. But be aware that the
preset's file path relative
to the controller or main preset folder is at the same time its ID! If you change its location or
name, you will make
it a different preset as far as ReaLearn is concerned!
**Example:** If the name of your workspace folder is `john` and you put your preset in
`john/foo/daw-control.json`,
the preset ID will be `john/foo/daw-control`.
Tips:
- Factory presets always begin with `factory`. This workspace name is reserved, so you shouldn't use
it. There's no way
to override factory presets.
- Presets can also reside directly in the main/controller preset folder, not in a workspace folder.
This was normal
in the past but is deprecated now. Such presets will show up as "Unsorted" in ReaLearn's preset
picker.
Presets can be written in the following different formats.
### Compartment presets in JSON format
**File extension:** `.json`
ReaLearn will read all files with this extension as compartment presets written
in [JSON](https://www.json.org/) format.
A JSON preset is essentially a big data structure that describes the contents of one ReaLearn
compartment, such as
mappings and groups. JSON presets are simple and verbose. They don't contain any logic and can
become very
repetitive.
It's the format in which ReaLearn saves presets whenever you use "Save as..." in the user
interface. For all other purposes, it's not recommended to use JSON! If you want to code your own
presets,
you should use the Luau format instead.
### Compartment presets in Luau format
**File extension:** `.preset.luau` or `.preset.lua`
ReaLearn will read all files with this extension as compartment presets written
in [Luau](https://luau-lang.org/).
A Luau preset is written in a real programming language. It contains a Luau program whose single
purpose is to return
a result. And that result should look very similar to the big data structure of JSON presets.
In addition to the actual Luau code, Luau compartment presets contain a meta-data section right at
the top,
which contains the name of the preset and other data that can be scanned by ReaLearn before actually
loading the
preset by executing its code.
If you have chosen to create this workspace with factory presets, you should find multiple Luau
presets in this folder
that can serve as starting point for building your own presets. You will realize that many of them
use Luau type
annotations and helper methods, which enables auto-completion during development and should make the
preset code
more understandable. If you want to learn more about this, read the section below.
As an additional help, you can use "Export to clipboard → Export ... compartment as Lua" in
ReaLearn. This gives you
a chunk of text formatted as Luau. It doesn't contain any logic, it looks more like a configuration
file
but its valid Luau code. This chunk of text is not a ready-made preset (because it's meant to be
used with
"Import from clipboard"). But you will see that a big part of the chunk is exactly the same kind of
data structure that you need to generate as part of a Luau preset.
### Reusable Luau modules
**File extension:** `.luau` or `.lua` (without `.preset`)
The workspace folder can contain Luau files that are not presets. ReaLearn ignores them when
scanning for
presets. But you can make use of them to make preset development more convenient.
Let's assume you have a function that you need in more than one preset. Instead of pasting it into
each preset, you can
put that function into a module and require it in each preset. Luau presets can use the function
`require()` to include
Luau modules that are located in the same workspace. The path passed to `require()` is always
relative to the workspace
root folder.
**Example:** `local my_module = require("my_module")` makes the contents of module `my_module.luau`
available in your
preset.
When ReaLearn creates a workspace for you, it will put a few useful modules into your workspace
root. You are free
to use them for developing your own presets. The most important file is `realearn.lua`, which
contains Luau type
declarations and helper functions. Have a look at the factory presets to see how to make use of
them.
Having said all that ... you don't need to use any type declarations, annotations or helper
functions, they are
completely optional. As long as the value that your script returns is a table and all the entries in
that table
meet ReaLearn's expectations, you are good.
## Basic process of coding presets
The basic process of coding presets goes like this:
1. Open the preset in your text editor
2. Make modifications
3. In ReaLearn, choose "Menu → Compartment presets → Reload all compartment presets from disk"
4. Find the preset in the preset menu and (re)load it into your compartment
If you code presets that reside in your *user workspace* (the folder that has the same name as your
operating-system
username), a welcome shortcut is available:
1. Open the preset in your text editor
2. Make modifications
3. Copy the complete code to the clipboard
4. In ReaLearn, press "Import from clipboard"
This doesn't "officially" load the preset but imports its contents, which has almost the same
effect. Please note that
ReaLearn can't detect from where you copied the code. That's why if the copied Luau code uses
`require()`, ReaLearn
will look for the required module **in the user workspace only**.
## Development environment
You can use *any* text editor to code ReaLearn presets. For basic auto-completion and other goodies,
it should
have special support for the [Luau](https://luau-lang.org/) language.
For a good coding experience right out of the box, I can
recommend [Visual Studio Code](https://code.visualstudio.com/).
The workspace created by ReaLearn is pre-configured to play nice with it:
1. Open Visual Studio Code
2. File → Open Folder... → Choose the workspace directory (in which this `README.md` file is
located) and press "Open"
3. View → Command Palette... → Search for "Extension: Show Recommended Extensions"
4. Install the recommended extensions
Now you are good to go! Open one of the factory presets and enjoy all syntax highlighting, code
completion,
code formatting, etc. :)
@@ -0,0 +1,49 @@
--!strict
--- Contains types for building ReaLearn feedback scripts in Lua.
local module = {}
--- Provides access to some data that might come in useful to create the feedback value.
export type Context = {
--- Queries arbitrary properties, e.g. target or mapping properties.
---
--- Those properties are the very same properties that you can use in textual feedback.
prop: (key: string) -> any?
}
--- You are supposed to return a value structured like that.
export type Output = {
--- Feedback event.
feedback_event: FeedbackEvent,
}
--- Feedback event.
export type FeedbackEvent = {
--- Feedback value (the most important piece of information to return).
---
--- Can either be ...
---
--- - ... a string (ideal for display sources)
--- - ... a number (ideal for LEDs and motor faders)
--- - ... nil (which means "turn source off", e.g. turn off the LED, turn down the motor fader, clear the display text)
--- - ... or anything else: `true`, `false` or an arbitrary table. The latter is currently only useful for the MIDI script source
--- because other sources don't support arbitrary tables.
value: any?,
--- Main color.
---
--- Either the default color (= `nil`) or an RGB color.
color: RgbColor?,
--- Background color.
---
--- Either the default color (= `nil`) or an RGB color.
background_color: RgbColor?,
}
--- Color in the RGB color system.
export type RgbColor = {
r: number,
g: number,
b: number,
}
return module
@@ -0,0 +1,80 @@
--!strict
--- Contains types for building ReaLearn MIDI scripts in Lua.
local module = {}
--- Type of the `y` variable in MIDI scripts, which represents the input value of the MIDI script.
---
--- This input value is usually generated by the "Target" and/or the "Glue" section.
export type InputValue = OffInputValue | NumericInputValue | TextInputValue | ComplexInputValue
--- Whenever the input value is `nil`, ReaLearn wants you to "switch off" feedback.
---
--- Meaning of "switch off" depending on the type of feedback element:
---
--- - LED: Switch LED off
--- - Motor fader: Tear it completely down
--- - Text display: Clear all characters
export type OffInputValue = nil
--- A simple numeric value.
---
--- ReaLearn sends this if the feedback type in the "Glue" section is set to "Numeric feedback".
---
--- Currently, this should always be a value within the unit interval, that is a value between 0.0 (= 0%)
--- and 1.0 (= 100%).
export type NumericInputValue = number
--- A chunk of text.
---
--- ReaLearn sends this if the feedback type in the "Glue" section is set to "Textual feedback".
---
--- This is obviously most useful for text displays. But it can also be used for LED. When you design
--- a virtual control scheme, you could for example declare that the text "blinking" should make the LED blink.
export type TextInputValue = string
--- A value that could be anything, from a simple number to a complex table.
---
--- ReaLearn sends this if the feedback type in the "Glue" section is set to "Dynamic feedback".
export type ComplexInputValue = any
--- Provides access to some data that might come in useful to create the outgoing MIDI messages.
export type Context = {
feedback_event: FeedbackEvent
}
--- More data about the feedback event which triggered the execution of this MIDI script.
export type FeedbackEvent = {
--- Color as set in the "Glue" section.
---
--- Either the default color (= `nil`) or an RGB color.
color: RgbColor?,
--- Background color as set in the "Glue" section.
background_color: RgbColor?,
}
--- Color in the RGB color system.
export type RgbColor = {
r: number,
g: number,
b: number,
}
--- You are supposed to return a value structured like that.
export type Output = {
--- Feedback address.
---
--- Each distinct feedback element on the controller (LED, motor fader, etc.) should get a unique feedback address.
--- If you get this value wrong or don't set it at all, you might experience weird feedback behavior, e.g. LEDs that
--- stay on or switch off when they shouldn't.
address: number?,
--- A list MIDI messages to be sent to the controller.
messages: { MidiMessage }
}
--- Array containing the raw bytes of a MIDI message.
---
--- You can express any kind of MIDI message with that.
export type MidiMessage = { number }
return module
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
--!strict
--- Contains types and function stubs for building presets. The actual function implementations are provided
--- by the runtime.
local module = {}
--- Returns the content of the given file as string.
---
--- The given path is always relative to the module root.
---
--- This function is very useful when you build a preset in which the compartment contains commona Lua code.
--- Instead of writing the common Lua code as a Lua string, you can include it from a dedicated file. That way,
--- you can benefit from syntax highlighting and typechecking when building the common Lua code.
function module.include_str(path: string): string?
return nil
end
return module
File diff suppressed because it is too large Load Diff