text: String,
paste_buffer: String,
point: usize,
+ secret: bool,
}
impl EditorCore {
None => None,
Some(c) => {
let width = UnicodeWidthChar::width(c).unwrap_or(0);
+ let width = if self.secret { min(width, 1) } else { width };
let mut end = pos + 1;
while !self.is_char_boundary(end) {
end += 1;
}
}
+ fn char_at(&self, start: usize, end: usize) -> &str {
+ if self.secret {
+ "*"
+ } else {
+ &self.text[start..end]
+ }
+ }
+
fn is_word_sep(c: char) -> bool {
c == ' '
}
text: "héllo, wørld".to_owned(),
point: 0,
paste_buffer: "".to_owned(),
+ secret: false,
};
assert!(ec.forward());
text: "lorem ipsum dolor sit amet".to_owned(),
point: 0,
paste_buffer: "".to_owned(),
+ secret: false,
};
assert!(ec.forward_word());
text: "hélło".to_owned(),
point: 3,
paste_buffer: "".to_owned(),
+ secret: false,
};
ec.delete_forward();
text: "hélło".to_owned(),
point: 3,
paste_buffer: "".to_owned(),
+ secret: false,
};
ec.insert("PÏNG");
text,
point,
paste_buffer: "".to_owned(),
+ secret: false,
},
width: 0,
first_visible: 0,
break;
} else {
s.push_str(ColouredString::plain(
- &self.core.text[pos..pos + b],
+ &self.core.char_at(pos, pos + b),
));
pos += b;
}
text: "hélło".to_owned(),
point: 3,
paste_buffer: "".to_owned(),
+ secret: false,
},
width: 0,
first_visible: 0,
text: "".to_owned(),
point: 0,
paste_buffer: "".to_owned(),
+ secret: false,
},
width: 5,
first_visible: 0,
}
pub trait EditableMenuLineData {
+ // If SECRET, then the implementor of this trait promises that
+ // display() will show the text as ***** when it's not being
+ // edited, and instructs the SingleLineEditor to do the same
+ // during editing.
+ //
+ // display() can use the helper function count_edit_chars to help
+ // it figure out how many * to display.
+ const SECRET: bool = false;
+
fn display(&self) -> ColouredString;
fn to_text(&self) -> String;
fn from_text(text: &str) -> Self;
last_width: Option<usize>,
}
+pub fn count_edit_chars(text: &str) -> usize {
+ text.chars()
+ .map(|c| UnicodeWidthChar::width(c).unwrap_or(0) > 0)
+ .count()
+}
+
impl<Data: EditableMenuLineData> EditableMenuLine<Data> {
pub fn new(key: OurKey, description: ColouredString, data: Data) -> Self {
let menuline = Self::make_menuline(key, &description, &data);
// Returns a LogicalAction just to make it more convenient to put
// in matches on keypresses
pub fn start_editing(&mut self) -> LogicalAction {
- self.editor = Some(SingleLineEditor::new(self.data.to_text()));
+ let mut editor = SingleLineEditor::new(self.data.to_text());
+ editor.core.secret = Data::SECRET;
+ self.editor = Some(editor);
self.refresh_editor_prompt();
LogicalAction::Nothing
}
text: post.text,
point,
paste_buffer: "".to_owned(),
+ secret: false,
},
regions: Vec::new(),
layout: Vec::new(),