summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--development.md2
-rw-r--r--src/event_exec.rs25
-rw-r--r--src/input.rs27
-rw-r--r--src/keybindings.rs1
-rw-r--r--src/tab.rs23
-rw-r--r--src/term_manager.rs6
8 files changed, 61 insertions, 31 deletions
diff --git a/Cargo.lock b/Cargo.lock
index fa1312a..74f85f3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -923,6 +923,7 @@ dependencies = [
"tokio",
"tuikit",
"ueberzug",
+ "unicode-segmentation",
"url-escape",
"users",
"which",
@@ -2781,6 +2782,12 @@ dependencies = [
]
[[package]]
+name = "unicode-segmentation"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
+
+[[package]]
name = "unicode-width"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 47372a2..b9cffbd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -64,4 +64,5 @@ users = "0.11.0"
zip = "0.6.4"
tokio = "1"
ueberzug = "0.1.0"
+unicode-segmentation = "1.10.1"
which = "4.4.0"
diff --git a/development.md b/development.md
index eafe2dc..df79336 100644
--- a/development.md
+++ b/development.md
@@ -581,6 +581,8 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally.
- [x] more args : dual pane, preview second, display full, show hidden
- [x] history: when moving back select back the file we were at
- [x] use yellow block char to make flagged files more visibles.
+- [x] move input 1 char right since we inserted a space
+- [ ] BUG: when encrypted drive is already mounted don't let user mount it again
- [ ] document filepicking (from my config etc.).
- [ ] avoid multiple refreshs if we edit files ourself
diff --git a/src/event_exec.rs b/src/event_exec.rs
index 91d1fce..eff4b91 100644
--- a/src/event_exec.rs
+++ b/src/event_exec.rs
@@ -38,8 +38,8 @@ use crate::status::Status;
use crate::tab::Tab;
use crate::utils::is_program_in_path;
use crate::utils::{
- args_is_empty, disk_used_by_path, filename_from_path, is_sudo_command, open_in_current_neovim,
- opt_mount_point, string_to_path,
+ args_is_empty, disk_used_by_path, is_sudo_command, open_in_current_neovim, opt_mount_point,
+ string_to_path,
};
/// Links events from tuikit to custom actions.
@@ -358,21 +358,7 @@ impl EventAction {
/// When we enter rename from a "tree" mode, we'll need to rename the selected file in the tree,
/// not the selected file in the pathcontent.
pub fn rename(tab: &mut Tab) -> Result<()> {
- if tab.selected().is_some() {
- let old_name = match tab.mode {
- Mode::Tree => tab.directory.tree.current_node.filename(),
- _ => filename_from_path(
- &tab.path_content
- .selected()
- .context("Event rename: no file in current directory")?
- .path,
- )?
- .to_owned(),
- };
- tab.input.replace(&old_name);
- tab.set_mode(Mode::InputSimple(InputSimple::Rename));
- }
- Ok(())
+ tab.rename()
}
/// Enter the goto mode where an user can type a path to jump to.
@@ -635,10 +621,7 @@ impl EventAction {
pub fn delete(status: &mut Status) -> Result<()> {
match status.selected().mode {
Mode::InputSimple(_) | Mode::InputCompleted(_) => {
- {
- let tab: &mut Tab = status.selected();
- tab.input.delete_chars_right()
- };
+ status.selected().input.delete_chars_right();
Ok(())
}
_ => Ok(()),
diff --git a/src/input.rs b/src/input.rs
index 00f7838..d70eb6d 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -1,9 +1,11 @@
+use unicode_segmentation::UnicodeSegmentation;
+
/// Holds the chars typed by the user and the cursor position.
/// Methods allow mutation of this content and movement of the cursor.
#[derive(Clone, Default)]
pub struct Input {
/// The input typed by the user
- chars: Vec<char>,
+ chars: Vec<String>,
/// The index of the cursor in that string
pub cursor_index: usize,
}
@@ -57,12 +59,17 @@ impl Input {
/// Delete all chars right to the cursor
pub fn delete_chars_right(&mut self) {
- self.chars = self.chars.iter().copied().take(self.cursor_index).collect();
+ self.chars = self
+ .chars
+ .iter()
+ .take(self.cursor_index)
+ .map(|s| s.to_string())
+ .collect();
}
/// Returns the content typed by the user as a String.
pub fn string(&self) -> String {
- self.chars.iter().collect()
+ self.chars.join("")
}
/// Returns a string of * for every char typed.
@@ -72,7 +79,7 @@ impl Input {
/// Insert an utf-8 char into the input at cursor index.
pub fn insert(&mut self, c: char) {
- self.chars.insert(self.cursor_index, c);
+ self.chars.insert(self.cursor_index, String::from(c));
self.cursor_index += 1
}
@@ -84,8 +91,18 @@ impl Input {
/// Replace the content with the new content.
/// Put the cursor at the end.
+ ///
+ /// To avoid splitting graphemes at wrong place, the new content is read
+ /// as Unicode Graphemes with
+ /// ```rust
+ /// unicode_segmentation::UnicodeSegmentation::graphemes(content, true)
+ /// ```
pub fn replace(&mut self, content: &str) {
- self.chars = content.chars().collect();
+ self.chars = UnicodeSegmentation::graphemes(content, true)
+ .collect::<Vec<&str>>()
+ .iter()
+ .map(|s| s.to_string())
+ .collect();
self.cursor_index = self.len()
}
}
diff --git a/src/keybindings.rs b/src/keybindings.rs
index c3c53be..8fc4662 100644
--- a/src/keybindings.rs
+++ b/src/keybindings.rs
@@ -112,6 +112,7 @@ impl Bindings {
(Key::Ctrl('f'), ActionMap::FuzzyFind),
(Key::Ctrl('g'), ActionMap::Shortcut),
(Key::Ctrl('h'), ActionMap::History),
+ (Key::Ctrl('k'), ActionMap::Delete),
(Key::Ctrl('s'), ActionMap::FuzzyFindLine),
(Key::Ctrl('u'), ActionMap::PageUp),
(Key::Ctrl('p'), ActionMap::CopyFilepath),
diff --git a/src/tab.rs b/src/tab.rs
index 064412e..0fe3eb3 100644
--- a/src/tab.rs
+++ b/src/tab.rs
@@ -12,12 +12,12 @@ use crate::fileinfo::{FileInfo, FileKind, PathContent};
use crate::filter::FilterKind;
use crate::history::History;
use crate::input::Input;
-use crate::mode::Mode;
+use crate::mode::{InputSimple, Mode};
use crate::opener::execute_in_child;
use crate::preview::{Directory, Preview};
use crate::selectable_content::SelectableContent;
use crate::shortcut::Shortcut;
-use crate::utils::{row_to_window_index, set_clipboard};
+use crate::utils::{filename_from_path, row_to_window_index, set_clipboard};
/// Holds every thing about the current tab of the application.
/// Most of the mutation is done externally.
@@ -707,4 +707,23 @@ impl Tab {
execute_in_child(command, &args)?;
Ok(true)
}
+
+ pub fn rename(&mut self) -> Result<()> {
+ if self.selected().is_some() {
+ let old_name = match self.mode {
+ Mode::Tree => self.directory.tree.current_node.filename(),
+ _ => filename_from_path(
+ &self
+ .path_content
+ .selected()
+ .context("Event rename: no file in current directory")?
+ .path,
+ )?
+ .to_owned(),
+ };
+ self.input.replace(&old_name);
+ self.set_mode(Mode::InputSimple(InputSimple::Rename));
+ }
+ Ok(())
+ }
}
diff --git a/src/term_manager.rs b/src/term_manager.rs
index 399d1ab..4dd2fa9 100644
--- a/src/term_manager.rs
+++ b/src/term_manager.rs
@@ -546,10 +546,10 @@ impl<'a> Draw for WinSecondary<'a> {
}
impl<'a> WinSecondary<'a> {
- const EDIT_BOX_OFFSET: usize = 9;
const ATTR_YELLOW: Attr = color_to_attr(Color::YELLOW);
- const SORT_CURSOR_OFFSET: usize = 37;
- const PASSWORD_CURSOR_OFFSET: usize = 7;
+ const EDIT_BOX_OFFSET: usize = 10;
+ const SORT_CURSOR_OFFSET: usize = 38;
+ const PASSWORD_CURSOR_OFFSET: usize = 8;
fn new(status: &'a Status, index: usize) -> Self {
Self {