#[allow(unused_imports)]
use crate::ported::zle::zle_h::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_main::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_misc::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_hist::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_move::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_word::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_vi::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_utils::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_refresh::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_tricky::*;
#[allow(unused_imports)]
use crate::ported::zle::textobjects::*;
#[allow(unused_imports)]
use crate::ported::zle::deltochar::*;
pub fn get_buffer() -> String { crate::ported::zle::zle_main::ZLELINE.lock().unwrap().iter().collect()
}
pub fn set_buffer(s: &str) { *crate::ported::zle::zle_main::ZLELINE.lock().unwrap() = s.chars().collect();
crate::ported::zle::zle_main::ZLELL.store(crate::ported::zle::zle_main::ZLELINE.lock().unwrap().len(), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLECS.store(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst).min(crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst)), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
}
pub fn get_cursor() -> usize { crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)
}
pub fn set_cursor(pos: usize) { crate::ported::zle::zle_main::ZLECS.store(pos.min(crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst)), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
}
pub fn get_lbuffer() -> String { crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[..crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)].iter().collect()
}
pub fn set_lbuffer(s: &str) { let rbuf: String = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)..].iter().collect();
*crate::ported::zle::zle_main::ZLELINE.lock().unwrap() = s.chars().chain(rbuf.chars()).collect();
crate::ported::zle::zle_main::ZLELL.store(crate::ported::zle::zle_main::ZLELINE.lock().unwrap().len(), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLECS.store(s.chars().count(), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
}
pub fn get_rbuffer() -> String { crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)..].iter().collect()
}
pub fn set_rbuffer(s: &str) { let lbuf: String = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[..crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)].iter().collect();
*crate::ported::zle::zle_main::ZLELINE.lock().unwrap() = lbuf.chars().chain(s.chars()).collect();
crate::ported::zle::zle_main::ZLELL.store(crate::ported::zle::zle_main::ZLELINE.lock().unwrap().len(), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
}
pub fn get_cutbuffer() -> String { crate::ported::zle::zle_main::KILLRING.lock().unwrap()
.front()
.map(|v| v.iter().collect())
.unwrap_or_default()
}
pub fn set_cutbuffer(s: &str) { let chars: Vec<char> = s.chars().collect();
if crate::ported::zle::zle_main::KILLRING.lock().unwrap().is_empty() {
crate::ported::zle::zle_main::KILLRING.lock().unwrap().push_front(chars);
} else {
crate::ported::zle::zle_main::KILLRING.lock().unwrap()[0] = chars;
}
}
pub fn get_mark() -> usize { crate::ported::zle::zle_main::MARK.load(std::sync::atomic::Ordering::SeqCst)
}
pub fn set_mark(pos: usize) { crate::ported::zle::zle_main::MARK.store(pos.min(crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst)), std::sync::atomic::Ordering::SeqCst);
}
pub fn get_bufferlines() -> usize { crate::ported::zle::zle_main::ZLELINE.lock().unwrap().iter().filter(|&&c| c == '\n').count() + 1
}
pub fn get_pending() -> usize { 0 }
pub fn get_keymap() -> String { crate::ported::zle::zle_keymap::curkeymapname().clone()
}
pub fn get_numeric() -> Option<i32> { if crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags & super::zle_h::MOD_MULT != 0 {
Some(crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult)
} else {
None
}
}
pub fn is_insert_mode() -> bool {
(crate::ported::zle::zle_main::INSMODE.load(std::sync::atomic::Ordering::SeqCst) != 0)
}
pub fn is_region_active() -> bool {
crate::ported::zle::zle_main::MARK.load(std::sync::atomic::Ordering::SeqCst) != crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)
}
pub fn get_zle_state() -> String {
let mut state = String::new();
if (crate::ported::zle::zle_main::INSMODE.load(std::sync::atomic::Ordering::SeqCst) != 0) {
state.push_str("insert");
} else {
state.push_str("overwrite");
}
state.push(':');
state.push_str(&crate::ported::zle::zle_keymap::curkeymapname());
state
}
pub fn free_prepostdisplay() { use crate::ported::zle::zle_misc::{POSTDISPLAY, PREDISPLAY};
use std::sync::Mutex;
PREDISPLAY.get_or_init(|| Mutex::new(String::new())).lock().unwrap().clear();
POSTDISPLAY.get_or_init(|| Mutex::new(String::new())).lock().unwrap().clear();
}
pub fn get_context() -> &'static str { use crate::ported::zsh_h::{ZLCON_LINE_CONT, ZLCON_SELECT, ZLCON_VARED};
match crate::ported::zle::zle_main::ZLECONTEXT.load(std::sync::atomic::Ordering::SeqCst) {
x if x == ZLCON_LINE_CONT => "cont", x if x == ZLCON_SELECT => "select", x if x == ZLCON_VARED => "vared", _ => "line", }
}
pub fn get_histno() -> i64 { crate::ported::zle::zle_main::history().lock().unwrap().cursor as i64
}
pub fn get_isearchmatchactive() -> i64 { use std::sync::atomic::Ordering;
crate::ported::zle::zle_hist::ISEARCH_ACTIVE.load(Ordering::Relaxed) as i64 }
pub fn get_isearchmatchend() -> i64 { use std::sync::atomic::Ordering;
crate::ported::zle::zle_hist::ISEARCH_ENDPOS.load(Ordering::Relaxed) as i64 }
pub fn get_isearchmatchstart() -> i64 { use std::sync::atomic::Ordering;
crate::ported::zle::zle_hist::ISEARCH_STARTPOS.load(Ordering::Relaxed) as i64 }
pub fn get_keys() -> Vec<u8> { crate::ported::zle::zle_keymap::keybuf.lock().unwrap().clone()
}
pub fn get_keys_queued_count() -> i64 { crate::ported::zle::zle_main::KUNGETBUF.lock().unwrap().len() as i64
}
pub fn get_killring() -> Vec<String> { crate::ported::zle::zle_main::KILLRING.lock().unwrap().iter()
.map(|entry| entry.iter().collect::<String>())
.collect()
}
pub fn get_lasearch() -> String { use crate::ported::zle::zle_misc::PREVIOUS_ABORTED_SEARCH;
use std::sync::Mutex;
PREVIOUS_ABORTED_SEARCH.get_or_init(|| Mutex::new(String::new()))
.lock().unwrap().clone()
}
pub fn get_lsearch() -> String { use crate::ported::zle::zle_misc::PREVIOUS_SEARCH;
use std::sync::Mutex;
PREVIOUS_SEARCH.get_or_init(|| Mutex::new(String::new()))
.lock().unwrap().clone()
}
pub fn get_lwidget() -> String { crate::ported::zle::zle_main::LBINDK.lock().unwrap().as_ref().map(|t| t.nam.clone()).unwrap_or_default()
}
pub fn get_postdisplay() -> String { use crate::ported::zle::zle_misc::POSTDISPLAY;
use std::sync::Mutex;
POSTDISPLAY.get_or_init(|| Mutex::new(String::new()))
.lock().unwrap().clone()
}
pub fn get_prebuffer() -> String { String::new()
}
pub fn get_predisplay() -> String { use crate::ported::zle::zle_misc::PREDISPLAY;
use std::sync::Mutex;
PREDISPLAY.get_or_init(|| Mutex::new(String::new()))
.lock().unwrap().clone()
}
pub fn get_prepost(text: &str, len: usize) -> String { text.chars().take(len).collect()
}
pub fn get_recursive() -> i64 { crate::ported::zle::zle_main::ZLE_RECURSIVE.load(std::sync::atomic::Ordering::SeqCst) as i64 }
pub fn get_region_active() -> i64 { crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst) as i64 }
pub fn get_registers(name: &str) -> Option<String> { let bytes = name.as_bytes();
if bytes.len() != 1 {
return None;
}
let c = bytes[0];
let idx: i32 = if c.is_ascii_digit() {
(c - b'0') as i32 + 26
} else if c.is_ascii_lowercase() {
(c - b'a') as i32
} else {
return None; };
if (idx as usize) < crate::ported::zle::zle_main::vibuf().lock().unwrap().len() {
Some(crate::ported::zle::zle_main::vibuf().lock().unwrap()[idx as usize].iter().collect::<String>())
} else {
None
}
}
pub fn get_suffixactive() -> i64 { use std::sync::atomic::Ordering;
crate::ported::zle::zle_misc::SUFFIXLEN.load(Ordering::Relaxed) as i64 }
pub fn get_suffixend() -> i64 { crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) as i64 }
pub fn get_suffixstart() -> i64 { use std::sync::atomic::Ordering;
let suffixlen = crate::ported::zle::zle_misc::SUFFIXLEN.load(Ordering::Relaxed);
(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) as i64) - (suffixlen as i64) }
pub fn get_widget() -> String { crate::ported::zle::zle_main::BINDK.lock().unwrap().as_ref().map(|t| t.nam.clone()).unwrap_or_default()
}
pub fn get_widgetfunc() -> String { use crate::ported::zle::zle_h::WidgetImpl as WidgetFunc;
let bindk_guard = crate::ported::zle::zle_main::BINDK.lock().unwrap();
let Some(t) = bindk_guard.as_ref() else {
return String::new();
};
let Some(w) = t.widget.as_ref() else {
return String::new();
};
if (w.flags & WIDGET_INT) != 0 {
return ".internal".to_string();
}
match &w.u {
WidgetFunc::UserFunc(name) => name.clone(),
WidgetFunc::Internal(_) => ".internal".to_string(),
_ => ".internal".to_string(),
}
}
pub fn get_widgetstyle() -> String {
let bindk_guard = crate::ported::zle::zle_main::BINDK.lock().unwrap();
let Some(t) = bindk_guard.as_ref() else {
return String::new();
};
let Some(w) = t.widget.as_ref() else {
return String::new();
};
if (w.flags & WIDGET_INT) != 0 {
return ".internal".to_string();
}
String::new() }
pub fn get_yankactive() -> i64 { let last = crate::ported::zle::zle_main::LASTCMD.load(std::sync::atomic::Ordering::SeqCst) as i32;
let yank = ((last & ZLE_YANK) != 0) as i64;
let yankafter = ((last & ZLE_YANKAFTER) != 0) as i64;
yank + yankafter
}
pub fn get_yankend() -> i64 { crate::ported::zle::zle_main::YANKE.load(std::sync::atomic::Ordering::SeqCst) as i64
}
pub fn get_yankstart() -> i64 { crate::ported::zle::zle_main::YANKB.load(std::sync::atomic::Ordering::SeqCst) as i64
}
pub fn makezleparams(_ro: i32) { use crate::ported::zle::compcore::{ZLECS, ZLELINE, ZMULT};
let line = ZLELINE.get_or_init(|| std::sync::Mutex::new(String::new()))
.lock().map(|g| g.clone()).unwrap_or_default();
let cs = ZLECS.load(std::sync::atomic::Ordering::Relaxed) as usize;
let (lbuf, rbuf) = if cs <= line.len() {
(line[..cs].to_string(), line[cs..].to_string())
} else {
(line.clone(), String::new())
};
let _ = crate::ported::params::setsparam("BUFFER", &line); let _ = crate::ported::params::setsparam("LBUFFER", &lbuf); let _ = crate::ported::params::setsparam("RBUFFER", &rbuf); let _ = crate::ported::params::setiparam(
"CURSOR",
ZLECS.load(std::sync::atomic::Ordering::Relaxed) as i64,
); let _ = crate::ported::params::setiparam("NUMERIC", ZMULT.load(
std::sync::atomic::Ordering::Relaxed,
) as i64); let lines = line.chars().filter(|c| *c == '\n').count() as i64 + 1;
let _ = crate::ported::params::setiparam("BUFFERLINES", lines); }
pub fn scan_registers(_t: i32, _flags: i32) { }
pub fn set_histno(x: i64) { let idx = x.max(0) as usize;
if idx <= crate::ported::zle::zle_main::history().lock().unwrap().entries.len() {
crate::ported::zle::zle_main::history().lock().unwrap().cursor = idx;
}
}
pub fn set_killring(x: Option<&[String]>) { crate::ported::zle::zle_main::KILLRING.lock().unwrap().clear();
if let Some(arr) = x {
for entry in arr {
crate::ported::zle::zle_main::KILLRING.lock().unwrap().push_back(entry.chars().collect());
}
}
}
pub fn set_numeric(x: i64) { use crate::ported::zle::zle_h::{MOD_MULT, MOD_TMULT, MOD_VIBUF, MOD_VIAPP, MOD_NEG, MOD_NULL, MOD_CHAR, MOD_LINE, MOD_PRI, MOD_CLIP, MOD_OSSEL};
crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult = x as i32;
crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags = MOD_MULT;
}
pub fn set_postdisplay(x: Option<&str>) { use crate::ported::zle::zle_misc::POSTDISPLAY;
use std::sync::Mutex;
let g = POSTDISPLAY.get_or_init(|| Mutex::new(String::new()));
let mut buf = g.lock().unwrap();
buf.clear();
if let Some(s) = x {
buf.push_str(s);
}
}
pub fn set_predisplay(x: Option<&str>) { use crate::ported::zle::zle_misc::PREDISPLAY;
use std::sync::Mutex;
let g = PREDISPLAY.get_or_init(|| Mutex::new(String::new()));
let mut buf = g.lock().unwrap();
buf.clear();
if let Some(s) = x {
buf.push_str(s);
}
}
pub fn set_prepost(textvar: &mut String, lenvar: &mut usize, x: Option<&str>) { if *lenvar != 0 {
textvar.clear();
*lenvar = 0;
}
if let Some(s) = x {
textvar.push_str(s);
*lenvar = s.chars().count();
}
}
pub fn set_region_active( x: i64,
) {
crate::ported::zle::zle_main::REGION_ACTIVE.store(if x != 0 { 1 } else { 0 }, std::sync::atomic::Ordering::SeqCst);
}
pub fn set_register(name: char, value: &str) -> i32 { let idx: i32 = if ('0'..='9').contains(&name) {
name as i32 - b'0' as i32 + 26
} else if ('a'..='z').contains(&name) {
name as i32 - b'a' as i32
} else {
return 1;
};
if (idx as usize) < crate::ported::zle::zle_main::vibuf().lock().unwrap().len() {
crate::ported::zle::zle_main::vibuf().lock().unwrap()[idx as usize] = value.chars().collect();
}
0
}
pub fn set_registers( map: &std::collections::HashMap<String, String>) {
for (name, value) in map {
if let Some(ch) = name.chars().next() {
let _ = set_register(ch, value);
}
}
}
pub fn set_yankend(i: i64) { crate::ported::zle::zle_main::YANKE.store(i.max(0) as usize, std::sync::atomic::Ordering::SeqCst);
}
pub fn set_yankstart(i: i64) { crate::ported::zle::zle_main::YANKB.store(i.max(0) as usize, std::sync::atomic::Ordering::SeqCst);
}
pub fn unset_cutbuffer(exp: i32) { if exp != 0 {
crate::ported::zle::zle_main::KILLRING.lock().unwrap().pop_front();
}
}
pub fn unset_killring(exp: i32) { if exp != 0 {
set_killring(None);
}
}
pub fn unset_numeric(exp: i32) { use crate::ported::zle::zle_h::{MOD_MULT, MOD_TMULT, MOD_VIBUF, MOD_VIAPP, MOD_NEG, MOD_NULL, MOD_CHAR, MOD_LINE, MOD_PRI, MOD_CLIP, MOD_OSSEL};
if exp != 0 { crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags = 0; crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult = 1; }
}
pub fn unset_register(name: char, _exp: i32) { let _ = set_register(name, "");
}
pub fn unset_registers(exp: i32) { if exp != 0 {
for buf in crate::ported::zle::zle_main::vibuf().lock().unwrap().iter_mut() {
buf.clear();
}
}
}
pub fn zleunsetfn(pm: &mut crate::ported::zsh_h::param, exp: i32) { crate::ported::params::stdunsetfn(pm, exp); }
#[cfg(test)]
mod region_active_tests {
use super::*;
#[test]
fn get_region_active_reads_field() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
crate::ported::zle::zle_main::REGION_ACTIVE.store(0, std::sync::atomic::Ordering::SeqCst);
assert_eq!(get_region_active(), 0);
crate::ported::zle::zle_main::REGION_ACTIVE.store(1, std::sync::atomic::Ordering::SeqCst);
assert_eq!(get_region_active(), 1);
crate::ported::zle::zle_main::REGION_ACTIVE.store(2, std::sync::atomic::Ordering::SeqCst);
assert_eq!(get_region_active(), 2);
}
#[test]
fn set_region_active_double_bang_idiom() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
set_region_active(0);
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 0);
set_region_active(1);
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 1);
set_region_active(99);
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 1);
set_region_active(-1);
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 1);
set_region_active(0);
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 0);
}
}
#[cfg(test)]
mod trap_tests {
use crate::ported::zle::zle_main::{zleaftertrap, zlebeforetrap};
#[test]
fn zlebeforetrap_returns_zero() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
assert_eq!(zlebeforetrap(), 0);
}
#[test]
fn zleaftertrap_returns_zero() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
assert_eq!(zleaftertrap(), 0);
}
}
#[cfg(test)]
mod numeric_tests {
use super::*;
use crate::ported::zle::zle_h::{MOD_MULT, MOD_TMULT, MOD_VIBUF, MOD_VIAPP, MOD_NEG, MOD_NULL, MOD_CHAR, MOD_LINE, MOD_PRI, MOD_CLIP, MOD_OSSEL};
#[test]
fn set_numeric_sets_mult_and_replaces_flags() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags |= MOD_TMULT | MOD_NEG;
crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult = 99;
set_numeric(7);
assert_eq!(crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult, 7);
assert!(crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags & MOD_MULT != 0);
assert_eq!(crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags & MOD_TMULT, 0);
assert_eq!(crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags & MOD_NEG, 0);
}
#[test]
fn unset_numeric_resets_when_exp_nonzero() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags |= MOD_MULT;
crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult = 5;
unset_numeric(1);
assert_eq!(crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult, 1);
assert_eq!(crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags, 0);
}
#[test]
fn unset_numeric_noop_when_exp_zero() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags |= MOD_MULT;
crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult = 5;
unset_numeric(0);
assert_eq!(crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult, 5);
assert!(crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags & MOD_MULT != 0);
}
}
#[cfg(test)]
mod suffix_tests {
use super::*;
use crate::ported::zle::zle_misc::SUFFIXLEN;
use std::sync::atomic::Ordering;
#[test]
fn get_suffixactive_reads_suffixlen() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
SUFFIXLEN.store(7, Ordering::SeqCst);
assert_eq!(get_suffixactive(), 7);
SUFFIXLEN.store(0, Ordering::SeqCst);
assert_eq!(get_suffixactive(), 0);
}
#[test]
fn get_suffixend_reads_zlecs() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
crate::ported::zle::zle_main::ZLECS.store(11, std::sync::atomic::Ordering::SeqCst);
assert_eq!(get_suffixend(), 11);
}
#[test]
fn get_suffixstart_subtracts_suffixlen() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
crate::ported::zle::zle_main::ZLECS.store(20, std::sync::atomic::Ordering::SeqCst);
SUFFIXLEN.store(5, Ordering::SeqCst);
assert_eq!(get_suffixstart(), 15);
SUFFIXLEN.store(0, Ordering::SeqCst);
assert_eq!(get_suffixstart(), 20);
}
}
#[cfg(test)]
mod widget_tests {
use super::*;
use crate::ported::zle::zle_thingy::Thingy;
#[test]
fn get_widget_reads_bindk_nam() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
*crate::ported::zle::zle_main::BINDK.lock().unwrap() = Some(Thingy::new("self-insert"));
assert_eq!(get_widget(), "self-insert");
}
#[test]
fn get_widget_empty_when_no_bindk() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
assert_eq!(get_widget(), "");
}
#[test]
fn get_lwidget_reads_lbindk_nam() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
*crate::ported::zle::zle_main::LBINDK.lock().unwrap() = Some(Thingy::new("forward-char"));
assert_eq!(get_lwidget(), "forward-char");
}
#[test]
fn get_lwidget_empty_when_no_lbindk() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
assert_eq!(get_lwidget(), "");
}
#[test]
fn get_recursive_reads_zle_recursive_field() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::zle_reset();
crate::ported::zle::zle_main::ZLE_RECURSIVE.store(0, std::sync::atomic::Ordering::SeqCst);
assert_eq!(get_recursive(), 0);
crate::ported::zle::zle_main::ZLE_RECURSIVE.store(5, std::sync::atomic::Ordering::SeqCst);
assert_eq!(get_recursive(), 5);
}
}
#[cfg(test)]
mod isearch_tests {
use super::*;
use crate::ported::zle::zle_hist::{ISEARCH_ACTIVE, ISEARCH_ENDPOS, ISEARCH_STARTPOS};
use std::sync::atomic::Ordering;
#[test]
fn get_isearchmatchactive_reads_global() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
ISEARCH_ACTIVE.store(0, Ordering::SeqCst);
assert_eq!(get_isearchmatchactive(), 0);
ISEARCH_ACTIVE.store(1, Ordering::SeqCst);
assert_eq!(get_isearchmatchactive(), 1);
ISEARCH_ACTIVE.store(0, Ordering::SeqCst);
}
#[test]
fn get_isearchmatchstart_reads_global() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
ISEARCH_STARTPOS.store(7, Ordering::SeqCst);
assert_eq!(get_isearchmatchstart(), 7);
ISEARCH_STARTPOS.store(0, Ordering::SeqCst);
}
#[test]
fn get_isearchmatchend_reads_global() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
ISEARCH_ENDPOS.store(13, Ordering::SeqCst);
assert_eq!(get_isearchmatchend(), 13);
ISEARCH_ENDPOS.store(0, Ordering::SeqCst);
}
}
#[cfg(test)]
mod batch_getters_tests {
use super::*;
#[test]
fn get_histno_reads_history_cursor() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::history().lock().unwrap().cursor = 7;
assert_eq!(get_histno(), 7);
}
#[test]
fn get_keys_returns_keybuf_clone() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
*crate::ported::zle::zle_keymap::keybuf.lock().unwrap() = vec![0x1b, b'a'];
assert_eq!(get_keys(), vec![0x1b, b'a']);
}
#[test]
fn get_keys_queued_count_returns_unget_len() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::KUNGETBUF.lock().unwrap().push_back(b'a');
crate::ported::zle::zle_main::KUNGETBUF.lock().unwrap().push_back(b'b');
crate::ported::zle::zle_main::KUNGETBUF.lock().unwrap().push_back(b'c');
assert_eq!(get_keys_queued_count(), 3);
}
#[test]
fn get_yankstart_yankend_read_fields() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::YANKB.store(3, std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::YANKE.store(8, std::sync::atomic::Ordering::SeqCst);
assert_eq!(get_yankstart(), 3);
assert_eq!(get_yankend(), 8);
}
#[test]
fn set_yankstart_yankend_write_fields() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
set_yankstart(5);
set_yankend(11);
assert_eq!(crate::ported::zle::zle_main::YANKB.load(std::sync::atomic::Ordering::SeqCst), 5);
assert_eq!(crate::ported::zle::zle_main::YANKE.load(std::sync::atomic::Ordering::SeqCst), 11);
}
}
#[cfg(test)]
mod keybuf_tests {
use crate::ported::zle::zle_keymap::{addkeybuf, freekeynode, KeyBinding};
#[test]
fn addkeybuf_plain_byte() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_keymap::keybuf.lock().unwrap().clear();
addkeybuf(b'a' as i32);
assert_eq!(*crate::ported::zle::zle_keymap::keybuf.lock().unwrap(), vec![b'a']);
}
#[test]
fn addkeybuf_meta_quoted() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_keymap::keybuf.lock().unwrap().clear();
addkeybuf(0xa0);
assert_eq!(*crate::ported::zle::zle_keymap::keybuf.lock().unwrap(), vec![0x83, 0x80]);
}
#[test]
fn freekeynode_consumes_binding() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let kb = KeyBinding {
bind: None,
str: Some("send-string".to_string()),
prefixct: 0,
};
freekeynode(kb);
}
}
#[cfg(test)]
mod display_tests {
use super::*;
use crate::ported::zsh_h::{ZLCON_LINE_START, ZLCON_LINE_CONT, ZLCON_SELECT, ZLCON_VARED};
#[test]
fn get_set_predisplay_round_trip() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
set_predisplay(Some("[hint] "));
assert_eq!(get_predisplay(), "[hint] ");
set_predisplay(None);
assert_eq!(get_predisplay(), "");
}
#[test]
fn get_set_postdisplay_round_trip() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
set_postdisplay(Some("trailer"));
assert_eq!(get_postdisplay(), "trailer");
set_postdisplay(None);
assert_eq!(get_postdisplay(), "");
}
#[test]
fn free_prepostdisplay_clears_both() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
set_predisplay(Some("a"));
set_postdisplay(Some("b"));
free_prepostdisplay();
assert_eq!(get_predisplay(), "");
assert_eq!(get_postdisplay(), "");
}
#[test]
fn get_context_branches() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
use crate::ported::zle::zle_main::ZLECONTEXT;
use std::sync::atomic::Ordering;
crate::ported::zle::zle_main::zle_reset();
ZLECONTEXT.store(ZLCON_LINE_START, Ordering::SeqCst); assert_eq!(get_context(), "line");
ZLECONTEXT.store(ZLCON_LINE_CONT, Ordering::SeqCst); assert_eq!(get_context(), "cont");
ZLECONTEXT.store(ZLCON_SELECT, Ordering::SeqCst); assert_eq!(get_context(), "select");
ZLECONTEXT.store(ZLCON_VARED, Ordering::SeqCst); assert_eq!(get_context(), "vared");
}
#[test]
fn get_lasearch_lsearch_default_empty() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
use crate::ported::zle::zle_misc::{PREVIOUS_ABORTED_SEARCH, PREVIOUS_SEARCH};
use std::sync::Mutex;
PREVIOUS_ABORTED_SEARCH.get_or_init(|| Mutex::new(String::new())).lock().unwrap().clear();
PREVIOUS_SEARCH.get_or_init(|| Mutex::new(String::new())).lock().unwrap().clear();
assert_eq!(get_lasearch(), "");
assert_eq!(get_lsearch(), "");
}
#[test]
fn get_prepost_truncates_to_len() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
assert_eq!(get_prepost("abcdef", 3), "abc");
assert_eq!(get_prepost("xyz", 99), "xyz"); }
#[test]
fn set_prepost_writes_and_clears() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut text = String::new();
let mut len = 0;
set_prepost(&mut text, &mut len, Some("hello"));
assert_eq!(text, "hello");
assert_eq!(len, 5);
set_prepost(&mut text, &mut len, None);
assert_eq!(text, "");
assert_eq!(len, 0);
}
}
#[cfg(test)]
mod widget_killring_tests {
use super::*;
use crate::ported::zle::zle_h::{widget as Widget, WidgetImpl as WidgetFunc};
use crate::ported::zle::zle_thingy::Thingy;
use std::sync::Arc;
#[test]
fn set_get_register_round_trip() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
set_register('a', "hello");
let s: String = crate::ported::zle::zle_main::vibuf().lock().unwrap()[0].iter().collect();
assert_eq!(s, "hello");
assert_eq!(get_registers("a"), Some("hello".to_string()));
}
#[test]
fn set_register_digit_uses_offset_26() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
set_register('0', "zero");
let s: String = crate::ported::zle::zle_main::vibuf().lock().unwrap()[26].iter().collect();
assert_eq!(s, "zero");
assert_eq!(get_registers("0"), Some("zero".to_string()));
}
#[test]
fn set_register_invalid_returns_one() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
assert_eq!(set_register('!', "x"), 1);
}
#[test]
fn unset_register_clears_buffer() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
set_register('a', "hi");
unset_register('a', 1);
assert_eq!(get_registers("a"), Some(String::new()));
}
#[test]
fn set_get_killring_round_trip() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let entries = vec!["first".to_string(), "second".to_string()];
set_killring(Some(&entries));
let got = get_killring();
assert_eq!(got, vec!["first".to_string(), "second".to_string()]);
}
#[test]
fn unset_killring_clears_when_exp_nonzero() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let entries = vec!["x".to_string()];
set_killring(Some(&entries));
unset_killring(1);
assert!(get_killring().is_empty());
}
#[test]
fn set_histno_clamps_to_entries_len() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
crate::ported::zle::zle_main::history().lock().unwrap().entries.push(crate::ported::zle::zle_hist::HistEntry {
line: "ls".to_string(), num: 1, time: None,
});
crate::ported::zle::zle_main::history().lock().unwrap().entries.push(crate::ported::zle::zle_hist::HistEntry {
line: "cd".to_string(), num: 2, time: None,
});
set_histno(1);
assert_eq!(crate::ported::zle::zle_main::history().lock().unwrap().cursor, 1);
crate::ported::zle::zle_main::history().lock().unwrap().cursor = 7;
set_histno(99);
assert_eq!(crate::ported::zle::zle_main::history().lock().unwrap().cursor, 7);
}
}