Skip to content
Closed
Show file tree
Hide file tree
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 Jul 5, 2025
6bdfbe0
feat(source): add window source for listing Vim windows
lambdalisue Jul 6, 2025
ad2d410
feat(source): add tabpage source for listing Vim tab pages
lambdalisue Jul 6, 2025
9004a59
feat(source): add loclist source for listing location list items
lambdalisue Jul 6, 2025
d337686
feat(source): add colorscheme source for listing available colorschemes
lambdalisue Jul 6, 2025
d8a627c
feat(source): add highlight source for listing highlight groups
lambdalisue Jul 6, 2025
33e58cd
feat(source): add jumplist source for listing jump locations
lambdalisue Jul 6, 2025
fd1a7c8
feat(source): add register source for listing Vim registers
lambdalisue Jul 6, 2025
5006534
feat(source): add mark source for listing Vim marks
lambdalisue Jul 6, 2025
1c0e825
feat(source): add command source for listing user-defined commands
lambdalisue Jul 6, 2025
9c39f46
feat(source): add mapping source for listing key mappings
lambdalisue Jul 6, 2025
e8f21f1
feat(source): add git status source for listing modified files
lambdalisue Jul 6, 2025
881a059
feat(source): add grep source for vim's :grep command results
lambdalisue Jul 6, 2025
c3bf51b
feat(source): add vimgrep source for vim's :vimgrep command results
lambdalisue Jul 6, 2025
89e0265
feat(source): add autocmd source for vim autocmds
lambdalisue Jul 6, 2025
c74961d
feat(previewer): add shell command previewer
lambdalisue Jul 6, 2025
bfba569
feat(renderer): add file info renderer for displaying file metadata
lambdalisue Jul 6, 2025
8090011
feat(renderer): add buffer info renderer for displaying buffer metadata
lambdalisue Jul 6, 2025
0f0a8f2
feat(renderer): add smart grep renderer for formatting grep-like results
lambdalisue Jul 6, 2025
e9a3319
feat(refiner): add file info refiner for filtering by file properties
lambdalisue Jul 6, 2025
c166b92
feat(refiner): add buffer info refiner for filtering by buffer proper…
lambdalisue Jul 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions CLAUDE.md
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.
Copy link
Contributor Author

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.

- Use `@denops/std` for Vim/Neovim API access.
1 change: 1 addition & 0 deletions builtin/previewer/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from "./buffer.ts";
export * from "./file.ts";
export * from "./helptag.ts";
export * from "./noop.ts";
export * from "./shell.ts";
163 changes: 163 additions & 0 deletions builtin/previewer/shell.ts
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;

Check warning on line 65 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L62-L65

Added lines #L62 - L65 were not covered by tests

return definePreviewer(async (_denops, { item }, { signal }) => {

Check warning on line 67 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L67

Added line #L67 was not covered by tests
// 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;

Check warning on line 73 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L69-L73

Added lines #L69 - L73 were not covered by tests

// Prepare command array
let cmd: string[];
if (args.length > 0) {
cmd = [command, ...args];
} else {

Check warning on line 79 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L76-L79

Added lines #L76 - L79 were not covered by tests
// Use shell to execute the command string
cmd = [...shell, command];
}

Check warning on line 82 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L81-L82

Added lines #L81 - L82 were not covered by tests

try {

Check warning on line 84 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L84

Added line #L84 was not covered by tests
// 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,
});

Check warning on line 93 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L86-L93

Added lines #L86 - L93 were not covered by tests

// Set up timeout
const timeoutId = setTimeout(() => {
try {
process.spawn().kill();
} catch {

Check warning on line 99 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L96-L99

Added lines #L96 - L99 were not covered by tests
// Ignore errors when killing
}
}, timeout);

Check warning on line 102 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L101-L102

Added lines #L101 - L102 were not covered by tests

try {

Check warning on line 104 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L104

Added line #L104 was not covered by tests
// Execute command
const { stdout, stderr, success } = await process.output();
clearTimeout(timeoutId);

Check warning on line 107 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L106-L107

Added lines #L106 - L107 were not covered by tests

// Decode output
const decoder = new TextDecoder();
const stdoutText = decoder.decode(stdout);
const stderrText = decoder.decode(stderr);

Check warning on line 112 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L110-L112

Added lines #L110 - L112 were not covered by tests

// Combine stdout and stderr
let content: string[] = [];

Check warning on line 115 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L115

Added line #L115 was not covered by tests

if (stdoutText) {
content.push(...splitText(stdoutText));
}

Check warning on line 119 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L117-L119

Added lines #L117 - L119 were not covered by tests

if (stderrText) {
if (content.length > 0) {
content.push("--- stderr ---");
}
content.push(...splitText(stderrText));
}

Check warning on line 126 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L121-L126

Added lines #L121 - L126 were not covered by tests

// Add status line if command failed
if (!success) {
content.push("", `[Command failed with non-zero exit code]`);
}

Check warning on line 131 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L129-L131

Added lines #L129 - L131 were not covered by tests

// Limit output lines
if (content.length > maxLines) {
content = content.slice(0, maxLines);
content.push("", `[Output truncated to ${maxLines} lines]`);
}

Check warning on line 137 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L134-L137

Added lines #L134 - L137 were not covered by tests

// Handle empty output
if (content.length === 0) {
content = ["[No output]"];
}

Check warning on line 142 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L140-L142

Added lines #L140 - L142 were not covered by tests

return {
content,
filename: `$ ${cmd.join(" ")}`,
};
} finally {
clearTimeout(timeoutId);
}
} catch (err) {

Check warning on line 151 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L144-L151

Added lines #L144 - L151 were not covered by tests
// Handle command execution errors
return {
content: [
`Error executing command: ${command}`,
"",
...String(err).split("\n"),
],
filename: `$ ${cmd.join(" ")}`,
};
}
});
}

Check warning on line 163 in builtin/previewer/shell.ts

View check run for this annotation

Codecov / codecov/patch

builtin/previewer/shell.ts#L153-L163

Added lines #L153 - L163 were not covered by tests
Loading