You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
When settings, a rebind or file watching fail, TuiCode says nothing and I can't tell why #92
When something goes wrong behind the scenes, TuiCode says nothing, so I can't tell why it's behaving oddly.
Some things fail quietly today, and each one leaves the user guessing:
A typo in ~/.tui/TuiCode.settings.json (a trailing comma, say) and every setting silently goes back to its default. Theme, indent size and wrap all change at once, with no hint why. The same goes for the keybindings and grammar association files: a broken file means every override is dropped without a word.
A rebind that doesn't take. An invalid override is skipped and logged, but the log goes nowhere, so the key just doesn't work.
The editor stops watching for outside changes (the folder is on a filesystem without change events, or the watcher hits its limit). The disk-change notices (Notice when open files change on disk #133, A clean tab shows what is actually on disk #269) then never come, so you can overwrite a file someone changed on disk without any warning. This is logged too, and goes nowhere too.
A broken user grammar in ~/.tui/grammars gives you a file with no colours and no reason.
When asking for help, there's no log to attach to a bug report.
Evidence
Program.cs calls services.AddLogging() with no provider. The eight warnings in the code today (three file watchers, the invalid keybinding override, the terminal profile rewrite) are all thrown away. AGENTS.md says so and points here.
DefaultSettingsService catches JsonException on all three settings files and carries on with defaults, without logging. SyntaxHighlighter does the same for a user grammar that fails to load, and WorkspaceStateStore for a state file it can't read or write.
Every editor the vision learns from has a log the user can open from inside it: VS Code's Output panel and Developer: Open Logs Folder; Zed's zed: open log (docs); Helix's :log-open (docs). VS Code and Zed also put up a notice when the settings file doesn't parse, instead of quietly using defaults.
Options considered
Do nothing. Free. But each of the cases above stays a mystery, and the watcher one can cost work.
A log file only, at a documented path. Cheap, and good for bug reports. But nobody knows to look in it, so the settings typo is still invisible from inside the editor.
A pop-up dialog for each warning. Hard to miss. But it blocks you, often at startup, for things that mostly don't need an answer. Too loud for "a watcher stopped".
A log file you open in a tab, and a warning count in the status bar until you've looked.(Proposed.) Warnings go to a log file. Show log (sl) opens it as an ordinary editor tab, so it can be searched, copied from and attached to an issue with nothing new to learn. While there are warnings you haven't looked at, the status bar's right side shows ⚠ 2, which stays put rather than being replaced, and goes once you open the log. The silent failures above start logging, each naming the file and what was wrong.
Option 5 is option 2 made findable from inside the editor, with one small, persistent status item rather than option 3's passing messages.
Proposal
Warnings and errors go to ~/.tui/logs/TuiCode.log, one line each: time, level, what happened, and the exception's message. Exceptions' stack traces follow on indented lines. Each session starts a new file; the previous session's is kept as TuiCode.1.log, and older ones are deleted.
Show log (sl, no default key) is in the palette and under Help, beside Show diagnostics. It opens the current log as a normal file tab. The disk-change notices keep it up to date while it's open.
While there are warnings you haven't seen, the status bar's right side shows ⚠ 2 before Ln, Col, in the theme's Warning colour. Opening the log clears it; a new warning brings it back with a new count.
Clicking ⚠ 2 opens the log, the same as sl: it opens the log tab, or switches to it if it's already open, and clears the count. It's the status bar's first clickable item; the rest stay as they are.
The silent failures log a warning that names the file and what's wrong:
TuiCode.settings.json, the keybindings file and the grammar associations file not parsing (with the line and column from the JSON error), and the fact that defaults were used for the whole file;
a user grammar that fails to load (named, with the reason);
the workspace state file that can't be read or written.
A settings file that doesn't parse is also said once at startup, because it changes everything you see: the status bar's message reads TuiCode.settings.json has an error, so defaults are in use. sl shows the log. It's an ordinary message and goes when the next one replaces it; ⚠ stays.
A crash leaves its exception in the log, and after the terminal is restored TuiCode prints TuiCode crashed. Details: ~/.tui/logs/TuiCode.log.
AGENTS.md's logging line becomes the convention: Warning and above go to the log and count towards ⚠; Information and Debug aren't written; the status bar is never used for diagnostics, except the one settings message above.
Mockup
Status bar after starting with a watcher that couldn't start and a bad keybinding override:
src/TuiCode/Program.cs • C# ⚠ 2 Ln 12, Col 5
Startup with a broken settings file:
TuiCode.settings.json has an error, so defaults are in use. sl shows the log ⚠ 1 Press F1 for help
sl opens the log as a tab:
┏ TuiCode.log ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ 1 2026-10-04 09:12:03 WARN TuiCode.settings.json didn't parse (line 14, col 3: trailing comma); using ┃
┃ defaults for every setting ┃
┃ 2 2026-10-04 09:12:03 WARN Ignored keybinding override Ctrl+Alt+Shift+K for editor.action.foo: unknown ┃
┃ command ┃
┃ 3 2026-10-04 09:12:04 WARN Not watching /mnt/share/repo for changes made outside the editor: inotify ┃
┃ watch limit reached ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
~/.tui/logs/TuiCode.log • Plain Text • Wrap Ln 1, Col 1
Help menu:
Help
┌──────────────────────────────┐
│ Getting Started (help) F1 │
│ Show diagnostics │
│ Show log │
└──────────────────────────────┘
Scope
In
The log file, its location and keeping one previous session.
Show log (sl) in the palette and the Help menu.
The ⚠ n status item, cleared by opening the log, and clicking it to open the log.
Warnings for the silent failures listed above.
The one startup message for a settings file that doesn't parse.
A crash's exception in the log, and the path printed on exit.
The logging convention in AGENTS.md.
Out
A Settings option for the log level or location. Fixed until someone needs otherwise.
An Output panel, log channels, or filtering by level.
Pointing at the error inside the settings file (squiggles). The log names the line.
Sending logs or crash reports anywhere.
Logging Information or Debug messages, or adding log calls beyond the silent failures above.
Delivery
One PR: the log file, Show log, the ⚠ n status item, the new warnings for the silent failures, the startup settings message and the crash path. The parts only make sense together; a log with nothing new in it, or warnings with nowhere to go, wouldn't show you much.
Decided
Each of these was the Lead's call, accepted when you approved, except the first, which was yours.
Clicking ⚠ n opens the log, the same as sl (yours, on this pitch).
The log lives in ~/.tui/logs/, beside the settings and workspace state, so everything TuiCode writes is in one place. The platform conventions (~/Library/Logs, ~/.local/state, %LOCALAPPDATA%) are more correct but would split TuiCode's files three ways.
The startup settings message is worth breaking the "no diagnostics in the status bar" rule. A settings file that doesn't parse changes everything at once with no clue why. It's the only exception.
⚠ for the status item, though A tab tells you the moment its file changes on disk #268 also puts ⚠ on a tab. It's in a different place and carries a count, so the two shouldn't be confused, and ⚠ is the sign people know for a warning.
Clicking anywhere on ⚠ 2, icon or count, opens the log; there's no hover highlight or tooltip, since the rest of the status bar has none either.
Original idea
Context
#90 introduced the first use of Microsoft.Extensions.Logging in the app: WorkbenchHost.ApplyKeybindings now logs a warning (via ILogger<WorkbenchHost>) when it skips a malformed user keybinding override instead of crashing.
Right now logging is wired with services.AddLogging() and no provider, so those messages are captured through the abstraction but go nowhere visible. That was deliberate for #90 — capture first, decide the sink later.
Decision to make
How and where should logged messages reach the user / a log file? Options to weigh:
A log provider that writes to a file (e.g. ~/.tui/TuiCode.log).
Surface messages at or above a configurable level (e.g. Warning) to the status bar — reusing StatusBarPart.SetMessage.
An in-app log/diagnostics view (the F12 overlay could grow a "recent messages" panel).
Some combination, with the threshold/sink configurable in Settings.
Acceptance
A logging provider is registered so ILogger output is actually observable somewhere.
A documented convention for which levels surface where.
changed the title [-]Decide how/where ILogger messages surface to the user[/-][+]When settings, a rebind or file watching fail, TuiCode says nothing and I can't tell why[/+]on Oct 4, 2026
Now in front of you. Since drafting I've changed two things: it ships as one PR rather than three, after your note on #439, and the open questions became Assumed, each with my pick (~/.tui/logs/, keep the startup settings message, keep ⚠). Comment to change any of them.
Done: clicking ⚠ 2 now opens the log, the same as sl (opens the log tab or switches to it, and clears the count). It's in Proposal and Scope, and Assumed says the whole item is the click target, with no hover highlight. It'll be the status bar's first clickable item.
Broken down into one task: #473, the whole pitch in one PR. It waits on #442 (Terminal.Gui 2.5), which rewrites the settings loading this adds warnings to.
Nothing was left open; Assumed is now Decided, with your click-to-open call marked as yours.
Tried on origin/main (fc01c6b) with a settings file that has a trailing comma. At startup the status bar said the settings file has an error, with ⚠ 1 on the right. sl from the palette opened TuiCode.log as a tab with the WARN line, naming the line and column. Clicking ⚠ 1 did the same and cleared the count. The previous session's log was kept as TuiCode.1.log, and Show log is under Help. This matches the pitch, so I'm closing it.
Opportunity
When something goes wrong behind the scenes, TuiCode says nothing, so I can't tell why it's behaving oddly.
Some things fail quietly today, and each one leaves the user guessing:
~/.tui/TuiCode.settings.json(a trailing comma, say) and every setting silently goes back to its default. Theme, indent size and wrap all change at once, with no hint why. The same goes for the keybindings and grammar association files: a broken file means every override is dropped without a word.~/.tui/grammarsgives you a file with no colours and no reason.Evidence
Program.cscallsservices.AddLogging()with no provider. The eight warnings in the code today (three file watchers, the invalid keybinding override, the terminal profile rewrite) are all thrown away.AGENTS.mdsays so and points here.DefaultSettingsServicecatchesJsonExceptionon all three settings files and carries on with defaults, without logging.SyntaxHighlighterdoes the same for a user grammar that fails to load, andWorkspaceStateStorefor a state file it can't read or write.zed: open log(docs); Helix's:log-open(docs). VS Code and Zed also put up a notice when the settings file doesn't parse, instead of quietly using defaults.Options considered
sl) opens it as an ordinary editor tab, so it can be searched, copied from and attached to an issue with nothing new to learn. While there are warnings you haven't looked at, the status bar's right side shows⚠ 2, which stays put rather than being replaced, and goes once you open the log. The silent failures above start logging, each naming the file and what was wrong.Option 5 is option 2 made findable from inside the editor, with one small, persistent status item rather than option 3's passing messages.
Proposal
~/.tui/logs/TuiCode.log, one line each: time, level, what happened, and the exception's message. Exceptions' stack traces follow on indented lines. Each session starts a new file; the previous session's is kept asTuiCode.1.log, and older ones are deleted.sl, no default key) is in the palette and under Help, beside Show diagnostics. It opens the current log as a normal file tab. The disk-change notices keep it up to date while it's open.⚠ 2beforeLn, Col, in the theme'sWarningcolour. Opening the log clears it; a new warning brings it back with a new count.⚠ 2opens the log, the same assl: it opens the log tab, or switches to it if it's already open, and clears the count. It's the status bar's first clickable item; the rest stay as they are.TuiCode.settings.json, the keybindings file and the grammar associations file not parsing (with the line and column from the JSON error), and the fact that defaults were used for the whole file;TuiCode.settings.json has an error, so defaults are in use. sl shows the log. It's an ordinary message and goes when the next one replaces it;⚠stays.TuiCode crashed. Details: ~/.tui/logs/TuiCode.log.AGENTS.md's logging line becomes the convention: Warning and above go to the log and count towards⚠; Information and Debug aren't written; the status bar is never used for diagnostics, except the one settings message above.Mockup
Status bar after starting with a watcher that couldn't start and a bad keybinding override:
Startup with a broken settings file:
slopens the log as a tab:Help menu:
Scope
In
sl) in the palette and the Help menu.⚠ nstatus item, cleared by opening the log, and clicking it to open the log.AGENTS.md.Out
Delivery
One PR: the log file, Show log, the
⚠ nstatus item, the new warnings for the silent failures, the startup settings message and the crash path. The parts only make sense together; a log with nothing new in it, or warnings with nowhere to go, wouldn't show you much.Decided
Each of these was the Lead's call, accepted when you approved, except the first, which was yours.
⚠ nopens the log, the same assl(yours, on this pitch).~/.tui/logs/, beside the settings and workspace state, so everything TuiCode writes is in one place. The platform conventions (~/Library/Logs,~/.local/state,%LOCALAPPDATA%) are more correct but would split TuiCode's files three ways.⚠for the status item, though A tab tells you the moment its file changes on disk #268 also puts⚠on a tab. It's in a different place and carries a count, so the two shouldn't be confused, and⚠is the sign people know for a warning.⚠ nitem sits with the status bar's right-hand items, however The status bar is crowded with key hints, and the keys that only work where I am are hard to find #406 leaves them.⚠ 2, icon or count, opens the log; there's no hover highlight or tooltip, since the rest of the status bar has none either.Original idea