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
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
push:
branches: [master]
pull_request:
branches: [master]

permissions:
contents: read

env:
CARGO_TERM_COLOR: always

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # stable
with:
toolchain: stable
components: clippy, rustfmt
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
- run: cargo fmt --check
- run: cargo clippy -- -D warnings
- run: cargo test
104 changes: 104 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Release

on:
push:
tags: ["v*"]

permissions: {}

env:
CARGO_TERM_COLOR: always

jobs:
build:
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact: crabmail-linux-amd64
- os: macos-latest
target: aarch64-apple-darwin
artifact: crabmail-darwin-arm64
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # stable
with:
toolchain: stable
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
- run: cargo build --release
- name: Package
run: |
tar czf ${{ matrix.artifact }}.tar.gz -C target/release crabmail
shasum -a 256 ${{ matrix.artifact }}.tar.gz > ${{ matrix.artifact }}.tar.gz.sha256
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ${{ matrix.artifact }}
path: |
${{ matrix.artifact }}.tar.gz
${{ matrix.artifact }}.tar.gz.sha256

release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
merge-multiple: true
- name: Create release
uses: softprops/action-gh-release@3bb12739c298aeb8a4aeaf626c5b8d85266b0e65 # v2.6.2
with:
files: |
*.tar.gz
*.sha256
generate_release_notes: true

update-tap:
needs: release
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
id: app-token
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: CyTechNomad
repositories: homebrew-tap
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
merge-multiple: true
- name: Get version and checksums
id: meta
run: |
VERSION="${GITHUB_REF_NAME#v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "sha256_darwin=$(awk '{print $1}' crabmail-darwin-arm64.tar.gz.sha256)" >> "$GITHUB_OUTPUT"
echo "sha256_linux=$(awk '{print $1}' crabmail-linux-amd64.tar.gz.sha256)" >> "$GITHUB_OUTPUT"
- name: Update tap formula
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
VERSION: ${{ steps.meta.outputs.version }}
SHA256_DARWIN: ${{ steps.meta.outputs.sha256_darwin }}
SHA256_LINUX: ${{ steps.meta.outputs.sha256_linux }}
run: |
git config --global url."https://x-access-token:${GH_TOKEN}@github.com/".insteadOf "https://github.com/"
git clone https://github.com/CyTechNomad/homebrew-tap.git tap
cd tap

# Update main formula
sed -i "s/version \".*\"/version \"${VERSION}\"/" Formula/crabmail.rb
sed -i "0,/sha256 \".*\"/{s/sha256 \".*\"/sha256 \"${SHA256_DARWIN}\"/}" Formula/crabmail.rb
sed -i "/sha256 \"${SHA256_DARWIN}\"/!{0,/sha256 \".*\"/{s/sha256 \".*\"/sha256 \"${SHA256_LINUX}\"/}}" Formula/crabmail.rb

# Create versioned formula
cp Formula/crabmail.rb "Formula/crabmail@${VERSION}.rb"
sed -i "s/class Crabmail </class CrabmailAT${VERSION//\./-} </" "Formula/crabmail@${VERSION}.rb"

git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git commit -m "Update crabmail to ${VERSION}"
git push
19 changes: 19 additions & 0 deletions Cargo.lock

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

11 changes: 10 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ toml = "0.8"
dirs = "6"

# Credentials
keyring = { version = "3", features = ["apple-native"] }
keyring = "3"
secrecy = "0.10"
zeroize = "1"

Expand All @@ -44,3 +44,12 @@ anyhow = "1"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing-appender = "0.2"

[target.'cfg(target_os = "macos")'.dependencies]
keyring = { version = "3", features = ["apple-native"] }

[target.'cfg(target_os = "linux")'.dependencies]
keyring = { version = "3", features = ["linux-native"] }

[target.'cfg(target_os = "windows")'.dependencies]
keyring = { version = "3", features = ["windows-native"] }
66 changes: 33 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,50 +60,50 @@ Configuration is stored at `~/.config/crabmail/config.toml`.

#### Normal Mode

| Key | Action |
| ----------- | -------------------------------------- |
| `j` / `k` | Navigate down / up |
| `h` / `l` | Focus mailboxes / messages |
| `Enter` | Open selected message / select mailbox |
| `i` | Compose new email |
| `/` | Search |
| `:` | Command mode |
| `r` | Refresh mailbox |
| `d` | Delete message (press `y` to confirm) |
| `Esc` | Back / cancel |
| `q` | Quit |
| Key | Action |
| --------- | -------------------------------------- |
| `j` / `k` | Navigate down / up |
| `h` / `l` | Focus mailboxes / messages |
| `Enter` | Open selected message / select mailbox |
| `i` | Compose new email |
| `/` | Search |
| `:` | Command mode |
| `r` | Refresh mailbox |
| `d` | Delete message (press `y` to confirm) |
| `Esc` | Back / cancel |
| `q` | Quit |

#### Reading a Message

| Key | Action |
| ----------- | ------------------- |
| `j` / `k` | Scroll down / up |
| `r` | Reply to message |
| `f` | Forward message |
| `d` | Delete message |
| `q` / `Esc` | Close reader |
| Key | Action |
| ----------- | ---------------- |
| `j` / `k` | Scroll down / up |
| `r` | Reply to message |
| `f` | Forward message |
| `d` | Delete message |
| `q` / `Esc` | Close reader |

#### Composing

| Key | Action |
| ------------- | ----------------------------------- |
| `Tab` | Cycle fields (To → Subject → Body) |
| `Shift+Tab` | Cycle fields backward |
| `Ctrl+w` | Send message |
| `Esc` | Cancel compose |
| Key | Action |
| ----------- | ---------------------------------- |
| `Tab` | Cycle fields (To → Subject → Body) |
| `Shift+Tab` | Cycle fields backward |
| `Ctrl+w` | Send message |
| `Esc` | Cancel compose |

![Composer](assets/Composer.png)

#### Commands

| Command | Action |
| -------------------- | ------------------- |
| `:q` / `:quit` | Quit |
| `:account <name>` | Switch account |
| `:add-account` | Add a new account |
| `:edit-account` | Edit active account |
| `:theme <name>` | Switch color theme |
| `:help` | Show keybind hints |
| Command | Action |
| ----------------- | ------------------- |
| `:q` / `:quit` | Quit |
| `:account <name>` | Switch account |
| `:add-account` | Add a new account |
| `:edit-account` | Edit active account |
| `:theme <name>` | Switch color theme |
| `:help` | Show keybind hints |

## Configuration

Expand Down
3 changes: 3 additions & 0 deletions src/action.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crossterm::event::KeyEvent;

// Some variants are matched but not yet constructed — they exist as scaffolding
// for a future decoupled event dispatch architecture.
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum Action {
Quit,
Noop,
Expand Down
Loading
Loading