File tree Expand file tree Collapse file tree 9 files changed +167
-8
lines changed Expand file tree Collapse file tree 9 files changed +167
-8
lines changed Original file line number Diff line number Diff line change 44 "editor.formatOnSaveMode" : " file" ,
55 "editor.defaultFormatter" : " rust-lang.rust-analyzer"
66 },
7+ "[typescript]" : {
8+ "editor.formatOnSave" : true ,
9+ "editor.defaultFormatter" : " esbenp.prettier-vscode"
10+ },
711 "rust-analyzer.check.command" : " clippy" ,
812 "rust-analyzer.imports.prefix" : " crate" ,
913 "rust-analyzer.imports.granularity.group" : " item" ,
Original file line number Diff line number Diff line change @@ -36,6 +36,7 @@ use crate::documents::Document;
3636use crate :: logging;
3737use crate :: logging:: LogMessageSender ;
3838use crate :: main_loop:: LspState ;
39+ use crate :: settings:: InitializationOptions ;
3940use crate :: state:: workspace_uris;
4041use crate :: state:: WorldState ;
4142
@@ -65,9 +66,13 @@ pub(crate) fn initialize(
6566 state : & mut WorldState ,
6667 log_tx : LogMessageSender ,
6768) -> anyhow:: Result < InitializeResult > {
68- // TODO: Get user specified options from `params.initialization_options`
69- let log_level = None ;
70- let dependency_log_levels = None ;
69+ let InitializationOptions {
70+ log_level,
71+ dependency_log_levels,
72+ } = params. initialization_options . map_or_else (
73+ InitializationOptions :: default,
74+ InitializationOptions :: from_value,
75+ ) ;
7176
7277 logging:: init_logging (
7378 log_tx,
Original file line number Diff line number Diff line change @@ -15,6 +15,7 @@ pub mod handlers_state;
1515pub mod logging;
1616pub mod main_loop;
1717pub mod rust_analyzer;
18+ pub mod settings;
1819pub mod state;
1920pub mod to_proto;
2021pub mod tower_lsp;
Original file line number Diff line number Diff line change @@ -145,7 +145,7 @@ pub(crate) struct GlobalState {
145145 log_tx : Option < LogMessageSender > ,
146146}
147147
148- /// Unlike `WorldState`, `ParserState ` cannot be cloned and is only accessed by
148+ /// Unlike `WorldState`, `LspState ` cannot be cloned and is only accessed by
149149/// exclusive handlers.
150150pub ( crate ) struct LspState {
151151 /// The negociated encoding for document positions. Note that documents are
Original file line number Diff line number Diff line change 1+ use serde:: Deserialize ;
2+ use serde_json:: Value ;
3+
4+ /// This is the exact schema for initialization options sent in by the client
5+ /// during initialization. Remember that initialization options are ones that are
6+ /// strictly required at startup time, and most configuration options should really be
7+ /// "pulled" dynamically by the server after startup and whenever we receive a
8+ /// configuration change notification (#121).
9+ #[ derive( Debug , Deserialize , Default ) ]
10+ #[ serde( rename_all = "camelCase" ) ]
11+ pub ( crate ) struct InitializationOptions {
12+ pub ( crate ) log_level : Option < crate :: logging:: LogLevel > ,
13+ pub ( crate ) dependency_log_levels : Option < String > ,
14+ }
15+
16+ impl InitializationOptions {
17+ pub ( crate ) fn from_value ( value : Value ) -> Self {
18+ serde_json:: from_value ( value)
19+ . map_err ( |err| {
20+ tracing:: error!( "Failed to deserialize initialization options: {err}. Falling back to default settings." ) ;
21+ } )
22+ . unwrap_or_default ( )
23+ }
24+ }
Original file line number Diff line number Diff line change 3535 ]
3636 }
3737 ],
38+ "configuration" : {
39+ "properties" : {
40+ "air.logLevel" : {
41+ "default" : null ,
42+ "markdownDescription" : " Controls the log level of the language server.\n\n **This setting requires a restart to take effect.**" ,
43+ "enum" : [
44+ " error" ,
45+ " warning" ,
46+ " info" ,
47+ " debug" ,
48+ " trace"
49+ ],
50+ "scope" : " application" ,
51+ "type" : " string"
52+ },
53+ "air.dependencyLogLevels" : {
54+ "default" : null ,
55+ "markdownDescription" : " Controls the log level of the Rust crates that the language server depends on.\n\n **This setting requires a restart to take effect.**" ,
56+ "scope" : " application" ,
57+ "type" : " string"
58+ }
59+ }
60+ },
3861 "configurationDefaults" : {
3962 "[r]" : {
4063 "editor.defaultFormatter" : " Posit.air"
Original file line number Diff line number Diff line change 11import * as vscode from "vscode" ;
22import * as lc from "vscode-languageclient/node" ;
33import { default as PQueue } from "p-queue" ;
4+ import { getInitializationOptions } from "./settings" ;
45
56// All session management operations are put on a queue. They can't run
67// concurrently and either result in a started or stopped state. Starting when
@@ -52,7 +53,9 @@ export class Lsp {
5253 return ;
5354 }
5455
55- let options : lc . ServerOptions = {
56+ const initializationOptions = getInitializationOptions ( "air" ) ;
57+
58+ let serverOptions : lc . ServerOptions = {
5659 command : "air" ,
5760 args : [ "language-server" ] ,
5861 } ;
@@ -71,13 +74,14 @@ export class Lsp {
7174 vscode . workspace . createFileSystemWatcher ( "**/*.[Rr]" ) ,
7275 } ,
7376 outputChannel : this . channel ,
77+ initializationOptions : initializationOptions ,
7478 } ;
7579
7680 const client = new lc . LanguageClient (
7781 "airLanguageServer" ,
7882 "Air Language Server" ,
79- options ,
80- clientOptions ,
83+ serverOptions ,
84+ clientOptions
8185 ) ;
8286 await client . start ( ) ;
8387
Original file line number Diff line number Diff line change 1+ import { ConfigurationScope , workspace , WorkspaceConfiguration } from "vscode" ;
2+
3+ type LogLevel = "error" | "warn" | "info" | "debug" | "trace" ;
4+
5+ // This is a direct representation of the Client settings sent to the Server in the
6+ // `initializationOptions` field of `InitializeParams`. These are only pulled at the
7+ // user level since they are global settings on the server side (and are scoped to
8+ // `"scope": "application"` in `package.json` so they can't even be set at workspace level).
9+ export type InitializationOptions = {
10+ logLevel ?: LogLevel ;
11+ dependencyLogLevels ?: string ;
12+ } ;
13+
14+ export function getInitializationOptions (
15+ namespace : string
16+ ) : InitializationOptions {
17+ const config = getConfiguration ( namespace ) ;
18+
19+ return {
20+ logLevel : getOptionalUserValue < LogLevel > ( config , "logLevel" ) ,
21+ dependencyLogLevels : getOptionalUserValue < string > (
22+ config ,
23+ "dependencyLogLevels"
24+ ) ,
25+ } ;
26+ }
27+
28+ function getOptionalUserValue < T > (
29+ config : WorkspaceConfiguration ,
30+ key : string
31+ ) : T | undefined {
32+ const inspect = config . inspect < T > ( key ) ;
33+ return inspect ?. globalValue ;
34+ }
35+
36+ function getConfiguration (
37+ config : string ,
38+ scope ?: ConfigurationScope
39+ ) : WorkspaceConfiguration {
40+ return workspace . getConfiguration ( config , scope ) ;
41+ }
You can’t perform that action at this time.
0 commit comments