1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//! ZLE thingies - named bindings to widgets
//!
//! Direct port from zsh/Src/Zle/zle_keymap.c thingy structures
//!
//! A "thingy" is a named entity that refers to a widget. Multiple thingies
//! can refer to the same widget. Thingies are reference-counted.
use std::sync::Arc;
use super::widget::Widget;
/// Flags for thingies
#[derive(Debug, Clone, Copy, Default)]
pub struct ThingyFlags {
/// Thingy is disabled
pub disabled: bool,
/// Can't refer to a different widget
pub immortal: bool,
}
/// A thingy - a named reference to a widget
#[derive(Debug, Clone)]
pub struct Thingy {
/// Name of the thingy
pub name: String,
/// Flags
pub flags: ThingyFlags,
/// Reference count (for compatibility, though Arc handles this)
pub rc: i32,
/// Widget this thingy refers to
pub widget: Option<Arc<Widget>>,
}
impl Thingy {
/// Create a thingy with no widget bound — equivalent to a freshly
/// allocated entry from `makethingynode()` in
/// Src/Zle/zle_thingy.c:108. Callers fill in `widget` later via
/// `bindwidget` (zle_thingy.c:199).
pub fn new(name: &str) -> Self {
Thingy {
name: name.to_string(),
flags: ThingyFlags::default(),
rc: 1,
widget: None,
}
}
/// Create a thingy that wraps a built-in widget.
/// Equivalent to the `addzlefunction()` path at
/// Src/Zle/zle_thingy.c:281: builds the immortal-flagged Thingy
/// and binds it to a Widget produced by the built-in dispatch
/// table (`Widget::builtin`).
pub fn builtin(name: &str) -> Self {
let widget = Widget::builtin(name);
Thingy {
name: name.to_string(),
flags: ThingyFlags {
disabled: false,
immortal: true,
},
rc: 1,
widget: Some(Arc::new(widget)),
}
}
/// Create a thingy that wraps a user-defined shell function.
/// Equivalent to `bin_zle_new()` at Src/Zle/zle_thingy.c:584 — the
/// `zle -N name fn` builtin path.
pub fn user_defined(name: &str, func_name: &str) -> Self {
let widget = Widget::user_defined(name, func_name);
Thingy {
name: name.to_string(),
flags: ThingyFlags::default(),
rc: 1,
widget: Some(Arc::new(widget)),
}
}
/// Test whether this thingy's name matches `name`.
/// Equivalent to the `IS_THINGY(thingy, name)` macro at
/// Src/Zle/zle.h — used by widget bodies that special-case their
/// own bound name (e.g. select-a-word checking which alias fired).
pub fn is(&self, name: &str) -> bool {
self.name == name
}
/// Test whether this thingy is `name` or its dot-prefixed variant.
/// The `.foo` form names the underlying built-in when a user has
/// aliased `foo` to something else — see `bin_zle_new`'s args[0]
/// vs args[1] split at zle_thingy.c:584. Callers use this when
/// they want the canonical built-in regardless of user aliasing.
pub fn is_thingy(&self, name: &str) -> bool {
self.name == name || self.name == format!(".{}", name)
}
}
/// Standard thingy names used throughout ZLE
pub mod names {
/// Accept and execute a line
pub const ACCEPT_LINE: &str = "accept-line";
/// Send break (abort)
pub const SEND_BREAK: &str = "send-break";
/// Insert character
pub const SELF_INSERT: &str = "self-insert";
/// Delete character or list completions
pub const DELETE_CHAR_OR_LIST: &str = "delete-char-or-list";
/// Backward delete character
pub const BACKWARD_DELETE_CHAR: &str = "backward-delete-char";
/// Move backward one character
pub const BACKWARD_CHAR: &str = "backward-char";
/// Move forward one character
pub const FORWARD_CHAR: &str = "forward-char";
/// Move to beginning of line
pub const BEGINNING_OF_LINE: &str = "beginning-of-line";
/// Move to end of line
pub const END_OF_LINE: &str = "end-of-line";
/// Move backward one word
pub const BACKWARD_WORD: &str = "backward-word";
/// Move forward one word
pub const FORWARD_WORD: &str = "forward-word";
/// Kill to end of line
pub const KILL_LINE: &str = "kill-line";
/// Kill whole line
pub const KILL_WHOLE_LINE: &str = "kill-whole-line";
/// Kill word forward
pub const KILL_WORD: &str = "kill-word";
/// Kill word backward
pub const BACKWARD_KILL_WORD: &str = "backward-kill-word";
/// Yank from kill ring
pub const YANK: &str = "yank";
/// Undo
pub const UNDO: &str = "undo";
/// Redo
pub const REDO: &str = "redo";
/// Clear screen
pub const CLEAR_SCREEN: &str = "clear-screen";
/// Expand or complete
pub const EXPAND_OR_COMPLETE: &str = "expand-or-complete";
/// History search backward
pub const HISTORY_INCREMENTAL_SEARCH_BACKWARD: &str = "history-incremental-search-backward";
/// History search forward
pub const HISTORY_INCREMENTAL_SEARCH_FORWARD: &str = "history-incremental-search-forward";
/// Up line or history
pub const UP_LINE_OR_HISTORY: &str = "up-line-or-history";
/// Down line or history
pub const DOWN_LINE_OR_HISTORY: &str = "down-line-or-history";
/// Transpose characters
pub const TRANSPOSE_CHARS: &str = "transpose-chars";
/// Delete character
pub const DELETE_CHAR: &str = "delete-char";
/// Vi command mode
pub const VI_CMD_MODE: &str = "vi-cmd-mode";
/// Vi insert mode
pub const VI_INSERT: &str = "vi-insert";
}