How to print line on LSP?

Using tower-lsp I'm getting a panic but my println! or self.client.log_message() right before it doesn't show up in Visual Studio Code's output:

[Info  - 6:55:51 PM] server initialized!

thread 'main' panicked at crates\whack\src\processes\commons.rs:48:60:
called `Result::unwrap()` on an `Err` value: Os { code: 161, kind: InvalidFilename, message: "The specified path is invalid." }
stack backtrace:
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Here's my Rust setup:

#[realhydroper_lsp::async_trait(?Send)]
impl LanguageServer for Backend {
    async fn initialize(&self, _: InitializeParams) -> Result<InitializeResult> {
        Ok(InitializeResult {
            capabilities: ServerCapabilities {
                position_encoding: Some(PositionEncodingKind::UTF16),
                hover_provider: Some(HoverProviderCapability::Simple(true)),
                definition_provider: Some(OneOf::Left(true)),
                text_document_sync: Some(TextDocumentSyncCapability::Options(
                    TextDocumentSyncOptions {
                        open_close: Some(true),
                        change: Some(TextDocumentSyncKind::FULL),
                        save: Some(TextDocumentSyncSaveOptions::SaveOptions(SaveOptions {
                            include_text: Some(true),
                        })),
                        ..Default::default()
                    },
                )),
                workspace: Some(WorkspaceServerCapabilities {
                    workspace_folders: Some(WorkspaceFoldersServerCapabilities {
                        supported: Some(true),
                        change_notifications: Some(OneOf::Left(true)),
                    }),
                    file_operations: None,
                }),
                ..ServerCapabilities::default()
            },
            server_info: None,
            ..default()
        })
    }

    // code
}

Extension TypeScript:

// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import path from 'path';
import * as vscode from 'vscode';

// Language client
import * as vscodelc from "vscode-languageclient/node";

const whackHome = process.env.WHACK_HOME;

// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
    // Use the console to output diagnostic information (console.log) and errors (console.error)
    // This line of code will only be executed once when your extension is activated
    console.log('Congratulations, your extension "whack-engine" is now active!');

    if (whackHome === undefined)
    {
        vscode.window.showErrorMessage("Environment variable WHACK_HOME must be set.");
    }

    // The command has been defined in the package.json file
    // Now provide the implementation of the command with registerCommand
    // The commandId parameter must match the command field in package.json
    const disposable = vscode.commands.registerCommand('whack-engine.helloWorld', () => {
        // The code you place here will be executed every time your command is executed
        // Display a message box to the user
        vscode.window.showInformationMessage('Hello World from Whack engine support!');
    });

    context.subscriptions.push(disposable);

    // Setup language server
    if (whackHome)
    {
        const underWindows = process.platform == "win32";
        const server: vscodelc.Executable = {
            command: path.resolve(whackHome, "bin/whacklangserver" + (underWindows ? ".exe" : "")),
            args: [],
            options: {
                env: {
                    ...process.env,
                }
            },
        };

        const serverOptions: vscodelc.ServerOptions = server;

        let clientOptions: vscodelc.LanguageClientOptions = {
            // Register the server for AS3/MXML/CSS
            documentSelector: [
                { scheme: "file", language: "as3" },
                { scheme: "file", language: "mxml" },
                { scheme: "file", language: "css" }
            ],
            synchronize: {
                // Notify the server about file changes to AS3/MXML/CSS and
                // whack.toml files contained in the workspace
                fileEvents: [
                    vscode.workspace.createFileSystemWatcher("**/*.{as,mxml,css}"),
                    vscode.workspace.createFileSystemWatcher("**/whack.toml"),
                ],
            },
        };

        const client = new vscodelc.LanguageClient("ActionScript 3 & MXML language server", serverOptions, clientOptions);
        client.start();
    }
}

// This method is called when your extension is deactivated
export function deactivate() {}

When you start a LSP server, the host will typically send requests to it via stdin and read responses from stdout.

That means if you use println!() to print debug messages, it'll be interpreted as a response by VS Code will probably ignore it because it doesn't match the format.

You probably want to do eprintln!() so your debug messages are printed to stderr, instead. Anything printed to stderr should get shown in the output tab.

2 Likes

Thanks!