Repository navigation
Releases: ofamtools/ochazuke
Releases · ofamtools/ochazuke
Release list
v0.82.0
- Fixed: editing a long Markdown document no longer pegs the CPU. Glamour draws the document in runs of top-level blocks, each cached, so an edit redraws only the run it touched (output byte-identical);
TasksandElementsno longer copy the source per item. 10 edits on a 3,000-line doc: 3.0 s → 0.8 s CPU. - Added
markdown.wrap, defaulttrue: the Markdown block editor soft-wraps a long line at the last space that fits as you type (a word wider than the pane breaks at the edge), a list item's next rows under its text; the source gets no line breaks.falsekeeps the sideways scroll. - Added
Input.WrapandInput.WrapIndent(soft wrap inInputBlock, off by default) andInputRows(in, width).
v0.17.0
- Framework namespace is
ochazuke: framework nouns areochazuke.settings,ochazuke.page,ochazuke.stateand so on. In v0.16.0 they wereapp.<noun>, which collided with theappnoun's own verbs (app.state). The short names stay as aliases, andapp.<framework noun>is accepted silently for one release. Exported noun constants changed value. cli.ExtensionNamespace(bin): strips a leadingo-and refuses reserved names (o-ai →ai, o-qbt →qbt). Hosts use it withcli.Namespace.- Catalog fix:
cli.Cataloglists each noun once, sorted by name. It used to split one noun into several entries. - Card timeline:
AddTimelinedraws boxed cards with wrapped headers (no…), lazily drawn bodies with foldable sections,Active(bold,●) andMutedcards, group rules, and follow-tail scrolling.
v0.16.0
- Noun namespaces:
- Framework nouns are now
app.<noun>(app.settings,app.config, …), and their short names stay as aliases. Defineextends a framework noun with the same short name;DefineOwn(name)lets an app claim the short name instead.- Dotted nouns split on the last dot (
SplitKey); a verb can't contain a dot. - The CLI takes nested, dotted and alias spellings (
bin app settings list,bin app.settings list,bin settings list). - Extension hosts namespace extension nouns with
cli.Namespace(ext). The catalog publishesaliases.
- Framework nouns are now
- Compatibility:
Runtime.NounsandRuntime.Operationsare keyed by canonical names, so look framework nouns up throughNoun()/Operation(). Several exported noun constants changed value. - State explorer:
ochazuke/explorepresses keys through any app built headless with fakes, and checks invariants in every state:- no panic, focus and modal rules, honest hints, no traps, render fits, jobs settle.
- Findings come with shrunk key paths, as gap stories or Go tests.
- Entry points:
explore.Run,Survey,Reproduce;o-story explore;make explore.
v0.15.0
config.reload: reads themes.json, settings.json, actions.json and bindings.json again, in dependency order, then each app hook (Runtime.OnConfigReload(name, fn)). Problems are reported per file and stale notices withdrawn.- Noun places: each instance's noun, ancestor-noun chain, page and modal are recorded and persisted per app in
noun-places.json. Read them withnouns places,nouns listandRuntime.NounPlaces. ?help views:Scycles here → pick → table. Pick shows a noun and mode you choose (n,m); table shows keys by mode. Both resolve at a recorded place (p), defaulting to where?was opened. Settingshelp.pick-view,help.table-viewandhelp.pending-modes.ctrl+\\opens the help from any insert mode.- Bindings export: rows print as mode, noun, request (verb first), keys.
bindings list --allandbindings.reference.jsonare sorted the same way.
v0.14.0
- Modals: about 80% of the terminal width with no 78-column cap; a chooser fills the modal width and no longer resizes while typing (story
chooser/wide-fills). - Terminal overlays:
Terminal.SetOverlay(*TerminalOverlay{Dim, Marks})draws over a live pane without touching its frame or stream. With an app passthrough mode entered from the leader, this gives tuios-style hints (storiesterminal/hints-*). - Keys: the key classes
upperandctrl+alpha, and the argument sourceletter. - Palette:
Parameter.Nounlists that noun's things as the parameter's choices.
v0.13.0
Table cell mode is opt-in: CellSelect(); every other table selects rows as before v0.12.0.
Table cell mode is opt-in: only a table added with CellSelect() is cell-based.
Tables
CellSelect()(anInstanceOptionforAddList) makes a table cell-based: the current column,h/l,0/^/home,$/end,N|,g c,y(copy the cell) andz >/z </z =, with the column and widths remembered intables.json, asv0.12.0gave every table.AddTreeignores it.- Every other table selects rows again, as on
v0.11.0:h/lare free for row nouns,$,^and0(without a count) runlist.scroll-columns(verb guardtable-scrolls),z l/z hscroll a column, no current cell is drawn, and nothing is read from or written totables.jsonfor it (widths av0.12.0cell table saved no longer stick to it). Storytables/row-select. RowSelect()is a deprecated no-op; the framework's trees,?help modal and Settings page no longer pass it.Y(copy the row's cells joined by tabs) answers on every table (verb guardlist-table),yonly on a cell-mode table.Vanswers on every table with marks: a visual range over the marks, cell-mode or not.escends it throughlist.end-visual(verb and row guardlist-visual), so the row no longer hides an outereschint, such as a modal'sesc modal.pop, over a table.- The width keys
z >/z </z =need a current column, so they answer on cell-mode tables only;List.SetColumnWidthstill sets a width on any table. list.column,list.choose-columnandlist.resize-columnrefuse a row-select table ("not a cell table");list.yank {what: cell}too.- cli: catalog tables select rows, so the groups rail's
hback row (guardlist-first-column) answers at once on them. Storycatalog/groups-table-h.
o-story
- A story list takes
cellSelect(ListSpec.CellSelect); the cell stories set it, and the goldens of tables that select rows readR|again.
v0.12.0
Tables are cell-based: a current column, per-column widths, and V for rows.
Tables are cell-based, like o-csv's grid: a current column, column widths, and a visual row selection.
Tables
- A list with columns has a current column (
List.Column,SetColumn;columnin its state). On thelistnoun in normal mode, on a cell-mode table only:h/l/left/rightmove by column (counts),0/^/homeand$/endgo to the first and last,N|to column N,g cchooses one from a chooser of the titles (list.column,list.choose-column, motions);j/kkeep the column. Every frame scrolls the column offset as little as shows the current column;z l/z hcarry it along.$,^and0no longer runlist.scroll-columns;list.columnscrolls a row-select table the same way. Storiestables/cell-motion,tables/column-count. - The current cell is drawn reverse and underlined inside the row's highlight, the header underlines the current column's title, and an unfocused table fades both. Story
tables/unfocused-cell-dimmed. yandYcopy the current cell, or the row's cells joined by tabs, into the registers (list.yank {what, register}).z >/z <widen or narrow the current column byColumnWidthStep(2) cells, never below 3;z =makes every column automatic (list.resize-column,list.reset-columns;List.SetColumnWidth,ColumnWidths,ResetColumnWidths). The widths and the current column are remembered per table id in the state directory'stables.json(Runtime.TableState,SetTableState). Storytables/column-resize.Vstarts a visual row selection drawn into the marks:j/kextend it (they clamp), a row's application verb runs for every selected row throughlist.apply,escorVends it and the marks go back (list.visual,List.Visual,StartVisual,EndVisual). Storytables/visual-apply.list.applytakesargsfor every row's request, and a verb with a confirm asks once for all the rows.RowSelect()keeps a table on row selection: trees' lists (h/l expand and collapse), the?help modal and the Settings page use it.- y, Y, V and the width keys are hidden from the footer;
?help lists them. - cli: the groups rail's
h/leftback rows take the new guardlist-first-column, so in a tablehmoves left and goes back to the rail from the first column. Storycatalog/groups-table-h.
grid
- Per-column widths:
z >/z </z =on the grid noun (grid.resize-column,grid.reset-columns;Grid.SetColumnWidth,ColumnWidth,ColumnWidths,ResetColumnWidths). A given width replacesMaxCellWidthfor its column and is remembered under the grid's id.
o-story
- Goldens read
C|(c|dimmed) for a highlighted row that holds a table's current cell; the expect fieldcellnames the current cell's text.
v0.11.0
The terminal leader can wait for the next key indefinitely.
terminal-leader-timeout(TerminalLeaderTimeoutSetting, duration): how longleader_pendingwaits for the next key before it sends the leader alone.0never expires, so the leader waits like tmux's prefix; a positive value is the leader's own timeout.EnsureTerminalLeaderdeclares it besideterminal-leaderunless the app declared it first (with its own default); the framework default isDefaultBindingTimeout, and until settings.json holds a value the leader followsBindingTimeout. Other key sequences keepBindingTimeout. Storyterminal/leader-timeout-zero-waits.
v0.10.0
An unfocused list keeps its selected row, faded; the dims are settings. A list can clear its filter when enter picks a row.
Unfocused lists and dims
- A page list without the focus keeps its selected row in reverse video and is drawn faded as a whole, so the row an unfocused list is on (a tree beside a live terminal) stays visible and the focused row is the one highlight at full strength. A list in a modal stays plain until focused; a tree editing a line is not faded. Replaces the old rule "an unfocused list draws every row plain" (UX rule R5.1). Stories
lists/unfocused-dimmed,lists/beside-terminal-keeps-row. - Two framework settings, declared by
EnsureConfigSettings:dim-unfocused(percent an unfocused list fades toward the background, default 20) andmodal-dim(the page behind a modal, default 35, the backdrop's look until now). Both 0 to 90 (MaxDim); 0 is off. Styles.Fade(percent)blends the scheme's text colour toward its surface (lipgloss.Blend1D, perceptual); in mono or NO_COLOR any fade is the faint attribute.Styles.WithDims(modal, unfocused)sets the newStyles.BackdropandStyles.Unfocused;Model.Styles()applies the settings.NewStylesuses the defaults.- o-story:
highlightedcounts full-strength highlights only; the newdimmedcounts highlights under faint; goldens mark a dimmed-only rowr|.
Lists
ClearFilterOnEnter()(anInstanceOptionforAddListandAddTree): enter in the list's filter line chooses the selected match (list.filter-choose, guardlist-chooses): the filter clears, the selection stays on that row and on screen, the mode is normal. With no match enter keeps the filter, as on every list; other lists are unchanged. Storylists/filter-enter-clears.
Fixes
- Custom components' explicit
Block.Cursornow reachesModel.View().Cursorwithout a focused input, using the normal block or visual underline shape. Blocks without a cursor remain hidden; input and terminal cursor shapes are unchanged.
v0.9.0
List motions
- Every list answers Vim's paging motions in normal mode:
g gandGgo to the first and last row, and with a count to that row (5G,5gg,list.goto {position, row});ctrl+d/ctrl+umove half a page (a count is rows) andctrl+f/ctrl+ba page (a count is pages) (list.scroll {delta, half, steps}). A page is the list's own window, else the page body's height; the window moves with the selection. They clamp at the list's edges, never spill, and are motions (off the footer, undermovementin?). A row noun that binds the same key keeps it. Storylists/page-motions. - A table with more columns than fit scrolls them (
list.scroll-columns {to, delta, steps},List.ColumnOffset):$brings the last column into view,^(and0without a count) goes back,z l/z hmove one column. The first column stays; the unscrolled view still drops columns byPriority. The keys answer only on a table that hides a column or is scrolled. Storytables/column-motions. - A key-sequence prefix whose only remaining row is its generated
<prefix> esccancel (every sequence on it guarded off) no longer waits for a second key.