lsmux

package module
v0.0.0-...-627d271 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 11, 2026 License: MIT Imports: 24 Imported by: 0

README

lsmux

A language server multiplexer.

Installation

% go install github.com/buzztaiki/lsmux/cmd/lsmux@latest

Usage

Put your configuration to $HOME/.config/lsmux/config.yaml as shown below:

servers:
  - name: tsls
    command: typescript-language-server
    args: [--stdio]
    initializationOptions:
      plugins:
        - name: "@vue/typescript-plugin"
          location: /usr/lib/node_modules/@vue/language-server
          languages: ["vue"]
          configNamespace: typescript

  - name: vuels
    command: vue-language-server
    args: [--stdio]

  - name: eslint
    command: eslint-language-server
    args: [--stdio]

  - name: pyright
    command: pyright-langserver
    args: [--stdio]

  - name: ruff
    command: ruff
    args: [server]

Run it by specifying the language servers you want to run simultaneously with the --servers option as shown below:

% lsmux --servers tsls,vuels,eslint
% lsmux --servers pyright,ruff

Write it as follows for Eglot:

(add-to-list 'eglot-server-programs
             '(((js-mode :language-id "javascript") (js-ts-mode :language-id "javascript")
                typescript-mode typescript-ts-mode
                vue-mode vue-ts-mode)
               "lsmux" "--servers" "tsls,vuels,eslint"))
(add-to-list 'eglot-server-programs
             '((python-ts-mode python-mode) "lsmux" "--servers" "pyright,ruff"))

Features

  • Merge completion results from all servers.
  • Merge Diagnostics notifications from all servers.
  • Dispatch Code Action and Execute Command.
  • Transfer requests other than the above to the first capable server.
  • Transfer notifications to all servers.
  • Support tsserver/request for vuels v3.

Alternatives

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrParse            = jsonrpc2.ErrParse
	ErrInvalidRequest   = jsonrpc2.ErrInvalidRequest
	ErrMethodNotFound   = jsonrpc2.ErrMethodNotFound
	ErrInvalidParams    = jsonrpc2.ErrInvalidParams
	ErrUnknown          = jsonrpc2.ErrUnknown
	ErrInternal         = jsonrpc2.ErrInternal
	ErrServerOverloaded = jsonrpc2.ErrServerOverloaded
)

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#errorCodes

Functions

func CLI

func CLI(args []string) error

func Deref

func Deref[T any](t *T) T

func Execute

func Execute(ctx context.Context, cfg *Config) error

func NewCmdPipeListener

func NewCmdPipeListener(ctx context.Context, cmd *exec.Cmd) (jsonrpc2.Listener, error)

func NewIOPipeListener

func NewIOPipeListener(ctx context.Context, r io.Reader, w io.Writer) (jsonrpc2.Listener, error)

func SliceFor

func SliceFor[T any](t T, n int) []T

SliceFor creates a slice of type T with length n.

Types

type Binder

type Binder struct {
	// contains filtered or unexported fields
}

func NewBinder

func NewBinder(h jsonrpc2.Handler) *Binder

func (Binder) Bind

type ClientHandler

type ClientHandler struct {
	// contains filtered or unexported fields
}

func NewClientHandler

func NewClientHandler(serverRegistry *ServerConnectionRegistry) *ClientHandler

func (*ClientHandler) Handle

func (h *ClientHandler) Handle(ctx context.Context, r *jsonrpc2.Request) (any, error)

func (*ClientHandler) WaitExit

func (h *ClientHandler) WaitExit()

type Config

type Config struct {
	LogLevel slog.Level     `yaml:"logLevel"`
	Servers  []ServerConfig `yaml:"servers"` // use slice to respect config order
}

func LoadConfig

func LoadConfig(r io.Reader, serverNames []string) (*Config, error)

func LoadConfigFile

func LoadConfigFile(fname string, serverNames []string) (*Config, error)

type DiagnosticRegistry

type DiagnosticRegistry struct {
	// contains filtered or unexported fields
}

func NewDiagnosticRegistry

func NewDiagnosticRegistry() *DiagnosticRegistry

func (*DiagnosticRegistry) GetDiagnostics

func (r *DiagnosticRegistry) GetDiagnostics(uri protocol.DocumentUri) []protocol.Diagnostic

func (*DiagnosticRegistry) UpdateDiagnostics

func (r *DiagnosticRegistry) UpdateDiagnostics(uri protocol.DocumentUri, serverName string, diags []protocol.Diagnostic)

type Middleware

type Middleware func(next jsonrpc2.Handler) jsonrpc2.Handler

func ContextLogMiddleware

func ContextLogMiddleware(name string) Middleware

func LoggingMiddleware

func LoggingMiddleware() Middleware

type MiddlewareBinder

type MiddlewareBinder struct {
	// contains filtered or unexported fields
}

func NewMiddlewareBinder

func NewMiddlewareBinder(binder jsonrpc2.Binder, middlewares ...Middleware) *MiddlewareBinder

func (*MiddlewareBinder) Bind

type ServerConfig

type ServerConfig struct {
	Name                  string         `yaml:"name"`
	Command               string         `yaml:"command"`
	Args                  []string       `yaml:"args"`
	InitializationOptions map[string]any `yaml:"initializationOptions"`
}

type ServerConnection

type ServerConnection struct {
	Name string

	InitOptions           map[string]any
	SupportedCapabilities capability.SupportedSet
	Capabilities          *protocol.ServerCapabilities
	// contains filtered or unexported fields
}

func (*ServerConnection) Call

func (c *ServerConnection) Call(ctx context.Context, method string, params any, res any) error

func (*ServerConnection) CallWithRawResult

func (c *ServerConnection) CallWithRawResult(ctx context.Context, method string, params any) (json.RawMessage, error)

func (*ServerConnection) Close

func (c *ServerConnection) Close() error

func (*ServerConnection) Notify

func (c *ServerConnection) Notify(ctx context.Context, method string, params any) error

type ServerConnectionList

type ServerConnectionList []*ServerConnection

func (ServerConnectionList) FilterBySupportedMethod

func (l ServerConnectionList) FilterBySupportedMethod(method string) ServerConnectionList

func (ServerConnectionList) FindByCommand

func (l ServerConnectionList) FindByCommand(command string) (*ServerConnection, bool)

func (ServerConnectionList) FindByName

func (l ServerConnectionList) FindByName(name string) (*ServerConnection, bool)

type ServerConnectionRegistry

type ServerConnectionRegistry struct {
	// contains filtered or unexported fields
}

func NewServerConnectionRegistry

func NewServerConnectionRegistry(nservers int) *ServerConnectionRegistry

func (*ServerConnectionRegistry) Add

func (r *ServerConnectionRegistry) Add(ctx context.Context, name string, conn *jsonrpc2.Connection, initOptions map[string]any)

func (*ServerConnectionRegistry) Servers

type ServerHandler

type ServerHandler struct {
	// contains filtered or unexported fields
}

func NewServerHandler

func NewServerHandler(name string, clientConn *jsonrpc2.Connection, diagRegistry *DiagnosticRegistry) *ServerHandler

func (*ServerHandler) Handle

func (h *ServerHandler) Handle(ctx context.Context, r *jsonrpc2.Request) (any, error)

type VuelsTSServerRequestInterceptor

type VuelsTSServerRequestInterceptor struct {
	// contains filtered or unexported fields
}

VuelsTSServerRequestInterceptor intercepts "tsserver/request" notifications to support vuels v3 features. see https://github.com/vuejs/language-tools/discussions/5456

func NewVuelsTSServerRequestInterceptor

func NewVuelsTSServerRequestInterceptor(name string, serverRegistry *ServerConnectionRegistry) *VuelsTSServerRequestInterceptor

func (*VuelsTSServerRequestInterceptor) Handler

Directories

Path Synopsis
cmd
lsmux command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL