-
-
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? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
75b036b
Add CLAUDE.md to provide guidance for Claude Code
lambdalisue 6bdfbe0
feat(source): add window source for listing Vim windows
lambdalisue ad2d410
feat(source): add tabpage source for listing Vim tab pages
lambdalisue 9004a59
feat(source): add loclist source for listing location list items
lambdalisue d337686
feat(source): add colorscheme source for listing available colorschemes
lambdalisue d8a627c
feat(source): add highlight source for listing highlight groups
lambdalisue 33e58cd
feat(source): add jumplist source for listing jump locations
lambdalisue fd1a7c8
feat(source): add register source for listing Vim registers
lambdalisue 5006534
feat(source): add mark source for listing Vim marks
lambdalisue 1c0e825
feat(source): add command source for listing user-defined commands
lambdalisue 9c39f46
feat(source): add mapping source for listing key mappings
lambdalisue e8f21f1
feat(source): add git status source for listing modified files
lambdalisue 881a059
feat(source): add grep source for vim's :grep command results
lambdalisue c3bf51b
feat(source): add vimgrep source for vim's :vimgrep command results
lambdalisue 89e0265
feat(source): add autocmd source for vim autocmds
lambdalisue c74961d
feat(previewer): add shell command previewer
lambdalisue bfba569
feat(renderer): add file info renderer for displaying file metadata
lambdalisue 8090011
feat(renderer): add buffer info renderer for displaying buffer metadata
lambdalisue 0f0a8f2
feat(renderer): add smart grep renderer for formatting grep-like results
lambdalisue e9a3319
feat(refiner): add file info refiner for filtering by file properties
lambdalisue c166b92
feat(refiner): add buffer info refiner for filtering by buffer proper…
lambdalisue File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with | ||
| code in this repository. | ||
|
|
||
| ## Project Overview | ||
|
|
||
| This is `@vim-fall/std`, the standard library for Fall - a fuzzy finder plugin | ||
| for Vim/Neovim powered by Denops. The project provides built-in extensions and | ||
| utility functions for the Fall ecosystem, written in Deno/TypeScript. | ||
|
|
||
| ## Key Commands | ||
|
|
||
| ### Development | ||
|
|
||
| - **Type check**: `deno task check` - Run TypeScript type checking | ||
| - **Test**: `deno test -A --parallel --shuffle --doc` - Run all tests | ||
| - **Test single file**: `deno test -A path/to/file_test.ts` - Run specific test | ||
| file | ||
| - **Test with coverage**: `deno task test:coverage` - Run tests with coverage | ||
| collection | ||
| - **Lint**: `deno lint` - Run Deno linter | ||
| - **Format**: `deno fmt` - Auto-format code | ||
| - **Format check**: `deno fmt --check` - Check formatting without modifying | ||
|
|
||
| ### Code Generation | ||
|
|
||
| - **Generate all**: `deno task gen` - Run all code generation tasks | ||
| - **Generate modules**: `deno task gen:mod` - Generate module files in each | ||
| directory | ||
| - **Generate exports**: `deno task gen:exports` - Generate export declarations | ||
| - **Generate nerdfont**: `deno task gen:builtin-renderer-nerdfont` - Generate | ||
| nerdfont icon mappings | ||
|
|
||
| ### Dependencies | ||
|
|
||
| - **Update check**: `deno task update` - Check for dependency updates | ||
| - **Update write**: `deno task update:write` - Update dependencies in place | ||
| - **Update commit**: `deno task update:commit` - Update and commit dependency | ||
| changes | ||
|
|
||
| ### Publishing | ||
|
|
||
| - **Dry run**: `deno publish --dry-run` - Test JSR publishing without publishing | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### Module Organization | ||
|
|
||
| The codebase follows a plugin-based architecture with these core concepts: | ||
|
|
||
| 1. **Extension Types** (in `/builtin/`): | ||
|
|
||
| - **Actions**: Operations performed on selected items (open, yank, cd) | ||
| - **Coordinators**: UI layout managers (compact, modern, separate) | ||
| - **Curators**: Search/filter tools wrapping external commands (grep, | ||
| ripgrep, git-grep) | ||
| - **Matchers**: Fuzzy matching algorithms (fzf, regexp, substring) | ||
| - **Previewers**: Item preview handlers (file, buffer, helptag) | ||
| - **Refiners**: Item transformation/filtering tools | ||
| - **Renderers**: Display formatters (nerdfont icons, path formatting) | ||
| - **Sorters**: Sorting algorithms (lexical, numerical) | ||
| - **Sources**: Data providers (files, buffers, quickfix, history) | ||
| - **Themes**: UI border styles (ascii, modern, single, double) | ||
|
|
||
| 2. **Core APIs** (in root): | ||
|
|
||
| - Each extension type has a corresponding definition file (e.g., `action.ts`, | ||
| `source.ts`) | ||
| - These files define the interface and helper functions for that extension | ||
| type | ||
| - The `mod.ts` file re-exports utility functions for composing extensions | ||
|
|
||
| 3. **Denops Integration**: | ||
| - All extensions receive a `Denops` instance for Vim/Neovim interaction | ||
| - Uses `@denops/std` for Vim API access | ||
| - Test files use `@denops/test` for testing with real Vim instances | ||
|
|
||
| ### Key Patterns | ||
|
|
||
| 1. **Extension Definition**: Use `define*` functions (e.g., `defineAction`, | ||
| `defineSource`) | ||
| 2. **Composition**: Use `compose*` functions to combine multiple extensions | ||
| 3. **Type Safety**: Extensive use of TypeScript generics for item detail types | ||
| 4. **Async/Streaming**: Sources use async generators for efficient data | ||
| streaming | ||
| 5. **Parameter Binding**: `ArgsBinder` pattern for flexible parameter handling | ||
|
|
||
| ### Testing Approach | ||
|
|
||
| - Tests use Deno's built-in test runner with `Deno.test()` | ||
| - Integration tests use real Vim/Neovim instances via `@denops/test` | ||
| - Test files follow `*_test.ts` naming convention | ||
| - Use `@std/assert` for assertions | ||
|
|
||
| ### Libraries | ||
|
|
||
| - Use `@core/unknownutil` for type-guarding unknown types | ||
| - 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. | ||
| - Use `@denops/std` for Vim/Neovim API access. | ||
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| import { unnullish } from "@lambdalisue/unnullish"; | ||
|
|
||
| import { definePreviewer, type Previewer } from "../../previewer.ts"; | ||
| import { splitText } from "../../util/stringutil.ts"; | ||
|
|
||
| type Detail = { | ||
| /** | ||
| * Command to execute | ||
| */ | ||
| command?: string; | ||
|
|
||
| /** | ||
| * Arguments to pass to the command | ||
| */ | ||
| args?: string[]; | ||
|
|
||
| /** | ||
| * Current working directory for command execution | ||
| */ | ||
| cwd?: string; | ||
|
|
||
| /** | ||
| * Environment variables | ||
| */ | ||
| env?: Record<string, string>; | ||
|
|
||
| /** | ||
| * Timeout in milliseconds | ||
| */ | ||
| timeout?: number; | ||
| }; | ||
|
|
||
| export type ShellOptions = { | ||
| /** | ||
| * Default shell to use if no command is specified. | ||
| * @default ["sh", "-c"] | ||
| */ | ||
| shell?: string[]; | ||
|
|
||
| /** | ||
| * Default timeout in milliseconds. | ||
| * @default 5000 | ||
| */ | ||
| defaultTimeout?: number; | ||
|
|
||
| /** | ||
| * Maximum number of lines to display. | ||
| * @default 1000 | ||
| */ | ||
| maxLines?: number; | ||
| }; | ||
|
|
||
| /** | ||
| * Creates a Previewer that executes shell commands and displays their output. | ||
| * | ||
| * This Previewer runs a specified command and shows its stdout/stderr output. | ||
| * It supports custom working directories, environment variables, and timeouts. | ||
| * | ||
| * @param options - Options to customize shell command execution. | ||
| * @returns A Previewer that shows the command output. | ||
| */ | ||
| export function shell(options: Readonly<ShellOptions> = {}): Previewer<Detail> { | ||
| const shell = options.shell ?? ["sh", "-c"]; | ||
| const defaultTimeout = options.defaultTimeout ?? 5000; | ||
| const maxLines = options.maxLines ?? 1000; | ||
|
|
||
| return definePreviewer(async (_denops, { item }, { signal }) => { | ||
| // Get command from detail or use item value as command | ||
| const command = item.detail.command ?? item.value; | ||
| const args = item.detail.args ?? []; | ||
| const cwd = item.detail.cwd; | ||
| const env = item.detail.env; | ||
| const timeout = item.detail.timeout ?? defaultTimeout; | ||
|
|
||
| // Prepare command array | ||
| let cmd: string[]; | ||
| if (args.length > 0) { | ||
| cmd = [command, ...args]; | ||
| } else { | ||
| // Use shell to execute the command string | ||
| cmd = [...shell, command]; | ||
| } | ||
|
|
||
| try { | ||
| // Create subprocess | ||
| const process = new Deno.Command(cmd[0], { | ||
| args: cmd.slice(1), | ||
| cwd: unnullish(cwd, (v) => v), | ||
| env: unnullish(env, (v) => v), | ||
| stdout: "piped", | ||
| stderr: "piped", | ||
| signal, | ||
| }); | ||
|
|
||
| // Set up timeout | ||
| const timeoutId = setTimeout(() => { | ||
| try { | ||
| process.spawn().kill(); | ||
| } catch { | ||
| // Ignore errors when killing | ||
| } | ||
| }, timeout); | ||
|
|
||
| try { | ||
| // Execute command | ||
| const { stdout, stderr, success } = await process.output(); | ||
| clearTimeout(timeoutId); | ||
|
|
||
| // Decode output | ||
| const decoder = new TextDecoder(); | ||
| const stdoutText = decoder.decode(stdout); | ||
| const stderrText = decoder.decode(stderr); | ||
|
|
||
| // Combine stdout and stderr | ||
| let content: string[] = []; | ||
|
|
||
| if (stdoutText) { | ||
| content.push(...splitText(stdoutText)); | ||
| } | ||
|
|
||
| if (stderrText) { | ||
| if (content.length > 0) { | ||
| content.push("--- stderr ---"); | ||
| } | ||
| content.push(...splitText(stderrText)); | ||
| } | ||
|
|
||
| // Add status line if command failed | ||
| if (!success) { | ||
| content.push("", `[Command failed with non-zero exit code]`); | ||
| } | ||
|
|
||
| // Limit output lines | ||
| if (content.length > maxLines) { | ||
| content = content.slice(0, maxLines); | ||
| content.push("", `[Output truncated to ${maxLines} lines]`); | ||
| } | ||
|
|
||
| // Handle empty output | ||
| if (content.length === 0) { | ||
| content = ["[No output]"]; | ||
| } | ||
|
|
||
| return { | ||
| content, | ||
| filename: `$ ${cmd.join(" ")}`, | ||
| }; | ||
| } finally { | ||
| clearTimeout(timeoutId); | ||
| } | ||
| } catch (err) { | ||
| // Handle command execution errors | ||
| return { | ||
| content: [ | ||
| `Error executing command: ${command}`, | ||
| "", | ||
| ...String(err).split("\n"), | ||
| ], | ||
| filename: `$ ${cmd.join(" ")}`, | ||
| }; | ||
| } | ||
| }); | ||
| } | ||
Oops, something went wrong.
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.
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.