Skip to content

Clear the issue backlog (4.3.12) - #1235

Merged
ddehilster merged 12 commits into
VisualText:masterfrom
ddehilster:fix/remaining-issues
Oct 14, 2026
Merged

ddehilster merged 12 commits into
VisualText:masterfrom
ddehilster:fix/remaining-issues

Conversation

@ddehilster

@ddehilster ddehilster commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

All thirteen open issues, one commit each, released together as 4.3.12 so the version bumps and the CHANGELOG don't collide. Each commit message gives the details and how it was checked.

Issue Change
#475 Generate rules from pass tree Generate Rule General/Exact work on a selection in a .tree file; the rule goes into that tree's pass
#794 Generated .nlp back into the sequence Output view: "Add to Analyzer Sequence" on .nlp/.pat. Choose the pass to insert after; on a name clash, replace (the pass keeps its place) or add under the next free name
#658 Move output file anywhere Output view: "Copy or Move File To..."
#688 Multi-file output browser Select a folder in the Text view to see every file under it that has outputs, each expandable. Also fixes: matches/trees modes depended on "all" having run; fileHasTest always returned false
#613 Sort and count for corpus study "Sort & Count text lines" (editor) and "Count Words in Folder" (Text view); counts open in a new editor
#785 Trees after a failed run A failed run refreshes the sequence's per-pass tree icons and lists the trees in the Output view
#230 Progress while initializing The updater shows its current step in the status bar
#481 New version loads the wrong engine The engine is that of the running version, not the newest one on disk
#328 Revisit settings analyzer.runMode was never declared, so the run mode was lost on every reload; stray createtmpfile.tmpDir setting removed; descriptions fixed. Keys are not renamed, because renaming would reset everyone's values
#295 Partial tree colorization Partial and full trees color identically (1,230 partial trees, 30,469 lines checked); the real defect was [ tokens dropped from partial trees
#98 Manifest files Already exists as .nlm mod files; they were Windows-only and now work on macOS/Linux
#272 KB passes regenerate and re-run "Toggle KB Generator" on a pass; with nlp.analyzer.regenerateKB on (default off), the .kbb/.dict files a changed generator pass writes are copied from the log folder into kb/user and the text runs once more. Premise checked with the engine (run 2 reads the dict run 1 wrote)
#626 writekb help Already present: Help/markdown/writekb.md on visualtext-files main, under Knowledge Base Functions

Tested: npm test (all suites; new unit tests for counts, tree ranges, mod paths, last tree pass), integration 57/57 (new: Sort & Count, run-mode registration), and vsce-package with the icon check.

Not exercised in VS Code: the dialog/quick-pick flows (#658, #794), the folder browser (#688) and the updater progress (#230), and the KB generator re-run (#272), which needs an installed engine for the running version. All are typechecked and linted, but the harness can't click through them.

Closes #475
Closes #794
Closes #658
Closes #688
Closes #613
Closes #785
Closes #230
Closes #481
Closes #328
Closes #295
Closes #98
Closes #626
Closes #272

🤖 Generated with Claude Code

ddehilster and others added 12 commits October 13, 2026 18:22
A run counts as failed when the engine exits with an error or err.log
holds a located error -- and the engine has usually written the trees
of every pass it got through. The failure branch refreshed only the
output and log views, so the sequence view's per-pass tree icons kept
whatever state the previous run left: passes that did produce trees
offered none on a first run, and the output view listed no trees.

Now a failed run refreshes the sequence and text views, switches the
output view to its tree listing when any trees exist, and logs how far
they go. Checked with a pass that hits a run-time error: 14 trees
written, run reported failed.

Closes VisualText#785.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Generate Rule General/Exact" worked from text (.txt), highlighted text
(.txxt) and pass files, but not from the place a rule is usually
designed: a pass's parse tree. findSelectedTreeStr had no .tree branch,
so the command did nothing there, and the editor menu did not offer it.

In a .tree file the selected lines are parsed directly (parseTreeLines,
as Generate Path does) and the top-level nodes become the rule's
elements. The rule goes into the pass the tree belongs to (anaNNN.tree
-> pass NNN, as Generate Path does); final.tree falls back to the
current pass. Both commands are now in the .tree editor menu.

Closes VisualText#475.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lText#328)

Going through every setting the extension declares and every one it
reads turned up two defects and a set of descriptions that did not say
what the setting does:

- analyzer.runMode (the status-bar run mode: interpreted / compiled /
  compiled-analyzer / compiled-kb) was read and written but never
  declared. VS Code refuses to write an unregistered setting, so the
  mode was lost on every reload; the refusal is an async rejection the
  surrounding try/catch could not catch. Declared as an enum, the
  write's rejection is now handled, and the integration test that
  guards written settings covers it.
- createtmpfile.tmpDir, another extension's setting copied in with a
  snippet, chose where partial trees were written. They go to the
  system temp folder, which is what it fell back to.
- update.auto, textView.fast, analyzer.current, engine.visualtext,
  engine.analyzers, user.name and logs.clear get descriptions that say
  what they do and which ones the extension sets itself.

Every declared setting is read somewhere. Keys are not renamed:
moving the un-prefixed ones (update.*, user.name, ...) under nlp.*
would silently reset everyone's values.

Closes VisualText#328.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…alText#613)

"Sort & Unique text lines" sorted and de-duplicated but threw the
counts away, and nothing counted words across a corpus.

- Sort & Count text lines (editor menu, beside Sort & Unique): each
  distinct line with how often it occurs, most frequent first, as
  "count<TAB>line" in a new editor -- the text itself is untouched.
  Works on the selection or the whole file.
- Count Words in Folder (Text view, on a folder): word frequencies over
  every file under it, skipping the engine's _log folders, with a
  header giving the total, distinct and file counts. A word is a run of
  letters and digits in any script, inner apostrophes and hyphens kept,
  lowercased.

Counting is pure (src/output/counts.ts) and unit-tested; an integration
test runs Sort & Count in VS Code.

Closes VisualText#613.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…isualText#658, VisualText#794)

VisualText#658: the output view could copy a file only to another analyzer's kb/
or input/ folder. "Copy or Move File To..." (output item context menu)
asks where with a save dialog, starting in the analyzer's input folder,
then whether to copy or move.

VisualText#794: a pass file a run produced -- a generated rule file, a RUG pass --
had to be found again through Select Library Pass to get it into the
sequence. Output .nlp/.pat files now carry "Add to Analyzer Sequence":
pick the pass to insert after; if a pass of that name is already in the
sequence, either replace it (it keeps its place, only its file changes)
or add this one under the next free name (name2, name3, ...).

Closes VisualText#658.
Closes VisualText#794.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The output view showed one input file's outputs at a time. After
analyzing a folder, each file's _log folder had to be reached by
selecting the files one by one.

Selecting a folder in the Text view now lists every input file under
it that has outputs, each expanding to its own outputs in the current
mode (all / matches / trees). Selecting a file goes back to that file's
flat list. KB and orphan-pass modes are per analyzer and unchanged.
The file actions (delete, rename, copy, add test) are not offered on
the input-file rows, so they cannot act on the input itself.

Also fixed on the way:
- The matches and trees modes reused the _log folder the "all" mode
  had last found, and listed nothing if "all" had not run first. Each
  mode now finds the folder itself. The trees mode no longer lists
  final.tree twice.
- fileHasTest set the log folder instead of the test folder, so it
  always answered false.

Closes VisualText#688.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
)

At activation the updater checks, downloads and unpacks the engine,
ICU libraries, VisualText files and example analyzers. It reported
only to the log view, so a first start that downloaded the engine
looked like an extension that did nothing for a minute.

While the updater runs, the status bar now shows a spinning "NLP++"
item naming the step in progress -- "Downloading the NLP++ engine",
"Unpacking the example analyzers" -- and it goes away when the queue
finishes or the user stops it. Status-bar progress rather than a
notification, so an ordinary start that finds nothing to do is not
interrupted.

Closes VisualText#230.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
)

The engine is downloaded into the extension's own folder,
~/.vscode/extensions/dehilster.nlp-<version>/nlp-engine. Which
<version> was decided in three places: at activation the newest
version found on disk; then, only if auto-update was on, the running
extension's version; and a lexicographic sort in getLatestExtPath that
also wrote it. With several versions on disk -- after an update VS Code
has not cleaned up yet, or a downgrade, or with update.auto off -- a
new version could run an older version's engine, or download into
another version's folder. Removing the older versions was the
workaround the issue describes. (This machine had seven.)

The version is now the running extension's, set once at activation
and never replaced by a directory scan. getExtensionPath() (settings
init, the example-analyzers path, engine updates) prefers the running
version's folder, falling back to the newest installed and then to the
code's own location as before. getLatestExtPath is gone. The folder
layout is unchanged, so F5 debugging still uses the installed engine of
the same version.

Closes VisualText#481.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sualText#295)

VisualText#295 reported wrong colorization in the partial tree ("View selected
tree"), with no repro. Checked against today's tree grammar: 1,230
partial trees cut from 15 real final.tree files exactly as
findTreeFileLines cuts them, 30,469 lines, tokenized with vscode-textmate
beside the full trees they came from -- every line gets the same scopes
in both. The grammar colors a tree line by line, so a partial tree
cannot color differently any more.

What the check did find is in the cut itself. findTreeFileLines split
each line on its first "[" to read the offsets, and the engine writes
a literal bracket token as "   [ [2,2,2,2,0,0,punct]": the token was
taken for the field list and the line dropped, so the partial tree of
"x [y] z" lost its "[". The cut now goes through the shared, tested
parseTreeLine (src/trace/treeParse.ts), which already knew that case,
via a new treeLinesInRange -- tested on the engine's own output for
that text.

Closes VisualText#295.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
VisualText#98 asked for a manifest that bundles .nlp passes and KB files. That is
the .nlm mod file: sections under "<modfile kb\user\x.dict>" headers,
unpacked by the extension into kb/user, spec and input, with the passes
inserted into the sequence after a pass the user picks (Mod Load /
Create / Add in the KB, sequence and text views). The engine needs no
change -- the extension does the unpacking.

But the format only worked on Windows. Headers use backslashes, and
sections were classified by looking for "\kb\user\", "\spec\" and
"\input\" in a joined path. On macOS and Linux nothing matched, so
every section was "unknown" and its pass never went into the
sequence, and path.join kept the backslashes, writing a file literally
named "kb\user\en-numbers.dict" in the analyzer folder. Building a mod
file there recorded the path with "/".

Paths are now split on either separator (src/session/modPaths.ts,
tested), and headers are always written with backslashes so a mod file
made anywhere loads in older versions too. Checked against the shipped
languages/English/en-numbers.nlm: kb, input and spec sections all
recognized.

Closes VisualText#98.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Version bump and CHANGELOG for the twelve issue fixes on this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sualText#272)

A pass that builds a knowledge base -- SaveKB("mykb.kbb", ...), or a
.dict written with << -- puts the file in the run's <text>_log folder,
where the analyzer's kb/user never sees it; using it meant copying it
by hand and running again.

- "Toggle KB Generator" on a pass in the sequence marks it (shown as
  "KB generator"); the marks live in the analyzer's state.json.
- With nlp.analyzer.regenerateKB on (off by default), after a
  successful run in which a marked pass has changed since its output
  was last copied, the .kbb/.dict files named in that pass's own text
  are copied from the log folder into kb/user and the text is queued
  once more. The second run finds nothing changed, so it does not
  repeat. The re-run waits for the current queue, since a second queue
  entry for the same file would share the first one's status.

Checked with the engine: a pass writing words.dict -> run 1 leaves the
attribute empty; with words.dict copied into kb/user, run 2 reads it
(animal=1). File-name extraction and change detection are pure and
unit-tested (src/session/kbGen.ts).

Closes VisualText#272.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ddehilster
ddehilster merged commit b8e543b into VisualText:master Oct 14, 2026
5 checks passed
@ddehilster
ddehilster deleted the fix/remaining-issues branch October 14, 2026 00:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment