150 lines
4.2 KiB
Lua
150 lines
4.2 KiB
Lua
--[[
|
|
1. Synchronize options: tabstop, shiftwidth, expandtab, number, relativenumber
|
|
Check for changes in nvim and then send them to vscode
|
|
Receive changes from vscode and set nvim options
|
|
|
|
2. Process modeline
|
|
The buffer's initial text is filled after creating the buffer,
|
|
the modeline processing needs to be triggered manually.
|
|
Additionally, the scratch buffer sets nomodeline by default.
|
|
]]
|
|
|
|
local api = vim.api
|
|
local vscode = require("vscode.api")
|
|
local util = require("vscode.util")
|
|
|
|
local M = {}
|
|
|
|
---@class EditorOptions
|
|
---@field tabSize number
|
|
---@field insertSpaces boolean
|
|
---@field lineNumbers "on"|"off"|"relative"
|
|
|
|
---@param nu boolean number
|
|
---@param rnu boolean relativenumber
|
|
---@return "on"|"off"|"relative"
|
|
local function get_number_style(nu, rnu)
|
|
return rnu and "relative" or nu and "on" or "off"
|
|
end
|
|
|
|
---@param win number
|
|
---@param lineNumbers "on"|"off"|"relative"
|
|
local function set_number(win, lineNumbers)
|
|
if lineNumbers == "relative" then
|
|
util.win_set_option(win, "relativenumber", true)
|
|
elseif lineNumbers == "on" then
|
|
util.win_set_option(win, "number", true)
|
|
util.win_set_option(win, "relativenumber", false)
|
|
else
|
|
util.win_set_option(win, "number", false)
|
|
util.win_set_option(win, "relativenumber", false)
|
|
end
|
|
end
|
|
|
|
---Handle changes from vscode
|
|
---Set nvim options
|
|
---@param buf number
|
|
---@param opts EditorOptions
|
|
local function set_options(buf, opts)
|
|
if not api.nvim_buf_is_valid(buf) then
|
|
return
|
|
end
|
|
|
|
api.nvim_buf_set_var(buf, "vscode_editor_options", opts)
|
|
|
|
util.buf_set_option(buf, "tabstop", opts.tabSize)
|
|
util.buf_set_option(buf, "shiftwidth", opts.tabSize)
|
|
util.buf_set_option(buf, "expandtab", opts.insertSpaces)
|
|
|
|
local win = api.nvim_get_current_win()
|
|
if api.nvim_win_get_buf(win) == buf then
|
|
set_number(win, opts.lineNumbers)
|
|
end
|
|
end
|
|
|
|
---Check changes from nvim
|
|
---Set vscode options
|
|
local function _check_options()
|
|
local vscode_opts = vim.b.vscode_editor_options
|
|
if not vscode_opts then -- should not happen
|
|
return
|
|
end
|
|
|
|
if not vim.b.vscode_editor_options_first_checked then --load the defaults
|
|
vim.b.vscode_editor_options_first_checked = true
|
|
util.buf_set_option(0, "tabstop", vscode_opts.tabSize)
|
|
util.buf_set_option(0, "shiftwidth", vscode_opts.tabSize)
|
|
util.buf_set_option(0, "expandtab", vscode_opts.insertSpaces)
|
|
set_number(0, vscode_opts.lineNumbers)
|
|
return
|
|
end
|
|
|
|
local buf = api.nvim_get_current_buf()
|
|
local ts, sw, et = vim.bo.ts, vim.bo.sw, vim.bo.et
|
|
|
|
if sw ~= ts then
|
|
util.buf_set_option(buf, "shiftwidth", ts) -- must be the same
|
|
end
|
|
|
|
local nvim_opts = {
|
|
tabSize = ts,
|
|
insertSpaces = et,
|
|
lineNumbers = get_number_style(vim.wo.nu, vim.wo.rnu),
|
|
}
|
|
|
|
if vim.deep_equal(nvim_opts, vscode_opts) then
|
|
return
|
|
end
|
|
|
|
vim.b.vscode_editor_options = nvim_opts
|
|
vscode.action("set_editor_options", { args = { buf, nvim_opts } })
|
|
end
|
|
|
|
local check_options = util.debounce(_check_options, 20)
|
|
|
|
local function process_modeline()
|
|
if vim.b.vscode_editor_options_first_checked then
|
|
if not vim.b.vscode_processed_modeline then
|
|
vim.b.vscode_processed_modeline = true
|
|
if vim.go.modeline then -- nomodeline by default for scratch buffer
|
|
vim.bo.modeline = true
|
|
end
|
|
vim.cmd.doautocmd("CursorMoved") -- process modeline
|
|
check_options()
|
|
end
|
|
end
|
|
end
|
|
|
|
function M.setup()
|
|
vscode.on("editor_options_changed", set_options)
|
|
vscode.on("document_buffer_init", function(buf)
|
|
if not api.nvim_buf_is_valid(buf) then
|
|
return
|
|
end
|
|
local has, opts = pcall(api.nvim_buf_get_var, buf, "vscode_editor_options")
|
|
if has then
|
|
set_options(buf, opts)
|
|
vim.defer_fn(process_modeline, 100)
|
|
end
|
|
end)
|
|
|
|
local group = api.nvim_create_augroup("vscode.sync-editor-options", { clear = true })
|
|
-- options
|
|
api.nvim_create_autocmd({ "OptionSet" }, {
|
|
group = group,
|
|
callback = check_options,
|
|
pattern = { "tabstop", "shiftwidth", "expandtab", "number", "relativenumber" },
|
|
})
|
|
api.nvim_create_autocmd(
|
|
{ "CursorMoved", "BufWinEnter", "InsertEnter", "InsertLeave", "FileType" },
|
|
{ group = group, callback = check_options }
|
|
)
|
|
-- modeline
|
|
api.nvim_create_autocmd({ "BufWinEnter", "WinEnter", "CursorMoved", "FileType" }, {
|
|
group = group,
|
|
callback = process_modeline,
|
|
})
|
|
end
|
|
|
|
return M
|