Skip to main content
Glama
ls_config.py13.4 kB
""" Configuration objects for language servers """ import fnmatch from collections.abc import Iterable from dataclasses import dataclass, field from enum import Enum from typing import TYPE_CHECKING, Self if TYPE_CHECKING: from solidlsp import SolidLanguageServer class FilenameMatcher: def __init__(self, *patterns: str) -> None: """ :param patterns: fnmatch-compatible patterns """ self.patterns = patterns def is_relevant_filename(self, fn: str) -> bool: for pattern in self.patterns: if fnmatch.fnmatch(fn, pattern): return True return False class Language(str, Enum): """ Enumeration of language servers supported by SolidLSP. """ CSHARP = "csharp" PYTHON = "python" RUST = "rust" JAVA = "java" KOTLIN = "kotlin" TYPESCRIPT = "typescript" GO = "go" RUBY = "ruby" DART = "dart" CPP = "cpp" PHP = "php" R = "r" PERL = "perl" CLOJURE = "clojure" ELIXIR = "elixir" ELM = "elm" TERRAFORM = "terraform" SWIFT = "swift" BASH = "bash" ZIG = "zig" LUA = "lua" NIX = "nix" ERLANG = "erlang" AL = "al" REGO = "rego" SCALA = "scala" JULIA = "julia" FORTRAN = "fortran" HASKELL = "haskell" # Experimental or deprecated Language Servers TYPESCRIPT_VTS = "typescript_vts" """Use the typescript language server through the natively bundled vscode extension via https://github.com/yioneko/vtsls""" PYTHON_JEDI = "python_jedi" """Jedi language server for Python (instead of pyright, which is the default)""" CSHARP_OMNISHARP = "csharp_omnisharp" """OmniSharp language server for C# (instead of the default csharp-ls by microsoft). Currently has problems with finding references, and generally seems less stable and performant. """ RUBY_SOLARGRAPH = "ruby_solargraph" """Solargraph language server for Ruby (legacy, experimental). Use Language.RUBY (ruby-lsp) for better performance and modern LSP features. """ MARKDOWN = "markdown" """Marksman language server for Markdown (experimental). Must be explicitly specified as the main language, not auto-detected. This is an edge case primarily useful when working on documentation-heavy projects. """ YAML = "yaml" """YAML language server (experimental). Must be explicitly specified as the main language, not auto-detected. """ @classmethod def iter_all(cls, include_experimental: bool = False) -> Iterable[Self]: for lang in cls: if include_experimental or not lang.is_experimental(): yield lang def is_experimental(self) -> bool: """ Check if the language server is experimental or deprecated. """ return self in {self.TYPESCRIPT_VTS, self.PYTHON_JEDI, self.CSHARP_OMNISHARP, self.RUBY_SOLARGRAPH, self.MARKDOWN, self.YAML} def __str__(self) -> str: return self.value def get_source_fn_matcher(self) -> FilenameMatcher: match self: case self.PYTHON | self.PYTHON_JEDI: return FilenameMatcher("*.py", "*.pyi") case self.JAVA: return FilenameMatcher("*.java") case self.TYPESCRIPT | self.TYPESCRIPT_VTS: # see https://github.com/oraios/serena/issues/204 path_patterns = [] for prefix in ["c", "m", ""]: for postfix in ["x", ""]: for base_pattern in ["ts", "js"]: path_patterns.append(f"*.{prefix}{base_pattern}{postfix}") return FilenameMatcher(*path_patterns) case self.CSHARP | self.CSHARP_OMNISHARP: return FilenameMatcher("*.cs") case self.RUST: return FilenameMatcher("*.rs") case self.GO: return FilenameMatcher("*.go") case self.RUBY: return FilenameMatcher("*.rb", "*.erb") case self.RUBY_SOLARGRAPH: return FilenameMatcher("*.rb") case self.CPP: return FilenameMatcher("*.cpp", "*.h", "*.hpp", "*.c", "*.hxx", "*.cc", "*.cxx") case self.KOTLIN: return FilenameMatcher("*.kt", "*.kts") case self.DART: return FilenameMatcher("*.dart") case self.PHP: return FilenameMatcher("*.php") case self.R: return FilenameMatcher("*.R", "*.r", "*.Rmd", "*.Rnw") case self.PERL: return FilenameMatcher("*.pl", "*.pm", "*.t") case self.CLOJURE: return FilenameMatcher("*.clj", "*.cljs", "*.cljc", "*.edn") # codespell:ignore edn case self.ELIXIR: return FilenameMatcher("*.ex", "*.exs") case self.ELM: return FilenameMatcher("*.elm") case self.TERRAFORM: return FilenameMatcher("*.tf", "*.tfvars", "*.tfstate") case self.SWIFT: return FilenameMatcher("*.swift") case self.BASH: return FilenameMatcher("*.sh", "*.bash") case self.YAML: return FilenameMatcher("*.yaml", "*.yml") case self.ZIG: return FilenameMatcher("*.zig", "*.zon") case self.LUA: return FilenameMatcher("*.lua") case self.NIX: return FilenameMatcher("*.nix") case self.ERLANG: return FilenameMatcher("*.erl", "*.hrl", "*.escript", "*.config", "*.app", "*.app.src") case self.AL: return FilenameMatcher("*.al", "*.dal") case self.REGO: return FilenameMatcher("*.rego") case self.MARKDOWN: return FilenameMatcher("*.md", "*.markdown") case self.SCALA: return FilenameMatcher("*.scala", "*.sbt") case self.JULIA: return FilenameMatcher("*.jl") case self.FORTRAN: return FilenameMatcher( "*.f90", "*.F90", "*.f95", "*.F95", "*.f03", "*.F03", "*.f08", "*.F08", "*.f", "*.F", "*.for", "*.FOR", "*.fpp", "*.FPP" ) case self.HASKELL: return FilenameMatcher("*.hs", "*.lhs") case _: raise ValueError(f"Unhandled language: {self}") def get_ls_class(self) -> type["SolidLanguageServer"]: match self: case self.PYTHON: from solidlsp.language_servers.pyright_server import PyrightServer return PyrightServer case self.PYTHON_JEDI: from solidlsp.language_servers.jedi_server import JediServer return JediServer case self.JAVA: from solidlsp.language_servers.eclipse_jdtls import EclipseJDTLS return EclipseJDTLS case self.KOTLIN: from solidlsp.language_servers.kotlin_language_server import KotlinLanguageServer return KotlinLanguageServer case self.RUST: from solidlsp.language_servers.rust_analyzer import RustAnalyzer return RustAnalyzer case self.CSHARP: from solidlsp.language_servers.csharp_language_server import CSharpLanguageServer return CSharpLanguageServer case self.CSHARP_OMNISHARP: from solidlsp.language_servers.omnisharp import OmniSharp return OmniSharp case self.TYPESCRIPT: from solidlsp.language_servers.typescript_language_server import TypeScriptLanguageServer return TypeScriptLanguageServer case self.TYPESCRIPT_VTS: from solidlsp.language_servers.vts_language_server import VtsLanguageServer return VtsLanguageServer case self.GO: from solidlsp.language_servers.gopls import Gopls return Gopls case self.RUBY: from solidlsp.language_servers.ruby_lsp import RubyLsp return RubyLsp case self.RUBY_SOLARGRAPH: from solidlsp.language_servers.solargraph import Solargraph return Solargraph case self.DART: from solidlsp.language_servers.dart_language_server import DartLanguageServer return DartLanguageServer case self.CPP: from solidlsp.language_servers.clangd_language_server import ClangdLanguageServer return ClangdLanguageServer case self.PHP: from solidlsp.language_servers.intelephense import Intelephense return Intelephense case self.PERL: from solidlsp.language_servers.perl_language_server import PerlLanguageServer return PerlLanguageServer case self.CLOJURE: from solidlsp.language_servers.clojure_lsp import ClojureLSP return ClojureLSP case self.ELIXIR: from solidlsp.language_servers.elixir_tools.elixir_tools import ElixirTools return ElixirTools case self.ELM: from solidlsp.language_servers.elm_language_server import ElmLanguageServer return ElmLanguageServer case self.TERRAFORM: from solidlsp.language_servers.terraform_ls import TerraformLS return TerraformLS case self.SWIFT: from solidlsp.language_servers.sourcekit_lsp import SourceKitLSP return SourceKitLSP case self.BASH: from solidlsp.language_servers.bash_language_server import BashLanguageServer return BashLanguageServer case self.YAML: from solidlsp.language_servers.yaml_language_server import YamlLanguageServer return YamlLanguageServer case self.ZIG: from solidlsp.language_servers.zls import ZigLanguageServer return ZigLanguageServer case self.NIX: from solidlsp.language_servers.nixd_ls import NixLanguageServer # type: ignore return NixLanguageServer case self.LUA: from solidlsp.language_servers.lua_ls import LuaLanguageServer return LuaLanguageServer case self.ERLANG: from solidlsp.language_servers.erlang_language_server import ErlangLanguageServer return ErlangLanguageServer case self.AL: from solidlsp.language_servers.al_language_server import ALLanguageServer return ALLanguageServer case self.REGO: from solidlsp.language_servers.regal_server import RegalLanguageServer return RegalLanguageServer case self.MARKDOWN: from solidlsp.language_servers.marksman import Marksman return Marksman case self.R: from solidlsp.language_servers.r_language_server import RLanguageServer return RLanguageServer case self.SCALA: from solidlsp.language_servers.scala_language_server import ScalaLanguageServer return ScalaLanguageServer case self.JULIA: from solidlsp.language_servers.julia_server import JuliaLanguageServer return JuliaLanguageServer case self.FORTRAN: from solidlsp.language_servers.fortran_language_server import FortranLanguageServer return FortranLanguageServer case self.HASKELL: from solidlsp.language_servers.haskell_language_server import HaskellLanguageServer return HaskellLanguageServer case _: raise ValueError(f"Unhandled language: {self}") @classmethod def from_ls_class(cls, ls_class: type["SolidLanguageServer"]) -> Self: """ Get the Language enum value from a SolidLanguageServer class. :param ls_class: The SolidLanguageServer class to find the corresponding Language for :return: The Language enum value :raises ValueError: If the language server class is not supported """ for enum_instance in cls: if enum_instance.get_ls_class() == ls_class: return enum_instance raise ValueError(f"Unhandled language server class: {ls_class}") @dataclass class LanguageServerConfig: """ Configuration parameters """ code_language: Language trace_lsp_communication: bool = False start_independent_lsp_process: bool = True ignored_paths: list[str] = field(default_factory=list) """Paths, dirs or glob-like patterns. The matching will follow the same logic as for .gitignore entries""" encoding: str = "utf-8" """File encoding to use when reading source files""" @classmethod def from_dict(cls, env: dict) -> Self: import inspect return cls(**{k: v for k, v in env.items() if k in inspect.signature(cls).parameters})

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/oraios/serena'

If you have feedback or need assistance with the MCP directory API, please join our Discord server