using System; using System.Text; using System.Linq; using System.Drawing; using System.Diagnostics; using System.Windows.Forms; using System.Threading; using System.Threading.Tasks; using System.Collections.Generic; using Tango.PMR.Stubs; using Tango.Stubs; public void OnExecute(StubManager stubManager) { while(true) { stubManager.Run("StubMotorMovRequest" ,14, true, 1700); Thread.Sleep(400); stubManager.Run("StubMotorMovRequest" ,14, false, 1700); Thread.Sleep(400); } }
--
-- Session plugin
--

local session_dir = vim.fn.stdpath("state") .. "/sessions"
local session_default = session_dir .. "/default.vim"
if not vim.uv.fs_stat(session_dir) then
	vim.uv.fs_mkdir(session_dir, tonumber("755", 8))
	vim.notify("Sessions save directory created at " .. session_dir)
end

-- :mksession doesn't persist everything we want (e.g. tab-local t:tabname), so we keep a
-- sidecar JSON object alongside the .vim session for extra data. Tab names live under the
-- `tabnames` key, stored positionally because :mksession recreates tabs in their original
-- order, making the index stable across reloads.
local function sidecar_path(path)
	return (path:gsub("%.vim$", "")) .. ".json"
end

local function read_sidecar(path)
	local f = io.open(sidecar_path(path), "r")
	if not f then
		return {}
	end
	local content = f:read("*a")
	f:close()
	local ok, data = pcall(vim.json.decode, content)
	return (ok and type(data) == "table") and data or {}
end

local function write_sidecar(path, data)
	local f = io.open(sidecar_path(path), "w")
	if f then
		f:write(vim.json.encode(data))
		f:close()
	end
end

-- :mksession can't restore man:// buffers (they're :buftype=nofile, not backed by a file), so
-- we record them ourselves, nested as tab index -> window number -> { buffer name, cursor line }.
-- Both indices are positional for the same reason as tab names above: :mksession recreates tabs
-- and their windows in order, so the ordinals are stable across reloads. Nesting by tab matters
-- because window numbers restart at 1 in each tabpage and would otherwise collide. The indices
-- are stringified so the sparse table encodes as a JSON object, not a null-padded array.
--
-- Limitation: the cursor line is an index into the *rendered* man page, whose line wrapping
-- depends on MANWIDTH. If MANWIDTH differs on load, the page re-wraps and the saved line points
-- elsewhere. (It never changes in this setup, but the dependency is real.)
local function man_windows()
	local pages = {}
	for ti, tp in ipairs(vim.api.nvim_list_tabpages()) do
		for _, win in ipairs(vim.api.nvim_tabpage_list_wins(tp)) do
			local name = vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(win))
			if name:match("^man://") then
				local tk = tostring(ti)
				pages[tk] = pages[tk] or {}
				pages[tk][tostring(vim.api.nvim_win_get_number(win))] =
					{ name = name, line = vim.api.nvim_win_get_cursor(win)[1] }
			end
		end
	end
	return pages
end

local function save_session(path)
	vim.cmd.mksession({ path, bang = true })
	local names = {}
	for i, tp in ipairs(vim.api.nvim_list_tabpages()) do
		-- pcall: nvim_tabpage_get_var errors when the variable isn't set on that tab
		local ok, name = pcall(vim.api.nvim_tabpage_get_var, tp, "tabname")
		names[i] = (ok and type(name) == "string") and name or ""
	end
	write_sidecar(path, { tabnames = names, manpages = man_windows() })
end

-- Reopen the man:// buffers recorded by man_windows(). Keys come back from JSON as strings,
-- hence the tonumber(). :edit man://... re-renders the page via the man plugin's BufReadCmd; we
-- run it window-scoped so the layout restored by :mksession is left untouched, then clamp the
-- saved cursor line to the (possibly re-wrapped) page.
local function restore_man_windows(manpages)
	if not manpages then
		return
	end
	local tabpages = vim.api.nvim_list_tabpages()
	for tk, wins in pairs(manpages) do
		local tp = tabpages[tonumber(tk)]
		if tp then
			local by_number = {}
			for _, win in ipairs(vim.api.nvim_tabpage_list_wins(tp)) do
				by_number[vim.api.nvim_win_get_number(win)] = win
			end
			for wk, info in pairs(wins) do
				local win = by_number[tonumber(wk)]
				if win then
					vim.api.nvim_win_call(win, function()
						vim.cmd.edit({ args = { info.name } })
					end)
					local buf = vim.api.nvim_win_get_buf(win)
					local line = math.max(1, math.min(info.line or 1, vim.api.nvim_buf_line_count(buf)))
					vim.api.nvim_win_set_cursor(win, { line, 0 })
				end
			end
		end
	end
end

local function load_session(path)
	vim.cmd.source(path)
	local data = read_sidecar(path)
	if data.tabnames then
		for i, tp in ipairs(vim.api.nvim_list_tabpages()) do
			if data.tabnames[i] and data.tabnames[i] ~= "" then
				vim.api.nvim_tabpage_set_var(tp, "tabname", data.tabnames[i])
			end
		end
		vim.cmd.redrawtabline()
	end
	restore_man_windows(data.manpages)
end

local function reload_session(path)
	save_session(path)
	vim.cmd.restart({ args = { "+qall", "SessionLoad", path } })
end

local function delete_session(path)
	vim.fs.rm(path)
	local sidecar = sidecar_path(path)
	if vim.uv.fs_stat(sidecar) then
		vim.fs.rm(sidecar)
	end
end

local function session_completefunc(arg_lead, _, _)
	local completions = {}
	for path in vim.fs.dir(session_dir) do
		if string.match(path, "^" .. arg_lead) and string.match(path, ".vim$") then
			completions[#completions + 1] = path:sub(1, -5)
		end
	end
	return completions
end

local function session_op(base, op)
	local path = #base > 0 and base or session_default
	if not string.match(path, "^" .. session_dir) then
		path = session_dir .. "/" .. path
	end
	if not string.match(path, "%.vim$") then
		path = path .. ".vim"
	end
	op(path)
end

vim.api.nvim_create_user_command("SessionSave", function(ev)
	session_op(ev.args, save_session)
end, { desc = "Save session", nargs = "?", complete = session_completefunc })
vim.api.nvim_create_user_command("SessionLoad", function(ev)
	session_op(ev.args, load_session)
end, { desc = "Load session", nargs = "?", complete = session_completefunc })
vim.api.nvim_create_user_command("SessionDelete", function(ev)
	session_op(ev.args, delete_session)
end, { desc = "Delete session", nargs = "?", complete = session_completefunc })
vim.api.nvim_create_user_command("SessionRestart", function(ev)
	session_op(ev.args, reload_session)
end, { desc = "Reload session", nargs = "?", complete = session_completefunc })
vim.api.nvim_create_user_command("SessionExitSave", function(ev)
	session_op(ev.args, save_session)
	vim.cmd.qall()
end, { desc = "Save session and exit", nargs = "?", complete = session_completefunc })
vim.api.nvim_create_user_command("SessionExitNoSave", function()
	vim.cmd.qall()
end, { desc = "Exit without saving session", nargs = "?", complete = session_completefunc })