fish-lsp

1.0.10 • Public • Published

demo.gif

Introducing the fish-lsp, a Language Server Protocol (LSP) implementation for the fish shell language.

Quick Start

Please choose a method to install the language server and configure a client to use fish-lsp in your editor.

A detailed explanation of how a language server connection works is described in the how it works section.

Why? 🐟

Features

Feature Description Status
Completion Provides completions for commands, variables, and functions
Hover Shows documentation for commands, variables, and functions. Has special handlers for --flag, commands, functions, and variables
Signature Help Shows the signature of a command or function
Goto Definition Jumps to the definition of a command, variable, function or --flag
Goto Implementation Jumps between symbol definitions and completion definitions
Find References Shows all references to a command, variable, function, or --flag
Rename Rename within matching global && local scope
Document Symbols Shows all commands, variables, and functions in a document
Workspace Symbols Shows all commands, variables, and functions in a workspace
Document Formatting Formats a document, full & selection
On Type Formatting Formats a document while typing
Document Highlight Highlights all references to a command, variable, or function.
Command Execution Executes a server command from the client
Code Action Automate code generation
Quick fix Auto fix lint issues
Inlay Hint Shows Virtual Text/Inlay Hints
Code Lens Shows all available code lenses
Logger Logs all server activity
Diagnostic Shows all diagnostics
Folding Range Toggle ranges to fold text
Semantic Tokens Server provides extra syntax highlighting
CLI Interactivity Provides a CLI for server interaction.
Built by fish-lsp complete
Client Tree Shows the defined scope as a Tree
Indexing Indexes all commands, variables, functions, and source files

Installation

Some language clients might support downloading the fish-lsp directly from within the client, but for the most part, you'll typically be required to install the language server manually.

Below are a few methods to install the language server, and how to verify that it's working.

Use a Package Manager

Stability across package managers can vary. Consider using another installation method if issues arise.

npm install -g fish-lsp

yarn global add fish-lsp

pnpm install -g fish-lsp

nix-shell -p fish-lsp

brew install fish-lsp

If you installed the language server using a node based package manager (i.e. npm/yarn/pnpm), you can install the completions by running the following command:

fish-lsp complete > ~/.config/fish/completions/fish-lsp.fish

Build from Source

Recommended Dependencies: yarn@1.22.22 node@22.14.0 fish@4.0.2

git clone https://github.com/ndonfris/fish-lsp && cd fish-lsp
yarn install 
yarn dev # to watch for changes use `yarn dev:watch` 

Using the yarn dev:watch command will automatically rebuild the project when changes are detected. This allows easy testing of new features or bug fixes, if you're interested in contributing.

Building the project from source is the most portable method for installing the language server.

Verifying Installation

After installation, verify that fish-lsp is working correctly:

fish-lsp --help

fish-lsp --help

Setup

To properly configure fish-lsp, you need to define a client configuration after installing the language server.

Configuring a client should be relatively straightforward. Typically, you're only required to translate the shell command fish-lsp start for fish files, in the client's configuration. However, further configuration can be specified as a server configuration.

Some clients may also allow specifying the server configuration directly in the client configuration.

Client Configuration (Required)

Theoretically, the language-server should generally be compatible with almost any text-editor or IDE you prefer using. Feel free to setup the project in any fish-lsp-client of your choice, or submit a PR for new configurations.

neovim (v0.8)

Full table of options available in the neovim documentation

vim.api.nvim_create_autocmd('FileType', {
  pattern = 'fish',
  callback = function()
    vim.lsp.start({
      name = 'fish-lsp',
      cmd = { 'fish-lsp', 'start' },
    })
  end,
})

Alternatively, you can also see official documentation for nvim-lspconfig, or use your client of choice below.

There is also a useful configuration for testing out the language server in nvim@v0.11.1 included in the fish-lsp-language-clients repository.

mason.nvim

Install the fish-lsp using mason.nvim

:MasonInstall fish-lsp
coc.nvim

Neovim client using coc.nvim configuration, located inside coc-settings.json "languageserver" key

{
  "fish-lsp": {
    "command": "fish-lsp",
    "filetypes": ["fish"],
    "args": ["start"]
  }
}
YouCompleteMe

YouCompleteMe configuration for vim/neovim

let g:ycm_language_server =
          \ [
          \   {
          \       'name': 'fish',
          \       'cmdline': [ 'fish-lsp', 'start' ],
          \       'filetypes': [ 'fish' ],
          \   }
          \ ]
vim-lsp

Configuration of prabirshrestha/vim-lsp in your init.vim or init.lua file

if executable('fish-lsp')
  au User lsp_setup call lsp#register_server({
      \ 'name': 'fish-lsp',
      \ 'cmd': {server_info->['fish-lsp', 'start']},
      \ 'allowlist': ['fish'],
      \ })
endif
helix

In config file ~/.config/helix/languages.toml

[[language]]
name = "fish"
language-servers = [ "fish-lsp" ]

[language-server.fish-lsp]
command = "fish-lsp"
args= ["start"]
environment = { "fish_lsp_show_client_popups" = "false" }
kakoune

Configuration for kakoune-lsp, located in ~/.config/kak-lsp/kak-lsp.toml

[language.fish]
filetypes = ["fish"]
command = "fish-lsp"
args = ["start"]

Or in your ~/.config/kak/lsp.kak file

hook -group lsp-filetype-fish global BufSetOption filetype=fish %{
    set-option buffer lsp_servers %{
        [fish-lsp]
        root_globs = [ "*.fish", "config.fish", ".git", ".hg" ]
        args = [ "start" ]
    }
}
kate

Configuration for kate

{
  "servers": {
    "fish": {
      "command": ["fish-lsp", "start"],
      "url": "https://github.com/ndonfris/fish-lsp",
      "highlightingModeRegex": "^fish$"
    }
  }
}
emacs

Configuration using eglot (Built into Emacs 29+)

;; Add to your init.el or .emacs
(require 'eglot)

(add-to-list 'eglot-server-programs
  '(fish-mode . ("fish-lsp" "start")))

;; Optional: auto-start eglot for fish files
(add-hook 'fish-mode-hook 'eglot-ensure)

or place in your languages/fish.el file

(use-package fish-mode)

(with-eval-after-load 'eglot
  (add-to-list 'eglot-server-programs
               '(fish-mode . ("fish-lsp" "start"))))

Configuration using lsp-mode

;; Add to your init.el or .emacs
(require 'lsp-mode)

(lsp-register-client
 (make-lsp-client
  :new-connection (lsp-stdio-connection '("fish-lsp" "start"))
  :activation-fn (lsp-activate-on "fish")
  :server-id 'fish-lsp))

;; Optional: auto-start lsp for fish files
(add-hook 'fish-mode-hook #'lsp)

Full example configuration using doom-emacs can be found in the fish-lsp language clients repo.

VSCode

To download the extension, visit the fish-lsp extension on the VSCode Marketplace.

VSCode configuration does not require a client configuration. The server will automatically start when a .fish file is opened.

A server configuration can still be specified to control the server's behavior. (see below)

BBEdit

To install the fish-lsp in BBEdit, please follow the instructions in the repository fish-lsp-language-clients.

This configuration includes a Fish.plist file that provides syntax highlighting and other features for the fish shell.

Server Configuration (Optional)

Specific functionality for the server can be set independently from the client. The server allows for both environment variables and command flags to customize how specific server processes are started.

Environment variables

Generated by fish-lsp env --create

# $fish_lsp_enabled_handlers <ARRAY>
# Enables the fish-lsp handlers. By default, all handlers are enabled.
# (Options: 'complete', 'hover', 'rename', 'definition', 'implementation', 
#           'reference', 'logger', 'formatting', 'formatRange', 
#           'typeFormatting', 'codeAction', 'codeLens', 'folding', 
#           'signature', 'executeCommand', 'inlayHint', 'highlight', 
#           'diagnostic', 'popups')
# (Default: [])
set -gx fish_lsp_enabled_handlers 

# $fish_lsp_disabled_handlers <ARRAY>
# Disables the fish-lsp handlers. By default, no handlers are disabled.
# (Options: 'complete', 'hover', 'rename', 'definition', 'implementation', 
#           'reference', 'logger', 'formatting', 'formatRange', 
#           'typeFormatting', 'codeAction', 'codeLens', 'folding', 
#           'signature', 'executeCommand', 'inlayHint', 'highlight', 
#           'diagnostic', 'popups')
# (Default: [])
set -gx fish_lsp_disabled_handlers 

# $fish_lsp_commit_characters <ARRAY>
# Array of the completion expansion characters.
# Single letter values only.
# Commit characters are used to select completion items, as shortcuts.
# (Example Options: '.', ',', ';', ':', '(', ')', '[', ']', '{', '}', '<', 
#                   '>', ''', '"', '=', '+', '-', '/', '\', '|', '&', '%', 
#                   '$', '#', '@', '!', '?', '*', '^', '`', '~', '\t', ' ')
# (Default: ['\t', ';', ' '])
set -gx fish_lsp_commit_characters 

# $fish_lsp_log_file <STRING>
# A path to the fish-lsp's logging file. Empty string disables logging.
# (Example Options: '/tmp/fish_lsp.logs', '~/path/to/fish_lsp/logs.txt')
# (Default: '')
set -gx fish_lsp_log_file 

# $fish_lsp_log_level <STRING>
# The logging severity level for displaying messages in the log file.
# (Options: 'debug', 'info', 'warning', 'error', 'log')
# (Default: '')
set -gx fish_lsp_log_level 

# $fish_lsp_all_indexed_paths <ARRAY>
# The fish file paths to include in the fish-lsp's startup indexing, as workspaces.
# Order matters (usually place `$__fish_config_dir` before `$__fish_data_dir`).
# (Example Options: '$HOME/.config/fish', '/usr/share/fish', 
#                   '$__fish_config_dir', '$__fish_data_dir')
# (Default: ['$__fish_config_dir', '$__fish_data_dir'])
set -gx fish_lsp_all_indexed_paths 

# $fish_lsp_modifiable_paths <ARRAY>
# The fish file paths, for workspaces where global symbols can be renamed by the user.
# (Example Options: '/usr/share/fish', '$HOME/.config/fish', 
#                   '$__fish_data_dir', '$__fish_config_dir')
# (Default: ['$__fish_config_dir'])
set -gx fish_lsp_modifiable_paths 

# $fish_lsp_diagnostic_disable_error_codes <ARRAY>
# The diagnostics error codes to disable from the fish-lsp's diagnostics.
# (Options: 1001, 1002, 1003, 1004, 1005, 2001, 2002, 2003, 3001, 3002, 3003, 
#           4001, 4002, 4003, 4004, 4005, 4006, 4007, 5001, 5555, 6001, 8001, 9999)
# (Default: [])
set -gx fish_lsp_diagnostic_disable_error_codes 

# $fish_lsp_enable_experimental_diagnostics <BOOLEAN>
# Enables the experimental diagnostics feature, using `fish --no-execute`.
# This feature will enable the diagnostic error code 9999 (disabled by default).
# (Options: 'true', 'false')
# (Default: 'false')
set -gx fish_lsp_enable_experimental_diagnostics 

# $fish_lsp_max_background_files <NUMBER>
# The maximum number of background files to read into buffer on startup.
# (Example Options: 100, 250, 500, 1000, 5000, 10000)
# (Default: 10000)
set -gx fish_lsp_max_background_files 

# $fish_lsp_show_client_popups <BOOLEAN>
# Should the client receive pop-up window notification requests from the fish-lsp server?
# (Options: 'true', 'false')
# (Default: 'false')
set -gx fish_lsp_show_client_popups 

# $fish_lsp_single_workspace_support <BOOLEAN>
# Try to limit the fish-lsp's workspace searching to only the current workspace open.
# (Options: 'true', 'false')
# (Default: 'false')
set -gx fish_lsp_single_workspace_support

If you're interested in disabling specific diagnostic messages, the wiki includes a table of error codes that should be helpful. Diagnostics are a newer feature so PRs are welcome to improve their support.

Alternatively, you can now use comments to disable diagnostics.

# @fish-lsp-disable

Command Flags

Both the flags --enable and --disable are provided on the fish-lsp start subcommand. By default, all handlers will be enabled.

# displays what handlers are enabled. Removing the dump flag will run the server.
fish-lsp start --disable complete signature --dump 

Further Server Configuration

Any flags will overwrite their corresponding environment variables, if both are seen for the fish-lsp process. For this reason, it is encouraged to wrap any non-standard behavior of the fish-lsp in functions or aliases.

Custom server configurations can also be set interactively, or in a fish function (i.e., edit_command_buffer).

Due to the vast possibilities this project aims to support in the fish shell, sharing useful configurations is highly encouraged.

How does it work?

If you're new to the concept of the Language Server Protocol (LSP), this section should be useful to help you grasp its core purpose and benefits.

📸 Check out this insightful video by TJ DeVries for an introduction to the subject.

The LSP is designed to create a uniform approach for supporting a programming language across various development tools, moving beyond the confines of specific Text-Editor/IDE ecosystems. This standardization enhances a language's appeal by allowing developers to maintain consistent tooling support without needing to switch developer environments.

The core of this system is the interaction between a 'language server', which provides language services, and a 'language client', which consumes these services. The protocol facilitates this interaction, ensuring that any language client can leverage a well-defined set of features provided by the server.

Show a diagram to visualize a hypothetical fish-lsp process

graph

Additional Resources

  • Contributing - documentation describing how to contribute to the fish-lsp project.
  • Roadmap - goals for future project releases.
  • Wiki - further documentation and knowledge relevant to the project
  • Discussions - interact with maintainers
  • Site - website homepage
  • Client Examples - testable language client configurations
  • Sources - major influences for the project

Contributors

Special thanks to anyone who contributed to the project! Contributions of any kind are welcome!

nick
nick

💻
mimikun
mimikun

💻
Jaakko Paju
Jaakko Paju

💻
Sean Perry
Sean Perry

💻
Fabio Coatti
Fabio Coatti

💻
Peter Cardenas
Peter Cardenas

💻
Peter Tri Ho
Peter Tri Ho

💻
bnwa
bnwa

💻
Branch Vincent
Branch Vincent

💻
Jaeseok Lee
Jaeseok Lee

💻
ClanEver
ClanEver

💻
Nathan DeGruchy
Nathan DeGruchy

💻
Nan Huang
Nan Huang

💻

This project follows the all-contributors specification.

License

MIT

Package Sidebar

Install

npm i fish-lsp

Homepage

fish-lsp.dev

Weekly Downloads

1,448

Version

1.0.10

License

MIT

Unpacked Size

960 kB

Total Files

112

Last publish

Collaborators

  • ndonfris