From b045b33743cb29df458408d53e073fb52c8bf885 Mon Sep 17 00:00:00 2001 From: 0x2CA <2478557459@qq.com> Date: Mon, 30 Dec 2024 10:24:19 +0800 Subject: [PATCH] separator --- assets/keymaps/vim.json | 1 + crates/editor/src/actions.rs | 10 ++++++++-- crates/editor/src/editor.rs | 7 +++++-- crates/editor/src/editor_tests.rs | 22 +++++++++++----------- crates/vim/src/command.rs | 2 +- crates/vim/src/normal.rs | 21 +++++++++++++++++---- 6 files changed, 43 insertions(+), 20 deletions(-) diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index 417916db4d..b65df6b787 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -197,6 +197,7 @@ "d": ["vim::PushOperator", "Delete"], "shift-d": "vim::DeleteToEndOfLine", "shift-j": "vim::JoinLines", + "g shift-j": ["vim::JoinLines", { "separator": "" }], "y": ["vim::PushOperator", "Yank"], "shift-y": "vim::YankLine", "i": "vim::InsertBefore", diff --git a/crates/editor/src/actions.rs b/crates/editor/src/actions.rs index 721b71ddec..80250f46f1 100644 --- a/crates/editor/src/actions.rs +++ b/crates/editor/src/actions.rs @@ -174,6 +174,12 @@ pub enum UuidVersion { V7, } +#[derive(PartialEq, Clone, Deserialize, Default)] +pub struct JoinLines { + #[serde(default)] + pub separator: Option, +} + impl_actions!( editor, [ @@ -204,7 +210,8 @@ impl_actions!( ToggleCodeActions, ToggleComments, UnfoldAt, - FoldAtLevel + FoldAtLevel, + JoinLines, ] ); @@ -282,7 +289,6 @@ gpui::actions!( Indent, InsertUuidV4, InsertUuidV7, - JoinLines, KillRingCut, KillRingYank, LineDown, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 02f01dbaec..6d083ae55b 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -5842,7 +5842,7 @@ impl Editor { }); } - pub fn join_lines(&mut self, _: &JoinLines, cx: &mut ViewContext) { + pub fn join_lines(&mut self, options: &JoinLines, cx: &mut ViewContext) { if self.read_only(cx) { return; } @@ -5885,7 +5885,10 @@ impl Editor { let start_of_next_line = Point::new(next_line_row.0, indent.len); let replace = if snapshot.line_len(next_line_row) > indent.len { - " " + match options.separator.as_deref() { + Some(replace_str) => replace_str, + None => " ", + } } else { "" }; diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index cc7d612bbf..dd33df9b80 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -3173,7 +3173,7 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) { ); // When on single line, replace newline at end by space - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); assert_eq!(buffer.read(cx).text(), "aaa bbb\nccc\nddd\n\n"); assert_eq!( editor.selections.ranges::(cx), @@ -3184,7 +3184,7 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) { editor.change_selections(None, cx, |s| { s.select_ranges([Point::new(0, 5)..Point::new(2, 2)]) }); - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); assert_eq!(buffer.read(cx).text(), "aaa bbb ccc ddd\n\n"); assert_eq!( editor.selections.ranges::(cx), @@ -3203,7 +3203,7 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) { editor.change_selections(None, cx, |s| { s.select_ranges([Point::new(2, 1)..Point::new(2, 2)]) }); - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); assert_eq!(buffer.read(cx).text(), "aaa bbb\nccc\nddd\n"); assert_eq!( editor.selections.ranges::(cx), @@ -3211,7 +3211,7 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) { ); // We can remove trailing newlines - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); assert_eq!(buffer.read(cx).text(), "aaa bbb\nccc\nddd"); assert_eq!( editor.selections.ranges::(cx), @@ -3219,7 +3219,7 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) { ); // We don't blow up on the last line - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); assert_eq!(buffer.read(cx).text(), "aaa bbb\nccc\nddd"); assert_eq!( editor.selections.ranges::(cx), @@ -3243,15 +3243,15 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) { editor.change_selections(None, cx, |s| { s.select_ranges([Point::new(0, 1)..Point::new(0, 1)]) }); - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); assert_eq!(buffer.read(cx).text(), "aaa bbb c\n \n\td"); // We don't insert a space for a line containing only spaces - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); assert_eq!(buffer.read(cx).text(), "aaa bbb c\n\td"); // We ignore any leading tabs - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); assert_eq!(buffer.read(cx).text(), "aaa bbb c d"); editor @@ -3275,7 +3275,7 @@ fn test_join_lines_with_multi_selection(cx: &mut TestAppContext) { ]) }); - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); assert_eq!(buffer.read(cx).text(), "aaa bbb ccc\nddd\n"); assert_eq!( @@ -3321,7 +3321,7 @@ async fn test_join_lines_with_git_diff_base( // Join lines cx.update_editor(|editor, cx| { - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); }); executor.run_until_parked(); @@ -3335,7 +3335,7 @@ async fn test_join_lines_with_git_diff_base( ); // Join again cx.update_editor(|editor, cx| { - editor.join_lines(&JoinLines, cx); + editor.join_lines(&JoinLines::default(), cx); }); executor.run_until_parked(); diff --git a/crates/vim/src/command.rs b/crates/vim/src/command.rs index 660a2a161f..6b9977f3cf 100644 --- a/crates/vim/src/command.rs +++ b/crates/vim/src/command.rs @@ -665,7 +665,7 @@ fn generate_commands(_: &AppContext) -> Vec { VimCommand::new(("cN", "ext"), editor::actions::GoToPrevDiagnostic).range(wrap_count), VimCommand::new(("lp", "revious"), editor::actions::GoToPrevDiagnostic).range(wrap_count), VimCommand::new(("lN", "ext"), editor::actions::GoToPrevDiagnostic).range(wrap_count), - VimCommand::new(("j", "oin"), JoinLines).range(select_range), + VimCommand::new(("j", "oin"), JoinLines::default()).range(select_range), VimCommand::new(("fo", "ld"), editor::actions::FoldSelectedRanges).range(act_on_range), VimCommand::new(("foldo", "pen"), editor::actions::UnfoldLines) .bang(editor::actions::UnfoldRecursive) diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index bde3c12027..5347cb051d 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -22,6 +22,7 @@ use crate::{ surrounds::SurroundsType, Vim, }; +use ::serde::Deserialize; use case::CaseTarget; use collections::BTreeSet; use editor::scroll::Autoscroll; @@ -29,11 +30,19 @@ use editor::Anchor; use editor::Bias; use editor::Editor; use editor::{display_map::ToDisplayPoint, movement}; -use gpui::{actions, ViewContext}; +use gpui::{actions, impl_actions, ViewContext}; use language::{Point, SelectionGoal}; use log::error; use multi_buffer::MultiBufferRow; +#[derive(PartialEq, Clone, Deserialize, Default)] +pub struct JoinLines { + #[serde(default)] + pub separator: Option, +} + +impl_actions!(vim, [JoinLines]); + actions!( vim, [ @@ -53,7 +62,6 @@ actions!( ChangeCase, ConvertToUpperCase, ConvertToLowerCase, - JoinLines, ToggleComments, Undo, Redo, @@ -107,7 +115,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut ViewContext) { cx, ); }); - Vim::action(editor, cx, |vim, _: &JoinLines, cx| { + Vim::action(editor, cx, |vim, options: &JoinLines, cx| { vim.record_current_action(cx); let mut times = Vim::take_count(cx).unwrap_or(1); if vim.mode.is_visual() { @@ -120,7 +128,12 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut ViewContext) { vim.update_editor(cx, |_, editor, cx| { editor.transact(cx, |editor, cx| { for _ in 0..times { - editor.join_lines(&Default::default(), cx) + editor.join_lines( + &editor::actions::JoinLines { + separator: options.separator.clone(), + }, + cx, + ) } }) });