diff --git a/CMakeLists.txt b/CMakeLists.txt index 62d04605f..dcf7edb40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,7 +117,7 @@ set(FISH_SRCS src/exec.cpp src/expand.cpp src/fallback.cpp src/fish_indent_common.cpp src/fish_version.cpp src/flog.cpp src/function.cpp src/highlight.cpp src/history.cpp src/history_file.cpp src/input.cpp src/input_common.cpp - src/io.cpp src/kill.cpp + src/io.cpp src/null_terminated_array.cpp src/operation_context.cpp src/output.cpp src/pager.cpp src/parse_execution.cpp src/parse_util.cpp src/parser.cpp src/parser_keywords.cpp src/path.cpp src/postfork.cpp diff --git a/fish-rust/src/kill.rs b/fish-rust/src/kill.rs index 1f3d218f2..94e69ed6d 100644 --- a/fish-rust/src/kill.rs +++ b/fish-rust/src/kill.rs @@ -3,14 +3,15 @@ //! Works like the killring in emacs and readline. The killring is cut and paste with a memory of //! previous cuts. -use cxx::CxxWString; +use cxx::{CxxWString, UniquePtr}; +use once_cell::sync::Lazy; use std::collections::VecDeque; use std::pin::Pin; use std::sync::Mutex; use crate::ffi::wcstring_list_ffi_t; use crate::wchar::prelude::*; -use crate::wchar_ffi::WCharFromFFI; +use crate::wchar_ffi::{WCharFromFFI, WCharToFFI}; #[cxx::bridge] mod kill_ffi { @@ -25,16 +26,15 @@ mod kill_ffi { #[cxx_name = "kill_replace"] fn kill_replace_ffi(old_entry: &CxxWString, new_entry: &CxxWString); #[cxx_name = "kill_yank_rotate"] - fn kill_yank_rotate_ffi(mut out_front: Pin<&mut CxxWString>); + fn kill_yank_rotate_ffi() -> UniquePtr; #[cxx_name = "kill_yank"] - fn kill_yank_ffi(mut out_front: Pin<&mut CxxWString>); + fn kill_yank_ffi() -> UniquePtr; #[cxx_name = "kill_entries"] fn kill_entries_ffi(mut out: Pin<&mut wcstring_list_ffi_t>); } } -static KILL_LIST: once_cell::sync::Lazy>> = - once_cell::sync::Lazy::new(|| Mutex::new(VecDeque::new())); +static KILL_LIST: Lazy>> = Lazy::new(|| Mutex::new(VecDeque::new())); fn kill_add_ffi(new_entry: &CxxWString) { kill_add(new_entry.from_ffi()); @@ -62,11 +62,8 @@ pub fn kill_replace(old_entry: WString, new_entry: WString) { } } -fn kill_yank_rotate_ffi(mut out_front: Pin<&mut CxxWString>) { - out_front.as_mut().clear(); - out_front - .as_mut() - .push_chars(kill_yank_rotate().as_char_slice()); +fn kill_yank_rotate_ffi() -> UniquePtr { + kill_yank_rotate().to_ffi() } /// Rotate the killring. @@ -76,9 +73,8 @@ pub fn kill_yank_rotate() -> WString { kill_list.front().cloned().unwrap_or_default() } -fn kill_yank_ffi(mut out_front: Pin<&mut CxxWString>) { - out_front.as_mut().clear(); - out_front.as_mut().push_chars(kill_yank().as_char_slice()); +fn kill_yank_ffi() -> UniquePtr { + kill_yank().to_ffi() } /// Paste from the killring. @@ -97,3 +93,27 @@ fn kill_entries_ffi(mut out_entries: Pin<&mut wcstring_list_ffi_t>) { pub fn kill_entries() -> Vec { KILL_LIST.lock().unwrap().iter().cloned().collect() } + +#[cfg(test)] +fn test_killring() { + assert!(kill_entries().is_empty()); + + kill_add(WString::from_str("a")); + kill_add(WString::from_str("b")); + kill_add(WString::from_str("c")); + + assert!((kill_entries() == [L!("c"), L!("b"), L!("a")])); + + assert!(kill_yank_rotate() == L!("b")); + assert!((kill_entries() == [L!("b"), L!("a"), L!("c")])); + + assert!(kill_yank_rotate() == L!("a")); + assert!((kill_entries() == [L!("a"), L!("c"), L!("b")])); + + kill_add(WString::from_str("d")); + + assert!((kill_entries() == [L!("d"), L!("a"), L!("c"), L!("b")])); + + assert!(kill_yank_rotate() == L!("a")); + assert!((kill_entries() == [L!("a"), L!("c"), L!("b"), L!("d")])); +} diff --git a/src/env.cpp b/src/env.cpp index 1647ac412..3d70788b8 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -29,7 +29,6 @@ #include "global_safety.h" #include "history.h" #include "input.h" -#include "kill.h" #include "null_terminated_array.h" #include "path.h" #include "proc.h" diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index c7287a11b..6ff916c2f 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -77,7 +77,7 @@ #include "input_common.h" #include "io.h" #include "iothread.h" -#include "kill.h" +#include "kill.rs.h" #include "lru.h" #include "maybe.h" #include "null_terminated_array.h" @@ -5482,31 +5482,6 @@ static void test_fd_event_signaller() { do_test(!sema.try_consume()); } -static void test_killring() { - say(L"Testing killring"); - - do_test(kill_entries().empty()); - - kill_add(L"a"); - kill_add(L"b"); - kill_add(L"c"); - - do_test((kill_entries() == std::vector{L"c", L"b", L"a"})); - - do_test(kill_yank_rotate() == L"b"); - do_test((kill_entries() == std::vector{L"b", L"a", L"c"})); - - do_test(kill_yank_rotate() == L"a"); - do_test((kill_entries() == std::vector{L"a", L"c", L"b"})); - - kill_add(L"d"); - - do_test((kill_entries() == std::vector{L"d", L"a", L"c", L"b"})); - - do_test(kill_yank_rotate() == L"a"); - do_test((kill_entries() == std::vector{L"a", L"c", L"b", L"d"})); -} - void test_wgetopt() { // Regression test for a crash. const wchar_t *const short_options = L"-a"; @@ -5651,7 +5626,6 @@ static const test_t s_tests[]{ {TEST_GROUP("topics"), test_topic_monitor_torture}, {TEST_GROUP("pipes"), test_pipes}, {TEST_GROUP("fd_event"), test_fd_event_signaller}, - {TEST_GROUP("killring"), test_killring}, {TEST_GROUP("wgetopt"), test_wgetopt}, {TEST_GROUP("rust_smoke"), test_rust_smoke}, {TEST_GROUP("rust_ffi"), test_rust_ffi}, diff --git a/src/kill.cpp b/src/kill.cpp deleted file mode 100644 index e86a88286..000000000 --- a/src/kill.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "config.h" // IWYU pragma: keep - -#include "kill.h" - -wcstring kill_yank_rotate() { - wcstring front; - kill_yank_rotate(front); - return front; -} - -wcstring kill_yank() { - wcstring front; - kill_yank(front); - return front; -} - -std::vector kill_entries() { - wcstring_list_ffi_t entries; - kill_entries(entries); - return std::move(entries.vals); -} diff --git a/src/kill.h b/src/kill.h deleted file mode 100644 index 1b074c688..000000000 --- a/src/kill.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef FISH_KILL_H -#define FISH_KILL_H - -#include "common.h" -#include "kill.rs.h" - -/// Rotate the killring. -wcstring kill_yank_rotate(); - -/// Paste from the killring. -wcstring kill_yank(); - -/// Get copy of kill ring as vector of strings -std::vector kill_entries(); - -#endif diff --git a/src/reader.cpp b/src/reader.cpp index 963b2379a..a25a644b1 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -66,7 +66,7 @@ #include "input_common.h" #include "io.h" #include "iothread.h" -#include "kill.h" +#include "kill.rs.h" #include "operation_context.h" #include "output.h" #include "pager.h" @@ -3702,7 +3702,7 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat break; } case rl::yank: { - wcstring yank_str = kill_yank(); + wcstring yank_str = std::move(*kill_yank()); insert_string(active_edit_line(), yank_str); rls.yank_len = yank_str.size(); break; @@ -3710,7 +3710,7 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat case rl::yank_pop: { if (rls.yank_len) { editable_line_t *el = active_edit_line(); - wcstring yank_str = kill_yank_rotate(); + wcstring yank_str = std::move(*kill_yank_rotate()); size_t new_yank_len = yank_str.size(); replace_substring(el, el->position() - rls.yank_len, rls.yank_len, std::move(yank_str));