1use super::main::Zle;
9
10pub type ZleIntFunc = fn(&mut Zle) -> i32;
12
13#[derive(Clone)]
15pub enum WidgetFunc {
16 Internal(fn(&mut Zle)),
18 User(String),
20}
21
22impl std::fmt::Debug for WidgetFunc {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 match self {
25 WidgetFunc::Internal(_) => write!(f, "Internal(<fn>)"),
26 WidgetFunc::User(name) => write!(f, "User({})", name),
27 }
28 }
29}
30
31bitflags::bitflags! {
32 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
34 pub struct WidgetFlags: u32 {
35 const INT = 1 << 0;
37 const NCOMP = 1 << 1;
39 const MENUCMP = 1 << 2;
41 const YANKAFTER = 1 << 3;
43 const YANKBEFORE = 1 << 4;
45 const YANK = Self::YANKAFTER.bits() | Self::YANKBEFORE.bits();
47 const LINEMOVE = 1 << 5;
49 const VIOPER = 1 << 6;
51 const LASTCOL = 1 << 7;
53 const KILL = 1 << 8;
55 const KEEPSUFFIX = 1 << 9;
57 const NOTCOMMAND = 1 << 10;
59 const ISCOMP = 1 << 11;
61 const INUSE = 1 << 12;
63 const FREE = 1 << 13;
65 const NOLAST = 1 << 14;
67 }
68}
69
70#[derive(Debug, Clone)]
72pub struct Widget {
73 pub flags: WidgetFlags,
75 pub func: WidgetFunc,
77}
78
79impl Widget {
80 pub fn internal(name: &str, func: fn(&mut Zle), flags: WidgetFlags) -> Self {
82 let _ = name; Widget {
84 flags: flags | WidgetFlags::INT,
85 func: WidgetFunc::Internal(func),
86 }
87 }
88
89 pub fn builtin(name: &str) -> Self {
91 let (func, flags) = get_builtin_widget(name);
92 Widget {
93 flags: flags | WidgetFlags::INT,
94 func: WidgetFunc::Internal(func),
95 }
96 }
97
98 pub fn user_defined(name: &str, func_name: &str) -> Self {
100 let _ = name;
101 Widget {
102 flags: WidgetFlags::empty(),
103 func: WidgetFunc::User(func_name.to_string()),
104 }
105 }
106}
107
108fn get_builtin_widget(name: &str) -> (fn(&mut Zle), WidgetFlags) {
110 match name {
111 "accept-line" => (widget_accept_line, WidgetFlags::empty()),
113 "accept-and-hold" => (widget_accept_and_hold, WidgetFlags::empty()),
114 "accept-line-and-down-history" => {
115 (widget_accept_line_and_down_history, WidgetFlags::empty())
116 }
117
118 "self-insert" => (widget_self_insert, WidgetFlags::empty()),
120 "self-insert-unmeta" => (widget_self_insert_unmeta, WidgetFlags::empty()),
121
122 "forward-char" => (widget_forward_char, WidgetFlags::empty()),
124 "backward-char" => (widget_backward_char, WidgetFlags::empty()),
125
126 "forward-word" => (widget_forward_word, WidgetFlags::empty()),
128 "backward-word" => (widget_backward_word, WidgetFlags::empty()),
129
130 "beginning-of-line" => (widget_beginning_of_line, WidgetFlags::empty()),
132 "end-of-line" => (widget_end_of_line, WidgetFlags::empty()),
133
134 "delete-char" => (widget_delete_char, WidgetFlags::empty()),
136 "backward-delete-char" => (widget_backward_delete_char, WidgetFlags::empty()),
137 "delete-char-or-list" => (widget_delete_char_or_list, WidgetFlags::empty()),
138
139 "kill-line" => (widget_kill_line, WidgetFlags::KILL),
141 "backward-kill-line" => (widget_backward_kill_line, WidgetFlags::KILL),
142 "kill-whole-line" => (widget_kill_whole_line, WidgetFlags::KILL),
143 "kill-word" => (widget_kill_word, WidgetFlags::KILL),
144 "backward-kill-word" => (widget_backward_kill_word, WidgetFlags::KILL),
145
146 "yank" => (widget_yank, WidgetFlags::YANK),
148 "yank-pop" => (widget_yank_pop, WidgetFlags::YANK),
149
150 "undo" => (widget_undo, WidgetFlags::empty()),
152 "redo" => (widget_redo, WidgetFlags::empty()),
153
154 "up-line-or-history" => (widget_up_line_or_history, WidgetFlags::LINEMOVE),
156 "down-line-or-history" => (widget_down_line_or_history, WidgetFlags::LINEMOVE),
157 "up-history" => (widget_up_history, WidgetFlags::LINEMOVE),
158 "down-history" => (widget_down_history, WidgetFlags::LINEMOVE),
159 "history-incremental-search-backward" => {
160 (widget_history_isearch_backward, WidgetFlags::empty())
161 }
162 "history-incremental-search-forward" => {
163 (widget_history_isearch_forward, WidgetFlags::empty())
164 }
165 "beginning-of-buffer-or-history" => {
166 (widget_beginning_of_buffer_or_history, WidgetFlags::LINEMOVE)
167 }
168 "end-of-buffer-or-history" => (widget_end_of_buffer_or_history, WidgetFlags::LINEMOVE),
169
170 "transpose-chars" => (widget_transpose_chars, WidgetFlags::empty()),
172 "clear-screen" => (widget_clear_screen, WidgetFlags::empty()),
173 "redisplay" => (widget_redisplay, WidgetFlags::empty()),
174 "send-break" => (widget_send_break, WidgetFlags::empty()),
175 "overwrite-mode" => (widget_overwrite_mode, WidgetFlags::empty()),
176 "quoted-insert" => (widget_quoted_insert, WidgetFlags::empty()),
177
178 "expand-or-complete" => (widget_expand_or_complete, WidgetFlags::MENUCMP),
180 "complete-word" => (widget_complete_word, WidgetFlags::MENUCMP),
181 "expand-word" => (widget_expand_word, WidgetFlags::empty()),
182 "list-choices" => (widget_list_choices, WidgetFlags::MENUCMP),
183 "menu-complete" => (widget_menu_complete, WidgetFlags::MENUCMP),
184
185 "vi-cmd-mode" => (widget_vi_cmd_mode, WidgetFlags::empty()),
187 "vi-insert" => (widget_vi_insert, WidgetFlags::empty()),
188 "vi-insert-bol" => (widget_vi_insert_bol, WidgetFlags::empty()),
189 "vi-add-next" => (widget_vi_add_next, WidgetFlags::empty()),
190 "vi-add-eol" => (widget_vi_add_eol, WidgetFlags::empty()),
191 "vi-forward-char" => (widget_vi_forward_char, WidgetFlags::empty()),
192 "vi-backward-char" => (widget_vi_backward_char, WidgetFlags::empty()),
193 "vi-forward-word" => (widget_vi_forward_word, WidgetFlags::empty()),
194 "vi-forward-word-end" => (widget_vi_forward_word_end, WidgetFlags::empty()),
195 "vi-forward-blank-word" => (widget_vi_forward_blank_word, WidgetFlags::empty()),
196 "vi-forward-blank-word-end" => (widget_vi_forward_blank_word_end, WidgetFlags::empty()),
197 "vi-backward-word" => (widget_vi_backward_word, WidgetFlags::empty()),
198 "vi-backward-blank-word" => (widget_vi_backward_blank_word, WidgetFlags::empty()),
199 "vi-delete" => (widget_vi_delete, WidgetFlags::VIOPER | WidgetFlags::KILL),
200 "vi-delete-char" => (widget_vi_delete_char, WidgetFlags::empty()),
201 "vi-backward-delete-char" => (widget_vi_backward_delete_char, WidgetFlags::empty()),
202 "vi-change" => (widget_vi_change, WidgetFlags::VIOPER | WidgetFlags::KILL),
203 "vi-change-eol" => (widget_vi_change_eol, WidgetFlags::KILL),
204 "vi-kill-eol" => (widget_vi_kill_eol, WidgetFlags::KILL),
205 "vi-yank" => (widget_vi_yank, WidgetFlags::VIOPER),
206 "vi-yank-whole-line" => (widget_vi_yank_whole_line, WidgetFlags::empty()),
207 "vi-put-after" => (widget_vi_put_after, WidgetFlags::YANK),
208 "vi-put-before" => (widget_vi_put_before, WidgetFlags::YANK),
209 "vi-replace" => (widget_vi_replace, WidgetFlags::empty()),
210 "vi-replace-chars" => (widget_vi_replace_chars, WidgetFlags::empty()),
211 "vi-substitute" => (widget_vi_substitute, WidgetFlags::empty()),
212 "vi-change-whole-line" => (widget_vi_change_whole_line, WidgetFlags::KILL),
213 "vi-first-non-blank" => (widget_vi_first_non_blank, WidgetFlags::empty()),
214 "vi-end-of-line" => (widget_vi_end_of_line, WidgetFlags::empty()),
215 "vi-digit-or-beginning-of-line" => {
216 (widget_vi_digit_or_beginning_of_line, WidgetFlags::empty())
217 }
218 "vi-open-line-below" => (widget_vi_open_line_below, WidgetFlags::empty()),
219 "vi-open-line-above" => (widget_vi_open_line_above, WidgetFlags::empty()),
220 "vi-join" => (widget_vi_join, WidgetFlags::empty()),
221 "vi-repeat-change" => (widget_vi_repeat_change, WidgetFlags::empty()),
222 "vi-find-next-char" => (widget_vi_find_next_char, WidgetFlags::empty()),
223 "vi-find-prev-char" => (widget_vi_find_prev_char, WidgetFlags::empty()),
224 "vi-find-next-char-skip" => (widget_vi_find_next_char_skip, WidgetFlags::empty()),
225 "vi-find-prev-char-skip" => (widget_vi_find_prev_char_skip, WidgetFlags::empty()),
226 "vi-repeat-find" => (widget_vi_repeat_find, WidgetFlags::empty()),
227 "vi-rev-repeat-find" => (widget_vi_rev_repeat_find, WidgetFlags::empty()),
228 "vi-history-search-forward" => (widget_vi_history_search_forward, WidgetFlags::empty()),
229 "vi-history-search-backward" => (widget_vi_history_search_backward, WidgetFlags::empty()),
230 "vi-repeat-search" => (widget_vi_repeat_search, WidgetFlags::empty()),
231 "vi-rev-repeat-search" => (widget_vi_rev_repeat_search, WidgetFlags::empty()),
232 "vi-fetch-history" => (widget_vi_fetch_history, WidgetFlags::LINEMOVE),
233 "vi-goto-column" => (widget_vi_goto_column, WidgetFlags::empty()),
234 "vi-backward-kill-word" => (widget_vi_backward_kill_word, WidgetFlags::KILL),
235
236 "digit-argument" => (widget_digit_argument, WidgetFlags::NOTCOMMAND),
238
239 _ => (widget_undefined, WidgetFlags::empty()),
241 }
242}
243
244fn widget_accept_line(zle: &mut Zle) {
247 zle.accept_line();
248}
249
250fn widget_accept_and_hold(zle: &mut Zle) {
251 zle.accept_line();
253}
254
255fn widget_accept_line_and_down_history(zle: &mut Zle) {
256 zle.accept_line();
258}
259
260fn widget_self_insert(zle: &mut Zle) {
261 #[cfg(feature = "multibyte")]
262 if let Some(c) = char::from_u32(zle.lastchar as u32) {
263 zle.self_insert(c);
264 }
265 #[cfg(not(feature = "multibyte"))]
266 if zle.lastchar >= 0 && zle.lastchar <= 127 {
267 zle.self_insert(zle.lastchar as u8 as char);
268 }
269}
270
271fn widget_self_insert_unmeta(zle: &mut Zle) {
272 let c = (zle.lastchar & 0x7f) as u8 as char;
273 zle.self_insert(c);
274}
275
276fn widget_forward_char(zle: &mut Zle) {
277 if zle.zlecs < zle.zlell {
278 zle.zlecs += 1;
279 zle.resetneeded = true;
280 }
281}
282
283fn widget_backward_char(zle: &mut Zle) {
284 if zle.zlecs > 0 {
285 zle.zlecs -= 1;
286 zle.resetneeded = true;
287 }
288}
289
290fn widget_forward_word(zle: &mut Zle) {
291 while zle.zlecs < zle.zlell && is_word_char(zle.zleline[zle.zlecs]) {
293 zle.zlecs += 1;
294 }
295 while zle.zlecs < zle.zlell && !is_word_char(zle.zleline[zle.zlecs]) {
297 zle.zlecs += 1;
298 }
299 zle.resetneeded = true;
300}
301
302fn widget_backward_word(zle: &mut Zle) {
303 while zle.zlecs > 0 && !is_word_char(zle.zleline[zle.zlecs - 1]) {
305 zle.zlecs -= 1;
306 }
307 while zle.zlecs > 0 && is_word_char(zle.zleline[zle.zlecs - 1]) {
309 zle.zlecs -= 1;
310 }
311 zle.resetneeded = true;
312}
313
314fn widget_beginning_of_line(zle: &mut Zle) {
315 zle.zlecs = 0;
316 zle.resetneeded = true;
317}
318
319fn widget_end_of_line(zle: &mut Zle) {
320 zle.zlecs = zle.zlell;
321 zle.resetneeded = true;
322}
323
324fn widget_delete_char(zle: &mut Zle) {
325 if zle.zlecs < zle.zlell {
326 zle.zleline.remove(zle.zlecs);
327 zle.zlell -= 1;
328 zle.resetneeded = true;
329 }
330}
331
332fn widget_backward_delete_char(zle: &mut Zle) {
333 if zle.zlecs > 0 {
334 zle.zlecs -= 1;
335 zle.zleline.remove(zle.zlecs);
336 zle.zlell -= 1;
337 zle.resetneeded = true;
338 }
339}
340
341fn widget_delete_char_or_list(zle: &mut Zle) {
342 if zle.zlell == 0 {
343 zle.done = true;
345 } else if zle.zlecs < zle.zlell {
346 widget_delete_char(zle);
347 } else {
348 }
351}
352
353fn widget_kill_line(zle: &mut Zle) {
354 if zle.zlecs < zle.zlell {
355 let killed: Vec<char> = zle.zleline.drain(zle.zlecs..).collect();
356 zle.zlell = zle.zlecs;
357 zle.killring.push_front(killed);
359 if zle.killring.len() > zle.killringmax {
360 zle.killring.pop_back();
361 }
362 zle.resetneeded = true;
363 }
364}
365
366fn widget_backward_kill_line(zle: &mut Zle) {
367 if zle.zlecs > 0 {
368 let killed: Vec<char> = zle.zleline.drain(..zle.zlecs).collect();
369 zle.zlell -= zle.zlecs;
370 zle.zlecs = 0;
371 zle.killring.push_front(killed);
372 if zle.killring.len() > zle.killringmax {
373 zle.killring.pop_back();
374 }
375 zle.resetneeded = true;
376 }
377}
378
379fn widget_kill_whole_line(zle: &mut Zle) {
380 if zle.zlell > 0 {
381 let killed = std::mem::take(&mut zle.zleline);
382 zle.killring.push_front(killed);
383 if zle.killring.len() > zle.killringmax {
384 zle.killring.pop_back();
385 }
386 zle.zlecs = 0;
387 zle.zlell = 0;
388 zle.resetneeded = true;
389 }
390}
391
392fn widget_kill_word(zle: &mut Zle) {
393 let start = zle.zlecs;
394 while zle.zlecs < zle.zlell && !is_word_char(zle.zleline[zle.zlecs]) {
396 zle.zlecs += 1;
397 }
398 while zle.zlecs < zle.zlell && is_word_char(zle.zleline[zle.zlecs]) {
400 zle.zlecs += 1;
401 }
402 let end = zle.zlecs;
403 zle.zlecs = start;
404
405 if end > start {
406 let killed: Vec<char> = zle.zleline.drain(start..end).collect();
407 zle.zlell -= end - start;
408 zle.killring.push_front(killed);
409 if zle.killring.len() > zle.killringmax {
410 zle.killring.pop_back();
411 }
412 zle.resetneeded = true;
413 }
414}
415
416fn widget_backward_kill_word(zle: &mut Zle) {
417 let end = zle.zlecs;
418 while zle.zlecs > 0 && !is_word_char(zle.zleline[zle.zlecs - 1]) {
420 zle.zlecs -= 1;
421 }
422 while zle.zlecs > 0 && is_word_char(zle.zleline[zle.zlecs - 1]) {
424 zle.zlecs -= 1;
425 }
426 let start = zle.zlecs;
427
428 if end > start {
429 let killed: Vec<char> = zle.zleline.drain(start..end).collect();
430 zle.zlell -= end - start;
431 zle.killring.push_front(killed);
432 if zle.killring.len() > zle.killringmax {
433 zle.killring.pop_back();
434 }
435 zle.resetneeded = true;
436 }
437}
438
439fn widget_yank(zle: &mut Zle) {
440 if let Some(text) = zle.killring.front().cloned() {
441 for c in text {
442 zle.zleline.insert(zle.zlecs, c);
443 zle.zlecs += 1;
444 zle.zlell += 1;
445 }
446 zle.resetneeded = true;
447 }
448}
449
450fn widget_yank_pop(zle: &mut Zle) {
451 if let Some(text) = zle.killring.pop_front() {
453 zle.killring.push_back(text);
454 }
455 }
457
458fn widget_undo(zle: &mut Zle) {
459 let _ = zle;
461}
462
463fn widget_redo(zle: &mut Zle) {
464 let _ = zle;
466}
467
468fn widget_up_line_or_history(zle: &mut Zle) {
469 let _ = zle;
471}
472
473fn widget_down_line_or_history(zle: &mut Zle) {
474 let _ = zle;
476}
477
478fn widget_up_history(zle: &mut Zle) {
479 let _ = zle;
481}
482
483fn widget_down_history(zle: &mut Zle) {
484 let _ = zle;
486}
487
488fn widget_history_isearch_backward(zle: &mut Zle) {
489 let _ = zle;
491}
492
493fn widget_history_isearch_forward(zle: &mut Zle) {
494 let _ = zle;
496}
497
498fn widget_beginning_of_buffer_or_history(zle: &mut Zle) {
499 zle.zlecs = 0;
500 zle.resetneeded = true;
501}
502
503fn widget_end_of_buffer_or_history(zle: &mut Zle) {
504 zle.zlecs = zle.zlell;
505 zle.resetneeded = true;
506}
507
508fn widget_transpose_chars(zle: &mut Zle) {
509 if zle.zlecs > 0 && zle.zlell >= 2 {
510 let pos = if zle.zlecs == zle.zlell {
511 zle.zlecs - 1
512 } else {
513 zle.zlecs
514 };
515 if pos > 0 {
516 zle.zleline.swap(pos - 1, pos);
517 zle.zlecs = pos + 1;
518 zle.resetneeded = true;
519 }
520 }
521}
522
523fn widget_clear_screen(zle: &mut Zle) {
524 print!("\x1b[2J\x1b[H");
525 zle.resetneeded = true;
526}
527
528fn widget_redisplay(zle: &mut Zle) {
529 zle.resetneeded = true;
530}
531
532fn widget_send_break(zle: &mut Zle) {
533 zle.send_break();
534}
535
536fn widget_overwrite_mode(zle: &mut Zle) {
537 zle.insmode = !zle.insmode;
538}
539
540fn widget_quoted_insert(zle: &mut Zle) {
541 if let Some(c) = zle.getfullchar(true) {
543 zle.self_insert(c);
544 }
545}
546
547fn widget_expand_or_complete(zle: &mut Zle) {
548 let _ = zle;
550}
551
552fn widget_complete_word(zle: &mut Zle) {
553 let _ = zle;
555}
556
557fn widget_expand_word(zle: &mut Zle) {
558 let _ = zle;
560}
561
562fn widget_list_choices(zle: &mut Zle) {
563 let _ = zle;
565}
566
567fn widget_menu_complete(zle: &mut Zle) {
568 let _ = zle;
570}
571
572fn widget_vi_cmd_mode(zle: &mut Zle) {
575 zle.keymaps.select("vicmd");
576 if zle.zlecs > 0 {
577 zle.zlecs -= 1;
578 }
579 zle.resetneeded = true;
580}
581
582fn widget_vi_insert(zle: &mut Zle) {
583 zle.keymaps.select("viins");
584 zle.insmode = true;
585}
586
587fn widget_vi_insert_bol(zle: &mut Zle) {
588 zle.keymaps.select("viins");
589 zle.insmode = true;
590 zle.zlecs = 0;
592 while zle.zlecs < zle.zlell && zle.zleline[zle.zlecs].is_whitespace() {
593 zle.zlecs += 1;
594 }
595 zle.resetneeded = true;
596}
597
598fn widget_vi_add_next(zle: &mut Zle) {
599 zle.keymaps.select("viins");
600 zle.insmode = true;
601 if zle.zlecs < zle.zlell {
602 zle.zlecs += 1;
603 }
604 zle.resetneeded = true;
605}
606
607fn widget_vi_add_eol(zle: &mut Zle) {
608 zle.keymaps.select("viins");
609 zle.insmode = true;
610 zle.zlecs = zle.zlell;
611 zle.resetneeded = true;
612}
613
614fn widget_vi_forward_char(zle: &mut Zle) {
615 if zle.zlecs < zle.zlell.saturating_sub(1) {
616 zle.zlecs += 1;
617 zle.resetneeded = true;
618 }
619}
620
621fn widget_vi_backward_char(zle: &mut Zle) {
622 if zle.zlecs > 0 {
623 zle.zlecs -= 1;
624 zle.resetneeded = true;
625 }
626}
627
628fn widget_vi_forward_word(zle: &mut Zle) {
629 widget_forward_word(zle);
630}
631
632fn widget_vi_forward_word_end(zle: &mut Zle) {
633 if zle.zlecs < zle.zlell {
634 zle.zlecs += 1;
635 }
636 while zle.zlecs < zle.zlell && !is_word_char(zle.zleline[zle.zlecs]) {
638 zle.zlecs += 1;
639 }
640 while zle.zlecs < zle.zlell.saturating_sub(1) && is_word_char(zle.zleline[zle.zlecs + 1]) {
642 zle.zlecs += 1;
643 }
644 zle.resetneeded = true;
645}
646
647fn widget_vi_forward_blank_word(zle: &mut Zle) {
648 while zle.zlecs < zle.zlell && !zle.zleline[zle.zlecs].is_whitespace() {
650 zle.zlecs += 1;
651 }
652 while zle.zlecs < zle.zlell && zle.zleline[zle.zlecs].is_whitespace() {
654 zle.zlecs += 1;
655 }
656 zle.resetneeded = true;
657}
658
659fn widget_vi_forward_blank_word_end(zle: &mut Zle) {
660 if zle.zlecs < zle.zlell {
661 zle.zlecs += 1;
662 }
663 while zle.zlecs < zle.zlell && zle.zleline[zle.zlecs].is_whitespace() {
665 zle.zlecs += 1;
666 }
667 while zle.zlecs < zle.zlell.saturating_sub(1) && !zle.zleline[zle.zlecs + 1].is_whitespace() {
669 zle.zlecs += 1;
670 }
671 zle.resetneeded = true;
672}
673
674fn widget_vi_backward_word(zle: &mut Zle) {
675 widget_backward_word(zle);
676}
677
678fn widget_vi_backward_blank_word(zle: &mut Zle) {
679 while zle.zlecs > 0 && zle.zleline[zle.zlecs - 1].is_whitespace() {
681 zle.zlecs -= 1;
682 }
683 while zle.zlecs > 0 && !zle.zleline[zle.zlecs - 1].is_whitespace() {
685 zle.zlecs -= 1;
686 }
687 zle.resetneeded = true;
688}
689
690fn widget_vi_delete(zle: &mut Zle) {
691 let _ = zle;
693}
694
695fn widget_vi_delete_char(zle: &mut Zle) {
696 widget_delete_char(zle);
697}
698
699fn widget_vi_backward_delete_char(zle: &mut Zle) {
700 widget_backward_delete_char(zle);
701}
702
703fn widget_vi_change(zle: &mut Zle) {
704 let _ = zle;
706}
707
708fn widget_vi_change_eol(zle: &mut Zle) {
709 widget_kill_line(zle);
710 widget_vi_insert(zle);
711}
712
713fn widget_vi_kill_eol(zle: &mut Zle) {
714 widget_kill_line(zle);
715}
716
717fn widget_vi_yank(zle: &mut Zle) {
718 let _ = zle;
720}
721
722fn widget_vi_yank_whole_line(zle: &mut Zle) {
723 zle.killring.push_front(zle.zleline.clone());
724 if zle.killring.len() > zle.killringmax {
725 zle.killring.pop_back();
726 }
727}
728
729fn widget_vi_put_after(zle: &mut Zle) {
730 if zle.zlecs < zle.zlell {
731 zle.zlecs += 1;
732 }
733 widget_yank(zle);
734}
735
736fn widget_vi_put_before(zle: &mut Zle) {
737 widget_yank(zle);
738}
739
740fn widget_vi_replace(zle: &mut Zle) {
741 zle.keymaps.select("viins");
742 zle.insmode = false;
743}
744
745fn widget_vi_replace_chars(zle: &mut Zle) {
746 if let Some(c) = zle.getfullchar(true) {
748 if zle.zlecs < zle.zlell {
749 zle.zleline[zle.zlecs] = c;
750 zle.resetneeded = true;
751 }
752 }
753}
754
755fn widget_vi_substitute(zle: &mut Zle) {
756 widget_delete_char(zle);
757 widget_vi_insert(zle);
758}
759
760fn widget_vi_change_whole_line(zle: &mut Zle) {
761 widget_kill_whole_line(zle);
762 widget_vi_insert(zle);
763}
764
765fn widget_vi_first_non_blank(zle: &mut Zle) {
766 zle.zlecs = 0;
767 while zle.zlecs < zle.zlell && zle.zleline[zle.zlecs].is_whitespace() {
768 zle.zlecs += 1;
769 }
770 zle.resetneeded = true;
771}
772
773fn widget_vi_end_of_line(zle: &mut Zle) {
774 if zle.zlell > 0 {
775 zle.zlecs = zle.zlell - 1;
776 }
777 zle.resetneeded = true;
778}
779
780fn widget_vi_digit_or_beginning_of_line(zle: &mut Zle) {
781 if zle.zmod.flags.contains(super::main::ModifierFlags::MULT) {
782 widget_digit_argument(zle);
783 } else {
784 widget_beginning_of_line(zle);
785 }
786}
787
788fn widget_vi_open_line_below(zle: &mut Zle) {
789 zle.zlecs = zle.zlell;
790 zle.self_insert('\n');
791 widget_vi_insert(zle);
792}
793
794fn widget_vi_open_line_above(zle: &mut Zle) {
795 zle.zlecs = 0;
796 zle.self_insert('\n');
797 zle.zlecs = 0;
798 widget_vi_insert(zle);
799}
800
801fn widget_vi_join(zle: &mut Zle) {
802 while zle.zlecs < zle.zlell {
804 if zle.zleline[zle.zlecs] == '\n' {
805 zle.zleline.remove(zle.zlecs);
806 zle.zlell -= 1;
807 if zle.zlecs > 0 && zle.zlecs < zle.zlell {
809 zle.zleline.insert(zle.zlecs, ' ');
810 zle.zlell += 1;
811 }
812 break;
813 }
814 zle.zlecs += 1;
815 }
816 zle.resetneeded = true;
817}
818
819fn widget_vi_repeat_change(zle: &mut Zle) {
820 let _ = zle;
822}
823
824fn widget_vi_find_next_char(zle: &mut Zle) {
825 let _ = zle;
827}
828
829fn widget_vi_find_prev_char(zle: &mut Zle) {
830 let _ = zle;
832}
833
834fn widget_vi_find_next_char_skip(zle: &mut Zle) {
835 let _ = zle;
837}
838
839fn widget_vi_find_prev_char_skip(zle: &mut Zle) {
840 let _ = zle;
842}
843
844fn widget_vi_repeat_find(zle: &mut Zle) {
845 let _ = zle;
847}
848
849fn widget_vi_rev_repeat_find(zle: &mut Zle) {
850 let _ = zle;
852}
853
854fn widget_vi_history_search_forward(zle: &mut Zle) {
855 let _ = zle;
857}
858
859fn widget_vi_history_search_backward(zle: &mut Zle) {
860 let _ = zle;
862}
863
864fn widget_vi_repeat_search(zle: &mut Zle) {
865 let _ = zle;
867}
868
869fn widget_vi_rev_repeat_search(zle: &mut Zle) {
870 let _ = zle;
872}
873
874fn widget_vi_fetch_history(zle: &mut Zle) {
875 let _ = zle;
877}
878
879fn widget_vi_goto_column(zle: &mut Zle) {
880 let col = zle.zmod.mult.saturating_sub(1) as usize;
881 zle.zlecs = col.min(zle.zlell);
882 zle.resetneeded = true;
883}
884
885fn widget_vi_backward_kill_word(zle: &mut Zle) {
886 widget_backward_kill_word(zle);
887}
888
889fn widget_digit_argument(zle: &mut Zle) {
890 let digit = (zle.lastchar as u8).saturating_sub(b'0') as i32;
891
892 if zle.zmod.flags.contains(super::main::ModifierFlags::TMULT) {
893 zle.zmod.tmult = zle.zmod.tmult * zle.zmod.base + digit;
894 } else {
895 zle.zmod.flags.insert(super::main::ModifierFlags::TMULT);
896 zle.zmod.tmult = digit;
897 }
898
899 zle.prefixflag = true;
900}
901
902fn widget_undefined(zle: &mut Zle) {
903 let _ = zle;
905}
906
907fn is_word_char(c: char) -> bool {
909 c.is_alphanumeric() || c == '_'
910}