From b52c45baff5792f7fe9c31a78f8411237200def7 Mon Sep 17 00:00:00 2001 From: Shane Smith Date: Sat, 22 Jun 2024 22:34:35 -0400 Subject: [PATCH] Fix error "E1502: Lua failed to grow stack to 4001" The `neoVimBuffer` function was updated in #1015 to used a lua script through `nvimExecLua`. The script returns the dictionary retrieved from the `getbufinfo` vim functions. The issue is that this can grow very large, especially the `variables` entry, and can cause the lua stack to grow too big and error. In the end the `neoVimBuffer` function only needs a small handful of the entries from `getbufinfo`, and so the lua script has been updated to return a dictionary with only those entries. At the same time the `hasDirtyBuffers` function was found to also return the `getbufinfo` dictionary and was similarly fixed. It was also noticed that the argument passed into `getbuinfo` here was a vim style dictionary and not valid lua. This made `hasDirtyBuffers` fail and caused an issue in `MainWindow.windowShouldClose` where selecting `File > Close Window` would close the window even when dirty buffers were present. The proper lua dictionary syntax is now used and fixes this issues. Fixes #1044 --- NvimView/Sources/NvimView/NvimView+Api.swift | 34 ++++++++------------ 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/NvimView/Sources/NvimView/NvimView+Api.swift b/NvimView/Sources/NvimView/NvimView+Api.swift index 117ec93b6..1879bd252 100644 --- a/NvimView/Sources/NvimView/NvimView+Api.swift +++ b/NvimView/Sources/NvimView/NvimView+Api.swift @@ -40,13 +40,14 @@ public extension NvimView { func hasDirtyBuffers() -> Single { self.api .nvimExecLua(code: """ - return vim.fn.getbufinfo({"bufmodified": v:true}) + local buffers = vim.fn.getbufinfo({bufmodified = true}) + return #buffers > 0 """, args: []) .map { result -> Bool in - guard let info_array = result.arrayValue else { - throw RxNeovimApi.Error.exception(message: "Could not convert values into info array.") + guard let bool = result.boolValue else { + throw RxNeovimApi.Error.exception(message: "Could not convert values into boolean.") } - return info_array.count > 0 + return bool } } @@ -264,25 +265,18 @@ public extension NvimView { currentBuffer: RxNeovimApi.Buffer? ) -> Single { self.api.nvimExecLua(code: """ - local function map(tbl, f) - local t = {} - for k,v in pairs(tbl) do - t[k] = f(v) - end - return t - end - return map(vim.fn.getbufinfo(...), function(i) - i.buftype = vim.api.nvim_get_option_value("buftype", - {buf=i.bufnr}) - return i - end) + local info = vim.fn.getbufinfo(...)[1] + local result = {} + result.name = info.name + result.changed = info.changed + result.listed = info.listed + result.buftype = vim.api.nvim_get_option_value("buftype", {buf=info.bufnr}) + return result """, args: [MessagePackValue(buf.handle)]) .map { result -> NvimView.Buffer in - guard let info_array = result.arrayValue, - info_array.count == 1, - let raw_info = info_array[0].dictionaryValue + guard let raw_info = result.dictionaryValue else { - throw RxNeovimApi.Error.exception(message: "Could not convert values into info array.") + throw RxNeovimApi.Error.exception(message: "Could not convert values into info dictionary.") } let info: [String: MessagePackValue] = .init( uniqueKeysWithValues: raw_info.map {