-
-
Notifications
You must be signed in to change notification settings - Fork 3
feat: add 13 new builtin extensions (sources, previewers, renderers) #9
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tabnr
is repeated if the label
is Tab ${tabnr}
.
denops, | ||
"", | ||
"color", | ||
) as string[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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, | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just yield
.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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), | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just yield.
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 fmt
deno task check
mod.ts
filesEach 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