Merge pull request #11 from zaphar/user_manual

Add a user manual for sheetui
This commit is contained in:
Jeremy Wall 2024-12-03 17:47:57 -05:00 committed by GitHub
commit 5e99cf5d7b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 104 additions and 24 deletions

View File

@ -36,3 +36,7 @@ sheetui path/to/file.xlsx # edit/view a spreadsheet
``` ```
<img src="./assets/screenshot.png" /> <img src="./assets/screenshot.png" />
## Reference
* [Documentation](./docs/index.md)

96
docs/index.md Normal file
View File

@ -0,0 +1,96 @@
# The sheetui user documentation
## Running sheetui
`sheetui --help` will print out help for the command line tags.
Currently this will print out:
```sh
Usage: sheetui [OPTIONS] <WORKBOOK>
Arguments:
<WORKBOOK>
Options:
-l, --locale-name <LOCALE_NAME> [default: en]
-t, --timezone-name <TIMEZONE_NAME> [default: America/New_York]
--log-input <LOG_INPUT>
-h, --help Print help
-V, --version Print version
```
## User Interface
The sheetui user interface is loosely inspired by vim. It is a modal interface that is entirely keyboard driven. At nearly any time you can type `Alt-h` to get some context sensitive help.
### Navigation Mode
The interface will start out in navigation mode. You can navigate around the table and between the sheets using the following keybinds:
**Cell Navigation**
* `h`, ⬆️, and `TAB` will move one cell to the left.
* `l` and, ➡️ will move one cell to the right.
* `j`, ⬇️, and `Enter` will move one cell down.
* `k` ⬆️, will move one cell up.
**Sheet Navigation**
* `Ctrl-n` moves to the next sheet
* `Ctrl-p` moves to the prev sheet
Sheet navigation moving will loop around when you reach the ends.
**Numeric prefixes**
You can prefix each of the keybinds above with a numeric prefix to do them that many times. So typing `123h` will move to the left 123 times. Hitting `Esc` will clear the numeric prefix if you want to cancel it.
**Modifying the Sheet or Cells**
* `e` or `i` will enter CellEdit mode for the current cell.
* `Ctrl-h` will shorten the width of the column you are on.
* `Ctrl-l` will lengthen the width of the column you are on.
**Other Keybindings**
* `Ctrl-s` will save the sheet.
* `q` will exit the application.
* `:` will enter CommandMode.
<aside>Note that for `q` this will not currently prompt you if the sheet is not saved.</aside>
### CellEdit Mode
You enter CellEdit mode by hitting `e` or `i` while in navigation mode. Type what you want into the cell.
Starting with:
* `=` will treat what you type as a formula.
* `$` will treat it as us currency.
Typing a number will treat the contents as a number. While typing non-numeric text will treat it as text content. <aside>We do not yet support modifyint the type of a cell after the fact. We may add this in the future.</aside>
For the most part this should work the same way you expect a spreadsheet to work.
* `Enter` will update the cell contents.
* `Esc` will cancel editing the cell and leave it unedited.
You can find the functions we support documented here: [ironcalc docs](https://docs.ironcalc.com/functions/lookup-and-reference.html)
### Command Mode
You enter command mode by typing `:` while in navigation mode. You can then type a command and hit `Enter` to execute it or `Esc` to cancel.
The currently supported commands are:
* `write [path]` save the current spreadsheet. If the path is provided it will save it to that path. If omitted it will save to the path you are currently editing. `w` is a shorthand alias for this command.
* `insert-rows [number]` Inserts a row into the sheet at your current row. If the number is provided then inserts that many rows. If omitted then just inserts one.
* `insert-cols [number]` Just line `insert-rows` but for columns.
* `rename-sheet [idx] <name>` rename a sheet. If the idx is provide then renames that sheet. If omitted then it renames the current sheet.
* `new-sheet [name]` Creates a new sheet. If the name is provided then uses that. If omitted then uses a default sheet name.
* `select-sheet <name>` Select a sheet by name.
* `edit <path>` Edit a new spreadsheet at the current path. `e` is a shorthand alias for this command.
* `quit` Quits the application. `q` is a shorthand alias for this command.
<aside>Note that in the case of `quit` and `edit` that we do not currently prompt you if the current spreadsheet has not been saved yet. So your changes will be discarded if you have not saved first.</aside>

View File

@ -108,7 +108,7 @@ fn try_consume_new_sheet<'cmd, 'i: 'cmd>(
return Ok(None); return Ok(None);
} }
if input.remaining() > 0 && !is_ws(&mut input) { if input.remaining() > 0 && !is_ws(&mut input) {
return Err("Invalid command: Did you mean to type `write <arg>`?"); return Err("Invalid command: Did you mean to type `new-sheet <arg>`?");
} }
let arg = input.span(0..).trim(); let arg = input.span(0..).trim();
return Ok(Some(Cmd::NewSheet(if arg.is_empty() { return Ok(Some(Cmd::NewSheet(if arg.is_empty() {
@ -129,11 +129,11 @@ fn try_consume_select_sheet<'cmd, 'i: 'cmd>(
return Ok(None); return Ok(None);
} }
if input.remaining() > 0 && !is_ws(&mut input) { if input.remaining() > 0 && !is_ws(&mut input) {
return Err("Invalid command: Did you mean to type `write <sheet-name>`?"); return Err("Invalid command: Did you mean to type `select-sheet <sheet-name>`?");
} }
let arg = input.span(0..).trim(); let arg = input.span(0..).trim();
if arg.is_empty() { if arg.is_empty() {
return Err("Invalid command: Did you forget the sheet name? `write <sheet-name>`?"); return Err("Invalid command: Did you forget the sheet name? `select-sheet <sheet-name>`?");
} }
return Ok(Some(Cmd::SelectSheet(arg))); return Ok(Some(Cmd::SelectSheet(arg)));
} }
@ -189,7 +189,7 @@ fn try_consume_insert_column<'cmd, 'i: 'cmd>(
if let Ok(count) = arg.parse() { if let Ok(count) = arg.parse() {
count count
} else { } else {
return Err("You must pass in a non negative number for the row count"); return Err("You must pass in a non negative number for the column count");
} }
}))); })));
} }

View File

@ -420,26 +420,6 @@ impl<'ws> Workspace<'ws> {
Ok(()) Ok(())
})?; })?;
} }
KeyCode::Char('r') if key.modifiers == KeyModifiers::CONTROL => {
self.run_with_prefix(|ws: &mut Workspace<'_>| -> Result<()> {
let (row_count, _) = ws.book.get_size()?;
ws.book.update_entry(
&Address {
row: row_count + 1,
col: 1,
},
"",
)?;
let (row, _) = ws.book.get_size()?;
let mut loc = ws.book.location.clone();
if loc.row < row as usize {
loc.row = row as usize;
ws.book.move_to(&loc)?;
}
ws.handle_movement_change();
Ok(())
})?;
}
KeyCode::Char('q') => { KeyCode::Char('q') => {
return Ok(Some(ExitCode::SUCCESS)); return Ok(Some(ExitCode::SUCCESS));
} }