Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 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 @@ -29,6 +29,7 @@ encoding_rs = "0.8.35"
futures = "0.3.31"
humansize = "2.1.3"
image = "0.25.5"
indexmap = { version = "2.7.1", features = ["serde"] }
infer = "0.19.0"
itsuki = "0.2.0"
laurier = "0.1.0"
Expand Down
29 changes: 21 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,32 @@ For other S3-compatible services, which one to use depends on the service.

### Keybindings

#### Default

The basic key bindings are as follows:

| Key | Description |
| -------------------- | ---------------------------------- |
| <kbd>Ctrl-C</kbd> | Quit app |
| <kbd>Esc</kbd> | Quit app / Close dialog |
| <kbd>Enter</kbd> | Confirm / Open selected item |
| <kbd>Backspace</kbd> | Go back to previous / Close dialog |
| <kbd>j/k</kbd> | Select item / Scroll |
| <kbd>?</kbd> | Show help |
| Key | Description |
| -------------------- | ---------------------------- |
| <kbd>Ctrl-C</kbd> | Quit app |
| <kbd>Enter</kbd> | Confirm / Open selected item |
| <kbd>Backspace</kbd> | Go back to previous |
| <kbd>j/k</kbd> | Select item / Scroll |
| <kbd>?</kbd> | Show help |

Detailed operations on each view can be displayed by pressing `?` key.

#### Custom keybindings

You can set your own custom key bindings.

Custom bindings are loaded from `$STU_ROOT_DIR/keybindings.toml`.

The default key bindings are defined in [./assets/keybindings.toml](./assets/keybindings.toml). You can set key bindings for each screen action in the same format.

- It is possible to set multiple key bindings for one action.
- If you do not set key bindings for an action, the default key bindings will be assigned.
- You can disable an action by setting `[]` as the key bindings.

### Config

Config is loaded from `$STU_ROOT_DIR/config.toml`.
Expand Down
89 changes: 89 additions & 0 deletions assets/keybindings.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
[common]
quit = ["ctrl-c"]
help = ["?"]
dump = ["f12"]

[bucket_list]
down = ["j"]
up = ["k"]
go_to_top = ["g"]
go_to_bottom = ["shift-g"]
page_down = ["ctrl-f"]
page_up = ["ctrl-b"]
select = ["enter"]

filter = ["/"]
sort = ["o"]
copy_details = ["r"]
refresh = ["shift-r"]
reset_filter = ["esc"]
management_console = ["x"]

[object_list]
down = ["j"]
up = ["k"]
go_to_top = ["g"]
go_to_bottom = ["shift-g"]
page_down = ["ctrl-f"]
page_up = ["ctrl-b"]
select = ["enter"]
back = ["backspace"]
bucket_list = ["~"]

download = ["s"]
filter = ["/"]
sort = ["o"]
copy_details = ["r"]
refresh = ["shift-r"]
reset_filter = ["esc"]
management_console = ["x"]

[object_detail]
down = ["j"]
up = ["k"]
right = ["l"]
left = ["h"]
go_to_top = ["g"]
go_to_bottom = ["shift-g"]
back = ["backspace"]

download = ["s"]
download_as = ["shift-s"]
preview = ["p"]
copy_details = ["r"]
management_console = ["x"]

[object_preview]
down = ["j"]
up = ["k"]
right = ["l"]
left = ["h"]
go_to_top = ["g"]
go_to_bottom = ["shift-g"]
page_down = ["ctrl-f"]
page_up = ["ctrl-b"]
back = ["backspace"]

download = ["s"]
download_as = ["shift-s"]
encoding = ["e"]
toggle_wrap = ["w"]
toggle_number = ["n"]

[help]
close = ["?", "backspace"]

# filter
[input_dialog]
close = ["esc"]
apply = ["enter"]

# sort, copy, encoding, confirm
[select_dialog]
down = ["j"]
up = ["k"]
right = ["l"]
left = ["h"]

close = ["esc"]
select = ["enter"]
Binary file modified img/bucket-list-copy-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/bucket-list-filter-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/bucket-list-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/bucket-list-sort-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/bucket-list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed img/initialize.png
Binary file not shown.
Binary file modified img/loading-object-list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-detail-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-detail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-details-copy-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-download-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-list-copy-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-list-filter-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-list-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-list-hierarchy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-list-many.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-list-simple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-list-sort-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-preview-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-preview-image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-version-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/object-version.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 14 additions & 3 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::{
CompleteReloadObjectsResult, Sender,
},
file::{copy_to_clipboard, create_binary_file, save_error_log},
keys::UserEventMapper,
object::{AppObjects, DownloadObjectInfo, FileDetail, ObjectItem, ObjectKey, RawObject},
pages::page::{Page, PageStack},
widget::{Header, LoadingDialog, Status, StatusType},
Expand Down Expand Up @@ -52,6 +53,7 @@ impl AppContext {
#[derive(Debug)]
pub struct App {
pub page_stack: PageStack,
pub mapper: UserEventMapper,
app_objects: AppObjects,
client: Option<Arc<Client>>,
ctx: Rc<AppContext>,
Expand All @@ -64,11 +66,18 @@ pub struct App {
}

impl App {
pub fn new(ctx: AppContext, tx: Sender, width: usize, height: usize) -> App {
pub fn new(
mapper: UserEventMapper,
ctx: AppContext,
tx: Sender,
width: usize,
height: usize,
) -> App {
let ctx = Rc::new(ctx);
App {
app_objects: AppObjects::default(),
page_stack: PageStack::new(Rc::clone(&ctx), tx.clone()),
mapper,
client: None,
ctx,
tx,
Expand Down Expand Up @@ -433,7 +442,7 @@ impl App {
}

pub fn open_help(&mut self) {
let helps = self.page_stack.current_page().helps();
let helps = self.page_stack.current_page().helps(&self.mapper);
if helps.is_empty() {
return;
}
Expand Down Expand Up @@ -926,7 +935,9 @@ impl App {
Notification::Success(msg) => StatusType::Success(msg.into()),
Notification::Warn(msg) => StatusType::Warn(msg.into()),
Notification::Error(msg) => StatusType::Error(msg.into()),
Notification::None => StatusType::Help(self.page_stack.current_page().short_helps()),
Notification::None => {
StatusType::Help(self.page_stack.current_page().short_helps(&self.mapper))
}
};
let status = Status::new(status_type).theme(&self.ctx.theme);
f.render_widget(status, area);
Expand Down
6 changes: 6 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const STU_ROOT_DIR_ENV_VAR: &str = "STU_ROOT_DIR";

const APP_BASE_DIR: &str = ".stu";
const CONFIG_FILE_NAME: &str = "config.toml";
const KEYBINDINGS_FILE_NAME: &str = "keybindings.toml";
const ERROR_LOG_FILE_NAME: &str = "error.log";
const DEBUG_LOG_FILE_NAME: &str = "debug.log";
const DOWNLOAD_DIR: &str = "download";
Expand Down Expand Up @@ -103,6 +104,11 @@ impl Config {
dir.join(name)
}

pub fn keybindings_file_path(&self) -> anyhow::Result<PathBuf> {
let dir = Config::get_app_base_dir()?;
Ok(dir.join(KEYBINDINGS_FILE_NAME))
}

pub fn error_log_path(&self) -> anyhow::Result<PathBuf> {
let dir = Config::get_app_base_dir()?;
Ok(dir.join(ERROR_LOG_FILE_NAME))
Expand Down
1 change: 0 additions & 1 deletion src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ pub enum AppEventType {
NotifySuccess(String),
NotifyWarn(String),
NotifyError(AppError),
Quit,
}

#[derive(Debug)]
Expand Down
Loading