Skip to content

Commit

Permalink
refactor: make CustomTypableCommands cheaper to clone
Browse files Browse the repository at this point in the history
  • Loading branch information
RoloEdits committed Dec 26, 2024
1 parent 4ba6445 commit de674c5
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 56 deletions.
36 changes: 13 additions & 23 deletions helix-term/src/commands/typed.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::fmt::Write;
use std::io::BufReader;
use std::ops::Deref;
use std::sync::Arc;

use crate::job::Job;

Expand Down Expand Up @@ -3060,9 +3059,7 @@ pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableComma

#[allow(clippy::unnecessary_unwrap, clippy::too_many_lines)]
pub(super) fn command_mode(cx: &mut Context) {
let arced = Arc::new(cx.editor.config().commands.clone());

let commands = arced.clone();
let commands = cx.editor.config().commands.clone();
let mut prompt = Prompt::new(
":".into(),
Some(':'),
Expand All @@ -3071,23 +3068,16 @@ pub(super) fn command_mode(cx: &mut Context) {
let shellwords = Shellwords::from(input.trim_start_matches('^'));
let command = shellwords.command();

let commands = commands.clone();
let names = commands.names();

// HACK: Cloning(to_string) because of lifetimes
let items = if input.starts_with('^') {
TYPABLE_COMMAND_LIST
.iter()
.map(|command| command.name.to_string())
.collect::<Vec<String>>()
} else {
TYPABLE_COMMAND_LIST
.iter()
.map(|command| command.name)
.chain(names)
.map(|name| name.to_string())
.collect::<Vec<String>>()
};
let items = TYPABLE_COMMAND_LIST
.iter()
.map(|command| command.name)
.chain(commands.names())
// HACK: `to_string` because of lifetimes:
//
// captured variable cannot escape `FnMut` closure body
// `FnMut` closures only have access to their captured variables while they are executing
// therefore, they cannot allow references to captured variables to escape
.map(|name| name.to_string());

if command.is_empty()
|| (shellwords.args().next().is_none() && !shellwords.ends_with_whitespace())
Expand Down Expand Up @@ -3298,11 +3288,11 @@ pub(super) fn command_mode(cx: &mut Context) {
},
);

let commands = arced.clone();
let commands = cx.editor.config().commands.clone();
prompt.doc_fn = Box::new(move |input: &str| {
let shellwords = Shellwords::from(input);

if let Some(command) = commands.clone().get(input) {
if let Some(command) = commands.get(input) {
return Some(command.prompt().into());
} else if let Some(typed::TypableCommand { doc, aliases, .. }) =
typed::TYPABLE_COMMAND_MAP.get(shellwords.command())
Expand Down
60 changes: 27 additions & 33 deletions helix-view/src/commands/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,41 @@
// TODO: Need to get access to a new table in the config: [commands].
// TODO: Could add an `aliases` to `CustomTypableCommand` and then add those as well?

use std::fmt::Write;
use std::{fmt::Write, sync::Arc};

use serde::{Deserialize, Serialize};

// TODO: Might need to manually implement Serialize and Deserialize
// -Will need to do so if want to use `Arc` to make cloning cheaper.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CustomTypeableCommands {
pub commands: Vec<CustomTypableCommand>,
pub commands: Arc<[CustomTypableCommand]>,
}

impl Default for CustomTypeableCommands {
fn default() -> Self {
Self {
commands: vec![
CustomTypableCommand {
name: String::from(":lg"),
desc: Some(String::from("runs lazygit in a floating pane")),
commands: vec![String::from(
":sh wezterm cli spawn --floating-pane lazygit",
)],
name: Arc::from(":lg"),
desc: Some(Arc::from("runs lazygit in a floating pane")),
commands: vec![Arc::from(":sh wezterm cli spawn --floating-pane lazygit")]
.into(),
accepts: None,
completer: None,
},
CustomTypableCommand {
name: String::from(":w"),
desc: Some(String::from(
"writes buffer forcefully and changes directory",
)),
name: Arc::from(":w"),
desc: Some(Arc::from("writes buffer forcefully and changes directory")),
commands: vec![
String::from(":write --force %{arg}"),
String::from(":cd %sh{ %{arg} | path dirname }"),
String::from(":cd %sh{ %{arg} | path dirname }"),
String::from(":cd %sh{ %{arg} | path dirname }"),
String::from(":cd %sh{ %{arg} | path dirname }"),
],
accepts: Some(String::from("<path>")),
completer: Some(String::from(":write")),
Arc::from(":write --force %{arg}"),
Arc::from(":cd %sh{ %{arg} | path dirname }"),
Arc::from(":cd %sh{ %{arg} | path dirname }"),
Arc::from(":cd %sh{ %{arg} | path dirname }"),
Arc::from(":cd %sh{ %{arg} | path dirname }"),
]
.into(),
accepts: Some(Arc::from("<path>")),
completer: Some(Arc::from(":write")),
},
],
]
.into(),
}
}
}
Expand All @@ -62,18 +57,17 @@ impl CustomTypeableCommands {
self.commands
.iter()
// ":wbc!" -> "wbc!"
.map(|command| command.name.as_str().trim_start_matches(':'))
.map(|command| command.name.as_ref())
}
}

// TODO: Arc<str> ?
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CustomTypableCommand {
pub name: String,
pub desc: Option<String>,
pub commands: Vec<String>,
pub accepts: Option<String>,
pub completer: Option<String>,
pub name: Arc<str>,
pub desc: Option<Arc<str>>,
pub commands: Arc<[Arc<str>]>,
pub accepts: Option<Arc<str>>,
pub completer: Option<Arc<str>>,
}

impl CustomTypableCommand {
Expand Down
1 change: 1 addition & 0 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ pub struct Config {
pub end_of_line_diagnostics: DiagnosticFilter,
// Set to override the default clipboard provider
pub clipboard_provider: ClipboardProvider,
#[serde(skip)]
/// Custom typeable commands
pub commands: CustomTypeableCommands,
}
Expand Down

0 comments on commit de674c5

Please sign in to comment.