#![allow(non_camel_case_types, non_snake_case, dead_code)]
use crate::ported::zsh_h::{zattr, HashNode};
#[allow(unused_imports)]
use crate::ported::zle::{
deltochar::*, textobjects::*, zle_hist::*, zle_main::*, zle_misc::*, zle_move::*,
zle_params::*, zle_refresh::*, zle_tricky::*, zle_utils::*, zle_vi::*, zle_word::*,
};
#[allow(unused_imports)]
#[allow(unused_imports)]
pub type ZLE_CHAR_T = char;
pub type ZLE_STRING_T = String;
pub type ZLE_INT_T = i32;
pub const ZLE_CHAR_SIZE: usize = 4;
pub const ZLEEOF: i32 = -1;
#[inline]
pub fn Th(index: i32) -> Option<crate::ported::zle::zle_thingy::Thingy> {
let i: usize = (index as i64).try_into().ok()?;
let name = T_THINGY_NAMES.get(i)?;
crate::ported::zle::zle_thingy::gethashnode2(name)
}
pub const T_THINGY_NAMES: &[&str] = &[
"accept-and-hold", "accept-line", "accept-line-and-down-history", "accept-search", "auto-suffix-remove", "auto-suffix-retain", "backward-char", "backward-delete-char", "beep", "clear-screen", "complete-word", "describe-key-briefly", "down-line-or-history", "execute-named-cmd", "exit", "forward-char", "history-incremental-search-backward", "history-incremental-search-forward", "list-choices", "menu-complete", "menu-expand-or-complete", "redisplay", "self-insert", "self-insert-unmeta", "send-break", "undefined-key", "undo", "up-line-or-history", "vi-cmd-mode", "yank", ];
#[inline]
pub fn invicmdmode(curkeymapname: &str) -> bool {
curkeymapname == "vicmd"
}
#[inline]
pub fn ZS_memcpy(dst: &mut [ZLE_CHAR_T], src: &[ZLE_CHAR_T], n: usize) {
dst[..n].copy_from_slice(&src[..n]);
}
#[inline]
pub fn ZS_memmove(dst: &mut [ZLE_CHAR_T], src: &[ZLE_CHAR_T], n: usize) {
let v: Vec<ZLE_CHAR_T> = src[..n].to_vec();
dst[..n].copy_from_slice(&v);
}
#[inline]
pub fn ZS_memset(dst: &mut [ZLE_CHAR_T], c: ZLE_CHAR_T, n: usize) {
for slot in dst.iter_mut().take(n) {
*slot = c;
}
}
#[inline]
pub fn ZS_memcmp(a: &[ZLE_CHAR_T], b: &[ZLE_CHAR_T], n: usize) -> std::cmp::Ordering {
a[..n].cmp(&b[..n])
}
#[inline]
pub fn ZS_strlen(s: &[ZLE_CHAR_T]) -> usize {
s.iter().position(|&c| c == '\0').unwrap_or(s.len())
}
#[inline]
pub fn ZS_strcpy(dst: &mut [ZLE_CHAR_T], src: &[ZLE_CHAR_T]) {
let n = ZS_strlen(src);
let limit = dst.len().min(n);
dst[..limit].copy_from_slice(&src[..limit]);
if limit < dst.len() {
dst[limit] = '\0';
}
}
#[inline]
pub fn ZS_strncpy(dst: &mut [ZLE_CHAR_T], src: &[ZLE_CHAR_T], n: usize) {
let s_len = ZS_strlen(src).min(n);
let limit = dst.len().min(n);
let copy = s_len.min(limit);
dst[..copy].copy_from_slice(&src[..copy]);
for slot in dst.iter_mut().take(limit).skip(copy) {
*slot = '\0';
}
}
#[inline]
pub fn ZS_strncmp(a: &[ZLE_CHAR_T], b: &[ZLE_CHAR_T], n: usize) -> std::cmp::Ordering {
let a_n = ZS_strlen(a).min(n);
let b_n = ZS_strlen(b).min(n);
let limit = a_n.min(b_n);
let cmp = a[..limit].cmp(&b[..limit]);
if cmp != std::cmp::Ordering::Equal {
return cmp;
}
a_n.cmp(&b_n)
}
#[inline]
pub fn ZS_strchr(s: &[ZLE_CHAR_T], c: ZLE_CHAR_T) -> Option<usize> {
s.iter().position(|&x| x == c)
}
#[inline]
pub fn ZS_memchr(s: &[ZLE_CHAR_T], c: ZLE_CHAR_T, n: usize) -> Option<usize> {
s[..n.min(s.len())].iter().position(|&x| x == c)
}
#[inline]
pub fn ZS_width(s: &[ZLE_CHAR_T]) -> usize {
ZS_strlen(s)
}
#[inline]
pub fn ZC_ialpha(c: ZLE_CHAR_T) -> bool {
c.is_alphabetic()
} #[inline]
pub fn ZC_ialnum(c: ZLE_CHAR_T) -> bool {
c.is_alphanumeric()
} #[inline]
pub fn ZC_iblank(c: ZLE_CHAR_T) -> bool {
crate::ported::utils::wcsiblank(c)
}
#[inline]
pub fn ZC_icntrl(c: ZLE_CHAR_T) -> bool {
c.is_control()
} #[inline]
pub fn ZC_idigit(c: ZLE_CHAR_T) -> bool {
c.is_ascii_digit()
} #[inline]
pub fn ZC_iident(c: ZLE_CHAR_T) -> bool {
c.is_alphanumeric() || c == '_'
} #[inline]
pub fn ZC_ilower(c: ZLE_CHAR_T) -> bool {
c.is_lowercase()
} #[inline]
pub fn ZC_inblank(c: ZLE_CHAR_T) -> bool {
c.is_whitespace()
} #[inline]
pub fn ZC_iupper(c: ZLE_CHAR_T) -> bool {
c.is_uppercase()
} #[inline]
pub fn ZC_iword(c: ZLE_CHAR_T) -> bool {
c.is_alphanumeric() || c == '_'
} #[inline]
pub fn ZC_ipunct(c: ZLE_CHAR_T) -> bool {
c.is_ascii_punctuation()
}
#[inline]
pub fn ZC_tolower(c: ZLE_CHAR_T) -> ZLE_CHAR_T {
c.to_lowercase().next().unwrap_or(c)
}
#[inline]
pub fn ZC_toupper(c: ZLE_CHAR_T) -> ZLE_CHAR_T {
c.to_uppercase().next().unwrap_or(c)
}
pub type WidgetPtr = Box<widget>;
pub type ThingyPtr = Box<thingy>;
pub type ZleIntFunc = fn(args: &[String]) -> i32;
pub struct widget {
pub flags: i32, pub first: Option<ThingyPtr>, pub u: WidgetImpl, }
impl Clone for widget {
fn clone(&self) -> Self {
widget {
flags: self.flags,
first: None, u: match &self.u {
WidgetImpl::Internal(f) => WidgetImpl::Internal(*f),
WidgetImpl::UserFunc(s) => WidgetImpl::UserFunc(s.clone()),
WidgetImpl::Comp { fn_, wid, func } => WidgetImpl::Comp {
fn_: *fn_,
wid: wid.clone(),
func: func.clone(),
},
},
}
}
}
impl std::fmt::Debug for widget {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("widget")
.field("flags", &self.flags)
.field(
"u",
&match &self.u {
WidgetImpl::Internal(_) => "Internal(<fn>)".to_string(),
WidgetImpl::UserFunc(s) => format!("UserFunc({})", s),
WidgetImpl::Comp { .. } => "Comp{..}".to_string(),
},
)
.finish()
}
}
impl widget {
pub fn internal(name: &str, func: ZleIntFunc, flags: i32) -> Self {
let _ = name;
widget {
flags: flags | WIDGET_INT,
first: None,
u: WidgetImpl::Internal(func),
}
}
pub fn builtin(name: &str) -> Self {
let f = super::zle_bindings::iwidget_lookup(name).unwrap_or(|_args: &[String]| 0i32);
widget {
flags: WIDGET_INT,
first: None,
u: WidgetImpl::Internal(f),
}
}
pub fn user_defined(name: &str, func_name: &str) -> Self {
let _ = name;
widget {
flags: 0i32,
first: None,
u: WidgetImpl::UserFunc(func_name.to_string()),
}
}
}
pub enum WidgetImpl {
Internal(ZleIntFunc), UserFunc(String), Comp {
fn_: ZleIntFunc,
wid: String,
func: String,
}, }
pub const WIDGET_INT: i32 = 1 << 0;
pub const WIDGET_NCOMP: i32 = 1 << 1;
pub const ZLE_MENUCMP: i32 = 1 << 2;
pub const ZLE_YANKAFTER: i32 = 1 << 3; pub const ZLE_YANKBEFORE: i32 = 1 << 4; pub const ZLE_YANK: i32 = ZLE_YANKAFTER | ZLE_YANKBEFORE; pub const ZLE_LINEMOVE: i32 = 1 << 5;
pub const ZLE_VIOPER: i32 = 1 << 6;
pub const ZLE_LASTCOL: i32 = 1 << 7;
pub const ZLE_KILL: i32 = 1 << 8; pub const ZLE_KEEPSUFFIX: i32 = 1 << 9;
pub const ZLE_NOTCOMMAND: i32 = 1 << 10;
pub const ZLE_ISCOMP: i32 = 1 << 11;
pub const WIDGET_INUSE: i32 = 1 << 12;
pub const WIDGET_FREE: i32 = 1 << 13;
pub const ZLE_NOLAST: i32 = 1 << 14;
pub struct thingy {
pub next: Option<HashNode>, pub nam: String, pub flags: i32, pub rc: i32, pub widget: Option<WidgetPtr>, pub samew: Option<ThingyPtr>, }
pub const TH_IMMORTAL: i32 = 1 << 1;
#[derive(Clone)]
pub struct modifier {
pub flags: i32, pub mult: i32, pub tmult: i32, pub vibuf: i32, pub base: i32, }
pub const MOD_MULT: i32 = 1 << 0;
pub const MOD_TMULT: i32 = 1 << 1;
pub const MOD_VIBUF: i32 = 1 << 2;
pub const MOD_VIAPP: i32 = 1 << 3;
pub const MOD_NEG: i32 = 1 << 4;
pub const MOD_NULL: i32 = 1 << 5;
pub const MOD_CHAR: i32 = 1 << 6;
pub const MOD_LINE: i32 = 1 << 7;
pub const MOD_PRI: i32 = 1 << 8;
pub const MOD_CLIP: i32 = 1 << 9;
pub const MOD_OSSEL: i32 = MOD_PRI | MOD_CLIP;
pub const CUT_FRONT: i32 = 1 << 0;
pub const CUT_REPLACE: i32 = 1 << 1;
pub const CUT_RAW: i32 = 1 << 2; pub const CUT_YANK: i32 = 1 << 3;
#[derive(Clone, Debug)]
pub struct change {
pub prev: Option<Box<change>>, pub next: Option<Box<change>>, pub flags: i32, pub hist: i32, pub off: i32, pub del: ZLE_STRING_T, pub dell: i32, pub ins: ZLE_STRING_T, pub insl: i32, pub old_cs: i32, pub new_cs: i32, pub changeno: i64, }
pub const CH_NEXT: i32 = 1 << 0;
pub const CH_PREV: i32 = 1 << 1;
pub struct vichange {
pub mod_: modifier, pub buf: Vec<u8>, pub bufsz: i32, pub bufptr: i32, }
pub type KeyScanFunc = fn(seq: &str, t: &thingy, ext: &str, data: usize);
pub const NO_INSERT_CHAR: i32 = 256;
pub fn removesuffix() -> i32 {
crate::ported::zle::zle_misc::iremovesuffix(NO_INSERT_CHAR, 0) }
pub struct cutbuffer {
pub buf: ZLE_STRING_T, pub len: usize, pub flags: u8, }
pub type CutbufferPtr = Box<cutbuffer>;
pub const CUTBUFFER_LINE: u8 = 1;
pub const KRINGCTDEF: i32 = 8;
pub const COMP_COMPLETE: i32 = 0; pub const COMP_LIST_COMPLETE: i32 = 1; pub const COMP_SPELL: i32 = 2; pub const COMP_EXPAND: i32 = 3; pub const COMP_EXPAND_COMPLETE: i32 = 4; pub const COMP_LIST_EXPAND: i32 = 5;
#[inline]
pub fn COMP_ISEXPAND(x: i32) -> bool {
x >= COMP_EXPAND
}
pub type BrinfoPtr = Box<brinfo>;
pub struct brinfo {
pub next: Option<BrinfoPtr>, pub prev: Option<BrinfoPtr>, pub str: String, pub pos: i32, pub qpos: i32, pub curpos: i32, }
pub const LISTMATCHESHOOK: i32 = 0; pub const COMPLETEHOOK: i32 = 1; pub const BEFORECOMPLETEHOOK: i32 = 2; pub const AFTERCOMPLETEHOOK: i32 = 3; pub const ACCEPTCOMPHOOK: i32 = 4; pub const INVALIDATELISTHOOK: i32 = 5;
pub type CompldatPtr = Box<compldat>;
pub struct compldat {
pub s: String, pub lst: i32, pub incmd: i32, }
pub fn listmatches() {
let h = crate::ported::module::gethookdef("list-matches");
let handled = if !h.is_null() {
crate::ported::module::runhookdef(h, std::ptr::null_mut()) != 0
} else {
false
};
if !handled {
let _ = crate::ported::zle::compresult::ilistmatches();
}
}
pub fn invalidatelist() {
let h = crate::ported::module::gethookdef("invalidate-list");
let handled = if !h.is_null() {
crate::ported::module::runhookdef(h, std::ptr::null_mut()) != 0
} else {
false
};
if !handled {
let _ = crate::ported::zle::compresult::invalidate_list();
}
}
pub const ZSL_COPY: i32 = 1;
pub const ZSL_TOEND: i32 = 2;
pub const SUFTYP_POSSTR: i32 = 0;
pub const SUFTYP_NEGSTR: i32 = 1;
pub const SUFTYP_POSRNG: i32 = 2;
pub const SUFTYP_NEGRNG: i32 = 3;
pub const SUFFLAGS_SPACE: i32 = 0x0001;
pub const ZRH_PREDISPLAY: i32 = 1;
pub struct region_highlight {
pub atr: zattr, pub atrmask: zattr, pub layer: i32, pub start: i32, pub start_meta: i32, pub end: i32, pub end_meta: i32, pub flags: i32, pub memo: Option<String>, }
pub const N_SPECIAL_HIGHLIGHTS: i32 = 4;
pub const CURC_EDIT: i32 = 0; pub const CURC_COMMAND: i32 = 1; pub const CURC_INSERT: i32 = 2; pub const CURC_OVERWRITE: i32 = 3; pub const CURC_PENDING: i32 = 4; pub const CURC_REGION_START: i32 = 5; pub const CURC_REGION_END: i32 = 6; pub const CURC_VISUAL: i32 = 7; pub const CURC_DEFAULT: i32 = 8;
pub const CURF_DEFAULT: i32 = 0; pub const CURF_UNDERLINE: i32 = 1; pub const CURF_BAR: i32 = 2; pub const CURF_BLOCK: i32 = 3; pub const CURF_SHAPE_MASK: i32 = 3; pub const CURF_BLINK: i32 = 1 << 2; pub const CURF_STEADY: i32 = 1 << 3; pub const CURF_HIDDEN: i32 = 1 << 4; pub const CURF_COLOR: i32 = 1 << 5; pub const CURF_COLOR_MASK: u32 = (0xffffff_u32 << 8) | (CURF_COLOR as u32); pub const CURF_RED_SHIFT: i32 = 24; pub const CURF_GREEN_SHIFT: i32 = 16; pub const CURF_BLUE_SHIFT: i32 = 8;
pub type REFRESH_CHAR = char;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct REFRESH_ELEMENT {
pub chr: REFRESH_CHAR, pub atr: zattr, }
pub type REFRESH_STRING = Vec<REFRESH_ELEMENT>;
pub const ZSH_INVALID_WCHAR_BASE: u32 = 0xe000;
#[inline]
pub fn ZSH_INVALID_WCHAR_TEST(x: u32) -> bool {
x >= ZSH_INVALID_WCHAR_BASE && x <= ZSH_INVALID_WCHAR_BASE + 255
}
#[inline]
pub fn ZSH_INVALID_WCHAR_TO_CHAR(x: u32) -> u8 {
(x - ZSH_INVALID_WCHAR_BASE) as u8
}
#[inline]
pub fn ZSH_INVALID_WCHAR_TO_INT(x: u32) -> i32 {
(x - ZSH_INVALID_WCHAR_BASE) as i32
}
#[inline]
pub fn ZSH_CHAR_TO_INVALID_WCHAR(x: u8) -> u32 {
(x as u32) + ZSH_INVALID_WCHAR_BASE
}
#[inline]
pub fn METACHECK() { }
#[inline]
pub fn UNMETACHECK() { }
pub type WatchFdPtr = Box<watch_fd>;
pub struct watch_fd {
pub func: String, pub fd: i32, pub widget: i32, }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn zs_strlen_stops_at_nul() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert_eq!(ZS_strlen(&['a', 'b', 'c']), 3);
assert_eq!(ZS_strlen(&['a', '\0', 'c']), 1);
assert_eq!(ZS_strlen(&[]), 0);
}
#[test]
fn zs_memcpy_first_n_chars() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
let mut dst = ['x'; 5];
let src = ['a', 'b', 'c', 'd', 'e'];
ZS_memcpy(&mut dst, &src, 3);
assert_eq!(dst, ['a', 'b', 'c', 'x', 'x']);
}
#[test]
fn zs_memmove_handles_self_copy() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
let mut buf = ['a', 'b', 'c', 'd', 'e'];
let src: Vec<char> = buf[1..4].to_vec();
ZS_memmove(&mut buf, &src, 3);
assert_eq!(buf, ['b', 'c', 'd', 'd', 'e']);
}
#[test]
fn zs_memset_fills_n() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
let mut dst = ['x'; 5];
ZS_memset(&mut dst, 'z', 3);
assert_eq!(dst, ['z', 'z', 'z', 'x', 'x']);
}
#[test]
fn zs_memcmp_ordering() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert_eq!(
ZS_memcmp(&['a', 'b'], &['a', 'b'], 2),
std::cmp::Ordering::Equal
);
assert_eq!(
ZS_memcmp(&['a', 'b'], &['a', 'c'], 2),
std::cmp::Ordering::Less
);
}
#[test]
fn zs_strncmp_terminates_at_nul() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert_eq!(
ZS_strncmp(&['a', 'b'], &['a', 'b'], 2),
std::cmp::Ordering::Equal
);
assert_eq!(
ZS_strncmp(&['a', 'b'], &['a', 'c'], 2),
std::cmp::Ordering::Less
);
assert_eq!(
ZS_strncmp(&['a', '\0'], &['a'], 5),
std::cmp::Ordering::Equal
);
}
#[test]
fn zs_strchr_returns_first_index() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert_eq!(ZS_strchr(&['a', 'b', 'c'], 'b'), Some(1));
assert_eq!(ZS_strchr(&['a', 'b', 'c'], 'z'), None);
}
#[test]
fn zc_iblank_matches_wcsiblank_semantics() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert!(ZC_iblank(' '), "space is iblank");
assert!(ZC_iblank('\t'), "tab is iblank");
assert!(ZC_iblank('\r'), "CR is iblank per wcsiblank");
assert!(ZC_iblank('\x0c'), "FF is iblank per wcsiblank");
assert!(ZC_iblank('\x0b'), "VT is iblank per wcsiblank");
assert!(ZC_iblank('\u{00A0}'), "NBSP is iblank per wcsiblank");
assert!(ZC_iblank('\u{2028}'), "line-separator U+2028 is iblank");
assert!(!ZC_iblank('\n'), "newline is the sole iswspace exclusion");
assert!(!ZC_iblank('a'));
assert!(!ZC_iblank('0'));
assert!(!ZC_iblank('_'));
}
#[test]
fn zc_inblank_matches_iswspace_semantics() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert!(ZC_inblank('\n'), "newline IS iswspace");
assert!(ZC_inblank(' '));
assert!(ZC_inblank('\t'));
assert!(ZC_inblank('\r'), "CR is iswspace");
assert!(ZC_inblank('\x0c'), "FF is iswspace");
assert!(ZC_inblank('\x0b'), "VT is iswspace");
assert!(ZC_inblank('\u{00A0}'), "NBSP is iswspace");
assert!(!ZC_inblank('a'));
assert!(!ZC_inblank('0'));
}
#[test]
fn zc_iword_includes_underscore() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert!(ZC_iword('a'));
assert!(ZC_iword('1'));
assert!(ZC_iword('_'));
assert!(!ZC_iword('-'));
}
#[test]
fn zc_iident_matches_iword() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
for c in ['a', 'A', '0', '_'] {
assert_eq!(ZC_iident(c), ZC_iword(c));
}
}
#[test]
fn zc_tolower_toupper_round_trip() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert_eq!(ZC_tolower('A'), 'a');
assert_eq!(ZC_toupper('a'), 'A');
assert_eq!(ZC_tolower('1'), '1');
}
#[test]
fn invicmdmode_only_true_for_vicmd() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert!(invicmdmode("vicmd"));
assert!(!invicmdmode("main"));
assert!(!invicmdmode("emacs"));
assert!(!invicmdmode(""));
}
#[test]
fn th_out_of_range_returns_none() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert!(Th(99).is_none());
assert!(Th(-1).is_none());
}
#[test]
fn th_in_range_looks_up_thingytab() {
let _g = crate::test_util::global_state_lock();
let _g = zle_test_setup();
assert_eq!(T_THINGY_NAMES[10], "complete-word");
assert!(Th(10).is_none() || Th(10).is_some());
}
#[test]
fn zle_widget_flags_match_c_zle_h_canonical_values() {
let _g = crate::test_util::global_state_lock();
assert_eq!(ZLE_MENUCMP, 1 << 2, "c:207");
assert_eq!(ZLE_YANKAFTER, 1 << 3, "c:208");
assert_eq!(ZLE_YANKBEFORE, 1 << 4, "c:209");
assert_eq!(
ZLE_YANK,
ZLE_YANKAFTER | ZLE_YANKBEFORE,
"c:210 — composite"
);
assert_eq!(ZLE_LINEMOVE, 1 << 5, "c:211");
assert_eq!(ZLE_VIOPER, 1 << 6, "c:212");
assert_eq!(ZLE_LASTCOL, 1 << 7, "c:213");
assert_eq!(ZLE_KILL, 1 << 8, "c:214");
assert_eq!(ZLE_KEEPSUFFIX, 1 << 9, "c:215");
assert_eq!(ZLE_NOTCOMMAND, 1 << 10, "c:216");
assert_eq!(ZLE_ISCOMP, 1 << 11, "c:217");
assert_eq!(ZLE_NOLAST, 1 << 14, "c:220");
}
#[test]
fn zle_h_corpus_zle_char_size_is_four() {
assert_eq!(ZLE_CHAR_SIZE, 4);
}
#[test]
fn zle_h_corpus_zleeof_is_minus_one() {
assert_eq!(ZLEEOF, -1);
}
#[test]
fn zle_h_corpus_widget_flag_bits_disjoint() {
assert_eq!(WIDGET_INT & WIDGET_NCOMP, 0);
assert_eq!(WIDGET_INT & ZLE_MENUCMP, 0);
assert_eq!(WIDGET_NCOMP & ZLE_YANKAFTER, 0);
}
#[test]
fn zle_h_corpus_all_widget_flags_pairwise_distinct() {
let flags = [
WIDGET_INT,
WIDGET_NCOMP,
ZLE_MENUCMP,
ZLE_YANKAFTER,
ZLE_YANKBEFORE,
ZLE_LINEMOVE,
ZLE_VIOPER,
ZLE_LASTCOL,
ZLE_KILL,
ZLE_KEEPSUFFIX,
ZLE_NOTCOMMAND,
ZLE_ISCOMP,
WIDGET_INUSE,
WIDGET_FREE,
ZLE_NOLAST,
];
for (i, a) in flags.iter().enumerate() {
for b in &flags[i + 1..] {
assert_eq!(a & b, 0,
"flags {a:#x} and {b:#x} must be disjoint");
}
}
}
#[test]
fn zle_h_corpus_thingy_names_table_nonempty() {
assert!(!T_THINGY_NAMES.is_empty(),
"thingy names table must list canonical widget names");
}
#[test]
fn zle_h_corpus_th_immortal_value() {
assert_eq!(TH_IMMORTAL, 1 << 1);
}
}