diff --git a/README.md b/README.md new file mode 100644 index 0000000..368d579 --- /dev/null +++ b/README.md @@ -0,0 +1,118 @@ +# skyshift + +Track your work shifts from the terminal: start, pause, end the day +(even when the day runs past midnight), copy totals into your timesheet, +export reports, and see your work patterns. + +Runs on Windows, Linux and macOS. Keyboard first, with vim-style keys, and +the mouse works too. + +## Build and run + +You need Rust 1.89 or newer ([rustup.rs](https://rustup.rs), or your +distribution's `rust` and `cargo` packages). + +```sh +cargo build --release +``` + +The program is `target/release/skyshift` (`skyshift.exe` on Windows): copy +it to a folder on your `PATH`. + +- **Windows**: nothing else to install. The `.exe` carries its own C runtime + and runs on any Windows 10 or 11. +- **Void Linux**: `sudo xbps-install -S rust cargo`, then build as above. +- **Fedora**: `sudo dnf install rust cargo`, then build as above. + +On Linux no system library is needed: the clipboard works on both X11 and +Wayland. If copying doesn't work in your setup, set `clipboard = "command"` +and `clipboard_command = "wl-copy"` (or `"xclip -selection clipboard"`) +in the settings. + +## Everyday keys + +| Keys | What they do | +|------------------|----------------------------------------------------------| +| `s` `p` `e` | start, pause, end the work day | +| `` | start / pause | +| `p` | "I actually paused at 17:30" (also `s`, `e`) | +| `Ctrl-x` `Ctrl-a`| the running session started 5 minutes earlier / later | +| `yy` `yw` | copy the day / the week for your timesheet | +| `c` | copy in another format, with a preview | +| `gh` `gd` `gi` `gs` | Tracker, Days, Insights, Settings (also `gt`, `Tab`) | +| `u` `Ctrl-r` | undo, redo: mistakes cost nothing | +| `zz` | snooze the break suggestion | +| `:` | command line: `:pause 17:30`, `:export csv lastmonth`, `:set time_format=12h` | +| `?` | every key, for the screen you're on | +| `q` | quit (a running shift keeps running) | + +After the first key of a sequence (`g`, `y`, ``...), a popup lists +what can follow (like which-key in Neovim). It can be turned off in the +settings, or with `w`. + +## How work days work + +- **Start** opens a work day if none is open. The day keeps its date until + you press **End day**, so a shift from 22:00 to 04:00 counts for the day + it started. +- Forgot **End day**? If a break lasts longer than 8 hours (a setting), the + next Start opens a new work day by itself. +- Times you type (`22:30`, `2230`, `22h30`, `10:30pm`, `10p`) are read in + both 12h and 24h styles. An end time before the start time means the next + day. +- Times are recorded to the minute, so what you see always adds up. + +## Your files + +Run `skyshift --paths` to see where they are. + +- **`config.toml`**: every setting, each with a comment explaining it. + Change settings in the app (Settings tab, `za` shows the expert ones) or + in the file. +- **`shifts.toml`**: your work, in plain text. You can edit it by hand; + skyshift reloads it when it changes, and won't overwrite it while it has + a mistake in it. A copy is saved once a day in `backups/`. +- **Exports** (CSV, JSON, Markdown) go to your Documents folder, or the + folder set in the settings. + +To keep everything together, for example on a USB stick or in a synced +folder: `skyshift --config D:\skyshift\config.toml` with +`data_file = "shifts.toml"` in that config. + +## How the code is organized + +Every file starts with a comment explaining what it's for. + +| Folder / file | What's in it | +|----------------|--------------------------------------------------------------| +| `domain/` | the rules: segments, work days, the journal (no files, no UI) | +| `time/` | the clock, 12h/24h text, typed times, date ranges | +| `analysis/` | the numbers behind the Insights screen | +| `export/` | timesheet text, the clipboard, CSV/JSON/Markdown reports | +| `storage/` | config.toml, shifts.toml, backups, the lock | +| `ui/` | keys (`keymap.rs`), screens, popups, widgets, colors | +| `settings.rs` | every setting, described once in one table | +| `reminders.rs` | the pomodoro rhythm | +| `action.rs` | everything the screens can ask the app to do | +| `app.rs` | the core: the loop, and the one place where data changes | + +The flow is always the same: a key becomes a `Command` (`ui/keymap.rs`), +the screen turns the command into an `Action`, and `App::apply` changes the +data, saves it, and shows a message. + +Common changes: + +- **Change a key**: edit the tables in `src/ui/keymap.rs`. The help screen + and the which-key popup follow automatically. +- **Add a setting**: add a field to `Settings`, its default, and one entry + in `FIELDS` (all in `src/settings.rs`). The Settings screen and + config.toml follow automatically. + +## Development + +```sh +cargo test # run the tests +cargo lint # clippy, treating warnings as errors +cargo fmt # format the code +cargo test show_screens -- --ignored --nocapture # print every screen as text +```