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]>
114 lines
4.3 KiB
Lua
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
|