Skip to content

Instantly share code, notes, and snippets.

@akitaonrails
Created January 13, 2026 18:30
Show Gist options
  • Select an option

  • Save akitaonrails/daa4ce4f707c4f43bd89b8649531f9ff to your computer and use it in GitHub Desktop.

Select an option

Save akitaonrails/daa4ce4f707c4f43bd89b8649531f9ff to your computer and use it in GitHub Desktop.
Installs all LSPs for all available Languages (Arch Linux/Omarch + Mise)
#!/usr/bin/env bash
set -euo pipefail
# LSP Installer for Arch Linux with Mise
# Installs major LSPs using native package managers or yay
# Only installs LSPs for languages that are already installed
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[OK]${NC} $1"; }
warn() { echo -e "${YELLOW}[SKIP]${NC} $1"; }
skip_lang() { echo -e "${RED}[LANG]${NC} $1 not installed, skipping LSPs"; }
command_exists() { command -v "$1" &>/dev/null; }
# ─────────────────────────────────────────────────────────────
# Language detection helpers
# ─────────────────────────────────────────────────────────────
has_c() { command_exists gcc || command_exists clang; }
has_rust() { command_exists rustc || command_exists cargo; }
has_go() { command_exists go; }
has_python() { command_exists python || command_exists python3; }
has_node() { command_exists node || command_exists npm; }
has_java() { command_exists java || command_exists javac; }
has_kotlin() { command_exists kotlin || command_exists kotlinc; }
has_ruby() { command_exists ruby; }
has_php() { command_exists php; }
has_lua() { command_exists lua || command_exists luajit; }
has_zig() { command_exists zig; }
has_haskell() { command_exists ghc || command_exists stack || command_exists cabal; }
has_elixir() { command_exists elixir || command_exists iex; }
has_scala() { command_exists scala || command_exists sbt; }
has_dotnet() { command_exists dotnet; }
has_ocaml() { command_exists ocaml || command_exists opam; }
has_clojure() { command_exists clojure || command_exists clj || command_exists lein; }
has_nix() { command_exists nix; }
has_terraform() { command_exists terraform || command_exists tofu; }
has_latex() { command_exists latex || command_exists pdflatex || command_exists xelatex; }
has_docker() { command_exists docker || command_exists podman; }
has_ansible() { command_exists ansible; }
has_sql() { command_exists psql || command_exists mysql || command_exists sqlite3; }
has_bash() { command_exists bash; }
# ─────────────────────────────────────────────────────────────
# Package installation helpers
# ─────────────────────────────────────────────────────────────
install_pacman() {
local pkg="$1"
if pacman -Qi "$pkg" &>/dev/null; then
warn "$pkg already installed"
else
sudo pacman -S --noconfirm --needed "$pkg" && success "$pkg" || warn "Failed: $pkg"
fi
}
install_yay() {
local pkg="$1"
if ! command_exists yay; then
warn "yay not found, skipping $pkg"
return
fi
if yay -Qi "$pkg" &>/dev/null; then
warn "$pkg already installed"
else
yay -S --noconfirm --needed "$pkg" && success "$pkg" || warn "Failed: $pkg"
fi
}
install_npm() {
local pkg="$1"
if npm list -g "$pkg" &>/dev/null 2>&1; then
warn "$pkg already installed"
else
npm install -g "$pkg" && success "$pkg" || warn "Failed: $pkg"
fi
}
install_pipx() {
local pkg="$1"
if ! command_exists pipx; then
pip install --user pipx 2>/dev/null || {
pip install --user "$pkg" && success "$pkg" || warn "Failed: $pkg"
return
}
fi
if pipx list 2>/dev/null | grep -q "$pkg"; then
warn "$pkg already installed"
else
pipx install "$pkg" && success "$pkg" || warn "Failed: $pkg"
fi
}
install_go() {
local pkg="$1"
local name="${pkg##*/}"
name="${name%%@*}"
# Check if binary already exists in GOPATH/bin
local gobin="${GOBIN:-${GOPATH:-$HOME/go}/bin}"
if [[ -x "$gobin/$name" ]]; then
warn "$name already installed"
return
fi
go install "$pkg" && success "$name" || warn "Failed: $name"
}
install_gem() {
local pkg="$1"
if gem list -i "^${pkg}$" &>/dev/null; then
warn "$pkg already installed"
else
gem install "$pkg" && success "$pkg" || warn "Failed: $pkg"
fi
}
# ─────────────────────────────────────────────────────────────
# C/C++ LSPs
# ─────────────────────────────────────────────────────────────
install_c_lsps() {
if ! has_c; then
skip_lang "C/C++ (gcc/clang)"
return
fi
info "Installing C/C++ LSPs..."
install_pacman clang # includes clangd
}
# ─────────────────────────────────────────────────────────────
# Rust LSPs
# ─────────────────────────────────────────────────────────────
install_rust_lsps() {
if ! has_rust; then
skip_lang "Rust"
return
fi
info "Installing Rust LSPs..."
if command_exists rustup; then
rustup component add rust-analyzer 2>/dev/null && success "rust-analyzer (rustup)" || install_pacman rust-analyzer
else
install_pacman rust-analyzer
fi
}
# ─────────────────────────────────────────────────────────────
# Go LSPs
# ─────────────────────────────────────────────────────────────
install_go_lsps() {
if ! has_go; then
skip_lang "Go"
return
fi
info "Installing Go LSPs..."
install_go golang.org/x/tools/gopls@latest
install_go github.com/go-delve/delve/cmd/dlv@latest
install_go github.com/nametake/golangci-lint-langserver@latest
}
# ─────────────────────────────────────────────────────────────
# Python LSPs
# ─────────────────────────────────────────────────────────────
install_python_lsps() {
if ! has_python; then
skip_lang "Python"
return
fi
info "Installing Python LSPs..."
# Prefer npm pyright (faster updates) if node available
if has_node; then
install_npm pyright
else
install_pipx pyright
fi
install_pipx python-lsp-server
install_pipx ruff-lsp
}
# ─────────────────────────────────────────────────────────────
# Node.js/TypeScript LSPs
# ─────────────────────────────────────────────────────────────
install_node_lsps() {
if ! has_node; then
skip_lang "Node.js"
return
fi
info "Installing Node.js/TypeScript LSPs..."
install_npm typescript
install_npm typescript-language-server
install_npm vscode-langservers-extracted # HTML, CSS, JSON, ESLint
install_npm "@tailwindcss/language-server"
install_npm "@vue/language-server"
install_npm svelte-language-server
install_npm graphql-language-service-cli
install_npm "@prisma/language-server"
install_npm emmet-ls
}
# ─────────────────────────────────────────────────────────────
# Java LSPs
# ─────────────────────────────────────────────────────────────
install_java_lsps() {
if ! has_java; then
skip_lang "Java"
return
fi
info "Installing Java LSPs..."
install_yay jdtls
}
# ─────────────────────────────────────────────────────────────
# Kotlin LSPs
# ─────────────────────────────────────────────────────────────
install_kotlin_lsps() {
if ! has_kotlin; then
skip_lang "Kotlin"
return
fi
info "Installing Kotlin LSPs..."
install_yay kotlin-language-server
}
# ─────────────────────────────────────────────────────────────
# Ruby LSPs
# ─────────────────────────────────────────────────────────────
install_ruby_lsps() {
if ! has_ruby; then
skip_lang "Ruby"
return
fi
info "Installing Ruby LSPs..."
install_gem solargraph
install_gem ruby-lsp
}
# ─────────────────────────────────────────────────────────────
# PHP LSPs
# ─────────────────────────────────────────────────────────────
install_php_lsps() {
if ! has_php; then
skip_lang "PHP"
return
fi
if ! has_node; then
warn "PHP LSP (intelephense) requires npm, skipping"
return
fi
info "Installing PHP LSPs..."
install_npm intelephense
}
# ─────────────────────────────────────────────────────────────
# Lua LSPs
# ─────────────────────────────────────────────────────────────
install_lua_lsps() {
if ! has_lua; then
skip_lang "Lua"
return
fi
info "Installing Lua LSPs..."
install_pacman lua-language-server
}
# ─────────────────────────────────────────────────────────────
# Zig LSPs
# ─────────────────────────────────────────────────────────────
install_zig_lsps() {
if ! has_zig; then
skip_lang "Zig"
return
fi
info "Installing Zig LSPs..."
install_pacman zls
}
# ─────────────────────────────────────────────────────────────
# Haskell LSPs
# ─────────────────────────────────────────────────────────────
install_haskell_lsps() {
if ! has_haskell; then
skip_lang "Haskell"
return
fi
info "Installing Haskell LSPs..."
install_yay haskell-language-server
}
# ─────────────────────────────────────────────────────────────
# Elixir LSPs
# ─────────────────────────────────────────────────────────────
install_elixir_lsps() {
if ! has_elixir; then
skip_lang "Elixir"
return
fi
info "Installing Elixir LSPs..."
install_yay elixir-ls
}
# ─────────────────────────────────────────────────────────────
# Scala LSPs
# ─────────────────────────────────────────────────────────────
install_scala_lsps() {
if ! has_scala; then
skip_lang "Scala"
return
fi
info "Installing Scala LSPs..."
install_yay metals
}
# ─────────────────────────────────────────────────────────────
# C# / F# (.NET) LSPs
# ─────────────────────────────────────────────────────────────
install_dotnet_lsps() {
if ! has_dotnet; then
skip_lang ".NET (C#/F#)"
return
fi
info "Installing .NET LSPs..."
install_yay omnisharp-roslyn
install_yay fsautocomplete
}
# ─────────────────────────────────────────────────────────────
# OCaml LSPs
# ─────────────────────────────────────────────────────────────
install_ocaml_lsps() {
if ! has_ocaml; then
skip_lang "OCaml"
return
fi
info "Installing OCaml LSPs..."
if command_exists opam; then
opam install ocaml-lsp-server -y && success "ocaml-lsp-server" || warn "Failed"
else
install_yay ocaml-lsp-server
fi
}
# ─────────────────────────────────────────────────────────────
# Clojure LSPs
# ─────────────────────────────────────────────────────────────
install_clojure_lsps() {
if ! has_clojure; then
skip_lang "Clojure"
return
fi
info "Installing Clojure LSPs..."
install_yay clojure-lsp-bin
}
# ─────────────────────────────────────────────────────────────
# Nix LSPs
# ─────────────────────────────────────────────────────────────
install_nix_lsps() {
if ! has_nix; then
skip_lang "Nix"
return
fi
info "Installing Nix LSPs..."
install_pacman nil
}
# ─────────────────────────────────────────────────────────────
# Bash LSPs
# ─────────────────────────────────────────────────────────────
install_bash_lsps() {
if ! has_bash; then
skip_lang "Bash"
return
fi
info "Installing Bash LSPs..."
install_pacman bash-language-server
}
# ─────────────────────────────────────────────────────────────
# Terraform LSPs
# ─────────────────────────────────────────────────────────────
install_terraform_lsps() {
if ! has_terraform; then
skip_lang "Terraform"
return
fi
info "Installing Terraform LSPs..."
install_pacman terraform-ls
}
# ─────────────────────────────────────────────────────────────
# LaTeX LSPs
# ─────────────────────────────────────────────────────────────
install_latex_lsps() {
if ! has_latex; then
skip_lang "LaTeX"
return
fi
info "Installing LaTeX LSPs..."
install_pacman texlab
}
# ─────────────────────────────────────────────────────────────
# Docker LSPs
# ─────────────────────────────────────────────────────────────
install_docker_lsps() {
if ! has_docker; then
skip_lang "Docker"
return
fi
info "Installing Docker LSPs..."
install_yay dockerfile-language-server
}
# ─────────────────────────────────────────────────────────────
# Ansible LSPs
# ─────────────────────────────────────────────────────────────
install_ansible_lsps() {
if ! has_ansible; then
skip_lang "Ansible"
return
fi
if ! has_node; then
warn "Ansible LSP requires npm, skipping"
return
fi
info "Installing Ansible LSPs..."
install_npm "@ansible/ansible-language-server"
}
# ─────────────────────────────────────────────────────────────
# SQL LSPs
# ─────────────────────────────────────────────────────────────
install_sql_lsps() {
if ! has_sql; then
skip_lang "SQL (psql/mysql/sqlite)"
return
fi
info "Installing SQL LSPs..."
install_pacman sqls
}
# ─────────────────────────────────────────────────────────────
# Generic config file LSPs (always install)
# ─────────────────────────────────────────────────────────────
install_generic_lsps() {
info "Installing generic config LSPs (YAML, TOML, JSON, Markdown, XML)..."
install_pacman yaml-language-server
install_pacman taplo # TOML
install_pacman marksman # Markdown
install_yay lemminx # XML
}
# ─────────────────────────────────────────────────────────────
# Main
# ─────────────────────────────────────────────────────────────
main() {
echo "═══════════════════════════════════════════════════════════"
echo " LSP Installer for Arch Linux + Mise"
echo " (Only installs LSPs for detected languages)"
echo "═══════════════════════════════════════════════════════════"
echo
# Language-specific LSPs
install_c_lsps
install_rust_lsps
install_go_lsps
install_python_lsps
install_node_lsps
install_java_lsps
install_kotlin_lsps
install_ruby_lsps
install_php_lsps
install_lua_lsps
install_zig_lsps
install_haskell_lsps
install_elixir_lsps
install_scala_lsps
install_dotnet_lsps
install_ocaml_lsps
install_clojure_lsps
install_nix_lsps
install_bash_lsps
install_terraform_lsps
install_latex_lsps
install_docker_lsps
install_ansible_lsps
install_sql_lsps
echo
# Always-useful LSPs for config files
install_generic_lsps
echo
echo "═══════════════════════════════════════════════════════════"
success "LSP installation complete!"
echo "═══════════════════════════════════════════════════════════"
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment