Use tui-input to handle input buffer

New message: `UpdateInputBufferFromKey` to replace most
`BufferInputFromKey` usage.

This adds more functionalities to the input buffer and reduces
boilerplate code.

This commit also deprecates `config.general.cursor` as the cursor will
be set by the terminal from now.

Repo: https://github.com/sayanarijit/tui-input
pull/398/head
Arijit Basu 3 years ago committed by Arijit Basu
parent 4495740cb0
commit ca6cefb1c1

125
Cargo.lock generated

@ -13,9 +13,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.44"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7"
[[package]]
name = "assert_cmd"
@ -56,9 +56,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bstr"
version = "0.2.16"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"lazy_static",
"memchr",
@ -68,9 +68,9 @@ dependencies = [
[[package]]
name = "bumpalo"
version = "3.7.0"
version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
[[package]]
name = "cassowary"
@ -342,9 +342,9 @@ dependencies = [
[[package]]
name = "half"
version = "1.7.1"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
[[package]]
name = "hashbrown"
@ -380,9 +380,9 @@ dependencies = [
[[package]]
name = "instant"
version = "0.1.10"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
@ -404,9 +404,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "js-sys"
version = "0.3.53"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d"
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
dependencies = [
"wasm-bindgen",
]
@ -419,9 +419,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.105"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "869d572136620d55835903746bcb5cdc54cb2851fd0aeec53220b4bb65ef3013"
checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
[[package]]
name = "linked-hash-map"
@ -449,18 +449,18 @@ dependencies = [
[[package]]
name = "lua-src"
version = "543.0.0"
version = "543.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "029180f994b9b36f47d905f92569b516acf7d073778e2e781c15ee375b1ca27d"
checksum = "b72914332bf1ef0e1185b229135d639f11a4a8ccfd32852db8e52419c04c0247"
dependencies = [
"cc",
]
[[package]]
name = "luajit-src"
version = "210.3.0+restyeced77f"
version = "210.3.1+restycd2285f"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "084807a533537567019ffc9415c901d5d0a2f1e5f3956f2f4de0534a4bb74118"
checksum = "0107579f29cba96b4450335469432ee6f0f0bc68690626a951bd680212477efc"
dependencies = [
"cc",
]
@ -498,9 +498,9 @@ dependencies = [
[[package]]
name = "mio"
version = "0.7.13"
version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
dependencies = [
"libc",
"log",
@ -618,9 +618,9 @@ dependencies = [
[[package]]
name = "pkg-config"
version = "0.3.19"
version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
[[package]]
name = "plotters"
@ -652,9 +652,9 @@ dependencies = [
[[package]]
name = "predicates"
version = "2.0.2"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c143348f141cc87aab5b950021bac6145d0e5ae754b0591de23244cee42c9308"
checksum = "5c6ce811d0b2e103743eec01db1c50612221f173084ce2f7941053e94b6bb474"
dependencies = [
"difflib",
"itertools",
@ -669,28 +669,28 @@ checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
[[package]]
name = "predicates-tree"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7dd0fd014130206c9352efbdc92be592751b2b9274dff685348341082c6ea3d"
checksum = "338c7be2905b732ae3984a2f40032b5e94fd8f52505b186c7d4d68d193445df7"
dependencies = [
"predicates-core",
"treeline",
"termtree",
]
[[package]]
name = "proc-macro2"
version = "1.0.29"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [
"proc-macro2",
]
@ -828,9 +828,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.67"
version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950"
checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
dependencies = [
"itoa",
"ryu",
@ -881,21 +881,27 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.6.1"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
[[package]]
name = "syn"
version = "1.0.75"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7"
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "termtree"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16"
[[package]]
name = "textwrap"
version = "0.11.0"
@ -926,12 +932,6 @@ dependencies = [
"serde_json",
]
[[package]]
name = "treeline"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
[[package]]
name = "tui"
version = "0.16.0"
@ -946,6 +946,16 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "tui-input"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "425271346f51f4a17222eb51b80a3184d7927fcdc1dee0d3e8b7933cbd756ca9"
dependencies = [
"crossterm 0.22.1",
"serde",
]
[[package]]
name = "unicase"
version = "2.6.0"
@ -963,9 +973,9 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-width"
version = "0.1.8"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
@ -1007,9 +1017,9 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasm-bindgen"
version = "0.2.76"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0"
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@ -1017,9 +1027,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.76"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041"
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
dependencies = [
"bumpalo",
"lazy_static",
@ -1032,9 +1042,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.76"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef"
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -1042,9 +1052,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.76"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad"
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
dependencies = [
"proc-macro2",
"quote",
@ -1055,15 +1065,15 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.76"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29"
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
[[package]]
name = "web-sys"
version = "0.3.53"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c"
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
dependencies = [
"js-sys",
"wasm-bindgen",
@ -1121,6 +1131,7 @@ dependencies = [
"serde",
"serde_yaml",
"tui",
"tui-input",
]
[[package]]

@ -25,7 +25,7 @@ dirs = "4.0.0"
serde = { version = "1.0.130", features = ["derive"] }
serde_yaml = "0.8.21"
mime_guess = "2.0.3"
anyhow = "1.0.44"
anyhow = "1.0.45"
chrono = { version = "0.4.19", features = ["serde"] }
lazy_static = "1.4.0"
indexmap = { version = "1.7.0", features = ["serde"] }
@ -33,7 +33,8 @@ natord = "1.0.9"
humansize = "1.1.1"
mlua = { version = "0.6.6", features = ["luajit", "vendored", "serialize", "send"] }
ansi-to-tui = "0.4.1"
libc = "0.2.105"
libc = "0.2.106"
tui-input = { version = "0.1.2", features = [ "serde" ] }
[dev-dependencies]
criterion = "0.3.5"

@ -29,19 +29,6 @@ Type: boolean
Set it to `true` if you want to enable a safety feature that will save you from
yourself when you type recklessly.
## cursor.format
Type: nullable string
This is the shape of the cursor visible when the input buffer contains some
string.
## cursor.style
Type: [Style][1]
Style of the cursor.
## initial_layout
Type: string

@ -72,10 +72,10 @@ Modifier can be one of the following:
## Example
```lua
xplr.config.general.cursor.style.fg = "Red"
xplr.config.general.cursor.style.bg = { Rgb = { 100, 150, 200 } }
xplr.config.general.cursor.style.add_modifiers = { "Bold", "Italic" }
xplr.config.general.cursor.style.sub_modifiers = { "Hidden" }
xplr.config.general.prompt.style.fg = "Red"
xplr.config.general.prompt.style.bg = { Rgb = { 100, 150, 200 } }
xplr.config.general.prompt.style.add_modifiers = { "Bold", "Italic" }
xplr.config.general.prompt.style.sub_modifiers = { "Hidden" }
```
[1]: #fg

@ -16,6 +16,7 @@ use std::collections::VecDeque;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use tui_input::{Input, InputRequest};
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const TEMPLATE_TABLE_ROW: &str = "TEMPLATE_TABLE_ROW";
@ -776,6 +777,9 @@ pub enum ExternalMsg {
/// Follow the symlink under focus to its actual location.
FollowSymlink,
/// Update the input buffer from given key
UpdateInputBufferFromKey,
/// Append/buffer the given string into the input buffer.
///
/// **Example:** `BufferInput: foo`
@ -1247,7 +1251,7 @@ pub struct App {
pub msg_out: VecDeque<MsgOut>,
pub mode: Mode,
pub layout: Layout,
pub input_buffer: Option<String>,
pub input: Option<Input>,
pub pid: u32,
pub session_path: String,
pub pipe: Pipe,
@ -1372,7 +1376,7 @@ impl App {
msg_out: Default::default(),
mode,
layout,
input_buffer: Default::default(),
input: Default::default(),
pid,
session_path: session_path.clone(),
pipe: Pipe::from_session_path(&session_path)?,
@ -1477,6 +1481,9 @@ impl App {
ExternalMsg::LastVisitedPath => self.last_visited_path(),
ExternalMsg::NextVisitedPath => self.next_visited_path(),
ExternalMsg::FollowSymlink => self.follow_symlink(),
ExternalMsg::UpdateInputBufferFromKey => {
self.update_input_buffer_from_key(key)
}
ExternalMsg::BufferInput(input) => self.buffer_input(&input),
ExternalMsg::BufferInputFromKey => {
self.buffer_input_from_key(key)
@ -1731,9 +1738,9 @@ impl App {
fn focus_previous_by_relative_index_from_input(self) -> Result<Self> {
if let Some(index) = self
.input_buffer
.input
.as_ref()
.and_then(|i| i.parse::<usize>().ok())
.and_then(|i| i.value().parse::<usize>().ok())
{
self.focus_previous_by_relative_index(index)
} else {
@ -1769,9 +1776,9 @@ impl App {
fn focus_next_by_relative_index_from_input(self) -> Result<Self> {
if let Some(index) = self
.input_buffer
.input
.as_ref()
.and_then(|i| i.parse::<usize>().ok())
.and_then(|i| i.value().parse::<usize>().ok())
{
self.focus_next_by_relative_index(index)
} else {
@ -1865,11 +1872,26 @@ impl App {
}
}
fn update_input_buffer_from_key(
mut self,
key: Option<Key>,
) -> Result<Self> {
if let Some(req) = key.and_then(|k| k.to_input_request()) {
if let Some(buf) = self.input.as_mut() {
buf.handle(req);
}
}
Ok(self)
}
fn buffer_input(mut self, input: &str) -> Result<Self> {
if let Some(buf) = self.input_buffer.as_mut() {
buf.push_str(input)
if let Some(buf) = self.input.as_mut() {
buf.handle(InputRequest::GoToEnd);
for c in input.chars() {
buf.handle(InputRequest::InsertChar(c));
}
} else {
self.input_buffer = Some(input.to_owned());
self.input = Some(Input::default().with_value(input.into()));
};
self.logs_hidden = true;
Ok(self)
@ -1884,41 +1906,31 @@ impl App {
}
fn set_input_buffer(mut self, string: String) -> Result<Self> {
self.input_buffer = Some(string);
self.input = Some(Input::default().with_value(string));
self.logs_hidden = true;
Ok(self)
}
fn remove_input_buffer_last_character(mut self) -> Result<Self> {
if let Some(mut buf) = self.input_buffer {
buf.pop();
self.input_buffer = Some(buf);
if let Some(buf) = self.input.as_mut() {
buf.handle(InputRequest::GoToEnd);
buf.handle(InputRequest::DeletePrevChar);
self.logs_hidden = true;
};
Ok(self)
}
fn remove_input_buffer_last_word(mut self) -> Result<Self> {
if let Some(buf) = self.input_buffer {
let buf = buf
.chars()
.into_iter()
.rev()
.skip_while(|c| !c.is_ascii_alphanumeric())
.skip_while(|c| c.is_ascii_alphanumeric())
.collect::<Vec<char>>()
.into_iter()
.rev()
.collect::<String>();
self.input_buffer = Some(buf);
if let Some(buf) = self.input.as_mut() {
buf.handle(InputRequest::GoToEnd);
buf.handle(InputRequest::DeletePrevWord);
self.logs_hidden = true;
};
Ok(self)
}
fn reset_input_buffer(mut self) -> Result<Self> {
self.input_buffer = None;
self.input = None;
Ok(self)
}
@ -1935,9 +1947,9 @@ impl App {
fn focus_by_index_from_input(self) -> Result<Self> {
if let Some(index) = self
.input_buffer
.input
.as_ref()
.and_then(|i| i.parse::<usize>().ok())
.and_then(|i| i.value().parse::<usize>().ok())
{
self.focus_by_index(index)
} else {
@ -2004,8 +2016,8 @@ impl App {
}
fn focus_path_from_input(self) -> Result<Self> {
if let Some(p) = self.input_buffer.clone() {
self.focus_path(&p, true)
if let Some(p) = self.input.clone() {
self.focus_path(p.value(), true)
} else {
Ok(self)
}
@ -2026,7 +2038,7 @@ impl App {
fn pop_mode(self) -> Result<Self> {
self.pop_mode_keeping_input_buffer().map(|mut a| {
a.input_buffer = None;
a.input = None;
a
})
}
@ -2040,7 +2052,7 @@ impl App {
fn switch_mode(self, mode: &str) -> Result<Self> {
self.switch_mode_keeping_input_buffer(mode).map(|mut a| {
a.input_buffer = None;
a.input = None;
a
})
}
@ -2058,7 +2070,7 @@ impl App {
fn switch_mode_builtin(self, mode: &str) -> Result<Self> {
self.switch_mode_builtin_keeping_input_buffer(mode)
.map(|mut a| {
a.input_buffer = None;
a.input = None;
a
})
}
@ -2079,7 +2091,7 @@ impl App {
fn switch_mode_custom(self, mode: &str) -> Result<Self> {
self.switch_mode_custom_keeping_input_buffer(mode)
.map(|mut a| {
a.input_buffer = None;
a.input = None;
a
})
}
@ -2290,10 +2302,13 @@ impl App {
mut self,
filter: NodeFilter,
) -> Result<Self> {
if let Some(input) = self.input_buffer.clone() {
if let Some(input) = self.input.as_ref() {
self.explorer_config
.filters
.insert(NodeFilterApplicable::new(filter, input));
.insert(NodeFilterApplicable::new(
filter,
input.value().into(),
));
};
Ok(self)
}
@ -2310,8 +2325,8 @@ impl App {
mut self,
filter: NodeFilter,
) -> Result<Self> {
if let Some(input) = self.input_buffer.clone() {
let nfa = NodeFilterApplicable::new(filter, input);
if let Some(input) = self.input.as_ref() {
let nfa = NodeFilterApplicable::new(filter, input.value().into());
self.explorer_config.filters.retain(|f| f != &nfa);
};
Ok(self)
@ -2668,7 +2683,7 @@ impl App {
selection: self.selection.clone(),
mode: self.mode.clone(),
layout: self.layout.clone(),
input_buffer: self.input_buffer.clone(),
input_buffer: self.input.as_ref().map(|i| i.value().into()),
pid: self.pid,
session_path: self.session_path.clone(),
explorer_config: self.explorer_config.clone(),

@ -227,9 +227,6 @@ pub struct GeneralConfig {
#[serde(default)]
pub enable_recover_mode: bool,
#[serde(default)]
pub cursor: UiElement,
#[serde(default)]
pub prompt: UiElement,

@ -26,13 +26,6 @@ xplr.config.general.prompt.style.sub_modifiers = nil
xplr.config.general.prompt.style.bg = nil
xplr.config.general.prompt.style.fg = nil
------ Cursor
xplr.config.general.cursor.format = ""
xplr.config.general.cursor.style.add_modifiers = nil
xplr.config.general.cursor.style.bg = nil
xplr.config.general.cursor.style.fg = nil
xplr.config.general.cursor.style.sub_modifiers = nil
------ Initial layout
xplr.config.general.initial_layout = "default"
@ -1170,26 +1163,10 @@ xplr.config.modes.builtin.create_directory = {
extra_help = nil,
key_bindings = {
on_key = {
backspace = {
help = "remove last character",
messages = { "RemoveInputBufferLastCharacter" },
},
["ctrl-c"] = {
help = "terminate",
messages = { "Terminate" },
},
["ctrl-u"] = {
help = "remove line",
messages = {
{
SetInputBuffer = "",
},
},
},
["ctrl-w"] = {
help = "remove last word",
messages = { "RemoveInputBufferLastWord" },
},
enter = {
help = "create directory",
messages = {
@ -1219,7 +1196,7 @@ xplr.config.modes.builtin.create_directory = {
on_special_character = nil,
default = {
help = nil,
messages = { "BufferInputFromKey" },
messages = { "UpdateInputBufferFromKey" },
},
},
}
@ -1231,26 +1208,10 @@ xplr.config.modes.builtin.create_file = {
extra_help = nil,
key_bindings = {
on_key = {
backspace = {
help = "remove last character",
messages = { "RemoveInputBufferLastCharacter" },
},
["ctrl-c"] = {
help = "terminate",
messages = { "Terminate" },
},
["ctrl-u"] = {
help = "remove line",
messages = {
{
SetInputBuffer = "",
},
},
},
["ctrl-w"] = {
help = "remove last word",
messages = { "RemoveInputBufferLastWord" },
},
enter = {
help = "create file",
messages = {
@ -1280,7 +1241,7 @@ xplr.config.modes.builtin.create_file = {
on_special_character = nil,
default = {
help = nil,
messages = { "BufferInputFromKey" },
messages = { "UpdateInputBufferFromKey" },
},
},
}
@ -1292,26 +1253,10 @@ xplr.config.modes.builtin.number = {
extra_help = nil,
key_bindings = {
on_key = {
backspace = {
help = "remove last character",
messages = { "RemoveInputBufferLastCharacter" },
},
["ctrl-c"] = {
help = "terminate",
messages = { "Terminate" },
},
["ctrl-u"] = {
help = "remove line",
messages = {
{
SetInputBuffer = "",
},
},
},
["ctrl-w"] = {
help = "remove last word",
messages = { "RemoveInputBufferLastWord" },
},
down = {
help = "to down",
messages = { "FocusNextByRelativeIndexFromInput", "PopMode" },
@ -1332,7 +1277,7 @@ xplr.config.modes.builtin.number = {
on_alphabet = nil,
on_number = {
help = "input",
messages = { "BufferInputFromKey" },
messages = { "UpdateInputBufferFromKey" },
},
on_special_character = nil,
default = nil,
@ -1404,26 +1349,10 @@ xplr.config.modes.builtin.rename = {
extra_help = nil,
key_bindings = {
on_key = {
backspace = {
help = "remove last character",
messages = { "RemoveInputBufferLastCharacter" },
},
["ctrl-c"] = {
help = "terminate",
messages = { "Terminate" },
},
["ctrl-u"] = {
help = "remove line",
messages = {
{
SetInputBuffer = "",
},
},
},
["ctrl-w"] = {
help = "remove last word",
messages = { "RemoveInputBufferLastWord" },
},
enter = {
help = "rename",
messages = {
@ -1450,7 +1379,7 @@ xplr.config.modes.builtin.rename = {
on_special_character = nil,
default = {
help = nil,
messages = { "BufferInputFromKey" },
messages = { "UpdateInputBufferFromKey" },
},
},
}
@ -1684,51 +1613,10 @@ xplr.config.modes.builtin.search = {
extra_help = nil,
key_bindings = {
on_key = {
backspace = {
help = "remove last character",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesContain",
},
"RemoveInputBufferLastCharacter",
{
AddNodeFilterFromInput = "IRelativePathDoesContain",
},
"ExplorePwdAsync",
},
},
["ctrl-c"] = {
help = "terminate",
messages = { "Terminate" },
},
["ctrl-u"] = {
help = "remove line",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesContain",
},
{
SetInputBuffer = "",
},
{
AddNodeFilterFromInput = "IRelativePathDoesContain",
},
"ExplorePwdAsync",
},
},
["ctrl-w"] = {
help = "remove last word",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesContain",
},
"RemoveInputBufferLastWord",
{
AddNodeFilterFromInput = "IRelativePathDoesContain",
},
"ExplorePwdAsync",
},
},
down = {
help = "down",
messages = { "FocusNext" },
@ -1743,26 +1631,26 @@ xplr.config.modes.builtin.search = {
"ExplorePwdAsync",
},
},
left = {
help = "back",
right = {
help = "enter",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesContain",
},
"Back",
"Enter",
{
SetInputBuffer = "",
},
"ExplorePwdAsync",
},
},
right = {
help = "enter",
left = {
help = "back",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesContain",
},
"Enter",
"Back",
{
SetInputBuffer = "",
},
@ -1787,7 +1675,7 @@ xplr.config.modes.builtin.search = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesContain",
},
"BufferInputFromKey",
"UpdateInputBufferFromKey",
{
AddNodeFilterFromInput = "IRelativePathDoesContain",
},
@ -1826,10 +1714,6 @@ xplr.config.modes.builtin.filter = {
"ExplorePwdAsync",
},
},
backspace = {
help = "remove last filter",
messages = { "RemoveLastNodeFilter", "ExplorePwdAsync" },
},
["ctrl-c"] = {
help = "terminate",
messages = { "Terminate" },
@ -1879,51 +1763,10 @@ xplr.config.modes.builtin.relative_path_does_contain = {
extra_help = nil,
key_bindings = {
on_key = {
backspace = {
help = "remove last character",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesContain",
},
"RemoveInputBufferLastCharacter",
{
AddNodeFilterFromInput = "IRelativePathDoesContain",
},
"ExplorePwdAsync",
},
},
["ctrl-c"] = {
help = "terminate",
messages = { "Terminate" },
},
["ctrl-u"] = {
help = "remove line",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesContain",
},
{
SetInputBuffer = "",
},
{
AddNodeFilterFromInput = "IRelativePathDoesContain",
},
"ExplorePwdAsync",
},
},
["ctrl-w"] = {
help = "remove last word",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesContain",
},
"RemoveInputBufferLastWord",
{
AddNodeFilterFromInput = "IRelativePathDoesContain",
},
"ExplorePwdAsync",
},
},
enter = {
help = "apply filter",
messages = { "PopMode" },
@ -1948,7 +1791,7 @@ xplr.config.modes.builtin.relative_path_does_contain = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesContain",
},
"BufferInputFromKey",
"UpdateInputBufferFromKey",
{
AddNodeFilterFromInput = "IRelativePathDoesContain",
},
@ -1965,51 +1808,10 @@ xplr.config.modes.builtin.relative_path_does_not_contain = {
extra_help = nil,
key_bindings = {
on_key = {
backspace = {
help = "remove last character",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesNotContain",
},
"RemoveInputBufferLastCharacter",
{
AddNodeFilterFromInput = "IRelativePathDoesNotContain",
},
"ExplorePwdAsync",
},
},
["ctrl-c"] = {
help = "terminate",
messages = { "Terminate" },
},
["ctrl-u"] = {
help = "remove line",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesNotContain",
},
{
SetInputBuffer = "",
},
{
AddNodeFilterFromInput = "IRelativePathDoesNotContain",
},
"ExplorePwdAsync",
},
},
["ctrl-w"] = {
help = "remove last word",
messages = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesNotContain",
},
"RemoveInputBufferLastWord",
{
AddNodeFilterFromInput = "IRelativePathDoesNotContain",
},
"ExplorePwdAsync",
},
},
enter = {
help = "apply filter",
messages = { "PopMode" },
@ -2034,7 +1836,7 @@ xplr.config.modes.builtin.relative_path_does_not_contain = {
{
RemoveNodeFilterFromInput = "IRelativePathDoesNotContain",
},
"BufferInputFromKey",
"UpdateInputBufferFromKey",
{
AddNodeFilterFromInput = "IRelativePathDoesNotContain",
},

@ -1,6 +1,7 @@
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use tui_input::InputRequest;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
@ -111,6 +112,23 @@ pub enum Key {
CtrlY,
CtrlZ,
CtrlBackspace,
CtrlLeft,
CtrlRight,
CtrlUp,
CtrlDown,
CtrlHome,
CtrlEnd,
CtrlPageUp,
CtrlPageDown,
CtrlBackTab,
CtrlDelete,
CtrlInsert,
CtrlEnter,
CtrlSpace,
CtrlTab,
CtrlEsc,
AltA,
AltB,
AltC,
@ -190,6 +208,35 @@ impl std::fmt::Display for Key {
}
impl Key {
pub fn to_input_request(self) -> Option<InputRequest> {
use InputRequest::*;
use Key::*;
if self.is_alphabet() || self.is_number() || self.is_special_character()
{
self.to_char().map(InsertChar)
} else {
match self {
Backspace => Some(DeletePrevChar),
Delete => Some(DeleteNextChar),
Tab => Some(InsertChar('\t')),
Space => Some(InsertChar(' ')),
Left => Some(GoToPrevChar),
CtrlLeft => Some(GoToPrevWord),
Right => Some(GoToNextChar),
CtrlRight => Some(GoToNextWord),
CtrlU => Some(DeleteLine),
CtrlW => Some(DeletePrevWord),
CtrlDelete => Some(DeleteNextWord),
CtrlA => Some(GoToStart),
CtrlE => Some(GoToEnd),
Enter => Some(Submit),
Esc => Some(Escape),
_ => None,
}
}
}
pub fn from_event(key: KeyEvent) -> Self {
match key.modifiers {
KeyModifiers::CONTROL => match key.code {
@ -219,6 +266,23 @@ impl Key {
KeyCode::Char('x') => Key::CtrlX,
KeyCode::Char('y') => Key::CtrlY,
KeyCode::Char('z') => Key::CtrlZ,
KeyCode::Char(' ') => Key::CtrlSpace,
KeyCode::Backspace => Key::CtrlBackspace,
KeyCode::Left => Key::CtrlLeft,
KeyCode::Right => Key::CtrlRight,
KeyCode::Up => Key::CtrlUp,
KeyCode::Down => Key::CtrlDown,
KeyCode::Home => Key::CtrlHome,
KeyCode::End => Key::CtrlEnd,
KeyCode::PageUp => Key::CtrlPageUp,
KeyCode::PageDown => Key::CtrlPageDown,
KeyCode::BackTab => Key::CtrlBackTab,
KeyCode::Delete => Key::CtrlDelete,
KeyCode::Insert => Key::CtrlInsert,
KeyCode::Enter => Key::CtrlEnter,
KeyCode::Tab => Key::CtrlTab,
KeyCode::Esc => Key::CtrlEsc,
KeyCode::Char(c) => c.into(),

@ -68,7 +68,10 @@ fn call(app: &app::App, cmd: app::Command, silent: bool) -> Result<ExitStatus> {
.env("XPLR_PID", &app.pid.to_string())
.env(
"XPLR_INPUT_BUFFER",
app.input_buffer.clone().unwrap_or_default(),
app.input
.as_ref()
.map(|i| i.value().to_string())
.unwrap_or_default(),
)
.env("XPLR_FOCUS_PATH", app.focused_node_str())
.env("XPLR_FOCUS_INDEX", focus_index)

@ -769,6 +769,26 @@ fn draw_input_buffer<B: Backend>(
.default
.to_owned()
.extend(&panel_config.input_and_logs);
let cursor_offset = if config
.borders
.as_ref()
.map(|b| b.contains(&Border::Right))
.unwrap_or(false)
{
3
} else {
2
};
let input_val = app
.input
.as_ref()
.map(|i| i.value().to_string())
.unwrap_or_default();
let input_cursor =
app.input.as_ref().map(|i| i.cursor()).unwrap_or_default();
let input_buf = Paragraph::new(Spans::from(vec![
Span::styled(
app.config
@ -779,22 +799,20 @@ fn draw_input_buffer<B: Backend>(
.unwrap_or_default(),
app.config.general.prompt.style.to_owned().into(),
),
Span::raw(app.input_buffer.clone().unwrap_or_else(|| "".into())),
Span::styled(
app.config
.general
.cursor
.format
.to_owned()
.unwrap_or_default(),
app.config.general.cursor.style.to_owned().into(),
),
Span::raw(&input_val),
]))
.block(block(
config,
format!(" Input [{}{}] ", app.mode.name, read_only_indicator(app)),
));
f.render_widget(input_buf, layout_size);
f.set_cursor(
// Put cursor past the end of the input text
layout_size.x + input_cursor as u16 + cursor_offset,
// Move one line down, from the border to the input line
layout_size.y + 1,
);
}
fn draw_sort_n_filter<B: Backend>(
@ -1202,7 +1220,7 @@ pub fn draw_layout<B: Backend>(
draw_selection(f, screen_size, layout_size, app, lua)
}
Layout::InputAndLogs => {
if app.input_buffer.is_some() {
if app.input.is_some() {
draw_input_buffer(f, screen_size, layout_size, app, lua);
} else {
draw_logs(f, screen_size, layout_size, app, lua);

Loading…
Cancel
Save