diff options
Diffstat (limited to 'editors/code')
-rw-r--r-- | editors/code/package.json | 2 | ||||
-rw-r--r-- | editors/code/src/config.ts | 5 | ||||
-rw-r--r-- | editors/code/src/extension.ts | 10 | ||||
-rw-r--r-- | editors/code/src/highlighting.ts | 81 | ||||
-rw-r--r-- | editors/code/src/scopes.ts | 60 | ||||
-rw-r--r-- | editors/code/src/scopes_mapper.ts | 58 |
6 files changed, 110 insertions, 106 deletions
diff --git a/editors/code/package.json b/editors/code/package.json index 35f2f1e62..5c5be34db 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -550,4 +550,4 @@ | |||
550 | } | 550 | } |
551 | ] | 551 | ] |
552 | } | 552 | } |
553 | } \ No newline at end of file | 553 | } |
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 234a390ac..4cedbea46 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts | |||
@@ -46,14 +46,14 @@ export class Config { | |||
46 | 46 | ||
47 | public userConfigChanged() { | 47 | public userConfigChanged() { |
48 | const config = vscode.workspace.getConfiguration('rust-analyzer'); | 48 | const config = vscode.workspace.getConfiguration('rust-analyzer'); |
49 | 49 | ||
50 | Server.highlighter.removeHighlights(); | 50 | Server.highlighter.removeHighlights(); |
51 | 51 | ||
52 | if (config.has('highlightingOn')) { | 52 | if (config.has('highlightingOn')) { |
53 | this.highlightingOn = config.get('highlightingOn') as boolean; | 53 | this.highlightingOn = config.get('highlightingOn') as boolean; |
54 | if (this.highlightingOn) { | 54 | if (this.highlightingOn) { |
55 | scopes.load(); | 55 | scopes.load(); |
56 | scopesMapper.load(); | 56 | scopesMapper.load(); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
@@ -63,7 +63,6 @@ export class Config { | |||
63 | ) as boolean; | 63 | ) as boolean; |
64 | } | 64 | } |
65 | 65 | ||
66 | |||
67 | if (config.has('enableEnhancedTyping')) { | 66 | if (config.has('enableEnhancedTyping')) { |
68 | this.enableEnhancedTyping = config.get( | 67 | this.enableEnhancedTyping = config.get( |
69 | 'enableEnhancedTyping' | 68 | 'enableEnhancedTyping' |
diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts index 07a5c59e8..c06928d12 100644 --- a/editors/code/src/extension.ts +++ b/editors/code/src/extension.ts | |||
@@ -91,11 +91,11 @@ export function activate(context: vscode.ExtensionContext) { | |||
91 | const allNotifications: Iterable< | 91 | const allNotifications: Iterable< |
92 | [string, lc.GenericNotificationHandler] | 92 | [string, lc.GenericNotificationHandler] |
93 | > = [ | 93 | > = [ |
94 | [ | 94 | [ |
95 | 'rust-analyzer/publishDecorations', | 95 | 'rust-analyzer/publishDecorations', |
96 | notifications.publishDecorations.handle | 96 | notifications.publishDecorations.handle |
97 | ] | 97 | ] |
98 | ]; | 98 | ]; |
99 | const syntaxTreeContentProvider = new SyntaxTreeContentProvider(); | 99 | const syntaxTreeContentProvider = new SyntaxTreeContentProvider(); |
100 | 100 | ||
101 | // The events below are plain old javascript events, triggered and handled by vscode | 101 | // The events below are plain old javascript events, triggered and handled by vscode |
diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts index ee39ca64c..14199dbea 100644 --- a/editors/code/src/highlighting.ts +++ b/editors/code/src/highlighting.ts | |||
@@ -25,35 +25,15 @@ function fancify(seed: string, shade: 'light' | 'dark') { | |||
25 | return `hsl(${h},${s}%,${l}%)`; | 25 | return `hsl(${h},${s}%,${l}%)`; |
26 | } | 26 | } |
27 | 27 | ||
28 | 28 | function createDecorationFromTextmate( | |
29 | function createDecorationFromTextmate(themeStyle: scopes.TextMateRuleSettings): vscode.TextEditorDecorationType { | 29 | themeStyle: scopes.TextMateRuleSettings |
30 | const options: vscode.DecorationRenderOptions = {}; | 30 | ): vscode.TextEditorDecorationType { |
31 | options.rangeBehavior = vscode.DecorationRangeBehavior.OpenOpen; | 31 | const decorationOptions: vscode.DecorationRenderOptions = {}; |
32 | if (themeStyle.foreground) { | 32 | decorationOptions.rangeBehavior = vscode.DecorationRangeBehavior.OpenOpen; |
33 | options.color = themeStyle.foreground; | 33 | decorationOptions.color = themeStyle.foreground; |
34 | } | 34 | decorationOptions.backgroundColor = themeStyle.background; |
35 | if (themeStyle.background) { | 35 | decorationOptions.fontStyle = themeStyle.fontStyle; |
36 | options.backgroundColor = themeStyle.background; | 36 | return vscode.window.createTextEditorDecorationType(decorationOptions); |
37 | } | ||
38 | if (themeStyle.fontStyle) { | ||
39 | const parts: string[] = themeStyle.fontStyle.split(' '); | ||
40 | parts.forEach((part) => { | ||
41 | switch (part) { | ||
42 | case 'italic': | ||
43 | options.fontStyle = 'italic'; | ||
44 | break; | ||
45 | case 'bold': | ||
46 | options.fontWeight = 'bold'; | ||
47 | break; | ||
48 | case 'underline': | ||
49 | options.textDecoration = 'underline'; | ||
50 | break; | ||
51 | default: | ||
52 | break; | ||
53 | } | ||
54 | }) | ||
55 | } | ||
56 | return vscode.window.createTextEditorDecorationType(options); | ||
57 | } | 37 | } |
58 | 38 | ||
59 | export class Highlighter { | 39 | export class Highlighter { |
@@ -65,14 +45,12 @@ export class Highlighter { | |||
65 | tag: string, | 45 | tag: string, |
66 | textDecoration?: string | 46 | textDecoration?: string |
67 | ): [string, vscode.TextEditorDecorationType] => { | 47 | ): [string, vscode.TextEditorDecorationType] => { |
68 | |||
69 | const rule = scopesMapper.toRule(tag, scopes.find); | 48 | const rule = scopesMapper.toRule(tag, scopes.find); |
70 | 49 | ||
71 | if (rule) { | 50 | if (rule) { |
72 | const decor = createDecorationFromTextmate(rule); | 51 | const decor = createDecorationFromTextmate(rule); |
73 | return [tag, decor]; | 52 | return [tag, decor]; |
74 | } | 53 | } else { |
75 | else { | ||
76 | const fallBackTag = 'ralsp.' + tag; | 54 | const fallBackTag = 'ralsp.' + tag; |
77 | // console.log(' '); | 55 | // console.log(' '); |
78 | // console.log('Missing theme for: <"' + tag + '"> for following mapped scopes:'); | 56 | // console.log('Missing theme for: <"' + tag + '"> for following mapped scopes:'); |
@@ -91,25 +69,25 @@ export class Highlighter { | |||
91 | const decorations: Iterable< | 69 | const decorations: Iterable< |
92 | [string, vscode.TextEditorDecorationType] | 70 | [string, vscode.TextEditorDecorationType] |
93 | > = [ | 71 | > = [ |
94 | decoration('comment'), | 72 | decoration('comment'), |
95 | decoration('string'), | 73 | decoration('string'), |
96 | decoration('keyword'), | 74 | decoration('keyword'), |
97 | decoration('keyword.control'), | 75 | decoration('keyword.control'), |
98 | decoration('keyword.unsafe'), | 76 | decoration('keyword.unsafe'), |
99 | decoration('function'), | 77 | decoration('function'), |
100 | decoration('parameter'), | 78 | decoration('parameter'), |
101 | decoration('constant'), | 79 | decoration('constant'), |
102 | decoration('type'), | 80 | decoration('type'), |
103 | decoration('builtin'), | 81 | decoration('builtin'), |
104 | decoration('text'), | 82 | decoration('text'), |
105 | decoration('attribute'), | 83 | decoration('attribute'), |
106 | decoration('literal'), | 84 | decoration('literal'), |
107 | decoration('macro'), | 85 | decoration('macro'), |
108 | decoration('variable'), | 86 | decoration('variable'), |
109 | decoration('variable.mut', 'underline'), | 87 | decoration('variable.mut', 'underline'), |
110 | decoration('field'), | 88 | decoration('field'), |
111 | decoration('module') | 89 | decoration('module') |
112 | ]; | 90 | ]; |
113 | 91 | ||
114 | return new Map<string, vscode.TextEditorDecorationType>(decorations); | 92 | return new Map<string, vscode.TextEditorDecorationType>(decorations); |
115 | } | 93 | } |
@@ -138,7 +116,6 @@ export class Highlighter { | |||
138 | // Note: decoration objects need to be kept around so we can dispose them | 116 | // Note: decoration objects need to be kept around so we can dispose them |
139 | // if the user disables syntax highlighting | 117 | // if the user disables syntax highlighting |
140 | 118 | ||
141 | |||
142 | if (this.decorations == null) { | 119 | if (this.decorations == null) { |
143 | this.decorations = Highlighter.initDecorations(); | 120 | this.decorations = Highlighter.initDecorations(); |
144 | } | 121 | } |
diff --git a/editors/code/src/scopes.ts b/editors/code/src/scopes.ts index a6138fad0..98099872c 100644 --- a/editors/code/src/scopes.ts +++ b/editors/code/src/scopes.ts | |||
@@ -2,8 +2,6 @@ import * as fs from 'fs'; | |||
2 | import * as path from 'path'; | 2 | import * as path from 'path'; |
3 | import * as vscode from 'vscode'; | 3 | import * as vscode from 'vscode'; |
4 | 4 | ||
5 | |||
6 | |||
7 | export interface TextMateRule { | 5 | export interface TextMateRule { |
8 | scope: string | string[]; | 6 | scope: string | string[]; |
9 | settings: TextMateRuleSettings; | 7 | settings: TextMateRuleSettings; |
@@ -27,7 +25,9 @@ export function load() { | |||
27 | // Remove any previous theme | 25 | // Remove any previous theme |
28 | rules.clear(); | 26 | rules.clear(); |
29 | // Find out current color theme | 27 | // Find out current color theme |
30 | const themeName = vscode.workspace.getConfiguration('workbench').get('colorTheme'); | 28 | const themeName = vscode.workspace |
29 | .getConfiguration('workbench') | ||
30 | .get('colorTheme'); | ||
31 | 31 | ||
32 | if (typeof themeName !== 'string') { | 32 | if (typeof themeName !== 'string') { |
33 | // console.warn('workbench.colorTheme is', themeName) | 33 | // console.warn('workbench.colorTheme is', themeName) |
@@ -42,38 +42,43 @@ export function load() { | |||
42 | } | 42 | } |
43 | 43 | ||
44 | function filterThemeExtensions(extension: vscode.Extension<any>): boolean { | 44 | function filterThemeExtensions(extension: vscode.Extension<any>): boolean { |
45 | return extension.extensionKind === vscode.ExtensionKind.UI && | 45 | return ( |
46 | extension.extensionKind === vscode.ExtensionKind.UI && | ||
46 | extension.packageJSON.contributes && | 47 | extension.packageJSON.contributes && |
47 | extension.packageJSON.contributes.themes; | 48 | extension.packageJSON.contributes.themes |
49 | ); | ||
48 | } | 50 | } |
49 | 51 | ||
50 | |||
51 | |||
52 | // Find current theme on disk | 52 | // Find current theme on disk |
53 | function loadThemeNamed(themeName: string) { | 53 | function loadThemeNamed(themeName: string) { |
54 | |||
55 | const themePaths = vscode.extensions.all | 54 | const themePaths = vscode.extensions.all |
56 | .filter(filterThemeExtensions) | 55 | .filter(filterThemeExtensions) |
57 | .reduce((list, extension) => { | 56 | .reduce((list, extension) => { |
58 | return extension.packageJSON.contributes.themes | 57 | return extension.packageJSON.contributes.themes |
59 | .filter((element: any) => (element.id || element.label) === themeName) | 58 | .filter( |
60 | .map((element: any) => path.join(extension.extensionPath, element.path)) | 59 | (element: any) => |
61 | .concat(list) | 60 | (element.id || element.label) === themeName |
61 | ) | ||
62 | .map((element: any) => | ||
63 | path.join(extension.extensionPath, element.path) | ||
64 | ) | ||
65 | .concat(list); | ||
62 | }, Array<string>()); | 66 | }, Array<string>()); |
63 | 67 | ||
64 | |||
65 | themePaths.forEach(loadThemeFile); | 68 | themePaths.forEach(loadThemeFile); |
66 | 69 | ||
67 | const tokenColorCustomizations: [any] = [vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations')] | 70 | const tokenColorCustomizations: [any] = [ |
71 | vscode.workspace | ||
72 | .getConfiguration('editor') | ||
73 | .get('tokenColorCustomizations') | ||
74 | ]; | ||
68 | 75 | ||
69 | tokenColorCustomizations | 76 | tokenColorCustomizations |
70 | .filter(custom => custom && custom.textMateRules) | 77 | .filter(custom => custom && custom.textMateRules) |
71 | .map(custom => custom.textMateRules) | 78 | .map(custom => custom.textMateRules) |
72 | .forEach(loadColors); | 79 | .forEach(loadColors); |
73 | |||
74 | } | 80 | } |
75 | 81 | ||
76 | |||
77 | function loadThemeFile(themePath: string) { | 82 | function loadThemeFile(themePath: string) { |
78 | const themeContent = [themePath] | 83 | const themeContent = [themePath] |
79 | .filter(isFile) | 84 | .filter(isFile) |
@@ -92,18 +97,26 @@ function loadThemeFile(themePath: string) { | |||
92 | .forEach(loadThemeFile); | 97 | .forEach(loadThemeFile); |
93 | } | 98 | } |
94 | 99 | ||
95 | function mergeRuleSettings(defaultSetting: TextMateRuleSettings | undefined, override: TextMateRuleSettings): TextMateRuleSettings { | 100 | function mergeRuleSettings( |
96 | if (defaultSetting === undefined) { return override; } | 101 | defaultSetting: TextMateRuleSettings | undefined, |
102 | override: TextMateRuleSettings | ||
103 | ): TextMateRuleSettings { | ||
104 | if (defaultSetting === undefined) { | ||
105 | return override; | ||
106 | } | ||
97 | const mergedRule = defaultSetting; | 107 | const mergedRule = defaultSetting; |
98 | 108 | ||
99 | mergedRule.background = override.background || defaultSetting.background; | 109 | mergedRule.background = override.background || defaultSetting.background; |
100 | mergedRule.foreground = override.foreground || defaultSetting.foreground; | 110 | mergedRule.foreground = override.foreground || defaultSetting.foreground; |
101 | mergedRule.fontStyle = override.fontStyle || defaultSetting.foreground; | 111 | mergedRule.fontStyle = override.fontStyle || defaultSetting.foreground; |
102 | 112 | ||
103 | return mergedRule | 113 | return mergedRule; |
104 | } | 114 | } |
105 | 115 | ||
106 | function updateRules(scope: string, updatedSettings: TextMateRuleSettings): void { | 116 | function updateRules( |
117 | scope: string, | ||
118 | updatedSettings: TextMateRuleSettings | ||
119 | ): void { | ||
107 | [rules.get(scope)] | 120 | [rules.get(scope)] |
108 | .map(settings => mergeRuleSettings(settings, updatedSettings)) | 121 | .map(settings => mergeRuleSettings(settings, updatedSettings)) |
109 | .forEach(settings => rules.set(scope, settings)); | 122 | .forEach(settings => rules.set(scope, settings)); |
@@ -113,11 +126,10 @@ function loadColors(textMateRules: TextMateRule[]): void { | |||
113 | textMateRules.forEach(rule => { | 126 | textMateRules.forEach(rule => { |
114 | if (typeof rule.scope === 'string') { | 127 | if (typeof rule.scope === 'string') { |
115 | updateRules(rule.scope, rule.settings); | 128 | updateRules(rule.scope, rule.settings); |
116 | } | 129 | } else if (rule.scope instanceof Array) { |
117 | else if (rule.scope instanceof Array) { | ||
118 | rule.scope.forEach(scope => updateRules(scope, rule.settings)); | 130 | rule.scope.forEach(scope => updateRules(scope, rule.settings)); |
119 | } | 131 | } |
120 | }) | 132 | }); |
121 | } | 133 | } |
122 | 134 | ||
123 | function isFile(filePath: string): boolean { | 135 | function isFile(filePath: string): boolean { |
@@ -128,7 +140,7 @@ function readFileText(filePath: string): string { | |||
128 | return fs.readFileSync(filePath, 'utf8'); | 140 | return fs.readFileSync(filePath, 'utf8'); |
129 | } | 141 | } |
130 | 142 | ||
131 | // Might need to replace with JSONC if a theme contains comments. | 143 | // Might need to replace with JSONC if a theme contains comments. |
132 | function parseJSON(content: string): any { | 144 | function parseJSON(content: string): any { |
133 | return JSON.parse(content); | 145 | return JSON.parse(content); |
134 | } \ No newline at end of file | 146 | } |
diff --git a/editors/code/src/scopes_mapper.ts b/editors/code/src/scopes_mapper.ts index dfb8bf217..85c791ff5 100644 --- a/editors/code/src/scopes_mapper.ts +++ b/editors/code/src/scopes_mapper.ts | |||
@@ -1,17 +1,25 @@ | |||
1 | import * as vscode from 'vscode'; | 1 | import * as vscode from 'vscode'; |
2 | import { TextMateRuleSettings } from './scopes'; | 2 | import { TextMateRuleSettings } from './scopes'; |
3 | 3 | ||
4 | |||
5 | |||
6 | let mappings = new Map<string, string[]>(); | 4 | let mappings = new Map<string, string[]>(); |
7 | 5 | ||
8 | |||
9 | const defaultMapping = new Map<string, string[]>([ | 6 | const defaultMapping = new Map<string, string[]>([ |
10 | ['comment', ['comment', 'comment.block', 'comment.line', 'comment.block.documentation']], | 7 | [ |
8 | 'comment', | ||
9 | [ | ||
10 | 'comment', | ||
11 | 'comment.block', | ||
12 | 'comment.line', | ||
13 | 'comment.block.documentation' | ||
14 | ] | ||
15 | ], | ||
11 | ['string', ['string']], | 16 | ['string', ['string']], |
12 | ['keyword', ['keyword']], | 17 | ['keyword', ['keyword']], |
13 | ['keyword.control', ['keyword.control', 'keyword', 'keyword.other']], | 18 | ['keyword.control', ['keyword.control', 'keyword', 'keyword.other']], |
14 | ['keyword.unsafe', ['storage.modifier', 'keyword.other', 'keyword.control', 'keyword']], | 19 | [ |
20 | 'keyword.unsafe', | ||
21 | ['storage.modifier', 'keyword.other', 'keyword.control', 'keyword'] | ||
22 | ], | ||
15 | ['function', ['entity.name.function']], | 23 | ['function', ['entity.name.function']], |
16 | ['parameter', ['variable.parameter']], | 24 | ['parameter', ['variable.parameter']], |
17 | ['constant', ['constant', 'variable']], | 25 | ['constant', ['constant', 'variable']], |
@@ -23,21 +31,32 @@ const defaultMapping = new Map<string, string[]>([ | |||
23 | ['macro', ['support.other']], | 31 | ['macro', ['support.other']], |
24 | ['variable', ['variable']], | 32 | ['variable', ['variable']], |
25 | ['variable.mut', ['variable', 'storage.modifier']], | 33 | ['variable.mut', ['variable', 'storage.modifier']], |
26 | ['field', ['variable.object.property', 'meta.field.declaration', 'meta.definition.property', 'variable.other',]], | 34 | [ |
35 | 'field', | ||
36 | [ | ||
37 | 'variable.object.property', | ||
38 | 'meta.field.declaration', | ||
39 | 'meta.definition.property', | ||
40 | 'variable.other' | ||
41 | ] | ||
42 | ], | ||
27 | ['module', ['entity.name.section', 'entity.other']] | 43 | ['module', ['entity.name.section', 'entity.other']] |
28 | ] | 44 | ]); |
29 | ); | ||
30 | 45 | ||
31 | // Temporary exported for debugging for now. | 46 | // Temporary exported for debugging for now. |
32 | export function find(scope: string): string[] { | 47 | export function find(scope: string): string[] { |
33 | return mappings.get(scope) || []; | 48 | return mappings.get(scope) || []; |
34 | } | 49 | } |
35 | 50 | ||
36 | export function toRule(scope: string, intoRule: (scope: string) => TextMateRuleSettings | undefined): TextMateRuleSettings | undefined { | 51 | export function toRule( |
37 | return find(scope).map(intoRule).filter(rule => rule !== undefined)[0]; | 52 | scope: string, |
53 | intoRule: (scope: string) => TextMateRuleSettings | undefined | ||
54 | ): TextMateRuleSettings | undefined { | ||
55 | return find(scope) | ||
56 | .map(intoRule) | ||
57 | .filter(rule => rule !== undefined)[0]; | ||
38 | } | 58 | } |
39 | 59 | ||
40 | |||
41 | function isString(value: any): value is string { | 60 | function isString(value: any): value is string { |
42 | return typeof value === 'string'; | 61 | return typeof value === 'string'; |
43 | } | 62 | } |
@@ -46,18 +65,15 @@ function isArrayOfString(value: any): value is string[] { | |||
46 | return Array.isArray(value) && value.every(item => isString(item)); | 65 | return Array.isArray(value) && value.every(item => isString(item)); |
47 | } | 66 | } |
48 | 67 | ||
49 | |||
50 | export function load() { | 68 | export function load() { |
51 | const rawConfig: { [key: string]: any } = vscode.workspace | 69 | const rawConfig: { [key: string]: any } = |
52 | .getConfiguration('rust-analyzer') | 70 | vscode.workspace |
53 | .get('scopeMappings') | 71 | .getConfiguration('rust-analyzer') |
54 | || {}; | 72 | .get('scopeMappings') || {}; |
55 | 73 | ||
56 | mappings = Object | 74 | mappings = Object.entries(rawConfig) |
57 | .entries(rawConfig) | ||
58 | .filter(([_, value]) => isString(value) || isArrayOfString(value)) | 75 | .filter(([_, value]) => isString(value) || isArrayOfString(value)) |
59 | .reduce((list, [key, value]: [string, string | string[]]) => { | 76 | .reduce((list, [key, value]: [string, string | string[]]) => { |
60 | return list.set(key, isString(value) ? [value] : value); | 77 | return list.set(key, isString(value) ? [value] : value); |
61 | }, defaultMapping); | 78 | }, defaultMapping); |
62 | 79 | } | |
63 | } \ No newline at end of file | ||