summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2019-09-15 18:18:23 +0200
committerCanop <cano.petrole@gmail.com>2019-09-15 18:18:23 +0200
commit6140883fd1af29c2adc5869fa888f174acfd23ec (patch)
tree87de4135248f108d8295e56a1c494563ffbc4a2a
parentca3e3a91acc4a9645a08b811adf5290f63358c2e (diff)
more commands available for shortcuts & keyboard keys
All verbs also documented in website
-rw-r--r--CHANGELOG.md3
-rw-r--r--Cargo.lock6
-rw-r--r--Cargo.toml2
-rw-r--r--src/browser_states.rs18
-rw-r--r--src/browser_verbs.rs51
-rw-r--r--src/commands.rs42
-rw-r--r--src/conf.rs9
-rw-r--r--src/help_states.rs12
-rw-r--r--src/help_verbs.rs16
-rw-r--r--src/verb_conf.rs3
-rw-r--r--src/verb_store.rs55
-rw-r--r--website/docs/css/extra.css1
-rw-r--r--website/docs/documentation/configuration.md70
-rw-r--r--website/docs/documentation/usage.md4
14 files changed, 207 insertions, 85 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b0a9ee0..168642d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+### Next version
+* keyboard keys & shortcuts can be defined for more actions, all built-in verbs documented in website
+
<a name="v0.9.4"></a>
### v0.9.4 - 2019-09-13
New internal verbs like :focus_root, :focus_user_home, :refresh, :select_first
diff --git a/Cargo.lock b/Cargo.lock
index f887c63..9a47349 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -106,7 +106,7 @@ dependencies = [
"opener 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"simplelog 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "termimad 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termimad 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"umask 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"users 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -591,7 +591,7 @@ dependencies = [
[[package]]
name = "termimad"
-version = "0.6.4"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -767,7 +767,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)" = "66c8865bf5a7cbb662d8b011950060b3c8743dca141b054bf7195b20d314d8e2"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
-"checksum termimad 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e719aff75d732980c604d2c5a28f2d5c532f1e72cbd6eee5bae3a66547226a8"
+"checksum termimad 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "29f1ac3fef535e940f497b0ed1e405dbe742b5338d9e4f59163b26628e741a80"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
diff --git a/Cargo.toml b/Cargo.toml
index 772e50a..696cb40 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,7 +30,7 @@ crossterm_style = "=0.3.3"
crossterm_terminal = "=0.2.4"
crossterm_utils = "=0.2.3"
umask = "0.1.4"
-termimad = "0.6.4"
+termimad = "0.6.5"
#termimad = { path = "../termimad" }
[target.'cfg(unix)'.dependencies]
diff --git a/src/browser_states.rs b/src/browser_states.rs
index af28388..bffc8ca 100644
--- a/src/browser_states.rs
+++ b/src/browser_states.rs
@@ -71,7 +71,7 @@ impl BrowserState {
)
}
- fn page_height(screen: &Screen) -> i32 {
+ pub fn page_height(screen: &Screen) -> i32 {
i32::from(screen.h) - 2
}
@@ -87,7 +87,7 @@ impl BrowserState {
self.filtered_tree.as_mut().unwrap_or(&mut self.tree)
}
- fn open_selection_stay_in_broot(
+ pub fn open_selection_stay_in_broot(
&mut self,
screen: &mut Screen,
_con: &AppContext,
@@ -130,7 +130,7 @@ impl BrowserState {
}
}
- fn open_selection_quit_broot(
+ pub fn open_selection_quit_broot(
&mut self,
screen: &mut Screen,
con: &AppContext,
@@ -242,14 +242,6 @@ impl AppState for BrowserState {
self.displayed_tree_mut().move_selection(*dy, page_height);
Ok(AppStateCmdResult::Keep)
}
- Action::ScrollPage(dp) => {
- let tree = self.displayed_tree_mut();
- if page_height < tree.lines.len() as i32 {
- let dy = dp * page_height;
- tree.try_scroll(dy, page_height);
- }
- Ok(AppStateCmdResult::Keep)
- }
Action::Click(_, y) => {
let y = *y as i32 - 1; // click position starts at (1, 1)
self.displayed_tree_mut().try_select_y(y);
@@ -267,6 +259,10 @@ impl AppState for BrowserState {
}
Action::OpenSelection => self.open_selection_stay_in_broot(screen, con),
Action::AltOpenSelection => self.open_selection_quit_broot(screen, con),
+ Action::VerbIndex(index) => {
+ let verb = &con.verb_store.verbs[*index];
+ self.execute_verb(verb, &verb.invocation, screen, con)
+ },
Action::VerbInvocate(invocation) => match con.verb_store.search(&invocation.key) {
PrefixSearchResult::Match(verb) => {
self.execute_verb(verb, &invocation, screen, con)
diff --git a/src/browser_verbs.rs b/src/browser_verbs.rs
index d8baf20..5e91910 100644
--- a/src/browser_verbs.rs
+++ b/src/browser_verbs.rs
@@ -6,7 +6,7 @@ use crate::app::AppStateCmdResult;
use crate::app_context::AppContext;
use crate::browser_states::BrowserState;
use crate::commands::Command;
-use crate::external::{self, Launchable};
+use crate::external;
use crate::flat_tree::Tree;
use crate::help_states::HelpState;
use crate::screens::Screen;
@@ -42,30 +42,55 @@ impl VerbExecutor for BrowserState {
if let Some(err) = verb.match_error(invocation) {
return Ok(AppStateCmdResult::DisplayError(err));
}
- let tree = self.displayed_tree();
- let line = &tree.selected_line();
+ let page_height = BrowserState::page_height(screen);
Ok(match verb.execution.as_ref() {
":back" => AppStateCmdResult::PopState,
":focus" => {
- let mut path = tree.selected_line().target();
+ let tree = self.displayed_tree_mut();
+ let line = &tree.selected_line();
+ let mut path = line.target();
if !path.is_dir() {
path = path.parent().unwrap().to_path_buf();
}
focus_path(path, screen, tree)
}
- ":focus_root" => focus_path(PathBuf::from("/"), screen, tree),
+ ":focus_root" => focus_path(PathBuf::from("/"), screen, self.displayed_tree()),
":focus_user_home" => match UserDirs::new() {
- Some(ud) => focus_path(ud.home_dir().to_path_buf(), screen, tree),
+ Some(ud) => focus_path(ud.home_dir().to_path_buf(), screen, self.displayed_tree()),
None => AppStateCmdResult::DisplayError("no user home directory found".to_string()), // does this happen ?
}
":help" => AppStateCmdResult::NewState(Box::new(HelpState::new(screen, con)), Command::new()),
- ":open" => AppStateCmdResult::from(Launchable::opener(line.target())),
- ":parent" => match &line.path.parent() {
- Some(path) => focus_path(path.to_path_buf(), screen, tree),
+ //":open" => AppStateCmdResult::from(Launchable::opener(self.displayed_tree().selected_line().target())),
+ ":open_stay" => self.open_selection_stay_in_broot(screen, con)?,
+ ":open_leave" => self.open_selection_quit_broot(screen, con)?,
+ ":line_down" => {
+ self.displayed_tree_mut().move_selection(1, page_height);
+ AppStateCmdResult::Keep
+ }
+ ":line_up" => {
+ self.displayed_tree_mut().move_selection(-1, page_height);
+ AppStateCmdResult::Keep
+ }
+ ":page_down" => {
+ let tree = self.displayed_tree_mut();
+ if page_height < tree.lines.len() as i32 {
+ tree.try_scroll(page_height, page_height);
+ }
+ AppStateCmdResult::Keep
+ }
+ ":page_up" => {
+ let tree = self.displayed_tree_mut();
+ if page_height < tree.lines.len() as i32 {
+ tree.try_scroll(-page_height, page_height);
+ }
+ AppStateCmdResult::Keep
+ }
+ ":parent" => match &self.displayed_tree().selected_line().path.parent() {
+ Some(path) => focus_path(path.to_path_buf(), screen, self.displayed_tree()),
None => AppStateCmdResult::DisplayError("no parent found".to_string()),
}
- ":print_path" => external::print_path(&line.target(), con)?,
- ":print_tree" => external::print_tree(&tree, screen, con)?,
+ ":print_path" => external::print_path(&self.displayed_tree().selected_line().target(), con)?,
+ ":print_tree" => external::print_tree(&self.displayed_tree(), screen, con)?,
":refresh" => AppStateCmdResult::RefreshState,
":select_first" => {
self.displayed_tree_mut().try_select_first();
@@ -81,7 +106,7 @@ impl VerbExecutor for BrowserState {
":toggle_git_ignore" => self.with_new_options(screen, &|options| {
options.respect_git_ignore = match options.respect_git_ignore {
OptionBool::Auto => {
- if tree.nb_gitignored > 0 {
+ if self.displayed_tree().nb_gitignored > 0 {
OptionBool::No
} else {
OptionBool::Yes
@@ -95,7 +120,7 @@ impl VerbExecutor for BrowserState {
":toggle_sizes" => self.with_new_options(screen, &|o| o.show_sizes ^= true),
":toggle_trim_root" => self.with_new_options(screen, &|o| o.trim_root ^= true),
":quit" => AppStateCmdResult::Quit,
- _ => verb.to_cmd_result(&line.path.clone(), &invocation.args, screen, con)?,
+ _ => verb.to_cmd_result(&self.displayed_tree().selected_line().path.clone(), &invocation.args, screen, con)?,
})
}
}
diff --git a/src/commands.rs b/src/commands.rs
index f3dfb4a..ab5a75c 100644
--- a/src/commands.rs
+++ b/src/commands.rs
@@ -30,11 +30,11 @@ struct CommandParts {
#[derive(Debug, Clone)]
pub enum Action {
MoveSelection(i32), // up (neg) or down (positive) in the list
- ScrollPage(i32), // in number of pages, not lines
OpenSelection, // open the selected line
AltOpenSelection, // alternate open the selected line
VerbEdit(VerbInvocation), // verb invocation, unfinished
- VerbInvocate(VerbInvocation), // verb invocation, after the user hit enter (or used a trigger key)
+ VerbInvocate(VerbInvocation), // verb invocation, after the user hit enter
+ VerbIndex(usize), // verb call, withtout specific argument (using a trigger key)
FuzzyPatternEdit(String), // a pattern being edited
RegexEdit(String, String), // a regex being edited (core & flags)
Back, // back to last app state, or clear pattern
@@ -140,6 +140,7 @@ impl Command {
con: &AppContext,
) {
let mut handled_by_input_field = false;
+ debug!("add_event {:?}", event);
match event {
Event::Click(x, y) => {
if !input_field.apply_event(&event) {
@@ -150,18 +151,10 @@ impl Command {
self.action = Action::DoubleClick(*x, *y);
}
Event::Key(key) => {
- // we start by looking if the key is the trigger key of
- // one of the verbs
- for verb in &con.verb_store.verbs {
- if let Some(verb_key) = verb.key {
- if verb_key == *key {
- // Cloning the invocation when we already know the verb
- // isn't very clean or efficient (it means a second search will
- // occur behind but it's simpler to manage now
- self.action = Action::VerbInvocate(verb.invocation.clone());
- return;
- }
- }
+ // we start by looking if the key is the trigger key of one of the verbs
+ if let Some(index) = con.verb_store.index_of_key(key) {
+ self.action = Action::VerbIndex(index);
+ return;
}
match *key {
KeyEvent::Char('\t') => {
@@ -170,25 +163,20 @@ impl Command {
KeyEvent::BackTab => {
self.action = Action::Previous;
}
+
+ // this may be a call to open_stay, or simply
+ // validating the verb choice in the input
KeyEvent::Char('\n') => {
self.action = Action::from(&self.parts, true);
}
+
+ // Normally redundant due to internal verb but
+ // I'm not yet 100% sure it's Alt('\r') on all platforms
KeyEvent::Alt('\r') | KeyEvent::Alt('\n') => {
self.action = Action::AltOpenSelection;
}
- KeyEvent::Up => {
- self.action = Action::MoveSelection(-1);
- }
- KeyEvent::Down => {
- self.action = Action::MoveSelection(1);
- }
- KeyEvent::PageUp | KeyEvent::Ctrl('u') => {
- self.action = Action::ScrollPage(-1);
- }
- KeyEvent::PageDown | KeyEvent::Ctrl('d') => {
- self.action = Action::ScrollPage(1);
- }
- KeyEvent::Char(c) if c =='?' && (self.raw.is_empty() || self.parts.verb_invocation.is_some()) => {
+
+ KeyEvent::Char('?') if self.raw.is_empty() || self.parts.verb_invocation.is_some() => {
// a '?' opens the help when it's the first char or when it's part of the verb
// invocation
self.action = Action::Help;
diff --git a/src/conf.rs b/src/conf.rs
index b9ded64..80214ee 100644
--- a/src/conf.rs
+++ b/src/conf.rs
@@ -156,19 +156,12 @@ impl Conf {
const DEFAULT_CONF_FILE: &str = r#"
# This configuration file lets you define new commands
-# or change the shortcut of built-in verbs.
+# or change the shortcut or triggering keys of built-in verbs.
# You can change the colors of broot too.
#
# Configuration documentation is available at https://dystroy.org/broot
#
-###############################
-# shortcuts for built-in verbs:
-
-[[verbs]]
-invocation = "p"
-execution = ":parent"
-
#####################
# user defined verbs:
diff --git a/src/help_states.rs b/src/help_states.rs
index aa77fed..295f3af 100644
--- a/src/help_states.rs
+++ b/src/help_states.rs
@@ -16,7 +16,7 @@ use crate::verbs::VerbExecutor;
/// an application state dedicated to help
pub struct HelpState {
- view: MadView,
+ pub view: MadView,
}
impl HelpState {
@@ -30,7 +30,7 @@ impl HelpState {
fn resize_area(&mut self, screen: &Screen) {
let mut area = Area::new(0, 0, screen.w, screen.h - 2);
- area.pad_for_max_width(100);
+ area.pad_for_max_width(110);
self.view.resize(&area);
}
}
@@ -45,6 +45,10 @@ impl AppState for HelpState {
self.resize_area(screen);
Ok(match &cmd.action {
Action::Back => AppStateCmdResult::PopState,
+ Action::VerbIndex(index) => {
+ let verb = &con.verb_store.verbs[*index];
+ self.execute_verb(verb, &verb.invocation, screen, con)?
+ },
Action::VerbInvocate(invocation) => match con.verb_store.search(&invocation.key) {
PrefixSearchResult::Match(verb) => {
self.execute_verb(verb, &invocation, screen, con)?
@@ -55,10 +59,6 @@ impl AppState for HelpState {
self.view.try_scroll_lines(*dy);
AppStateCmdResult::Keep
}
- Action::ScrollPage(dp) => {
- self.view.try_scroll_pages(*dp);
- AppStateCmdResult::Keep
- }
_ => AppStateCmdResult::Keep,
})
}
diff --git a/src/help_verbs.rs b/src/help_verbs.rs
index 7ee6030..998e4db 100644
--- a/src/help_verbs.rs
+++ b/src/help_verbs.rs
@@ -36,7 +36,23 @@ impl VerbExecutor for HelpState {
Command::new(),
),
":help" => AppStateCmdResult::Keep,
+ ":line_down" => {
+ self.view.try_scroll_lines(1);
+ AppStateCmdResult::Keep
+ }
+ ":line_up" => {
+ self.view.try_scroll_lines(-1);
+ AppStateCmdResult::Keep
+ }
":open" => AppStateCmdResult::from(Launchable::opener(Conf::default_location())),
+ ":page_down" => {
+ self.view.try_scroll_pages(1);
+ AppStateCmdResult::Keep
+ }
+ ":page_up" => {
+ self.view.try_scroll_pages(-1);
+ AppStateCmdResult::Keep
+ }
":print_path" => external::print_path(&Conf::default_location(), con)?,
":quit" => AppStateCmdResult::Quit,
":focus_user_home" | ":focus_root" => AppStateCmdResult::PopStateAndReapply,
diff --git a/src/verb_conf.rs b/src/verb_conf.rs
index 41fe733..5cc97e2 100644
--- a/src/verb_conf.rs
+++ b/src/verb_conf.rs
@@ -62,8 +62,7 @@ pub fn parse_key(raw: &str) -> Result<KeyEvent, ConfError> {
("ctrl", Some(minor)) | ("^", Some(minor)) => KeyEvent::Ctrl(
minor.as_str().chars().next().unwrap().to_ascii_lowercase()
),
- // other possible mappings are disabled as they would break
- // basic behaviors of broot
+ // other possible mappings are disabled as they would break basic behaviors of broot
_ => bad_key(raw)?
}),
None => bad_key(raw)
diff --git a/src/verb_store.rs b/src/verb_store.rs
index 21ae064..92b3b76 100644
--- a/src/verb_store.rs
+++ b/src/verb_store.rs
@@ -59,7 +59,7 @@ impl VerbStore {
}
self.add_builtin(
"back",
- None,
+ None, // esc is mapped in commands.rs
None,
"revert to the previous state (mapped to `<esc>`)",
);
@@ -101,6 +101,18 @@ impl VerbStore {
Some("?".to_string()),
"display broot's help",
);
+ self.add_builtin(
+ "line_down",
+ Some(KeyEvent::Down),
+ None,
+ "move one line down"
+ );
+ self.add_builtin(
+ "line_up",
+ Some(KeyEvent::Up),
+ None,
+ "move one line up"
+ );
self.verbs.push(
Verb::create_external(
"mkdir {subpath}",
@@ -128,15 +140,33 @@ impl VerbStore {
.unwrap(),
);
self.add_builtin(
- "open",
+ "open_stay",
+ None, // default mapping directly handled in commands#add_event
None,
+ "open file or directory according to OS settings (stays in broot)",
+ );
+ self.add_builtin(
+ "open_leave",
+ None, // default mapping directly handled in commands#add_event
None,
"open file or directory according to OS settings (quit broot)",
);
self.add_builtin(
- "parent",
+ "page_down",
+ Some(KeyEvent::PageDown),
None,
+ "scroll one page down"
+ );
+ self.add_builtin(
+ "page_up",
+ Some(KeyEvent::PageUp),
+ None,
+ "scroll one page up"
+ );
+ self.add_builtin(
+ "parent",
None,
+ Some("p".to_string()),
"move to the parent directory"
);
self.add_builtin(
@@ -249,10 +279,10 @@ impl VerbStore {
_ => PrefixSearchResult::TooManyMatches,
}
}
- // return the index of the verb having the long name. This function is meant
- // for internal access when it's sure it can't failed (i.e. for a builtin)
- // It looks for verbs by key, starting from the builtins, to
- // ensure it hasn't been overriden.
+ /// return the index of the verb having the long name. This function is meant
+ /// for internal access when it's sure it can't failed (i.e. for a builtin)
+ /// It looks for verbs by key, starting from the builtins, to
+ /// ensure it hasn't been overriden.
pub fn index_of(&self, name: &str) -> usize {
for i in 0..self.verbs.len() {
if self.verbs[i].invocation.key == name {
@@ -261,4 +291,15 @@ impl VerbStore {
}
panic!("invalid verb search");
}
+ /// return the index of the verb which is triggered by the given key, if any
+ pub fn index_of_key(&self, key: &KeyEvent) -> Option<usize> {
+ for i in 0..self.verbs.len() {
+ if let Some(verb_key) = self.verbs[i].key {
+ if verb_key == *key {
+ return Some(i);
+ }
+ }
+ }
+ None
+ }
}
diff --git a/website/docs/css/extra.css b/website/docs/css/extra.css
index f9babec..20c94d6 100644
--- a/website/docs/css/extra.css
+++ b/website/docs/css/extra.css
@@ -30,6 +30,7 @@ kbd {
background-color: #333;
border-radius: 2px;
box-shadow: none;
+ margin: 1px;
}
kbd.b {
diff --git a/website/docs/documentation/configuration.md b/website/docs/documentation/configuration.md
index 564a1a6..dfef22b 100644
--- a/website/docs/documentation/configuration.md
+++ b/website/docs/documentation/configuration.md
@@ -12,7 +12,7 @@ Currently, you can configure
* verbs
* colors
-# Verbs
+# Verbs, Shortcuts, and keys
## Verb Definition Attributes
@@ -35,7 +35,7 @@ shorcut | no | an alternate way to call the verb (without the arguments part)
leave_broot | no | whether to quit broot on execution (default: `true`)
from_shell | no | whether the verb must be executed from the parent shell (needs `br`, default: `false`)
-### Shortcuts and Verb search
+## Shortcuts and Verb search
**broot** looks for the first token following a space or `:` and tryes to find the verb you want.
@@ -56,7 +56,7 @@ Its interest is that if you do `:p`, then `enter`, it is executed even while the
Use shortcuts for verbs you frequently use.
-### Keyboard key
+## Keyboard key
The main keys you can use are
@@ -87,9 +87,26 @@ For example you could add those mappings:
key = "F7"
execution = ":select_last"
-Then, when doing <key>Ctrl-H</key>, you would go to you user home (`~` when on linux) and <key>F7</key> would select the last line of the tree.
+ [[verbs]]
+ invocation = "open"
+ key = "^O"
+ execution = ":open_stay"
+
+ [[verbs]]
+ invocation = "edit"
+ key = "F2"
+ shortcut = "e"
+ execution = "$EDITOR {file}"
+ from_shell = true
+
+Then,
-Beware that consoles often intercept some possible keys.
+* when doing <kbd>Ctrl-H</kbd>, you would go to you user home (`~` when on linux),
+* you would open files (without closing broot) with <kbd>ctrl-O</kbd>,
+* <kbd>F7</kbd> would select the last line of the tree,
+* and you'd switch to your favorite editor with <kbd>F2</kbd>
+
+Beware that consoles intercept some possible keys. Many keyboard shortcuts aren't available, depending on your configuration.
### Verbs not leaving broot
@@ -157,6 +174,49 @@ Let's say we don't want the type to contain dots, then we do this:
You can override the default behavior of broot by giving your verb the same shortcut or invocation than a default one.
+## Built In Verbs
+
+Here's the list of actions you can add an alternate shortcut or keyboard key for:
+
+invocation | default key | default shortcut | behavior / details
+-|-|-|-
+:back | <kbd>Esc</kbd> | - | back to previous app state (see Usage page) |
+:cd | <kbd>alt</kbd><kbd>enter</kbd> | - | leave broot and cd to the selected directory (needs the br shell function)
+:cp {newpath} | - | - | copy the file or directory to the provided name
+:help | <kbd>F1</kbd> | - | open the help page. Help page can also be open with <kbd>?</kbd>
+:focus | <kbd>enter</kbd> | - | set the selected directory the root of the displayed tree |
+:focus_user_home | - | - | focus the user's home (`~` on linux) |
+:focus_root | - | - | focus the root directory (`/` on linux)
+:line_down | <kbd>↓</kbd> | - | scroll one line down or select the next line
+:line_up | <kbd>↑</kbd> | - | scroll one line up or select the previous line
+:mkdir {subpath} | - | md | create a directory
+:mv {newpath} | - | - | move the file or directory to the provided path
+:open_stay | <kbd>enter</kbd> | - | open the selected file in the default OS opener
+:open_leave | <kbd>alt</kbd><kbd>enter</kbd> | - | open the selected file in the default OS opener and leaves broot
+:page_down | <kbd>⇟</kbd> | - | scroll one page down
+:page_up | <kbd>⇞</kbd> | - | scroll one page up
+:parent | - | - | focus the parent directory
+:print_path | - | pp | print path and leaves broot
+:print_tree | - | pt | print tree and leaves broot
+:quit | <kbd>ctrl</kbd><kbd>q</kbd> | q | quit broot
+:refresh | <kbd>F5</kbd> | - | refresh the displayed tree and clears the directory sizes cache
+:rm | - | - | remove the selected file or directory. To stay safe, don't define a keyboard key for this action
+:select_firt | - | - | select the firt line
+:select_last | - | - | select the last line
+:toggle_dates | - | - | toggle display of last modified dates
+:toggle_files | - | - | toggle showing files (or just folders)
+:toggle_git_ignore | - | - | toggle git hignore handling (auto, no or yes)
+:toggle_hidden | - | - | toggle display of hidden files (the ones whose name starts with a dot on linux)
+:toggle_perm | - | - | toggle display of permissions (not available on Windows)
+:toggle_sizes | - | - | toggle the size mode
+:toggle_trim_root | - | - | toggle trimming of top level files in tree display
+
+Note that
+
+- you can always call a verb with its default invocation, you don't *have* to define a shortcut
+- verbs whose invocation needs an argument (like `{newpath}`) can't be triggered with just a keyboard key.
+- many keyboard keys should be kept available for the input
+
# Colors
You can change all colors by adding a `[skin]` section in your `conf.toml` file.
diff --git a/website/docs/documentation/usage.md b/website/docs/documentation/usage.md
index ad010a1..7d2788e 100644
--- a/website/docs/documentation/usage.md
+++ b/website/docs/documentation/usage.md
@@ -37,12 +37,12 @@ From here you may navigate using the following keys:
There are also a few more shortcuts:
-* moving one page up can be done with <kbd>Ctrl</kbd> <kbd>u</kbd>
-* moving one page down can be done with <kbd>Ctrl</kbd> <kbd>d</kbd>
* you can quit with <kbd>Ctrl</kbd> <kbd>q</kbd>
* you can select a line with a mouse click
* you can open a line with a mouse double-click
+and you can define your own [shorcuts](../configuration//#shortcuts-and-verb-search) or triggering [keyboard keys](../configuration/#keyboard-key).
+
## Fuzzy Patterns