@@ -227,6 +227,8 @@ impl Command {
227227 select_mode, "Enter selection extend mode",
228228 exit_select_mode, "Exit selection mode",
229229 goto_definition, "Goto definition",
230+ add_newline_above, "Add newline above",
231+ add_newline_below, "Add newline below",
230232 goto_type_definition, "Goto type definition",
231233 goto_implementation, "Goto implementation",
232234 goto_file_start, "Goto file start/line",
@@ -4473,3 +4475,37 @@ fn suspend(_cx: &mut Context) {
44734475 #[cfg(not(windows))]
44744476 signal_hook::low_level::raise(signal_hook::consts::signal::SIGTSTP).unwrap();
44754477}
4478+
4479+fn add_newline_above(cx: &mut Context) {
4480+ add_newline_impl(cx, Open::Above);
4481+}
4482+
4483+fn add_newline_below(cx: &mut Context) {
4484+ add_newline_impl(cx, Open::Below)
4485+}
4486+
4487+fn add_newline_impl(cx: &mut Context, open: Open) {
4488+ let count = cx.count();
4489+ let (view, doc) = current!(cx.editor);
4490+ let selection = doc.selection(view.id);
4491+ let text = doc.text();
4492+ let slice = text.slice(..);
4493+
4494+ let changes = selection.into_iter().map(|range| {
4495+ let (start, end) = range.line_range(slice);
4496+ let line = match open {
4497+ Open::Above => start,
4498+ Open::Below => end + 1,
4499+ };
4500+ let pos = text.line_to_char(line);
4501+ (
4502+ pos,
4503+ pos,
4504+ Some(doc.line_ending.as_str().repeat(count).into()),
4505+ )
4506+ });
4507+
4508+ let transaction = Transaction::change(text, changes);
4509+ doc.apply(&transaction, view.id);
4510+ doc.append_changes_to_history(view.id);
4511+}