feat: add toggleable buffer word wrap
This commit is contained in:
+105
@@ -574,6 +574,18 @@ core_actions![
|
||||
),
|
||||
("core.save", Action::Save, &[Mode::Normal], true),
|
||||
("core.diff", Action::Diff, &[Mode::Normal], true),
|
||||
(
|
||||
"core.word_wrap.toggle",
|
||||
Action::WordWrapToggle,
|
||||
&[
|
||||
Mode::Normal,
|
||||
Mode::Insert,
|
||||
Mode::Visual,
|
||||
Mode::Command,
|
||||
Mode::Search
|
||||
],
|
||||
true,
|
||||
),
|
||||
(
|
||||
"core.diff.close",
|
||||
Action::DiffClose,
|
||||
@@ -1023,6 +1035,7 @@ struct Buffer {
|
||||
targets: Vec<Target>,
|
||||
primary: usize,
|
||||
mode: Mode,
|
||||
word_wrap: bool,
|
||||
linewise: bool,
|
||||
search_query: String,
|
||||
search_match: Option<SearchMatch>,
|
||||
@@ -1068,6 +1081,7 @@ impl Buffer {
|
||||
targets: vec![Target::caret(Cursor::default())],
|
||||
primary: 0,
|
||||
mode: Mode::Normal,
|
||||
word_wrap: false,
|
||||
linewise: false,
|
||||
search_query: String::new(),
|
||||
search_match: None,
|
||||
@@ -1363,6 +1377,13 @@ impl Editor {
|
||||
self.diff.as_ref()
|
||||
}
|
||||
|
||||
pub fn word_wrap(&self) -> bool {
|
||||
self.diff
|
||||
.as_ref()
|
||||
.filter(|diff| diff.phase == Phase::View)
|
||||
.map_or(self.active.word_wrap, |diff| diff.word_wrap)
|
||||
}
|
||||
|
||||
pub(crate) fn set_diff_context_options(&mut self, context_lines: usize, expand_lines: usize) {
|
||||
self.diff_context_options = (context_lines, expand_lines);
|
||||
if let Some(diff) = &mut self.diff {
|
||||
@@ -1427,6 +1448,7 @@ impl Editor {
|
||||
}
|
||||
self.outstanding_diff_request = None;
|
||||
let mut diff = DiffState::new();
|
||||
diff.word_wrap = self.active.word_wrap;
|
||||
diff.set_context_options(self.diff_context_options.0, self.diff_context_options.1);
|
||||
self.diff = Some(diff);
|
||||
}
|
||||
@@ -1868,6 +1890,7 @@ impl Editor {
|
||||
| Action::FilePicker
|
||||
| Action::FileExplorer
|
||||
| Action::DiffClose
|
||||
| Action::WordWrapToggle
|
||||
| Action::Quit
|
||||
| Action::ForceQuit
|
||||
| Action::Plugins
|
||||
@@ -3956,6 +3979,7 @@ impl Editor {
|
||||
| Action::BufferForceDelete
|
||||
| Action::Diff
|
||||
| Action::DiffClose
|
||||
| Action::WordWrapToggle
|
||||
| Action::LspDefinition
|
||||
| Action::LspHover
|
||||
| Action::LspDiagnostics => unreachable!("catalog Ex actions dispatch above"),
|
||||
@@ -4535,6 +4559,28 @@ impl Editor {
|
||||
|
||||
fn execute_action(&mut self, entry: &CoreAction, args: &str) -> Option<Invocation> {
|
||||
self.finish_diff_prompt();
|
||||
if entry.action == Action::WordWrapToggle {
|
||||
if !args.is_empty() {
|
||||
self.set_message("The word_wrap.toggle command takes no arguments");
|
||||
return None;
|
||||
}
|
||||
if let Some(diff) = &mut self.diff
|
||||
&& diff.phase == Phase::View
|
||||
{
|
||||
diff.word_wrap = !diff.word_wrap;
|
||||
diff.follow_caret = true;
|
||||
} else {
|
||||
self.active.word_wrap = !self.active.word_wrap;
|
||||
}
|
||||
self.count = None;
|
||||
self.clear_leader();
|
||||
self.palette = None;
|
||||
if self.active.mode == Mode::Command {
|
||||
self.command_line.clear();
|
||||
self.active.mode = Mode::Normal;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
if entry.action == Action::DiffClose {
|
||||
if args.is_empty() {
|
||||
self.release_diff_buffers();
|
||||
@@ -7989,6 +8035,65 @@ mod tests {
|
||||
assert_eq!(editor.lines(), ["beta"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn word_wrap_toggle_retains_buffers_and_readonly_diff_state() {
|
||||
let directory = Directory::new();
|
||||
let mut editor = editor();
|
||||
assert!(!editor.word_wrap());
|
||||
editor
|
||||
.bind("normal", "W", Some("core.word_wrap.toggle".into()))
|
||||
.unwrap();
|
||||
editor.handle(Input::Char('W'));
|
||||
assert!(editor.word_wrap());
|
||||
let original = editor.buffer_id();
|
||||
editor.execute(&format!("edit {}", directory.path("other").display()));
|
||||
assert!(!editor.word_wrap());
|
||||
editor.execute(&format!("buffer {original}"));
|
||||
assert!(editor.word_wrap());
|
||||
editor.execute("word_wrap.toggle unexpected");
|
||||
assert!(editor.word_wrap());
|
||||
editor.execute("word_wrap.toggle");
|
||||
assert!(!editor.word_wrap());
|
||||
editor.execute("word_wrap.toggle");
|
||||
historical_diff(
|
||||
&mut editor,
|
||||
&directory.0,
|
||||
vec!["alpha beta".into()],
|
||||
vec!["alpha changed".into()],
|
||||
);
|
||||
assert!(editor.word_wrap());
|
||||
editor
|
||||
.bind("visual", "W", Some("core.word_wrap.toggle".into()))
|
||||
.unwrap();
|
||||
type_text(&mut editor, "v2l");
|
||||
let text = editor.lines().to_vec();
|
||||
let selections = editor.selections();
|
||||
let cursor = editor.cursor();
|
||||
let revision = editor.active.text_revision;
|
||||
let history = (editor.active.undo.len(), editor.active.redo.len());
|
||||
let comparison = editor.diff().unwrap().comparison_id;
|
||||
editor.execute("word_wrap.toggle unexpected");
|
||||
assert!(editor.word_wrap());
|
||||
editor.handle(Input::Char('W'));
|
||||
assert!(!editor.word_wrap());
|
||||
assert_eq!(editor.lines(), text);
|
||||
assert_eq!(editor.selections(), selections);
|
||||
assert_eq!(editor.cursor(), cursor);
|
||||
assert_eq!(editor.active.text_revision, revision);
|
||||
assert_eq!(
|
||||
(editor.active.undo.len(), editor.active.redo.len()),
|
||||
history
|
||||
);
|
||||
assert_eq!(editor.diff().unwrap().comparison_id, comparison);
|
||||
assert_eq!(editor.diff().unwrap().phase, Phase::View);
|
||||
editor.handle(Input::Ctrl('p'));
|
||||
type_text(&mut editor, "word_wrap.toggle");
|
||||
editor.handle(Input::Enter);
|
||||
assert!(editor.word_wrap());
|
||||
editor.execute("diff.close");
|
||||
assert!(editor.word_wrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn diff_readonly_panes_dispatch_prompts_palette_and_picker_remaps_without_edits() {
|
||||
let directory = Directory::new();
|
||||
|
||||
Reference in New Issue
Block a user