migrate portfolio tab to new keybindings
This commit is contained in:
parent
b8b6dffcb5
commit
816653e812
3 changed files with 16 additions and 49 deletions
38
src/tui.zig
38
src/tui.zig
|
|
@ -1243,26 +1243,6 @@ pub const App = struct {
|
||||||
return ctx.consumeAndRedraw();
|
return ctx.consumeAndRedraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Escape: portfolio tab clears its account filter inline.
|
|
||||||
// Other tabs fall through to the global keymap (no global
|
|
||||||
// Esc binding) and then to the tab-local fallback dispatcher
|
|
||||||
// (e.g. history binds Esc to `compare_cancel`, projections
|
|
||||||
// binds Esc to `clear_as_of`). When portfolio migrates, its
|
|
||||||
// Esc handling moves into a tab-local action too.
|
|
||||||
if (key.codepoint == vaxis.Key.escape) {
|
|
||||||
if (self.active_tab == .portfolio and self.states.portfolio.account_filter != null) {
|
|
||||||
self.setAccountFilter(null);
|
|
||||||
self.states.portfolio.cursor = 0;
|
|
||||||
self.scroll_offset = 0;
|
|
||||||
tab_modules.portfolio.rebuildPortfolioRows(&self.states.portfolio, self);
|
|
||||||
self.setStatus("Filter cleared: showing all accounts");
|
|
||||||
return ctx.consumeAndRedraw();
|
|
||||||
}
|
|
||||||
// Fall through — no tab-specific handler. Esc isn't
|
|
||||||
// globally bound, so matchAction returns null and the
|
|
||||||
// tab-local fallback gets a chance.
|
|
||||||
}
|
|
||||||
|
|
||||||
const action = self.keymap.matchAction(key) orelse {
|
const action = self.keymap.matchAction(key) orelse {
|
||||||
// No global binding matched. Fall back to tab-local
|
// No global binding matched. Fall back to tab-local
|
||||||
// dispatch — the active tab may bind this key in its
|
// dispatch — the active tab may bind this key in its
|
||||||
|
|
@ -1371,24 +1351,6 @@ pub const App = struct {
|
||||||
self.reloadPortfolioFile();
|
self.reloadPortfolioFile();
|
||||||
return ctx.consumeAndRedraw();
|
return ctx.consumeAndRedraw();
|
||||||
},
|
},
|
||||||
.sort_col_next => {
|
|
||||||
if (self.active_tab == .portfolio) {
|
|
||||||
tab_modules.portfolio.tab.handleAction(&self.states.portfolio, self, tab_modules.portfolio.Action.sort_col_next);
|
|
||||||
return ctx.consumeAndRedraw();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.sort_col_prev => {
|
|
||||||
if (self.active_tab == .portfolio) {
|
|
||||||
tab_modules.portfolio.tab.handleAction(&self.states.portfolio, self, tab_modules.portfolio.Action.sort_col_prev);
|
|
||||||
return ctx.consumeAndRedraw();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.account_filter => {
|
|
||||||
if (self.active_tab == .portfolio) {
|
|
||||||
tab_modules.portfolio.tab.handleAction(&self.states.portfolio, self, tab_modules.portfolio.Action.open_account_picker);
|
|
||||||
return ctx.consumeAndRedraw();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,6 @@ pub const Action = enum {
|
||||||
symbol_input,
|
symbol_input,
|
||||||
help,
|
help,
|
||||||
reload_portfolio,
|
reload_portfolio,
|
||||||
sort_col_next,
|
|
||||||
sort_col_prev,
|
|
||||||
account_filter,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const KeyCombo = struct {
|
pub const KeyCombo = struct {
|
||||||
|
|
@ -147,9 +144,6 @@ pub const global_default_bindings = [_]Binding{
|
||||||
.{ .action = .symbol_input, .key = .{ .codepoint = '/' } },
|
.{ .action = .symbol_input, .key = .{ .codepoint = '/' } },
|
||||||
.{ .action = .help, .key = .{ .codepoint = '?' } },
|
.{ .action = .help, .key = .{ .codepoint = '?' } },
|
||||||
.{ .action = .reload_portfolio, .key = .{ .codepoint = 'R' } },
|
.{ .action = .reload_portfolio, .key = .{ .codepoint = 'R' } },
|
||||||
.{ .action = .sort_col_next, .key = .{ .codepoint = '>' } },
|
|
||||||
.{ .action = .sort_col_prev, .key = .{ .codepoint = '<' } },
|
|
||||||
.{ .action = .account_filter, .key = .{ .codepoint = 'a' } },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn defaults() KeyMap {
|
pub fn defaults() KeyMap {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,9 @@ pub const Action = enum {
|
||||||
/// Open the account picker modal (mode = .account_picker).
|
/// Open the account picker modal (mode = .account_picker).
|
||||||
/// No-op if no portfolio is loaded.
|
/// No-op if no portfolio is loaded.
|
||||||
open_account_picker,
|
open_account_picker,
|
||||||
|
/// Clear the active account filter (return to "all accounts").
|
||||||
|
/// No-op when no filter is active. Bound to Esc.
|
||||||
|
clear_account_filter,
|
||||||
/// Select the cursor row's symbol as the currently-active
|
/// Select the cursor row's symbol as the currently-active
|
||||||
/// symbol for the per-symbol tabs (quote/perf/options/etc.).
|
/// symbol for the per-symbol tabs (quote/perf/options/etc.).
|
||||||
select_symbol,
|
select_symbol,
|
||||||
|
|
@ -127,14 +130,12 @@ pub const tab = struct {
|
||||||
pub const label: []const u8 = "Portfolio";
|
pub const label: []const u8 = "Portfolio";
|
||||||
|
|
||||||
pub const default_bindings: []const framework.TabBinding(Action) = &.{
|
pub const default_bindings: []const framework.TabBinding(Action) = &.{
|
||||||
// These are dead until scoped keymaps land — the global
|
|
||||||
// keymap matches first. Declared per-tab so the help
|
|
||||||
// overlay and future scoped-dispatch can find them.
|
|
||||||
.{ .action = .expand_collapse, .key = .{ .codepoint = vaxis.Key.enter } },
|
.{ .action = .expand_collapse, .key = .{ .codepoint = vaxis.Key.enter } },
|
||||||
.{ .action = .sort_col_next, .key = .{ .codepoint = 'S' } },
|
.{ .action = .sort_col_next, .key = .{ .codepoint = '>' } },
|
||||||
.{ .action = .sort_col_prev, .key = .{ .codepoint = ';' } },
|
.{ .action = .sort_col_prev, .key = .{ .codepoint = '<' } },
|
||||||
.{ .action = .sort_reverse, .key = .{ .codepoint = 'o' } },
|
.{ .action = .sort_reverse, .key = .{ .codepoint = 'o' } },
|
||||||
.{ .action = .open_account_picker, .key = .{ .codepoint = 'a' } },
|
.{ .action = .open_account_picker, .key = .{ .codepoint = 'a' } },
|
||||||
|
.{ .action = .clear_account_filter, .key = .{ .codepoint = vaxis.Key.escape } },
|
||||||
.{ .action = .select_symbol, .key = .{ .codepoint = 's' } },
|
.{ .action = .select_symbol, .key = .{ .codepoint = 's' } },
|
||||||
.{ .action = .select_symbol, .key = .{ .codepoint = vaxis.Key.space } },
|
.{ .action = .select_symbol, .key = .{ .codepoint = vaxis.Key.space } },
|
||||||
};
|
};
|
||||||
|
|
@ -145,6 +146,7 @@ pub const tab = struct {
|
||||||
.sort_col_prev = "Sort: previous column",
|
.sort_col_prev = "Sort: previous column",
|
||||||
.sort_reverse = "Sort: reverse direction",
|
.sort_reverse = "Sort: reverse direction",
|
||||||
.open_account_picker = "Filter by account",
|
.open_account_picker = "Filter by account",
|
||||||
|
.clear_account_filter = "Clear account filter",
|
||||||
.select_symbol = "Select symbol",
|
.select_symbol = "Select symbol",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -222,6 +224,15 @@ pub const tab = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.clear_account_filter => {
|
||||||
|
// No-op when no filter is active.
|
||||||
|
if (state.account_filter == null) return;
|
||||||
|
app.setAccountFilter(null);
|
||||||
|
state.cursor = 0;
|
||||||
|
app.scroll_offset = 0;
|
||||||
|
rebuildPortfolioRows(state, app);
|
||||||
|
app.setStatus("Filter cleared: showing all accounts");
|
||||||
|
},
|
||||||
.select_symbol => {
|
.select_symbol => {
|
||||||
if (state.rows.items.len == 0) return;
|
if (state.rows.items.len == 0) return;
|
||||||
if (state.cursor >= state.rows.items.len) return;
|
if (state.cursor >= state.rows.items.len) return;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue