add vimgrep support for TUI picker output#41
Conversation
|
I don't use vim personally, but if you say its good to use I totally trust you, and YES this is something I want in here. PR's are always encouraged. BTW if you rebase and install again you can get a nice performance win ;) Reviewing this now. |
|
Looks good, only thing I ask, is can you add a section to the README.md about how to set this up and use it? Ideally for console and TUI, but im ok with just one. Then I can try it out too :P Do that and it will be merged. |
|
Set up what, the nvim plugin? |
There was a problem hiding this comment.
Pull request overview
This PR adds support for vimgrep-style output formatting in TUI mode by respecting the --format=vimgrep flag. When a user exits the TUI by pressing Enter on a search result, the output is now formatted as vimgrep-style matches that can be consumed by tools like vim's quickfix list, rather than just printing the file location. This brings TUI mode into parity with console mode for output formatting.
Changes:
- Added vimgrep format support when exiting TUI mode via Enter key
- Implemented
tuiVimGrepfunction that mirrorsformatVimGreplogic for single-file formatting - Added format checking in both list view and file viewer modes to conditionally apply vimgrep formatting
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func tuiVimGrep(cfg *Config, location string, matchLocations map[string][][]int) string { | ||
| content, err := readFileContent(location, cfg.MaxReadSizeBytes) | ||
| if err != nil { | ||
| return location | ||
| } | ||
| fj := &common.FileJob{ | ||
| Filename: location, | ||
| Location: location, | ||
| Content: content, | ||
| MatchLocations: matchLocations, | ||
| } | ||
| fileMode := resolveSnippetMode(cfg.SnippetMode, location) | ||
|
|
||
| var vimGrepOutput []string | ||
| if fileMode == "grep" { | ||
| lineResults := snippet.FindAllMatchingLines(fj, cfg.LineLimit, 0, 0) | ||
| for _, lr := range lineResults { | ||
| col := 1 | ||
| if len(lr.Locs) > 0 { | ||
| col = lr.Locs[0][0] + 1 | ||
| } | ||
| hint := strings.ReplaceAll(lr.Content, "\n", "\\n") | ||
| line := fmt.Sprintf("%v:%v:%v:%v", location, lr.LineNumber, col, hint) | ||
| vimGrepOutput = append(vimGrepOutput, line) | ||
| } | ||
| } else if fileMode == "lines" { | ||
| lineResults := snippet.FindMatchingLines(fj, 0) | ||
| for _, lr := range lineResults { | ||
| col := 1 | ||
| if len(lr.Locs) > 0 { | ||
| col = lr.Locs[0][0] + 1 | ||
| } | ||
| hint := strings.ReplaceAll(lr.Content, "\n", "\\n") | ||
| line := fmt.Sprintf("%v:%v:%v:%v", location, lr.LineNumber, col, hint) | ||
| vimGrepOutput = append(vimGrepOutput, line) | ||
| } | ||
| } else { | ||
| docFreq := make(map[string]int, len(matchLocations)) | ||
| for k, v := range matchLocations { | ||
| docFreq[k] = len(v) | ||
| } | ||
| snippets := snippet.ExtractRelevant(fj, docFreq, 50) | ||
| if len(snippets) > cfg.SnippetCount { | ||
| snippets = snippets[:cfg.SnippetCount] | ||
| } | ||
| for _, snip := range snippets { | ||
| hint := strings.ReplaceAll(snip.Content, "\n", "\\n") | ||
| line := fmt.Sprintf("%v:%v:%v:%v", location, snip.LineStart, snip.StartPos, hint) | ||
| vimGrepOutput = append(vimGrepOutput, line) | ||
| } | ||
| } | ||
|
|
||
| if len(vimGrepOutput) == 0 { | ||
| return location | ||
| } | ||
| return strings.Join(vimGrepOutput, "\n") | ||
| } |
There was a problem hiding this comment.
Consider adding test coverage for the tuiVimGrep function. While the implementation closely mirrors formatVimGrep from console.go, having tests would help ensure correct behavior across different snippet modes (grep, lines, snippet) and verify proper handling of edge cases like file read errors or empty match locations. The existing tui_test.go file demonstrates that TUI functions are tested in this codebase.
Just whatever you need to do to add it? Sorry I really only know enough vim to open, edit, search, save and quit. Its really not what I learnt... I went emacs, then got emacs pinkie and moved away. |
|
Bah gonna merge anyway. Ill learn some vim. |
|
Thank you @oyarsa ! |
I found it useful to have
cssupport printing vimgrep-style matches when exiting TUI mode, as I can use it inside nvim to populate the quickfix list, butcsseems to just ignore--formatfrom TUI. This is used here: oyarsa/codespelunker.nvim.The TUI code is mostly copied from the existing one in
console.go. If you're interested, I can look into refactoring this.PS: I hope it's okay to open PRs like this. It's something I found useful for myself, and I thought maybe you would too.