Skip to content

terror/just-lsp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

5bf8f87 · Apr 15, 2025
Apr 11, 2025
Mar 31, 2025
Apr 11, 2025
Apr 6, 2025
Mar 20, 2025
Mar 19, 2025
Feb 12, 2022
Mar 20, 2025
Apr 11, 2025
Apr 11, 2025
Feb 12, 2022
Apr 11, 2025
Apr 11, 2025
Feb 12, 2022
Apr 15, 2025
Mar 20, 2025
Mar 18, 2025
Apr 11, 2025
Mar 18, 2025

Repository files navigation

just-lsp

release crates.io CI dependency status

just-lsp is a server implementation of the language server protocol for just, the command runner.

demo

Installation

just-lsp should run on any system, including Linux, MacOS, and the BSDs.

The easiest way to install it is by using cargo, the Rust package manager:

cargo install just-lsp

Otherwise, see below for the complete package list:

Cross-platform

Package Manager Package Command
Cargo just-lsp cargo install just-lsp

Linux

Operating System Package Manager Package Command
Arch pacman just-lsp pacman -S just-lsp

just-lsp package version table

Pre-built binaries

Pre-built binaries for Linux, MacOS, and Windows can be found on the releases page.

Usage

just-lsp can be used with any LSP client, this section documents integration with some of the more popular ones.

Neovim

You can use the release build of just-lsp by setting up the just server on lspconfig, so somewhere in your config:

local lsp = require('lspconfig')

lsp.just.setup({
  -- ...
})

This assumes just-lsp is installed on your system and is in your $PATH.

Features

The server implements a decent amount of the language server protocol specification. This section aims to document some of them.

textDocument/codeAction

We provide a code action for each recipe. These code actions run the selected recipe using just, populating a buffer with its output (stderr + stdout).

textDocument/completion

Completions are provided to you as you type. We currently show recipes, built-in functions, and constants.

textDocument/definition

You're able to go to a recipe, parameter or assignment definition from an identifier.

textDocument/documentHighlight

Like references, but highlights them inside the document.

textDocument/foldingRange

Code folding for recipes.

textDocument/formatting

You're able to format your justfile. This calls just --fmt --unstable and writes the result to your buffer.

textDocument/hover

You can request hover information for syntactic elements like recipes, built-in functions, constants, etc. and see information about them.

textDocument/publishDiagnostics

We try to publish useful diagnostics. Some of them include checks for non-existent aliases, dependencies, and syntax errors.

textDocument/references

All references to an identifier can be shown. This includes aliases, dependencies, recipes, and more.

textDocument/rename

Workspace-wide symbol renaming is supported.

Development

I use Neovim to work on this project, and I load the development build of this server to test out my changes instantly. This section describes a development setup using Neovim as the LSP client, for other clients you would need to look up their respective documentation.

First, clone the repository:

git clone https://github.com/terror/just-lsp

Build the project:

cd just-lsp
cargo build

Add this to your editor configuration:

local lsp = require('lspconfig')

local configs = require('lspconfig.configs')

if not configs.just_lsp then
  configs.just_lsp = {
    default_config = {
      cmd = { '/path/to/just-lsp/target/debug/just-lsp' },
      filetypes = { 'just' },
      root_dir = function(fname)
        return lsp.util.find_git_ancestor(fname)
      end,
      settings = {},
    },
  }
end

local on_attach = function(client)
  -- Add your implementation here
end

local capabilities = {} -- Define what functionality the LSP client is able to handle

lsp.just_lsp.setup({
  on_attach = on_attach,
  capabilities = capabilities,
})

n.b. You'll need to replace /path/to/just-lsp/target/debug/just-lsp with the actual absolute path to the binary.

on_attach is a function that gets called after an LSP client gets attached to a buffer, mine just sets up a few mappings:

local on_attach = function(client)
  client.server_capabilities.semanticTokensProvider = nil

  map('n', '<leader>ar', '<cmd>lua vim.lsp.buf.rename()<CR>')
  map('n', '<leader>s', '<cmd>lua vim.lsp.buf.format({ async = true })<CR>')
  map('n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>')
  map('n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>')
  map('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>')
  map('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>')
end

...and capabilities is a table defining what functionality the LSP client is able to handle, I use default capabilities provided by cmp-nvim-lsp:

local capabilities = require('cmp_nvim_lsp').default_capabilities()

n.b. This will require you to have the nvim-lspconfig (and optionally cmp-nvim-lsp) plugin installed.

Prior Art

Check out just, the command runner.

About

A language server for just

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages