1
0
зеркало из https://github.com/glebtv/tui-textarea.git synced 2026-09-07 16:05:50 +03:00

support hard tab indent by TextArea::set_hard_tab

Этот коммит содержится в:
rhysd
2022-06-22 09:01:22 +09:00
родитель fdd48efb39
Коммит 08bcc50e11
2 изменённых файлов: 66 добавлений и 10 удалений

Просмотреть файл

@@ -18,11 +18,8 @@ use tui::Terminal;
use tui_textarea::{Input, Key, TextArea}; use tui_textarea::{Input, Key, TextArea};
macro_rules! error { macro_rules! error {
($fmt: expr, $($args:tt),+) => {{ ($fmt: expr $(, $args:tt)*) => {{
Err(io::Error::new(io::ErrorKind::Other, format!($fmt, $($args),+))) Err(io::Error::new(io::ErrorKind::Other, format!($fmt $(, $args)*)))
}};
($msg: expr) => {{
Err(io::Error::new(io::ErrorKind::Other, $msg))
}}; }};
} }
@@ -36,14 +33,17 @@ impl<'a> Buffer<'a> {
fn new(path: PathBuf) -> io::Result<Self> { fn new(path: PathBuf) -> io::Result<Self> {
let mut textarea = if let Ok(md) = path.metadata() { let mut textarea = if let Ok(md) = path.metadata() {
if md.is_file() { if md.is_file() {
io::BufReader::new(fs::File::open(&path)?) let mut textarea: TextArea = io::BufReader::new(fs::File::open(&path)?)
.lines() .lines()
.collect::<Result<_, _>>()? .collect::<Result<_, _>>()?;
let hard_tab = textarea.lines().iter().any(|l| l.starts_with('\t'));
textarea.set_hard_tab(hard_tab);
textarea
} else { } else {
return error!("{:?} is not a file", path); return error!("{:?} is not a file", path);
} }
} else { } else {
TextArea::default() TextArea::default() // File does not exist
}; };
textarea.set_line_number_style(Style::default().fg(Color::DarkGray)); textarea.set_line_number_style(Style::default().fg(Color::DarkGray));
Ok(Self { Ok(Self {

Просмотреть файл

@@ -41,6 +41,7 @@ pub struct TextArea<'a> {
style: Style, style: Style,
cursor: (usize, usize), // 0-base cursor: (usize, usize), // 0-base
tab_len: u8, tab_len: u8,
hard_tab: bool,
history: History, history: History,
cursor_line_style: Style, cursor_line_style: Style,
line_number_style: Option<Style>, line_number_style: Option<Style>,
@@ -134,6 +135,7 @@ impl<'a> TextArea<'a> {
style: Style::default(), style: Style::default(),
cursor: (0, 0), cursor: (0, 0),
tab_len: 4, tab_len: 4,
hard_tab: false,
history: History::new(50), history: History::new(50),
cursor_line_style: Style::default().add_modifier(Modifier::UNDERLINED), cursor_line_style: Style::default().add_modifier(Modifier::UNDERLINED),
line_number_style: None, line_number_style: None,
@@ -619,8 +621,13 @@ impl<'a> TextArea<'a> {
if self.tab_len == 0 { if self.tab_len == 0 {
return false; return false;
} }
let len = self.tab_len - (self.cursor.1 % self.tab_len as usize) as u8; let tab = if self.hard_tab {
self.insert_str(spaces(len)) "\t"
} else {
let len = self.tab_len - (self.cursor.1 % self.tab_len as usize) as u8;
spaces(len)
};
self.insert_str(tab)
} }
/// Insert a newline at current cursor position. /// Insert a newline at current cursor position.
@@ -1079,6 +1086,55 @@ impl<'a> TextArea<'a> {
self.tab_len self.tab_len
} }
/// Set if a hard tab is used or not for indent. When `true` is set, typing a tab key inserts a hard tab instead of
/// spaces. By default, hard tab is disabled.
/// ```
/// use tui_textarea::TextArea;
///
/// let mut textarea = TextArea::default();
///
/// textarea.set_hard_tab(true);
/// textarea.insert_tab();
/// assert_eq!(textarea.lines(), ["\t"]);
/// ```
pub fn set_hard_tab(&mut self, enabled: bool) {
self.hard_tab = enabled;
}
/// Get if a hard tab is used for indent or not.
/// ```
/// use tui_textarea::TextArea;
///
/// let mut textarea = TextArea::default();
///
/// assert!(!textarea.hard_tab());
/// textarea.set_hard_tab(true);
/// assert!(textarea.hard_tab());
/// ```
pub fn hard_tab(&self) -> bool {
self.hard_tab
}
/// Get a string for indent. It consists of spaces by default. When hard tab is enabled, it is a tab character.
/// ```
/// use tui_textarea::TextArea;
///
/// let mut textarea = TextArea::default();
///
/// assert_eq!(textarea.indent(), " ");
/// textarea.set_tab_length(2);
/// assert_eq!(textarea.indent(), " ");
/// textarea.set_hard_tab(true);
/// assert_eq!(textarea.indent(), "\t");
/// ```
pub fn indent(&self) -> &'static str {
if self.hard_tab {
"\t"
} else {
spaces(self.tab_len)
}
}
/// Set how many modifications are remembered for undo/redo. Setting 0 disables undo/redo. /// Set how many modifications are remembered for undo/redo. Setting 0 disables undo/redo.
pub fn set_max_histories(&mut self, max: usize) { pub fn set_max_histories(&mut self, max: usize) {
self.history = History::new(max); self.history = History::new(max);