Neovim plugin to help writing and testing CodeQL queries.
gh-mrva
){
"pwntester/codeql.nvim",
dependencies = {
"MunifTanjim/nui.nvim",
"nvim-lua/telescope.nvim",
"kyazdani42/nvim-web-devicons",
{
's1n7ax/nvim-window-picker',
version = 'v1.*',
opts = {
autoselect_one = true,
include_current = false,
filter_rules = {
bo = {
filetype = {
"codeql_panel",
"codeql_explorer",
"qf",
"TelescopePrompt",
"TelescopeResults",
"notify",
"noice",
"NvimTree",
"neo-tree",
},
buftype = { 'terminal' },
},
},
current_win_hl_color = '#e35e4f',
other_win_hl_color = '#44cc41',
},
}
},
opts = {}
}
use {
"pwntester/codeql.nvim",
requires = {
"MunifTanjim/nui.nvim",
"nvim-lua/telescope.nvim",
"kyazdani42/nvim-web-devicons",
{
's1n7ax/nvim-window-picker',
tag = 'v1.*',
config = function()
require'window-picker'.setup({
autoselect_one = true,
include_current = false,
filter_rules = {
bo = {
filetype = {
"codeql_panel",
"codeql_explorer",
"qf",
"TelescopePrompt",
"TelescopeResults",
"notify",
"noice",
"NvimTree",
"neo-tree",
},
buftype = { 'terminal' },
},
},
current_win_hl_color = '#e35e4f',
other_win_hl_color = '#44cc41',
})
end,
}
},
config = function()
require("codeql").setup {}
end
}
Use QL database set <path to db>
to let the plugin know what DB to work with.
Use QL database unset
to unregister the current registered database.
Use QL query run
or QL query quick-eval
commands or qr
, qp
shortcuts respectively to run the query or evaluate the predicate under the cursor.
eg:
require("codeql").setup {
results = {
max_paths = 10,
max_path_depth = nil,
},
panel = {
width = 50,
pos = "botright",
group_by = "sink", -- "source"
show_filename = true,
long_filename = false,
context_lines = 3,
},
max_ram = 32000,
job_timeout = 15000,
format_on_save = true,
additional_packs = {
"/Users/pwntester/codeql-home/codeql",
"/Users/pwntester/codeql-home/codeql-go",
"/Users/pwntester/codeql-home/codeql-ruby",
"./codeql",
},
mappings = {
run_query = { modes = { "n" }, lhs = "<space>qr", desc = "run query" },
quick_eval = { modes = { "x", "n" }, lhs = "<space>qe", desc = "quick evaluate" },
quick_eval_predicate = { modes = { "n" }, lhs = "<space>qp", desc = "quick evaluate enclosing predicate" },
},
}
QL database set <path to db>
: Required before running any query.QL database unset
: Unregister current database.QL database browse
: Shows source archive tree explorerQL query run
: Runs the query on the current buffer. Requires a DB to be set first.QL query eval
: Quick evals the predicate or selection under cursor. Requires a DB to be set first.QL query cancel
: Cancels current query.QL history list
: Shows a menu to render results of previous queries (on the same nvim session).QL server stop
: Stops the query server associated with the query buffer. A new one will be started upon query evaluation.QL ast print
: On a ql:/
buffer, prints the AST of the current file.QL sarif load <path to SARIF file>
: Loads the issues of a SARIF file. To browse the results, use QL db set
before.QL sarif permalink
: Copies a permalink to the current line of a SARIF file.QL sarif browse
: Open the file in GitHub.QL mrva load <name of MRVA session>
: Loads results of MRVA scan.gd
: On a ql:/
file, jumps to the symbol definition.gr
: On a ql:/
file, show symbol references in the QuickFix window.<leader>qr
: Runs the current query.<leader>qe
: Quick evaluate the selected predicate.<leader>qp
: Quick evaluate the enclosing predicate.<Plug>(CodeQLGrepSource)
: shows a telescope menu to grep the source archiveAfter running a query or quick evaluating a predicate, results will be rendered in a special panel.
o
: collapses/Expands resultEnter
(on a visitable result node): opens node file in nvim and moves cursor to window with source code filep
: similar to Enter
but keeps cursor on the results panelN
: change to next pathP
: change to previous pathf
: filter issues by issue labelF
: filter issuesc
: clear filtert
: open all foldsT
: closes all foldsq
: closes result panels
: show context snippetThis plugin does not provide any support for the Language Server Protocol (LSP). But in order to have the best CodeQL writing experience it is recommended to configure a LSP client to connect to the CodeQL Language Server.
There are many LSP clients in the Neovim ecosystem. The following clients have been tested with CodeQL Language Server:
It is possible to configure the built-in LSP client without any additional plugins, but a configuration for the CodeQL Language Server is included in nvim-lspconfig. If you are using packer
, it is a matter of adding following line to your neovim config:
use 'neovim/nvim-lspconfig'
Using this client, it is only required to configure the client with:
local lspconfig = require'lspconfig'
lspconfig.codeqlls.setup{
on_attach = on_attach_callback;
settings = {
additional_packs = {'~/codeql-home/codeql-repo'};
};
}
NOTE: change additional_packs
to the path where the CodeQL repo has been installed to.
It is also recommended to add an on_attach
callback to define LSP mappings. E.g:
local function on_attach_callback(client, bufnr)
api.nvim_buf_set_keymap(bufnr, "n", "gD", "<Cmd>lua show_diagnostics_details()<CR>", { silent = true; })
api.nvim_buf_set_keymap(bufnr, "n", "gd", "<Cmd>lua vim.lsp.buf.definition()<CR>", { silent = true; })
api.nvim_buf_set_keymap(bufnr, "n", "gi", "<Cmd>lua vim.lsp.buf.implementation()<CR>", { silent = true; })
api.nvim_buf_set_keymap(bufnr, "n", "gK", "<Cmd>lua vim.lsp.buf.hover()<CR>", { silent = true; })
api.nvim_buf_set_keymap(bufnr, "n", "gh", "<Cmd>lua vim.lsp.buf.signature_help()<CR>", { silent = true; })
api.nvim_buf_set_keymap(bufnr, "n", "gr", "<Cmd>lua vim.lsp.buf.references()<CR>", { silent = true; })
api.nvim_buf_set_keymap(bufnr, "n", "gF", "<Cmd>lua vim.lsp.buf.formatting()<CR>", { silent = true; })
api.nvim_command [[autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()]]
api.nvim_command [[autocmd CursorHoldI <buffer> lua vim.lsp.buf.document_highlight()]]
api.nvim_command [[autocmd CursorMoved <buffer> lua vim.lsp.util.buf_clear_references()]]
end
local lspconfig = require'lspconfig'
lspconfig.codeqlls.setup{
on_attach = on_attach_callback;
settings = {
additional_packs = {'~/codeql-home/codeql-repo'};
};
}
Check my dotfiles for examples on how to configure the NVIM LSP client.
It is possible to add codeql language server to coc.nvim
using coc-settings.json
as an
executable language server
{
"languageserver": {
"codeql": {
"command": "<path to codeql binary>",
"args": [
"execute",
"language-server",
"--check-errors=ON_CHANGE",
"--search-path=./:<path to semmle/ql repo maybe>:<any more paths>",
"-q"
],
"filetypes": ["ql"],
"rootPatterns": ["qlpack.yml"],
"requireRootPattern": true
}
}
}
If you like this plugin and would like to buy me a coffee, you can!