Skip to content

Commit

Permalink
merge my PRs
Browse files Browse the repository at this point in the history
  • Loading branch information
kyoto7250 committed Jun 16, 2024
1 parent 5f815bb commit eeb17bd
Show file tree
Hide file tree
Showing 20 changed files with 1,088 additions and 64 deletions.
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ clap = "4.5.7"
structopt = "0.3.26"
syntect = { version = "5.0", default-features = false, features = ["metadata", "default-fancy"]}
unicode-segmentation = "1.11.0"
ron = "0.8.1"

[target.'cfg(all(target_family="unix",not(target_os="macos")))'.dependencies]
which = "6.0.1"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# dolce
# zhobo

`dolce` is the rebaked [gobang project](https://github.com/TaKO8Ki/gobang).
`zhobo` is the rebaked [gobang project](https://github.com/TaKO8Ki/gobang).

## Features
- Cross-platform support (macOS, Windows, Linux)
Expand Down
26 changes: 26 additions & 0 deletions examples/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[[conn]]
type = "mysql"
user = "root"
host = "localhost"
port = 3306

[[conn]]
type = "mysql"
user = "root"
host = "localhost"
port = 3306
password = "password"
database = "foo"
name = "mysql Foo DB"

[[conn]]
type = "postgres"
user = "root"
host = "localhost"
port = 5432
database = "bar"
name = "postgres Bar DB"

[[conn]]
type = "sqlite"
path = "/path/to/baz.db"
44 changes: 44 additions & 0 deletions examples/key_bind.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* This file is a custom key configuration file.
* Place this file in `$HOME/.config/zhobo/key_bind.ron`.
*/
(
scroll_up: Some(Char('k')),
scroll_down: Some(Char('j')),
scroll_right: Some(Char('l')),
scroll_left: Some(Char('h')),
sort_by_column: Some(Char('s')),
move_up: Some(Up),
move_down: Some(Down),
copy: Some(Char('y')),
enter: Some(Enter),
exit: Some(Ctrl('c')),
quit: Some(Char('q')),
exit_popup: Some(Esc),
focus_right: Some(Right),
focus_left: Some(Left),
focus_above: Some(Up),
focus_connections: Some(Char('c')),
open_help: Some(Char('?')),
filter: Some(Char('/')),
scroll_down_multiple_lines: Some(Ctrl('d')),
scroll_up_multiple_lines: Some(Ctrl('u')),
scroll_to_top: Some(Char('g')),
scroll_to_bottom: Some(Char('G')),
move_to_head_of_line: Some(Char('^')),
move_to_tail_of_line: Some(Char('$')),
extend_selection_by_one_cell_left: Some(Char('H')),
extend_selection_by_one_cell_right: Some(Char('L')),
extend_selection_by_one_cell_down: Some(Char('J')),
extend_selection_by_horizontal_line: Some(Char('V')),
extend_selection_by_one_cell_up: Some(Char('K')),
tab_records: Some(Char('1')),
tab_properties: Some(Char('2')),
tab_sql_editor: Some(Char('3')),
tab_columns: Some(Char('4')),
tab_constraints: Some(Char('5')),
tab_foreign_keys: Some(Char('6')),
tab_indexes: Some(Char('7')),
extend_or_shorten_widget_width_to_right: Some(Char('>')),
extend_or_shorten_widget_width_to_left: Some(Char('<')),
)
87 changes: 80 additions & 7 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::components::{
use crate::config::Config;
use crate::database::{MySqlPool, Pool, PostgresPool, SqlitePool, RECORDS_LIMIT_PER_PAGE};
use crate::event::Key;
use ratatui::layout::Flex;
use ratatui::{
layout::{Constraint, Direction, Layout, Rect},
Frame,
Expand Down Expand Up @@ -82,6 +83,7 @@ impl App {

let right_chunks = Layout::default()
.direction(Direction::Vertical)
.flex(Flex::Legacy)
.constraints([Constraint::Length(3), Constraint::Length(5)].as_ref())
.split(main_chunks[1]);

Expand Down Expand Up @@ -139,6 +141,7 @@ impl App {
if let Some(pool) = self.pool.as_ref() {
pool.close().await;
}

self.pool = if conn.is_mysql() {
Some(Box::new(
MySqlPool::new(conn.database_url()?.as_str()).await?,
Expand All @@ -162,7 +165,12 @@ impl App {
Ok(())
}

async fn update_record_table(&mut self) -> anyhow::Result<()> {
async fn update_record_table(
&mut self,
orders: Option<String>,
header_icons: Option<Vec<String>>,
hold_cursor_position: bool,
) -> anyhow::Result<()> {
if let Some((database, table)) = self.databases.tree().selected_table() {
let (headers, records) = self
.pool
Expand All @@ -177,10 +185,16 @@ impl App {
} else {
Some(self.record_table.filter.input_str())
},
orders,
)
.await?;
self.record_table
.update(records, headers, database.clone(), table.clone());
self.record_table.update(
records,
self.concat_headers(headers, header_icons),
database.clone(),
table.clone(),
hold_cursor_position,
);
}
Ok(())
}
Expand Down Expand Up @@ -230,10 +244,15 @@ impl App {
.pool
.as_ref()
.unwrap()
.get_records(&database, &table, 0, None)
.get_records(&database, &table, 0, None, None)
.await?;
self.record_table
.update(records, headers, database.clone(), table.clone());
self.record_table.update(
records,
headers,
database.clone(),
table.clone(),
false,
);
self.properties
.update(database.clone(), table.clone(), self.pool.as_ref().unwrap())
.await?;
Expand All @@ -249,6 +268,17 @@ impl App {
return Ok(EventState::Consumed);
};

if key == self.config.key_config.sort_by_column
&& !self.record_table.table.headers.is_empty()
{
self.record_table.table.add_order();
let order_query = self.record_table.table.generate_order_query();
let header_icons = self.record_table.table.generate_header_icons();
self.update_record_table(order_query, Some(header_icons), true)
.await?;
return Ok(EventState::Consumed);
};

if key == self.config.key_config.copy {
if let Some(text) = self.record_table.table.selected_cells() {
copy_to_clipboard(text.as_str())?
Expand All @@ -258,7 +288,10 @@ impl App {
if key == self.config.key_config.enter && self.record_table.filter_focused()
{
self.record_table.focus = crate::components::record_table::Focus::Table;
self.update_record_table().await?;
let order_query = self.record_table.table.generate_order_query();
let header_icons = self.record_table.table.generate_header_icons();
self.update_record_table(order_query, Some(header_icons), false)
.await?;
}

if self.record_table.table.eod {
Expand All @@ -283,6 +316,7 @@ impl App {
} else {
Some(self.record_table.filter.input_str())
},
None,
)
.await?;
if !records.is_empty() {
Expand Down Expand Up @@ -321,6 +355,24 @@ impl App {
Ok(EventState::NotConsumed)
}

fn concat_headers(
&self,
headers: Vec<String>,
header_icons: Option<Vec<String>>,
) -> Vec<String> {
if let Some(header_icons) = &header_icons {
let mut new_headers = vec![String::new(); headers.len()];
for (index, header) in headers.iter().enumerate() {
new_headers[index] = format!("{} {}", header, header_icons[index])
.trim()
.to_string();
}
return new_headers;
}

headers
}

fn extend_or_shorten_widget_width(&mut self, key: Key) -> anyhow::Result<EventState> {
if key
== self
Expand Down Expand Up @@ -408,4 +460,25 @@ mod test {
);
assert_eq!(app.left_main_chunk_percentage, 15);
}

#[test]
fn test_concat_headers() {
let app = App::new(Config::default());
let headers = vec![
"ID".to_string(),
"NAME".to_string(),
"TIMESTAMP".to_string(),
];
let header_icons = vec!["".to_string(), "↑1".to_string(), "↓2".to_string()];
let concat_headers: Vec<String> = app.concat_headers(headers, Some(header_icons));

assert_eq!(
concat_headers,
vec![
"ID".to_string(),
"NAME ↑1".to_string(),
"TIMESTAMP ↓2".to_string()
]
)
}
}
27 changes: 27 additions & 0 deletions src/components/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ pub fn scroll_to_top_bottom(key: &KeyConfig) -> CommandText {
)
}

pub fn move_to_head_tail_of_line(key: &KeyConfig) -> CommandText {
CommandText::new(
format!(
"Move to head/tail of line [{},{}]",
key.move_to_head_of_line, key.move_to_tail_of_line,
),
CMD_GROUP_TABLE,
)
}

pub fn expand_collapse(key: &KeyConfig) -> CommandText {
CommandText::new(
format!("Expand/Collapse [{},{}]", key.scroll_right, key.scroll_left,),
Expand All @@ -83,6 +93,13 @@ pub fn move_focus(key: &KeyConfig) -> CommandText {
)
}

pub fn sort_by_column(key: &KeyConfig) -> CommandText {
CommandText::new(
format!("Sort by column [{}]", key.sort_by_column),
CMD_GROUP_TABLE,
)
}

pub fn extend_selection_by_one_cell(key: &KeyConfig) -> CommandText {
CommandText::new(
format!(
Expand All @@ -96,6 +113,16 @@ pub fn extend_selection_by_one_cell(key: &KeyConfig) -> CommandText {
)
}

pub fn extend_selection_by_line(key: &KeyConfig) -> CommandText {
CommandText::new(
format!(
"Extend selection by horizontal line [{}]",
key.extend_selection_by_horizontal_line,
),
CMD_GROUP_TABLE,
)
}

pub fn extend_or_shorten_widget_width(key: &KeyConfig) -> CommandText {
CommandText::new(
format!(
Expand Down
7 changes: 5 additions & 2 deletions src/components/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl CompletionComponent {
fn next(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i >= self.filterd_candidates().count() - 1 {
if i + 1 >= self.filterd_candidates().count() {
0
} else {
i + 1
Expand All @@ -63,7 +63,10 @@ impl CompletionComponent {
let i = match self.state.selected() {
Some(i) => {
if i == 0 {
self.filterd_candidates().count() - 1
self.filterd_candidates()
.count()
.checked_sub(1)
.unwrap_or(0)
} else {
i - 1
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl PropertiesComponent {
columns.first().unwrap().fields(),
database.clone(),
table.clone(),
false,
);
}
self.constraint_table.reset();
Expand All @@ -89,6 +90,7 @@ impl PropertiesComponent {
constraints.first().unwrap().fields(),
database.clone(),
table.clone(),
false,
);
}
self.foreign_key_table.reset();
Expand All @@ -102,6 +104,7 @@ impl PropertiesComponent {
foreign_keys.first().unwrap().fields(),
database.clone(),
table.clone(),
false,
);
}
self.index_table.reset();
Expand All @@ -115,6 +118,7 @@ impl PropertiesComponent {
indexes.first().unwrap().fields(),
database.clone(),
table.clone(),
false,
);
}
Ok(())
Expand Down
Loading

0 comments on commit eeb17bd

Please sign in to comment.