work started on refactoring LineBuf
This commit is contained in:
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -577,6 +577,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"smallvec",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
@@ -584,6 +585,12 @@ dependencies = [
|
|||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.15.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ rand = "0.10.0"
|
|||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
scopeguard = "1.2.0"
|
scopeguard = "1.2.0"
|
||||||
serde_json = "1.0.149"
|
serde_json = "1.0.149"
|
||||||
|
smallvec = { version = "1.15.1", features = ["write"] }
|
||||||
tempfile = "3.24.0"
|
tempfile = "3.24.0"
|
||||||
unicode-segmentation = "1.12.0"
|
unicode-segmentation = "1.12.0"
|
||||||
unicode-width = "0.2.0"
|
unicode-width = "0.2.0"
|
||||||
|
|||||||
@@ -160,6 +160,12 @@ fn main() -> ExitCode {
|
|||||||
on_exit_autocmds.exec();
|
on_exit_autocmds.exec();
|
||||||
|
|
||||||
write_jobs(|j| j.hang_up());
|
write_jobs(|j| j.hang_up());
|
||||||
|
|
||||||
|
let code = QUIT_CODE.load(Ordering::SeqCst) as u8;
|
||||||
|
if code == 0 && isatty(STDIN_FILENO).unwrap_or_default() {
|
||||||
|
write(borrow_fd(STDERR_FILENO), b"\nexit\n").ok();
|
||||||
|
}
|
||||||
|
|
||||||
ExitCode::from(QUIT_CODE.load(Ordering::SeqCst) as u8)
|
ExitCode::from(QUIT_CODE.load(Ordering::SeqCst) as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use crate::{
|
|||||||
readline::{
|
readline::{
|
||||||
Marker, annotate_input_recursive,
|
Marker, annotate_input_recursive,
|
||||||
keys::{KeyCode as C, KeyEvent as K, ModKeys as M},
|
keys::{KeyCode as C, KeyEvent as K, ModKeys as M},
|
||||||
linebuf::{ClampedUsize, LineBuf},
|
linebuf::LineBuf,
|
||||||
markers::{self, is_marker},
|
markers::{self, is_marker},
|
||||||
term::{LineWriter, TermWriter, calc_str_width, get_win_size},
|
term::{LineWriter, TermWriter, calc_str_width, get_win_size},
|
||||||
vimode::{ViInsert, ViMode},
|
vimode::{ViInsert, ViMode},
|
||||||
@@ -818,7 +818,6 @@ impl QueryEditor {
|
|||||||
self.available_width = width;
|
self.available_width = width;
|
||||||
}
|
}
|
||||||
pub fn update_scroll_offset(&mut self) {
|
pub fn update_scroll_offset(&mut self) {
|
||||||
self.linebuf.update_graphemes();
|
|
||||||
let cursor_pos = self.linebuf.cursor.get();
|
let cursor_pos = self.linebuf.cursor.get();
|
||||||
if cursor_pos < self.scroll_offset + 1 {
|
if cursor_pos < self.scroll_offset + 1 {
|
||||||
self.scroll_offset = self.linebuf.cursor.ret_sub(1);
|
self.scroll_offset = self.linebuf.cursor.ret_sub(1);
|
||||||
@@ -829,10 +828,8 @@ impl QueryEditor {
|
|||||||
.cursor
|
.cursor
|
||||||
.ret_sub(self.available_width.saturating_sub(1));
|
.ret_sub(self.available_width.saturating_sub(1));
|
||||||
}
|
}
|
||||||
let max_offset = self
|
let max_offset = self.linebuf
|
||||||
.linebuf
|
.count_graphemes()
|
||||||
.grapheme_indices()
|
|
||||||
.len()
|
|
||||||
.saturating_sub(self.available_width);
|
.saturating_sub(self.available_width);
|
||||||
self.scroll_offset = self.scroll_offset.min(max_offset);
|
self.scroll_offset = self.scroll_offset.min(max_offset);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@ use vimode::{CmdReplay, ModeReport, ViInsert, ViMode, ViNormal, ViReplace, ViVis
|
|||||||
|
|
||||||
use crate::builtin::keymap::{KeyMapFlags, KeyMapMatch};
|
use crate::builtin::keymap::{KeyMapFlags, KeyMapMatch};
|
||||||
use crate::expand::expand_prompt;
|
use crate::expand::expand_prompt;
|
||||||
|
use crate::libsh::error::{ShErr, ShErrKind};
|
||||||
use crate::libsh::utils::AutoCmdVecUtils;
|
use crate::libsh::utils::AutoCmdVecUtils;
|
||||||
use crate::parse::lex::{LexStream, QuoteState};
|
use crate::parse::lex::{LexStream, QuoteState};
|
||||||
use crate::readline::complete::{FuzzyCompleter, SelectorResponse};
|
use crate::readline::complete::{FuzzyCompleter, SelectorResponse};
|
||||||
@@ -882,7 +883,9 @@ impl ShedVi {
|
|||||||
self.needs_redraw = true;
|
self.needs_redraw = true;
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
}
|
} else if cmd.verb().is_some_and(|v| v.1 == Verb::Quit) {
|
||||||
|
return Ok(Some(ReadlineEvent::Eof));
|
||||||
|
}
|
||||||
|
|
||||||
let has_edit_verb = cmd.verb().is_some_and(|v| v.1.is_edit());
|
let has_edit_verb = cmd.verb().is_some_and(|v| v.1.is_edit());
|
||||||
let is_shell_cmd = cmd.verb().is_some_and(|v| matches!(v.1, Verb::ShellCmd(_)));
|
let is_shell_cmd = cmd.verb().is_some_and(|v| matches!(v.1, Verb::ShellCmd(_)));
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
|
||||||
use crate::readline::vimode::ex::SubFlags;
|
use crate::readline::{linebuf::Grapheme, vimode::ex::SubFlags};
|
||||||
|
|
||||||
use super::register::{RegisterContent, append_register, read_register, write_register};
|
use super::register::{RegisterContent, append_register, read_register, write_register};
|
||||||
|
|
||||||
@@ -161,23 +161,11 @@ impl ViCmd {
|
|||||||
self.motion.as_ref().is_some_and(|m| {
|
self.motion.as_ref().is_some_and(|m| {
|
||||||
matches!(
|
matches!(
|
||||||
m.1,
|
m.1,
|
||||||
Motion::LineUp | Motion::LineDown | Motion::LineUpCharwise | Motion::LineDownCharwise
|
Motion::LineUp | Motion::LineDown
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/// If a ViCmd has a linewise motion, but no verb, we change it to charwise
|
/// If a ViCmd has a linewise motion, but no verb, we change it to charwise
|
||||||
pub fn alter_line_motion_if_no_verb(&mut self) {
|
|
||||||
if self.is_line_motion()
|
|
||||||
&& self.verb.is_none()
|
|
||||||
&& let Some(motion) = self.motion.as_mut()
|
|
||||||
{
|
|
||||||
match motion.1 {
|
|
||||||
Motion::LineUp => motion.1 = Motion::LineUpCharwise,
|
|
||||||
Motion::LineDown => motion.1 = Motion::LineDownCharwise,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn is_mode_transition(&self) -> bool {
|
pub fn is_mode_transition(&self) -> bool {
|
||||||
self.verb.as_ref().is_some_and(|v| {
|
self.verb.as_ref().is_some_and(|v| {
|
||||||
matches!(
|
matches!(
|
||||||
@@ -261,6 +249,7 @@ pub enum Verb {
|
|||||||
Read(ReadSrc),
|
Read(ReadSrc),
|
||||||
Write(WriteDest),
|
Write(WriteDest),
|
||||||
Edit(PathBuf),
|
Edit(PathBuf),
|
||||||
|
Quit,
|
||||||
Substitute(String, String, SubFlags),
|
Substitute(String, String, SubFlags),
|
||||||
RepeatSubstitute,
|
RepeatSubstitute,
|
||||||
RepeatGlobal,
|
RepeatGlobal,
|
||||||
@@ -326,23 +315,20 @@ impl Verb {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub enum Motion {
|
pub enum Motion {
|
||||||
WholeLineInclusive, // whole line including the linebreak
|
WholeLine,
|
||||||
WholeLineExclusive, // whole line excluding the linebreak
|
|
||||||
TextObj(TextObj),
|
TextObj(TextObj),
|
||||||
EndOfLastWord,
|
EndOfLastWord,
|
||||||
BeginningOfFirstWord,
|
BeginningOfFirstWord,
|
||||||
BeginningOfLine,
|
BeginningOfLine,
|
||||||
EndOfLine,
|
EndOfLine,
|
||||||
WordMotion(To, Word, Direction),
|
WordMotion(To, Word, Direction),
|
||||||
CharSearch(Direction, Dest, char),
|
CharSearch(Direction, Dest, Grapheme),
|
||||||
BackwardChar,
|
BackwardChar,
|
||||||
ForwardChar,
|
ForwardChar,
|
||||||
BackwardCharForced, // These two variants can cross line boundaries
|
BackwardCharForced, // These two variants can cross line boundaries
|
||||||
ForwardCharForced,
|
ForwardCharForced,
|
||||||
LineUp,
|
LineUp,
|
||||||
LineUpCharwise,
|
|
||||||
LineDown,
|
LineDown,
|
||||||
LineDownCharwise,
|
|
||||||
WholeBuffer,
|
WholeBuffer,
|
||||||
StartOfBuffer,
|
StartOfBuffer,
|
||||||
EndOfBuffer,
|
EndOfBuffer,
|
||||||
@@ -382,8 +368,6 @@ impl Motion {
|
|||||||
&self,
|
&self,
|
||||||
Self::BeginningOfLine
|
Self::BeginningOfLine
|
||||||
| Self::BeginningOfFirstWord
|
| Self::BeginningOfFirstWord
|
||||||
| Self::LineDownCharwise
|
|
||||||
| Self::LineUpCharwise
|
|
||||||
| Self::ToColumn
|
| Self::ToColumn
|
||||||
| Self::TextObj(TextObj::Sentence(_))
|
| Self::TextObj(TextObj::Sentence(_))
|
||||||
| Self::TextObj(TextObj::Paragraph(_))
|
| Self::TextObj(TextObj::Paragraph(_))
|
||||||
@@ -398,7 +382,7 @@ impl Motion {
|
|||||||
pub fn is_linewise(&self) -> bool {
|
pub fn is_linewise(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self,
|
self,
|
||||||
Self::WholeLineInclusive | Self::WholeLineExclusive | Self::LineUp | Self::LineDown
|
Self::WholeLine | Self::LineUp | Self::LineDown
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,6 +280,7 @@ fn parse_ex_command(chars: &mut Peekable<Chars<'_>>) -> Result<Option<Verb>, Opt
|
|||||||
_ if "delete".starts_with(&cmd_name) => Ok(Some(Verb::Delete)),
|
_ if "delete".starts_with(&cmd_name) => Ok(Some(Verb::Delete)),
|
||||||
_ if "yank".starts_with(&cmd_name) => Ok(Some(Verb::Yank)),
|
_ if "yank".starts_with(&cmd_name) => Ok(Some(Verb::Yank)),
|
||||||
_ if "put".starts_with(&cmd_name) => Ok(Some(Verb::Put(Anchor::After))),
|
_ if "put".starts_with(&cmd_name) => Ok(Some(Verb::Put(Anchor::After))),
|
||||||
|
_ if "quit".starts_with(&cmd_name) => Ok(Some(Verb::Quit)),
|
||||||
_ if "read".starts_with(&cmd_name) => parse_read(chars),
|
_ if "read".starts_with(&cmd_name) => parse_read(chars),
|
||||||
_ if "write".starts_with(&cmd_name) => parse_write(chars),
|
_ if "write".starts_with(&cmd_name) => parse_write(chars),
|
||||||
_ if "edit".starts_with(&cmd_name) => parse_edit(chars),
|
_ if "edit".starts_with(&cmd_name) => parse_edit(chars),
|
||||||
|
|||||||
Reference in New Issue
Block a user