#[derive(Debug)]
pub(super) struct Verb {
pub(super) name: &'static str,
pub(super) alias: &'static str,
pub(super) opts: &'static str,
pub(super) src: bool,
}
const fn verb(name: &'static str, alias: &'static str, opts: &'static str, src: bool) -> Verb {
Verb {
name,
alias,
opts,
src,
}
}
pub(super) const DENY_VERBS: &[Verb] = &[
verb("send-keys", "send", "c:FHKlMN:Rt:X", false),
verb("send-prefix", "", "2t:", false),
verb("paste-buffer", "pasteb", "db:prs:t:", false),
verb("pipe-pane", "pipep", "IOot:", false),
verb("kill-pane", "killp", "at:", false),
verb("kill-window", "killw", "at:", false),
verb("kill-session", "", "aCt:", false),
verb("kill-server", "", "", false),
verb("respawn-pane", "respawnp", "c:e:kt:", false),
verb("respawn-window", "respawnw", "c:e:kt:", false),
verb("swap-pane", "swapp", "dDs:t:UZ", true),
verb("swap-window", "swapw", "ds:t:", true),
verb("join-pane", "joinp", "bdfhvp:l:s:t:", true),
verb("move-pane", "movep", "bdfhvp:l:s:t:", true),
verb("break-pane", "breakp", "abdPF:n:s:t:", true),
verb("move-window", "movew", "abdkrs:t:", true),
verb("link-window", "linkw", "abdks:t:", true),
verb("unlink-window", "unlinkw", "kt:", false),
verb("clear-history", "clearhist", "Ht:", false),
verb("new-window", "neww", "abc:de:F:kn:PSt:", false),
];
#[rustfmt::skip]
const OTHER_VERBS: &[&str] = &[
"attach-session",
"attach",
"bind-key",
"bind",
"capture-pane",
"capturep",
"choose-buffer",
"choose-client",
"choose-tree",
"clear-prompt-history",
"clearphist",
"clock-mode",
"command-prompt",
"confirm-before",
"confirm",
"copy-mode",
"customize-mode",
"delete-buffer",
"deleteb",
"detach-client",
"detach",
"display-menu",
"menu",
"display-message",
"display",
"display-popup",
"popup",
"display-panes",
"displayp",
"find-window",
"findw",
"has-session",
"has",
"if-shell",
"if",
"last-pane",
"lastp",
"last-window",
"last",
"list-buffers",
"lsb",
"list-clients",
"lsc",
"list-commands",
"lscm",
"list-keys",
"lsk",
"list-panes",
"lsp",
"list-sessions",
"ls",
"list-windows",
"lsw",
"load-buffer",
"loadb",
"lock-client",
"lockc",
"lock-server",
"lock",
"lock-session",
"locks",
"new-session",
"new",
"next-layout",
"nextl",
"next-window",
"next",
"previous-layout",
"prevl",
"previous-window",
"prev",
"refresh-client",
"refresh",
"rename-session",
"rename",
"rename-window",
"renamew",
"resize-pane",
"resizep",
"resize-window",
"resizew",
"rotate-window",
"rotatew",
"run-shell",
"run",
"save-buffer",
"saveb",
"select-layout",
"selectl",
"select-pane",
"selectp",
"select-window",
"selectw",
"server-access",
"set-buffer",
"setb",
"set-environment",
"setenv",
"set-hook",
"set-option",
"set",
"set-window-option",
"setw",
"show-buffer",
"showb",
"show-environment",
"showenv",
"show-hooks",
"show-messages",
"showmsgs",
"show-options",
"show",
"show-prompt-history",
"showphist",
"show-window-options",
"showw",
"split-window",
"splitw",
"start-server",
"start",
"suspend-client",
"suspendc",
"switch-client",
"switchc",
"unbind-key",
"unbind",
"wait-for",
"wait",
"split-pane",
"splitp",
"server-info",
"info",
"choose-window",
"choose-session",
];
const OPAQUE_VERBS: &[&str] = &["source-file", "source"];
pub(super) enum Resolved {
Deny(&'static Verb),
Known,
Opaque,
Unknown,
}
const MIN_NESTED_PREFIX: usize = 4;
pub(super) fn resolve(name: &str, nested: bool) -> Resolved {
if let Some(v) = DENY_VERBS
.iter()
.find(|v| v.name == name || v.alias == name)
{
return Resolved::Deny(v);
}
if OPAQUE_VERBS.contains(&name) {
return Resolved::Opaque;
}
if OTHER_VERBS.contains(&name) {
return Resolved::Known;
}
if name.is_empty() || (nested && name.len() < MIN_NESTED_PREFIX) {
return Resolved::Unknown;
}
let deny: Vec<&'static Verb> = DENY_VERBS
.iter()
.filter(|v| v.name.starts_with(name))
.collect();
let others = OTHER_VERBS
.iter()
.chain(OPAQUE_VERBS)
.filter(|v| v.starts_with(name));
match (deny.as_slice(), others.count()) {
([only], 0) => Resolved::Deny(only),
([], 0) => Resolved::Unknown,
_ => Resolved::Known,
}
}