From f7a9a1b87107424db026ddd8b6d0e6b4ce7fc4a8 Mon Sep 17 00:00:00 2001 From: sxyazi Date: Mon, 20 Oct 2025 14:36:34 +0800 Subject: [PATCH] Simplify the code --- cspell.json | 2 +- yazi-config/preset/keymap-default.toml | 8 +++--- yazi-parser/src/input/casefy.rs | 25 +++++++++++++++++ yazi-parser/src/input/mod.rs | 2 +- yazi-widgets/src/input/commands/case.rs | 24 ---------------- yazi-widgets/src/input/commands/casefy.rs | 31 +++++++++++++++++++++ yazi-widgets/src/input/commands/commands.rs | 3 +- yazi-widgets/src/input/commands/mod.rs | 2 +- yazi-widgets/src/input/commands/undo.rs | 2 +- yazi-widgets/src/input/input.rs | 14 ---------- yazi-widgets/src/input/op.rs | 2 -- 11 files changed, 65 insertions(+), 50 deletions(-) create mode 100644 yazi-parser/src/input/casefy.rs delete mode 100644 yazi-widgets/src/input/commands/case.rs create mode 100644 yazi-widgets/src/input/commands/casefy.rs diff --git a/cspell.json b/cspell.json index 65ac5b6a..c55d3a1a 100644 --- a/cspell.json +++ b/cspell.json @@ -1 +1 @@ -{"version":"0.2","flagWords":[],"language":"en","words":["Punct","KEYMAP","splitn","crossterm","YAZI","peekable","ratatui","syntect","pbpaste","pbcopy","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","Konsole","Überzug","pkgs","pdftoppm","poppler","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox","cfgs","fstype","objc","rdev","runloop","exfat","rclone","DECRQSS","DECSCUSR","libvterm","Uninit","lockin","rposition","resvg","foldhash","tilded","futs","chdir","hashbrown","JEMALLOC","RUSTFLAGS","RDONLY","GETPATH","fcntl","casefold","inodes","Splatable"]} \ No newline at end of file +{"language":"en","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","peekable","ratatui","syntect","pbpaste","pbcopy","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","Konsole","Überzug","pkgs","pdftoppm","poppler","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox","cfgs","fstype","objc","rdev","runloop","exfat","rclone","DECRQSS","DECSCUSR","libvterm","Uninit","lockin","rposition","resvg","foldhash","tilded","futs","chdir","hashbrown","JEMALLOC","RUSTFLAGS","RDONLY","GETPATH","fcntl","casefold","inodes","Splatable","casefied"],"version":"0.2"} \ No newline at end of file diff --git a/yazi-config/preset/keymap-default.toml b/yazi-config/preset/keymap-default.toml index dcf991e0..7342a93c 100644 --- a/yazi-config/preset/keymap-default.toml +++ b/yazi-config/preset/keymap-default.toml @@ -301,10 +301,10 @@ keymap = [ { on = "p", run = "paste", desc = "Paste copied characters after the cursor" }, { on = "P", run = "paste --before", desc = "Paste copied characters before the cursor" }, - # Undo/Redo/Change case - { on = "u", run = [ "undo", "lowercase"], desc = "Undo the last operation or Lowercase selected characters" }, - { on = "", run = "redo", desc = "Redo the last operation" }, - { on = "U", run = "uppercase", desc = "Uppercase selected characters" }, + # Undo/Redo/Casefy + { on = "u", run = [ "undo", "casefy lower" ], desc = "Undo, or lowercase if in visual mode" }, + { on = "U", run = "casefy upper", desc = "Uppercase" }, + { on = "", run = "redo", desc = "Redo the last operation" }, # Help { on = "~", run = "help", desc = "Open help" }, diff --git a/yazi-parser/src/input/casefy.rs b/yazi-parser/src/input/casefy.rs new file mode 100644 index 00000000..30628c91 --- /dev/null +++ b/yazi-parser/src/input/casefy.rs @@ -0,0 +1,25 @@ +use mlua::{ExternalError, FromLua, IntoLua, Lua, Value}; +use yazi_shared::event::CmdCow; + +#[derive(Debug)] +pub struct CasefyOpt { + pub upper: bool, +} + +impl From for CasefyOpt { + fn from(c: CmdCow) -> Self { Self { upper: c.str(0) == "upper" } } +} + +impl FromLua for CasefyOpt { + fn from_lua(_: Value, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + +impl IntoLua for CasefyOpt { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } +} + +impl CasefyOpt { + pub fn transform(&self, s: &str) -> String { + if self.upper { s.to_ascii_uppercase() } else { s.to_ascii_lowercase() } + } +} diff --git a/yazi-parser/src/input/mod.rs b/yazi-parser/src/input/mod.rs index 9f587eba..7f002580 100644 --- a/yazi-parser/src/input/mod.rs +++ b/yazi-parser/src/input/mod.rs @@ -1 +1 @@ -yazi_macro::mod_flat!(backspace backward close complete delete forward insert kill paste r#move show); +yazi_macro::mod_flat!(backspace backward casefy close complete delete forward insert kill paste r#move show); diff --git a/yazi-widgets/src/input/commands/case.rs b/yazi-widgets/src/input/commands/case.rs deleted file mode 100644 index 85798b0c..00000000 --- a/yazi-widgets/src/input/commands/case.rs +++ /dev/null @@ -1,24 +0,0 @@ -use anyhow::Result; -use yazi_macro::{act, render, succ}; -use yazi_parser::VoidOpt; -use yazi_shared::data::Data; - -use crate::input::{Input, op::InputOp}; - -impl Input { - pub fn uppercase(&mut self, _: VoidOpt) -> Result { self.apply_case(true) } - - pub fn lowercase(&mut self, _: VoidOpt) -> Result { self.apply_case(false) } - - fn apply_case(&mut self, uppercase: bool) -> Result { - match self.snap().op { - InputOp::Select(start) => { - self.snap_mut().op = InputOp::Case(uppercase, start); - render!(self.handle_op(self.snap().cursor, true)); - act!(r#move, self)?; - } - _ => {} - } - succ!(); - } -} diff --git a/yazi-widgets/src/input/commands/casefy.rs b/yazi-widgets/src/input/commands/casefy.rs new file mode 100644 index 00000000..8ab6f6e6 --- /dev/null +++ b/yazi-widgets/src/input/commands/casefy.rs @@ -0,0 +1,31 @@ +use std::ops::Range; + +use anyhow::Result; +use yazi_macro::{act, render, succ}; +use yazi_parser::input::CasefyOpt; +use yazi_shared::data::Data; + +use crate::input::{Input, op::InputOp}; + +impl Input { + pub fn casefy(&mut self, opt: CasefyOpt) -> Result { + let snap = self.snap_mut(); + if !matches!(snap.op, InputOp::Select(_)) { + succ!(); + } + + let range = snap.op.range(snap.cursor, true).unwrap(); + let Range { start, end } = snap.idx(range.start)..snap.idx(range.end); + + let (start, end) = (start.unwrap(), end.unwrap()); + let casefied = opt.transform(&snap.value[start..end]); + + snap.value.replace_range(start..end, &casefied); + snap.op = InputOp::None; + snap.cursor = range.start; + self.snaps.tag(self.limit).then(|| self.flush_value()); + + act!(r#move, self)?; + succ!(render!()); + } +} diff --git a/yazi-widgets/src/input/commands/commands.rs b/yazi-widgets/src/input/commands/commands.rs index 5bd15dbc..86644ee3 100644 --- a/yazi-widgets/src/input/commands/commands.rs +++ b/yazi-widgets/src/input/commands/commands.rs @@ -36,8 +36,7 @@ impl Input { on!(undo); on!(redo); - on!(uppercase); - on!(lowercase); + on!(casefy); } InputMode::Insert => { on!(visual); diff --git a/yazi-widgets/src/input/commands/mod.rs b/yazi-widgets/src/input/commands/mod.rs index ce716f4b..8e01d1f5 100644 --- a/yazi-widgets/src/input/commands/mod.rs +++ b/yazi-widgets/src/input/commands/mod.rs @@ -1 +1 @@ -yazi_macro::mod_flat!(backspace backward commands complete delete escape forward insert kill paste r#move r#type redo replace undo visual yank case); +yazi_macro::mod_flat!(backspace backward casefy commands complete delete escape forward insert kill paste r#move r#type redo replace undo visual yank); diff --git a/yazi-widgets/src/input/commands/undo.rs b/yazi-widgets/src/input/commands/undo.rs index 119871a1..934299b0 100644 --- a/yazi-widgets/src/input/commands/undo.rs +++ b/yazi-widgets/src/input/commands/undo.rs @@ -7,7 +7,7 @@ use crate::input::{Input, InputMode, InputOp}; impl Input { pub fn undo(&mut self, _: VoidOpt) -> Result { - if let InputOp::Select(_) = self.snap().op { + if self.snap().op != InputOp::None { succ!(); } diff --git a/yazi-widgets/src/input/input.rs b/yazi-widgets/src/input/input.rs index 742366b5..8c636592 100644 --- a/yazi-widgets/src/input/input.rs +++ b/yazi-widgets/src/input/input.rs @@ -50,20 +50,6 @@ impl Input { snap.op = InputOp::None; futures::executor::block_on(CLIPBOARD.set(yanked)); } - InputOp::Case(upper, _) => { - let range = snap.op.range(cursor, include).unwrap(); - let Range { start, end } = snap.idx(range.start)..snap.idx(range.end); - - if let (Some(start), Some(end)) = (start, end) { - let selected = &snap.value[start..end]; - let replaced = if upper { selected.to_uppercase() } else { selected.to_lowercase() }; - snap.value.replace_range(start..end, &replaced); - } - - snap.op = InputOp::None; - snap.mode = InputMode::Normal; - snap.cursor = range.start; - } }; snap.cursor = snap.count().saturating_sub(snap.mode.delta()).min(snap.cursor); diff --git a/yazi-widgets/src/input/op.rs b/yazi-widgets/src/input/op.rs index b68a8513..036ca44a 100644 --- a/yazi-widgets/src/input/op.rs +++ b/yazi-widgets/src/input/op.rs @@ -7,7 +7,6 @@ pub enum InputOp { Select(usize), Delete(bool, bool, usize), // cut, insert, start Yank(usize), - Case(bool, usize), // upper, start } impl InputOp { @@ -18,7 +17,6 @@ impl InputOp { Self::Select(s) => Some(*s), Self::Delete(.., s) => Some(*s), Self::Yank(s) => Some(*s), - Self::Case(.., s) => Some(*s), } }