Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions builtin/source/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export * from "./list.ts";
export * from "./noop.ts";
export * from "./oldfiles.ts";
export * from "./quickfix.ts";
export * from "./tabpage.ts";
export * from "./window.ts";
119 changes: 119 additions & 0 deletions builtin/source/tabpage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import * as fn from "@denops/std/function";
import { collect } from "@denops/std/batch";

import { defineSource, type Source } from "../../source.ts";

type Detail = {
/**
* Tab page number (1-indexed)
*/
tabnr: number;

/**
* Tab page variables
*/
variables: Record<string, unknown>;

/**
* Windows in the tab page
*/
windows: fn.WinInfo[];
};

export type TabpageOptions = {
/**
* Whether to include the tab label.
* If true, uses the tab label if set, otherwise shows buffer names.
* @default true
*/
showLabel?: boolean;

/**
* The indicator string for the current tab.
* @default "> "
*/
indicator?: string;
};

/**
* Creates a Source that generates items from Vim tab pages.
*
* This Source retrieves information about all tab pages and generates items
* for each tab with details about windows and buffers in that tab.
*
* @param options - Options to customize tabpage listing.
* @returns A Source that generates items representing tab pages.
*/
export function tabpage(
options: Readonly<TabpageOptions> = {},
): Source<Detail> {
const showLabel = options.showLabel ?? true;
return defineSource(async function* (denops, _params, { signal }) {
const [currentTabnr, lastTabnr, allWininfos] = await collect(
denops,
(denops) => [
fn.tabpagenr(denops),
fn.tabpagenr(denops, "$"),
fn.getwininfo(denops),
],
);
signal?.throwIfAborted();

const items = [];
for (let tabnr = 1; tabnr <= lastTabnr; tabnr++) {
// Get windows in this tab
const windows = allWininfos.filter((w) => w.tabnr === tabnr);
const windowCount = windows.length;

// Get tab variables
const variables = await fn.gettabvar(denops, tabnr, "") as Record<
string,
unknown
>;

let label: string;
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 {
Comment on lines +75 to +93
Copy link
Member Author

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.

label = `Tab ${tabnr}`;
}

// Add current tab indicator
const indicator = options.indicator ?? "> ";
const prefix = tabnr === currentTabnr
? indicator
: " ".repeat(indicator.length);
const value = `${prefix}${tabnr}: ${label} (${windowCount} window${
windowCount !== 1 ? "s" : ""
})`;
Comment on lines +102 to +104
Copy link
Member Author

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}.


items.push({
id: tabnr - 1,
value,
detail: {
tabnr,
variables,
windows,
},
});
}

yield* items;
});
}