30 releases (5 breaking)
0.6.15 | Dec 8, 2024 |
---|---|
0.6.14 | Nov 28, 2024 |
0.5.5 | Nov 15, 2024 |
0.4.2 | Nov 1, 2024 |
0.1.1 | Oct 26, 2024 |
#15 in Text editors
1,994 downloads per month
110KB
2.5K
SLoC
pickls
(pronounced /ˈpɪkᵊlz/)
The General Purpose Language Server for Command-Line Linters and Formatters
Inspired by tools like ale,
null-ls,
none-ls, and
diagnostic-languageserver,
and conform, pickls
offers a
unified way to configure command-line linters, formatters and LLMs with editor
LSP integration.
Key Features
- Integrate command-line linting and formatting tools with your IDE.
- Configure multiple linters and formatters for any language. This is ideal for projects with toolchains lacking native LSP integration.
- Has a built-in code action for multi-LLM "Inline Assist" which can be used to simultaneously query multiple LLMs for assistance. Currently OpenAI and Ollama are supported.
- Supports dynamic invocation of ctags to provide workspace symbol information. (See configuration notes below.)
Language Server Protocol - Primary Server Capabilities
diagnosticProvider
(spec)documentFormattingProvider
(spec)textDocumentSync
(spec)workspaceSymbolProvider
(spec)codeAction
(spec)
Why Use pickls?
- You'd like to have LSP support for LLM completion as a code action.
- Avoid installing and configuring separate plugins or language servers for each tool in your workflow.
- Utilize a seamless LSP integration for command-line oriented toolchains.
Installation
Install pickls Binary
Pickls is available via crates.io here.
Ensure you have a recent stable
Rust toolchain and the cargo binary directory
in your path:
cargo install pickls
Running from Source
Consider using pickls-debug-runner
to run from source, which is helpful for
development purposes.
Configuration
User-level Configuration
Complete configuration source code is available here.
User-level configuration lives in "$XDG_CONFIG_HOME/pickls/pickls.yaml
where
$XDG_CONFIG_HOME
defaults to "$HOME"/.config
. Pickls will respect your
$XDG_CONFIG_HOME
if it is set.
Project-level Configuration
Project-level configuration is not yet implemented, but is on the roadmap.
Example pickls.yaml
---
ai:
inline_assistants:
- provider: ollama
model: tinyllama
- provider: ollama
model: llama3.2:latest
- provider: openai
model: gpt-4o
- provider: openai
model: gpt-4o-mini
symbols:
source: universal-ctags # Currently only universal-ctags is supported.
ctags_timeout_ms: 500 # 500ms is the default timeout.
languages:
c: &c-settings
formatters:
- program: clang-format
args: ["-"]
cpp: *c-settings
dockerfile:
linters:
- program: hadolint
args:
- --no-color
- --format
- tty
- '-'
description_match: 3
line_match: 1
pattern: '-:(\d+) [^ ]+ (\w+): (.*)'
severity_match: 2
use_stderr: false
use_stdin: true
lua:
linters:
- program: luacheck
args:
- --formatter
- plain
- --ranges
- --no-color
- '-'
pattern: 'stdin:(\d+):(\d+)-(\d+): (.*)'
line_match: 1
start_col_match: 2
end_col_match: 3
description_match: 4
use_stderr: false
use_stdin: true
formatters:
- program: lua-format
args:
- "--indent-width=2"
- "--spaces-inside-table-braces"
- "--align-table-field"
- "--break-before-table-rb"
- "--chop-down-table"
markdown:
formatters:
- program: mdformat
args:
- --wrap
- '80'
- '-'
python:
root_markers:
- .git
- pyproject.toml
- setup.py
- mypy.ini
formatters:
- program: autoimport
args: ["-"]
- program: isort
args: ["-", "-d"]
- program: ruff
args: ["check", "--exit-zero", "--fix", "--stdin-filename", "$filename"]
- program: ruff
args:
- format
- --stdin-filename
- $filename
linters:
# Try out [dmypyls](https://github.com/wbbradly/dmypyls).
- program: mypy
args:
- --show-column-numbers
- --show-error-end
- --hide-error-codes
- --hide-error-context
- --no-color-output
- --no-error-summary
- --no-pretty
- --shadow-file
- $filename
- /dev/stdin
- $filename
pattern: '(.*):(\d+):(\d+):\d+:(\d+): error: (.*)'
filename_match: 1
line_match: 2
start_col_match: 3
end_col_match: 4
description_match: 5
use_stderr: false
use_stdin: true
- program: ruff
args:
- check
- --stdin-filename
- $filename
pattern: '(.*):(\d+):(\d+): (.*)'
filename_match: 1
line_match: 2
start_col_match: 3
description_match: 4
use_stderr: false
use_stdin: true
sh: &sh
linters:
- program: shellcheck
args: ["-f", "gcc", "-"]
pattern: '(.*):(\d+):(\d+): (\w+): (.*)'
filename_match: 1
line_match: 2
start_col_match: 3
severity_match: 4
description_match: 5
use_stderr: false
use_stdin: true
bash: *sh
shell script: *sh
toml:
linters:
- program: tomllint
args: ["-"]
pattern: '(.*):(\d+):(\d+): error: (.*)'
filename_match: 1
line_match: 2
start_col_match: 3
description_match: 4
use_stderr: true
use_stdin: true
yaml:
linters:
- program: yamllint
args: ["-f", "parsable", "-"]
pattern: '.*:(\d+):(\d+): \[(.*)\] (.*) \((.*)\)'
line_match: 1
start_col_match: 2
severity_match: 3
description_match: 4
use_stderr: false
use_stdin: true
Note the usage of YAML anchors and references in order to handle different language names for the same formats.
Neovim
Enable pickls
for all Neovim buffers:
vim.api.nvim_create_autocmd({ "BufRead" }, {
group = vim.api.nvim_create_augroup("pickls-bufread", { clear = true }),
callback = function(_)
if vim.fn.executable("pickls") ~= 0 then
vim.lsp.start({
name = "pickls",
cmd = { "pickls", vim.api.nvim_buf_get_name(0) },
root_dir = vim.fs.root(0, { ".git", "pyproject.toml", "setup.py", "Cargo.toml", "go.mod" }),
}, {
bufnr = 0,
reuse_client = function(_, _) return false end,
})
else
vim.notify("Pickls executable not found. See pickls-debug-runner for setup instructions.")
end
end,
})
-- Invoke LSP formatting on save.
vim.api.nvim_create_autocmd("BufWritePre", {
callback = function() vim.lsp.buf.format() end
})
-- You'll want to enable a shortcut for code actions in order to trigger inline-assist.
vim.keymap.set('n', '<leader>a', function() vim.lsp.buf.code_action() end)
Zed
To use pickls
in Zed, install the
pickls-zed extension. Use the
following command:
git clone https://github.com/wbbradley/pickls-zed "$HOME"/src/pickls-zed
Note that Zed supports formatting via command-line out of the box (see
format_on_save
), so you don't really need to use pickls
for formatting in
Zed. However, I've included it in the configuration here for demonstration
purposes.
Example Zed Settings
{
"format_on_save": "language_server",
"languages": {
"Python": {
// Note that this implicitly disables Zed's built-in usage of Pyright.
"language_servers": ["pickls"],
}
},
"lsp": {
"pickls": {
"binary": {"path": "pickls", "arguments": ["zed"]},
}
}
}
Troubleshooting
If you encounter issues with pickls
, please open an issue
here. When logging an issue,
please include the following information:
- How you have configured
pickls
in your editor. - Any relevant lines from
"$HOME"/.local/state/pickls/pickls.log
.
Dependencies
~59MB
~1M SLoC