ui/text_editing: add Ctrl-{f,b,u} readline shortcuts
parent
3dc0cb1963
commit
9a516e0663
|
@ -128,7 +128,7 @@ impl Component for Field {
|
||||||
if let UIEvent::InsertInput(Key::Char('\t')) = event {
|
if let UIEvent::InsertInput(Key::Char('\t')) = event {
|
||||||
if let Some(suggestion) = auto_complete.get_suggestion() {
|
if let Some(suggestion) = auto_complete.get_suggestion() {
|
||||||
*s = UText::new(suggestion);
|
*s = UText::new(suggestion);
|
||||||
let len = s.as_str().len().saturating_sub(1);
|
let len = s.as_str().len();
|
||||||
s.set_cursor(len);
|
s.set_cursor(len);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -199,6 +199,43 @@ impl Component for Field {
|
||||||
s.set_cursor(0);
|
s.set_cursor(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UIEvent::InsertInput(Key::Ctrl('b')) => {
|
||||||
|
/* Backward one character */
|
||||||
|
if let Text(ref mut s, _) = self {
|
||||||
|
s.cursor_dec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UIEvent::InsertInput(Key::Ctrl('f')) => {
|
||||||
|
/* Forward one character */
|
||||||
|
if let Text(ref mut s, _) = self {
|
||||||
|
s.cursor_inc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UIEvent::InsertInput(Key::Ctrl('w')) => {
|
||||||
|
// FIXME: Use Unicode word-breaking algorithm.
|
||||||
|
/* Cut previous word */
|
||||||
|
if let Text(ref mut s, _) = self {
|
||||||
|
while s.as_str()[..s.cursor_pos()]
|
||||||
|
.last_grapheme()
|
||||||
|
.map(|(_, graph)| !graph.is_empty() && graph.trim().is_empty())
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
s.backspace();
|
||||||
|
}
|
||||||
|
while s.as_str()[..s.cursor_pos()]
|
||||||
|
.last_grapheme()
|
||||||
|
.map(|(_, graph)| !graph.is_empty() && !graph.trim().is_empty())
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
s.backspace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UIEvent::InsertInput(Key::Ctrl('u')) => {
|
||||||
|
if let Text(ref mut s, _) = self {
|
||||||
|
s.cut_left()
|
||||||
|
}
|
||||||
|
}
|
||||||
UIEvent::InsertInput(Key::Ctrl('e')) => {
|
UIEvent::InsertInput(Key::Ctrl('e')) => {
|
||||||
if let Text(ref mut s, _) = self {
|
if let Text(ref mut s, _) = self {
|
||||||
s.set_cursor(s.as_str().len());
|
s.set_cursor(s.as_str().len());
|
||||||
|
|
|
@ -89,6 +89,10 @@ impl UText {
|
||||||
* self.cursor_pos
|
* self.cursor_pos
|
||||||
*/
|
*/
|
||||||
pub fn insert_char(&mut self, k: char) {
|
pub fn insert_char(&mut self, k: char) {
|
||||||
|
if k.is_control() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.content.insert(self.cursor_pos, k);
|
self.content.insert(self.cursor_pos, k);
|
||||||
self.cursor_pos += k.len_utf8();
|
self.cursor_pos += k.len_utf8();
|
||||||
self.grapheme_cursor_pos += 1;
|
self.grapheme_cursor_pos += 1;
|
||||||
|
@ -132,4 +136,19 @@ impl UText {
|
||||||
|
|
||||||
self.content.drain(offset..offset + graph_len).count();
|
self.content.drain(offset..offset + graph_len).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cut_left(&mut self) {
|
||||||
|
if self.content.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let offset = {
|
||||||
|
let (left, _) = self.content.split_at(self.cursor_pos);
|
||||||
|
left.last_grapheme()
|
||||||
|
.map(|(offset, graph)| offset + graph.len())
|
||||||
|
.unwrap_or(0)
|
||||||
|
};
|
||||||
|
self.cursor_pos = 0;
|
||||||
|
self.grapheme_cursor_pos = 0;
|
||||||
|
self.content.drain(..offset).count();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue