open-standards/wai/tools/wai-quantum-editor/editors/wai-quantum.lua
Transaction Science 770f3b3039 wai/tools/wai-quantum-editor: the debugger, in the extension and the other editors
The extension contributes breakpoints for OpenQASM and a `wai-quantum`
debugger whose launch settings (program, stopOnEntry, inputs, noise, method,
outcomes) are the ones `wai-quantum dap` reads; it starts the adapter as the
command line's dap verb, and "Debug the program" debugs the file in the
editor. The Lua configuration registers the adapter with the debug adapter
plugin, and languages.toml declares it with a launch template. test/check.mjs
holds the manifest to the adapter's source and checks the client starts it;
the editors workflow runs the debugger's module tests and tests/dap.rs on
Linux and macOS.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 23:44:27 -04:00

114 lines
4.3 KiB
Lua

-- OpenQASM for an editor configured in Lua: the file type, the language
-- server (`wai-quantum lsp`), the tree-sitter grammar, and the debugger
-- (`wai-quantum dap`) for the debug adapter plugin.
--
-- Copy this file into your configuration's plugin/ directory, where it runs
-- at start. With the tree-sitter plugin, `:TSInstall openqasm` builds the
-- grammar; if your version of the plugin does not install its queries, copy
-- wai/tools/tree-sitter-openqasm/queries/*.scm to queries/openqasm/ in your
-- configuration directory.
vim.filetype.add({ extension = { qasm = 'openqasm' } })
local server = {
cmd = { 'wai-quantum', 'lsp' },
filetypes = { 'openqasm' },
root_markers = { '.git' },
-- The values a generator's inputs are read at, and the shots a run samples.
settings = { ['wai-quantum'] = { inputs = {} } },
}
if vim.lsp.config and vim.lsp.enable then
-- Version 0.11 and later: the built-in configuration.
vim.lsp.config('wai_quantum', server)
vim.lsp.enable('wai_quantum')
else
-- Earlier versions: through the lspconfig plugin.
local ok, configs = pcall(require, 'lspconfig.configs')
if ok then
if not configs.wai_quantum then
configs.wai_quantum = {
default_config = {
cmd = server.cmd,
filetypes = server.filetypes,
root_dir = require('lspconfig.util').root_pattern('.git'),
single_file_support = true,
settings = server.settings,
},
}
end
require('lspconfig').wai_quantum.setup({})
end
end
-- The grammar, which the tree-sitter plugin builds from the repository.
local grammar = {
url = 'https://git.transaction.science/Transaction-Science/open-standards',
location = 'wai/tools/tree-sitter-openqasm',
branch = 'main',
}
local ok, parsers = pcall(require, 'nvim-treesitter.parsers')
if ok and parsers.get_parser_configs then
-- The plugin's earlier interface.
parsers.get_parser_configs().openqasm = {
install_info = { url = grammar.url, location = grammar.location, branch = grammar.branch, files = { 'src/parser.c' } },
filetype = 'openqasm',
}
elseif ok then
-- Its current interface: registered each time it reads its list of parsers.
vim.api.nvim_create_autocmd('User', {
pattern = 'TSUpdate',
callback = function()
require('nvim-treesitter.parsers').openqasm = {
install_info = { url = grammar.url, location = grammar.location, branch = grammar.branch, queries = 'queries' },
}
end,
})
end
vim.treesitter.language.register('openqasm', 'openqasm')
-- Highlight OpenQASM with the grammar, once it is built.
vim.api.nvim_create_autocmd('FileType', {
pattern = 'openqasm',
callback = function(args)
pcall(vim.treesitter.start, args.buf, 'openqasm')
end,
})
-- The engine's commands, as the lenses run them: :QuantumRun, :QuantumPlan,
-- :QuantumCritique, :QuantumShortcuts, :QuantumReceipt.
for _, name in ipairs({ 'run', 'plan', 'critique', 'shortcuts', 'receipt' }) do
local title = name:sub(1, 1):upper() .. name:sub(2)
vim.api.nvim_create_user_command('Quantum' .. title, function()
local buf = vim.api.nvim_get_current_buf()
local client = vim.lsp.get_clients({ bufnr = buf, name = 'wai_quantum' })[1]
if not client then
vim.notify('the wai-quantum language server is not running in this buffer', vim.log.levels.WARN)
return
end
local params = { command = 'wai-quantum.' .. name, arguments = { vim.uri_from_bufnr(buf) } }
client:request('workspace/executeCommand', params, function(err, answer)
if err then
vim.notify(err.message, vim.log.levels.ERROR)
return
end
vim.schedule(function()
vim.cmd('botright new')
vim.bo.buftype = 'nofile'
vim.bo.bufhidden = 'wipe'
vim.api.nvim_buf_set_lines(0, 0, -1, false, vim.split(answer.text, '\n'))
vim.api.nvim_buf_set_name(0, 'wai-quantum ' .. name)
end)
end, buf)
end, {})
end
-- The engine's debugger, with the debug adapter plugin: breakpoints by line,
-- steps forward and back, and the state's probes as variables.
local has_dap, dap = pcall(require, 'dap')
if has_dap then
dap.adapters['wai-quantum'] = { type = 'executable', command = 'wai-quantum', args = { 'dap' } }
dap.configurations.openqasm = {
{ type = 'wai-quantum', request = 'launch', name = 'Debug the program', program = '${file}', stopOnEntry = true },
}
end