85 KiB
layout | title | category | tags | order | |||
---|---|---|---|---|---|---|---|
developer-doc | Enso Protocol Language Server Message Specification | language-server |
|
4 |
Enso Protocol Language Server Message Specification
This document contains the specification of the Enso protocol messages that pertain to the language server component. Please familiarise yourself with the common features of the protocol before reading this document.
For information on the design and architecture of the protocol, as well as its transport formats, please look here.
- Types
ExpressionId
ContextId
StackItem
MethodPointer
ProfilingInfo
ExpressionUpdate
ExpressionUpdatePayload
VisualisationConfiguration
SuggestionEntryArgument
SuggestionEntry
SuggestionEntryType
SuggestionId
SuggestionsDatabaseEntry
FieldAction
FieldUpdate
SuggestionArgumentUpdate
SuggestionsDatabaseUpdate
Export
File
DirectoryTree
FileAttributes
UTCDateTime
FileEventKind
Position
Range
TextEdit
DiagnosticType
StackTraceElement
Diagnostic
SHA3-224
FileEdit
FileContents
FileSystemObject
WorkspaceEdit
EnsoDigest
FileSegment
- Connection Management
- Capability Management
- Capabilities
- File Management Operations
- Text Editing Operations
- Workspace Operations
- Monitoring
- Refactoring
- Execution Management Operations
- Execution Management Example
- Create Execution Context
- Push Item
- Pop Item
executionContext/create
executionContext/destroy
executionContext/fork
executionContext/push
executionContext/pop
executionContext/recompute
executionContext/expressionUpdates
executionContext/executionFailed
executionContext/executionStatus
executionContext/executeExpression
executionContext/attachVisualisation
executionContext/detachVisualisation
executionContext/modifyVisualisation
executionContext/visualisationUpdate
executionContext/visualisationEvaluationFailed
- Search Operations
- Input/Output Operations
- Errors
Error
AccessDeniedError
FileSystemError
ContentRootNotFoundError
FileNotFound
FileExists
OperationTimeoutError
NotDirectory
NotFile
CannotOverwrite
ReadOutOfBounds
StackItemNotFoundError
ContextNotFoundError
EmptyStackError
InvalidStackItemError
ModuleNotFoundError
VisualisationNotFoundError
VisualisationExpressionError
FileNotOpenedError
TextEditValidationError
InvalidVersionError
WriteDeniedError
CapabilityNotAcquired
SessionNotInitialisedError
SessionAlreadyInitialisedError
ResourcesInitializationError
SuggestionsDatabaseError
ProjectNotFoundError
ModuleNameNotResolvedError
SuggestionNotFoundError
Types
There are a number of types that are used only within the language server's protocol messages. These are specified here.
ExpressionId
An identifier used for Enso expressions.
type ExpressionId = UUID;
ContextId
An identifier used for execution contexts.
type ContextId = UUID;
StackItem
A representation of an executable position in code, used by the execution APIs.
ExplicitCall
is a call performed at the top of the stack, to initialize the
context with first execution. The thisArgumentsPosition
field can be omitted,
in which case the context will try to infer the argument on a best-effort basis.
E.g. for a module-level method, or a method defined on a parameter-less atom
type, this
will be substituted for the unambiguous singleton instance.
LocalCall
is a call corresponding to "entering a function call".
type StackItem = ExplicitCall | LocalCall;
interface ExplicitCall {
methodPointer: MethodPointer;
thisArgumentExpression?: String;
positionalArgumentsExpressions: String[];
}
interface LocalCall {
expressionId: ExpressionId;
}
MethodPointer
Points to a method definition.
interface MethodPointer {
/** The fully qualified module name. */
module: String;
/** The type on which the method is defined. */
definedOnType: String;
/** The method name. */
name: String;
}
ProfilingInfo
Profiling information on an executed expression. It is implemented as a union as additional types of information will be added in the future.
type ProfilingInfo = ExecutionTime;
Where:
interface ExecutionTime {
/** The time elapsed during the expression's evaluation, in nanoseconds */
nanoTime: Number;
}
ExpressionUpdate
An update about the computed expression.
interface ExpressionUpdate {
/**
* The id of updated expression.
*/
expressionId: ExpressionId;
/**
* The updated type of the expression.
*/
type?: String;
/**
* The updated pointer to the method call.
*/
methodPointer?: SuggestionId;
/**
* Profiling information about the expression.
*/
profilingInfo: ProfilingInfo[];
/**
* Wether or not the expression's value came from the cache.
*/
fromCache: bool;
/**
* An extra information about the computed value.
*/
payload: ExpressionUpdatePayload;
}
ExpressionUpdatePayload
An information about the computed value.
type ExpressionUpdatePayload = Value | DatafalowError | Panic;
/**
* An empty payload. Indicates that the expression was computed to a value.
*/
interface Value {}
/**
* Indicates that the expression was computed to an error.
*/
interface DataflowError {
/**
* The list of expressions leading to the root error.
*/
trace: ExpressionId[];
}
/**
* Indicates that the expression failed with the runtime exception.
*/
interface Panic {
/**
* The error message.
*/
message: String;
/**
* The stack trace.
*/
trace: ExpressionId[];
}
VisualisationConfiguration
A configuration object for properties of the visualisation.
interface VisualisationConfiguration {
/**
* An execution context of the visualisation.
*/
executionContextId: UUID;
/**
* A qualified name of the module containing the expression which creates
* visualisation.
*/
visualisationModule: String;
/**
* The expression that creates a visualisation.
*/
expression: String;
}
SuggestionEntryArgument
The argument of a SuggestionEntry
.
Format
// The argument of an atom, method or function suggestion
interface SuggestionEntryArgument {
// The argument name
name: string;
// The arguement type. String 'Any' is used to specify genric types
type: string;
// Indicates whether the argument is lazy
isSuspended: bool;
// Indicates whether the argument has default value
hasDefault: bool;
// Optional default value
defaultValue?: string;
}
SuggestionEntry
The language construct that can be returned as a suggestion.
Format
// The definition scope
interface SuggestionEntryScope {
// The start position of the definition scope
start: Position;
// The end position of the definition scope
end: Position;
}
// A type of suggestion entries.
type SuggestionEntry =
// A value constructor
| SuggestionEntryAtom
// A method defined on a type
| SuggestionEntryMethod
// A function
| SuggestionEntryFunction
// A local value
| SuggestionEntryLocal;
interface SuggestionEntryAtom {
externalId?: UUID;
name: string;
module: string;
arguments: SuggestionEntryArgument[];
returnType: string;
documentation?: string;
}
interface SuggestionEntryMethod {
externalId?: UUID;
name: string;
module: string;
arguments: SuggestionEntryArgument[];
selfType: string;
returnType: string;
documentation?: string;
}
interface SuggestionEntryFunction {
externalId?: UUID;
name: string;
module: string;
arguments: SuggestionEntryArgument[];
returnType: string;
scope: SuggestionEntryScope;
}
interface SuggestionEntryLocal {
externalId?: UUID;
name: string;
module: string;
returnType: string;
scope: SuggestionEntryScope;
}
SuggestionEntryType
The suggestion entry type that is used as a filter in search requests.
Format
// The kind of a suggestion.
type SuggestionEntryType = Atom | Method | Function | Local;
SuggestionId
The suggestion entry id of the suggestions database.
Format
type SuggestionId = number;
SuggestionsDatabaseEntry
Format
The entry in the suggestions database.
interface SuggestionsDatabaseEntry {
/**
* The suggestion entry id.
*/
id: SuggestionId;
/**
* The suggestion entry.
*/
suggestion: SuggestionEntry;
}
FieldAction
The modifying action on a record field.
Format
type FieldAction = Remove | Set;
FieldUpdate
An object representing a modification of a field in a record.
Format
interface FieldUpdate<T> {
/**
* The modifying action.
*/
tag: FieldAction;
/**
* The updated value.
*/
value?: T;
}
SuggestionArgumentUpdate
An operation applied to the suggestion argument.
Format
type SuggestionArgumentUpdate = Add | Remove | Modify;
interface Add {
/**
* The position of the argument.
*/
index: int;
/**
* The argument to add.
*/
argument: SuggestionEntryArgument;
}
interface Remove {
/**
* The position of the argument.
*/
index: int;
}
interface Modify {
/**
* The position of the argument.
*/
index: int;
/**
* The name to update.
*/
name?: FieldUpdate<String>;
/**
* The argument type to update.
*/
reprType?: FieldUpdate<String>;
/**
* The isSuspended flag to update.
*/
isSuspended?: FieldUpdate<Boolean>;
/**
* The hasDefault flag to update.
*/
hasDefault?: FieldUpdate<Boolean>;
/**
* The default value to update.
*/
defaultValue?: FieldUpdate<String>;
}
SuggestionsDatabaseUpdate
The update of the suggestions database.
Format
/**
* The kind of the suggestions database update.
*/
type SuggestionsDatabaseUpdate = Add | Remove | Modify;
interface Add {
/**
* Suggestion entry id.
*/
id: SuggestionId;
/**
* Suggestion entry.
*/
suggestion: SuggestionEntry;
}
interface Remove {
/**
* Suggestion entry id.
*/
id: SuggestionId;
}
interface Modify {
/**
* Suggestion entry id.
*/
id: SuggestionId;
/**
* The external id to update.
*/
externalId?: FieldUpdate<UUID>;
/**
* The list of argument updates.
*/
arguments?: SuggestionArgumentUpdate[];
/**
* The module name to update.
*/
module?: FieldUpdate<String>;
/**
* The self type to update.
*/
selfType?: FieldUpdate<String>;
/**
* The return type to update.
*/
returnType?: FieldUpdate<String>;
/**
* The documentation string to update.
*/
documentation?: FieldUpdate<String>;
/**
* The scope to update.
*/
scope?: FieldUpdate<SuggestionEntryScope>;
}
Export
The info about module re-export.
Format
type Export = Qualified | Unqualified;
interface Qualified {
/**
* The module that re-exports the given module.
*/
module: String;
/**
* The new name of the given module if it was renamed in the export clause.
*
* I.e. `X` in `export A.B as X`.
*/
alias?: String;
}
interface Unqualified {
/**
* The module name that re-exports the given module.
*/
module: String;
}
File
A representation of a file on disk.
Format
interface File {
name: String; // Includes the file extension
type: String;
}
DirectoryTree
A directory tree is a recursive type used to represent tree structures of files
and directories. It contains files and symlinks in the files
section and
directories in the directories
section. When the tree was requested with the
parameter limiting the maximum depth, the bottom of the DirectoryTree
will
contain Directory
node in the files
section indicating that there is a
directory, but the contents are unknown because we've reached the maximum depth.
Format
interface DirectoryTree {
path: Path;
name: String;
files: [FileSystemObject];
directories: [DirectoryTree];
}
FileAttributes
A description of the attributes of a file required by the IDE. These attributes may be expanded in future.
Format
/**
* A representation of the attributes of a file.
*
* @param creationTime creation time
* @param lastAccessTime last access time
* @param lastModifiedTime last modified time
* @param kind type of [[FileSystemObject]], can be: `Directory`, `File`, `Other`
* @param byteSize size in bytes
*/
interface FileAttributes {
creationTime: UTCDateTime;
lastAccessTime: UTCDateTime;
lastModifiedTime: UTCDateTime;
kind: FileSystemObject;
byteSize: number;
}
UTCDateTime
Time in UTC time zone represented as ISO-8601 string
Format
type UTCDateTime = String;
FileEventKind
The kind of event being described for a watched file.
Format
type FileEventKind = Added | Removed | Modified;
Position
A representation of a position in a text file.
Format
interface Position {
/**
* Line position in a document (zero-based).
*/
line: number;
/**
* Character offset on a line in a document (zero-based). Assuming that the
* line is represented as a string, the `character` value represents the gap
* between the `character` and `character + 1`.
*
* If the character value is greater than the line length it defaults back to
* the line length.
*/
character: number;
}
namespace org.enso.languageserver.protocol.binary;
struct Position {
// Line position in a document (zero-based)
line: uint64;
// Character offset on a line in a document (zero-based)
character: uint64;
}
Range
A representation of a range of text in a text file.
Format
interface Range {
/**
* The range's start position.
*/
start: Position;
/**
* The range's end position.
*/
end: Position;
}
TextEdit
A representation of a change to a text file at a given position.
Format
interface TextEdit {
range: Range;
text: String;
}
DiagnosticType
The type of diagnostic message.
Format
type DiagnosticType = Error | Warning;
StackTraceElement
The frame of the stack trace. If the error refer to a builtin node, the path
and location
fields will be empty.
Format
interface StackTraceElement {
/**
* The function name containing the stack trace element.
*/
functionName: String;
/**
* The location of the file.
*/
path?: Path;
/**
* The location of the element in a file.
*/
location?: Range;
}
Diagnostic
A diagnostic object is produced as a result of an execution attempt, like
pushing the method pointer to a call stack, or editing the file. It can
represent a compiler warning, a compilation error, or a runtime error. The
message has optional path
, location
and stack
fields containing
information about the location in the source code.
In case of the runtime errors, the path
and location
fields may be empty if
the error happens in a builtin node. Then, to locate the error in the code, you
can use the stack
field with a stack trace to find the first element with
non-empty location (as the head of the stack will point to the builtin element).
Format
interface Diagnostic {
/**
* The type of diagnostic message.
*/
kind: DiagnosticType;
/**
* The diagnostic message.
*/
message: String;
/**
* The location of a file containing the diagnostic.
*/
path?: Path;
/**
* The location of the diagnostic object in a file.
*/
location?: Range;
/**
* The id of related expression.
*/
expressionId?: ExpressionId;
/**
* The stack trace.
*/
stack: StackTraceElement[];
}
SHA3-224
The SHA3-224
message digest encoded as a base16 string. For the equivalent
structure on the binary connection please see EnsoDigest
Format
type SHA3-224 = String;
FileEdit
A representation of a batch of edits to a file, versioned.
SHA3-224
represents hash of the file contents. oldVersion
is the version
you're applying your update on, newVersion
is what you compute as the hash
after applying the changes. In other words,
hash(origFile) == oldVersion
hash(applyEdits(origFile, edits)) == newVersion
it's a sanity check to make sure that the diffs are applied consistently.
Consecutive text edits are applied sequentially, every one acting on the result of applying previous ones on the original buffer contents. In pseudocode:
applyEdits buffer [] = buffer
applyEdits buffer (first : rest) = applyEdits (applyTextEdit buffer first) rest
Format
interface FileEdit {
path: Path;
edits: [TextEdit];
oldVersion: SHA3-224;
newVersion: SHA3-224;
}
FileContents
A representation of the contents of a file.
Format
interface FileContents[T] {
contents: T;
}
class TextFileContents extends FileContents[String];
FileSystemObject
A representation of what kind of type a filesystem object can be.
Format
type FileSystemObject = Directory | SymlinkLoop | File | Other;
/**
* Represents a directory.
*
* @param name a name of the directory
* @param path a path to the directory
*/
interface Directory {
name: String;
path: Path;
}
/**
* Represents a symbolic link that creates a loop.
*
* @param name a name of the symlink
* @param path a path to the symlink
* @param target a target of the symlink. Since it is a loop,
* target is a subpath of the symlink
*/
interface SymlinkLoop {
name: String;
path: Path;
target: Path;
}
/**
* Represents a file.
*
* @param name a name of the file
* @param path a path to the file
*/
interface File {
name: String;
path: Path;
}
/**
* Represents unrecognized object.
* Example is a broken symbolic link.
*/
interface Other {
name: String;
path: Path;
}
WorkspaceEdit
This is a message to be specified once we better understand the intricacies of undo/redo.
The actionables for this section are:
- Work out the design of this message.
- Specify this message.
EnsoDigest
A counterpart to SHA3-224 for the binary connection, this is a standard message digest encoded using FlatBuffers.
namespace org.enso.languageserver.protocol.binary;
table EnsoDigest {
bytes : [ubyte];
}
Notes:
- It is an error for the length of the vector
bytes
to not be equal to 28 (224 / 8). This is the length of the chosen digest in bytes.
FileSegment
A representation of a segment of a file for use in the binary protocol.
namespace org.enso.languageserver.protocol.binary;
table FileSegment {
// The file to access.
path : Path (required);
// The byte offset in the file to read from.
byteOffset : ulong (required);
// The number of bytes to read.
length : ulong (required);
}
The byteOffset
property is zero-indexed, so the last byte in the file is at
index file.length - 1
.
Connection Management
In order to properly set-up and tear-down the language server connection, we need a set of messages to control this process.
session/initProtocolConnection
This message initialises the connection used to send the textual protocol messages. This initialisation is important such that the client identifier can be correlated between the textual and data connections.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
clientId: UUID;
}
Result
{
contentRoots: [UUID];
}
Errors
SessionAlreadyInitialisedError
to signal that session is already initialised.ResourcesInitializationError
to signal about the error during the initialization of Language Server resources.
session/initBinaryConnection
This message initialises the data connection used for transferring binary data between engine and clients. This initialisation is important such that the client identifier can be correlated between the data and textual connections.
- Type: Request
- Direction: Client -> Server
- Connection: Data
- Visibility: Public
Parameters
namespace org.enso.languageserver.protocol.binary;
//A command initializing a data session.
table InitSessionCommand {
//A unique identifier of a client initializing the session.
identifier: EnsoUUID (required);
}
root_type InitSessionCommand;
Result
namespace org.enso.languageserver.protocol.binary;
//Indicates an operation has succeeded.
table Success {}
Errors
N/A
Capability Management
In order to mediate between multiple clients properly, the language server has a robust notion of capability management to grant and remove permissions from clients.
capability/acquire
This requests that the server grant the specified capability to the requesting client.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
method: String;
registerOptions?: any;
}
The registerOptions
are determined by the method
. The method must be listed
in the section on capabilities below.
Result
null;
Errors
TBC
capability/release
This requests that the server acknowledge that the client is releasing a given capability.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
registration: CapabilityRegistration;
}
Result
null;
Errors
TBC
capability/granted
This notifies the client that it has been granted a capability without any action on its part.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
{
registration: CapabilityRegistration;
}
Errors
TBC
capability/forceReleased
This notifies the client that a capability has been forcibly removed from its capability set.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
{
registration: CapabilityRegistration;
}
Errors
TBC
Capabilities
The capability management features work with the following capabilities.
text/canEdit
This capability states that the capability has the ability to perform both
text/applyEdit
and text/save
for the specified file.
- method:
text/canEdit
- registerOptions:
{path: Path;}
Enables
Disables
None
file/receivesTreeUpdates
This capability states that the client will receive updates for any watched content roots in the current project.
- method:
file/receivesTreeUpdates
- registerOptions:
{ path: Path; }
Enables
Disables
None
Errors
FileSystemError
to signal a generic, unrecoverable file-system error.FileNotFound
informs that path cannot be found.
CapabilityNotAcquired
informs that requested capability is not acquired.
executionContext/canModify
This capability states that the client has the ability to modify an execution context, including modifying the execution stack, invalidating caches, or destroying the context.
- method:
executionContext/canModify
- registerOptions:
{ contextId: ContextId; }
Enables
executionContext/destroy
executionContext/recompute
executionContext/push
executionContext/pop
executionContext/executeExpression
executionContext/attachVisualisation
executionContext/modifyVisualisation
executionContext/detachVisualisation
executionContext/visualisationUpdate
executionContext/visualisationEvaluationFailed
Disables
None
executionContext/receivesUpdates
This capability states that the client receives expression value updates from a given execution context.
- method:
executionContext/receivesUpdates
- registerOptions:
{ contextId: ContextId; }
Enables
executionContext/expressionUpdates
executionContext/executionFailed
executionContext/executionStatus
Disables
None
search/receivesSuggestionsDatabaseUpdates
This capability states that the client receives the search database updates for a given execution context.
- method:
search/receivesSuggestionsDatabaseUpdates
- registerOptions:
{}
Enables
Disables
None
File Management Operations
The language server also provides file operations to the IDE.
file/write
This requests that the file manager component write to a specified file with the specified contents.
- Type: Request
- Direction: Client -> Server
This request is explicitly allowed to write to files that do not exist, and will create them under such circumstances. If a file is recorded as 'open' by one of the clients, and another client attempts to write to that file, the write must fail.
Parameters
{
path: Path;
contents: FileContents[T];
}
Result
null;
Errors
FileSystemError
to signal a generic, unrecoverable file-system error.ContentRootNotFoundError
to signal that the requested content root cannot be found.AccessDeniedError
to signal that a user doesn't have access to a resource.
file/read
This requests that the file manager component reads the contents of a specified file.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
If the file is recorded as open by the language server, then the result will return the contents from the in-memory buffer rather than the file on disk.
Parameters
{
path: Path;
}
Result
{
contents: FileContents[T];
}
Errors
FileSystemError
to signal a generic, unrecoverable file-system error.ContentRootNotFoundError
to signal that the requested content root cannot be found.AccessDeniedError
to signal that a user doesn't have access to a resource.FileNotFound
informs that file cannot be found.
file/writeBinary
This requests that the file manager component write to a specified file with the binary contents.
- Type: Request
- Connection: Binary
- Direction: Client -> Server
This request is explicitly allowed to write to files that do not exist, and will create them under such circumstances. If a file is recorded as 'open' by one of the clients, and another client attempts to write to that file, the write must fail.
Parameters
namespace org.enso.languageserver.protocol.binary;
//A command writing binary contents to a file.
table WriteFileCommand {
//A path to a file.
path: Path;
//Binary contents.
contents: [ubyte];
}
Result
namespace org.enso.languageserver.protocol.binary;
//Indicates an operation has succeeded.
table Success {}
Errors
FileSystemError
to signal a generic, unrecoverable file-system error.ContentRootNotFoundError
to signal that the requested content root cannot be found.AccessDeniedError
to signal that a user doesn't have access to a resource.
file/readBinary
This requests that the file manager component reads the binary contents of a specified file.
- Type: Request
- Direction: Client -> Server
- Connection: Binary
- Visibility: Public
If the file is recorded as open by the language server, then the result will return the contents from the in-memory buffer rather than the file on disk.
Parameters
namespace org.enso.languageserver.protocol.binary;
//A command reading binary contents from a file.
table ReadFileCommand {
//A path to a file.
path: Path;
}
Result
namespace org.enso.languageserver.protocol.binary;
//A reply for a ReadFileCommand.
table FileContentsReply {
//Binary contents.
contents: [ubyte];
}
Errors
FileSystemError
to signal a generic, unrecoverable file-system error.ContentRootNotFoundError
to signal that the requested content root cannot be found.AccessDeniedError
to signal that a user doesn't have access to a resource.FileNotFound
informs that file cannot be found.
file/writeBytes
This requests that the file manager component writes a set of bytes to the specified file at the specified offset.
- Type: Request
- Direction: Client -> Server
- Connection: Binary
- Visibility: Public
This method will create a file if no file is present at path
.
- The
overwriteExisting
boolean should be set ifbyteOffset
is less than the length of the file. - The
byteOffset
property is zero-indexed. To append to the file you begin writing at indexfile.length
. - If
byteOffset > file.length
, the bytes in the range[file.length, byteOffset)
will be filled with null bytes.
Parameters
namespace org.enso.languageserver.protocol.binary;
table WriteBytesRequest {
// The file to write to.
path : Path (required);
// The byte offset in the file to write from.
byteOffset : ulong (required);
// Whether existing content should be overwritten.
overwriteExisting : bool (required);
// The file contents.
bytes : [ubyte] (required);
}
Result
namespace org.enso.languageserver.protocol.binary;
table WriteBytesResponse {
// The checksum of the written bytes.
checksum : EnsoDigest (required);
}
Notes:
- The
checksum
is only of thebytes
in the request as they were written to disk. This does not include checksumming the entire file. For that, please seefile/checksumBytes
.
Errors
CannotOverwrite
to signal that an overwrite would be necessary to perform the operation but thatoverwriteExisting
is not set.NotFile
if the providedsegment.path
is not a file.
file/readBytes
Asks the language server to read the specified number of bytes at the specified offset in the file.
- Type: Request
- Direction: Client -> Server
- Connection: Binary
- Visibility: Public
It will attempt to read as many as segment.length
bytes, but does not
guarantee that the response will contain segment.length
bytes (e.g. if
segment.length
would require reading off the end of the file).
Parameters
namespace org.enso.languageserver.protocol.binary;
table ReadBytesRequest {
// The segment in a file to read bytes from.
segment : FileSegment (required);
}
Result
namespace org.enso.languageserver.protocol.binary;
table ReadBytesResponse {
// The checksum of the bytes in this response.
checksum : EnsoDigest (required);
// The requested file contents.
bytes : [ubyte] (required);
}
Notes:
- The
checksum
is of thebytes
as they have been read from disk.
Errors
FileNotFound
if the file atsegment.path
does not exist.ReadOutOfBounds
ifsegment.byteOffset
is not present in the file atsegment.path
.NotFile
if the providedsegment.path
is not a file.
file/create
This request asks the file manager to create the specified file system object.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
This will fail if the specified object already exists.
Parameters
{
object: FileSystemObject;
}
Response
null;
Errors
FileSystemError
to signal a generic, unrecoverable file-system error.ContentRootNotFoundError
to signal that the requested content root cannot be found.AccessDeniedError
to signal that a user doesn't have access to a resource.
file/delete
This request asks the file manager to delete the specified file system object.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
path: Path;
}
Result
null
Errors
FileSystemError
to signal a generic, unrecoverable file-system error.ContentRootNotFoundError
to signal that the requested content root cannot be found.FileNotFound
informs that file cannot be found.FileExists
informs that file already exists
file/copy
This request asks the file manager to copy a specified filesystem object to another location.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
from: Path;
to: Path;
}
Result
null;
Errors
FileSystemError
to signal a generic, unrecoverable file-system error.ContentRootNotFoundError
to signal that the requested content root cannot be found.FileNotFound
informs that file cannot be found.
file/move
This request asks the file manager to move a specified filesystem object to another location.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
The move should be specified by filesystem events, and such notifications should inform the client that the currently edited file has been moved.
Parameters
{
from: Path;
to: Path;
}
Result
null;
Errors
FileSystemError
to signal a generic, unrecoverable file-system error.ContentRootNotFoundError
to signal that the requested content root cannot be found.FileNotFound
informs that file cannot be found.FileExists
informs that target file already exists.
file/exists
This request asks the file manager to check whether a filesystem object exists at the specified path.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
path: Path;
}
Result
{
exists: Boolean;
}
Errors
ContentRootNotFoundError
to signal that the requested content root cannot be found.
file/tree
This request asks the file manager component to generate and provide the directory tree starting at a given path.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
path: Path;
depth?: Number;
}
Result
{
tree: DirectoryTree;
}
Errors
ContentRootNotFoundError
to signal that the requested content root cannot be found.FileNotFound
informs that requested path does not exist or provided depth argument is <= 0.NotDirectory
informs that requested path is not a directory.
file/list
This request lists the contents of a given filesystem object. For a file it will just return the file, while for a directory it will list the contents of the directory.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
path: Path;
}
Result
{
paths: [FileSystemObject];
}
Errors
ContentRootNotFoundError
to signal that the requested content root cannot be found.FileNotFound
informs that requested path does not exist.NotDirectory
informs that requested path is not a directory.
file/info
This request gets information about a specified filesystem object.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
This request should work for all kinds of filesystem object.
Parameters
{
path: Path;
}
Result
{
attributes: FileAttributes;
}
Errors
ContentRootNotFoundError
to signal that the requested content root cannot be found.FileNotFound
informs that requested path does not exist.
file/checksum
Requests that the language server provide the checksum of the provided file.
Only defined when the provided path
is a file.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
It calculates the checksum of the entire file.
Parameters
interface ChecksumRequest {
// The path to the file to get the checksum for.
path: Path;
}
Result
interface ChecksumResponse {
// The checksum of the file at `path`.
checksum : SHA3-224;
}
Errors
FileNotFound
if the file atpath
does not exist.NotFile
if the providedpath
does not point to a file.
file/checksumBytes
Requests that the language server provides the checksum of the provided byte range.
- Type: Request
- Direction: Client -> Server
- Connection: Binary
- Visibility: Public
Parameters
namespace org.enso.languageserver.protocol.binary;
table ChecksumBytesRequest {
// The segment in a file to checksum.
segment : FileSegment (required);
}
Result
namespace org.enso.languageserver.protocol.binary;
table ChecksumBytesRequest {
// The segment in a file to checksum.
checksum : EnsoDigest;
}
Errors
FileNotFound
if the file atsegment.path
does not exist.ReadOutOfBounds
ifsegment.byteOffset
is not present in the file atsegment.path
, or ifsegment.length
does not fit within the file.NotFile
if the providedsegment.path
is not a file.
file/event
This is a notification that is sent every time something under a watched content root changes. It is used to ensure that the client's filesystem representation stays in synchronisation with reality.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Events should be sent from server to client for every event observed under one of the (possibly multiple) content roots.
Parameters
{
path: Path;
kind: FileEventKind;
}
Errors
None
file/addRoot
This request adds a content root to the active project.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
When a content root is added, the language server must notify clients other than
the one that added the root by sending a file/rootAdded
. Additionally, all
clients must be notified with a file/event
about the addition of the new root.
The IDE is responsible for calling file/tree
on that root to discover its
structure.
Parameters
{
absolutePath: [String];
id: UUID; // The ID of the content root
}
Result
null;
Errors
TBC
file/removeRoot
This request removes a content root from the active project.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
When a content root is removed, the language server must notify clients other
than the one that added the root by sending a file/rootRemoved
. Additionally,
the server must send a file/event
making the root of the new tree visible. The
IDE is responsible for any additional discovery.
Parameters
{
id: UUID; // The content root ID
}
Result
null;
Errors
TBC
file/rootAdded
This is a notification sent to all clients other than the one performing the addition of the root in order to inform them of the content root's ID.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
{
id: UUID; // The content root ID
absolutePath: [String];
}
Errors
TBC
file/rootRemoved
This is a notification sent to all clients other than the one performing the removal of the content root in order to inform them of the removal of the root.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
{
id: UUID; // The content root ID
}
Errors
TBC
Text Editing Operations
The language server also has a set of text editing operations to ensure that it stays in sync with the clients.
text/openFile
This requests the language server to open the specified file.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
If no client has write lock on the opened file, the capability is granted to the
client that sent the text/openFile
message.
Parameters
{
path: Path;
}
Result
{
writeCapability?: CapabilityRegistration;
content: String;
currentVersion: SHA3-224;
}
Errors
FileSystemError
to signal a generic, unrecoverable file-system error.ContentRootNotFoundError
to signal that the requested content root cannot be found.AccessDeniedError
to signal that a user doesn't have access to a resource.FileNotFound
informs that file cannot be found.
text/closeFile
This requests the language server to close the specified file.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
path: Path;
}
Result
null;
Errors
FileNotOpenedError
to signal that a file wasn't opened.
text/save
This requests for the language server to save the specified file.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
The request may fail if the requesting client does not have permission to edit that file, or if the client is requesting a save of an outdated version.
Parameters
{
path: Path;
currentVersion: SHA3 - 224;
}
Result
null;
Errors
FileNotOpenedError
to signal that the file isn't open.InvalidVersionError
to signal that the version provided by the client doesn't match the version computed by the server.WriteDeniedError
to signal that the client doesn't hold write lock for the buffer.FileSystemError
to signal a generic, unrecoverable file-system error.ContentRootNotFoundError
to signal that the requested content root cannot be found.AccessDeniedError
to signal that the user doesn't have access to a resource.
text/applyEdit
This requests that the server apply a series of edits to the project. These edits solely concern text files.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
This operation may fail if the requesting client does not have permission to edit the resources for which edits are sent. This failure may be partial, in that some edits are applied and others are not.
Parameters
{
edit: FileEdit;
}
Result
null;
Errors
FileNotOpenedError
to signal that the file isn't open.TextEditValidationError
to signal that validation has failed for a series of edits.InvalidVersionError
to signal that the version provided by the client doesn't match the version computed by the server.WriteDeniedError
to signal that the client doesn't hold write lock for the buffer.
text/didChange
This is a notification sent from the server to the clients to inform them of any changes made to files that they have open.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
This notification must only be sent for files that the client has open.
Parameters
{
edits: [FileEdit];
}
Errors
null;
Workspace Operations
The language server also has a set of operations useful for managing the client workspace.
workspace/undo
This request is sent from the client to the server to request that an operation be undone.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
The exact behaviour of this message is to be determined, but it must involve the server undoing that same action for all clients in the workspace.
Parameters
{
requestID?: UUID; // If not specified, it undoes the latest request
}
Result
null;
Errors
TBC
workspace/redo
This request is sent from the client to the server to request that an operation be redone.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
The exact behaviour of this message is to be determined, but it must involve the server redoing that same action for all clients in the workspace.
Parameters
{
requestID?: UUID; // If not specified, it redoes the latest request
}
Result
null;
Errors
TBC
Monitoring
The language server also has a heartbeat operation to monitor the Language server. This API is private and should be used only by the Project Manager.
heartbeat/ping
This request is sent from the supervisor process to the server to check the health of the Language Server.
- Type: Request
- Direction: Supervisor -> Server
- Connection: Protocol
- Visibility: Private
Parameters
null;
Result
null;
Errors
None
heartbeat/init
This request is sent from the bootloader to check if the started language server instance has finished initialization. A reply should only be sent when the main module has been fully initialized.
- Type: Request
- Direction: Supervisor -> Server
- Connection: Protocol
- Visibility: Private
Parameters
null;
Result
null;
Errors
None
Refactoring
The language server also provides refactoring operations to restructure an internal body of code.
refactoring/renameProject
This request is sent from the project manager to the server to refactor project name in an interpreter runtime.
- Type: Request
- Direction: Project Manager -> Server
- Connection: Protocol
- Visibility: Private
Parameters
{
oldName: String;
newName: String;
}
Result
null;
Errors
None
Execution Management Operations
The execution management portion of the language server API deals with exposing fine-grained control over program and expression execution to the clients of the language server. This is incredibly important for enabling the high levels of interactivity required by Enso Studio.
Execution Management Example
Given the default project structure.
├── package.yaml
└── src
└── Main.enso
$ cat src/Main.enso
main =
x = 6
y = x.foo 5
z = y + 5
z
Number.foo = x ->
y = this + 3
z = y * x
z
#### METADATA ####
[[{"index": {"value": 98}, "size": {"value": 5}}, "5fc0c11d-bd83-4ca3-b847-b8e362f7658c"],[{"index": {"value": 81}, "size": {"value": 8}}, "1cda3676-bd62-41f8-b6a1-a1e1b7c73d18"],[{"index": {"value": 42}, "size": {"value": 5}}, "899a11e5-4d2b-43dc-a867-2f2ef2d2ba62"],[{"index": {"value": 26}, "size": {"value": 7}}, "37f284d4-c593-4e65-a4be-4948fbd2adfb"],[{"index": {"value": 16}, "size": {"value": 1}}, "c553533e-a2b9-4305-9f12-b8fe7781f933"]]
[]
Notice extra newline in the beginning of the Main.enso
file, it is important
for the precalculated metadata indexes.
Create Execution Context
{
"jsonrpc": "2.0",
"method": "executionContext/create",
"id": 0,
"params": null
}
Return capabilities together with a newly created ContextId
.
{
"jsonrpc": "2.0",
"id": 0,
"result": {
"contextId": "1eb5ad04-4094-4c1f-be54-e9d29ddf19a3",
"canModify": {
"method": "executionContext/canModify",
"registerOptions": {
"contextId": "1eb5ad04-4094-4c1f-be54-e9d29ddf19a3"
}
},
"receivesUpdates": {
"method": "executionContext/receivesUpdates",
"registerOptions": {
"contextId": "1eb5ad04-4094-4c1f-be54-e9d29ddf19a3"
}
}
}
}
Push Item
Entering the main
method. First item on the stack should always be an
ExplicitCall
.
{
"jsonrpc": "2.0",
"method": "executionContext/push",
"id": 0,
"params": {
"contextId": "1eb5ad04-4094-4c1f-be54-e9d29ddf19a3",
"stackItem": {
"type": "ExplicitCall",
"methodPointer": {
"file": {
"rootId": "18f642a2-5f69-4fc8-add6-13bf199ca326",
"segments": ["src", "Main.enso"]
},
"definedOnType": "Main",
"name": "main"
},
"thisArgumentExpression": null,
"positionalArgumentsExpressions": []
}
}
}
Returns successful reponse.
{
"jsonrpc": "2.0",
"id": 0,
"result": null
}
And a value update, result of the method foo
call defined on type Number
.
{
"jsonrpc": "2.0",
"method": "executionContext/expressionValuesComputed",
"params": {
"contextId": "1eb5ad04-4094-4c1f-be54-e9d29ddf19a3",
"updates": [
{
"id": "37f284d4-c593-4e65-a4be-4948fbd2adfb",
"type": "Number",
"shortValue": "45",
"methodCall": {
"file": {
"rootId": "18f642a2-5f69-4fc8-add6-13bf199ca326",
"segments": ["src", "Main.enso"]
},
"definedOnType": "Number",
"name": "foo"
}
}
]
}
}
We can go deeper and evaluate the method foo
call by pushing the LocalCall
on the stack. In general, all consequent stack items should be LocalCall
s.
{
"jsonrpc": "2.0",
"method": "executionContext/push",
"id": 0,
"params": {
"contextId": "1eb5ad04-4094-4c1f-be54-e9d29ddf19a3",
"stackItem": {
"type": "LocalCall",
"expressionId": "37f284d4-c593-4e65-a4be-4948fbd2adfb"
}
}
}
Returns successful reponse.
{
"jsonrpc": "2.0",
"id": 0,
"result": null
}
And update of some value inside the function foo
.
{
"jsonrpc": "2.0",
"method": "executionContext/expressionValuesComputed",
"params": {
"contextId": "1eb5ad04-4094-4c1f-be54-e9d29ddf19a3",
"updates": [
{
"id": "1cda3676-bd62-41f8-b6a1-a1e1b7c73d18",
"type": "Number",
"shortValue": "9",
"methodCall": null
}
]
}
}
Pop Item
{
"jsonrpc": "2.0",
"method": "executionContext/pop",
"id": 0,
"params": {
"contextId": "1eb5ad04-4094-4c1f-be54-e9d29ddf19a3"
}
}
Popping one item will return us into the main
method. Second call will clear
the stack. Subsequent pop calls will result in an error indicating that the
stack is empty.
executionContext/create
Sent from the client to the server to create a new execution context. Return
capabilities executionContext/canModify
and
executionContext/receivesUpdates
.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
null;
Result
{
contextId: ContextId;
canModify: CapabilityRegistration;
receivesUpdates: CapabilityRegistration;
}
Errors
None
executionContext/destroy
Sent from the client to the server destroy an execution context and free its resources.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
contextId: ContextId;
}
Result
null;
Errors
AccessDeniedError
when the user does not hold theexecutionContext/canModify
capability for this context.ContextNotFoundError
when context can not be found by provided id.
executionContext/fork
Sent from the client to the server to duplicate an execution context, creating
an independent copy, containing all the data precomputed in the first one.
Return capabilities executionContext/canModify
and executionContext/receivesUpdates
.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
contextId: ContextId;
}
Result
{
contextId: ContextId;
canModify: CapabilityRegistration;
receivesUpdates: CapabilityRegistration;
}
Errors
No known errors.
executionContext/push
Sent from the client to the server execute item and move the execution context to a new location deeper down the stack. If a stack item becomes invalid because of a text edit (e.g. the root function of the view was removed), it will stop executing. If the function reappears, execution should resume as normal.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
contextId: ContextId;
stackItem: StackItem;
}
Result
null;
Errors
AccessDeniedError
when the user does not hold theexecutionContext/canModify
capability for this context.StackItemNotFoundError
when the request stack item could not be found.InvalidStackItemError
when pushingLocalCall
on top of the empty stack, or pushingExplicitCall
on top of non-empty stack.
executionContext/pop
Sent from the client to the server move the execution context up the stack, corresponding to the client clicking out of the current breadcrumb.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
contextId: ContextId;
}
Result
null;
Errors
AccessDeniedError
when the user does not hold theexecutionContext/canModify
capability for this context.EmptyStackError
when the user tries to pop an empty stack.
executionContext/recompute
Sent from the client to the server to force recomputation of current position. May include a list of expressions for which caches should be invalidated.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
contextId: ContextId;
invalidatedExpressions?: "all" | [ExpressionId]
}
Result
null;
Errors
AccessDeniedError
when the user does not hold theexecutionContext/canModify
capability for this context.EmptyStackError
when the user tries to recompute an empty stack.
executionContext/expressionUpdates
Sent from the server to the client to inform about new information for certain
expressions becoming available. Supersedes the
executionContext/expressionValuesComputed
notification, that will be removed
in future versions.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
{
contextId: ContextId;
updates: [ExpressionUpdate];
}
Errors
None
executionContext/executionFailed
Sent from the server to the client to inform about a critical failure when attempting to execute a context.
When the executionContext/executionStatus
notifies about potential problems in the code found by compiler, or the errors
during runtime, this message signals about the errors in the logic or the
implementation. It can be a compiler crash, an attempt to execute an empty
stack, an error location a method or a module when issuing a
executionContext/push
command.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
{
/**
* The identifier of the execution context.
*/
contextId: ContextId;
/**
* The error message.
*/
message: String;
/**
* The location of a file producing the error.
*/
path?: Path;
}
Errors
None
executionContext/executionStatus
Sent from the server to the client to inform about a status of execution.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
{
/**
* The identifier of the execution context.
*/
contextId: ContextId;
/**
* The list of encountered problems.
*/
diagnostics: Diagnostic[];
}
Errors
None
executionContext/executeExpression
This message allows the client to execute an arbitrary expression on a given
node. It behaves like oneshot
executionContext/attachVisualisation
visualisation request, meaning that the visualisation expression will be
executed only once.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
interface ExecuteExpressionRequest {
visualisationId: UUID;
expressionId: UUID;
visualisationConfig: VisualisationConfiguration;
}
Result
null;
Errors
AccessDeniedError
when the user does not hold theexecutionContext/canModify
capability for this context.ContextNotFoundError
when context can not be found by provided id.ModuleNotFoundError
to signal that the module with the visualisation cannot be found.VisualisationExpressionError
to signal that the expression specified in theVisualisationConfiguration
cannot be evaluated.
executionContext/attachVisualisation
This message allows the client to attach a visualisation, potentially preprocessed by some arbitrary Enso code, to a given node in the program.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
interface AttachVisualisationRequest {
visualisationId: UUID;
expressionId: UUID;
visualisationConfig: VisualisationConfiguration;
}
Result
null;
Errors
AccessDeniedError
when the user does not hold theexecutionContext/canModify
capability for this context.ContextNotFoundError
when context can not be found by provided id.ModuleNotFoundError
to signal that the module with the visualisation cannot be found.VisualisationExpressionError
to signal that the expression specified in theVisualisationConfiguration
cannot be evaluated.
executionContext/detachVisualisation
This message allows a client to detach a visualisation from the executing code.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
interface DetachVisualisationRequest {
executionContextId: UUID;
visualisationId: UUID;
expressionId: UUID;
}
Result
null;
Errors
AccessDeniedError
when the user does not hold theexecutionContext/canModify
capability for this context.ContextNotFoundError
when context can not be found by provided id.VisualisationNotFoundError
when a visualisation can not be found.
executionContext/modifyVisualisation
This message allows a client to modify the configuration for an existing visualisation.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
interface ModifyVisualisationRequest {
visualisationId: UUID;
visualisationConfig: VisualisationConfiguration;
}
Result
null;
Errors
AccessDeniedError
when the user does not hold theexecutionContext/canModify
capability for this context.ContextNotFoundError
when context can not be found by provided id.ModuleNotFoundError
to signal that the module with the visualisation cannot be found.VisualisationExpressionError
to signal that the expression specified in theVisualisationConfiguration
cannot be evaluated.VisualisationNotFoundError
when a visualisation can not be found.
executionContext/visualisationUpdate
This message is responsible for providing a visualisation data update to the client.
- Type: Notification
- Direction: Server -> Client
- Connection: Data
- Visibility: Public
The visualisationData
component of the table definition must be
pre-serialized before being inserted into this message. As far as this level of
transport is concerned, it is just a binary blob.
Parameters
namespace org.enso.languageserver.protocol.binary;
//A visualisation context identifying a concrete visualisation.
table VisualisationContext {
//A visualisation identifier.
visualisationId: EnsoUUID (required);
//A context identifier.
contextId: EnsoUUID (required);
//An expression identifier.
expressionId: EnsoUUID (required);
}
//An event signaling visualisation update.
table VisualisationUpdate {
//A visualisation context identifying a concrete visualisation.
visualisationContext: VisualisationContext (required);
//A visualisation data.
data: [ubyte] (required);
}
root_type VisualisationUpdate;
Errors
N/A
executionContext/visualisationEvaluationFailed
Signals that an evaluation of a visualisation expression on the computed value has failed.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
interface VisualisationEvaluationFailed {
/**
* An execution context identifier.
*/
contextId: ContextId;
/**
* A visualisation identifier.
*/
visualisationId: UUID;
/**
* An identifier of a visualised expression.
*/
expressionId: UUID;
/**
* An error message.
*/
message: string;
/**
* Detailed information about the error.
*/
diagnostic?: Diagnostic;
}
Errors
N/A
Search Operations
Search operations allow requesting for the autocomplete suggestions and search
for the documentation. Search operations return links to the items in the
Suggestions Database instead of returning full entries. Suggestions Database is
a key-value storage with SuggestionEntry
values.
Suggestions Database Example
The following code snippet shows examples of the database entries.
type MyType a b
type Maybe
Nothing
Just a
is_just = case this of
Just _ -> true
Nothing -> false
foo x =
10 - x
Number.baz x =
this + x * 10
main =
x = foo 42
y = x.baz x
IO.println y
MyType
<SuggestionEntryAtom>{
name: "MyType",
arguments: [],
returnType: "MyType",
};
Maybe.Nothing
<SuggestionEntryAtom>{
name: "Nothing",
arguments: [],
returnType: "Maybe",
};
Maybe.Just
<SuggestionEntryAtom>{
name: "Just",
arguments: [
{
name: "a",
type: "Any",
isSuspended: false,
hasDefault: false,
},
],
returnType: "Maybe",
};
Maybe.is_just
<SuggestionEntryMethod>{
name: "is_just",
arguments: [],
selfType: "Maybe",
returnType: "Bool",
};
foo
<SuggestionEntryFunction>{
name: "foo",
arguments: [
{
name: "x",
type: "Number",
isSuspended: false,
hasDefault: false,
},
],
returnType: "Bool",
};
Number.baz
<SuggestionEntryMethod>{
name: "baz",
arguments: [
{
name: "x",
type: "Number",
isSuspended: false,
hasDefault: false,
},
],
selfType: "Number",
returnType: "Number",
};
Local x
<SuggestionEntryLocal>{
name: "x",
returnType: "Number",
};
Local y
<SuggestionEntryLocal>{
name: "y",
returnType: "Number",
};
search/getSuggestionsDatabase
Sent from client to the server to receive the full suggestions database.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
null;
Result
{
// The list of suggestions database entries
entries: [SuggestionsDatabaseEntry];
// The version of received suggestions database
currentVersion: number;
}
Errors
SuggestionsDatabaseError
an error accessing the suggestions databaseProjectNotFoundError
project is not found in the root directory
search/invalidateSuggestionsDatabase
Sent from client to the server to clean the suggestions database resetting the version.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
null;
Result
null;
Errors
SuggestionsDatabaseError
an error accessing the suggestions database
search/getSuggestionsDatabaseVersion
Sent from client to the server to receive the current version of the suggestions database.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
null;
Result
{
// The version of the suggestions database
currentVersion: number;
}
Errors
SuggestionsDatabaseError
an error accessing the suggestions databaseProjectNotFoundError
project is not found in the root directory
search/suggestionsDatabaseUpdate
Sent from server to the client to inform abouth the change in the suggestions database.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
{
updates: [SuggestionsDatabaseUpdate];
currentVersion: number;
}
Errors
None
search/completion
Sent from client to the server to receive the autocomplete suggestion.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
// The edited file
file: Path;
// The cursor position
position: Position;
// Filter by methods with the provided self type
selfType?: string;
// Filter by the return type
returnType?: string;
// Filter by the suggestion types
tags?: [SuggestionEntryType];
}
Result
The identifiers in results
are guaranteed to be ordered by the specificity of
the type match.
{
results: [SuggestionId];
currentVersion: number;
}
Errors
SuggestionsDatabaseError
an error accessing the suggestions databaseProjectNotFoundError
project is not found in the root directoryModuleNameNotResolvedError
the module name cannot be extracted from the provided file path parameter
search/import
Sent from client to the server to receive the information required for module import.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
/**
* The id of suggestion to import.
*/
id: SuggestionId;
}
Result
{
/**
* The definition module of the suggestion.
*/
module: String;
/**
* The name of the resolved suggestion.
*/
symbol: String;
/**
* The list of modules that re-export the suggestion. Modules are ordered
* from the least to most nested.
*/
exports: Export[];
}
Errors
SuggestionsDatabaseError
an error accessing the suggestions databaseSuggestionNotFoundError
the requested suggestion was not found in the suggestions database
Input/Output Operations
The input/output portion of the language server API deals with redirecting stdin/stdout/stderr of Enso programs to the clients of the language server. This is incredibly important for enabling the high levels of interactivity required by Enso Studio.
io/redirectStandardOutput
This message allows a client to redirect the standard output of Enso programs.
Once the standard output is redirected, the Language server will notify the
client about new output data by emitting io/standardOutputAppended
messages.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
null;
Result
null;
Errors
N/A
io/suppressStandardOutput
This message allows a client to suppress the redirection of the standard output.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
null;
Result
null;
Errors
N/A
io/standardOutputAppended
Sent from the server to the client to inform that new output data are available for the standard output.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
{
output: String;
}
io/redirectStandardError
This message allows a client to redirect the standard error of Enso programs.
Once the standard error is redirected, the Language server will notify the
client about new output data by emitting io/standardErrorAppended
messages.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
null;
Result
null;
Errors
N/A
io/suppressStandardError
This message allows a client to suppress the redirection of the standard error.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
null;
Result
null;
Errors
N/A
io/standardErrorAppended
Sent from the server to the client to inform that new output data are available for the standard error.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
{
output: String;
}
io/feedStandardInput
This message allows a client to feed the standard input of Enso programs.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
Parameters
{
input: String;
isLineTerminated: Boolean;
}
Result
null;
Errors
N/A
io/waitingForStandardInput
Sent from the server to the client to inform that an Enso program is suspended
by IO.readln
. This message is used to notify a client that she should feed the
standard input.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
Parameters
null;
Errors
The language server component also has its own set of errors. This section is not a complete specification and will be updated as new errors are added.
Besides the required code
and message
fields, the errors may have a data
field which can store additional error-specific payload.
Error
An error container for the binary connection that contains a code, message and payload.
namespace org.enso.languageserver.protocol.binary;
table Error {
// A unique error code identifying error type.
code: int (required);
// An error message.
message: string (required);
// Additional payloads for the error.
data : ErrorPayload (required);
}
union ErrorPayload {
EMPTY: EmptyPayload,
...
}
struct EmptyPayload {}
Note:
- The union
ErrorPayload
will be extended with additional payloads as necessary. - All textual-protocol errors can be represented using this structure.
AccessDeniedError
It signals that a user doesn't have access to a resource.
"error" : {
"code" : 100,
"message" : "Access denied"
}
FileSystemError
This error signals generic file system errors.
"error" : {
"code" : 1000,
"message" : String
}
ContentRootNotFoundError
The error informs that the requested content root cannot be found.
"error" : {
"code" : 1001,
"message" : "Content root not found"
}
FileNotFound
It signals that requested file doesn't exist.
"error" : {
"code" : 1003,
"message" : "File not found"
}
FileExists
It signals that file already exists.
"error" : {
"code" : 1004,
"message" : "File already exists"
}
OperationTimeoutError
It signals that IO operation timed out.
"error" : {
"code" : 1005,
"message" : "IO operation timeout"
}
NotDirectory
It signals that provided path is not a directory.
"error" : {
"code" : 1006,
"message" : "Path is not a directory"
}
NotFile
It signals that the provided path is not a file.
"error" : {
"code" : 1007,
"message" : "Path is not a file"
}
CannotOverwrite
Signals that a streaming file write cannot overwrite a portion of the requested file.
"error" : {
"code" : 1008,
"message" : "Cannot overwrite the file without `overwriteExisting` set"
}
ReadOutOfBounds
Signals that the requested file read was out of bounds for the file's size.
"error" : {
"code" : 1009
"message" : "Read is out of bounds for the file"
"data" : {
fileLength : 0
}
}
namespace org.enso.languageserver.protocol.binary;
table ReadOutOfBoundsError {
// The actual length of the file.
fileLength : ulong (required);
}
StackItemNotFoundError
It signals that provided stack item was not found.
"error" : {
"code" : 2001,
"message" : "Stack item not found"
}
ContextNotFoundError
It signals that provided context was not found.
"error" : {
"code" : 2002,
"message" : "Context not found"
}
EmptyStackError
It signals that stack is empty.
"error" : {
"code" : 2003,
"message" : "Stack is empty"
}
InvalidStackItemError
It signals that stack is invalid in this context.
"error" : {
"code" : 2004,
"message" : "Invalid stack item"
}
ModuleNotFoundError
It signals that the given module cannot be found.
"error" : {
"code" : 2005,
"message" : "Module not found [Foo.Bar.Baz]"
}
VisualisationNotFoundError
It signals that the visualisation cannot be found.
"error" : {
"code" : 2006,
"message" : "Visualisation not found"
}
VisualisationExpressionError
It signals that the expression specified in the VisualisationConfiguration
cannot be evaluated. The error contains an optional data
field of type
Diagnostic
providing error details.
"error" : {
"code" : 2007,
"message" : "Evaluation of the visualisation expression failed [i is not defined]"
"data" : {
"kind" : "Error",
"message" : "i is not defined",
"path" : null,
"location" : {
"start" : {
"line" : 0,
"character" : 8
},
"end" : {
"line" : 0,
"character" : 9
}
},
"expressionId" : "aa1f75c4-8c4d-493d-a6a7-72123a52f084",
"stack" : []
}
}
FileNotOpenedError
Signals that a file wasn't opened.
"error" : {
"code" : 3001,
"message" : "File not opened"
}
TextEditValidationError
Signals that validation has failed for a series of edits.
"error" : {
"code" : 3002,
"message" : "The start position is after the end position"
}
InvalidVersionError
Signals that version provided by a client doesn't match to the version computed by the server.
"error" : {
"code" : 3003,
"message" : "Invalid version [client version: ade2967cab172183d1a67ea40cb8e92e23218764bc9934c3795fcea5, server version: 7602967cab172183d1a67ea40cb8e92e23218764bc9934c3795fcea5]"
}
WriteDeniedError
Signals that the client doesn't hold write lock to the buffer.
"error" : {
"code" : 3004,
"message" : "Write denied"
}
CapabilityNotAcquired
Signals that requested capability is not acquired.
"error" : {
"code" : 5001,
"message" : "Capability not acquired"
}
SessionNotInitialisedError
Signals that requested cannot be proccessed, beacuse session is not initialised.
"error" : {
"code" : 6001,
"message" : "Session not initialised"
}
SessionAlreadyInitialisedError
Signals that session is already initialised.
"error" : {
"code" : 6002,
"message" : "Session already initialised"
}
ResourcesInitializationError
Signals about the failure in the Language Server initialization process.
"error" : {
"code" : 6003,
"message" : "Failed to initialize the Language Server resources"
}
SuggestionsDatabaseError
Signals about an error accessing the suggestions database.
"error" : {
"code" : 7001,
"message" : "Suggestions database error"
}
ProjectNotFoundError
Signals that the project not found in the root directory.
"error" : {
"code" : 7002,
"message" : "Project not found in the root directory"
}
ModuleNameNotResolvedError
Signals that the module name can not be resolved for the given file.
"error" : {
"code" : 7003,
"message" : "Module name can't be resolved for the given file"
}
SuggestionNotFoundError
Signals that the requested suggestion was not found.
"error" : {
"code" : 7004,
"message" : "Requested suggestion was not found"
}