Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--.editorconfig19
-rw-r--r--.git-blame-ignore-revs8
-rw-r--r--editors/code/.eslintrc.js53
-rw-r--r--editors/code/.prettierignore3
-rw-r--r--editors/code/.prettierrc.js5
-rw-r--r--editors/code/language-configuration.json10
-rw-r--r--editors/code/package-lock.json200
-rw-r--r--editors/code/package.json7
-rw-r--r--editors/code/ra_syntax_tree.tmGrammar.json4
-rw-r--r--editors/code/src/ast_inspector.ts80
-rw-r--r--editors/code/src/client.ts277
-rw-r--r--editors/code/src/commands.ts472
-rw-r--r--editors/code/src/config.ts210
-rw-r--r--editors/code/src/ctx.ts38
-rw-r--r--editors/code/src/debug.ts77
-rw-r--r--editors/code/src/lsp_ext.ts74
-rw-r--r--editors/code/src/main.ts198
-rw-r--r--editors/code/src/persistent_state.ts4
-rw-r--r--editors/code/src/run.ts64
-rw-r--r--editors/code/src/snippets.ts50
-rw-r--r--editors/code/src/tasks.ts40
-rw-r--r--editors/code/src/toolchain.ts74
-rw-r--r--editors/code/src/util.ts29
-rw-r--r--editors/code/tests/runTests.ts24
-rw-r--r--editors/code/tests/unit/index.ts8
-rw-r--r--editors/code/tests/unit/launch_config.test.ts85
-rw-r--r--editors/code/tests/unit/runnable_env.test.ts62
-rw-r--r--editors/code/tests/unit/settings.test.ts32
-rw-r--r--editors/code/tsconfig.eslint.json16
-rw-r--r--editors/code/tsconfig.json14
30 files changed, 1263 insertions, 974 deletions
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000..314f79d3f9
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,19 @@
+# https://EditorConfig.org
+root = true
+
+[*]
+charset = utf-8
+trim_trailing_whitespace = true
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+
+[*.{rs,toml}]
+indent_size = 4
+
+[*.ts]
+indent_size = 4
+[*.js]
+indent_size = 4
+[*.json]
+indent_size = 4
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 0000000000..a302e23781
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,8 @@
+# for this file to take effect make sure you use git ^2.23 and
+# add ignoreFile to your git configuration:
+# ```
+# git config --global blame.ignoreRevsFile .git-blame-ignore-revs
+# ```
+
+# prettier format
+f247090558c9ba3c551566eae5882b7ca865225f
diff --git a/editors/code/.eslintrc.js b/editors/code/.eslintrc.js
index 631d956da2..297e9fa1e5 100644
--- a/editors/code/.eslintrc.js
+++ b/editors/code/.eslintrc.js
@@ -1,40 +1,37 @@
module.exports = {
- "env": {
- "es6": true,
- "node": true
+ env: {
+ es6: true,
+ node: true,
},
- "parser": "@typescript-eslint/parser",
- "parserOptions": {
- "project": "tsconfig.eslint.json",
- "tsconfigRootDir": __dirname,
- "sourceType": "module"
+ extends: ["prettier"],
+ parser: "@typescript-eslint/parser",
+ parserOptions: {
+ project: "tsconfig.eslint.json",
+ tsconfigRootDir: __dirname,
+ sourceType: "module",
},
- "plugins": [
- "@typescript-eslint"
- ],
- "rules": {
- "camelcase": ["error"],
- "eqeqeq": ["error", "always", { "null": "ignore" }],
+ plugins: ["@typescript-eslint"],
+ rules: {
+ camelcase: ["error"],
+ eqeqeq: ["error", "always", { null: "ignore" }],
+ curly: ["error", "multi-line"],
"no-console": ["error", { allow: ["warn", "error"] }],
"prefer-const": "error",
"@typescript-eslint/member-delimiter-style": [
"error",
{
- "multiline": {
- "delimiter": "semi",
- "requireLast": true
+ multiline: {
+ delimiter: "semi",
+ requireLast: true,
},
- "singleline": {
- "delimiter": "semi",
- "requireLast": false
- }
- }
- ],
- "@typescript-eslint/semi": [
- "error",
- "always"
+ singleline: {
+ delimiter: "semi",
+ requireLast: false,
+ },
+ },
],
+ "@typescript-eslint/semi": ["error", "always"],
"@typescript-eslint/no-unnecessary-type-assertion": "error",
- "@typescript-eslint/no-floating-promises": "error"
- }
+ "@typescript-eslint/no-floating-promises": "error",
+ },
};
diff --git a/editors/code/.prettierignore b/editors/code/.prettierignore
new file mode 100644
index 0000000000..13baf68d7c
--- /dev/null
+++ b/editors/code/.prettierignore
@@ -0,0 +1,3 @@
+node_modules
+.vscode-test
+out
diff --git a/editors/code/.prettierrc.js b/editors/code/.prettierrc.js
new file mode 100644
index 0000000000..cafb12f0e6
--- /dev/null
+++ b/editors/code/.prettierrc.js
@@ -0,0 +1,5 @@
+module.exports = {
+ // use 100 because it's Rustfmt's default
+ // https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#max_width
+ printWidth: 100,
+};
diff --git a/editors/code/language-configuration.json b/editors/code/language-configuration.json
index cf7b20eb79..b1ee0843e3 100644
--- a/editors/code/language-configuration.json
+++ b/editors/code/language-configuration.json
@@ -1,7 +1,7 @@
{
"comments": {
"lineComment": "//",
- "blockComment": [ "/*", "*/" ]
+ "blockComment": ["/*", "*/"]
},
"brackets": [
["{", "}"],
@@ -9,10 +9,10 @@
["(", ")"]
],
"colorizedBracketPairs": [
- ["{", "}"],
- ["[", "]"],
- ["(", ")"]
- ],
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"]
+ ],
"autoClosingPairs": [
{ "open": "{", "close": "}" },
{ "open": "[", "close": "]" },
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index 74cda037d8..20d3a304f8 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "rust-analyzer",
- "version": "0.4.0-dev",
+ "version": "0.5.0-dev",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "rust-analyzer",
- "version": "0.4.0-dev",
+ "version": "0.5.0-dev",
"license": "MIT OR Apache-2.0",
"dependencies": {
"d3": "^7.3.0",
@@ -22,9 +22,10 @@
"cross-env": "^7.0.3",
"esbuild": "^0.14.27",
"eslint": "^8.11.0",
+ "eslint-config-prettier": "^8.5.0",
+ "prettier": "^2.6.2",
"tslib": "^2.3.0",
"typescript": "^4.6.3",
- "typescript-formatter": "^7.2.2",
"vsce": "^2.7.0"
},
"engines": {
@@ -768,12 +769,6 @@
"node": ">= 10"
}
},
- "node_modules/commandpost": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.4.0.tgz",
- "integrity": "sha512-aE2Y4MTFJ870NuB/+2z1cXBhSBBzRydVVjzhFC4gtenEhpnj15yu0qptWGJsO9YGrcPZ3ezX8AWb1VA391MKpQ==",
- "dev": true
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -1492,52 +1487,6 @@
"readable-stream": "^2.0.2"
}
},
- "node_modules/editorconfig": {
- "version": "0.15.3",
- "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
- "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==",
- "dev": true,
- "dependencies": {
- "commander": "^2.19.0",
- "lru-cache": "^4.1.5",
- "semver": "^5.6.0",
- "sigmund": "^1.0.1"
- },
- "bin": {
- "editorconfig": "bin/editorconfig"
- }
- },
- "node_modules/editorconfig/node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
- },
- "node_modules/editorconfig/node_modules/lru-cache": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
- "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
- "dev": true,
- "dependencies": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
- }
- },
- "node_modules/editorconfig/node_modules/semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/editorconfig/node_modules/yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
- "dev": true
- },
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -1988,6 +1937,18 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/eslint-config-prettier": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
+ "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
+ "dev": true,
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
"node_modules/eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@@ -3130,18 +3091,27 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/prettier": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
+ "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
- "node_modules/pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
- "dev": true
- },
"node_modules/pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -3412,12 +3382,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/sigmund": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
- "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
- "dev": true
- },
"node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -3734,25 +3698,6 @@
"node": ">=4.2.0"
}
},
- "node_modules/typescript-formatter": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-7.2.2.tgz",
- "integrity": "sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ==",
- "dev": true,
- "dependencies": {
- "commandpost": "^1.0.0",
- "editorconfig": "^0.15.0"
- },
- "bin": {
- "tsfmt": "bin/tsfmt"
- },
- "engines": {
- "node": ">= 4.2.0"
- },
- "peerDependencies": {
- "typescript": "^2.1.6 || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev"
- }
- },
"node_modules/uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
@@ -4659,12 +4604,6 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="
},
- "commandpost": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.4.0.tgz",
- "integrity": "sha512-aE2Y4MTFJ870NuB/+2z1cXBhSBBzRydVVjzhFC4gtenEhpnj15yu0qptWGJsO9YGrcPZ3ezX8AWb1VA391MKpQ==",
- "dev": true
- },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -5207,48 +5146,6 @@
"readable-stream": "^2.0.2"
}
},
- "editorconfig": {
- "version": "0.15.3",
- "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
- "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==",
- "dev": true,
- "requires": {
- "commander": "^2.19.0",
- "lru-cache": "^4.1.5",
- "semver": "^5.6.0",
- "sigmund": "^1.0.1"
- },
- "dependencies": {
- "commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
- },
- "lru-cache": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
- "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
- "dev": true,
- "requires": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
- }
- },
- "semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "dev": true
- },
- "yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
- "dev": true
- }
- }
- },
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -5509,6 +5406,13 @@
}
}
},
+ "eslint-config-prettier": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
+ "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
+ "dev": true,
+ "requires": {}
+ },
"eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@@ -6386,18 +6290,18 @@
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
+ "prettier": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
+ "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
+ "dev": true
+ },
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
- "pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
- "dev": true
- },
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -6587,12 +6491,6 @@
"object-inspect": "^1.9.0"
}
},
- "sigmund": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
- "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
- "dev": true
- },
"signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -6820,16 +6718,6 @@
"integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==",
"dev": true
},
- "typescript-formatter": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-7.2.2.tgz",
- "integrity": "sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ==",
- "dev": true,
- "requires": {
- "commandpost": "^1.0.0",
- "editorconfig": "^0.15.0"
- }
- },
"uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
diff --git a/editors/code/package.json b/editors/code/package.json
index 04006d7434..02899b6d17 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -29,8 +29,8 @@
"build-base": "esbuild ./src/main.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node --target=node16",
"build": "npm run build-base -- --sourcemap",
"watch": "npm run build-base -- --sourcemap --watch",
- "lint": "tsfmt --verify && eslint -c .eslintrc.js --ext ts ./src ./tests",
- "fix": " tsfmt -r && eslint -c .eslintrc.js --ext ts ./src ./tests --fix",
+ "lint": "prettier --check . && eslint -c .eslintrc.js --ext ts ./src ./tests",
+ "fix": "prettier --write . && eslint -c .eslintrc.js --ext ts ./src ./tests --fix",
"pretest": "tsc && npm run build",
"test": "cross-env TEST_VARIABLE=test node ./out/tests/runTests.js"
},
@@ -48,9 +48,10 @@
"cross-env": "^7.0.3",
"esbuild": "^0.14.27",
"eslint": "^8.11.0",
+ "eslint-config-prettier": "^8.5.0",
+ "prettier": "^2.6.2",
"tslib": "^2.3.0",
"typescript": "^4.6.3",
- "typescript-formatter": "^7.2.2",
"vsce": "^2.7.0"
},
"activationEvents": [
diff --git a/editors/code/ra_syntax_tree.tmGrammar.json b/editors/code/ra_syntax_tree.tmGrammar.json
index 431d414f64..279e7bafa0 100644
--- a/editors/code/ra_syntax_tree.tmGrammar.json
+++ b/editors/code/ra_syntax_tree.tmGrammar.json
@@ -25,7 +25,5 @@
"name": "string"
}
},
- "fileTypes": [
- "rast"
- ]
+ "fileTypes": ["rast"]
}
diff --git a/editors/code/src/ast_inspector.ts b/editors/code/src/ast_inspector.ts
index 28d8b2a5fd..e57fb20e2c 100644
--- a/editors/code/src/ast_inspector.ts
+++ b/editors/code/src/ast_inspector.ts
@@ -1,13 +1,13 @@
-import * as vscode from 'vscode';
+import * as vscode from "vscode";
-import { Ctx, Disposable } from './ctx';
-import { RustEditor, isRustEditor } from './util';
+import { Ctx, Disposable } from "./ctx";
+import { RustEditor, isRustEditor } from "./util";
// FIXME: consider implementing this via the Tree View API?
// https://code.visualstudio.com/api/extension-guides/tree-view
export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, Disposable {
private readonly astDecorationType = vscode.window.createTextEditorDecorationType({
- borderColor: new vscode.ThemeColor('rust_analyzer.syntaxTreeBorder'),
+ borderColor: new vscode.ThemeColor("rust_analyzer.syntaxTreeBorder"),
borderStyle: "solid",
borderWidth: "2px",
});
@@ -35,11 +35,23 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
});
constructor(ctx: Ctx) {
- ctx.pushCleanup(vscode.languages.registerHoverProvider({ scheme: 'rust-analyzer' }, this));
+ ctx.pushCleanup(vscode.languages.registerHoverProvider({ scheme: "rust-analyzer" }, this));
ctx.pushCleanup(vscode.languages.registerDefinitionProvider({ language: "rust" }, this));
- vscode.workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, ctx.subscriptions);
- vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
- vscode.window.onDidChangeVisibleTextEditors(this.onDidChangeVisibleTextEditors, this, ctx.subscriptions);
+ vscode.workspace.onDidCloseTextDocument(
+ this.onDidCloseTextDocument,
+ this,
+ ctx.subscriptions
+ );
+ vscode.workspace.onDidChangeTextDocument(
+ this.onDidChangeTextDocument,
+ this,
+ ctx.subscriptions
+ );
+ vscode.window.onDidChangeVisibleTextEditors(
+ this.onDidChangeVisibleTextEditors,
+ this,
+ ctx.subscriptions
+ );
ctx.pushCleanup(this);
}
@@ -48,7 +60,10 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
}
private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
- if (this.rustEditor && event.document.uri.toString() === this.rustEditor.document.uri.toString()) {
+ if (
+ this.rustEditor &&
+ event.document.uri.toString() === this.rustEditor.document.uri.toString()
+ ) {
this.rust2Ast.reset();
}
}
@@ -68,7 +83,9 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
}
private findAstTextEditor(): undefined | vscode.TextEditor {
- return vscode.window.visibleTextEditors.find(it => it.document.uri.scheme === 'rust-analyzer');
+ return vscode.window.visibleTextEditors.find(
+ (it) => it.document.uri.scheme === "rust-analyzer"
+ );
}
private setRustEditor(newRustEditor: undefined | RustEditor) {
@@ -80,13 +97,20 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
}
// additional positional params are omitted
- provideDefinition(doc: vscode.TextDocument, pos: vscode.Position): vscode.ProviderResult<vscode.DefinitionLink[]> {
- if (!this.rustEditor || doc.uri.toString() !== this.rustEditor.document.uri.toString()) return;
+ provideDefinition(
+ doc: vscode.TextDocument,
+ pos: vscode.Position
+ ): vscode.ProviderResult<vscode.DefinitionLink[]> {
+ if (!this.rustEditor || doc.uri.toString() !== this.rustEditor.document.uri.toString()) {
+ return;
+ }
const astEditor = this.findAstTextEditor();
if (!astEditor) return;
- const rust2AstRanges = this.rust2Ast.get()?.find(([rustRange, _]) => rustRange.contains(pos));
+ const rust2AstRanges = this.rust2Ast
+ .get()
+ ?.find(([rustRange, _]) => rustRange.contains(pos));
if (!rust2AstRanges) return;
const [rustFileRange, astFileRange] = rust2AstRanges;
@@ -94,16 +118,21 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
astEditor.revealRange(astFileRange);
astEditor.selection = new vscode.Selection(astFileRange.start, astFileRange.end);
- return [{
- targetRange: astFileRange,
- targetUri: astEditor.document.uri,
- originSelectionRange: rustFileRange,
- targetSelectionRange: astFileRange,
- }];
+ return [
+ {
+ targetRange: astFileRange,
+ targetUri: astEditor.document.uri,
+ originSelectionRange: rustFileRange,
+ targetSelectionRange: astFileRange,
+ },
+ ];
}
// additional positional params are omitted
- provideHover(doc: vscode.TextDocument, hoverPosition: vscode.Position): vscode.ProviderResult<vscode.Hover> {
+ provideHover(
+ doc: vscode.TextDocument,
+ hoverPosition: vscode.Position
+ ): vscode.ProviderResult<vscode.Hover> {
if (!this.rustEditor) return;
const astFileLine = doc.lineAt(hoverPosition.line);
@@ -127,13 +156,14 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
return new vscode.Range(begin, end);
}
- private parseRustTextRange(doc: vscode.TextDocument, astLine: string): undefined | vscode.Range {
+ private parseRustTextRange(
+ doc: vscode.TextDocument,
+ astLine: string
+ ): undefined | vscode.Range {
const parsedRange = /(\d+)\.\.(\d+)/.exec(astLine);
if (!parsedRange) return;
- const [begin, end] = parsedRange
- .slice(1)
- .map(off => this.positionAt(doc, +off));
+ const [begin, end] = parsedRange.slice(1).map((off) => this.positionAt(doc, +off));
return new vscode.Range(begin, end);
}
@@ -173,7 +203,7 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
class Lazy<T> {
val: undefined | T;
- constructor(private readonly compute: () => undefined | T) { }
+ constructor(private readonly compute: () => undefined | T) {}
get() {
return this.val ?? (this.val = this.compute());
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 7519cd3de3..c960e283d3 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -1,39 +1,47 @@
-import * as lc from 'vscode-languageclient/node';
-import * as vscode from 'vscode';
-import * as ra from '../src/lsp_ext';
-import * as Is from 'vscode-languageclient/lib/common/utils/is';
-import { assert } from './util';
-import { WorkspaceEdit } from 'vscode';
-import { Workspace } from './ctx';
-import { updateConfig } from './config';
-import { substituteVariablesInEnv } from './config';
+import * as lc from "vscode-languageclient/node";
+import * as vscode from "vscode";
+import * as ra from "../src/lsp_ext";
+import * as Is from "vscode-languageclient/lib/common/utils/is";
+import { assert } from "./util";
+import { WorkspaceEdit } from "vscode";
+import { Workspace } from "./ctx";
+import { updateConfig } from "./config";
+import { substituteVariablesInEnv } from "./config";
export interface Env {
[name: string]: string;
}
function renderCommand(cmd: ra.CommandLink) {
- return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(JSON.stringify(cmd.arguments))} '${cmd.tooltip}')`;
+ return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(
+ JSON.stringify(cmd.arguments)
+ )} '${cmd.tooltip}')`;
}
function renderHoverActions(actions: ra.CommandLinkGroup[]): vscode.MarkdownString {
- const text = actions.map(group =>
- (group.title ? (group.title + " ") : "") + group.commands.map(renderCommand).join(' | ')
- ).join('___');
+ const text = actions
+ .map(
+ (group) =>
+ (group.title ? group.title + " " : "") +
+ group.commands.map(renderCommand).join(" | ")
+ )
+ .join("___");
const result = new vscode.MarkdownString(text);
result.isTrusted = true;
return result;
}
-export async function createClient(serverPath: string, workspace: Workspace, extraEnv: Env): Promise<lc.LanguageClient> {
+export async function createClient(
+ serverPath: string,
+ workspace: Workspace,
+ extraEnv: Env
+): 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 newEnv = substituteVariablesInEnv(Object.assign(
- {}, process.env, extraEnv
- ));
+ const newEnv = substituteVariablesInEnv(Object.assign({}, process.env, extraEnv));
const run: lc.Executable = {
command: serverPath,
options: { env: newEnv },
@@ -43,137 +51,176 @@ export async function createClient(serverPath: string, workspace: Workspace, ext
debug: run,
};
const traceOutputChannel = vscode.window.createOutputChannel(
- 'Rust Analyzer Language Server Trace',
+ "Rust Analyzer Language Server Trace"
);
let initializationOptions = vscode.workspace.getConfiguration("rust-analyzer");
// Update outdated user configs
- await updateConfig(initializationOptions).catch(err => {
+ await updateConfig(initializationOptions).catch((err) => {
void vscode.window.showErrorMessage(`Failed updating old config keys: ${err.message}`);
});
if (workspace.kind === "Detached Files") {
- initializationOptions = { "detachedFiles": workspace.files.map(file => file.uri.fsPath), ...initializationOptions };
+ initializationOptions = {
+ detachedFiles: workspace.files.map((file) => file.uri.fsPath),
+ ...initializationOptions,
+ };
}
const clientOptions: lc.LanguageClientOptions = {
- documentSelector: [{ scheme: 'file', language: 'rust' }],
+ documentSelector: [{ scheme: "file", language: "rust" }],
initializationOptions,
diagnosticCollectionName: "rustc",
traceOutputChannel,
middleware: {
- async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, _next: lc.ProvideHoverSignature) {
+ async provideHover(
+ document: vscode.TextDocument,
+ position: vscode.Position,
+ token: vscode.CancellationToken,
+ _next: lc.ProvideHoverSignature
+ ) {
const editor = vscode.window.activeTextEditor;
- const positionOrRange = editor?.selection?.contains(position) ? client.code2ProtocolConverter.asRange(editor.selection) : client.code2ProtocolConverter.asPosition(position);
- return client.sendRequest(ra.hover, {
- textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
- position: positionOrRange
- }, token).then(
- (result) => {
- const hover =
- client.protocol2CodeConverter.asHover(result);
- if (hover) {
- const actions = (<any>result).actions;
- if (actions) {
- hover.contents.push(renderHoverActions(actions));
+ const positionOrRange = editor?.selection?.contains(position)
+ ? client.code2ProtocolConverter.asRange(editor.selection)
+ : client.code2ProtocolConverter.asPosition(position);
+ return client
+ .sendRequest(
+ ra.hover,
+ {
+ textDocument:
+ client.code2ProtocolConverter.asTextDocumentIdentifier(document),
+ position: positionOrRange,
+ },
+ token
+ )
+ .then(
+ (result) => {
+ const hover = client.protocol2CodeConverter.asHover(result);
+ if (hover) {
+ const actions = (<any>result).actions;
+ if (actions) {
+ hover.contents.push(renderHoverActions(actions));
+ }
}
+ return hover;
+ },
+ (error) => {
+ client.handleFailedRequest(lc.HoverRequest.type, token, error, null);
+ return Promise.resolve(null);
}
- return hover;
- },
- (error) => {
- client.handleFailedRequest(
- lc.HoverRequest.type,
- token,
- error,
- null
- );
- return Promise.resolve(null);
- }
- );
+ );
},
// Using custom handling of CodeActions to support action groups and snippet edits.
// Note that this means we have to re-implement lazy edit resolving ourselves as well.
- async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) {
+ async provideCodeActions(
+ document: vscode.TextDocument,
+ range: vscode.Range,
+ context: vscode.CodeActionContext,
+ token: vscode.CancellationToken,
+ _next: lc.ProvideCodeActionsSignature
+ ) {
const params: lc.CodeActionParams = {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
range: client.code2ProtocolConverter.asRange(range),
- context: await client.code2ProtocolConverter.asCodeActionContext(context, token)
+ context: await client.code2ProtocolConverter.asCodeActionContext(
+ context,
+ token
+ ),
};
- return client.sendRequest(lc.CodeActionRequest.type, params, token).then(async (values) => {
- if (values === null) return undefined;
- const result: (vscode.CodeAction | vscode.Command)[] = [];
- const groups = new Map<string, { index: number; items: vscode.CodeAction[] }>();
- for (const item of values) {
- // In our case we expect to get code edits only from diagnostics
- if (lc.CodeAction.is(item)) {
- assert(!item.command, "We don't expect to receive commands in CodeActions");
- const action = await client.protocol2CodeConverter.asCodeAction(item, token);
- result.push(action);
- continue;
- }
- assert(isCodeActionWithoutEditsAndCommands(item), "We don't expect edits or commands here");
- const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind);
- const action = new vscode.CodeAction(item.title, kind);
- const group = (item as any).group;
- action.command = {
- command: "rust-analyzer.resolveCodeAction",
- title: item.title,
- arguments: [item],
- };
-
- // Set a dummy edit, so that VS Code doesn't try to resolve this.
- action.edit = new WorkspaceEdit();
-
- if (group) {
- let entry = groups.get(group);
- if (!entry) {
- entry = { index: result.length, items: [] };
- groups.set(group, entry);
+ return client.sendRequest(lc.CodeActionRequest.type, params, token).then(
+ async (values) => {
+ if (values === null) return undefined;
+ const result: (vscode.CodeAction | vscode.Command)[] = [];
+ const groups = new Map<
+ string,
+ { index: number; items: vscode.CodeAction[] }
+ >();
+ for (const item of values) {
+ // In our case we expect to get code edits only from diagnostics
+ if (lc.CodeAction.is(item)) {
+ assert(
+ !item.command,
+ "We don't expect to receive commands in CodeActions"
+ );
+ const action = await client.protocol2CodeConverter.asCodeAction(
+ item,
+ token
+ );
result.push(action);
+ continue;
}
- entry.items.push(action);
- } else {
- result.push(action);
- }
- }
- for (const [group, { index, items }] of groups) {
- if (items.length === 1) {
- result[index] = items[0];
- } else {
- const action = new vscode.CodeAction(group);
- action.kind = items[0].kind;
+ assert(
+ isCodeActionWithoutEditsAndCommands(item),
+ "We don't expect edits or commands here"
+ );
+ const kind = client.protocol2CodeConverter.asCodeActionKind(
+ (item as any).kind
+ );
+ const action = new vscode.CodeAction(item.title, kind);
+ const group = (item as any).group;
action.command = {
- command: "rust-analyzer.applyActionGroup",
- title: "",
- arguments: [items.map((item) => {
- return { label: item.title, arguments: item.command!.arguments![0] };
- })],
+ command: "rust-analyzer.resolveCodeAction",
+ title: item.title,
+ arguments: [item],
};
// Set a dummy edit, so that VS Code doesn't try to resolve this.
action.edit = new WorkspaceEdit();
- result[index] = action;
+ if (group) {
+ let entry = groups.get(group);
+ if (!entry) {
+ entry = { index: result.length, items: [] };
+ groups.set(group, entry);
+ result.push(action);
+ }
+ entry.items.push(action);
+ } else {
+ result.push(action);
+ }
}
- }
- return result;
- },
+ for (const [group, { index, items }] of groups) {
+ if (items.length === 1) {
+ result[index] = items[0];
+ } else {
+ const action = new vscode.CodeAction(group);
+ action.kind = items[0].kind;
+ action.command = {
+ command: "rust-analyzer.applyActionGroup",
+ title: "",
+ arguments: [
+ items.map((item) => {
+ return {
+ label: item.title,
+ arguments: item.command!.arguments![0],
+ };
+ }),
+ ],
+ };
+
+ // Set a dummy edit, so that VS Code doesn't try to resolve this.
+ action.edit = new WorkspaceEdit();
+
+ result[index] = action;
+ }
+ }
+ return result;
+ },
(_error) => undefined
);
- }
-
+ },
},
markdown: {
supportHtml: true,
- }
+ },
};
const client = new lc.LanguageClient(
- 'rust-analyzer',
- 'Rust Analyzer Language Server',
+ "rust-analyzer",
+ "Rust Analyzer Language Server",
serverOptions,
- clientOptions,
+ clientOptions
);
// To turn on all proposed features use: client.registerProposedFeatures();
@@ -196,20 +243,26 @@ class ExperimentalFeatures implements lc.StaticFeature {
"rust-analyzer.showReferences",
"rust-analyzer.gotoLocation",
"editor.action.triggerParameterHints",
- ]
+ ],
};
capabilities.experimental = caps;
}
- initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void {
- }
- dispose(): void {
- }
+ initialize(
+ _capabilities: lc.ServerCapabilities<any>,
+ _documentSelector: lc.DocumentSelector | undefined
+ ): void {}
+ dispose(): void {}
}
function isCodeActionWithoutEditsAndCommands(value: any): boolean {
const candidate: lc.CodeAction = value;
- return candidate && Is.string(candidate.title) &&
- (candidate.diagnostics === void 0 || Is.typedArray(candidate.diagnostics, lc.Diagnostic.is)) &&
+ return (
+ candidate &&
+ Is.string(candidate.title) &&
+ (candidate.diagnostics === void 0 ||
+ Is.typedArray(candidate.diagnostics, lc.Diagnostic.is)) &&
(candidate.kind === void 0 || Is.string(candidate.kind)) &&
- (candidate.edit === void 0 && candidate.command === void 0);
+ candidate.edit === void 0 &&
+ candidate.command === void 0
+ );
}
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index 1e89938c05..ae94ecac6d 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -1,32 +1,33 @@
-import * as vscode from 'vscode';
-import * as lc from 'vscode-languageclient';
-import * as ra from './lsp_ext';
-import * as path from 'path';
-
-import { Ctx, Cmd } from './ctx';
-import { applySnippetWorkspaceEdit, applySnippetTextEdits } from './snippets';
-import { spawnSync } from 'child_process';
-import { RunnableQuickPick, selectRunnable, createTask, createArgs } from './run';
-import { AstInspector } from './ast_inspector';
-import { isRustDocument, isCargoTomlDocument, sleep, isRustEditor } from './util';
-import { startDebugSession, makeDebugConfig } from './debug';
-import { LanguageClient } from 'vscode-languageclient/node';
-
-export * from './ast_inspector';
-export * from './run';
+import * as vscode from "vscode";
+import * as lc from "vscode-languageclient";
+import * as ra from "./lsp_ext";
+import * as path from "path";
+
+import { Ctx, Cmd } from "./ctx";
+import { applySnippetWorkspaceEdit, applySnippetTextEdits } from "./snippets";
+import { spawnSync } from "child_process";
+import { RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
+import { AstInspector } from "./ast_inspector";
+import { isRustDocument, isCargoTomlDocument, sleep, isRustEditor } from "./util";
+import { startDebugSession, makeDebugConfig } from "./debug";
+import { LanguageClient } from "vscode-languageclient/node";
+
+export * from "./ast_inspector";
+export * from "./run";
export function analyzerStatus(ctx: Ctx): Cmd {
- const tdcp = new class implements vscode.TextDocumentContentProvider {
- readonly uri = vscode.Uri.parse('rust-analyzer-status://status');
+ const tdcp = new (class implements vscode.TextDocumentContentProvider {
+ readonly uri = vscode.Uri.parse("rust-analyzer-status://status");
readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> {
- if (!vscode.window.activeTextEditor) return '';
+ if (!vscode.window.activeTextEditor) return "";
const params: ra.AnalyzerStatusParams = {};
const doc = ctx.activeRustEditor?.document;
if (doc != null) {
- params.textDocument = ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(doc);
+ params.textDocument =
+ ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(doc);
}
return ctx.client.sendRequest(ra.analyzerStatus, params);
}
@@ -34,48 +35,42 @@ export function analyzerStatus(ctx: Ctx): Cmd {
get onDidChange(): vscode.Event<vscode.Uri> {
return this.eventEmitter.event;
}
- }();
+ })();
ctx.pushCleanup(
- vscode.workspace.registerTextDocumentContentProvider(
- 'rust-analyzer-status',
- tdcp,
- ),
+ vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-status", tdcp)
);
return async () => {
const document = await vscode.workspace.openTextDocument(tdcp.uri);
tdcp.eventEmitter.fire(tdcp.uri);
- void await vscode.window.showTextDocument(document, {
+ void (await vscode.window.showTextDocument(document, {
viewColumn: vscode.ViewColumn.Two,
- preserveFocus: true
- });
+ preserveFocus: true,
+ }));
};
}
export function memoryUsage(ctx: Ctx): Cmd {
- const tdcp = new class implements vscode.TextDocumentContentProvider {
- readonly uri = vscode.Uri.parse('rust-analyzer-memory://memory');
+ const tdcp = new (class implements vscode.TextDocumentContentProvider {
+ readonly uri = vscode.Uri.parse("rust-analyzer-memory://memory");
readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> {
- if (!vscode.window.activeTextEditor) return '';
+ if (!vscode.window.activeTextEditor) return "";
return ctx.client.sendRequest(ra.memoryUsage).then((mem: any) => {
- return 'Per-query memory usage:\n' + mem + '\n(note: database has been cleared)';
+ return "Per-query memory usage:\n" + mem + "\n(note: database has been cleared)";
});
}
get onDidChange(): vscode.Event<vscode.Uri> {
return this.eventEmitter.event;
}
- }();
+ })();
ctx.pushCleanup(
- vscode.workspace.registerTextDocumentContentProvider(
- 'rust-analyzer-memory',
- tdcp,
- ),
+ vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-memory", tdcp)
);
return async () => {
@@ -101,15 +96,15 @@ export function matchingBrace(ctx: Ctx): Cmd {
if (!editor || !client) return;
const response = await client.sendRequest(ra.matchingBrace, {
- textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
- positions: editor.selections.map(s =>
- client.code2ProtocolConverter.asPosition(s.active),
+ textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(
+ editor.document
+ ),
+ positions: editor.selections.map((s) =>
+ client.code2ProtocolConverter.asPosition(s.active)
),
});
editor.selections = editor.selections.map((sel, idx) => {
- const active = client.protocol2CodeConverter.asPosition(
- response[idx],
- );
+ const active = client.protocol2CodeConverter.asPosition(response[idx]);
const anchor = sel.isEmpty ? active : sel.anchor;
return new vscode.Selection(anchor, active);
});
@@ -125,7 +120,9 @@ export function joinLines(ctx: Ctx): Cmd {
const items: lc.TextEdit[] = await client.sendRequest(ra.joinLines, {
ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)),
- textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
+ textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(
+ editor.document
+ ),
});
await editor.edit(async (builder) => {
(await client.protocol2CodeConverter.asTextEdits(items)).forEach((edit: any) => {
@@ -151,8 +148,10 @@ export function moveItem(ctx: Ctx, direction: ra.Direction): Cmd {
const lcEdits = await client.sendRequest(ra.moveItem, {
range: client.code2ProtocolConverter.asRange(editor.selection),
- textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
- direction
+ textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(
+ editor.document
+ ),
+ direction,
});
if (!lcEdits) return;
@@ -169,15 +168,17 @@ export function onEnter(ctx: Ctx): Cmd {
if (!editor || !client) return false;
- const lcEdits = await client.sendRequest(ra.onEnter, {
- textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
- position: client.code2ProtocolConverter.asPosition(
- editor.selection.active,
- ),
- }).catch((_error: any) => {
- // client.handleFailedRequest(OnEnterRequest.type, error, null);
- return null;
- });
+ const lcEdits = await client
+ .sendRequest(ra.onEnter, {
+ textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(
+ editor.document
+ ),
+ position: client.code2ProtocolConverter.asPosition(editor.selection.active),
+ })
+ .catch((_error: any) => {
+ // client.handleFailedRequest(OnEnterRequest.type, error, null);
+ return null;
+ });
if (!lcEdits) return false;
const edits = await client.protocol2CodeConverter.asTextEdits(lcEdits);
@@ -188,7 +189,7 @@ export function onEnter(ctx: Ctx): Cmd {
return async () => {
if (await handleKeypress()) return;
- await vscode.commands.executeCommand('default:type', { text: '\n' });
+ await vscode.commands.executeCommand("default:type", { text: "\n" });
};
}
@@ -200,10 +201,10 @@ export function parentModule(ctx: Ctx): Cmd {
if (!(isRustDocument(editor.document) || isCargoTomlDocument(editor.document))) return;
const locations = await client.sendRequest(ra.parentModule, {
- textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
- position: client.code2ProtocolConverter.asPosition(
- editor.selection.active,
+ textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(
+ editor.document
),
+ position: client.code2ProtocolConverter.asPosition(editor.selection.active),
});
if (!locations) return;
@@ -220,7 +221,12 @@ export function parentModule(ctx: Ctx): Cmd {
} else {
const uri = editor.document.uri.toString();
const position = client.code2ProtocolConverter.asPosition(editor.selection.active);
- await showReferencesImpl(client, uri, position, locations.map(loc => lc.Location.create(loc.targetUri, loc.targetRange)));
+ await showReferencesImpl(
+ client,
+ uri,
+ position,
+ locations.map((loc) => lc.Location.create(loc.targetUri, loc.targetRange))
+ );
}
};
}
@@ -232,7 +238,9 @@ export function openCargoToml(ctx: Ctx): Cmd {
if (!editor || !client) return;
const response = await client.sendRequest(ra.openCargoToml, {
- textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
+ textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(
+ editor.document
+ ),
});
if (!response) return;
@@ -254,7 +262,9 @@ export function ssr(ctx: Ctx): Cmd {
const position = editor.selection.active;
const selections = editor.selections;
- const textDocument = ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document);
+ const textDocument = ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(
+ editor.document
+ );
const options: vscode.InputBoxOptions = {
value: "() ==>> ()",
@@ -262,28 +272,41 @@ export function ssr(ctx: Ctx): Cmd {
validateInput: async (x: string) => {
try {
await client.sendRequest(ra.ssr, {
- query: x, parseOnly: true, textDocument, position, selections,
+ query: x,
+ parseOnly: true,
+ textDocument,
+ position,
+ selections,
});
} catch (e) {
return e.toString();
}
return null;
- }
+ },
};
const request = await vscode.window.showInputBox(options);
if (!request) return;
- await vscode.window.withProgress({
- location: vscode.ProgressLocation.Notification,
- title: "Structured search replace in progress...",
- cancellable: false,
- }, async (_progress, token) => {
- const edit = await client.sendRequest(ra.ssr, {
- query: request, parseOnly: false, textDocument, position, selections,
- });
-
- await vscode.workspace.applyEdit(await client.protocol2CodeConverter.asWorkspaceEdit(edit, token));
- });
+ await vscode.window.withProgress(
+ {
+ location: vscode.ProgressLocation.Notification,
+ title: "Structured search replace in progress...",
+ cancellable: false,
+ },
+ async (_progress, token) => {
+ const edit = await client.sendRequest(ra.ssr, {
+ query: request,
+ parseOnly: false,
+ textDocument,
+ position,
+ selections,
+ });
+
+ await vscode.workspace.applyEdit(
+ await client.protocol2CodeConverter.asWorkspaceEdit(edit, token)
+ );
+ }
+ );
};
}
@@ -292,17 +315,17 @@ export function serverVersion(ctx: Ctx): Cmd {
const { stdout } = spawnSync(ctx.serverPath, ["--version"], { encoding: "utf8" });
const versionString = stdout.slice(`rust-analyzer `.length).trim();
- void vscode.window.showInformationMessage(
- `rust-analyzer version: ${versionString}`
- );
+ void vscode.window.showInformationMessage(`rust-analyzer version: ${versionString}`);
};
}
export function toggleInlayHints(_ctx: Ctx): Cmd {
return async () => {
- const config = vscode.workspace.getConfiguration("editor.inlayHints", { languageId: "rust" });
+ const config = vscode.workspace.getConfiguration("editor.inlayHints", {
+ languageId: "rust",
+ });
const value = !config.get("enabled");
- await config.update('enabled', value, vscode.ConfigurationTarget.Global);
+ await config.update("enabled", value, vscode.ConfigurationTarget.Global);
};
}
@@ -310,12 +333,20 @@ export function toggleInlayHints(_ctx: Ctx): Cmd {
//
// The contents of the file come from the `TextDocumentContentProvider`
export function syntaxTree(ctx: Ctx): Cmd {
- const tdcp = new class implements vscode.TextDocumentContentProvider {
- readonly uri = vscode.Uri.parse('rust-analyzer://syntaxtree/tree.rast');
+ const tdcp = new (class implements vscode.TextDocumentContentProvider {
+ readonly uri = vscode.Uri.parse("rust-analyzer://syntaxtree/tree.rast");
readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
constructor() {
- vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
- vscode.window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor, this, ctx.subscriptions);
+ vscode.workspace.onDidChangeTextDocument(
+ this.onDidChangeTextDocument,
+ this,
+ ctx.subscriptions
+ );
+ vscode.window.onDidChangeActiveTextEditor(
+ this.onDidChangeActiveTextEditor,
+ this,
+ ctx.subscriptions
+ );
}
private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
@@ -331,47 +362,51 @@ export function syntaxTree(ctx: Ctx): Cmd {
}
}
- provideTextDocumentContent(uri: vscode.Uri, ct: vscode.CancellationToken): vscode.ProviderResult<string> {
+ provideTextDocumentContent(
+ uri: vscode.Uri,
+ ct: vscode.CancellationToken
+ ): vscode.ProviderResult<string> {
const rustEditor = ctx.activeRustEditor;
- if (!rustEditor) return '';
+ if (!rustEditor) return "";
// When the range based query is enabled we take the range of the selection
- const range = uri.query === 'range=true' && !rustEditor.selection.isEmpty
- ? ctx.client.code2ProtocolConverter.asRange(rustEditor.selection)
- : null;
+ const range =
+ uri.query === "range=true" && !rustEditor.selection.isEmpty
+ ? ctx.client.code2ProtocolConverter.asRange(rustEditor.selection)
+ : null;
- const params = { textDocument: { uri: rustEditor.document.uri.toString() }, range, };
+ const params = { textDocument: { uri: rustEditor.document.uri.toString() }, range };
return ctx.client.sendRequest(ra.syntaxTree, params, ct);
}
get onDidChange(): vscode.Event<vscode.Uri> {
return this.eventEmitter.event;
}
- };
+ })();
void new AstInspector(ctx);
- ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider('rust-analyzer', tdcp));
- ctx.pushCleanup(vscode.languages.setLanguageConfiguration("ra_syntax_tree", {
- brackets: [["[", ")"]],
- }));
+ ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider("rust-analyzer", tdcp));
+ ctx.pushCleanup(
+ vscode.languages.setLanguageConfiguration("ra_syntax_tree", {
+ brackets: [["[", ")"]],
+ })
+ );
return async () => {
const editor = vscode.window.activeTextEditor;
const rangeEnabled = !!editor && !editor.selection.isEmpty;
- const uri = rangeEnabled
- ? vscode.Uri.parse(`${tdcp.uri.toString()}?range=true`)
- : tdcp.uri;
+ const uri = rangeEnabled ? vscode.Uri.parse(`${tdcp.uri.toString()}?range=true`) : tdcp.uri;
const document = await vscode.workspace.openTextDocument(uri);
tdcp.eventEmitter.fire(uri);
- void await vscode.window.showTextDocument(document, {
+ void (await vscode.window.showTextDocument(document, {
viewColumn: vscode.ViewColumn.Two,
- preserveFocus: true
- });
+ preserveFocus: true,
+ }));
};
}
@@ -379,12 +414,20 @@ export function syntaxTree(ctx: Ctx): Cmd {
//
// The contents of the file come from the `TextDocumentContentProvider`
export function viewHir(ctx: Ctx): Cmd {
- const tdcp = new class implements vscode.TextDocumentContentProvider {
- readonly uri = vscode.Uri.parse('rust-analyzer://viewHir/hir.txt');
+ const tdcp = new (class implements vscode.TextDocumentContentProvider {
+ readonly uri = vscode.Uri.parse("rust-analyzer://viewHir/hir.txt");
readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
constructor() {
- vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
- vscode.window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor, this, ctx.subscriptions);
+ vscode.workspace.onDidChangeTextDocument(
+ this.onDidChangeTextDocument,
+ this,
+ ctx.subscriptions
+ );
+ vscode.window.onDidChangeActiveTextEditor(
+ this.onDidChangeActiveTextEditor,
+ this,
+ ctx.subscriptions
+ );
}
private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
@@ -400,16 +443,19 @@ export function viewHir(ctx: Ctx): Cmd {
}
}
- provideTextDocumentContent(_uri: vscode.Uri, ct: vscode.CancellationToken): vscode.ProviderResult<string> {
+ provideTextDocumentContent(
+ _uri: vscode.Uri,
+ ct: vscode.CancellationToken
+ ): vscode.ProviderResult<string> {
const rustEditor = ctx.activeRustEditor;
const client = ctx.client;
- if (!rustEditor || !client) return '';
+ if (!rustEditor || !client) return "";
const params = {
- textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(rustEditor.document),
- position: client.code2ProtocolConverter.asPosition(
- rustEditor.selection.active,
+ textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(
+ rustEditor.document
),
+ position: client.code2ProtocolConverter.asPosition(rustEditor.selection.active),
};
return client.sendRequest(ra.viewHir, params, ct);
}
@@ -417,27 +463,35 @@ export function viewHir(ctx: Ctx): Cmd {
get onDidChange(): vscode.Event<vscode.Uri> {
return this.eventEmitter.event;
}
- };
+ })();
- ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider('rust-analyzer', tdcp));
+ ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider("rust-analyzer", tdcp));
return async () => {
const document = await vscode.workspace.openTextDocument(tdcp.uri);
tdcp.eventEmitter.fire(tdcp.uri);
- void await vscode.window.showTextDocument(document, {
+ void (await vscode.window.showTextDocument(document, {
viewColumn: vscode.ViewColumn.Two,
- preserveFocus: true
- });
+ preserveFocus: true,
+ }));
};
}
export function viewFileText(ctx: Ctx): Cmd {
- const tdcp = new class implements vscode.TextDocumentContentProvider {
- readonly uri = vscode.Uri.parse('rust-analyzer://viewFileText/file.rs');
+ const tdcp = new (class implements vscode.TextDocumentContentProvider {
+ readonly uri = vscode.Uri.parse("rust-analyzer://viewFileText/file.rs");
readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
constructor() {
- vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
- vscode.window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor, this, ctx.subscriptions);
+ vscode.workspace.onDidChangeTextDocument(
+ this.onDidChangeTextDocument,
+ this,
+ ctx.subscriptions
+ );
+ vscode.window.onDidChangeActiveTextEditor(
+ this.onDidChangeActiveTextEditor,
+ this,
+ ctx.subscriptions
+ );
}
private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
@@ -453,39 +507,52 @@ export function viewFileText(ctx: Ctx): Cmd {
}
}
- provideTextDocumentContent(_uri: vscode.Uri, ct: vscode.CancellationToken): vscode.ProviderResult<string> {
+ provideTextDocumentContent(
+ _uri: vscode.Uri,
+ ct: vscode.CancellationToken
+ ): vscode.ProviderResult<string> {
const rustEditor = ctx.activeRustEditor;
const client = ctx.client;
- if (!rustEditor || !client) return '';
+ if (!rustEditor || !client) return "";
- const params = client.code2ProtocolConverter.asTextDocumentIdentifier(rustEditor.document);
+ const params = client.code2ProtocolConverter.asTextDocumentIdentifier(
+ rustEditor.document
+ );
return client.sendRequest(ra.viewFileText, params, ct);
}
get onDidChange(): vscode.Event<vscode.Uri> {
return this.eventEmitter.event;
}
- };
+ })();
- ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider('rust-analyzer', tdcp));
+ ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider("rust-analyzer", tdcp));
return async () => {
const document = await vscode.workspace.openTextDocument(tdcp.uri);
tdcp.eventEmitter.fire(tdcp.uri);
- void await vscode.window.showTextDocument(document, {
+ void (await vscode.window.showTextDocument(document, {
viewColumn: vscode.ViewColumn.Two,
- preserveFocus: true
- });
+ preserveFocus: true,
+ }));
};
}
export function viewItemTree(ctx: Ctx): Cmd {
- const tdcp = new class implements vscode.TextDocumentContentProvider {
- readonly uri = vscode.Uri.parse('rust-analyzer://viewItemTree/itemtree.rs');
+ const tdcp = new (class implements vscode.TextDocumentContentProvider {
+ readonly uri = vscode.Uri.parse("rust-analyzer://viewItemTree/itemtree.rs");
readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
constructor() {
- vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
- vscode.window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor, this, ctx.subscriptions);
+ vscode.workspace.onDidChangeTextDocument(
+ this.onDidChangeTextDocument,
+ this,
+ ctx.subscriptions
+ );
+ vscode.window.onDidChangeActiveTextEditor(
+ this.onDidChangeActiveTextEditor,
+ this,
+ ctx.subscriptions
+ );
}
private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
@@ -501,13 +568,18 @@ export function viewItemTree(ctx: Ctx): Cmd {
}
}
- provideTextDocumentContent(_uri: vscode.Uri, ct: vscode.CancellationToken): vscode.ProviderResult<string> {
+ provideTextDocumentContent(
+ _uri: vscode.Uri,
+ ct: vscode.CancellationToken
+ ): vscode.ProviderResult<string> {
const rustEditor = ctx.activeRustEditor;
const client = ctx.client;
- if (!rustEditor || !client) return '';
+ if (!rustEditor || !client) return "";
const params = {
- textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(rustEditor.document),
+ textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(
+ rustEditor.document
+ ),
};
return client.sendRequest(ra.viewItemTree, params, ct);
}
@@ -515,17 +587,17 @@ export function viewItemTree(ctx: Ctx): Cmd {
get onDidChange(): vscode.Event<vscode.Uri> {
return this.eventEmitter.event;
}
- };
+ })();
- ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider('rust-analyzer', tdcp));
+ ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider("rust-analyzer", tdcp));
return async () => {
const document = await vscode.workspace.openTextDocument(tdcp.uri);
tdcp.eventEmitter.fire(tdcp.uri);
- void await vscode.window.showTextDocument(document, {
+ void (await vscode.window.showTextDocument(document, {
viewColumn: vscode.ViewColumn.Two,
- preserveFocus: true
- });
+ preserveFocus: true,
+ }));
};
}
@@ -533,11 +605,16 @@ function crateGraph(ctx: Ctx, full: boolean): Cmd {
return async () => {
const nodeModulesPath = vscode.Uri.file(path.join(ctx.extensionPath, "node_modules"));
- const panel = vscode.window.createWebviewPanel("rust-analyzer.crate-graph", "rust-analyzer crate graph", vscode.ViewColumn.Two, {
- enableScripts: true,
- retainContextWhenHidden: true,
- localResourceRoots: [nodeModulesPath]
- });
+ const panel = vscode.window.createWebviewPanel(
+ "rust-analyzer.crate-graph",
+ "rust-analyzer crate graph",
+ vscode.ViewColumn.Two,
+ {
+ enableScripts: true,
+ retainContextWhenHidden: true,
+ localResourceRoots: [nodeModulesPath],
+ }
+ );
const params = {
full: full,
};
@@ -601,29 +678,31 @@ export function viewFullCrateGraph(ctx: Ctx): Cmd {
export function expandMacro(ctx: Ctx): Cmd {
function codeFormat(expanded: ra.ExpandedMacro): string {
let result = `// Recursive expansion of ${expanded.name}! macro\n`;
- result += '// ' + '='.repeat(result.length - 3);
- result += '\n\n';
+ result += "// " + "=".repeat(result.length - 3);
+ result += "\n\n";
result += expanded.expansion;
return result;
}
- const tdcp = new class implements vscode.TextDocumentContentProvider {
- uri = vscode.Uri.parse('rust-analyzer://expandMacro/[EXPANSION].rs');
+ const tdcp = new (class implements vscode.TextDocumentContentProvider {
+ uri = vscode.Uri.parse("rust-analyzer://expandMacro/[EXPANSION].rs");
eventEmitter = new vscode.EventEmitter<vscode.Uri>();
async provideTextDocumentContent(_uri: vscode.Uri): Promise<string> {
const editor = vscode.window.activeTextEditor;
const client = ctx.client;
- if (!editor || !client) return '';
+ if (!editor || !client) return "";
const position = editor.selection.active;
const expanded = await client.sendRequest(ra.expandMacro, {
- textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
+ textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(
+ editor.document
+ ),
position,
});
- if (expanded == null) return 'Not available';
+ if (expanded == null) return "Not available";
return codeFormat(expanded);
}
@@ -631,23 +710,14 @@ export function expandMacro(ctx: Ctx): Cmd {
get onDidChange(): vscode.Event<vscode.Uri> {
return this.eventEmitter.event;
}
- }();
+ })();
- ctx.pushCleanup(
- vscode.workspace.registerTextDocumentContentProvider(
- 'rust-analyzer',
- tdcp,
- ),
- );
+ ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider("rust-analyzer", tdcp));
return async () => {
const document = await vscode.workspace.openTextDocument(tdcp.uri);
tdcp.eventEmitter.fire(tdcp.uri);
- return vscode.window.showTextDocument(
- document,
- vscode.ViewColumn.Two,
- true,
- );
+ return vscode.window.showTextDocument(document, vscode.ViewColumn.Two, true);
};
}
@@ -655,13 +725,18 @@ export function reloadWorkspace(ctx: Ctx): Cmd {
return async () => ctx.client.sendRequest(ra.reloadWorkspace);
}
-async function showReferencesImpl(client: LanguageClient, uri: string, position: lc.Position, locations: lc.Location[]) {
+async function showReferencesImpl(
+ client: LanguageClient,
+ uri: string,
+ position: lc.Position,
+ locations: lc.Location[]
+) {
if (client) {
await vscode.commands.executeCommand(
- 'editor.action.showReferences',
+ "editor.action.showReferences",
vscode.Uri.parse(uri),
client.protocol2CodeConverter.asPosition(position),
- locations.map(client.protocol2CodeConverter.asLocation),
+ locations.map(client.protocol2CodeConverter.asLocation)
);
}
}
@@ -677,8 +752,8 @@ export function applyActionGroup(_ctx: Ctx): Cmd {
const selectedAction = await vscode.window.showQuickPick(actions);
if (!selectedAction) return;
await vscode.commands.executeCommand(
- 'rust-analyzer.resolveCodeAction',
- selectedAction.arguments,
+ "rust-analyzer.resolveCodeAction",
+ selectedAction.arguments
);
};
}
@@ -699,12 +774,11 @@ export function gotoLocation(ctx: Ctx): Cmd {
export function openDocs(ctx: Ctx): Cmd {
return async () => {
-
const client = ctx.client;
const editor = vscode.window.activeTextEditor;
if (!editor || !client) {
return;
- };
+ }
const position = editor.selection.active;
const textDocument = { uri: editor.document.uri.toString() };
@@ -715,7 +789,6 @@ export function openDocs(ctx: Ctx): Cmd {
await vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(doclink));
}
};
-
}
export function resolveCodeAction(ctx: Ctx): Cmd {
@@ -730,8 +803,13 @@ export function resolveCodeAction(ctx: Ctx): Cmd {
const edit = await client.protocol2CodeConverter.asWorkspaceEdit(itemEdit);
// filter out all text edits and recreate the WorkspaceEdit without them so we can apply
// snippet edits on our own
- const lcFileSystemEdit = { ...itemEdit, documentChanges: itemEdit.documentChanges?.filter(change => "kind" in change) };
- const fileSystemEdit = await client.protocol2CodeConverter.asWorkspaceEdit(lcFileSystemEdit);
+ const lcFileSystemEdit = {
+ ...itemEdit,
+ documentChanges: itemEdit.documentChanges?.filter((change) => "kind" in change),
+ };
+ const fileSystemEdit = await client.protocol2CodeConverter.asWorkspaceEdit(
+ lcFileSystemEdit
+ );
await vscode.workspace.applyEdit(fileSystemEdit);
await applySnippetWorkspaceEdit(edit);
if (item.command != null) {
@@ -753,7 +831,7 @@ export function run(ctx: Ctx): Cmd {
const item = await selectRunnable(ctx, prevRunnable);
if (!item) return;
- item.detail = 'rerun';
+ item.detail = "rerun";
prevRunnable = item;
const task = await createTask(item.runnable, ctx.config);
return await vscode.tasks.executeTask(task);
@@ -767,29 +845,33 @@ export function peekTests(ctx: Ctx): Cmd {
const editor = ctx.activeRustEditor;
if (!editor || !client) return;
- await vscode.window.withProgress({
- location: vscode.ProgressLocation.Notification,
- title: "Looking for tests...",
- cancellable: false,
- }, async (_progress, _token) => {
- const uri = editor.document.uri.toString();
- const position = client.code2ProtocolConverter.asPosition(
- editor.selection.active,
- );
-
- const tests = await client.sendRequest(ra.relatedTests, {
- textDocument: { uri: uri },
- position: position,
- });
- const locations: lc.Location[] = tests.map(it =>
- lc.Location.create(it.runnable.location!.targetUri, it.runnable.location!.targetSelectionRange));
-
- await showReferencesImpl(client, uri, position, locations);
- });
+ await vscode.window.withProgress(
+ {
+ location: vscode.ProgressLocation.Notification,
+ title: "Looking for tests...",
+ cancellable: false,
+ },
+ async (_progress, _token) => {
+ const uri = editor.document.uri.toString();
+ const position = client.code2ProtocolConverter.asPosition(editor.selection.active);
+
+ const tests = await client.sendRequest(ra.relatedTests, {
+ textDocument: { uri: uri },
+ position: position,
+ });
+ const locations: lc.Location[] = tests.map((it) =>
+ lc.Location.create(
+ it.runnable.location!.targetUri,
+ it.runnable.location!.targetSelectionRange
+ )
+ );
+
+ await showReferencesImpl(client, uri, position, locations);
+ }
+ );
};
}
-
export function runSingle(ctx: Ctx): Cmd {
return async (runnable: ra.Runnable) => {
const editor = ctx.activeRustEditor;
@@ -826,7 +908,7 @@ export function debug(ctx: Ctx): Cmd {
const item = await selectRunnable(ctx, prevDebuggee, true);
if (!item) return;
- item.detail = 'restart';
+ item.detail = "restart";
prevDebuggee = item;
return await startDebugSession(ctx, item.runnable);
};
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 9837fd16f5..592ebe0ce3 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -1,13 +1,16 @@
-import path = require('path');
-import * as vscode from 'vscode';
-import { Env } from './client';
+import path = require("path");
+import * as vscode from "vscode";
+import { Env } from "./client";
import { log } from "./util";
export type UpdatesChannel = "stable" | "nightly";
const NIGHTLY_TAG = "nightly";
-export type RunnableEnvCfg = undefined | Record<string, string> | { mask?: string; env: Record<string, string> }[];
+export type RunnableEnvCfg =
+ | undefined
+ | Record<string, string>
+ | { mask?: string; env: Record<string, string> }[];
export class Config {
readonly extensionId = "rust-lang.rust-analyzer";
@@ -20,8 +23,7 @@ export class Config {
"procMacro",
"files",
"lens", // works as lens.*
- ]
- .map(opt => `${this.rootSection}.${opt}`);
+ ].map((opt) => `${this.rootSection}.${opt}`);
readonly package: {
version: string;
@@ -33,7 +35,11 @@ export class Config {
constructor(ctx: vscode.ExtensionContext) {
this.globalStorageUri = ctx.globalStorageUri;
- vscode.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, ctx.subscriptions);
+ vscode.workspace.onDidChangeConfiguration(
+ this.onDidChangeConfiguration,
+ this,
+ ctx.subscriptions
+ );
this.refreshLogging();
}
@@ -48,8 +54,8 @@ export class Config {
private async onDidChangeConfiguration(event: vscode.ConfigurationChangeEvent) {
this.refreshLogging();
- const requiresReloadOpt = this.requiresReloadOpts.find(
- opt => event.affectsConfiguration(opt)
+ const requiresReloadOpt = this.requiresReloadOpts.find((opt) =>
+ event.affectsConfiguration(opt)
);
if (!requiresReloadOpt) return;
@@ -94,8 +100,12 @@ export class Config {
get serverPath() {
return this.get<null | string>("server.path") ?? this.get<null | string>("serverPath");
}
- get serverExtraEnv() { return this.get<Env | null>("server.extraEnv") ?? {}; }
- get traceExtension() { return this.get<boolean>("trace.extension"); }
+ get serverExtraEnv() {
+ return this.get<Env | null>("server.extraEnv") ?? {};
+ }
+ get traceExtension() {
+ return this.get<boolean>("trace.extension");
+ }
get cargoRunner() {
return this.get<string | undefined>("cargoRunner");
@@ -109,7 +119,8 @@ export class Config {
let sourceFileMap = this.get<Record<string, string> | "auto">("debug.sourceFileMap");
if (sourceFileMap !== "auto") {
// "/rustc/<id>" used by suggestions only.
- const { ["/rustc/<id>"]: _, ...trimmed } = this.get<Record<string, string>>("debug.sourceFileMap");
+ const { ["/rustc/<id>"]: _, ...trimmed } =
+ this.get<Record<string, string>>("debug.sourceFileMap");
sourceFileMap = trimmed;
}
@@ -117,7 +128,7 @@ export class Config {
engine: this.get<string>("debug.engine"),
engineSettings: this.get<object>("debug.engineSettings"),
openDebugPane: this.get<boolean>("debug.openDebugPane"),
- sourceFileMap: sourceFileMap
+ sourceFileMap: sourceFileMap,
};
}
@@ -139,57 +150,69 @@ export class Config {
export async function updateConfig(config: vscode.WorkspaceConfiguration) {
const renames = [
- ["assist.allowMergingIntoGlobImports", "imports.merge.glob",],
- ["assist.exprFillDefault", "assist.expressionFillDefault",],
- ["assist.importEnforceGranularity", "imports.granularity.enforce",],
- ["assist.importGranularity", "imports.granularity.group",],
- ["assist.importMergeBehavior", "imports.granularity.group",],
- ["assist.importMergeBehaviour", "imports.granularity.group",],
- ["assist.importGroup", "imports.group.enable",],
- ["assist.importPrefix", "imports.prefix",],
- ["primeCaches.enable", "cachePriming.enable",],
- ["cache.warmup", "cachePriming.enable",],
- ["cargo.loadOutDirsFromCheck", "cargo.buildScripts.enable",],
- ["cargo.runBuildScripts", "cargo.buildScripts.enable",],
- ["cargo.runBuildScriptsCommand", "cargo.buildScripts.overrideCommand",],
- ["cargo.useRustcWrapperForBuildScripts", "cargo.buildScripts.useRustcWrapper",],
- ["completion.snippets", "completion.snippets.custom",],
- ["diagnostics.enableExperimental", "diagnostics.experimental.enable",],
- ["experimental.procAttrMacros", "procMacro.attributes.enable",],
- ["highlighting.strings", "semanticHighlighting.strings.enable",],
- ["highlightRelated.breakPoints", "highlightRelated.breakPoints.enable",],
- ["highlightRelated.exitPoints", "highlightRelated.exitPoints.enable",],
- ["highlightRelated.yieldPoints", "highlightRelated.yieldPoints.enable",],
- ["highlightRelated.references", "highlightRelated.references.enable",],
- ["hover.documentation", "hover.documentation.enable",],
- ["hover.linksInHover", "hover.links.enable",],
- ["hoverActions.linksInHover", "hover.links.enable",],
- ["hoverActions.debug", "hover.actions.debug.enable",],
- ["hoverActions.enable", "hover.actions.enable.enable",],
- ["hoverActions.gotoTypeDef", "hover.actions.gotoTypeDef.enable",],
- ["hoverActions.implementations", "hover.actions.implementations.enable",],
- ["hoverActions.references", "hover.actions.references.enable",],
- ["hoverActions.run", "hover.actions.run.enable",],
- ["inlayHints.chainingHints", "inlayHints.chainingHints.enable",],
- ["inlayHints.closureReturnTypeHints", "inlayHints.closureReturnTypeHints.enable",],
- ["inlayHints.hideNamedConstructorHints", "inlayHints.typeHints.hideNamedConstructor",],
- ["inlayHints.parameterHints", "inlayHints.parameterHints.enable",],
- ["inlayHints.reborrowHints", "inlayHints.reborrowHints.enable",],
- ["inlayHints.typeHints", "inlayHints.typeHints.enable",],
- ["lruCapacity", "lru.capacity",],
- ["runnables.cargoExtraArgs", "runnables.extraArgs",],
- ["runnables.overrideCargo", "runnables.command",],
- ["rustcSource", "rustc.source",],
- ["rustfmt.enableRangeFormatting", "rustfmt.rangeFormatting.enable"]
+ ["assist.allowMergingIntoGlobImports", "imports.merge.glob"],
+ ["assist.exprFillDefault", "assist.expressionFillDefault"],
+ ["assist.importEnforceGranularity", "imports.granularity.enforce"],
+ ["assist.importGranularity", "imports.granularity.group"],
+ ["assist.importMergeBehavior", "imports.granularity.group"],
+ ["assist.importMergeBehaviour", "imports.granularity.group"],
+ ["assist.importGroup", "imports.group.enable"],
+ ["assist.importPrefix", "imports.prefix"],
+ ["primeCaches.enable", "cachePriming.enable"],
+ ["cache.warmup", "cachePriming.enable"],
+ ["cargo.loadOutDirsFromCheck", "cargo.buildScripts.enable"],
+ ["cargo.runBuildScripts", "cargo.buildScripts.enable"],
+ ["cargo.runBuildScriptsCommand", "cargo.buildScripts.overrideCommand"],
+ ["cargo.useRustcWrapperForBuildScripts", "cargo.buildScripts.useRustcWrapper"],
+ ["completion.snippets", "completion.snippets.custom"],
+ ["diagnostics.enableExperimental", "diagnostics.experimental.enable"],
+ ["experimental.procAttrMacros", "procMacro.attributes.enable"],
+ ["highlighting.strings", "semanticHighlighting.strings.enable"],
+ ["highlightRelated.breakPoints", "highlightRelated.breakPoints.enable"],
+ ["highlightRelated.exitPoints", "highlightRelated.exitPoints.enable"],
+ ["highlightRelated.yieldPoints", "highlightRelated.yieldPoints.enable"],
+ ["highlightRelated.references", "highlightRelated.references.enable"],
+ ["hover.documentation", "hover.documentation.enable"],
+ ["hover.linksInHover", "hover.links.enable"],
+ ["hoverActions.linksInHover", "hover.links.enable"],
+ ["hoverActions.debug", "hover.actions.debug.enable"],
+ ["hoverActions.enable", "hover.actions.enable.enable"],
+ ["hoverActions.gotoTypeDef", "hover.actions.gotoTypeDef.enable"],
+ ["hoverActions.implementations", "hover.actions.implementations.enable"],
+ ["hoverActions.references", "hover.actions.references.enable"],
+ ["hoverActions.run", "hover.actions.run.enable"],
+ ["inlayHints.chainingHints", "inlayHints.chainingHints.enable"],
+ ["inlayHints.closureReturnTypeHints", "inlayHints.closureReturnTypeHints.enable"],
+ ["inlayHints.hideNamedConstructorHints", "inlayHints.typeHints.hideNamedConstructor"],
+ ["inlayHints.parameterHints", "inlayHints.parameterHints.enable"],
+ ["inlayHints.reborrowHints", "inlayHints.reborrowHints.enable"],
+ ["inlayHints.typeHints", "inlayHints.typeHints.enable"],
+ ["lruCapacity", "lru.capacity"],
+ ["runnables.cargoExtraArgs", "runnables.extraArgs"],
+ ["runnables.overrideCargo", "runnables.command"],
+ ["rustcSource", "rustc.source"],
+ ["rustfmt.enableRangeFormatting", "rustfmt.rangeFormatting.enable"],
];
for (const [oldKey, newKey] of renames) {
const inspect = config.inspect(oldKey);
if (inspect !== undefined) {
const valMatrix = [
- { val: inspect.globalValue, langVal: inspect.globalLanguageValue, target: vscode.ConfigurationTarget.Global },
- { val: inspect.workspaceFolderValue, langVal: inspect.workspaceFolderLanguageValue, target: vscode.ConfigurationTarget.WorkspaceFolder },
- { val: inspect.workspaceValue, langVal: inspect.workspaceLanguageValue, target: vscode.ConfigurationTarget.Workspace }
+ {
+ val: inspect.globalValue,
+ langVal: inspect.globalLanguageValue,
+ target: vscode.ConfigurationTarget.Global,
+ },
+ {
+ val: inspect.workspaceFolderValue,
+ langVal: inspect.workspaceFolderLanguageValue,
+ target: vscode.ConfigurationTarget.WorkspaceFolder,
+ },
+ {
+ val: inspect.workspaceValue,
+ langVal: inspect.workspaceLanguageValue,
+ target: vscode.ConfigurationTarget.Workspace,
+ },
];
for (const { val, langVal, target } of valMatrix) {
const pred = (val: unknown) => {
@@ -197,7 +220,14 @@ export async function updateConfig(config: vscode.WorkspaceConfiguration) {
// that means on the next run we would find these again, but as objects with
// these properties causing us to destroy the config
// so filter those already updated ones out
- return val !== undefined && !(typeof val === "object" && val !== null && (val.hasOwnProperty("enable") || val.hasOwnProperty("custom")));
+ return (
+ val !== undefined &&
+ !(
+ typeof val === "object" &&
+ val !== null &&
+ (val.hasOwnProperty("enable") || val.hasOwnProperty("custom"))
+ )
+ );
};
if (pred(val)) {
await config.update(newKey, val, target, false);
@@ -216,48 +246,50 @@ export function substituteVariablesInEnv(env: Env): Env {
const missingDeps = new Set<string>();
// vscode uses `env:ENV_NAME` for env vars resolution, and it's easier
// to follow the same convention for our dependency tracking
- const definedEnvKeys = new Set(Object.keys(env).map(key => `env:${key}`));
- const envWithDeps = Object.fromEntries(Object.entries(env).map(([key, value]) => {
- const deps = new Set<string>();
- const depRe = new RegExp(/\${(?<depName>.+?)}/g);
- let match = undefined;
- while ((match = depRe.exec(value))) {
- const depName = match.groups!.depName;
- deps.add(depName);
- // `depName` at this point can have a form of `expression` or
- // `prefix:expression`
- if (!definedEnvKeys.has(depName)) {
- missingDeps.add(depName);
+ const definedEnvKeys = new Set(Object.keys(env).map((key) => `env:${key}`));
+ const envWithDeps = Object.fromEntries(
+ Object.entries(env).map(([key, value]) => {
+ const deps = new Set<string>();
+ const depRe = new RegExp(/\${(?<depName>.+?)}/g);
+ let match = undefined;
+ while ((match = depRe.exec(value))) {
+ const depName = match.groups!.depName;
+ deps.add(depName);
+ // `depName` at this point can have a form of `expression` or
+ // `prefix:expression`
+ if (!definedEnvKeys.has(depName)) {
+ missingDeps.add(depName);
+ }
}
- }
- return [`env:${key}`, { deps: [...deps], value }];
- }));
+ return [`env:${key}`, { deps: [...deps], value }];
+ })
+ );
const resolved = new Set<string>();
for (const dep of missingDeps) {
const match = /(?<prefix>.*?):(?<body>.+)/.exec(dep);
if (match) {
const { prefix, body } = match.groups!;
- if (prefix === 'env') {
+ if (prefix === "env") {
const envName = body;
envWithDeps[dep] = {
- value: process.env[envName] ?? '',
- deps: []
+ value: process.env[envName] ?? "",
+ deps: [],
};
resolved.add(dep);
} else {
// we can't handle other prefixes at the moment
// leave values as is, but still mark them as resolved
envWithDeps[dep] = {
- value: '${' + dep + '}',
- deps: []
+ value: "${" + dep + "}",
+ deps: [],
};
resolved.add(dep);
}
} else {
envWithDeps[dep] = {
value: computeVscodeVar(dep),
- deps: []
+ deps: [],
};
}
}
@@ -267,11 +299,13 @@ export function substituteVariablesInEnv(env: Env): Env {
do {
leftToResolveSize = toResolve.size;
for (const key of toResolve) {
- if (envWithDeps[key].deps.every(dep => resolved.has(dep))) {
+ if (envWithDeps[key].deps.every((dep) => resolved.has(dep))) {
envWithDeps[key].value = envWithDeps[key].value.replace(
- /\${(?<depName>.+?)}/g, (_wholeMatch, depName) => {
+ /\${(?<depName>.+?)}/g,
+ (_wholeMatch, depName) => {
return envWithDeps[depName].value;
- });
+ }
+ );
resolved.add(key);
toResolve.delete(key);
}
@@ -302,16 +336,16 @@ function computeVscodeVar(varName: string): string {
return folders[0].uri.fsPath;
} else {
// no workspace opened
- return '';
+ return "";
}
},
workspaceFolderBasename: () => {
- const workspaceFolder = computeVscodeVar('workspaceFolder');
+ const workspaceFolder = computeVscodeVar("workspaceFolder");
if (workspaceFolder) {
return path.basename(workspaceFolder);
} else {
- return '';
+ return "";
}
},
@@ -323,13 +357,13 @@ function computeVscodeVar(varName: string): string {
// https://github.com/microsoft/vscode/blob/29eb316bb9f154b7870eb5204ec7f2e7cf649bec/src/vs/server/node/remoteTerminalChannel.ts#L56
execPath: () => process.env.VSCODE_EXEC_PATH ?? process.execPath,
- pathSeparator: () => path.sep
+ pathSeparator: () => path.sep,
};
if (varName in supportedVariables) {
return supportedVariables[varName]();
} else {
// can't resolve, keep the expression as is
- return '${' + varName + '}';
+ return "${" + varName + "}";
}
}
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index 0c3e6810e9..fb2268f89f 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -1,20 +1,20 @@
-import * as vscode from 'vscode';
-import * as lc from 'vscode-languageclient/node';
-import * as ra from './lsp_ext';
+import * as vscode from "vscode";
+import * as lc from "vscode-languageclient/node";
+import * as ra from "./lsp_ext";
-import { Config } from './config';
-import { createClient } from './client';
-import { isRustEditor, RustEditor } from './util';
-import { ServerStatusParams } from './lsp_ext';
+import { Config } from "./config";
+import { createClient } from "./client";
+import { isRustEditor, RustEditor } from "./util";
+import { ServerStatusParams } from "./lsp_ext";
export type Workspace =
- {
- kind: 'Workspace Folder';
- }
| {
- kind: 'Detached Files';
- files: vscode.TextDocument[];
- };
+ kind: "Workspace Folder";
+ }
+ | {
+ kind: "Detached Files";
+ files: vscode.TextDocument[];
+ };
export class Ctx {
private constructor(
@@ -22,16 +22,14 @@ export class Ctx {
private readonly extCtx: vscode.ExtensionContext,
readonly client: lc.LanguageClient,
readonly serverPath: string,
- readonly statusBar: vscode.StatusBarItem,
- ) {
-
- }
+ readonly statusBar: vscode.StatusBarItem
+ ) {}
static async create(
config: Config,
extCtx: vscode.ExtensionContext,
serverPath: string,
- workspace: Workspace,
+ workspace: Workspace
): Promise<Ctx> {
const client = await createClient(serverPath, workspace, config.serverExtraEnv);
@@ -52,9 +50,7 @@ export class Ctx {
get activeRustEditor(): RustEditor | undefined {
const editor = vscode.window.activeTextEditor;
- return editor && isRustEditor(editor)
- ? editor
- : undefined;
+ return editor && isRustEditor(editor) ? editor : undefined;
}
get visibleRustEditors(): RustEditor[] {
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts
index 830980f968..1f06c99576 100644
--- a/editors/code/src/debug.ts
+++ b/editors/code/src/debug.ts
@@ -1,14 +1,19 @@
import * as os from "os";
-import * as vscode from 'vscode';
-import * as path from 'path';
-import * as ra from './lsp_ext';
+import * as vscode from "vscode";
+import * as path from "path";
+import * as ra from "./lsp_ext";
-import { Cargo, getRustcId, getSysroot } from './toolchain';
+import { Cargo, getRustcId, getSysroot } from "./toolchain";
import { Ctx } from "./ctx";
import { prepareEnv } from "./run";
const debugOutput = vscode.window.createOutputChannel("Debug");
-type DebugConfigProvider = (config: ra.Runnable, executable: string, env: Record<string, string>, sourceFileMap?: Record<string, string>) => vscode.DebugConfiguration;
+type DebugConfigProvider = (
+ config: ra.Runnable,
+ executable: string,
+ env: Record<string, string>,
+ sourceFileMap?: Record<string, string>
+) => vscode.DebugConfiguration;
export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise<void> {
const scope = ctx.activeRustEditor?.document.uri;
@@ -20,9 +25,13 @@ export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise<
const wsLaunchSection = vscode.workspace.getConfiguration("launch", scope);
const configurations = wsLaunchSection.get<any[]>("configurations") || [];
- const index = configurations.findIndex(c => c.name === debugConfig.name);
+ const index = configurations.findIndex((c) => c.name === debugConfig.name);
if (index !== -1) {
- const answer = await vscode.window.showErrorMessage(`Launch configuration '${debugConfig.name}' already exists!`, 'Cancel', 'Update');
+ const answer = await vscode.window.showErrorMessage(
+ `Launch configuration '${debugConfig.name}' already exists!`,
+ "Cancel",
+ "Update"
+ );
if (answer === "Cancel") return;
configurations[index] = debugConfig;
@@ -40,7 +49,7 @@ export async function startDebugSession(ctx: Ctx, runnable: ra.Runnable): Promis
const wsLaunchSection = vscode.workspace.getConfiguration("launch");
const configurations = wsLaunchSection.get<any[]>("configurations") || [];
- const index = configurations.findIndex(c => c.name === runnable.label);
+ const index = configurations.findIndex((c) => c.name === runnable.label);
if (-1 !== index) {
debugConfig = configurations[index];
message = " (from launch.json)";
@@ -56,13 +65,16 @@ export async function startDebugSession(ctx: Ctx, runnable: ra.Runnable): Promis
return vscode.debug.startDebugging(undefined, debugConfig);
}
-async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<vscode.DebugConfiguration | undefined> {
+async function getDebugConfiguration(
+ ctx: Ctx,
+ runnable: ra.Runnable
+): Promise<vscode.DebugConfiguration | undefined> {
const editor = ctx.activeRustEditor;
if (!editor) return;
const knownEngines: Record<string, DebugConfigProvider> = {
"vadimcn.vscode-lldb": getLldbDebugConfig,
- "ms-vscode.cpptools": getCppvsDebugConfig
+ "ms-vscode.cpptools": getCppvsDebugConfig,
};
const debugOptions = ctx.config.debug;
@@ -77,8 +89,10 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v
}
if (!debugEngine) {
- await vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)`
- + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`);
+ await vscode.window.showErrorMessage(
+ `Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)` +
+ ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`
+ );
return;
}
@@ -91,15 +105,17 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v
const workspaceFolders = vscode.workspace.workspaceFolders!;
const isMultiFolderWorkspace = workspaceFolders.length > 1;
const firstWorkspace = workspaceFolders[0];
- const workspace = !isMultiFolderWorkspace || !runnable.args.workspaceRoot ?
- firstWorkspace :
- workspaceFolders.find(w => runnable.args.workspaceRoot?.includes(w.uri.fsPath)) || firstWorkspace;
+ const workspace =
+ !isMultiFolderWorkspace || !runnable.args.workspaceRoot
+ ? firstWorkspace
+ : workspaceFolders.find((w) => runnable.args.workspaceRoot?.includes(w.uri.fsPath)) ||
+ firstWorkspace;
const wsFolder = path.normalize(workspace.uri.fsPath);
- const workspaceQualifier = isMultiFolderWorkspace ? `:${workspace.name}` : '';
+ const workspaceQualifier = isMultiFolderWorkspace ? `:${workspace.name}` : "";
function simplifyPath(p: string): string {
// see https://github.com/rust-analyzer/rust-analyzer/pull/5513#issuecomment-663458818 for why this is needed
- return path.normalize(p).replace(wsFolder, '${workspaceFolder' + workspaceQualifier + '}');
+ return path.normalize(p).replace(wsFolder, "${workspaceFolder" + workspaceQualifier + "}");
}
const executable = await getDebugExecutable(runnable);
@@ -114,7 +130,12 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v
sourceFileMap[`/rustc/${commitHash}/`] = rustlib;
}
- const debugConfig = knownEngines[debugEngine.id](runnable, simplifyPath(executable), env, sourceFileMap);
+ const debugConfig = knownEngines[debugEngine.id](
+ runnable,
+ simplifyPath(executable),
+ env,
+ sourceFileMap
+ );
if (debugConfig.type in debugOptions.engineSettings) {
const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type];
for (var key in settingsMap) {
@@ -136,14 +157,19 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v
}
async function getDebugExecutable(runnable: ra.Runnable): Promise<string> {
- const cargo = new Cargo(runnable.args.workspaceRoot || '.', debugOutput);
+ const cargo = new Cargo(runnable.args.workspaceRoot || ".", debugOutput);
const executable = await cargo.executableFromArgs(runnable.args.cargoArgs);
// if we are here, there were no compilation errors.
return executable;
}
-function getLldbDebugConfig(runnable: ra.Runnable, executable: string, env: Record<string, string>, sourceFileMap?: Record<string, string>): vscode.DebugConfiguration {
+function getLldbDebugConfig(
+ runnable: ra.Runnable,
+ executable: string,
+ env: Record<string, string>,
+ sourceFileMap?: Record<string, string>
+): vscode.DebugConfiguration {
return {
type: "lldb",
request: "launch",
@@ -153,13 +179,18 @@ function getLldbDebugConfig(runnable: ra.Runnable, executable: string, env: Reco
cwd: runnable.args.workspaceRoot,
sourceMap: sourceFileMap,
sourceLanguages: ["rust"],
- env
+ env,
};
}
-function getCppvsDebugConfig(runnable: ra.Runnable, executable: string, env: Record<string, string>, sourceFileMap?: Record<string, string>): vscode.DebugConfiguration {
+function getCppvsDebugConfig(
+ runnable: ra.Runnable,
+ executable: string,
+ env: Record<string, string>,
+ sourceFileMap?: Record<string, string>
+): vscode.DebugConfiguration {
return {
- type: (os.platform() === "win32") ? "cppvsdbg" : "cppdbg",
+ type: os.platform() === "win32" ? "cppvsdbg" : "cppdbg",
request: "launch",
name: runnable.label,
program: executable,
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
index 61078b58c7..f80af78a74 100644
--- a/editors/code/src/lsp_ext.ts
+++ b/editors/code/src/lsp_ext.ts
@@ -7,7 +7,9 @@ import * as lc from "vscode-languageclient";
export interface AnalyzerStatusParams {
textDocument?: lc.TextDocumentIdentifier;
}
-export const analyzerStatus = new lc.RequestType<AnalyzerStatusParams, string, void>("rust-analyzer/analyzerStatus");
+export const analyzerStatus = new lc.RequestType<AnalyzerStatusParams, string, void>(
+ "rust-analyzer/analyzerStatus"
+);
export const memoryUsage = new lc.RequestType0<string, void>("rust-analyzer/memoryUsage");
export const shuffleCrateGraph = new lc.RequestType0<null, void>("rust-analyzer/shuffleCrateGraph");
@@ -16,7 +18,9 @@ export interface ServerStatusParams {
quiescent: boolean;
message?: string;
}
-export const serverStatus = new lc.NotificationType<ServerStatusParams>("experimental/serverStatus");
+export const serverStatus = new lc.NotificationType<ServerStatusParams>(
+ "experimental/serverStatus"
+);
export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");
@@ -31,23 +35,33 @@ export interface SyntaxTreeParams {
textDocument: lc.TextDocumentIdentifier;
range: lc.Range | null;
}
-export const syntaxTree = new lc.RequestType<SyntaxTreeParams, string, void>("rust-analyzer/syntaxTree");
+export const syntaxTree = new lc.RequestType<SyntaxTreeParams, string, void>(
+ "rust-analyzer/syntaxTree"
+);
-export const viewHir = new lc.RequestType<lc.TextDocumentPositionParams, string, void>("rust-analyzer/viewHir");
+export const viewHir = new lc.RequestType<lc.TextDocumentPositionParams, string, void>(
+ "rust-analyzer/viewHir"
+);
-export const viewFileText = new lc.RequestType<lc.TextDocumentIdentifier, string, void>("rust-analyzer/viewFileText");
+export const viewFileText = new lc.RequestType<lc.TextDocumentIdentifier, string, void>(
+ "rust-analyzer/viewFileText"
+);
export interface ViewItemTreeParams {
textDocument: lc.TextDocumentIdentifier;
}
-export const viewItemTree = new lc.RequestType<ViewItemTreeParams, string, void>("rust-analyzer/viewItemTree");
+export const viewItemTree = new lc.RequestType<ViewItemTreeParams, string, void>(
+ "rust-analyzer/viewItemTree"
+);
export interface ViewCrateGraphParams {
full: boolean;
}
-export const viewCrateGraph = new lc.RequestType<ViewCrateGraphParams, string, void>("rust-analyzer/viewCrateGraph");
+export const viewCrateGraph = new lc.RequestType<ViewCrateGraphParams, string, void>(
+ "rust-analyzer/viewCrateGraph"
+);
export interface ExpandMacroParams {
textDocument: lc.TextDocumentIdentifier;
@@ -57,23 +71,35 @@ export interface ExpandedMacro {
name: string;
expansion: string;
}
-export const expandMacro = new lc.RequestType<ExpandMacroParams, ExpandedMacro | null, void>("rust-analyzer/expandMacro");
+export const expandMacro = new lc.RequestType<ExpandMacroParams, ExpandedMacro | null, void>(
+ "rust-analyzer/expandMacro"
+);
export interface MatchingBraceParams {
textDocument: lc.TextDocumentIdentifier;
positions: lc.Position[];
}
-export const matchingBrace = new lc.RequestType<MatchingBraceParams, lc.Position[], void>("experimental/matchingBrace");
+export const matchingBrace = new lc.RequestType<MatchingBraceParams, lc.Position[], void>(
+ "experimental/matchingBrace"
+);
-export const parentModule = new lc.RequestType<lc.TextDocumentPositionParams, lc.LocationLink[] | null, void>("experimental/parentModule");
+export const parentModule = new lc.RequestType<
+ lc.TextDocumentPositionParams,
+ lc.LocationLink[] | null,
+ void
+>("experimental/parentModule");
export interface JoinLinesParams {
textDocument: lc.TextDocumentIdentifier;
ranges: lc.Range[];
}
-export const joinLines = new lc.RequestType<JoinLinesParams, lc.TextEdit[], void>("experimental/joinLines");
+export const joinLines = new lc.RequestType<JoinLinesParams, lc.TextEdit[], void>(
+ "experimental/joinLines"
+);
-export const onEnter = new lc.RequestType<lc.TextDocumentPositionParams, lc.TextEdit[], void>("experimental/onEnter");
+export const onEnter = new lc.RequestType<lc.TextDocumentPositionParams, lc.TextEdit[], void>(
+ "experimental/onEnter"
+);
export interface RunnablesParams {
textDocument: lc.TextDocumentIdentifier;
@@ -93,13 +119,17 @@ export interface Runnable {
overrideCargo?: string;
};
}
-export const runnables = new lc.RequestType<RunnablesParams, Runnable[], void>("experimental/runnables");
+export const runnables = new lc.RequestType<RunnablesParams, Runnable[], void>(
+ "experimental/runnables"
+);
export interface TestInfo {
runnable: Runnable;
}
-export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, TestInfo[], void>("rust-analyzer/relatedTests");
+export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, TestInfo[], void>(
+ "rust-analyzer/relatedTests"
+);
export interface SsrParams {
query: string;
@@ -108,7 +138,7 @@ export interface SsrParams {
position: lc.Position;
selections: readonly lc.Range[];
}
-export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, void>('experimental/ssr');
+export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, void>("experimental/ssr");
export interface CommandLink extends lc.Command {
/**
@@ -122,15 +152,21 @@ export interface CommandLinkGroup {
commands: CommandLink[];
}
-export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>('experimental/externalDocs');
+export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>(
+ "experimental/externalDocs"
+);
-export const openCargoToml = new lc.RequestType<OpenCargoTomlParams, lc.Location, void>("experimental/openCargoToml");
+export const openCargoToml = new lc.RequestType<OpenCargoTomlParams, lc.Location, void>(
+ "experimental/openCargoToml"
+);
export interface OpenCargoTomlParams {
textDocument: lc.TextDocumentIdentifier;
}
-export const moveItem = new lc.RequestType<MoveItemParams, lc.TextEdit[], void>("experimental/moveItem");
+export const moveItem = new lc.RequestType<MoveItemParams, lc.TextEdit[], void>(
+ "experimental/moveItem"
+);
export interface MoveItemParams {
textDocument: lc.TextDocumentIdentifier;
@@ -140,5 +176,5 @@ export interface MoveItemParams {
export const enum Direction {
Up = "Up",
- Down = "Down"
+ Down = "Down",
}
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 39bd73c663..61824fae21 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -1,15 +1,15 @@
-import * as vscode from 'vscode';
-import * as lc from 'vscode-languageclient/node';
+import * as vscode from "vscode";
+import * as lc from "vscode-languageclient/node";
import * as os from "os";
-import * as commands from './commands';
-import { Ctx } from './ctx';
-import { Config } from './config';
-import { log, isValidExecutable, isRustDocument } from './util';
-import { PersistentState } from './persistent_state';
-import { activateTaskProvider } from './tasks';
-import { setContextValue } from './util';
-import { exec } from 'child_process';
+import * as commands from "./commands";
+import { Ctx } from "./ctx";
+import { Config } from "./config";
+import { log, isValidExecutable, isRustDocument } from "./util";
+import { PersistentState } from "./persistent_state";
+import { activateTaskProvider } from "./tasks";
+import { setContextValue } from "./util";
+import { exec } from "child_process";
let ctx: Ctx | undefined;
@@ -19,10 +19,12 @@ export interface RustAnalyzerExtensionApi {
client: lc.LanguageClient;
}
-export async function activate(context: vscode.ExtensionContext): Promise<RustAnalyzerExtensionApi> {
+export async function activate(
+ context: vscode.ExtensionContext
+): Promise<RustAnalyzerExtensionApi> {
// VS Code doesn't show a notification when an extension fails to activate
// so we do it ourselves.
- return await tryActivate(context).catch(err => {
+ return await tryActivate(context).catch((err) => {
void vscode.window.showErrorMessage(`Cannot activate rust-analyzer: ${err.message}`);
throw err;
});
@@ -31,7 +33,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<RustAn
async function tryActivate(context: vscode.ExtensionContext): Promise<RustAnalyzerExtensionApi> {
const config = new Config(context);
const state = new PersistentState(context.globalState);
- const serverPath = await bootstrap(context, config, state).catch(err => {
+ const serverPath = await bootstrap(context, config, state).catch((err) => {
let message = "bootstrap error. ";
message += 'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically). ';
@@ -42,9 +44,14 @@ async function tryActivate(context: vscode.ExtensionContext): Promise<RustAnalyz
});
if ((vscode.workspace.workspaceFolders || []).length === 0) {
- const rustDocuments = vscode.workspace.textDocuments.filter(document => isRustDocument(document));
+ const rustDocuments = vscode.workspace.textDocuments.filter((document) =>
+ isRustDocument(document)
+ );
if (rustDocuments.length > 0) {
- ctx = await Ctx.create(config, context, serverPath, { kind: 'Detached Files', files: rustDocuments });
+ ctx = await Ctx.create(config, context, serverPath, {
+ kind: "Detached Files",
+ files: rustDocuments,
+ });
} else {
throw new Error("no rust files are opened");
}
@@ -63,13 +70,16 @@ async function tryActivate(context: vscode.ExtensionContext): Promise<RustAnalyz
ctx.pushCleanup(configureLanguage());
vscode.workspace.onDidChangeConfiguration(
- _ => ctx?.client?.sendNotification('workspace/didChangeConfiguration', { settings: "" }).catch(log.error),
+ (_) =>
+ ctx?.client
+ ?.sendNotification("workspace/didChangeConfiguration", { settings: "" })
+ .catch(log.error),
null,
- ctx.subscriptions,
+ ctx.subscriptions
);
return {
- client: ctx.client
+ client: ctx.client,
};
}
@@ -88,9 +98,8 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) {
// "rust-analyzer is not available"
// ),
// )
- const defaultOnEnter = vscode.commands.registerCommand(
- 'rust-analyzer.onEnter',
- () => vscode.commands.executeCommand('default:type', { text: '\n' }),
+ const defaultOnEnter = vscode.commands.registerCommand("rust-analyzer.onEnter", () =>
+ vscode.commands.executeCommand("default:type", { text: "\n" })
);
context.subscriptions.push(defaultOnEnter);
@@ -99,8 +108,8 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) {
// Commands which invokes manually via command palette, shortcut, etc.
// Reloading is inspired by @DanTup maneuver: https://github.com/microsoft/vscode/issues/45774#issuecomment-373423895
- ctx.registerCommand('reload', _ => async () => {
- void vscode.window.showInformationMessage('Reloading rust-analyzer...');
+ ctx.registerCommand("reload", (_) => async () => {
+ void vscode.window.showInformationMessage("Reloading rust-analyzer...");
await deactivate();
while (context.subscriptions.length > 0) {
try {
@@ -112,45 +121,45 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) {
await activate(context).catch(log.error);
});
- ctx.registerCommand('analyzerStatus', commands.analyzerStatus);
- ctx.registerCommand('memoryUsage', commands.memoryUsage);
- ctx.registerCommand('shuffleCrateGraph', commands.shuffleCrateGraph);
- ctx.registerCommand('reloadWorkspace', commands.reloadWorkspace);
- ctx.registerCommand('matchingBrace', commands.matchingBrace);
- ctx.registerCommand('joinLines', commands.joinLines);
- ctx.registerCommand('parentModule', commands.parentModule);
- ctx.registerCommand('syntaxTree', commands.syntaxTree);
- ctx.registerCommand('viewHir', commands.viewHir);
- ctx.registerCommand('viewFileText', commands.viewFileText);
- ctx.registerCommand('viewItemTree', commands.viewItemTree);
- ctx.registerCommand('viewCrateGraph', commands.viewCrateGraph);
- ctx.registerCommand('viewFullCrateGraph', commands.viewFullCrateGraph);
- ctx.registerCommand('expandMacro', commands.expandMacro);
- ctx.registerCommand('run', commands.run);
- ctx.registerCommand('copyRunCommandLine', commands.copyRunCommandLine);
- ctx.registerCommand('debug', commands.debug);
- ctx.registerCommand('newDebugConfig', commands.newDebugConfig);
- ctx.registerCommand('openDocs', commands.openDocs);
- ctx.registerCommand('openCargoToml', commands.openCargoToml);
- ctx.registerCommand('peekTests', commands.peekTests);
- ctx.registerCommand('moveItemUp', commands.moveItemUp);
- ctx.registerCommand('moveItemDown', commands.moveItemDown);
+ ctx.registerCommand("analyzerStatus", commands.analyzerStatus);
+ ctx.registerCommand("memoryUsage", commands.memoryUsage);
+ ctx.registerCommand("shuffleCrateGraph", commands.shuffleCrateGraph);
+ ctx.registerCommand("reloadWorkspace", commands.reloadWorkspace);
+ ctx.registerCommand("matchingBrace", commands.matchingBrace);
+ ctx.registerCommand("joinLines", commands.joinLines);
+ ctx.registerCommand("parentModule", commands.parentModule);
+ ctx.registerCommand("syntaxTree", commands.syntaxTree);
+ ctx.registerCommand("viewHir", commands.viewHir);
+ ctx.registerCommand("viewFileText", commands.viewFileText);
+ ctx.registerCommand("viewItemTree", commands.viewItemTree);
+ ctx.registerCommand("viewCrateGraph", commands.viewCrateGraph);
+ ctx.registerCommand("viewFullCrateGraph", commands.viewFullCrateGraph);
+ ctx.registerCommand("expandMacro", commands.expandMacro);
+ ctx.registerCommand("run", commands.run);
+ ctx.registerCommand("copyRunCommandLine", commands.copyRunCommandLine);
+ ctx.registerCommand("debug", commands.debug);
+ ctx.registerCommand("newDebugConfig", commands.newDebugConfig);
+ ctx.registerCommand("openDocs", commands.openDocs);
+ ctx.registerCommand("openCargoToml", commands.openCargoToml);
+ ctx.registerCommand("peekTests", commands.peekTests);
+ ctx.registerCommand("moveItemUp", commands.moveItemUp);
+ ctx.registerCommand("moveItemDown", commands.moveItemDown);
defaultOnEnter.dispose();
- ctx.registerCommand('onEnter', commands.onEnter);
+ ctx.registerCommand("onEnter", commands.onEnter);
- ctx.registerCommand('ssr', commands.ssr);
- ctx.registerCommand('serverVersion', commands.serverVersion);
- ctx.registerCommand('toggleInlayHints', commands.toggleInlayHints);
+ ctx.registerCommand("ssr", commands.ssr);
+ ctx.registerCommand("serverVersion", commands.serverVersion);
+ ctx.registerCommand("toggleInlayHints", commands.toggleInlayHints);
// Internal commands which are invoked by the server.
- ctx.registerCommand('runSingle', commands.runSingle);
- ctx.registerCommand('debugSingle', commands.debugSingle);
- ctx.registerCommand('showReferences', commands.showReferences);
- ctx.registerCommand('applySnippetWorkspaceEdit', commands.applySnippetWorkspaceEditCommand);
- ctx.registerCommand('resolveCodeAction', commands.resolveCodeAction);
- ctx.registerCommand('applyActionGroup', commands.applyActionGroup);
- ctx.registerCommand('gotoLocation', commands.gotoLocation);
+ ctx.registerCommand("runSingle", commands.runSingle);
+ ctx.registerCommand("debugSingle", commands.debugSingle);
+ ctx.registerCommand("showReferences", commands.showReferences);
+ ctx.registerCommand("applySnippetWorkspaceEdit", commands.applySnippetWorkspaceEditCommand);
+ ctx.registerCommand("resolveCodeAction", commands.resolveCodeAction);
+ ctx.registerCommand("applyActionGroup", commands.applyActionGroup);
+ ctx.registerCommand("gotoLocation", commands.gotoLocation);
}
export async function deactivate() {
@@ -159,12 +168,16 @@ export async function deactivate() {
ctx = undefined;
}
-async function bootstrap(context: vscode.ExtensionContext, config: Config, state: PersistentState): Promise<string> {
+async function bootstrap(
+ context: vscode.ExtensionContext,
+ config: Config,
+ state: PersistentState
+): Promise<string> {
const path = await getServer(context, config, state);
if (!path) {
throw new Error(
"Rust Analyzer Language Server is not available. " +
- "Please, ensure its [proper installation](https://rust-analyzer.github.io/manual.html#installation)."
+ "Please, ensure its [proper installation](https://rust-analyzer.github.io/manual.html#installation)."
);
}
@@ -186,7 +199,7 @@ async function patchelf(dest: vscode.Uri): Promise<void> {
await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
- title: "Patching rust-analyzer for NixOS"
+ title: "Patching rust-analyzer for NixOS",
},
async (progress, _) => {
const expression = `
@@ -207,14 +220,16 @@ async function patchelf(dest: vscode.Uri): Promise<void> {
try {
progress.report({ message: "Patching executable", increment: 20 });
await new Promise((resolve, reject) => {
- const handle = exec(`nix-build -E - --argstr srcStr '${origFile.fsPath}' -o '${dest.fsPath}'`,
+ const handle = exec(
+ `nix-build -E - --argstr srcStr '${origFile.fsPath}' -o '${dest.fsPath}'`,
(err, stdout, stderr) => {
if (err != null) {
reject(Error(stderr));
} else {
resolve(stdout);
}
- });
+ }
+ );
handle.stdin?.write(expression);
handle.stdin?.end();
});
@@ -225,25 +240,35 @@ async function patchelf(dest: vscode.Uri): Promise<void> {
);
}
-async function getServer(context: vscode.ExtensionContext, config: Config, state: PersistentState): Promise<string | undefined> {
+async function getServer(
+ context: vscode.ExtensionContext,
+ config: Config,
+ state: PersistentState
+): Promise<string | undefined> {
const explicitPath = serverPath(config);
if (explicitPath) {
if (explicitPath.startsWith("~/")) {
return os.homedir() + explicitPath.slice("~".length);
}
return explicitPath;
- };
+ }
if (config.package.releaseTag === null) return "rust-analyzer";
const ext = process.platform === "win32" ? ".exe" : "";
const bundled = vscode.Uri.joinPath(context.extensionUri, "server", `rust-analyzer${ext}`);
- const bundledExists = await vscode.workspace.fs.stat(bundled).then(() => true, () => false);
+ const bundledExists = await vscode.workspace.fs.stat(bundled).then(
+ () => true,
+ () => false
+ );
if (bundledExists) {
let server = bundled;
if (await isNixOs()) {
await vscode.workspace.fs.createDirectory(config.globalStorageUri).then();
const dest = vscode.Uri.joinPath(config.globalStorageUri, `rust-analyzer${ext}`);
- let exists = await vscode.workspace.fs.stat(dest).then(() => true, () => false);
+ let exists = await vscode.workspace.fs.stat(dest).then(
+ () => true,
+ () => false
+ );
if (exists && config.package.version !== state.serverVersion) {
await vscode.workspace.fs.delete(dest);
exists = false;
@@ -261,11 +286,11 @@ async function getServer(context: vscode.ExtensionContext, config: Config, state
await state.updateServerVersion(undefined);
await vscode.window.showErrorMessage(
"Unfortunately we don't ship binaries for your platform yet. " +
- "You need to manually clone the rust-analyzer repository and " +
- "run `cargo xtask install --server` to build the language server from sources. " +
- "If you feel that your platform should be supported, please create an issue " +
- "about that [here](https://github.com/rust-analyzer/rust-analyzer/issues) and we " +
- "will consider it."
+ "You need to manually clone the rust-analyzer repository and " +
+ "run `cargo xtask install --server` to build the language server from sources. " +
+ "If you feel that your platform should be supported, please create an issue " +
+ "about that [here](https://github.com/rust-analyzer/rust-analyzer/issues) and we " +
+ "will consider it."
);
return undefined;
}
@@ -276,8 +301,10 @@ function serverPath(config: Config): string | null {
async function isNixOs(): Promise<boolean> {
try {
- const contents = (await vscode.workspace.fs.readFile(vscode.Uri.file("/etc/os-release"))).toString();
- const idString = contents.split('\n').find((a) => a.startsWith("ID=")) || "ID=linux";
+ const contents = (
+ await vscode.workspace.fs.readFile(vscode.Uri.file("/etc/os-release"))
+ ).toString();
+ const idString = contents.split("\n").find((a) => a.startsWith("ID=")) || "ID=linux";
return idString.indexOf("nixos") !== -1;
} catch {
return false;
@@ -286,11 +313,14 @@ async function isNixOs(): Promise<boolean> {
function warnAboutExtensionConflicts() {
if (vscode.extensions.getExtension("rust-lang.rust")) {
- vscode.window.showWarningMessage(
- `You have both the rust-analyzer (rust-lang.rust-analyzer) and Rust (rust-lang.rust) ` +
- "plugins enabled. These are known to conflict and cause various functions of " +
- "both plugins to not work correctly. You should disable one of them.", "Got it")
- .then(() => { }, console.error);
+ vscode.window
+ .showWarningMessage(
+ `You have both the rust-analyzer (rust-lang.rust-analyzer) and Rust (rust-lang.rust) ` +
+ "plugins enabled. These are known to conflict and cause various functions of " +
+ "both plugins to not work correctly. You should disable one of them.",
+ "Got it"
+ )
+ .then(() => {}, console.error);
}
}
@@ -302,38 +332,38 @@ function warnAboutExtensionConflicts() {
*/
function configureLanguage(): vscode.Disposable {
const indentAction = vscode.IndentAction.None;
- return vscode.languages.setLanguageConfiguration('rust', {
+ return vscode.languages.setLanguageConfiguration("rust", {
onEnterRules: [
{
// Doc single-line comment
// e.g. ///|
beforeText: /^\s*\/{3}.*$/,
- action: { indentAction, appendText: '/// ' },
+ action: { indentAction, appendText: "/// " },
},
{
// Parent doc single-line comment
// e.g. //!|
beforeText: /^\s*\/{2}\!.*$/,
- action: { indentAction, appendText: '//! ' },
+ action: { indentAction, appendText: "//! " },
},
{
// Begins an auto-closed multi-line comment (standard or parent doc)
// e.g. /** | */ or /*! | */
beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/,
afterText: /^\s*\*\/$/,
- action: { indentAction: vscode.IndentAction.IndentOutdent, appendText: ' * ' },
+ action: { indentAction: vscode.IndentAction.IndentOutdent, appendText: " * " },
},
{
// Begins a multi-line comment (standard or parent doc)
// e.g. /** ...| or /*! ...|
beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/,
- action: { indentAction, appendText: ' * ' },
+ action: { indentAction, appendText: " * " },
},
{
// Continues a multi-line comment
// e.g. * ...|
beforeText: /^(\ \ )*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
- action: { indentAction, appendText: '* ' },
+ action: { indentAction, appendText: "* " },
},
{
// Dedents after closing a multi-line comment
diff --git a/editors/code/src/persistent_state.ts b/editors/code/src/persistent_state.ts
index 3e86ed1e32..8964a78dc3 100644
--- a/editors/code/src/persistent_state.ts
+++ b/editors/code/src/persistent_state.ts
@@ -1,5 +1,5 @@
-import * as vscode from 'vscode';
-import { log } from './util';
+import * as vscode from "vscode";
+import { log } from "./util";
export class PersistentState {
constructor(private readonly globalState: vscode.Memento) {
diff --git a/editors/code/src/run.ts b/editors/code/src/run.ts
index d0be840686..b3dff3db5d 100644
--- a/editors/code/src/run.ts
+++ b/editors/code/src/run.ts
@@ -1,15 +1,22 @@
-import * as vscode from 'vscode';
-import * as lc from 'vscode-languageclient';
-import * as ra from './lsp_ext';
-import * as tasks from './tasks';
-
-import { Ctx } from './ctx';
-import { makeDebugConfig } from './debug';
-import { Config, RunnableEnvCfg } from './config';
-
-const quickPickButtons = [{ iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configurtation." }];
-
-export async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, debuggeeOnly = false, showButtons: boolean = true): Promise<RunnableQuickPick | undefined> {
+import * as vscode from "vscode";
+import * as lc from "vscode-languageclient";
+import * as ra from "./lsp_ext";
+import * as tasks from "./tasks";
+
+import { Ctx } from "./ctx";
+import { makeDebugConfig } from "./debug";
+import { Config, RunnableEnvCfg } from "./config";
+
+const quickPickButtons = [
+ { iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configurtation." },
+];
+
+export async function selectRunnable(
+ ctx: Ctx,
+ prevRunnable?: RunnableQuickPick,
+ debuggeeOnly = false,
+ showButtons: boolean = true
+): Promise<RunnableQuickPick | undefined> {
const editor = ctx.activeRustEditor;
const client = ctx.client;
if (!editor || !client) return;
@@ -20,23 +27,18 @@ export async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick,
const runnables = await client.sendRequest(ra.runnables, {
textDocument,
- position: client.code2ProtocolConverter.asPosition(
- editor.selection.active,
- ),
+ position: client.code2ProtocolConverter.asPosition(editor.selection.active),
});
const items: RunnableQuickPick[] = [];
if (prevRunnable) {
items.push(prevRunnable);
}
for (const r of runnables) {
- if (
- prevRunnable &&
- JSON.stringify(prevRunnable.runnable) === JSON.stringify(r)
- ) {
+ if (prevRunnable && JSON.stringify(prevRunnable.runnable) === JSON.stringify(r)) {
continue;
}
- if (debuggeeOnly && (r.label.startsWith('doctest') || r.label.startsWith('cargo'))) {
+ if (debuggeeOnly && (r.label.startsWith("doctest") || r.label.startsWith("cargo"))) {
continue;
}
items.push(new RunnableQuickPick(r));
@@ -53,7 +55,7 @@ export async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick,
const disposables: vscode.Disposable[] = [];
const close = (result?: RunnableQuickPick) => {
resolve(result);
- disposables.forEach(d => d.dispose());
+ disposables.forEach((d) => d.dispose());
};
const quickPick = vscode.window.createQuickPick<RunnableQuickPick>();
@@ -71,7 +73,7 @@ export async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick,
}),
quickPick.onDidChangeActive((active) => {
if (showButtons && active.length > 0) {
- if (active[0].label.startsWith('cargo')) {
+ if (active[0].label.startsWith("cargo")) {
// save button makes no sense for `cargo test` or `cargo check`
quickPick.buttons = [];
} else if (quickPick.buttons.length === 0) {
@@ -96,8 +98,11 @@ export class RunnableQuickPick implements vscode.QuickPickItem {
}
}
-export function prepareEnv(runnable: ra.Runnable, runnableEnvCfg: RunnableEnvCfg): Record<string, string> {
- const env: Record<string, string> = { "RUST_BACKTRACE": "short" };
+export function prepareEnv(
+ runnable: ra.Runnable,
+ runnableEnvCfg: RunnableEnvCfg
+): Record<string, string> {
+ const env: Record<string, string> = { RUST_BACKTRACE: "short" };
if (runnable.args.expectTest) {
env["UPDATE_EXPECT"] = "1";
@@ -141,7 +146,14 @@ export async function createTask(runnable: ra.Runnable, config: Config): Promise
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const target = vscode.workspace.workspaceFolders![0]; // safe, see main activate()
- const cargoTask = await tasks.buildCargoTask(target, definition, runnable.label, args, config.cargoRunner, true);
+ const cargoTask = await tasks.buildCargoTask(
+ target,
+ definition,
+ runnable.label,
+ args,
+ config.cargoRunner,
+ true
+ );
cargoTask.presentationOptions.clear = true;
// Sadly, this doesn't prevent focus stealing if the terminal is currently
@@ -157,7 +169,7 @@ export function createArgs(runnable: ra.Runnable): string[] {
args.push(...runnable.args.cargoExtraArgs); // Append user-specified cargo options.
}
if (runnable.args.executableArgs.length > 0) {
- args.push('--', ...runnable.args.executableArgs);
+ args.push("--", ...runnable.args.executableArgs);
}
return args;
}
diff --git a/editors/code/src/snippets.ts b/editors/code/src/snippets.ts
index a409e52963..299d29c27e 100644
--- a/editors/code/src/snippets.ts
+++ b/editors/code/src/snippets.ts
@@ -1,6 +1,6 @@
-import * as vscode from 'vscode';
+import * as vscode from "vscode";
-import { assert } from './util';
+import { assert } from "./util";
export async function applySnippetWorkspaceEdit(edit: vscode.WorkspaceEdit) {
if (edit.entries().length === 1) {
@@ -11,12 +11,17 @@ export async function applySnippetWorkspaceEdit(edit: vscode.WorkspaceEdit) {
}
for (const [uri, edits] of edit.entries()) {
const editor = await editorFromUri(uri);
- if (editor) await editor.edit((builder) => {
- for (const indel of edits) {
- assert(!parseSnippet(indel.newText), `bad ws edit: snippet received with multiple edits: ${JSON.stringify(edit)}`);
- builder.replace(indel.range, indel.newText);
- }
- });
+ if (editor) {
+ await editor.edit((builder) => {
+ for (const indel of edits) {
+ assert(
+ !parseSnippet(indel.newText),
+ `bad ws edit: snippet received with multiple edits: ${JSON.stringify(edit)}`
+ );
+ builder.replace(indel.range, indel.newText);
+ }
+ });
+ }
}
}
@@ -25,7 +30,9 @@ async function editorFromUri(uri: vscode.Uri): Promise<vscode.TextEditor | undef
// `vscode.window.visibleTextEditors` only contains editors whose contents are being displayed
await vscode.window.showTextDocument(uri, {});
}
- return vscode.window.visibleTextEditors.find((it) => it.document.uri.toString() === uri.toString());
+ return vscode.window.visibleTextEditors.find(
+ (it) => it.document.uri.toString() === uri.toString()
+ );
}
export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vscode.TextEdit[]) {
@@ -37,22 +44,26 @@ export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vs
if (parsed) {
const [newText, [placeholderStart, placeholderLength]] = parsed;
const prefix = newText.substr(0, placeholderStart);
- const lastNewline = prefix.lastIndexOf('\n');
+ const lastNewline = prefix.lastIndexOf("\n");
const startLine = indel.range.start.line + lineDelta + countLines(prefix);
- const startColumn = lastNewline === -1 ?
- indel.range.start.character + placeholderStart
- : prefix.length - lastNewline - 1;
+ const startColumn =
+ lastNewline === -1
+ ? indel.range.start.character + placeholderStart
+ : prefix.length - lastNewline - 1;
const endColumn = startColumn + placeholderLength;
- selections.push(new vscode.Selection(
- new vscode.Position(startLine, startColumn),
- new vscode.Position(startLine, endColumn),
- ));
+ selections.push(
+ new vscode.Selection(
+ new vscode.Position(startLine, startColumn),
+ new vscode.Position(startLine, endColumn)
+ )
+ );
builder.replace(indel.range, newText);
} else {
builder.replace(indel.range, indel.newText);
}
- lineDelta += countLines(indel.newText) - (indel.range.end.line - indel.range.start.line);
+ lineDelta +=
+ countLines(indel.newText) - (indel.range.end.line - indel.range.start.line);
}
});
if (selections.length > 0) editor.selections = selections;
@@ -65,8 +76,7 @@ function parseSnippet(snip: string): [string, [number, number]] | undefined {
const m = snip.match(/\$(0|\{0:([^}]*)\})/);
if (!m) return undefined;
const placeholder = m[2] ?? "";
- if (m.index == null)
- return undefined;
+ if (m.index == null) return undefined;
const range: [number, number] = [m.index, placeholder.length];
const insert = snip.replace(m[0], placeholder);
return [insert, range];
diff --git a/editors/code/src/tasks.ts b/editors/code/src/tasks.ts
index 99edd9ae9d..8aa6bcee19 100644
--- a/editors/code/src/tasks.ts
+++ b/editors/code/src/tasks.ts
@@ -1,12 +1,12 @@
-import * as vscode from 'vscode';
+import * as vscode from "vscode";
import * as toolchain from "./toolchain";
-import { Config } from './config';
-import { log } from './util';
+import { Config } from "./config";
+import { log } from "./util";
// This ends up as the `type` key in tasks.json. RLS also uses `cargo` and
// our configuration should be compatible with it so use the same key.
-export const TASK_TYPE = 'cargo';
-export const TASK_SOURCE = 'rust';
+export const TASK_TYPE = "cargo";
+export const TASK_SOURCE = "rust";
export interface CargoTaskDefinition extends vscode.TaskDefinition {
command?: string;
@@ -30,17 +30,23 @@ class CargoTaskProvider implements vscode.TaskProvider {
// tasks.json - only tweaked.
const defs = [
- { command: 'build', group: vscode.TaskGroup.Build },
- { command: 'check', group: vscode.TaskGroup.Build },
- { command: 'test', group: vscode.TaskGroup.Test },
- { command: 'clean', group: vscode.TaskGroup.Clean },
- { command: 'run', group: undefined },
+ { command: "build", group: vscode.TaskGroup.Build },
+ { command: "check", group: vscode.TaskGroup.Build },
+ { command: "test", group: vscode.TaskGroup.Test },
+ { command: "clean", group: vscode.TaskGroup.Clean },
+ { command: "run", group: undefined },
];
const tasks: vscode.Task[] = [];
for (const workspaceTarget of vscode.workspace.workspaceFolders || []) {
for (const def of defs) {
- const vscodeTask = await buildCargoTask(workspaceTarget, { type: TASK_TYPE, command: def.command }, `cargo ${def.command}`, [def.command], this.config.cargoRunner);
+ const vscodeTask = await buildCargoTask(
+ workspaceTarget,
+ { type: TASK_TYPE, command: def.command },
+ `cargo ${def.command}`,
+ [def.command],
+ this.config.cargoRunner
+ );
vscodeTask.group = def.group;
tasks.push(vscodeTask);
}
@@ -58,7 +64,13 @@ class CargoTaskProvider implements vscode.TaskProvider {
if (definition.type === TASK_TYPE && definition.command) {
const args = [definition.command].concat(definition.args ?? []);
- return await buildCargoTask(task.scope, definition, task.name, args, this.config.cargoRunner);
+ return await buildCargoTask(
+ task.scope,
+ definition,
+ task.name,
+ args,
+ this.config.cargoRunner
+ );
}
return undefined;
@@ -73,7 +85,6 @@ export async function buildCargoTask(
customRunner?: string,
throwOnError: boolean = false
): Promise<vscode.Task> {
-
let exec: vscode.ProcessExecution | vscode.ShellExecution | undefined = undefined;
if (customRunner) {
@@ -90,7 +101,6 @@ export async function buildCargoTask(
}
}
// fallback to default processing
-
} catch (e) {
if (throwOnError) throw `Cargo runner '${customRunner}' failed! ${e}`;
// fallback to default processing
@@ -117,7 +127,7 @@ export async function buildCargoTask(
name,
TASK_SOURCE,
exec,
- ['$rustc']
+ ["$rustc"]
);
}
diff --git a/editors/code/src/toolchain.ts b/editors/code/src/toolchain.ts
index 681932c93b..c23a9a8d9e 100644
--- a/editors/code/src/toolchain.ts
+++ b/editors/code/src/toolchain.ts
@@ -1,9 +1,9 @@
-import * as cp from 'child_process';
-import * as os from 'os';
-import * as path from 'path';
-import * as readline from 'readline';
-import * as vscode from 'vscode';
-import { execute, log, memoizeAsync } from './util';
+import * as cp from "child_process";
+import * as os from "os";
+import * as path from "path";
+import * as readline from "readline";
+import * as vscode from "vscode";
+import { execute, log, memoizeAsync } from "./util";
interface CompilationArtifact {
fileName: string;
@@ -18,7 +18,7 @@ export interface ArtifactSpec {
}
export class Cargo {
- constructor(readonly rootFolder: string, readonly output: vscode.OutputChannel) { }
+ constructor(readonly rootFolder: string, readonly output: vscode.OutputChannel) {}
// Made public for testing purposes
static artifactSpec(args: readonly string[]): ArtifactSpec {
@@ -27,7 +27,9 @@ export class Cargo {
// arguments for a runnable from the quick pick should be updated.
// see crates\rust-analyzer\src\main_loop\handlers.rs, handle_code_lens
switch (cargoArgs[0]) {
- case "run": cargoArgs[0] = "build"; break;
+ case "run":
+ cargoArgs[0] = "build";
+ break;
case "test": {
if (!cargoArgs.includes("--no-run")) {
cargoArgs.push("--no-run");
@@ -40,7 +42,7 @@ export class Cargo {
if (cargoArgs[0] === "test") {
// for instance, `crates\rust-analyzer\tests\heavy_tests\main.rs` tests
// produce 2 artifacts: {"kind": "bin"} and {"kind": "test"}
- result.filter = (artifacts) => artifacts.filter(it => it.isTest);
+ result.filter = (artifacts) => artifacts.filter((it) => it.isTest);
}
return result;
@@ -50,24 +52,25 @@ export class Cargo {
const artifacts: CompilationArtifact[] = [];
try {
- await this.runCargo(spec.cargoArgs,
- message => {
- if (message.reason === 'compiler-artifact' && message.executable) {
- const isBinary = message.target.crate_types.includes('bin');
- const isBuildScript = message.target.kind.includes('custom-build');
+ await this.runCargo(
+ spec.cargoArgs,
+ (message) => {
+ if (message.reason === "compiler-artifact" && message.executable) {
+ const isBinary = message.target.crate_types.includes("bin");
+ const isBuildScript = message.target.kind.includes("custom-build");
if ((isBinary && !isBuildScript) || message.profile.test) {
artifacts.push({
fileName: message.executable,
name: message.target.name,
kind: message.target.kind[0],
- isTest: message.profile.test
+ isTest: message.profile.test,
});
}
- } else if (message.reason === 'compiler-message') {
+ } else if (message.reason === "compiler-message") {
this.output.append(message.message.rendered);
}
},
- stderr => this.output.append(stderr),
+ (stderr) => this.output.append(stderr)
);
} catch (err) {
this.output.show(true);
@@ -81,9 +84,9 @@ export class Cargo {
const artifacts = await this.getArtifacts(Cargo.artifactSpec(args));
if (artifacts.length === 0) {
- throw new Error('No compilation artifacts');
+ throw new Error("No compilation artifacts");
} else if (artifacts.length > 1) {
- throw new Error('Multiple compilation artifacts are not supported.');
+ throw new Error("Multiple compilation artifacts are not supported.");
}
return artifacts[0].fileName;
@@ -97,25 +100,23 @@ export class Cargo {
const path = await cargoPath();
return await new Promise((resolve, reject) => {
const cargo = cp.spawn(path, cargoArgs, {
- stdio: ['ignore', 'pipe', 'pipe'],
- cwd: this.rootFolder
+ stdio: ["ignore", "pipe", "pipe"],
+ cwd: this.rootFolder,
});
- cargo.on('error', err => reject(new Error(`could not launch cargo: ${err}`)));
+ cargo.on("error", (err) => reject(new Error(`could not launch cargo: ${err}`)));
- cargo.stderr.on('data', chunk => onStderrString(chunk.toString()));
+ cargo.stderr.on("data", (chunk) => onStderrString(chunk.toString()));
const rl = readline.createInterface({ input: cargo.stdout });
- rl.on('line', line => {
+ rl.on("line", (line) => {
const message = JSON.parse(line);
onStdoutJson(message);
});
- cargo.on('exit', (exitCode, _) => {
- if (exitCode === 0)
- resolve(exitCode);
- else
- reject(new Error(`exit code: ${exitCode}.`));
+ cargo.on("exit", (exitCode, _) => {
+ if (exitCode === 0) resolve(exitCode);
+ else reject(new Error(`exit code: ${exitCode}.`));
});
});
}
@@ -158,7 +159,12 @@ export const getPathForExecutable = memoizeAsync(
try {
// hmm, `os.homedir()` seems to be infallible
// it is not mentioned in docs and cannot be infered by the type signature...
- const standardPath = vscode.Uri.joinPath(vscode.Uri.file(os.homedir()), ".cargo", "bin", executableName);
+ const standardPath = vscode.Uri.joinPath(
+ vscode.Uri.file(os.homedir()),
+ ".cargo",
+ "bin",
+ executableName
+ );
if (await isFileAtUri(standardPath)) return standardPath.fsPath;
} catch (err) {
@@ -169,13 +175,11 @@ export const getPathForExecutable = memoizeAsync(
);
async function lookupInPath(exec: string): Promise<boolean> {
- const paths = process.env.PATH ?? "";;
+ const paths = process.env.PATH ?? "";
- const candidates = paths.split(path.delimiter).flatMap(dirInPath => {
+ const candidates = paths.split(path.delimiter).flatMap((dirInPath) => {
const candidate = path.join(dirInPath, exec);
- return os.type() === "Windows_NT"
- ? [candidate, `${candidate}.exe`]
- : [candidate];
+ return os.type() === "Windows_NT" ? [candidate, `${candidate}.exe`] : [candidate];
});
for await (const isFile of candidates.map(isFileAtPath)) {
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index 057a3d2e19..cd91932bb6 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -13,7 +13,7 @@ export function assert(condition: boolean, explanation: string): asserts conditi
}
}
-export const log = new class {
+export const log = new (class {
private enabled = true;
private readonly output = vscode.window.createOutputChannel("Rust Analyzer Client");
@@ -55,21 +55,20 @@ export const log = new class {
depth: 6, // heuristic
});
}
-};
+})();
export async function sendRequestWithRetry<TParam, TRet>(
client: lc.LanguageClient,
reqType: lc.RequestType<TParam, TRet, unknown>,
param: TParam,
- token?: vscode.CancellationToken,
+ token?: vscode.CancellationToken
): Promise<TRet> {
// The sequence is `10 * (2 ** (2 * n))` where n is 1, 2, 3...
for (const delay of [40, 160, 640, 2560, 10240, null]) {
try {
return await (token
? client.sendRequest(reqType, param, token)
- : client.sendRequest(reqType, param)
- );
+ : client.sendRequest(reqType, param));
} catch (error) {
if (delay === null) {
log.warn("LSP request timed out", { method: reqType.method, param, error });
@@ -86,11 +85,11 @@ export async function sendRequestWithRetry<TParam, TRet>(
await sleep(delay);
}
}
- throw 'unreachable';
+ throw "unreachable";
}
export function sleep(ms: number) {
- return new Promise(resolve => setTimeout(resolve, ms));
+ return new Promise((resolve) => setTimeout(resolve, ms));
}
export type RustDocument = vscode.TextDocument & { languageId: "rust" };
@@ -101,12 +100,12 @@ export function isRustDocument(document: vscode.TextDocument): document is RustD
// by allowing only `file` schemes
// unfortunately extensions that use diff views not always set this
// to something different than 'file' (see ongoing bug: #4608)
- return document.languageId === 'rust' && document.uri.scheme === 'file';
+ return document.languageId === "rust" && document.uri.scheme === "file";
}
export function isCargoTomlDocument(document: vscode.TextDocument): document is RustDocument {
// ideally `document.languageId` should be 'toml' but user maybe not have toml extension installed
- return document.uri.scheme === 'file' && document.fileName.endsWith('Cargo.toml');
+ return document.uri.scheme === "file" && document.fileName.endsWith("Cargo.toml");
}
export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor {
@@ -116,9 +115,9 @@ export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor {
export function isValidExecutable(path: string): boolean {
log.debug("Checking availability of a binary at", path);
- const res = spawnSync(path, ["--version"], { encoding: 'utf8' });
+ const res = spawnSync(path, ["--version"], { encoding: "utf8" });
- const printOutput = res.error && (res.error as any).code !== 'ENOENT' ? log.warn : log.debug;
+ const printOutput = res.error && (res.error as any).code !== "ENOENT" ? log.warn : log.debug;
printOutput(path, "--version:", res);
return res.status === 0;
@@ -126,17 +125,19 @@ export function isValidExecutable(path: string): boolean {
/** Sets ['when'](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts) clause contexts */
export function setContextValue(key: string, value: any): Thenable<void> {
- return vscode.commands.executeCommand('setContext', key, value);
+ return vscode.commands.executeCommand("setContext", key, value);
}
/**
* Returns a higher-order function that caches the results of invoking the
* underlying async function.
*/
-export function memoizeAsync<Ret, TThis, Param extends string>(func: (this: TThis, arg: Param) => Promise<Ret>) {
+export function memoizeAsync<Ret, TThis, Param extends string>(
+ func: (this: TThis, arg: Param) => Promise<Ret>
+) {
const cache = new Map<string, Ret>();
- return async function(this: TThis, arg: Param) {
+ return async function (this: TThis, arg: Param) {
const cached = cache.get(arg);
if (cached) return cached;
diff --git a/editors/code/tests/runTests.ts b/editors/code/tests/runTests.ts
index 6172cc7d5f..08632ec3b4 100644
--- a/editors/code/tests/runTests.ts
+++ b/editors/code/tests/runTests.ts
@@ -1,43 +1,43 @@
-import * as path from 'path';
-import * as fs from 'fs';
+import * as path from "path";
+import * as fs from "fs";
-import { runTests } from '@vscode/test-electron';
+import { runTests } from "@vscode/test-electron";
async function main() {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
- const extensionDevelopmentPath = path.resolve(__dirname, '../../');
+ const extensionDevelopmentPath = path.resolve(__dirname, "../../");
// Minimum supported version.
- const jsonData = fs.readFileSync(path.join(extensionDevelopmentPath, 'package.json'));
+ const jsonData = fs.readFileSync(path.join(extensionDevelopmentPath, "package.json"));
const json = JSON.parse(jsonData.toString());
let minimalVersion: string = json.engines.vscode;
- if (minimalVersion.startsWith('^')) minimalVersion = minimalVersion.slice(1);
+ if (minimalVersion.startsWith("^")) minimalVersion = minimalVersion.slice(1);
const launchArgs = ["--disable-extensions", extensionDevelopmentPath];
// All test suites (either unit tests or integration tests) should be in subfolders.
- const extensionTestsPath = path.resolve(__dirname, './unit/index');
+ const extensionTestsPath = path.resolve(__dirname, "./unit/index");
// Run tests using the minimal supported version.
await runTests({
version: minimalVersion,
launchArgs,
extensionDevelopmentPath,
- extensionTestsPath
+ extensionTestsPath,
});
// and the latest one
await runTests({
- version: 'stable',
+ version: "stable",
launchArgs,
extensionDevelopmentPath,
- extensionTestsPath
+ extensionTestsPath,
});
}
-main().catch(err => {
+main().catch((err) => {
// eslint-disable-next-line no-console
- console.error('Failed to run tests', err);
+ console.error("Failed to run tests", err);
process.exit(1);
});
diff --git a/editors/code/tests/unit/index.ts b/editors/code/tests/unit/index.ts
index 288bd60326..2fa223bed4 100644
--- a/editors/code/tests/unit/index.ts
+++ b/editors/code/tests/unit/index.ts
@@ -1,5 +1,5 @@
-import { readdir } from 'fs/promises';
-import * as path from 'path';
+import { readdir } from "fs/promises";
+import * as path from "path";
class Test {
readonly name: string;
@@ -59,7 +59,9 @@ export class Context {
export async function run(): Promise<void> {
const context = new Context();
- const testFiles = (await readdir(path.resolve(__dirname))).filter(name => name.endsWith('.test.js'));
+ const testFiles = (await readdir(path.resolve(__dirname))).filter((name) =>
+ name.endsWith(".test.js")
+ );
for (const testFile of testFiles) {
try {
const testModule = require(path.resolve(__dirname, testFile));
diff --git a/editors/code/tests/unit/launch_config.test.ts b/editors/code/tests/unit/launch_config.test.ts
index aa7a6be269..0531e064d2 100644
--- a/editors/code/tests/unit/launch_config.test.ts
+++ b/editors/code/tests/unit/launch_config.test.ts
@@ -1,51 +1,98 @@
-import * as assert from 'assert';
-import { Cargo } from '../../src/toolchain';
-import { Context } from '.';
+import * as assert from "assert";
+import { Cargo } from "../../src/toolchain";
+import { Context } from ".";
export async function getTests(ctx: Context) {
- await ctx.suite('Launch configuration/Lens', suite => {
- suite.addTest('A binary', async () => {
- const args = Cargo.artifactSpec(["build", "--package", "pkg_name", "--bin", "pkg_name"]);
+ await ctx.suite("Launch configuration/Lens", (suite) => {
+ suite.addTest("A binary", async () => {
+ const args = Cargo.artifactSpec([
+ "build",
+ "--package",
+ "pkg_name",
+ "--bin",
+ "pkg_name",
+ ]);
- assert.deepStrictEqual(args.cargoArgs, ["build", "--package", "pkg_name", "--bin", "pkg_name", "--message-format=json"]);
+ assert.deepStrictEqual(args.cargoArgs, [
+ "build",
+ "--package",
+ "pkg_name",
+ "--bin",
+ "pkg_name",
+ "--message-format=json",
+ ]);
assert.deepStrictEqual(args.filter, undefined);
});
- suite.addTest('One of Multiple Binaries', async () => {
+ suite.addTest("One of Multiple Binaries", async () => {
const args = Cargo.artifactSpec(["build", "--package", "pkg_name", "--bin", "bin1"]);
- assert.deepStrictEqual(args.cargoArgs, ["build", "--package", "pkg_name", "--bin", "bin1", "--message-format=json"]);
+ assert.deepStrictEqual(args.cargoArgs, [
+ "build",
+ "--package",
+ "pkg_name",
+ "--bin",
+ "bin1",
+ "--message-format=json",
+ ]);
assert.deepStrictEqual(args.filter, undefined);
});
- suite.addTest('A test', async () => {
+ suite.addTest("A test", async () => {
const args = Cargo.artifactSpec(["test", "--package", "pkg_name", "--lib", "--no-run"]);
- assert.deepStrictEqual(args.cargoArgs, ["test", "--package", "pkg_name", "--lib", "--no-run", "--message-format=json"]);
+ assert.deepStrictEqual(args.cargoArgs, [
+ "test",
+ "--package",
+ "pkg_name",
+ "--lib",
+ "--no-run",
+ "--message-format=json",
+ ]);
assert.notDeepStrictEqual(args.filter, undefined);
});
});
- await ctx.suite('Launch configuration/QuickPick', suite => {
- suite.addTest('A binary', async () => {
+ await ctx.suite("Launch configuration/QuickPick", (suite) => {
+ suite.addTest("A binary", async () => {
const args = Cargo.artifactSpec(["run", "--package", "pkg_name", "--bin", "pkg_name"]);
- assert.deepStrictEqual(args.cargoArgs, ["build", "--package", "pkg_name", "--bin", "pkg_name", "--message-format=json"]);
+ assert.deepStrictEqual(args.cargoArgs, [
+ "build",
+ "--package",
+ "pkg_name",
+ "--bin",
+ "pkg_name",
+ "--message-format=json",
+ ]);
assert.deepStrictEqual(args.filter, undefined);
});
-
- suite.addTest('One of Multiple Binaries', async () => {
+ suite.addTest("One of Multiple Binaries", async () => {
const args = Cargo.artifactSpec(["run", "--package", "pkg_name", "--bin", "bin2"]);
- assert.deepStrictEqual(args.cargoArgs, ["build", "--package", "pkg_name", "--bin", "bin2", "--message-format=json"]);
+ assert.deepStrictEqual(args.cargoArgs, [
+ "build",
+ "--package",
+ "pkg_name",
+ "--bin",
+ "bin2",
+ "--message-format=json",
+ ]);
assert.deepStrictEqual(args.filter, undefined);
});
- suite.addTest('A test', async () => {
+ suite.addTest("A test", async () => {
const args = Cargo.artifactSpec(["test", "--package", "pkg_name", "--lib"]);
- assert.deepStrictEqual(args.cargoArgs, ["test", "--package", "pkg_name", "--lib", "--message-format=json", "--no-run"]);
+ assert.deepStrictEqual(args.cargoArgs, [
+ "test",
+ "--package",
+ "pkg_name",
+ "--lib",
+ "--message-format=json",
+ "--no-run",
+ ]);
assert.notDeepStrictEqual(args.filter, undefined);
});
});
diff --git a/editors/code/tests/unit/runnable_env.test.ts b/editors/code/tests/unit/runnable_env.test.ts
index 085c96da92..b7d59e399d 100644
--- a/editors/code/tests/unit/runnable_env.test.ts
+++ b/editors/code/tests/unit/runnable_env.test.ts
@@ -1,8 +1,8 @@
-import * as assert from 'assert';
-import { prepareEnv } from '../../src/run';
-import { RunnableEnvCfg } from '../../src/config';
-import { Context } from '.';
-import * as ra from '../../src/lsp_ext';
+import * as assert from "assert";
+import { prepareEnv } from "../../src/run";
+import { RunnableEnvCfg } from "../../src/config";
+import { Context } from ".";
+import * as ra from "../../src/lsp_ext";
function makeRunnable(label: string): ra.Runnable {
return {
@@ -11,8 +11,8 @@ function makeRunnable(label: string): ra.Runnable {
args: {
cargoArgs: [],
executableArgs: [],
- cargoExtraArgs: []
- }
+ cargoExtraArgs: [],
+ },
};
}
@@ -22,20 +22,20 @@ function fakePrepareEnv(runnableName: string, config: RunnableEnvCfg): Record<st
}
export async function getTests(ctx: Context) {
- await ctx.suite('Runnable env', suite => {
- suite.addTest('Global config works', async () => {
- const binEnv = fakePrepareEnv("run project_name", { "GLOBAL": "g" });
+ await ctx.suite("Runnable env", (suite) => {
+ suite.addTest("Global config works", async () => {
+ const binEnv = fakePrepareEnv("run project_name", { GLOBAL: "g" });
assert.strictEqual(binEnv["GLOBAL"], "g");
- const testEnv = fakePrepareEnv("test some::mod::test_name", { "GLOBAL": "g" });
+ const testEnv = fakePrepareEnv("test some::mod::test_name", { GLOBAL: "g" });
assert.strictEqual(testEnv["GLOBAL"], "g");
});
- suite.addTest('null mask works', async () => {
+ suite.addTest("null mask works", async () => {
const config = [
{
- env: { DATA: "data" }
- }
+ env: { DATA: "data" },
+ },
];
const binEnv = fakePrepareEnv("run project_name", config);
assert.strictEqual(binEnv["DATA"], "data");
@@ -44,14 +44,14 @@ export async function getTests(ctx: Context) {
assert.strictEqual(testEnv["DATA"], "data");
});
- suite.addTest('order works', async () => {
+ suite.addTest("order works", async () => {
const config = [
{
- env: { DATA: "data" }
+ env: { DATA: "data" },
},
{
- env: { DATA: "newdata" }
- }
+ env: { DATA: "newdata" },
+ },
];
const binEnv = fakePrepareEnv("run project_name", config);
assert.strictEqual(binEnv["DATA"], "newdata");
@@ -60,19 +60,19 @@ export async function getTests(ctx: Context) {
assert.strictEqual(testEnv["DATA"], "newdata");
});
- suite.addTest('mask works', async () => {
+ suite.addTest("mask works", async () => {
const config = [
{
- env: { DATA: "data" }
+ env: { DATA: "data" },
},
{
mask: "^run",
- env: { DATA: "rundata" }
+ env: { DATA: "rundata" },
},
{
mask: "special_test$",
- env: { DATA: "special_test" }
- }
+ env: { DATA: "special_test" },
+ },
];
const binEnv = fakePrepareEnv("run project_name", config);
assert.strictEqual(binEnv["DATA"], "rundata");
@@ -84,15 +84,15 @@ export async function getTests(ctx: Context) {
assert.strictEqual(specialTestEnv["DATA"], "special_test");
});
- suite.addTest('exact test name works', async () => {
+ suite.addTest("exact test name works", async () => {
const config = [
{
- env: { DATA: "data" }
+ env: { DATA: "data" },
},
{
mask: "some::mod::test_name",
- env: { DATA: "test special" }
- }
+ env: { DATA: "test special" },
+ },
];
const testEnv = fakePrepareEnv("test some::mod::test_name", config);
assert.strictEqual(testEnv["DATA"], "test special");
@@ -101,15 +101,15 @@ export async function getTests(ctx: Context) {
assert.strictEqual(specialTestEnv["DATA"], "data");
});
- suite.addTest('test mod name works', async () => {
+ suite.addTest("test mod name works", async () => {
const config = [
{
- env: { DATA: "data" }
+ env: { DATA: "data" },
},
{
mask: "some::mod",
- env: { DATA: "mod special" }
- }
+ env: { DATA: "mod special" },
+ },
];
const testEnv = fakePrepareEnv("test some::mod::test_name", config);
assert.strictEqual(testEnv["DATA"], "mod special");
diff --git a/editors/code/tests/unit/settings.test.ts b/editors/code/tests/unit/settings.test.ts
index dca4e38d13..224cea5a23 100644
--- a/editors/code/tests/unit/settings.test.ts
+++ b/editors/code/tests/unit/settings.test.ts
@@ -1,30 +1,30 @@
-import * as assert from 'assert';
-import { Context } from '.';
-import { substituteVariablesInEnv } from '../../src/config';
+import * as assert from "assert";
+import { Context } from ".";
+import { substituteVariablesInEnv } from "../../src/config";
export async function getTests(ctx: Context) {
- await ctx.suite('Server Env Settings', suite => {
- suite.addTest('Replacing Env Variables', async () => {
+ await ctx.suite("Server Env Settings", (suite) => {
+ suite.addTest("Replacing Env Variables", async () => {
const envJson = {
USING_MY_VAR: "${env:MY_VAR} test ${env:MY_VAR}",
- MY_VAR: "test"
+ MY_VAR: "test",
};
const expectedEnv = {
USING_MY_VAR: "test test test",
- MY_VAR: "test"
+ MY_VAR: "test",
};
const actualEnv = await substituteVariablesInEnv(envJson);
assert.deepStrictEqual(actualEnv, expectedEnv);
});
- suite.addTest('Circular dependencies remain as is', async () => {
+ suite.addTest("Circular dependencies remain as is", async () => {
const envJson = {
A_USES_B: "${env:B_USES_A}",
B_USES_A: "${env:A_USES_B}",
C_USES_ITSELF: "${env:C_USES_ITSELF}",
D_USES_C: "${env:C_USES_ITSELF}",
E_IS_ISOLATED: "test",
- F_USES_E: "${env:E_IS_ISOLATED}"
+ F_USES_E: "${env:E_IS_ISOLATED}",
};
const expectedEnv = {
A_USES_B: "${env:B_USES_A}",
@@ -32,30 +32,30 @@ export async function getTests(ctx: Context) {
C_USES_ITSELF: "${env:C_USES_ITSELF}",
D_USES_C: "${env:C_USES_ITSELF}",
E_IS_ISOLATED: "test",
- F_USES_E: "test"
+ F_USES_E: "test",
};
const actualEnv = await substituteVariablesInEnv(envJson);
assert.deepStrictEqual(actualEnv, expectedEnv);
});
- suite.addTest('Should support external variables', async () => {
+ suite.addTest("Should support external variables", async () => {
const envJson = {
- USING_EXTERNAL_VAR: "${env:TEST_VARIABLE} test ${env:TEST_VARIABLE}"
+ USING_EXTERNAL_VAR: "${env:TEST_VARIABLE} test ${env:TEST_VARIABLE}",
};
const expectedEnv = {
- USING_EXTERNAL_VAR: "test test test"
+ USING_EXTERNAL_VAR: "test test test",
};
const actualEnv = await substituteVariablesInEnv(envJson);
assert.deepStrictEqual(actualEnv, expectedEnv);
});
- suite.addTest('should support VSCode variables', async () => {
+ suite.addTest("should support VSCode variables", async () => {
const envJson = {
- USING_VSCODE_VAR: "${workspaceFolderBasename}"
+ USING_VSCODE_VAR: "${workspaceFolderBasename}",
};
const actualEnv = await substituteVariablesInEnv(envJson);
- assert.deepStrictEqual(actualEnv.USING_VSCODE_VAR, 'code');
+ assert.deepStrictEqual(actualEnv.USING_VSCODE_VAR, "code");
});
});
}
diff --git a/editors/code/tsconfig.eslint.json b/editors/code/tsconfig.eslint.json
index 9eddf27986..5e2b33ca39 100644
--- a/editors/code/tsconfig.eslint.json
+++ b/editors/code/tsconfig.eslint.json
@@ -1,11 +1,11 @@
// Special typescript project file, used by eslint only.
{
- "extends": "./tsconfig.json",
- "include": [
- // repeated from base config's "include" setting
- "src",
- "tests",
- // these are the eslint-only inclusions
- ".eslintrc.js",
- ]
+ "extends": "./tsconfig.json",
+ "include": [
+ // repeated from base config's "include" setting
+ "src",
+ "tests",
+ // these are the eslint-only inclusions
+ ".eslintrc.js"
+ ]
}
diff --git a/editors/code/tsconfig.json b/editors/code/tsconfig.json
index e2ba2f231a..42e2846858 100644
--- a/editors/code/tsconfig.json
+++ b/editors/code/tsconfig.json
@@ -3,9 +3,7 @@
"module": "commonjs",
"target": "es2021",
"outDir": "out",
- "lib": [
- "es2021"
- ],
+ "lib": ["es2021"],
"sourceMap": true,
"rootDir": ".",
"strict": true,
@@ -16,12 +14,6 @@
"noFallthroughCasesInSwitch": true,
"newLine": "LF"
},
- "exclude": [
- "node_modules",
- ".vscode-test"
- ],
- "include": [
- "src",
- "tests"
- ]
+ "exclude": ["node_modules", ".vscode-test"],
+ "include": ["src", "tests"]
}