From 0e43e09f132a23d1c7868506cac021fb5d80420d Mon Sep 17 00:00:00 2001 From: Emil Lerch Date: Fri, 26 Jun 2026 08:57:02 -0700 Subject: [PATCH] document "R" will upgrade tui from quote->portfolio operations --- docs/reference/tui.md | 7 +++++++ src/PortfolioData.zig | 5 +++++ src/tui/portfolio_tab.zig | 11 +++++++++++ 3 files changed, 23 insertions(+) diff --git a/docs/reference/tui.md b/docs/reference/tui.md index 7e6b05a..0251859 100644 --- a/docs/reference/tui.md +++ b/docs/reference/tui.md @@ -29,6 +29,12 @@ currently-selected symbol. The symbol-scoped tabs follow a single "current symbol"; change it from the Portfolio tab (select a holding) or by launching with `-s`. +When you launch on a symbol (`zfin i -s AAPL`), no portfolio is loaded, +so the portfolio-scoped tabs (Portfolio, Analysis, Review, Projections, +History) are greyed out and unselectable - you start on the Quote tab. +Press `R` to load your portfolio on demand: this "upgrades" the session +into the full portfolio view and enables those tabs. + ## Charts Tabs with charts render high-fidelity **Kitty graphics** when your @@ -46,6 +52,7 @@ current bindings). The global defaults: |----------------------------------------------|--------------------------------| | `q`, `Ctrl-C` | Quit | | `r`, `F5` | Refresh the current tab's data | +| `R` | Reload the portfolio from disk | | `l` / `right` / `tab` | Next tab | | `h` / `left` / `shift+tab` | Previous tab | | `1`-`8` | Jump to a tab by number | diff --git a/src/PortfolioData.zig b/src/PortfolioData.zig index f4b7770..cdb7ed2 100644 --- a/src/PortfolioData.zig +++ b/src/PortfolioData.zig @@ -458,6 +458,11 @@ pub fn invalidateClassificationMap(self: *PortfolioData) void { /// 'K' overlay) to show the `metadata.srf` security name the way the CLI /// `quote` command does. No-op when `paths_in` is empty or a portfolio /// is already loaded (a full `load()` populates the map itself). +/// +/// Intentional side effect: capturing `paths_in` here also lets the `R` +/// (reload_portfolio) key run a first full `load()` from symbol mode - +/// see `portfolio_tab.reloadPortfolioFile` - so the user can "upgrade" a +/// symbol-only session into the full portfolio view on demand. pub fn primeClassificationMap(self: *PortfolioData, paths_in: []const []const u8) void { if (paths_in.len == 0 or self.paths.len != 0) return; diff --git a/src/tui/portfolio_tab.zig b/src/tui/portfolio_tab.zig index 4d4978c..f1d80b7 100644 --- a/src/tui/portfolio_tab.zig +++ b/src/tui/portfolio_tab.zig @@ -1910,6 +1910,17 @@ pub fn buildWelcomeScreenLines( /// Inactive tabs stay in `loaded = false` and lazy-rebuild on /// next switch. pub fn reloadPortfolioFile(state: *State, app: *App) void { + // `paths` is non-empty once a portfolio has been resolved - either + // by a normal load, OR by the symbol-mode classification-map prime + // (see PortfolioData.primeClassificationMap). In that second case + // `file` is still null (no portfolio actually loaded yet), and the + // `pd.reload` below runs the FIRST full load. That's intentional: + // `R` lets you "upgrade" a symbol-only session (`zfin -s AAPL`) + // into the full portfolio view, lighting up the portfolio-scoped + // tabs. Only when nothing has been resolved at all (no portfolio + // file on disk) is `paths` empty and there's genuinely nothing to + // do. Do NOT tighten this to `file == null` - that would break the + // upgrade path. if (app.portfolio.paths.len == 0) { app.setStatus("No portfolio file to reload"); return;