fix: robust task-CLI I/O (#5), prefix-preserving completion (#4), wrap option + focusable confirm picker (#3)#6
Open
MattHandzel wants to merge 1 commit into
Open
Conversation
…focusable confirm picker Fixes three classes of user-reported bugs: Issue #5 — :Tw opened a blank buffer with no error. vim.fn.system merges stderr into stdout, so any Taskwarrior chatter around the export JSON (the `task news` nag, "Configuration override" notices, hook output, forced-color ANSI escapes) made the parse fail — and every parse site silently degraded to "zero tasks". A zero-task render is only the concealed header comment, so the buffer looked blank and :TwRefresh looked like a no-op. Now: - READ_RC adds rc.verbose=nothing + rc.color=off to every read-only invocation, suppressing chatter at the source (mutations keep verbose output — tw_add parses "Created task <uuid>" from it); - decode_json_array strips ANSI, scans prioritized bracket candidates, and falls back to line-filtering for chatter interleaved between TW3's line-per-task output; - the ten hand-rolled `find("%[")` slices (buffer, graph, inbox, views, delegate, modify, statusline, telescope, api.export) are replaced by one shared taskmd.shell_export that also redirects stderr away from the parse stream; - tw_export raises a diagnosable error instead of silently returning {} on unparseable output; - a zero-task render shows a virt-lines empty-state hint instead of a blank buffer; - _udas/_projects/_tags line parsing rejects lines containing whitespace (valid names never do; chatter always does). Issue #4 — <Tab> in the filter prompt wiped the already-typed filter. input() completion replaces the ENTIRE line, so candidates now carry the untouched leading tokens. Also defines _complete_modify, which the gm prompt referenced but which never existed (E117 on <Tab>), and adds a lint spec asserting every v:lua completion reference resolves. Issue #3 — adds setup{ wrap = false } to disable line wrap in task buffers, and vim.schedule()s the Apply/Cancel confirm picker out of the BufWriteCmd context so float-based vim.ui.select backends (dressing, snacks, telescope) can take focus. Verified: 19 new unit specs (decode robustness, completion prefixing, empty state, wrap validation, v:lua lint) and 6 new e2e specs (wrap window state, empty-state extmark on a real render, render survival under a real noisy on-launch hook, confirm-picker drain) — all green against a real Taskwarrior DB. Co-Authored-By: Claude Fable 5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
#5 —
:Twopens a blank buffer,:TwRefreshhas no effectRoot cause.
vim.fn.systemmerges stderr into stdout. Any Taskwarrior chatter around the export JSON — the TW 3.xtask newsnag,Configuration overridenotices (triggered by our ownrc.*args for users withverbose=override), hook output, forced-color ANSI escapes — made the JSON parse fail, and every parse site silently degraded to "zero tasks". A zero-task render is only the header comment, whichconceallevel=3hides entirely: the buffer looks blank, and:TwRefreshfaithfully re-renders the same empty result. (Telling detail from the report itself: the feedback template'stask_count_bucketworked —11-25— because that one call uses2>/dev/null.)Fix, defense in depth:
READ_RCaddsrc.verbose=nothing rc.color=offto every read-onlytaskinvocation — chatter suppressed at the source. Mutation paths keep verbose output (tw_addparsesCreated task <uuid>).decode_json_array: strips ANSI, tries prioritized bracket candidates, and falls back to line-filtering for chatter interleaved between TW3's line-per-task output.find("%[")slices (buffer render/virt-text, graph, inbox, views, delegate ×2, modify, statusline, telescope picker,api.export) are replaced by one sharedtaskmd.shell_exportthat additionally redirects stderr away from the parse stream.tw_exportnow raises a diagnosable error (with the actualtaskoutput) instead of silently returning{}— a failure can no longer render as silence.No tasks match filter: … · :TwFilter to change it) instead of a blank buffer._udas/_projects/_tagsline parsing rejects lines containing whitespace (valid names never do; chatter always does) so nag lines can't become phantom UDAs or completion candidates.#4 — Tab in the
:TwFilterbox deleted the already-typed filtervim.fn.input()completion replaces the entire typed text with the chosen candidate;_complete_filterreturned bare last-token candidates, so completing+ACTIVEafterproject:foowipedproject:foo. Candidates now carry the untouched leading tokens. Bonus find: thegmmodify prompt referenced_complete_modify, which was never defined — Tab there raised E117. It's now implemented, and a lint spec asserts everyv:luacompletion reference in the codebase resolves to a real function.#3 — wrap option + unusable Apply/Cancel popup
setup{ wrap = false }option (validated, documented in README +:help) for one-line-per-task rendering.vim.ui.selectcalled synchronously inside theBufWriteCmdhandler; float-based select backends (dressing, snacks, telescope) rendered the picker but couldn't take focus — cursor stayed in the task buffer. The picker is nowvim.schedule()d out of the autocmd context.Verification
tests/lua/spec/issue_fixes_spec.lua): decode robustness (leading/trailing/bracketed/ANSI/interleaved noise), tw_export raising instead of silently returning{}, empty-state extmarks, completion prefix preservation,_complete_modify, the v:lua lint, wrap validation.icons=true → NF glyphe2e failure exists onmainand is unrelated — worth a separate issue).Closes #3. Closes #4. Addresses #5 — leaving that one to be closed once @oliviertripet confirms on this branch (repro depends on his environment; see the ask in the issue thread).
🤖 Generated with Claude Code