use std::sync::atomic::Ordering;
use super::zle_h::{MOD_MULT, MOD_TMULT, MOD_VIBUF, MOD_VIAPP, MOD_NEG, MOD_NULL, MOD_CHAR, MOD_LINE, MOD_PRI, MOD_CLIP, MOD_OSSEL};
use super::zle_misc::{TAILADD, VFINDCHAR, VFINDDIR};
#[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_params::*;
#[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 static VIRANGEFLAG: std::sync::atomic::AtomicI32 = std::sync::atomic::AtomicI32::new(0);
pub static WORDFLAG: std::sync::atomic::AtomicI32 = std::sync::atomic::AtomicI32::new(0);
pub static VILINERANGE: std::sync::atomic::AtomicI32 = std::sync::atomic::AtomicI32::new(0);
pub static VICHGFLAG: std::sync::atomic::AtomicI32 = std::sync::atomic::AtomicI32::new(0);
pub static VIINREPEAT: std::sync::atomic::AtomicI32 = std::sync::atomic::AtomicI32::new(0);
pub static VIINSBEGIN: std::sync::atomic::AtomicI32 = std::sync::atomic::AtomicI32::new(0);
pub fn vi_get_arg() -> i32 {
if crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags & MOD_MULT != 0 {
crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult
} else {
1
}
}
pub fn vi_find_char(forward: bool, skip: bool) {
let c = match getfullchar(true) {
Some(c) => c,
None => return,
};
VFINDCHAR.store(c as i32, Ordering::SeqCst);
VFINDDIR.store(if forward { 1 } else { -1 }, Ordering::SeqCst);
TAILADD.store(
match (forward, skip) {
(_, false) => 0,
(true, true) => -1,
(false, true) => 1,
},
Ordering::SeqCst,
);
let _ = vi_find_char_inner(false);
}
pub fn vi_find_char_inner(repeat: bool) -> i32 {
let target_raw = VFINDCHAR.load(Ordering::SeqCst);
let target = match char::from_u32(target_raw as u32) {
Some(c) if target_raw != 0 => c,
_ => return 1,
};
if VFINDDIR.load(Ordering::SeqCst) == 0 {
return 1;
}
let ocs = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
let mut n = vi_get_arg();
if n < 0 {
n = -n;
VFINDDIR.store(-VFINDDIR.load(Ordering::SeqCst), Ordering::SeqCst);
TAILADD.store(-TAILADD.load(Ordering::SeqCst), Ordering::SeqCst);
let saved_mult = crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult;
crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult = n;
let ret = vi_find_char_inner(repeat);
crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult = saved_mult;
VFINDDIR.store(-VFINDDIR.load(Ordering::SeqCst), Ordering::SeqCst);
TAILADD.store(-TAILADD.load(Ordering::SeqCst), Ordering::SeqCst);
return ret;
}
if repeat && TAILADD.load(Ordering::SeqCst) != 0 {
if VFINDDIR.load(Ordering::SeqCst) > 0 {
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst)
&& crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) + 1 < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst)
&& crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) + 1] == target
{
crate::ported::zle::zle_main::ZLECS.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
}
} else if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) > 0 && crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) - 1] == target {
crate::ported::zle::zle_main::ZLECS.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
}
}
let dir = VFINDDIR.load(Ordering::SeqCst);
for _ in 0..n {
let found = if dir > 0 {
let mut p = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) + 1;
let mut hit = None;
while p < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
let ch = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[p];
if ch == '\n' {
break;
}
if ch == target {
hit = Some(p);
break;
}
p += 1;
}
hit
} else {
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) == 0 {
None
} else {
let mut p = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) - 1;
let mut hit = None;
loop {
let ch = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[p];
if ch == '\n' {
break;
}
if ch == target {
hit = Some(p);
break;
}
if p == 0 {
break;
}
p -= 1;
}
hit
}
};
match found {
Some(p) => { crate::ported::zle::zle_main::ZLECS.store(p, std::sync::atomic::Ordering::SeqCst); }
None => {
crate::ported::zle::zle_main::ZLECS.store(ocs, std::sync::atomic::Ordering::SeqCst);
return 1;
}
}
}
let tail = TAILADD.load(Ordering::SeqCst);
if tail > 0 && crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::ZLECS.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
} else if tail < 0 && crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) > 0 {
crate::ported::zle::zle_main::ZLECS.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn vi_match_bracket() {
let c = if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)]
} else {
return;
};
let (target, forward) = match c {
'(' => (')', true),
')' => ('(', false),
'[' => (']', true),
']' => ('[', false),
'{' => ('}', true),
'}' => ('{', false),
'<' => ('>', true),
'>' => ('<', false),
_ => return,
};
let mut depth = 1;
let mut pos = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
if forward {
pos += 1;
while pos < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) && depth > 0 {
if crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[pos] == c {
depth += 1;
} else if crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[pos] == target {
depth -= 1;
}
if depth > 0 {
pos += 1;
}
}
} else {
if pos > 0 {
pos -= 1;
loop {
if crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[pos] == c {
depth += 1;
} else if crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[pos] == target {
depth -= 1;
}
if depth == 0 || pos == 0 {
break;
}
pos -= 1;
}
}
}
if depth == 0 {
crate::ported::zle::zle_main::ZLECS.store(pos, std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
}
}
pub fn vi_replace_mode() {
crate::ported::zle::zle_keymap::selectkeymap("viins", 1);
crate::ported::zle::zle_main::INSMODE.store(0, std::sync::atomic::Ordering::SeqCst); }
pub fn vi_swap_case() {
let count = vi_get_arg() as usize;
for _ in 0..count {
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
let c = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)];
crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)] = if c.is_uppercase() {
c.to_lowercase().next().unwrap_or(c)
} else if c.is_lowercase() {
c.to_uppercase().next().unwrap_or(c)
} else {
c
};
crate::ported::zle::zle_main::ZLECS.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
}
}
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) > 0 && crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) == crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::ZLECS.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
}
pub fn vi_undo() {
let _ = undo_widget();
}
pub fn vi_visual_mode() {
match crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst) {
1 => {
crate::ported::zle::zle_main::REGION_ACTIVE.store(0, std::sync::atomic::Ordering::SeqCst);
}
0 => {
crate::ported::zle::zle_main::MARK.store(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::REGION_ACTIVE.store(1, std::sync::atomic::Ordering::SeqCst);
}
2 => {
crate::ported::zle::zle_main::REGION_ACTIVE.store(1, std::sync::atomic::Ordering::SeqCst);
}
_ => {}
}
}
pub fn vi_visual_line_mode() {
match crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst) {
2 => {
crate::ported::zle::zle_main::REGION_ACTIVE.store(0, std::sync::atomic::Ordering::SeqCst);
}
0 => {
crate::ported::zle::zle_main::MARK.store(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::REGION_ACTIVE.store(2, std::sync::atomic::Ordering::SeqCst);
}
1 => {
crate::ported::zle::zle_main::REGION_ACTIVE.store(2, std::sync::atomic::Ordering::SeqCst);
}
_ => {}
}
}
pub fn vi_visual_block_mode() {
if crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst) == 0 {
crate::ported::zle::zle_main::MARK.store(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::REGION_ACTIVE.store(1, std::sync::atomic::Ordering::SeqCst);
}
pub fn vi_deactivate_region() {
crate::ported::zle::zle_main::REGION_ACTIVE.store(0, std::sync::atomic::Ordering::SeqCst);
}
pub fn vi_set_mark(name: char) {
crate::ported::zle::zle_main::MARK.store(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), std::sync::atomic::Ordering::SeqCst);
if let Some(idx) = vimark_slot(name) {
crate::ported::zle::zle_main::vimarks().lock().unwrap()[idx] = Some((crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), crate::ported::zle::zle_main::history().lock().unwrap().cursor as i32));
}
}
pub fn vi_goto_mark(name: char) {
let idx = match vimark_slot(name) {
Some(i) => i,
None => return,
};
let (cs, hist) = match crate::ported::zle::zle_main::vimarks().lock().unwrap()[idx] {
Some(s) => s,
None => return,
};
crate::ported::zle::zle_main::vimarks().lock().unwrap()[26] = Some((crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), crate::ported::zle::zle_main::history().lock().unwrap().cursor as i32));
if hist >= 0 && (hist as usize) < crate::ported::zle::zle_main::history().lock().unwrap().entries.len() {
let target = hist as usize;
if target != crate::ported::zle::zle_main::history().lock().unwrap().cursor {
crate::ported::zle::zle_main::history().lock().unwrap().cursor = target;
*crate::ported::zle::zle_main::ZLELINE.lock().unwrap() = crate::ported::zle::zle_main::history().lock().unwrap().entries[target].line.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(cs.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 vi_record_change(key: u8) {
crate::ported::zle::zle_main::VICHGBUF.lock().unwrap().push(key);
}
pub fn vi_start_change_recording() {
crate::ported::zle::zle_main::VICHGBUF.lock().unwrap().clear();
}
pub fn vi_repeat_change() {
if crate::ported::zle::zle_main::VICHGBUF.lock().unwrap().is_empty() {
return;
}
let bytes = crate::ported::zle::zle_main::VICHGBUF.lock().unwrap().clone();
ungetbytes(&bytes);
}
pub fn vi_get_range(op_char: char) -> Option<(usize, usize, bool)> {
let pos = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
let n = vi_get_arg().max(1);
let motion = getfullchar(false)?;
if motion == op_char {
let bol = findbol();
let mut eol = findeol();
for _ in 1..n {
if eol >= crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
break;
}
eol = findeol();
}
let end = if eol < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) { eol + 1 } else { eol };
return Some((bol, end, true));
}
let other = match motion {
'w' => {
let mut p = pos;
for _ in 0..n {
let saved_cs = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLECS.store(p, std::sync::atomic::Ordering::SeqCst);
p = find_word_end(super::zle_word::WordStyle::Vi);
crate::ported::zle::zle_main::ZLECS.store(saved_cs, std::sync::atomic::Ordering::SeqCst);
}
p
}
'W' => {
let mut p = pos;
for _ in 0..n {
let saved_cs = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLECS.store(p, std::sync::atomic::Ordering::SeqCst);
p = find_word_end(super::zle_word::WordStyle::BlankDelimited);
crate::ported::zle::zle_main::ZLECS.store(saved_cs, std::sync::atomic::Ordering::SeqCst);
}
p
}
'b' => {
let mut p = pos;
for _ in 0..n {
let saved_cs = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLECS.store(p, std::sync::atomic::Ordering::SeqCst);
p = find_word_start(super::zle_word::WordStyle::Vi);
crate::ported::zle::zle_main::ZLECS.store(saved_cs, std::sync::atomic::Ordering::SeqCst);
}
p
}
'B' => {
let mut p = pos;
for _ in 0..n {
let saved_cs = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLECS.store(p, std::sync::atomic::Ordering::SeqCst);
p = find_word_start(super::zle_word::WordStyle::BlankDelimited);
crate::ported::zle::zle_main::ZLECS.store(saved_cs, std::sync::atomic::Ordering::SeqCst);
}
p
}
'e' => {
let saved_cs = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLECS.store(pos, std::sync::atomic::Ordering::SeqCst);
let mut p = find_word_end(super::zle_word::WordStyle::Vi);
crate::ported::zle::zle_main::ZLECS.store(saved_cs, std::sync::atomic::Ordering::SeqCst);
if p < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
p += 1;
}
p
}
'E' => {
let saved_cs = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLECS.store(pos, std::sync::atomic::Ordering::SeqCst);
let mut p = find_word_end(super::zle_word::WordStyle::BlankDelimited);
crate::ported::zle::zle_main::ZLECS.store(saved_cs, std::sync::atomic::Ordering::SeqCst);
if p < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
p += 1;
}
p
}
'0' => findbol(),
'^' => {
let bol = findbol();
let mut p = bol;
while p < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) && { let __c = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[p]; __c.is_whitespace() && __c != '\n' } {
p += 1;
}
p
}
'$' => findeol(),
'h' => pos.saturating_sub(n as usize),
'l' => (pos + n as usize).min(crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst)),
'j' => {
let mut p = findeol();
for _ in 0..n {
if p >= crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
break;
}
p = findeol();
}
let bol = findbol();
let end = if p < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) { p + 1 } else { p };
return Some((bol, end, true));
}
'k' => {
let mut bol = findbol();
for _ in 0..n {
if bol == 0 {
break;
}
bol = findbol();
}
let eol = findeol();
let end = if eol < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) { eol + 1 } else { eol };
return Some((bol, end, true));
}
'f' | 'F' | 't' | 'T' => {
let next = getfullchar(false)?;
VFINDCHAR.store(next as i32, Ordering::SeqCst);
VFINDDIR.store(
if motion == 'f' || motion == 't' { 1 } else { -1 },
Ordering::SeqCst,
);
TAILADD.store(
match motion {
'f' | 'F' => 0,
't' => -1,
'T' => 1,
_ => 0,
},
Ordering::SeqCst,
);
let saved_mult = crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult;
crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult = n;
let ok = vi_find_char_inner(false) == 0;
crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult = saved_mult;
if !ok {
return None;
}
let mut p = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
if (motion == 'f' || motion == 't') && p < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
p += 1;
}
crate::ported::zle::zle_main::ZLECS.store(pos, std::sync::atomic::Ordering::SeqCst);
p
}
_ => return None,
};
if other == pos {
return None;
}
let (start, end) = if other > pos { (pos, other) } else { (other, pos) };
Some((start, end, false))
}
fn vi_cut_into_killring(start: usize, end: usize) {
if end <= start || end > crate::ported::zle::zle_main::ZLELINE.lock().unwrap().len() {
return;
}
let killed: Vec<char> = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[start..end].to_vec();
crate::ported::zle::zle_main::KILLRING.lock().unwrap().push_front(killed);
if crate::ported::zle::zle_main::KILLRING.lock().unwrap().len() > crate::ported::zle::zle_main::KILLRINGMAX.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::KILLRING.lock().unwrap().pop_back();
}
}
pub fn vi_delete_op() -> i32 {
let (start, end, line_mode) = match vi_get_range('d') {
Some(r) => r,
None => return 1,
};
vi_cut_into_killring(start, end);
let drained = end - start;
crate::ported::zle::zle_main::ZLELINE.lock().unwrap().drain(start..end);
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(start.min(crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst)), std::sync::atomic::Ordering::SeqCst);
if line_mode && crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) > 0 {
crate::ported::zle::zle_main::LASTCOL.store(-1, std::sync::atomic::Ordering::SeqCst);
let bol = findbol();
let mut p = bol;
while p < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) && { let __c = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[p]; __c.is_whitespace() && __c != '\n' } {
p += 1;
}
crate::ported::zle::zle_main::ZLECS.store(p, std::sync::atomic::Ordering::SeqCst);
}
let _ = drained;
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn vi_change_op() -> i32 {
let (start, end, _) = match vi_get_range('c') {
Some(r) => r,
None => return 1,
};
vi_cut_into_killring(start, end);
crate::ported::zle::zle_main::ZLELINE.lock().unwrap().drain(start..end);
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(start.min(crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst)), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::VISTARTCHANGE.store(crate::ported::zle::zle_main::UNDO_CHANGENO.load(std::sync::atomic::Ordering::SeqCst), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_keymap::selectkeymap("main", 1);
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn vi_yank_op() -> i32 {
let saved_lastcol = crate::ported::zle::zle_main::LASTCOL.load(std::sync::atomic::Ordering::SeqCst);
let (start, end, line_mode) = match vi_get_range('y') {
Some(r) => r,
None => return 1,
};
vi_cut_into_killring(start, end);
crate::ported::zle::zle_main::ZLECS.store(start, std::sync::atomic::Ordering::SeqCst);
if line_mode && saved_lastcol != -1 {
let eol = findeol();
crate::ported::zle::zle_main::ZLECS.fetch_add(saved_lastcol as usize, std::sync::atomic::Ordering::SeqCst);
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) >= eol {
crate::ported::zle::zle_main::ZLECS.store(eol, std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::LASTCOL.store(-1, std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
fn vimark_slot(name: char) -> Option<usize> {
if name.is_ascii_lowercase() {
Some(name as usize - 'a' as usize)
} else if name == '\'' || name == '`' {
Some(26)
} else {
None
}
}
pub fn viyank(_args: &[String]) -> i32 { use std::sync::atomic::Ordering::SeqCst;
let mut ret = 1;
startvichange(1); let c2 = getvirange(0); if c2 != -1 {
let zlecs_now = crate::ported::zle::zle_main::ZLECS.load(SeqCst) as i32;
crate::ported::zle::zle_utils::cut( zlecs_now,
c2 - zlecs_now,
crate::ported::zle::zle_h::CUT_YANK,
);
ret = 0;
}
if VILINERANGE.load(SeqCst) != 0
&& crate::ported::zle::zle_main::LASTCOL.load(SeqCst) != -1
{
let x = crate::ported::zle::zle_utils::findeol() as i32;
let new_cs = crate::ported::zle::zle_main::ZLECS.load(SeqCst) as i32
+ crate::ported::zle::zle_main::LASTCOL.load(SeqCst);
if new_cs >= x {
crate::ported::zle::zle_main::ZLECS.store(x as usize, SeqCst);
let bol = crate::ported::zle::zle_utils::findbol() as i32;
let cmname = crate::ported::zle::zle_keymap::curkeymapname().clone();
if x > bol && crate::ported::zle::zle_h::invicmdmode(&cmname) {
crate::ported::zle::zle_move::deccs();
}
} else {
crate::ported::zle::zle_main::ZLECS.store(new_cs as usize, SeqCst);
}
crate::ported::zle::zle_main::LASTCOL.store(-1, SeqCst); }
ret
}
#[cfg(test)]
mod tests {
use super::*;
fn zle_with(line: &str, cs: usize) {
crate::ported::zle::zle_main::zle_reset();
*crate::ported::zle::zle_main::ZLELINE.lock().unwrap() = line.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(cs, std::sync::atomic::Ordering::SeqCst);
}
#[test]
fn vi_find_char_inner_lands_on_target_forward() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("abcdef", 0);
VFINDCHAR.store('d' as i32, Ordering::SeqCst);
VFINDDIR.store(1, Ordering::SeqCst);
TAILADD.store(0, Ordering::SeqCst);
assert_eq!(vi_find_char_inner(false), 0);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 3);
}
#[test]
fn vi_find_char_inner_skip_stops_one_short_forward() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("abcdef", 0);
VFINDCHAR.store('d' as i32, Ordering::SeqCst);
VFINDDIR.store(1, Ordering::SeqCst);
TAILADD.store(-1, Ordering::SeqCst); assert_eq!(vi_find_char_inner(false), 0);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 2);
}
#[test]
fn vi_find_char_inner_lands_on_target_backward() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("abcdef", 5);
VFINDCHAR.store('b' as i32, Ordering::SeqCst);
VFINDDIR.store(-1, Ordering::SeqCst);
TAILADD.store(0, Ordering::SeqCst);
assert_eq!(vi_find_char_inner(false), 0);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 1);
}
#[test]
fn vi_find_char_inner_returns_1_and_restores_when_missing() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("abcdef", 0);
VFINDCHAR.store('z' as i32, Ordering::SeqCst);
VFINDDIR.store(1, Ordering::SeqCst);
TAILADD.store(0, Ordering::SeqCst);
assert_eq!(vi_find_char_inner(false), 1);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 0);
}
#[test]
fn vi_find_char_inner_stops_at_newline() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("abc\ndef", 0);
VFINDCHAR.store('e' as i32, Ordering::SeqCst);
VFINDDIR.store(1, Ordering::SeqCst);
TAILADD.store(0, Ordering::SeqCst);
assert_eq!(vi_find_char_inner(false), 1);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 0);
}
#[test]
fn vi_repeat_find_walks_to_next_match_in_same_direction() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("a-b-c-d", 0);
VFINDCHAR.store('-' as i32, Ordering::SeqCst);
VFINDDIR.store(1, Ordering::SeqCst);
TAILADD.store(0, Ordering::SeqCst);
assert_eq!(vi_find_char_inner(false), 0);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 1);
assert_eq!(virepeatfind(), 0);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 3);
assert_eq!(virepeatfind(), 0);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 5);
}
#[test]
fn vi_set_and_goto_named_mark_round_trip() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("hello world", 6);
vi_set_mark('a');
crate::ported::zle::zle_main::ZLECS.store(0, std::sync::atomic::Ordering::SeqCst);
vi_goto_mark('a');
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 6);
}
#[test]
fn vi_goto_mark_records_implicit_last_position() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("0123456789", 4);
vi_set_mark('m');
crate::ported::zle::zle_main::ZLECS.store(9, std::sync::atomic::Ordering::SeqCst);
vi_goto_mark('m'); assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 4);
vi_goto_mark('\''); assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 9);
}
#[test]
fn vi_set_mark_ignores_invalid_names() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("abc", 1);
vi_set_mark('A'); vi_set_mark('1'); assert!(crate::ported::zle::zle_main::vimarks().lock().unwrap().iter().all(|m| m.is_none()));
}
fn feed(s: &str) {
ungetbytes(s.as_bytes());
}
#[test]
fn vi_get_range_dd_selects_whole_current_line() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("aaa\nbbb\nccc", 4); feed("d");
let (s, e, line) = vi_get_range('d').expect("range");
assert!(line);
assert_eq!(s, 4);
assert_eq!(e, 8); }
#[test]
fn vi_get_range_dw_selects_to_word_end() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("hello world", 0);
feed("w");
let (s, e, line) = vi_get_range('d').expect("range");
assert!(!line);
assert_eq!(s, 0);
assert_eq!(e, 6);
}
#[test]
fn vi_get_range_d_dollar_selects_to_eol() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("foo bar baz", 4);
feed("$");
let (s, e, _) = vi_get_range('d').expect("range");
assert_eq!(s, 4);
assert_eq!(e, 11);
}
#[test]
fn vi_delete_op_dw_removes_first_word() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("hello world", 0);
feed("w");
assert_eq!(vi_delete_op(), 0);
assert_eq!(crate::ported::zle::zle_main::ZLELINE.lock().unwrap().iter().collect::<String>(), "world");
assert_eq!(
crate::ported::zle::zle_main::KILLRING.lock().unwrap().front().map(|v| v.iter().collect::<String>()),
Some("hello ".to_string())
);
}
#[test]
fn vi_yank_op_y_dollar_copies_without_removing() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("foo bar", 4);
feed("$");
assert_eq!(vi_yank_op(), 0);
assert_eq!(crate::ported::zle::zle_main::ZLELINE.lock().unwrap().iter().collect::<String>(), "foo bar");
assert_eq!(
crate::ported::zle::zle_main::KILLRING.lock().unwrap().front().map(|v| v.iter().collect::<String>()),
Some("bar".to_string())
);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 4);
}
#[test]
fn vi_change_op_cw_removes_word_and_clears_pending_change() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("foo bar", 0);
feed("w");
assert_eq!(vi_change_op(), 0);
assert_eq!(crate::ported::zle::zle_main::ZLELINE.lock().unwrap().iter().collect::<String>(), "bar");
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 0);
assert_eq!(crate::ported::zle::zle_main::VISTARTCHANGE.load(std::sync::atomic::Ordering::SeqCst), crate::ported::zle::zle_main::UNDO_CHANGENO.load(std::sync::atomic::Ordering::SeqCst));
}
#[test]
fn vi_visual_mode_toggles_charwise() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("abcd", 2);
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 0);
vi_visual_mode();
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 1);
assert_eq!(crate::ported::zle::zle_main::MARK.load(std::sync::atomic::Ordering::SeqCst), 2);
vi_visual_mode();
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 0);
}
#[test]
fn vi_visual_line_mode_toggles_linewise_and_swaps_with_charwise() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("abcd", 0);
vi_visual_line_mode();
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 2);
vi_visual_mode();
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 1);
vi_visual_line_mode();
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 2);
vi_visual_line_mode();
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 0);
}
#[test]
fn vi_deactivate_region_clears_active_state() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("abcd", 0);
crate::ported::zle::zle_main::REGION_ACTIVE.store(2, std::sync::atomic::Ordering::SeqCst);
vi_deactivate_region();
assert_eq!(crate::ported::zle::zle_main::REGION_ACTIVE.load(std::sync::atomic::Ordering::SeqCst), 0);
}
#[test]
fn vi_record_change_appends_to_replay_buffer() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("", 0);
vi_start_change_recording();
vi_record_change(b'd');
vi_record_change(b'w');
assert_eq!(*crate::ported::zle::zle_main::VICHGBUF.lock().unwrap(), vec![b'd', b'w']);
vi_start_change_recording();
assert!(crate::ported::zle::zle_main::VICHGBUF.lock().unwrap().is_empty());
}
#[test]
fn vi_get_range_unknown_motion_returns_none() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("abc", 0);
feed("Z"); assert!(vi_get_range('d').is_none());
}
#[test]
fn vi_undo_reverses_a_recorded_change() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("", 0);
setlastline();
*crate::ported::zle::zle_main::ZLELINE.lock().unwrap() = "abc".chars().collect();
crate::ported::zle::zle_main::ZLELL.store(3, std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLECS.store(3, std::sync::atomic::Ordering::SeqCst);
mkundoent();
vi_undo();
assert_eq!(crate::ported::zle::zle_main::ZLELINE.lock().unwrap().iter().collect::<String>(), "");
}
#[test]
fn vi_rev_repeat_find_walks_back() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut zle = zle_with("a-b-c-d", 0);
VFINDCHAR.store('-' as i32, Ordering::SeqCst);
VFINDDIR.store(1, Ordering::SeqCst);
TAILADD.store(0, Ordering::SeqCst);
assert_eq!(vi_find_char_inner(false), 0);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 1);
assert_eq!(virepeatfind(), 0);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 3);
assert_eq!(virevrepeatfind(), 0);
assert_eq!(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), 1);
}
}
pub fn dovilinerange() -> (usize, usize) { let bol = crate::ported::zle::zle_utils::findbol();
let eol = crate::ported::zle::zle_utils::findeol();
let end = if eol < crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) { eol + 1 } else { eol };
(bol, end)
}
pub fn getvirange(_wf: i32) -> i32 { crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) as i32 }
pub fn startvichange(im: i32) { if im > -1 { crate::ported::zle::zle_main::INSMODE.store(if im != 0 { 1 } else { 0 }, std::sync::atomic::Ordering::SeqCst); }
}
pub fn startvitext(im: i32) { startvichange(im); crate::ported::zle::zle_keymap::selectkeymap("main", 1); crate::ported::zle::zle_main::VISTARTCHANGE.store(crate::ported::zle::zle_main::UNDO_CHANGENO.load(std::sync::atomic::Ordering::SeqCst), std::sync::atomic::Ordering::SeqCst); crate::ported::zle::zle_main::VIINSBEGIN.store(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), std::sync::atomic::Ordering::SeqCst); }
pub fn viaddeol() -> i32 { crate::ported::zle::zle_main::ZLECS.store(crate::ported::zle::zle_utils::findeol(), std::sync::atomic::Ordering::SeqCst);
startvitext(1);
0
}
pub fn viaddnext() -> i32 { let eol = crate::ported::zle::zle_utils::findeol();
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) != eol {
crate::ported::zle::zle_move::inccs();
}
startvitext(1);
0
}
pub fn vibackwarddeletechar() -> i32 { startvichange(-1);
crate::ported::zle::zle_misc::backwarddeletechar()
}
pub fn vicapslockpanic() -> i32 { use std::sync::atomic::Ordering;
crate::ported::zle::zle_refresh::CLEARLIST.store(1, Ordering::Relaxed);
crate::ported::utils::zbeep();
let _ = crate::ported::params::setsparam(
"STATUSLINE", "press a lowercase key to continue",
);
let _ = crate::ported::params::setsparam("STATUSLINE", "");
0 }
pub fn vichange() -> i32 { startvichange(1);
startvitext(1);
0
}
pub fn vichangeeol() -> i32 { let eol = crate::ported::zle::zle_utils::findeol();
if eol > crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) {
let text: Vec<char> = crate::ported::zle::zle_main::ZLELINE.lock().unwrap().drain(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)..eol).collect();
crate::ported::zle::zle_main::KILLRING.lock().unwrap().push_front(text);
if crate::ported::zle::zle_main::KILLRING.lock().unwrap().len() > crate::ported::zle::zle_main::KILLRINGMAX.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::KILLRING.lock().unwrap().pop_back();
}
crate::ported::zle::zle_main::ZLELL.fetch_sub(eol - crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), std::sync::atomic::Ordering::SeqCst);
}
startvitext(1);
0
}
pub fn vichangewholeline() -> i32 { crate::ported::zle::zle_move::vifirstnonblank();
vichangeeol()
}
pub fn vicmdmode() -> i32 { if *crate::ported::zle::zle_keymap::curkeymapname() == "vicmd" {
return 1;
}
if crate::ported::zle::zle_keymap::selectkeymap("vicmd", 0) != 0 {
return 1;
}
let bol = crate::ported::zle::zle_utils::findbol();
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) != bol {
crate::ported::zle::zle_move::deccs();
}
0
}
pub fn videlete() -> i32 { startvichange(1);
1 }
pub fn videletechar() -> i32 { startvichange(-1);
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) == crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) || crate::ported::zle::zle_main::ZLELINE.lock().unwrap().get(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)) == Some(&'\n') {
return 1; }
crate::ported::zle::zle_misc::deletechar()
}
pub fn vidigitorbeginningofline() -> 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 crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags & MOD_TMULT != 0 {
return crate::ported::zle::zle_misc::digitargument();
}
crate::ported::zle::zle_move::vibeginningofline()
}
pub fn vidowncase() -> i32 { startvichange(1);
let eol = crate::ported::zle::zle_utils::findeol();
for i in crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)..eol {
{ let mut __g = crate::ported::zle::zle_main::ZLELINE.lock().unwrap(); __g[i] = __g[i].to_ascii_lowercase(); }
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn vigetkey() -> i32 { if let Some(b) = crate::ported::zle::zle_main::KUNGETBUF.lock().unwrap().pop_front() {
b as i32
} else {
-1 }
}
pub fn viindent() -> i32 { startvichange(1);
let bol = crate::ported::zle::zle_utils::findbol();
for _ in 0..4 {
crate::ported::zle::zle_main::ZLELINE.lock().unwrap().insert(bol, ' ');
crate::ported::zle::zle_main::ZLELL.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
}
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) >= bol {
crate::ported::zle::zle_main::ZLECS.fetch_add(4, std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn viinsert() -> i32 { startvitext(1);
0
}
pub fn viinsert_init() { startvitext(-2);
}
pub fn viinsertbol() -> i32 { crate::ported::zle::zle_move::vifirstnonblank();
startvitext(1);
0
}
pub fn vijoin() -> i32 { startvichange(-1);
let n = crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult.max(1);
for _ in 0..n {
let eol = crate::ported::zle::zle_utils::findeol();
if eol >= crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) || crate::ported::zle::zle_main::ZLELINE.lock().unwrap().get(eol) != Some(&'\n') {
return 1;
}
crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[eol] = ' ';
let mut p = eol + 1;
while p < crate::ported::zle::zle_main::ZLELINE.lock().unwrap().len() && crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[p].is_whitespace() {
crate::ported::zle::zle_main::ZLELINE.lock().unwrap().remove(p);
crate::ported::zle::zle_main::ZLELL.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
}
let _ = p;
crate::ported::zle::zle_main::ZLECS.store(eol, std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn vikilleol() -> i32 { startvichange(1);
let eol = crate::ported::zle::zle_utils::findeol();
if eol > crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) {
let text: Vec<char> = crate::ported::zle::zle_main::ZLELINE.lock().unwrap().drain(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)..eol).collect();
crate::ported::zle::zle_main::KILLRING.lock().unwrap().push_front(text);
if crate::ported::zle::zle_main::KILLRING.lock().unwrap().len() > crate::ported::zle::zle_main::KILLRINGMAX.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::KILLRING.lock().unwrap().pop_back();
}
crate::ported::zle::zle_main::ZLELL.fetch_sub(eol - crate::ported::zle::zle_main::ZLECS.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);
0
}
pub fn vikillline() -> i32 { startvichange(1);
let bol = crate::ported::zle::zle_utils::findbol();
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) > bol {
let text: Vec<char> = crate::ported::zle::zle_main::ZLELINE.lock().unwrap().drain(bol..crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)).collect();
crate::ported::zle::zle_main::KILLRING.lock().unwrap().push_front(text);
if crate::ported::zle::zle_main::KILLRING.lock().unwrap().len() > crate::ported::zle::zle_main::KILLRINGMAX.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::KILLRING.lock().unwrap().pop_back();
}
crate::ported::zle::zle_main::ZLELL.fetch_sub(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) - bol, std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLECS.store(bol, std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn viopenlineabove() -> i32 { crate::ported::zle::zle_main::ZLECS.store(crate::ported::zle::zle_utils::findbol(), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLELINE.lock().unwrap().insert(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), '\n');
crate::ported::zle::zle_main::ZLELL.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
startvitext(1);
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn viopenlinebelow() -> i32 { crate::ported::zle::zle_main::ZLECS.store(crate::ported::zle::zle_utils::findeol(), std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLELINE.lock().unwrap().insert(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst), '\n');
crate::ported::zle::zle_main::ZLECS.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLELL.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
startvitext(1);
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn vioperswapcase() -> i32 { startvichange(1);
let eol = crate::ported::zle::zle_utils::findeol();
let oldcs = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
while crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) < eol {
let c = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)];
crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)] = if c.is_ascii_uppercase() {
c.to_ascii_lowercase()
} else if c.is_ascii_lowercase() {
c.to_ascii_uppercase()
} else {
c
};
crate::ported::zle::zle_main::ZLECS.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::ZLECS.store(oldcs, std::sync::atomic::Ordering::SeqCst);
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn vipoundinsert() -> i32 { crate::ported::zle::zle_misc::poundinsert()
}
pub fn viquotedinsert() -> i32 { startvichange(-1);
crate::ported::zle::zle_misc::quotedinsert()
}
pub fn virepeatchange() -> i32 { 1 }
pub fn vireplace() -> i32 { startvitext(0);
0
}
pub fn vireplacechars() -> i32 { startvichange(1);
let n = crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult.max(1) as usize;
let eol = crate::ported::zle::zle_utils::findeol();
let avail = eol.saturating_sub(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst));
if n > avail {
return 1; }
if let Some(c) = char::from_u32(crate::ported::zle::compcore::LASTCHAR.load(std::sync::atomic::Ordering::SeqCst) as u32) {
for i in 0..n {
crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) + i] = c;
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
}
0
}
pub fn visetbuffer() -> 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};
let c = (crate::ported::zle::compcore::LASTCHAR.load(std::sync::atomic::Ordering::SeqCst) & 0xff) as u8;
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 if c.is_ascii_uppercase() {
crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags |= MOD_VIAPP;
(c - b'A') as i32
} else {
return 1;
};
crate::ported::zle::zle_main::ZMOD.lock().unwrap().vibuf = idx;
crate::ported::zle::zle_main::ZMOD.lock().unwrap().flags |= MOD_VIBUF;
crate::ported::zle::zle_main::PREFIXFLAG.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn visubstitute() -> i32 { startvichange(1);
let n = crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult;
if n < 0 {
return 1;
}
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) == crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) || crate::ported::zle::zle_main::ZLELINE.lock().unwrap().get(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)) == Some(&'\n') {
return 1;
}
let eol = crate::ported::zle::zle_utils::findeol();
let count = (n as usize).min(eol - crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst));
if count > 0 {
let text: Vec<char> = crate::ported::zle::zle_main::ZLELINE.lock().unwrap().drain(crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)..crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) + count).collect();
crate::ported::zle::zle_main::KILLRING.lock().unwrap().push_front(text);
if crate::ported::zle::zle_main::KILLRING.lock().unwrap().len() > crate::ported::zle::zle_main::KILLRINGMAX.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::KILLRING.lock().unwrap().pop_back();
}
crate::ported::zle::zle_main::ZLELL.fetch_sub(count, std::sync::atomic::Ordering::SeqCst);
}
startvitext(1);
0
}
pub fn viswapcase() -> i32 { startvichange(-1);
let n = crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult;
if n < 1 {
return 1;
}
let eol = crate::ported::zle::zle_utils::findeol();
for _ in 0..n {
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) >= eol {
break;
}
let c = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)];
let swapped = if c.is_ascii_uppercase() {
c.to_ascii_lowercase()
} else if c.is_ascii_lowercase() {
c.to_ascii_uppercase()
} else {
c
};
crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)] = swapped;
crate::ported::zle::zle_main::ZLECS.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn viunindent() -> i32 { startvichange(1);
let bol = crate::ported::zle::zle_utils::findbol();
let mut removed = 0;
while removed < 4 && bol < crate::ported::zle::zle_main::ZLELINE.lock().unwrap().len() && crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[bol] == ' ' {
crate::ported::zle::zle_main::ZLELINE.lock().unwrap().remove(bol);
crate::ported::zle::zle_main::ZLELL.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
removed += 1;
}
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) >= bol + removed {
crate::ported::zle::zle_main::ZLECS.fetch_sub(removed, std::sync::atomic::Ordering::SeqCst);
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn viupcase() -> i32 { startvichange(1);
let eol = crate::ported::zle::zle_utils::findeol();
for i in crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)..eol {
{ let mut __g = crate::ported::zle::zle_main::ZLELINE.lock().unwrap(); __g[i] = __g[i].to_ascii_uppercase(); }
}
crate::ported::zle::zle_main::ZLE_RESET_NEEDED.store(1, std::sync::atomic::Ordering::SeqCst);
0
}
pub fn viyankeol() -> i32 { let x = crate::ported::zle::zle_utils::findeol();
startvichange(-1);
if x == crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) {
return 1; }
let text: Vec<char> = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst)..x].to_vec();
crate::ported::zle::zle_main::KILLRING.lock().unwrap().push_front(text);
if crate::ported::zle::zle_main::KILLRING.lock().unwrap().len() > crate::ported::zle::zle_main::KILLRINGMAX.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::KILLRING.lock().unwrap().pop_back();
}
0 }
pub fn viyankwholeline() -> i32 { let bol = crate::ported::zle::zle_utils::findbol();
let oldcs = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
startvichange(-1);
let n = crate::ported::zle::zle_main::ZMOD.lock().unwrap().mult;
if n < 1 {
return 1;
}
for _ in 0..n {
crate::ported::zle::zle_main::ZLECS.store(crate::ported::zle::zle_utils::findeol() + 1, std::sync::atomic::Ordering::SeqCst);
if crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst) > crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::ZLECS.store(crate::ported::zle::zle_main::ZLELL.load(std::sync::atomic::Ordering::SeqCst), std::sync::atomic::Ordering::SeqCst);
}
}
let end = crate::ported::zle::zle_main::ZLECS.load(std::sync::atomic::Ordering::SeqCst);
let text: Vec<char> = crate::ported::zle::zle_main::ZLELINE.lock().unwrap()[bol..end].to_vec();
crate::ported::zle::zle_main::KILLRING.lock().unwrap().push_front(text);
if crate::ported::zle::zle_main::KILLRING.lock().unwrap().len() > crate::ported::zle::zle_main::KILLRINGMAX.load(std::sync::atomic::Ordering::SeqCst) {
crate::ported::zle::zle_main::KILLRING.lock().unwrap().pop_back();
}
crate::ported::zle::zle_main::ZLECS.store(oldcs, std::sync::atomic::Ordering::SeqCst);
0
}