Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions crates/rust-analyzer/src/bin/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::{fmt::Write, path::PathBuf};

pub(crate) struct Args {
pub(crate) verbosity: Verbosity,
pub(crate) use_cwd: bool,
pub(crate) command: Command,
}

Expand Down Expand Up @@ -43,9 +44,15 @@ impl Args {
pub(crate) fn parse() -> Result<Result<Args, HelpPrinted>> {
let mut matches = Arguments::from_env();

let use_cwd = matches.contains("--use-cwd");

if matches.contains("--version") {
matches.finish().or_else(handle_extra_flags)?;
return Ok(Ok(Args { verbosity: Verbosity::Normal, command: Command::Version }));
return Ok(Ok(Args {
verbosity: Verbosity::Normal,
use_cwd,
command: Command::Version,
}));
}

let verbosity = match (
Expand All @@ -65,7 +72,7 @@ impl Args {
Some(it) => it,
None => {
matches.finish().or_else(handle_extra_flags)?;
return Ok(Ok(Args { verbosity, command: Command::RunServer }));
return Ok(Ok(Args { verbosity, use_cwd, command: Command::RunServer }));
}
};
let command = match subcommand.as_str() {
Expand Down Expand Up @@ -230,7 +237,7 @@ SUBCOMMANDS:
return Ok(Err(HelpPrinted));
}
};
Ok(Ok(Args { verbosity, command }))
Ok(Ok(Args { verbosity, use_cwd, command }))
}
}

Expand Down
35 changes: 24 additions & 11 deletions crates/rust-analyzer/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn main() -> Result<()> {
cli::analysis_bench(args.verbosity, path.as_ref(), what, load_output_dirs)?
}

args::Command::RunServer => run_server()?,
args::Command::RunServer => run_server(args.use_cwd)?,
args::Command::Version => println!("rust-analyzer {}", env!("REV")),
}
Ok(())
Expand All @@ -52,7 +52,7 @@ fn setup_logging() -> Result<()> {
Ok(())
}

fn run_server() -> Result<()> {
fn run_server(use_cwd: bool) -> Result<()> {
log::info!("lifecycle: server started");

let (connection, io_threads) = Connection::stdio();
Expand All @@ -67,15 +67,28 @@ fn run_server() -> Result<()> {
}

let cwd = std::env::current_dir()?;
let root = initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd);

let workspace_roots = initialize_params
.workspace_folders
.map(|workspaces| {
workspaces.into_iter().filter_map(|it| it.uri.to_file_path().ok()).collect::<Vec<_>>()
})
.filter(|workspaces| !workspaces.is_empty())
.unwrap_or_else(|| vec![root]);
let root = if use_cwd {
cwd
} else {
initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd)
};

log::info!("lifecycle: server started");

let workspace_roots = if use_cwd {
vec![root]
} else {
initialize_params
.workspace_folders
.map(|workspaces| {
workspaces
.into_iter()
.filter_map(|it| it.uri.to_file_path().ok())
.collect::<Vec<_>>()
})
.filter(|workspaces| !workspaces.is_empty())
.unwrap_or_else(|| vec![root])
};

let config = {
let mut config = Config::default();
Expand Down
9 changes: 5 additions & 4 deletions editors/code/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import * as vscode from 'vscode';
import { CallHierarchyFeature } from 'vscode-languageclient/lib/callHierarchy.proposed';
import { SemanticTokensFeature, DocumentSemanticsTokensSignature } from 'vscode-languageclient/lib/semanticTokens.proposed';

export async function createClient(serverPath: string, cwd: string): Promise<lc.LanguageClient> {
export async function createClient(serverPath: string, cwd: vscode.WorkspaceFolder): Promise<lc.LanguageClient> {
// '.' Is the fallback if no folder is open
// TODO?: Workspace folders support Uri's (eg: file://test.txt).
// It might be a good idea to test if the uri points to a file.

const run: lc.Executable = {
command: serverPath,
options: { cwd },
args: ["--use-cwd"],
options: { cwd: cwd.uri.fsPath },
};
const serverOptions: lc.ServerOptions = {
run,
Expand All @@ -22,7 +23,7 @@ export async function createClient(serverPath: string, cwd: string): Promise<lc.
);

const clientOptions: lc.LanguageClientOptions = {
documentSelector: [{ scheme: 'file', language: 'rust' }],
documentSelector: [{ scheme: 'file', language: 'rust', pattern: `**${cwd.uri.path}/**` }],
initializationOptions: vscode.workspace.getConfiguration("rust-analyzer"),
traceOutputChannel,
middleware: {
Expand All @@ -32,7 +33,7 @@ export async function createClient(serverPath: string, cwd: string): Promise<lc.
if (res === undefined) throw new Error('busy');
return res;
}
} as any
} as any,
};

const res = new lc.LanguageClient(
Expand Down
42 changes: 31 additions & 11 deletions editors/code/src/ctx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import * as lc from 'vscode-languageclient';
import { Config } from './config';
import { createClient } from './client';
import { isRustEditor, RustEditor } from './util';
import { StatusDisplay } from './status_display';
import { WorkDoneProgress } from 'vscode-languageclient';

export class Ctx {
private constructor(
readonly config: Config,
private readonly extCtx: vscode.ExtensionContext,
readonly client: lc.LanguageClient,
readonly serverPath: string,
readonly subscriptions: Disposable[],
private readonly status: StatusDisplay,
) {

}
Expand All @@ -19,12 +23,24 @@ export class Ctx {
config: Config,
extCtx: vscode.ExtensionContext,
serverPath: string,
cwd: string,
cwd: vscode.WorkspaceFolder,
): Promise<Ctx> {
const client = await createClient(serverPath, cwd);
const res = new Ctx(config, extCtx, client, serverPath);

const statusDisplay = new StatusDisplay(config.checkOnSave.command);
const res = new Ctx(config, extCtx, client, serverPath, [], statusDisplay);

res.pushCleanup(client.start());
await client.onReady();

res.pushCleanup(res.status);
if (client != null) {
res.pushCleanup(client.onProgress(
WorkDoneProgress.type,
'rustAnalyzer/cargoWatcher',
params => res.status.handleProgressNotification(params)
));
}
return res;
}

Expand All @@ -39,23 +55,27 @@ export class Ctx {
return vscode.window.visibleTextEditors.filter(isRustEditor);
}

registerCommand(name: string, factory: (ctx: Ctx) => Cmd) {
const fullName = `rust-analyzer.${name}`;
const cmd = factory(this);
const d = vscode.commands.registerCommand(fullName, cmd);
this.pushCleanup(d);
}

get globalState(): vscode.Memento {
return this.extCtx.globalState;
}

get subscriptions(): Disposable[] {
return this.extCtx.subscriptions;
show() {
this.status.statusBarItem.show();
}

hide() {
this.status.statusBarItem.hide();
}

dispose() {
for (const d of this.subscriptions) {
d.dispose();
}
}

pushCleanup(d: Disposable) {
this.extCtx.subscriptions.push(d);
this.subscriptions.push(d);
}
}

Expand Down
Loading