Make sets_bind_mode in input an Option<WString>

Previously this used an empty string to mean a sentinel; use an option instead.

Fixes a TODO.
This commit is contained in:
ridiculousfish
2024-01-21 13:41:48 -08:00
parent b4b5cff3d8
commit 3ce6a5fdd1
3 changed files with 43 additions and 40 deletions

View File

@@ -33,7 +33,7 @@ struct Options {
preset: bool,
mode: c_int,
bind_mode: WString,
sets_bind_mode: WString,
sets_bind_mode: Option<WString>,
}
impl Options {
@@ -51,7 +51,7 @@ fn new() -> Options {
preset: false,
mode: BIND_INSERT,
bind_mode: DEFAULT_BIND_MODE.to_owned(),
sets_bind_mode: WString::new(),
sets_bind_mode: None,
}
}
}
@@ -82,8 +82,8 @@ fn list_one(
parser: &Parser,
streams: &mut IoStreams,
) -> bool {
let mut ecmds = Vec::new();
let mut sets_mode = WString::new();
let mut ecmds: &[_] = &[];
let mut sets_mode = None;
let mut out = WString::new();
if !self
.input_mappings
@@ -102,9 +102,12 @@ fn list_one(
out.push_str(" -M ");
out.push_utfstr(&escape(bind_mode));
}
if !sets_mode.is_empty() && sets_mode != bind_mode {
out.push_str(" -m ");
out.push_utfstr(&escape(&sets_mode));
if let Some(sets_mode) = sets_mode {
if sets_mode != bind_mode {
out.push_str(" -m ");
out.push_utfstr(&escape(sets_mode));
}
}
// Append the name.
@@ -122,7 +125,7 @@ fn list_one(
// Now show the list of commands.
for ecmd in ecmds {
out.push(' ');
out.push_utfstr(&escape(&ecmd));
out.push_utfstr(&escape(ecmd));
}
out.push('\n');
@@ -229,7 +232,7 @@ fn add(
seq: &wstr,
cmds: &[&wstr],
mode: WString,
sets_mode: WString,
sets_mode: Option<WString>,
terminfo: bool,
user: bool,
streams: &mut IoStreams,
@@ -461,15 +464,14 @@ fn parse_cmd_opts(
opts.bind_mode_given = true;
}
'm' => {
if !valid_var_name(w.woptarg.unwrap()) {
streams.err.append(wgettext_fmt!(
BUILTIN_ERR_BIND_MODE,
cmd,
w.woptarg.unwrap()
));
let new_mode = w.woptarg.unwrap();
if !valid_var_name(new_mode) {
streams
.err
.append(wgettext_fmt!(BUILTIN_ERR_BIND_MODE, cmd, new_mode));
return STATUS_INVALID_ARGS;
}
opts.sets_bind_mode = w.woptarg.unwrap().to_owned();
opts.sets_bind_mode = Some(new_mode.to_owned());
}
'p' => {
opts.have_preset = true;

View File

@@ -49,9 +49,8 @@ struct InputMapping {
specification_order: u32,
/// Mode in which this command should be evaluated.
mode: WString,
/// New mode that should be switched to after command evaluation.
/// TODO: should be an Option, instead of empty string to mean none.
sets_mode: WString,
/// New mode that should be switched to after command evaluation, or None to leave the mode unchanged.
sets_mode: Option<WString>,
}
impl InputMapping {
@@ -60,10 +59,14 @@ fn new(
seq: WString,
commands: Vec<WString>,
mode: WString,
sets_mode: WString,
sets_mode: Option<WString>,
) -> InputMapping {
static LAST_INPUT_MAP_SPEC_ORDER: AtomicU32 = AtomicU32::new(0);
let specification_order = 1 + LAST_INPUT_MAP_SPEC_ORDER.fetch_add(1, Ordering::Relaxed);
assert!(
sets_mode.is_none() || !mode.is_empty(),
"sets_mode set but mode is empty"
);
InputMapping {
seq,
commands,
@@ -284,7 +287,7 @@ pub fn add(
sequence: WString,
commands: Vec<WString>,
mode: WString,
sets_mode: WString,
sets_mode: Option<WString>,
user: bool,
) {
// Clear cached mappings.
@@ -316,7 +319,7 @@ pub fn add1(
sequence: WString,
command: WString,
mode: WString,
sets_mode: WString,
sets_mode: Option<WString>,
user: bool,
) {
self.add(sequence, vec![command], mode, sets_mode, user);
@@ -339,7 +342,7 @@ pub fn init_input() {
// Helper for adding.
let mut add = |seq: &str, cmd: &str| {
let mode = DEFAULT_BIND_MODE.to_owned();
let sets_mode = DEFAULT_BIND_MODE.to_owned();
let sets_mode = Some(DEFAULT_BIND_MODE.to_owned());
input_mapping.add1(seq.into(), cmd.into(), mode, sets_mode, false);
};
@@ -510,8 +513,8 @@ fn mapping_execute(
// !has_functions && !has_commands: only set bind mode
if !has_commands && !has_functions {
if !m.sets_mode.is_empty() {
input_set_bind_mode(&self.parser, &m.sets_mode);
if let Some(sets_mode) = m.sets_mode.as_ref() {
input_set_bind_mode(&self.parser, sets_mode);
}
return;
}
@@ -541,9 +544,9 @@ fn mapping_execute(
// one.
self.push_front(CharEvent::from_check_exit());
}
// Empty bind mode indicates to not reset the mode (#2871)
if !m.sets_mode.is_empty() {
input_set_bind_mode(&self.parser, &m.sets_mode);
// Missing bind mode indicates to not reset the mode (#2871)
if let Some(sets_mode) = m.sets_mode.as_ref() {
input_set_bind_mode(&self.parser, sets_mode);
}
}
@@ -1014,15 +1017,14 @@ pub fn erase(&mut self, sequence: &wstr, mode: &wstr, user: bool) -> bool {
/// Gets the command bound to the specified key sequence in the specified mode. Returns true if
/// it exists, false if not.
pub fn get(
&self,
pub fn get<'a>(
&'a self,
sequence: &wstr,
mode: &wstr,
out_cmds: &mut Vec<WString>,
out_cmds: &mut &'a [WString],
user: bool,
out_sets_mode: &mut WString,
out_sets_mode: &mut Option<&'a wstr>,
) -> bool {
let mut result = false;
let ml = if user {
&self.mapping_list
} else {
@@ -1030,13 +1032,12 @@ pub fn get(
};
for m in ml {
if m.seq == sequence && m.mode == mode {
*out_cmds = m.commands.clone();
*out_sets_mode = m.sets_mode.clone();
result = true;
break;
*out_cmds = &m.commands;
*out_sets_mode = m.sets_mode.as_deref();
return true;
}
}
result
false
}
/// \return a snapshot of the list of input mappings.

View File

@@ -26,14 +26,14 @@ fn test_input() {
prefix_binding,
WString::from_str("up-line"),
default_mode(),
default_mode(),
None,
true,
);
input_mapping.add1(
desired_binding.clone(),
WString::from_str("down-line"),
default_mode(),
default_mode(),
None,
true,
);
}