Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
TwIStOy committed Dec 12, 2023
1 parent 1b83bea commit c5594d4
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 77 deletions.
176 changes: 156 additions & 20 deletions src/conf/lsp/index.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,168 @@
import { KittyBackend } from "@core/components/image/backend/kitty";
import { Image } from "@core/components/image/image";
import { MarkupRenderer } from "@core/format/markdown";
import { info } from "@core/utils/logger";
import { isNil } from "@core/vim";
import { Hover, MarkupContent } from "vscode-languageserver-types";
import {
CodeBlockNode,
PangoMarkupGenerator,
RenderedElement,
SpanNode,
} from "@core/format/rendered-node";
import { termGetSize } from "@core/utils/term";
import { cursorPositionToClient, ifNil, isNil } from "@core/vim";
import { BuildContext } from "@glib/build-context";
import { Widget } from "@glib/widget";
import { Container } from "@glib/widgets";
import { Padding } from "@glib/widgets/_utils";
import { Column } from "@glib/widgets/column";
import { Markup } from "@glib/widgets/markup";
import {
Hover,
MarkedString,
MarkupContent,
} from "vscode-languageserver-types";

function isMarkupContent(arg: any): arg is MarkupContent {
return !isNil(arg.kind);
}

function intoWidget(m: RenderedElement): Widget {
let hl_normal = vim.api.nvim_get_hl(0, {
name: "NormalFloat",
});
let fg = ifNil(hl_normal.get("guifg"), hl_normal.get("fg"));
if (m.kind === "line") {
return Markup(m.markup);
} else if (m.kind === "lines") {
return Column({
children: m.lines.map((p) => intoWidget(p)),
});
} else {
return Container({
margin: Padding.vertical(4),
height: m.width,
width: "expand",
color: fg,
});
}
}

function buildImage(contents: MarkupContent | MarkedString | MarkedString[]) {
let root;
if (isMarkupContent(contents)) {
let markup = new MarkupRenderer(contents.value);
root = markup.render();
} else {
let parts = [];
if (vim.tbl_islist(contents)) {
for (let m of contents) {
if (typeof m === "string") {
parts.push(new CodeBlockNode(m, null));
} else {
parts.push(new CodeBlockNode(m.value, m.language));
}
}
}
root = new SpanNode(parts);
}
let pango = new PangoMarkupGenerator();
root.intoPangoMarkup(pango);
let data = pango.done();
let widgets = data.map((p) => intoWidget(p));

let hl_normal = vim.api.nvim_get_hl(0, {
name: "NormalFloat",
});
let bg = ifNil(hl_normal.get("guibg"), hl_normal.get("bg"));
let rootWidget = Container({
color: bg,
border: { width: 4, color: "black", radius: 20 },
height: "shrink",
width: "shrink",
padding: Padding.all(10),
child: Column({
children: widgets,
}),
});

let context = new BuildContext(800, 600);
rootWidget.calculateRenderBox(context);
rootWidget.build(context);
let imageData = context.renderer.toPngBytes();
return {
data: imageData,
width: rootWidget._renderBox!.width,
height: rootWidget._renderBox!.height,
};
}

export function showHover() {
// vim.o.eventignore = "CursorHold";
// vim.api.nvim_exec_autocmds("User", {
// pattern: "ShowHover",
// });
bufHover();
}

function isMarkupContent(arg: any): arg is MarkupContent {
return !isNil(arg.kind);
class HoverImage {
private image: Image;

constructor(
data: number[],
private x: number,
private y: number
) {
this.image = Image.fromBuffer(data);

vim.o.eventignore = "CursorHold";
// close current diagnostic window
vim.api.nvim_exec_autocmds("User", {
pattern: "ShowHover",
});
vim.api.nvim_create_autocmd(
["CursorMoved", "FocusLost", "WinLeave", "WinClosed"],
{
once: true,
callback: () => {
this.delete();
return true;
},
}
);
vim.schedule(() => {
this.image.render(this.x, this.y);
});
}

delete() {
vim.schedule(() => {
KittyBackend.getInstance().delete(this.image.id);
});
}
}

function hoverCallback(
contents: MarkupContent | MarkedString | MarkedString[]
) {
let { data, width, height } = buildImage(contents);
vim.o.eventignore = "CursorHold";
// close current diagnostic window
vim.api.nvim_exec_autocmds("User", {
pattern: "ShowHover",
});
let termSize = termGetSize();
let imageWidthCells = Math.ceil(width / termSize.cell_width);
let imageHeightCells = Math.ceil(height / termSize.cell_height);
// let image = Image.fromBuffer(data);
let cursor = cursorPositionToClient();
let xOffset = Math.min(termSize.screen_cols - cursor.col - imageWidthCells);
let yOffset = Math.min(termSize.screen_rows - cursor.row - imageHeightCells);
new HoverImage(data, xOffset, yOffset);
}

function bufHover() {
let params = luaRequire("vim.lsp.util").make_position_params();
vim.lsp.buf_request(0, "textDocument/hover", params, (err, res, _context) => {
let result = res as Hover;
result.contents;
if (isMarkupContent(result.contents)) {
let [file] = io.open("/tmp/test.md", "w");
file?.write(result.contents.value);
file?.close();
info("markup content! %s", result.contents.value);
// let markup = new MarkupRenderer(result.contents.value);
vim.lsp.buf_request(
0,
"textDocument/hover",
params,
(_err, res: Hover, _context) => {
hoverCallback(res.contents);
}
info("%s %s", err, res);
});
);
}
4 changes: 2 additions & 2 deletions src/core/components/image/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ export class Image {
let left_cells = pane_left + cursor_x;
let top_cells = pane_top + cursor_y;
let termSize = termGetSize();
x = ifNil(x, 0) + termSize.cell_width * left_cells;
y = ifNil(y, 0) + termSize.cell_height * top_cells;
x = (ifNil(x, 0) + left_cells) * termSize.cell_width;
y = (ifNil(y, 0) + top_cells) * termSize.cell_height;
debug_("termSize: %s", vim.inspect(termSize));
}
debug_("render image at (%s, %s)", x, y);
Expand Down
13 changes: 13 additions & 0 deletions src/core/vim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,16 @@ export function sleep(ms: number): Promise<void> {
}, ms);
});
}

export function cursorPositionToClient(): CursorPosition {
let [row, col] = vim.api.nvim_win_get_cursor(0);
let win_pos = vim.api.nvim_win_get_position(0);
let lineStart = vim.fn.line("w0");

row = row - lineStart + win_pos[0];
col = col + win_pos[1];
return {
row,
col,
};
}
113 changes: 58 additions & 55 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { mountRightClickMenu } from "@conf/ui/right-click";
import { Image } from "@core/components/image/image";
import { Command } from "@core/model";
import { VimBuffer, hideCursor, ifNil } from "@core/vim";
import { VimBuffer, cursorPositionToClient, hideCursor, ifNil } from "@core/vim";
import { Padding } from "@glib/widgets/_utils";
import { Container } from "@glib/widgets/container";
import { Text } from "@glib/widgets/text/text";
Expand All @@ -20,6 +20,7 @@ import {
RenderedElement,
} from "@core/format/rendered-node";
import { Widget } from "@glib/widget";
import { termGetSize } from "@core/utils/term";

export * as _ from "@glib/index";
export { AllLspServers } from "./conf/external_tools";
Expand Down Expand Up @@ -67,59 +68,61 @@ function intoWidget(m: RenderedElement, fg: number): Widget[] {
}

export function test() {
let [file] = io.open("/tmp/test.md", "r");
let content = file!.read("*a");
file!.close();

info("content: %s", content);

let render = new MarkupRenderer(content!);
let rr = render.render();
info("rr:\n%s", rr.debugStringLines().join("\n"));
let generator = new PangoMarkupGenerator();

let context = new BuildContext(1000, 400);

rr.intoPangoMarkup(generator);

let paragraphs = generator.done();

let hl_normal = vim.api.nvim_get_hl(0, {
name: "NormalFloat",
});
let background = ifNil(hl_normal.get("guibg"), hl_normal.get("bg"));
let foreground = ifNil(hl_normal.get("guifg"), hl_normal.get("fg"));

let root = Container({
color: background,
border: { width: 4, color: "black", radius: 20 },
height: "shrink",
width: "shrink",
padding: Padding.all(10),
child: Column({
children: [
...paragraphs
.map((m) => {
return intoWidget(m, foreground);
})
.flat(),
Spacing(),
],
}),
});
try {
root.calculateRenderBox(context);
root.build(context);
} catch (e) {
error_("build failed, %s", e);
}

let data = context.renderer.toPngBytes();
vim.schedule(() => {
KittyBackend.getInstance().deleteAll();
let image = Image.fromBuffer(data);
image.render(0, 0);
info("=====================================================");
});
// let [file] = io.open("/tmp/test.md", "r");
// let content = file!.read("*a");
// file!.close();
//
// info("content: %s", content);
//
// let render = new MarkupRenderer(content!);
// let rr = render.render();
// info("rr:\n%s", rr.debugStringLines().join("\n"));
// let generator = new PangoMarkupGenerator();
//
// let context = new BuildContext(1000, 400);
//
// rr.intoPangoMarkup(generator);
//
// let paragraphs = generator.done();
//
// let hl_normal = vim.api.nvim_get_hl(0, {
// name: "NormalFloat",
// });
// let background = ifNil(hl_normal.get("guibg"), hl_normal.get("bg"));
// let foreground = ifNil(hl_normal.get("guifg"), hl_normal.get("fg"));
//
// let root = Container({
// color: background,
// border: { width: 4, color: "black", radius: 20 },
// height: "shrink",
// width: "shrink",
// padding: Padding.all(10),
// child: Column({
// children: [
// ...paragraphs
// .map((m) => {
// return intoWidget(m, foreground);
// })
// .flat(),
// Spacing(),
// ],
// }),
// });
// try {
// root.calculateRenderBox(context);
// root.build(context);
// } catch (e) {
// error_("build failed, %s", e);
// }
//
// let data = context.renderer.toPngBytes();
// vim.schedule(() => {
// KittyBackend.getInstance().deleteAll();
// let image = Image.fromBuffer(data);
// image.render(0, 0);
// info("=====================================================");
// });
let termSize = termGetSize();
info("term: %s, cursor: %s", termSize, cursorPositionToClient());
return toUtfChars("abcdd我");
}
2 changes: 2 additions & 0 deletions src/types/vim/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,5 +254,7 @@ declare namespace vim {
): LuaTable;

export function nvim_get_namespaces(): LuaTable<string, number>;

export function nvim_win_get_position(window: number): [number, number];
}
}

0 comments on commit c5594d4

Please sign in to comment.