highlight filter keywords

pull/34/head
Takayuki Maeda 3 years ago
parent 07b2b5090f
commit cfc46cddac

1
.gitignore vendored

@ -2,3 +2,4 @@
gobang
gobang.yml
gobang.log
src

@ -123,6 +123,81 @@ impl App {
res
}
async fn update_databases(&mut self) -> anyhow::Result<()> {
if let Some(conn) = self.connections.selected_connection() {
if let Some(pool) = self.pool.as_ref() {
pool.close().await;
}
self.pool = Some(Box::new(
MySqlPool::new(conn.database_url().as_str()).await?,
));
let databases = match &conn.database {
Some(database) => vec![Database::new(
database.clone(),
self.pool
.as_ref()
.unwrap()
.get_tables(database.clone())
.await?,
)],
None => self.pool.as_ref().unwrap().get_databases().await?,
};
self.databases.update(databases.as_slice()).unwrap();
self.focus = Focus::DabataseList;
self.record_table.reset();
}
Ok(())
}
async fn update_table(&mut self) -> anyhow::Result<()> {
if let Some((database, table)) = self.databases.tree().selected_table() {
self.focus = Focus::Table;
let (headers, records) = self
.pool
.as_ref()
.unwrap()
.get_records(&database.name, &table.name, 0, None)
.await?;
self.record_table
.update(records, headers, database.clone(), table.clone());
let (headers, records) = self
.pool
.as_ref()
.unwrap()
.get_columns(&database.name, &table.name)
.await?;
self.structure_table
.update(records, headers, database.clone(), table.clone());
self.table_status
.update(self.record_table.len() as u64, table);
}
Ok(())
}
async fn update_record_table(&mut self) -> anyhow::Result<()> {
if let Some((database, table)) = self.databases.tree().selected_table() {
let (headers, records) = self
.pool
.as_ref()
.unwrap()
.get_records(
&database.name,
&table.name,
0,
if self.record_table.filter.input.is_empty() {
None
} else {
Some(self.record_table.filter.input_str())
},
)
.await?;
self.record_table
.update(records, headers, database.clone(), table.clone());
}
Ok(())
}
pub async fn event(&mut self, key: Key) -> anyhow::Result<EventState> {
self.update_commands();
@ -152,28 +227,7 @@ impl App {
}
if key == self.config.key_config.enter {
if let Some(conn) = self.connections.selected_connection() {
if let Some(pool) = self.pool.as_ref() {
pool.close().await;
}
self.pool = Some(Box::new(
MySqlPool::new(conn.database_url().as_str()).await?,
));
let databases = match &conn.database {
Some(database) => vec![Database::new(
database.clone(),
self.pool
.as_ref()
.unwrap()
.get_tables(database.clone())
.await?,
)],
None => self.pool.as_ref().unwrap().get_databases().await?,
};
self.databases.update(databases.as_slice()).unwrap();
self.focus = Focus::DabataseList;
self.record_table.reset();
}
self.update_databases().await?;
return Ok(EventState::Consumed);
}
}
@ -183,32 +237,7 @@ impl App {
}
if key == self.config.key_config.enter && self.databases.tree_focused() {
if let Some((database, table)) = self.databases.tree().selected_table() {
self.focus = Focus::Table;
let (headers, records) = self
.pool
.as_ref()
.unwrap()
.get_records(&database.name, &table.name, 0, None)
.await?;
self.record_table
.update(records, headers, database.clone(), table.clone());
let (headers, records) = self
.pool
.as_ref()
.unwrap()
.get_columns(&database.name, &table.name)
.await?;
self.structure_table.update(
records,
headers,
database.clone(),
table.clone(),
);
self.table_status
.update(self.record_table.len() as u64, table);
}
self.update_table().await?;
return Ok(EventState::Consumed);
}
}
@ -228,25 +257,7 @@ impl App {
if key == self.config.key_config.enter && self.record_table.filter_focused()
{
self.record_table.focus = crate::components::record_table::Focus::Table;
if let Some((database, table)) = self.databases.tree().selected_table()
{
let (headers, records) = self
.pool
.as_ref()
.unwrap()
.get_records(
&database.name.clone(),
&table.name,
0,
if self.record_table.filter.input.is_empty() {
None
} else {
Some(self.record_table.filter.input_str())
},
)
.await?;
self.record_table.update(records, headers, database, table);
}
self.update_record_table().await?;
}
if self.record_table.table.eod {

@ -15,7 +15,7 @@ use tui::{
backend::Backend,
layout::{Constraint, Direction, Layout, Rect},
style::{Color, Style},
text::Span,
text::{Span, Spans},
widgets::{Block, Borders, Paragraph},
Frame,
};
@ -67,6 +67,7 @@ impl DatabasesComponent {
self.filterd_tree = None;
self.input = Vec::new();
self.input_idx = 0;
self.input_cursor_position = 0;
Ok(())
}
@ -78,7 +79,12 @@ impl DatabasesComponent {
self.filterd_tree.as_ref().unwrap_or(&self.tree)
}
fn tree_item_to_span(item: DatabaseTreeItem, selected: bool, width: u16) -> Span<'static> {
fn tree_item_to_span(
item: DatabaseTreeItem,
selected: bool,
width: u16,
filter: Option<String>,
) -> Spans<'static> {
let name = item.kind().name();
let indent = item.info().indent();
@ -99,21 +105,53 @@ impl DatabasesComponent {
EMPTY_STR
};
let name = format!(
"{}{}{:w$}",
indent_str,
path_arrow,
name,
w = width as usize
);
Span::styled(
name,
if let Some(filter) = filter {
if item.kind().is_table() {
let (first, second) = &name.split_at(name.find(filter.as_str()).unwrap_or(0));
let (filter, third) = &second.split_at(filter.len());
return Spans::from(vec![
Span::styled(
format!("{}{}{}", indent_str, path_arrow, first),
if selected {
Style::default().bg(Color::Blue)
} else {
Style::default()
},
),
Span::styled(
filter.to_string(),
if selected {
Style::default().bg(Color::Blue).fg(Color::Blue)
} else {
Style::default().fg(Color::Blue)
},
),
Span::styled(
format!("{}{:w$}", third.to_string(), w = width as usize),
if selected {
Style::default().bg(Color::Blue)
} else {
Style::default()
},
),
]);
}
}
Spans::from(Span::styled(
format!(
"{}{}{:w$}",
indent_str,
path_arrow,
name,
w = width as usize
),
if selected {
Style::default().bg(Color::Blue)
} else {
Style::default()
},
)
))
}
fn draw_tree<B: Backend>(&self, f: &mut Frame<B>, area: Rect, focused: bool) {
@ -173,7 +211,18 @@ impl DatabasesComponent {
let items = tree
.iterate(self.scroll.get_top(), tree_height)
.map(|(item, selected)| Self::tree_item_to_span(item.clone(), selected, area.width));
.map(|(item, selected)| {
Self::tree_item_to_span(
item.clone(),
selected,
area.width,
if self.input.is_empty() {
None
} else {
Some(self.input_str())
},
)
});
draw_list_block(f, chunks[1], Block::default().borders(Borders::NONE), items);
self.scroll.draw(f, area);

@ -4,7 +4,7 @@ use tui::{
buffer::Buffer,
layout::Rect,
style::Style,
text::Span,
text::{Span, Spans},
widgets::{Block, List, ListItem, Widget},
Frame,
};
@ -12,7 +12,7 @@ use tui::{
///
struct ScrollableList<'b, L>
where
L: Iterator<Item = Span<'b>>,
L: Iterator<Item = Spans<'b>>,
{
block: Option<Block<'b>>,
/// Items to be displayed
@ -23,7 +23,7 @@ where
impl<'b, L> ScrollableList<'b, L>
where
L: Iterator<Item = Span<'b>>,
L: Iterator<Item = Spans<'b>>,
{
fn new(items: L) -> Self {
Self {
@ -41,7 +41,7 @@ where
impl<'b, L> Widget for ScrollableList<'b, L>
where
L: Iterator<Item = Span<'b>>,
L: Iterator<Item = Spans<'b>>,
{
fn render(self, area: Rect, buf: &mut Buffer) {
// Render items
@ -54,7 +54,7 @@ where
pub fn draw_list_block<'b, B: Backend, L>(f: &mut Frame<B>, r: Rect, block: Block<'b>, items: L)
where
L: Iterator<Item = Span<'b>>,
L: Iterator<Item = Spans<'b>>,
{
let list = ScrollableList::new(items).block(block);
f.render_widget(list, r);

Loading…
Cancel
Save