add shift-tab keybind

This commit is contained in:
Emil Lerch 2026-03-01 12:11:15 -08:00
parent facc233976
commit b510a86b09
Signed by: lobo
GPG key ID: A7B62D657EF764F8
2 changed files with 83 additions and 82 deletions

View file

@ -34,7 +34,7 @@ zfin aggregates data from multiple free-tier APIs. Each provider is used for the
### Provider summary ### Provider summary
| Data type | Provider | Auth | Free-tier limit | Cache TTL | | Data type | Provider | Auth | Free-tier limit | Cache TTL |
|---|---|---|---|---| |-----------------------|---------------|------------------------|----------------------------|--------------|
| Daily candles (OHLCV) | TwelveData | `TWELVEDATA_API_KEY` | 8 req/min, 800/day | 24 hours | | Daily candles (OHLCV) | TwelveData | `TWELVEDATA_API_KEY` | 8 req/min, 800/day | 24 hours |
| Real-time quotes | TwelveData | `TWELVEDATA_API_KEY` | 8 req/min, 800/day | Never cached | | Real-time quotes | TwelveData | `TWELVEDATA_API_KEY` | 8 req/min, 800/day | Never cached |
| Dividends | Polygon | `POLYGON_API_KEY` | 5 req/min | 7 days | | Dividends | Polygon | `POLYGON_API_KEY` | 5 req/min | 7 days |
@ -103,7 +103,7 @@ The cache directory defaults to `~/.cache/zfin` and can be overridden with `ZFIN
Not all keys are required. Without a key, the corresponding data simply won't be available: Not all keys are required. Without a key, the corresponding data simply won't be available:
| Key | Without it | | Key | Without it |
|---|---| |------------------------|--------------------------------------------------------------------|
| `TWELVEDATA_API_KEY` | No candles, quotes, or trailing returns | | `TWELVEDATA_API_KEY` | No candles, quotes, or trailing returns |
| `POLYGON_API_KEY` | No dividends -- trailing returns show price-only (no total return) | | `POLYGON_API_KEY` | No dividends -- trailing returns show price-only (no total return) |
| `FINNHUB_API_KEY` | No earnings data (tab disabled) | | `FINNHUB_API_KEY` | No earnings data (tab disabled) |
@ -122,7 +122,7 @@ Every data fetch follows the same pattern:
Cache files use [SRF](https://github.com/lobo/srf) (Simple Record Format), a line-oriented key-value format. Freshness is determined by file modification time vs. the TTL for that data type. Cache files use [SRF](https://github.com/lobo/srf) (Simple Record Format), a line-oriented key-value format. Freshness is determined by file modification time vs. the TTL for that data type.
| Data type | TTL | Rationale | | Data type | TTL | Rationale |
|---|---|---| |---------------|--------------|-------------------------------------------------|
| Daily candles | 24 hours | Only changes once per trading day | | Daily candles | 24 hours | Only changes once per trading day |
| Dividends | 7 days | Declared well in advance | | Dividends | 7 days | Declared well in advance |
| Splits | 7 days | Rare corporate events | | Splits | 7 days | Rare corporate events |
@ -138,7 +138,7 @@ Manual refresh (`r` / `F5` in TUI) invalidates the cache for the current tab's d
Each provider has a client-side token-bucket rate limiter that prevents exceeding free-tier limits: Each provider has a client-side token-bucket rate limiter that prevents exceeding free-tier limits:
| Provider | Rate limit | | Provider | Rate limit |
|---|---| |---------------|------------|
| TwelveData | 8/minute | | TwelveData | 8/minute |
| Polygon | 5/minute | | Polygon | 5/minute |
| Finnhub | 60/minute | | Finnhub | 60/minute |
@ -296,7 +296,7 @@ security_type::watch,symbol::TSLA
### Lot fields ### Lot fields
| Field | Type | Required | Description | | Field | Type | Required | Description |
|---|---|---|---| |-----------------|--------|----------|--------------------------------------------------------------------------|
| `symbol` | string | Yes* | Ticker symbol or CUSIP. *Optional for `cash` lots. | | `symbol` | string | Yes* | Ticker symbol or CUSIP. *Optional for `cash` lots. |
| `shares` | number | Yes | Number of shares (or face value for cash/CDs) | | `shares` | number | Yes | Number of shares (or face value for cash/CDs) |
| `open_date` | string | Yes** | Purchase date (YYYY-MM-DD). **Not required for cash/watch. | | `open_date` | string | Yes** | Purchase date (YYYY-MM-DD). **Not required for cash/watch. |
@ -386,7 +386,7 @@ symbol::ARCC,sector::Financials,geo::US,asset_class::US Large Cap
### Classification fields ### Classification fields
| Field | Type | Required | Description | | Field | Type | Required | Description |
|---|---|---|---| |---------------|--------|----------|---------------------------------------------------------------------------|
| `symbol` | string | Yes | Ticker symbol or CUSIP (must match `symbol::` or `ticker::` in portfolio) | | `symbol` | string | Yes | Ticker symbol or CUSIP (must match `symbol::` or `ticker::` in portfolio) |
| `asset_class` | string | No | e.g. "US Large Cap", "Bonds", "Cash & CDs", "Emerging Markets" | | `asset_class` | string | No | e.g. "US Large Cap", "Bonds", "Cash & CDs", "Emerging Markets" |
| `sector` | string | No | e.g. "Technology", "Healthcare", "Financials" | | `sector` | string | No | e.g. "Technology", "Healthcare", "Financials" |

View file

@ -84,6 +84,7 @@ const default_bindings = [_]Binding{
.{ .action = .refresh, .key = .{ .codepoint = vaxis.Key.f5 } }, .{ .action = .refresh, .key = .{ .codepoint = vaxis.Key.f5 } },
.{ .action = .prev_tab, .key = .{ .codepoint = 'h' } }, .{ .action = .prev_tab, .key = .{ .codepoint = 'h' } },
.{ .action = .prev_tab, .key = .{ .codepoint = vaxis.Key.left } }, .{ .action = .prev_tab, .key = .{ .codepoint = vaxis.Key.left } },
.{ .action = .prev_tab, .key = .{ .codepoint = vaxis.Key.tab, .mods = .{ .shift = true } } },
.{ .action = .next_tab, .key = .{ .codepoint = 'l' } }, .{ .action = .next_tab, .key = .{ .codepoint = 'l' } },
.{ .action = .next_tab, .key = .{ .codepoint = vaxis.Key.right } }, .{ .action = .next_tab, .key = .{ .codepoint = vaxis.Key.right } },
.{ .action = .next_tab, .key = .{ .codepoint = vaxis.Key.tab } }, .{ .action = .next_tab, .key = .{ .codepoint = vaxis.Key.tab } },