serena.ls_manager#


exception LanguageServerManagerInitialisationError(message)[source]#

Bases: Exception

Parameters:

message (str)

class LanguageServerManager(language_servers, language_server_factory, project)[source]#

Bases: object

Manages one or more language servers for a project.

Parameters:
  • language_servers (dict[LanguageServerId, SolidLanguageServer]) – a mapping from language to language server; the servers are assumed to be already started. The first server in the iteration order is used as the default server. All servers are assumed to serve the same project root.

  • language_server_factory (LanguageServerFactory) – factory for language server creation; if None, dynamic (re)creation of language servers is not supported

  • project (Project)

static from_languages(languages, factory, project)[source]#

Creates a manager with language servers for the given languages using the given factory. The language servers are started in parallel threads.

Parameters:
  • languages (list[LanguageServerId]) – the languages for which to spawn language servers

  • factory (LanguageServerFactory) – the factory for language server creation

  • project (Project) – the project for which the language servers are created

Returns:

the instance

Return type:

LanguageServerManager

get_language_server(relative_path)[source]#
Parameters:

relative_path (str) – relative path to a file

Return type:

SolidLanguageServer

restart_language_server(language)[source]#

Forces recreation and restart of the language server for the given language. It is assumed that the language server for the given language is no longer running.

Parameters:

language (LanguageServerId) – the language

Returns:

the newly created language server

Return type:

SolidLanguageServer

add_language_server(ls_id)[source]#

Dynamically adds a new language server for the given language.

Parameters:

ls_id (LanguageServerId) – the language server to add

Returns:

the newly created language server

Return type:

SolidLanguageServer

remove_language_server(language, save_cache=False)[source]#

Removes the language server for the given language, stopping it if it is running.

Parameters:
  • language (LanguageServerId) – the language

  • save_cache (bool)

Return type:

None

get_active_language_server_ids()[source]#

Returns the list of languages for which language servers are currently managed.

Returns:

list of languages

Return type:

list[LanguageServerId]

stop_all(save_cache=False, timeout=2.0)[source]#

Stops all managed language servers.

Parameters:
  • save_cache (bool) – whether to save the cache before stopping

  • timeout (float) – timeout for shutdown of each language server

Return type:

None

save_all_caches()[source]#

Saves the caches of all managed language servers.

Return type:

None

sync_file_system_changes()[source]#

Polls the file system for changes to source files and notifies the language servers of any changes (particularly changes that happened outside of Serena’s own file tools, which are not covered by the notifications sent by those tools/CodeEditor).

Returns:

the number of individual file change events detected (0 if nothing changed).

Return type:

int

class LanguageServerFileChangeNotifier(project, language_server_manager, initial_poll=True)[source]#

Bases: object

Detects changes to source files on disk and notifies language servers of those changes.

Parameters:
poll_and_notify()[source]#

Detects source files that were changed, created or deleted on disk since the last call and notifies every language server managed for this project via the LSP workspace/didChangeWatchedFiles notification.

This exists because Serena’s own file and symbol tools notify the language server inline (via didOpen/didChange/didClose) when they edit a file, but edits made through any other channel (another editor, a second agent, a git checkout, a build step) are otherwise invisible to a warm language server, causing symbolic queries to answer from a stale index.

The set of files considered is exactly the set Serena itself tracks (see gather_source_files()), so no separate file-discovery logic has to be kept in sync. The dominant cost is the directory walk plus one os.stat per tracked file; this is intended to be called before symbolic tool invocations rather than on a timer.

Returns:

the number of change events sent (0 if nothing changed, if no language server is running yet, or on the first call, which only establishes the baseline).

Return type:

int