mirror of
https://mzte.de/git/LordMZTE/dotfiles.git
synced 2024-12-14 16:33:40 +01:00
port nvim-cmp tab handler to zig
This commit is contained in:
parent
16e21c8274
commit
6176faad12
3 changed files with 117 additions and 17 deletions
|
@ -1,11 +1,6 @@
|
|||
local cmp = require "cmp"
|
||||
local luasnip = require "luasnip"
|
||||
|
||||
-- checks if the char before the cursor is a whitespace
|
||||
local function has_words_before()
|
||||
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match "%s" == nil
|
||||
end
|
||||
local mztenv = require "mzte_nv"
|
||||
|
||||
cmp.setup {
|
||||
snippet = {
|
||||
|
@ -18,17 +13,7 @@ cmp.setup {
|
|||
["<C-b>"] = cmp.mapping(cmp.mapping.scroll_docs(-4), { "i", "c" }),
|
||||
["<C-f>"] = cmp.mapping(cmp.mapping.scroll_docs(4), { "i", "c" }),
|
||||
["<C-Space>"] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }),
|
||||
["<Tab>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_next_item()
|
||||
elseif luasnip.expand_or_jumpable() then
|
||||
luasnip.expand_or_jump()
|
||||
elseif has_words_before() then
|
||||
cmp.complete()
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, { "i", "s" }),
|
||||
["<Tab>"] = cmp.mapping(mztenv.cmp.onTab, { "i", "s" }),
|
||||
["<S-Tab>"] = cmp.mapping(cmp.mapping.select_prev_item()),
|
||||
["<CR>"] = cmp.mapping.confirm { select = true },
|
||||
},
|
||||
|
|
|
@ -6,6 +6,7 @@ const c = ffi.c;
|
|||
pub const version = "0.2.0";
|
||||
|
||||
const modules = struct {
|
||||
const cmp = @import("modules/cmp.zig");
|
||||
const jdtls = @import("modules/jdtls.zig");
|
||||
};
|
||||
|
||||
|
@ -13,6 +14,7 @@ export fn luaopen_mzte_nv(l_: ?*c.lua_State) c_int {
|
|||
const l = l_.?;
|
||||
ser.luaPushAny(l, .{
|
||||
.onInit = ffi.luaFunc(lOnInit),
|
||||
.cmp = modules.cmp,
|
||||
.jdtls = modules.jdtls,
|
||||
});
|
||||
return 1;
|
||||
|
|
113
mzte-nv/src/modules/cmp.zig
Normal file
113
mzte-nv/src/modules/cmp.zig
Normal file
|
@ -0,0 +1,113 @@
|
|||
const std = @import("std");
|
||||
const ser = @import("../ser.zig");
|
||||
const ffi = @import("../ffi.zig");
|
||||
const c = ffi.c;
|
||||
|
||||
pub fn luaPush(l: *c.lua_State) void {
|
||||
ser.luaPushAny(l, .{
|
||||
.onTab = ffi.luaFunc(lOnTab),
|
||||
});
|
||||
}
|
||||
|
||||
fn lOnTab(l: *c.lua_State) !c_int {
|
||||
// param 1 is the fallback function
|
||||
c.luaL_checktype(l, 1, c.LUA_TFUNCTION);
|
||||
|
||||
// vim.api at idx 2
|
||||
c.lua_getglobal(l, "vim");
|
||||
c.lua_getfield(l, -1, "api");
|
||||
c.lua_remove(l, 2);
|
||||
|
||||
// cmp module on stack idx 3
|
||||
c.lua_getglobal(l, "require");
|
||||
c.lua_pushstring(l, "cmp");
|
||||
c.lua_call(l, 1, 1);
|
||||
|
||||
// luasnip module on stack idx 4
|
||||
c.lua_getglobal(l, "require");
|
||||
c.lua_pushstring(l, "luasnip");
|
||||
c.lua_call(l, 1, 1);
|
||||
|
||||
// call cmp.visible()
|
||||
c.lua_getfield(l, 3, "visible");
|
||||
c.lua_call(l, 0, 1);
|
||||
const cmp_visible = c.lua_toboolean(l, -1);
|
||||
c.lua_pop(l, 1);
|
||||
|
||||
if (cmp_visible != 0) {
|
||||
// call cmp.select_next_item()
|
||||
c.lua_getfield(l, 3, "select_next_item");
|
||||
c.lua_call(l, 0, 0);
|
||||
} else if (blk: {
|
||||
// call luasnip.expand_or_jumpable()
|
||||
c.lua_getfield(l, 4, "expand_or_jumpable");
|
||||
c.lua_call(l, 0, 1);
|
||||
const b = c.lua_toboolean(l, -1) != 0;
|
||||
c.lua_pop(l, 1);
|
||||
break :blk b;
|
||||
}) {
|
||||
// call luasnip.expand_or_jump()
|
||||
c.lua_getfield(l, 4, "expand_or_jump");
|
||||
c.lua_call(l, 0, 0);
|
||||
} else if (blk: {
|
||||
// in this if, we check if the char before the cursor is NOT a whitespace,
|
||||
// in which case we have cmp complete.
|
||||
|
||||
// call vim.api.nvim_win_get_cursor(0), returns the cursor position in the current buf
|
||||
// in an array table with 2 values
|
||||
c.lua_getfield(l, 2, "nvim_win_get_cursor");
|
||||
c.lua_pushinteger(l, 0);
|
||||
c.lua_call(l, 1, 1);
|
||||
|
||||
c.lua_rawgeti(l, -1, 1);
|
||||
const cursor_line = c.lua_tointeger(l, -1);
|
||||
c.lua_pop(l, 1);
|
||||
|
||||
c.lua_rawgeti(l, -1, 2);
|
||||
const cursor_col = c.lua_tointeger(l, -1);
|
||||
c.lua_pop(l, 2);
|
||||
|
||||
// If the cursor column is 0, that counts as a whitespace.
|
||||
if (cursor_col == 0) {
|
||||
break :blk false;
|
||||
}
|
||||
|
||||
// call vim.api.nvim_buf_get_lines(0, line - 1, line, true)
|
||||
// returns in array containing the line the cursor is at
|
||||
c.lua_getfield(l, 2, "nvim_buf_get_lines");
|
||||
c.lua_pushinteger(l, 0);
|
||||
c.lua_pushinteger(l, cursor_line - 1);
|
||||
c.lua_pushinteger(l, cursor_line);
|
||||
c.lua_pushboolean(l, 1);
|
||||
c.lua_call(l, 4, 1);
|
||||
|
||||
// get the line
|
||||
c.lua_rawgeti(l, -1, 1);
|
||||
var strlen: usize = 0;
|
||||
const line = c.lua_tolstring(l, -1, &strlen)[0..strlen];
|
||||
|
||||
// char at the cursor is NOT whitespace
|
||||
const b = std.mem.indexOfScalar(
|
||||
u8,
|
||||
" \t\n",
|
||||
line[@intCast(usize, cursor_col) - 1],
|
||||
) == null;
|
||||
|
||||
// remove the string and the string array from the stack
|
||||
c.lua_pop(l, 2);
|
||||
|
||||
break :blk b;
|
||||
}) {
|
||||
// call cmp.complete()
|
||||
c.lua_getfield(l, 3, "complete");
|
||||
c.lua_call(l, 0, 0);
|
||||
} else {
|
||||
// call fallback function
|
||||
c.lua_pushvalue(l, 1);
|
||||
c.lua_call(l, 0, 0);
|
||||
}
|
||||
|
||||
// clear stack
|
||||
c.lua_settop(l, 0);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue