Skip to content

Commit

Permalink
v2.0~alpha release(#58)
Browse files Browse the repository at this point in the history
* Add Reapack installer
* Remove all autogenerated scripts (internal/rk.lua is the only one now)
* Fix key bindings menu non-monospace fonts on Linux
* Reset state on <ESC> correctly
* Handle clashes of NumLeft,Right,Up,Down with shifted characters
* Use a single config file internal/definitions/config.lua
* Move images to ImgBB
* Support more characters: F1-F12, Insert, Delete, ^, and *
* Add few more key bindings like C-. (repeat last action excluding the
  reaper-keys one
* Flatten key bindings structure
* Fix firstTrack/lastTrack bug on empty project
* Add performance profiler option
* Format some of code
  • Loading branch information
myrrc committed May 21, 2024
1 parent 8435f68 commit 7ae3200
Show file tree
Hide file tree
Showing 1,200 changed files with 2,642 additions and 18,049 deletions.
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
internal/saved/data/*
internal/gui/feedback/model_data.lua
!/internal/saved/data/.gitkeep
internal/gui/feedback/model_data.lua
internal/state_machine/state.lua
actions-runner
Scripts/gen
reaper-keys.ReaperKeyMap

3 changes: 3 additions & 0 deletions .luarc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"diagnostics.globals": [ "reaper", "gfx" ]
}
Empty file removed .projectile
Empty file.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2016 ggVGc
Copyright (c) 2016-2024 ggVGc, myrrc

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
127 changes: 67 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,107 +1,114 @@
# Reaper-Keys
# Reaper keys

<p align="center">
<img src="img/reaper-keys.png">
</p>
<p align="center"><img src="https://i.ibb.co/QHrVqNK/reaper-keys.png" alt="reaper-keys" border="0" /></p>

Reaper-Keys is an extension for the [REAPER DAW](https://www.reaper.fm/), that provides a new action
mapping system based on key sequences instead of key chords. The system is
similar to [Vim](https://en.wikipedia.org/wiki/Vim_%28text_editor%29), a modal text editor, and by default comes with vim-like bindings.
Reaper keys is an extension for the [REAPER DAW](https://www.reaper.fm/) that provides a
new action mapping system based on key sequences instead of key chords. The system is
similar to [Vim](https://en.wikipedia.org/wiki/Vim_%28text_editor%29), a modal text
editor, and by default comes with vim-like bindings.

Click [here](https://youtu.be/ChuZswEfQuo) for a very outdated and low quality demo and installation video.
Click [here](https://youtu.be/ChuZswEfQuo) for a very outdated and low quality demo and
installation video.

## Pros

- Save a couple minutes per hour
- Develop arthritis at 60 instead of 40
- Reduce mouse usage
- Increase maximum bandwidth between your brain and your project
- A structure for reapers giant bag of actions
- A structure for Reaper's giant bag of actions

# Table of Contents

1. [Features](#Features)
1. [Bind key sequences](#Bind-key-sequences)
2. [Compose actions](#Compose-actions)
3. [Multi-modal](#Multi-modal)
4. [Macros](#Macros)
3. [Installation](#Installation)
4. [Help](#Help)
5. [Further Information](#Further-Information)
## Installation

- Add `https://raw.githubusercontent.com/gwatcha/reaper-keys/master/index.xml` to Reapack.
- Optionally, install [SWS](https://sws-extension.org/) (by hand or from ReaTeam
Extensions). Although this extension _may_ work without SWS, the experience will be
worse.

## Features

### Bind key sequences

With reaper-keys, you may bind key sequences to actions, rather then singular
key presses. This allows one to hierarchically organize many keybindings for easy access to many keybindings.
With Reaper keys you may bind key sequences to actions rather then singular key presses.
This allows one to hierarchically organize many keybindings.
A completion/feedback window is provided to assist with command completion.

A completion/feedback window is provided to assist with command completion.

![img](img/completions.gif)
<a href="https://ibb.co/N3fgVYP"><img src="https://i.ibb.co/N3fgVYP/completions.gif" alt="completions" border="0" /></a>

### Compose actions

Reaper-keys lets one compose actions of different types to create new commands.

For example, in normal mode, any action with `timeline motion` type can follow any one with `timeline operator` type.
Reaper keys lets one compose actions of different types to create new commands. For
example, in normal mode, any action with `timeline motion` type can follow any one with
`timeline operator` type. So if one enters `tL`, it would compose into `(t ->
"PlayAndLoop", L -> "NextMeasure")`, and play and loop the next measure.

So if one enters `tL`, it would compose into `(t -> "PlayAndLoop", L -> "NextMeasure")`, and play and loop the next measure.
Other examples of `timeline operator` bindings are `s` -> "SelectItemsAndSplit" , or `z`
-> "ZoomTimeSelection", so you could also enter `sL` or `zL`.

Other example `timeline operator` bindings are `s` -> "SelectItemsAndSplit" , or `z` -> "ZoomTimeSelection", so you could also enter `sL` or `zL`.
<a href="https://ibb.co/j8QfT0c"><img src="https://i.ibb.co/j8QfT0c/compose.gif" alt="compose" border="0" /></a>

![img](img/compose.gif)

This grows the number of available actions exponentially but still preserves your
brain, as you only need to know the `timeline_motions`, `timeline_operators`, and
the fact that you can compose them.
This grows the number of available actions exponentially but still preserves your brain,
as you only need to know the `timeline_motions`, `timeline_operators`, and the fact that
you can compose them.

### Multi-modal

Changing modes changes the way keys compose. By default, it is in `normal` mode, but you could for example go into `visual timeline` mode by pressing `v`.
Changing modes changes the way keys compose. By default, it is in `normal` mode, but you
could for example go into `visual timeline` mode by pressing `v`.

In this mode, `timeline motions` extend the current time selection, and `timeline actions` operate immediately and return one to `normal` mode. Useful if you want
visual feedback before executing a timeline action, or just want to extend the
time selection using motion commands.
In this mode, `timeline motions` extend the current time selection, and `timeline actions`
operate immediately and return one to `normal` mode. Useful if you want visual feedback
before executing a timeline action, or just want to extend the time selection using motion
commands.

![img](img/visual_mode.gif)
<a href="https://ibb.co/64Md00Z"><img src="https://i.ibb.co/64Md00Z/visual-mode.gif" alt="visual-mode" border="0" /></a>

### Macros

Macros are a way to save a sequence of commands, and play them back later.

To record a macro, enter `q` and an arbitrary character to specify the `register` that
the macro will save into. Then, perform a series of actions, and finish
recording by pressing `q`.
To record a macro, enter `q` and an arbitrary character to specify the `register` that the
macro will save into. Then, perform a series of actions, and finish recording by pressing
`q`.

![img](img/macro_rec.gif)
<a href="https://ibb.co/z7zsS81"><img src="https://i.ibb.co/z7zsS81/macro-rec.gif"
alt="macro-rec" border="0" /></a>

You may play it back by entering `@` and the character you specified earlier.
Optionally, prefix it with a number to indicate the number of repetitions.
You may play it back by entering `@` and the character you specified earlier. Optionally,
prefix it with a number to indicate the number of repetitions.

![img](img/macro_play.gif)
<a href="https://ibb.co/884T1fR"><img src="https://i.ibb.co/884T1fR/macro-play.gif" alt="macro-play" border="0" /></a>

## Installation
## Help

- Clone this repository or download it via the 'releases' tab (download the file 'reaper-keys.zip').
- Put this repository into your `REAPER/Scripts` directory . If you're unsure where your `REAPER` directory is, just run the action 'Show REAPER resource path in explorer' in REAPER.
- Back up your key map by exporting it, then import the provided keymap `reaper-keys.ReaperKeyMap` via the `import` button at the bottom of the action list window in Reaper. (This will overwrite your current key bindings!)
- For all the actions to work, install the [SWS/S&M](https://sws-extension.org/) extension for Reaper.
Enter `<CM-x> (Ctrl + Alt + x)` to show a list of available bindings you can search and
filter.

When you restore your old keymap, you may want to empty the `reaper-kb.ini` in your `REAPER` root directory and restart REAPER. Otherwise, there will likely be remnants from reaper-keys.
<a href="https://ibb.co/hdd7HrH"><img src="https://i.ibb.co/hdd7HrH/binding-list.gif" alt="binding-list" border="0" /></a>

## Help
If you're stuck in a state you don't know how to get out of, you can press `<ESC>` to
reset back to normal.

Also, if your key press is not being detected, try unfocusing the feedback window.

Enter `<M-x>` to show a list of available bindings you can search and filter.
## Tweaking

![img](img/binding_list.gif)
```
internal/definitions/actions.lua -> add actions
internal/definitions/bindings.lua -> add or customise key bindings
internal/definitions/config.lua -> change GUI settings
```

If your stuck in a state you don't know how to get out of, you can press `<ESC>` to reset back to normal.
## Reporting performance issues

Also,
If your key press is not being detected, try unfocusing the feedback window.
If a dialog opens saying 'script is already running in the background' just click 'remember' and 'new instance'.
1. Download "Lua profiler" from ReaTeam Scripts and "ReaImGui" from ReaTeam Extensions via
ReaPack.
2. Change "profile" to "true" in internal/definitions/config.lua
3. In Reaper, click Actions > Running script > rk.lua > Terminate instances. There may be
no "Running script", then just skip this step.
4. Press any key. A profiler window will open.
5. Click "Acquisition > Stop" in the profiler window after you're done
6. Click "Copy to clipboard". Paste in a GitHub issue.
7. When you're done, change "profile" back to false and repeat (3)

## Further Information

Expand Down
42 changes: 0 additions & 42 deletions Rakefile

This file was deleted.

148 changes: 148 additions & 0 deletions Scripts/install-reaper-keys.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
-- @description reaper-keys: map keystroke combinations to actions like in vim
-- @version 2.0.0-a
-- @author gwatcha
-- @links
-- GitHub repository https://github.com/gwatcha/reaper-keys
-- @provides
-- ../internal/**/*
-- ../vendor/**/*

local function charCodes(from, count)
local out = {}
for i = 0, count do out[i + 1] = from + i end
return out
end

-- e.g. C-! will produce KEY 9 33 and will be parsed by reaper as C- Numpad Page Up
local clash = 65536
local key_groups = {
letters = { mod_id = 1, keys = charCodes(65, 25) }, -- A-Z
numbers = { mod_id = 1, keys = charCodes(48, 10) }, -- 0-9
special = {
mod_id = 1,
keys = {
8, -- backspace
9, -- tab
13, -- return
27, -- esc
32, -- space
112, -- f1
113, -- f2
114, -- f3
115, -- f4
116, -- f5
117, -- f6
118, -- f7
119, -- f8
120, -- f9
121, -- f10
122, -- f11
123, -- f12,
32801, -- page up
32802, -- page down
32803, -- end
32804, -- home
32805, -- left
32806, -- up
32807, -- right
32808, -- down
32813, -- insert
32814, -- delete
}
},
shifted = {
mod_id = 0,
keys = {
33 + clash, -- !
34 + clash, -- "
35 + clash, -- #
36 + clash, -- $
37 + clash, -- %
38 + clash, -- &
40 + clash, -- (
41 + clash, -- )
42 + clash, -- *
43 + clash, -- +
58, -- :
60 + clash, -- >
62 + clash, -- >
63, -- ?
64, -- @
94, -- ^
95, -- _
123 + clash, -- {
124 + clash, -- |
125 + clash, -- }
126, -- ~
126 + clash, -- ^
126 + clash, -- *
}
},
normal = {
mod_id = 0,
keys = {
39 + clash, -- '
44 + clash, -- ,
45 + clash, -- -
46 + clash, -- .
47, -- /
59 + clash, -- ;
61, -- =
91, -- [
92, -- \
93, -- ]
96 + clash, -- `
167, -- §
177, -- ±
}
}
}

local modifiers = { C = 9, M = 17, S = 5, MS = 21, CS = 13, CM = 25, CMS = 29 } -- C:ctrl, M:alt, S:shift
local mods_with_shift = { S = true, MS = true, CS = true, CMS = true }

local version = tonumber(reaper.GetAppVersion():match '[%d.]+')
if version < 6.71 then
return reaper.MB("Reaper keys supports only Reaper 6.71+", "Unsupported version", 0)
end

local function concat_path(...) return table.concat({ ... }, package.config:sub(1, 1)) end

local keymap_dir = concat_path(reaper.GetResourcePath(), 'KeyMaps')
local keymap_path = concat_path(keymap_dir, 'reaper-keys.ReaperKeyMap')
reaper.RecursiveCreateDirectory(keymap_dir, 0)
local keymap = io.open(keymap_path, "w")
if not keymap then return reaper.MB("Failed to create " .. keymap_path, "Error", 0) end

function KEY(mod_id, key_id, command_id, section_id)
return ("KEY %d %d %s %d\n"):format(mod_id, key_id, command_id, section_id)
end

local parent_dir = debug.getinfo(1, "S").source:match "@?(.*)[\\/].*[\\/]"
local command_path = concat_path(parent_dir, "internal", "rk.lua")
local sections = { midi = 32060, main = 0 }
for section_name, section_id in pairs(sections) do
local command_id = "_reaper_keys__" .. section_name
-- 260 focuses window on every key press so 516 is only option
keymap:write(('SCR 516 %d %s "reaper-keys" "%s"\n'):format(section_id, command_id, command_path))

for group_name, group in pairs(key_groups) do
for _, key_id in pairs(group.keys) do
local has_clash = (key_id >= clash) and 1 or 0
key_id = key_id - has_clash * clash
keymap:write(KEY(group.mod_id, key_id, command_id, section_id))

for mod, mod_id in pairs(modifiers) do
if group_name == "shifted" and mods_with_shift[mod] then goto iter_end end
keymap:write(KEY(mod_id - has_clash, key_id, command_id, section_id))
::iter_end::
end
end
end
end

local action_str = version >= 7. and "shortcuts/custom actions, import all sections" or ""
reaper.MB("Installation finished, now import reaper-keys.ReaperKeyMap:\n\t" ..
"Actions list > Key Map > Import " .. action_str .. "\n" ..
"WARNING: this will overwrite ALL your keybindings",
"Installation finished", 0)
2 changes: 0 additions & 2 deletions definitions/README.md

This file was deleted.

Loading

0 comments on commit 7ae3200

Please sign in to comment.