Skip to content
Open
Changes from all commits
Commits
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
61 changes: 49 additions & 12 deletions lua/contextindent/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,10 @@ M.setup = function(opts)
end

---Evaluate a vimscript function safely
---@param x string the function to evaluate
---@param expr string the function to evaluate
---@return any
local safe_eval = function(x)
local fn_name = x:gsub("%(%)$", "")
if fn_name == "" then return end
local ok, res = pcall(function() return vim.fn[fn_name]() end)
local safe_eval = function(expr)
local ok, res = pcall(vim.api.nvim_eval, expr)
return ok and res or nil
end

Expand All @@ -52,25 +50,64 @@ M.context_indent = function(buf_indentexpr)
return safe_eval(buf_indentexpr) or -1
end

local curr_ft = parser:language_for_range({ vim.v.lnum, 0, vim.v.lnum, 1 }):lang()
local curr_parser_name = parser:language_for_range({ vim.v.lnum, 0, vim.v.lnum, 1 }):lang()
local curr_ft
if curr_parser_name == 'c_sharp' then
curr_ft = 'cs'
elseif curr_parser_name == 'powershell' then
curr_ft = 'ps1'
else
curr_ft = curr_parser_name
end

if curr_ft == "" or curr_ft == vim.bo.filetype then
if buf_indentexpr == "" then
if vim.bo.cindent then
return vim.fn.cindent(vim.v.lnum)
elseif vim.bo.autoindent and vim.bo.smartindent then
return vim.fn.indent(vim.v.lnum)
end
end
return safe_eval(buf_indentexpr) or -1
end

---@as string
local curr_indentexpr = vim.filetype.get_option(curr_ft, "indentexpr")

local indent = -1

local buf_shiftwidth = vim.bo.shiftwidth
local buf_cindent = vim.bo.cindent
local buf_autoindent = vim.bo.autoindent
local buf_smartindent = vim.bo.smartindent

vim.bo.shiftwidth = vim.filetype.get_option(curr_ft, "shiftwidth")

if curr_indentexpr == "" or type(curr_indentexpr) ~= "string" then
return -1
--NOTE: cindent is not stable in context code, but generally ok
if vim.filetype.get_option(curr_ft, "cindent") then
vim.bo.cindent = true
vim.bo.cinoptions = vim.filetype.get_option(curr_ft, "cinoptions")
vim.bo.cinwords = vim.filetype.get_option(curr_ft, "cinwords")
vim.bo.cinkeys = vim.filetype.get_option(curr_ft, "cinkeys")
vim.bo.cinscopedecls = vim.filetype.get_option(curr_ft, "cinscopedecls")
indent = vim.fn.cindent(vim.v.lnum)
elseif vim.filetype.get_option(curr_ft, "autoindent") and vim.filetype.get_option(curr_ft, "smartindent") then
vim.bo.autoindent = true
vim.bo.smartindent = true
indent = vim.fn.indent(vim.v.lnum)
end
else
indent = safe_eval(curr_indentexpr) or -1
end

local buf_shiftwidth = vim.bo.shiftwidth
vim.bo.shiftwidth = vim.filetype.get_option(curr_ft, "shiftwidth")
local indent = safe_eval(curr_indentexpr)
vim.bo.shiftwidth = buf_shiftwidth
-- finally restore buf options
vim.bo.shiftwidth = buf_shiftwidth
vim.bo.cindent = buf_cindent
vim.bo.smartindent = buf_smartindent
vim.bo.autoindent = buf_autoindent

return indent or -1
return indent
end

return M
Expand Down