mirror of
https://github.com/sayanarijit/xplr
synced 2024-11-04 18:00:14 +00:00
Support more control over input buffer
This PR adds a new message: `UpdateInputBuffer: InputOperation` This makes it possible to perform cursor based input operations without needing input from the keyboard.
This commit is contained in:
parent
b45a553a0c
commit
05c2f7aa68
@ -210,9 +210,25 @@ Go to the next path visited.
|
||||
|
||||
Follow the symlink under focus to its actual location.
|
||||
|
||||
### { UpdateInputBuffer = [Input Opertaion][71] }
|
||||
|
||||
**YAML:** `BufferInput: Input Operation`
|
||||
|
||||
Update the input buffer using cursor based operations.
|
||||
|
||||
**YAML Example:** `UpdateInputBuffer: GoToPreviousWord`
|
||||
|
||||
**Lua Example:** `{ UpdateInputBuffer = "GoToPreviousWord" }`
|
||||
|
||||
### "UpdateInputBufferFromKey"
|
||||
|
||||
**YAML:** `UpdateInputBufferFromKey`
|
||||
|
||||
Update the input buffer from the key read from keyboard input.
|
||||
|
||||
### { BufferInput = "string" }
|
||||
|
||||
**YAML:** `BufferInput(String)`
|
||||
**YAML:** `BufferInput: string`
|
||||
|
||||
Append/buffer the given string into the input buffer.
|
||||
|
||||
@ -790,6 +806,24 @@ Write the application state to a file, without quitting. Also helpful for debugg
|
||||
|
||||
Terminate the application with a non-zero return code.
|
||||
|
||||
## InputOperation
|
||||
|
||||
Cursor based input operation can be one of the following:
|
||||
|
||||
- { SetCursor = int }
|
||||
- { InsertCharacter = str }
|
||||
- "GoToPreviousCharacter"
|
||||
- "GoToNextCharacter"
|
||||
- "GoToPreviousWord"
|
||||
- "GoToNextWord"
|
||||
- "GoToStart"
|
||||
- "GoToEnd"
|
||||
- "DeletePreviousCharacter"
|
||||
- "DeleteNextCharacter"
|
||||
- "DeletePreviousWord"
|
||||
- "DeleteNextWord"
|
||||
- "DeleteLine"
|
||||
|
||||
## Lua Function Calls
|
||||
|
||||
xplr allows users to define lua functions using the `xplr.fn.custom` Lua API.
|
||||
@ -1286,3 +1320,4 @@ xplr.config.modes.builtin.default.key_bindings.on_key.space = {
|
||||
[68]: #loc
|
||||
[69]: #paths
|
||||
[70]: #history-1
|
||||
[71]: #inputoperation
|
||||
|
29
src/app.rs
29
src/app.rs
@ -1,7 +1,7 @@
|
||||
use crate::config::Config;
|
||||
use crate::config::Mode;
|
||||
use crate::explorer;
|
||||
use crate::input::Key;
|
||||
use crate::input::{InputOperation, Key};
|
||||
use crate::lua;
|
||||
use crate::permissions::Permissions;
|
||||
use crate::ui::Layout;
|
||||
@ -777,6 +777,11 @@ pub enum ExternalMsg {
|
||||
/// Follow the symlink under focus to its actual location.
|
||||
FollowSymlink,
|
||||
|
||||
/// Update the input buffer using cursor based operations.
|
||||
///
|
||||
/// **Example:** `UpdateInputBuffer: GoToPreviousWord`
|
||||
UpdateInputBuffer(InputOperation),
|
||||
|
||||
/// Update the input buffer from given key
|
||||
UpdateInputBufferFromKey,
|
||||
|
||||
@ -1481,6 +1486,9 @@ impl App {
|
||||
ExternalMsg::LastVisitedPath => self.last_visited_path(),
|
||||
ExternalMsg::NextVisitedPath => self.next_visited_path(),
|
||||
ExternalMsg::FollowSymlink => self.follow_symlink(),
|
||||
ExternalMsg::UpdateInputBuffer(op) => {
|
||||
self.update_input_buffer(op)
|
||||
}
|
||||
ExternalMsg::UpdateInputBufferFromKey => {
|
||||
self.update_input_buffer_from_key(key)
|
||||
}
|
||||
@ -1886,18 +1894,21 @@ 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);
|
||||
}
|
||||
fn update_input_buffer(mut self, op: InputOperation) -> Result<Self> {
|
||||
if let Some(buf) = self.input.as_mut() {
|
||||
buf.handle(op.into());
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn update_input_buffer_from_key(self, key: Option<Key>) -> Result<Self> {
|
||||
if let Some(op) = key.and_then(|k| k.to_input_operation()) {
|
||||
self.update_input_buffer(op)
|
||||
} else {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn buffer_input(mut self, input: &str) -> Result<Self> {
|
||||
if let Some(buf) = self.input.as_mut() {
|
||||
buf.handle(InputRequest::GoToEnd);
|
||||
|
61
src/input.rs
61
src/input.rs
@ -208,27 +208,25 @@ impl std::fmt::Display for Key {
|
||||
}
|
||||
|
||||
impl Key {
|
||||
pub fn to_input_request(&self) -> Option<InputRequest> {
|
||||
use InputRequest::*;
|
||||
pub fn to_input_operation(&self) -> Option<InputOperation> {
|
||||
use InputOperation::*;
|
||||
use Key::*;
|
||||
|
||||
match self {
|
||||
Backspace => Some(DeletePrevChar),
|
||||
Delete => Some(DeleteNextChar),
|
||||
Tab => Some(InsertChar('\t')),
|
||||
Space => Some(InsertChar(' ')),
|
||||
Left => Some(GoToPrevChar),
|
||||
CtrlLeft => Some(GoToPrevWord),
|
||||
Right => Some(GoToNextChar),
|
||||
Backspace => Some(DeletePreviousCharacter),
|
||||
Delete => Some(DeleteNextCharacter),
|
||||
Tab => Some(InsertCharacter('\t')),
|
||||
Space => Some(InsertCharacter(' ')),
|
||||
Left => Some(GoToPreviousCharacter),
|
||||
CtrlLeft => Some(GoToPreviousWord),
|
||||
Right => Some(GoToNextCharacter),
|
||||
CtrlRight => Some(GoToNextWord),
|
||||
CtrlU => Some(DeleteLine),
|
||||
CtrlW => Some(DeletePrevWord),
|
||||
CtrlW => Some(DeletePreviousWord),
|
||||
CtrlDelete => Some(DeleteNextWord),
|
||||
CtrlA => Some(GoToStart),
|
||||
CtrlE => Some(GoToEnd),
|
||||
Enter => Some(Submit),
|
||||
Esc => Some(Escape),
|
||||
key => key.to_char().map(InsertChar),
|
||||
key => key.to_char().map(InsertCharacter),
|
||||
}
|
||||
}
|
||||
|
||||
@ -726,3 +724,40 @@ impl PartialOrd for Key {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum InputOperation {
|
||||
SetCursor(usize),
|
||||
InsertCharacter(char),
|
||||
GoToPreviousCharacter,
|
||||
GoToNextCharacter,
|
||||
GoToPreviousWord,
|
||||
GoToNextWord,
|
||||
GoToStart,
|
||||
GoToEnd,
|
||||
DeletePreviousCharacter,
|
||||
DeleteNextCharacter,
|
||||
DeletePreviousWord,
|
||||
DeleteNextWord,
|
||||
DeleteLine,
|
||||
}
|
||||
|
||||
impl Into<InputRequest> for InputOperation {
|
||||
fn into(self) -> InputRequest {
|
||||
match self {
|
||||
Self::SetCursor(i) => InputRequest::SetCursor(i),
|
||||
Self::InsertCharacter(c) => InputRequest::InsertChar(c),
|
||||
Self::GoToPreviousCharacter => InputRequest::GoToPrevChar,
|
||||
Self::GoToNextCharacter => InputRequest::GoToNextChar,
|
||||
Self::GoToPreviousWord => InputRequest::GoToPrevWord,
|
||||
Self::GoToNextWord => InputRequest::GoToNextWord,
|
||||
Self::GoToStart => InputRequest::GoToStart,
|
||||
Self::GoToEnd => InputRequest::GoToEnd,
|
||||
Self::DeletePreviousCharacter => InputRequest::DeletePrevChar,
|
||||
Self::DeleteNextCharacter => InputRequest::DeleteNextChar,
|
||||
Self::DeletePreviousWord => InputRequest::DeletePrevWord,
|
||||
Self::DeleteNextWord => InputRequest::DeleteNextWord,
|
||||
Self::DeleteLine => InputRequest::DeleteLine,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user