Created
January 13, 2026 18:30
-
-
Save akitaonrails/daa4ce4f707c4f43bd89b8649531f9ff to your computer and use it in GitHub Desktop.
Installs all LSPs for all available Languages (Arch Linux/Omarch + Mise)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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