Skip to content

Commit b7201c0

Browse files
committed
Add onEnterRules for language config
This change provides proper indent/outdent for block comments. Through onEnterRules. Because onEnterRules are not exactly API, I had to use a back door to implement them. Also, it tweaks the language-configuration.json by adding more support for things like word boundaries and auto-closing pairs. Since QL has similar syntactical items as JavaScriot, I started with the JS lang config and removed single quotes and back ticks.
1 parent 8db4885 commit b7201c0

3 files changed

Lines changed: 91 additions & 71 deletions

File tree

Lines changed: 37 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,38 @@
11
{
2-
"comments": {
3-
// symbol used for single line comment. Remove this entry if your language does not support line comments
4-
"lineComment": "//",
5-
// symbols used for start and end a block comment. Remove this entry if your language does not support block comments
6-
"blockComment": [
7-
"/*",
8-
"*/"
9-
]
10-
},
11-
// symbols used as brackets
12-
"brackets": [
13-
[
14-
"{",
15-
"}"
16-
],
17-
[
18-
"[",
19-
"]"
20-
],
21-
[
22-
"(",
23-
")"
24-
]
25-
],
26-
// symbols that are auto closed when typing
27-
"autoClosingPairs": [
28-
[
29-
"{",
30-
"}"
31-
],
32-
[
33-
"[",
34-
"]"
35-
],
36-
[
37-
"(",
38-
")"
39-
],
40-
[
41-
"\"",
42-
"\""
43-
],
44-
[
45-
"'",
46-
"'"
47-
]
48-
],
49-
// symbols that that can be used to surround a selection
50-
"surroundingPairs": [
51-
[
52-
"{",
53-
"}"
54-
],
55-
[
56-
"[",
57-
"]"
58-
],
59-
[
60-
"(",
61-
")"
62-
],
63-
[
64-
"\"",
65-
"\""
66-
],
67-
[
68-
"'",
69-
"'"
70-
]
71-
]
72-
}
2+
"comments": {
3+
"lineComment": "//",
4+
"blockComment": ["/*", "*/"]
5+
},
6+
"brackets": [
7+
["{", "}"],
8+
["[", "]"],
9+
["(", ")"]
10+
],
11+
"autoClosingPairs": [
12+
{ "open": "{", "close": "}" },
13+
{ "open": "[", "close": "]" },
14+
{ "open": "(", "close": ")" },
15+
{ "open": "'", "close": "'", "notIn": ["string", "comment"] },
16+
{ "open": "\"", "close": "\"", "notIn": ["string"] },
17+
{ "open": "/**", "close": " */", "notIn": ["string"] }
18+
],
19+
"autoCloseBefore": ";:.=}])> \n\t",
20+
"surroundingPairs": [
21+
["{", "}"],
22+
["[", "]"],
23+
["(", ")"],
24+
["'", "'"],
25+
["\"", "\""]
26+
],
27+
"folding": {
28+
"markers": {
29+
"start": "^\\s*//\\s*#?region\\b",
30+
"end": "^\\s*//\\s*#?endregion\\b"
31+
}
32+
},
33+
"wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\.\\<\\>\\/\\?\\s]+)",
34+
"indentationRules": {
35+
"increaseIndentPattern": "^((?!.*?\\/\\*).*\\*/)?\\s*[\\}\\]].*$",
36+
"decreaseIndentPattern": "^((?!\\/\\/).)*(\\{[^}\"']*|\\([^)\"']*|\\[[^\\]\"']*)$"
37+
}
38+
}

extensions/ql-vscode/src/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { testExplorerExtensionId, TestHub } from 'vscode-test-adapter-api';
44
import * as archiveFilesystemProvider from './archive-filesystem-provider';
55
import { CodeQLCliServer } from './cli';
66
import { DistributionConfigListener, QueryHistoryConfigListener, QueryServerConfigListener } from './config';
7+
import * as languageSupport from './languageSupport';
78
import { DatabaseManager } from './databases';
89
import { DatabaseUI } from './databases-ui';
910
import { TemplateQueryDefinitionProvider, TemplateQueryReferenceProvider } from './definitions';
@@ -78,6 +79,7 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
7879
logger.log('Starting CodeQL extension');
7980

8081
initializeLogging(ctx);
82+
languageSupport.install();
8183

8284
const distributionConfigListener = new DistributionConfigListener();
8385
ctx.subscriptions.push(distributionConfigListener);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { IndentAction, languages } from "vscode";
2+
3+
4+
/**
5+
* OnEnterRules are available in language-configurations, but you cannot specify them in the language-configuration.json.
6+
* They can only be specified programmatically.
7+
*
8+
* Also, we should keep the language-configuration.json as a json file and register it in the package.json because
9+
* it is registered first, before the extension is activated, so language features are available quicker.
10+
*
11+
* See https://github.com/microsoft/vscode/issues/11514
12+
* See https://github.com/microsoft/vscode/blob/master/src/vs/editor/test/common/modes/supports/javascriptOnEnterRules.ts
13+
*/
14+
export function install() {
15+
// eslint-disable-next-line @typescript-eslint/no-var-requires
16+
const langConfig = require('../language-configuration.json');
17+
// setLanguageConfiguration requires a regexp for the wordpattern, not a string
18+
langConfig.wordPattern = new RegExp(langConfig.wordPattern);
19+
langConfig.onEnterRules = onEnterRules;
20+
21+
languages.setLanguageConfiguration('ql', langConfig);
22+
languages.setLanguageConfiguration('qll', langConfig);
23+
languages.setLanguageConfiguration('dbscheme', langConfig);
24+
25+
}
26+
27+
const onEnterRules = [
28+
{
29+
// e.g. /** | */
30+
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
31+
afterText: /^\s*\*\/$/,
32+
action: { indentAction: IndentAction.IndentOutdent, appendText: ' * ' }
33+
}, {
34+
// e.g. /** ...|
35+
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
36+
action: { indentAction: IndentAction.None, appendText: ' * ' }
37+
}, {
38+
// e.g. * ...|
39+
beforeText: /^(\t|[ ])*[ ]\*([ ]([^\*]|\*(?!\/))*)?$/,
40+
oneLineAboveText: /^(\s*(\/\*\*|\*)).*/,
41+
action: { indentAction: IndentAction.None, appendText: '* ' }
42+
}, {
43+
// e.g. */|
44+
beforeText: /^(\t|[ ])*[ ]\*\/\s*$/,
45+
action: { indentAction: IndentAction.None, removeText: 1 }
46+
},
47+
{
48+
// e.g. *-----*/|
49+
beforeText: /^(\t|[ ])*[ ]\*[^/]*\*\/\s*$/,
50+
action: { indentAction: IndentAction.None, removeText: 1 }
51+
}
52+
];

0 commit comments

Comments
 (0)