feat: add 13 new builtin extensions (sources, previewers, renderers)#9
feat: add 13 new builtin extensions (sources, previewers, renderers)#9lambdalisue wants to merge 21 commits intomainfrom
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #9 +/- ##
===========================================
- Coverage 51.46% 34.22% -17.24%
===========================================
Files 78 98 +20
Lines 2318 3906 +1588
Branches 70 70
===========================================
+ Hits 1193 1337 +144
- Misses 1125 2569 +1444 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
703ec00 to
dd06d56
Compare
c93ed0d to
c166b92
Compare
| - Note that if you use `@denops/std/function`, some functions already provides | ||
| proper types so you may not need to use `@core/unknownutil` | ||
| - You should try hard to avoid using `as any` or `as unkonwn as`. Proper | ||
| type-guarding is preferred. |
There was a problem hiding this comment.
All changes applied to this file should be commited in the previous commit.
| if (showLabel) { | ||
| // Try to get tab label from 't:tabLabel' variable | ||
| const customLabel = await fn.gettabvar(denops, tabnr, "tabLabel") as | ||
| | string | ||
| | null; | ||
| if (customLabel) { | ||
| label = customLabel; | ||
| } else { | ||
| // Create label from buffer names in the tab | ||
| const bufferNames = []; | ||
| for (const w of windows) { | ||
| const name = await fn.bufname(denops, w.bufnr); | ||
| bufferNames.push( | ||
| name ? name.split("/").pop() || name : "[No Name]", | ||
| ); | ||
| } | ||
| label = bufferNames.join(", "); | ||
| } | ||
| } else { |
There was a problem hiding this comment.
I don't think Vim nor Neovim provides such variable (t:tabLabel). List up the reference that mentioned that variable or remove this custom label feature.
| const value = `${prefix}${tabnr}: ${label} (${windowCount} window${ | ||
| windowCount !== 1 ? "s" : "" | ||
| })`; |
There was a problem hiding this comment.
tabnr is repeated if the label is Tab ${tabnr}.
| denops, | ||
| "", | ||
| "color", | ||
| ) as string[]; |
There was a problem hiding this comment.
Do we really need this as string[] annotation?
| // Get current colorscheme if needed | ||
| let currentColorscheme = ""; | ||
| if (markCurrent) { | ||
| const colors = await fn.execute(denops, "colorscheme") as string; |
There was a problem hiding this comment.
It's better to use @core/unknownutil to check if the value is really string or not.
| items.push({ | ||
| id: id++, | ||
| value: `:${cmd} [builtin]`, | ||
| detail: { | ||
| name: cmd, | ||
| definition: "(builtin command)", | ||
| attributes: "", | ||
| bufferLocal: false, | ||
| nargs: "?", | ||
| complete: undefined, | ||
| }, | ||
| }); |
| const mappingList = await fn.maplist(denops, mode) as Array<{ | ||
| lhs: string; | ||
| rhs: string; | ||
| silent: number | boolean; | ||
| noremap: number | boolean; | ||
| nowait: number | boolean; | ||
| expr: number | boolean; | ||
| buffer: number | boolean; | ||
| mode?: string; | ||
| sid?: number; | ||
| lnum?: number; | ||
| script?: number | boolean; | ||
| }>; |
There was a problem hiding this comment.
Avoid using as. Try @core/unknownutil to use type guard.
| // Sort by mode and then by lhs | ||
| items.sort((a, b) => { | ||
| const modeCmp = a.detail.mode.localeCompare(b.detail.mode); | ||
| if (modeCmp !== 0) return modeCmp; | ||
| return a.detail.lhs.localeCompare(b.detail.lhs); | ||
| }); |
There was a problem hiding this comment.
We should NOT sort in source.
| items.push({ | ||
| id: id++, | ||
| value: `${modeIndicator} ${mapping.lhs}${attrStr} → ${truncatedRhs}`, | ||
| detail: { | ||
| lhs: mapping.lhs, | ||
| rhs: mapping.rhs, | ||
| mode: mode, | ||
| bufferLocal: isBufferLocal, | ||
| silent: Boolean(mapping.silent), | ||
| noremap: Boolean(mapping.noremap), | ||
| nowait: Boolean(mapping.nowait), | ||
| expr: Boolean(mapping.expr), | ||
| }, | ||
| }); |
| // Git status format: XY filename | ||
| // X = staged status, Y = unstaged status | ||
| const staged = line[0]; | ||
| const unstaged = line[1]; | ||
| const filename = line.substring(3); | ||
|
|
||
| // Determine status code and description | ||
| const status = `${staged}${unstaged}`; | ||
| let statusDescription = ""; | ||
| let isStaged = false; | ||
| let isUnstaged = false; | ||
|
|
||
| // Parse status codes | ||
| if (status === STATUS_CODES.UNTRACKED) { | ||
| statusDescription = "untracked"; | ||
| isUnstaged = true; | ||
| } else if (status === STATUS_CODES.IGNORED) { | ||
| statusDescription = "ignored"; | ||
| } else { | ||
| // Handle staged status | ||
| const stagedDesc = | ||
| STATUS_CODES.STAGED[staged as keyof typeof STATUS_CODES.STAGED]; | ||
| if (stagedDesc) { | ||
| statusDescription = stagedDesc; | ||
| isStaged = true; | ||
| } | ||
|
|
||
| // Handle unstaged status | ||
| const unstagedDesc = STATUS_CODES | ||
| .UNSTAGED[unstaged as keyof typeof STATUS_CODES.UNSTAGED]; | ||
| if (unstagedDesc) { | ||
| statusDescription += isStaged ? `, ${unstagedDesc}` : unstagedDesc; | ||
| isUnstaged = true; | ||
| } | ||
| } | ||
|
|
||
| // Create status indicator | ||
| const indicator = status === STATUS_CODES.UNTRACKED | ||
| ? "[?]" | ||
| : status === STATUS_CODES.IGNORED | ||
| ? "[!]" | ||
| : `[${status}]`; | ||
|
|
||
| // Format display value | ||
| const absolutePath = join(cwd, filename); | ||
| const displayPath = filename; | ||
| const value = `${indicator.padEnd(5)} ${displayPath}`; |
There was a problem hiding this comment.
Add a parser as a pure function so that we can easily test.
Summary
This PR adds 13 new builtin extensions to fulfill the missing extensions mentioned in #2, plus some additional useful ones for Vim/Neovim users.
New Extensions
Sources (11 new)
Previewers (1 new)
Renderers (1 new)
Implementation Details
All extensions:
deno fmtdeno task checkmod.tsfilesEach extension was committed individually for easy review and potential cherry-picking.
Related Issues
Closes #2
Test plan
deno task check)deno fmt)🤖 Generated with Claude Code