apps/docs/src/content/docs/en/language-server-protocol.mdx
import { TabItem, Tabs } from '@astrojs/starlight/components'
Daytona provides Language Server Protocol (LSP) support through sandbox instances. This enables advanced language features like code completion, diagnostics, and more.
Daytona provides methods to create LSP servers. The path_to_project argument is relative to the current sandbox working directory when no leading / is used. The working directory is specified by WORKDIR when it is present in the Dockerfile, and otherwise falls back to the user's home directory.
from daytona import Daytona, LspLanguageId
# Create Sandbox
daytona = Daytona()
sandbox = daytona.create()
# Create LSP server for Python
lsp_server = sandbox.create_lsp_server(
language_id=LspLanguageId.PYTHON,
path_to_project="workspace/project"
)
import { Daytona, LspLanguageId } from '@daytona/sdk'
// Create sandbox
const daytona = new Daytona()
const sandbox = await daytona.create({
language: 'typescript',
})
// Create LSP server for TypeScript
const lspServer = await sandbox.createLspServer(
LspLanguageId.TYPESCRIPT,
'workspace/project'
)
require 'daytona'
# Create Sandbox
daytona = Daytona::Daytona.new
sandbox = daytona.create
# Create LSP server for Python
lsp_server = sandbox.create_lsp_server(
language_id: Daytona::LspServer::Language::PYTHON,
path_to_project: 'workspace/project'
)
// Create sandbox
client, err := daytona.NewClient()
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
sandbox, err := client.Create(ctx, nil)
if err != nil {
log.Fatal(err)
}
// Get LSP service for Python
lsp := sandbox.Lsp(types.LspLanguagePython, "workspace/project")
import io.daytona.sdk.Daytona;
import io.daytona.sdk.LspServer;
import io.daytona.sdk.Sandbox;
public class App {
public static void main(String[] args) {
try (Daytona daytona = new Daytona()) {
Sandbox sandbox = daytona.create();
LspServer lspServer = sandbox.createLspServer(
LspServer.LspLanguageId.PYTHON.getValue(),
"workspace/project");
}
}
}
The supported languages for creating LSP servers with Daytona are defined by the LspLanguageId enum:
| Enum Value | Description |
|---|---|
LspLanguageId.PYTHON | Python language server |
LspLanguageId.TYPESCRIPT | TypeScript/JavaScript language server |
Daytona provides methods to start LSP servers.
<Tabs syncKey="language"> <TabItem label="Python" icon="seti:python">lsp = sandbox.create_lsp_server("typescript", "workspace/project")
lsp.start() # Initialize the server
# Now ready for LSP operations
const lsp = await sandbox.createLspServer('typescript', 'workspace/project')
await lsp.start() // Initialize the server
// Now ready for LSP operations
lsp = sandbox.create_lsp_server(
language_id: Daytona::LspServer::Language::PYTHON,
path_to_project: 'workspace/project'
)
lsp.start # Initialize the server
# Now ready for LSP operations
lsp := sandbox.Lsp(types.LspLanguagePython, "workspace/project")
err := lsp.Start(ctx) // Initialize the server
if err != nil {
log.Fatal(err)
}
// Now ready for LSP operations
LspServer lsp = sandbox.createLspServer("typescript", "workspace/project");
lsp.start("typescript", "workspace/project");
// Now ready for LSP operations
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/start' \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"languageId": "",
"pathToProject": ""
}'
Daytona provides methods to stop LSP servers.
<Tabs syncKey="language"> <TabItem label="Python" icon="seti:python"># When done with LSP features
lsp.stop() # Clean up resources
// When done with LSP features
await lsp.stop() // Clean up resources
# When done with LSP features
lsp.stop # Clean up resources
// When done with LSP features
err := lsp.Stop(ctx) // Clean up resources
if err != nil {
log.Fatal(err)
}
// When done with LSP features
lsp.stop("typescript", "workspace/project"); // Clean up resources
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/stop' \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"languageId": "",
"pathToProject": ""
}'
Daytona provides methods to get code completions for a specific position in a file.
<Tabs syncKey="language"> <TabItem label="Python" icon="seti:python">completions = lsp_server.completions(
path="workspace/project/main.py",
position={"line": 10, "character": 15}
)
print(f"Completions: {completions}")
const completions = await lspServer.completions('workspace/project/main.ts', {
line: 10,
character: 15,
})
console.log('Completions:', completions)
completions = lsp_server.completions(
path: 'workspace/project/main.py',
position: { line: 10, character: 15 }
)
puts "Completions: #{completions}"
completions, err := lsp.Completions(ctx, "workspace/project/main.py",
types.Position{Line: 10, Character: 15},
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Completions: %v\n", completions)
var completions = lsp.completions(
"typescript",
"workspace/project",
"workspace/project/Main.java",
10,
15);
System.out.println("Completions: " + completions);
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/completions' \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"context": {
"triggerCharacter": "",
"triggerKind": 1
},
"languageId": "",
"pathToProject": "",
"position": {
"character": 1,
"line": 1
},
"uri": ""
}'
Daytona provides methods to notify the LSP server when files are opened or closed. This enables features like diagnostics and completion tracking for the specified files.
Notifies the language server that a file has been opened for editing.
<Tabs syncKey="language"> <TabItem label="Python" icon="seti:python"># Notify server that a file is open
lsp_server.did_open("workspace/project/main.py")
// Notify server that a file is open
await lspServer.didOpen('workspace/project/main.ts')
# Notify server that a file is open
lsp_server.did_open('workspace/project/main.py')
// Notify server that a file is open
err := lsp.DidOpen(ctx, "workspace/project/main.py")
if err != nil {
log.Fatal(err)
}
// Notify server that a file is open
lsp.didOpen("typescript", "workspace/project", "workspace/project/Main.java");
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/did-open' \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"languageId": "",
"pathToProject": "",
"uri": ""
}'
Notifies the language server that a file has been closed. This allows the server to clean up resources associated with that file.
<Tabs syncKey="language"> <TabItem label="Python" icon="seti:python"># Notify server that a file is closed
lsp_server.did_close("workspace/project/main.py")
// Notify server that a file is closed
await lspServer.didClose('workspace/project/main.ts')
# Notify server that a file is closed
lsp_server.did_close('workspace/project/main.py')
// Notify server that a file is closed
err := lsp.DidClose(ctx, "workspace/project/main.py")
if err != nil {
log.Fatal(err)
}
// Notify server that a file is closed
lsp.didClose("typescript", "workspace/project", "workspace/project/Main.java");
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/did-close' \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"languageId": "",
"pathToProject": "",
"uri": ""
}'
Daytona provides methods to retrieve symbols (functions, classes, variables, etc.) from a document.
<Tabs syncKey="language"> <TabItem label="Python" icon="seti:python">symbols = lsp_server.document_symbols("workspace/project/main.py")
for symbol in symbols:
print(f"Symbol: {symbol.name}, Kind: {symbol.kind}")
const symbols = await lspServer.documentSymbols('workspace/project/main.ts')
symbols.forEach((symbol) => {
console.log(`Symbol: ${symbol.name}, Kind: ${symbol.kind}`)
})
symbols = lsp_server.document_symbols('workspace/project/main.py')
symbols.each do |symbol|
puts "Symbol: #{symbol.name}, Kind: #{symbol.kind}"
end
symbols, err := lsp.DocumentSymbols(ctx, "workspace/project/main.py")
if err != nil {
log.Fatal(err)
}
for _, symbol := range symbols {
fmt.Printf("Symbol: %v\n", symbol)
}
var symbols = lsp.documentSymbols(
"typescript",
"workspace/project",
"workspace/project/Main.java");
for (var symbol : symbols) {
System.out.println("Symbol: " + symbol.getName() + ", Kind: " + symbol.getKind());
}
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/document-symbols?languageId=&pathToProject=&uri='
Daytona provides methods to search for symbols across all files in the sandbox.
<Tabs syncKey="language"> <TabItem label="Python" icon="seti:python">symbols = lsp_server.sandbox_symbols("MyClass")
for symbol in symbols:
print(f"Found: {symbol.name} at {symbol.location}")
const symbols = await lspServer.sandboxSymbols('MyClass')
symbols.forEach((symbol) => {
console.log(`Found: ${symbol.name} at ${symbol.location}`)
})
symbols = lsp_server.sandbox_symbols('MyClass')
symbols.each do |symbol|
puts "Found: #{symbol.name} at #{symbol.location}"
end
symbols, err := lsp.SandboxSymbols(ctx, "MyClass")
if err != nil {
log.Fatal(err)
}
for _, symbol := range symbols {
fmt.Printf("Found: %v\n", symbol)
}
var symbols = lsp.workspaceSymbols("MyClass", "typescript", "workspace/project");
for (var symbol : symbols) {
System.out.println("Found: " + symbol.getName() + " at " + symbol.getLocation());
}
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/workspacesymbols?query=&languageId=&pathToProject='