Skip to content

Commit d9145a2

Browse files
Fix line comment action for makefiles (Fixes microsoft#234464) (microsoft#243283)
* Fix line comment action for makefiles (Fixes microsoft#234464) Pass languageId to _analyzeLines to distinguish makefiles from the rest of the languages. Add test to _analyzeLines specifically for makefiles. * Remove hardcoded string. Apply fix at LanguageConfigurationService. Add comment rule to specify fixed column token placement. Change test scope to test line command instead of just testing the _analyzeLines method. * change added field to use bool instead of user-chosen offset * add check to remove comment detection * add check to following space removal * update branch. add config interface for new noindent option. adapt existing logic for new config format. * fix small issue with following space removal * polish --------- Co-authored-by: Aiday Marlen Kyzy <[email protected]>
1 parent 2685e2a commit d9145a2

File tree

7 files changed

+109
-19
lines changed

7 files changed

+109
-19
lines changed

extensions/make/language-configuration.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
22
"comments": {
3-
"lineComment": "#"
3+
"lineComment": {
4+
"comment": "#",
5+
"noIndent": true
6+
}
47
},
58
"brackets": [
69
[

src/vs/editor/common/languages/languageConfiguration.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,30 @@ import { CharCode } from '../../../base/common/charCode.js';
77
import { StandardTokenType } from '../encodedTokenAttributes.js';
88
import { ScopedLineTokens } from './supports.js';
99

10+
/**
11+
* Configuration for line comments.
12+
*/
13+
export interface LineCommentConfig {
14+
/**
15+
* The line comment token, like `//`
16+
*/
17+
comment: string;
18+
/**
19+
* Whether the comment token should not be indented and placed at the first column.
20+
* Defaults to false.
21+
*/
22+
noIndent?: boolean;
23+
}
24+
1025
/**
1126
* Describes how comments for a language work.
1227
*/
1328
export interface CommentRule {
1429
/**
15-
* The line comment token, like `// this is a comment`
30+
* The line comment token, like `// this is a comment`.
31+
* Can be a string or an object with comment and optional noIndent properties.
1632
*/
17-
lineComment?: string | null;
33+
lineComment?: string | LineCommentConfig | null;
1834
/**
1935
* The block comment character pair, like `/* block comment *&#47;`
2036
*/

src/vs/editor/common/languages/languageConfigurationRegistry.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { LanguageBracketsConfiguration } from './supports/languageBracketsConfig
2727
*/
2828
export interface ICommentsConfiguration {
2929
lineCommentToken?: string;
30+
lineCommentNoIndent?: boolean;
3031
blockCommentStartToken?: string;
3132
blockCommentEndToken?: string;
3233
}
@@ -456,7 +457,12 @@ export class ResolvedLanguageConfiguration {
456457
const comments: ICommentsConfiguration = {};
457458

458459
if (commentRule.lineComment) {
459-
comments.lineCommentToken = commentRule.lineComment;
460+
if (typeof commentRule.lineComment === 'string') {
461+
comments.lineCommentToken = commentRule.lineComment;
462+
} else {
463+
comments.lineCommentToken = commentRule.lineComment.comment;
464+
comments.lineCommentNoIndent = commentRule.lineComment.noIndent;
465+
}
460466
}
461467
if (commentRule.blockComment) {
462468
const [blockStart, blockEnd] = commentRule.blockComment;

src/vs/editor/contrib/comment/browser/lineCommentCommand.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,12 @@ export class LineCommentCommand implements ICommand {
112112
* Analyze lines and decide which lines are relevant and what the toggle should do.
113113
* Also, build up several offsets and lengths useful in the generation of editor operations.
114114
*/
115-
public static _analyzeLines(type: Type, insertSpace: boolean, model: ISimpleModel, lines: ILinePreflightData[], startLineNumber: number, ignoreEmptyLines: boolean, ignoreFirstLine: boolean, languageConfigurationService: ILanguageConfigurationService): IPreflightData {
115+
public static _analyzeLines(type: Type, insertSpace: boolean, model: ISimpleModel, lines: ILinePreflightData[], startLineNumber: number, ignoreEmptyLines: boolean, ignoreFirstLine: boolean, languageConfigurationService: ILanguageConfigurationService, languageId: string): IPreflightData {
116116
let onlyWhitespaceLines = true;
117117

118+
const config = languageConfigurationService.getLanguageConfiguration(languageId).comments;
119+
const lineCommentNoIndent = config?.lineCommentNoIndent ?? false;
120+
118121
let shouldRemoveComments: boolean;
119122
if (type === Type.Toggle) {
120123
shouldRemoveComments = true;
@@ -140,15 +143,16 @@ export class LineCommentCommand implements ICommand {
140143
if (lineContentStartOffset === -1) {
141144
// Empty or whitespace only line
142145
lineData.ignore = ignoreEmptyLines;
143-
lineData.commentStrOffset = lineContent.length;
146+
lineData.commentStrOffset = lineCommentNoIndent ? 0 : lineContent.length;
144147
continue;
145148
}
146149

147150
onlyWhitespaceLines = false;
151+
const offset = lineCommentNoIndent ? 0 : lineContentStartOffset;
148152
lineData.ignore = false;
149-
lineData.commentStrOffset = lineContentStartOffset;
153+
lineData.commentStrOffset = offset;
150154

151-
if (shouldRemoveComments && !BlockCommentCommand._haystackHasNeedleAtOffset(lineContent, lineData.commentStr, lineContentStartOffset)) {
155+
if (shouldRemoveComments && !BlockCommentCommand._haystackHasNeedleAtOffset(lineContent, lineData.commentStr, offset)) {
152156
if (type === Type.Toggle) {
153157
// Every line so far has been a line comment, but this one is not
154158
shouldRemoveComments = false;
@@ -190,13 +194,14 @@ export class LineCommentCommand implements ICommand {
190194
*/
191195
public static _gatherPreflightData(type: Type, insertSpace: boolean, model: ITextModel, startLineNumber: number, endLineNumber: number, ignoreEmptyLines: boolean, ignoreFirstLine: boolean, languageConfigurationService: ILanguageConfigurationService): IPreflightData {
192196
const lines = LineCommentCommand._gatherPreflightCommentStrings(model, startLineNumber, endLineNumber, languageConfigurationService);
197+
const languageId = model.getLanguageIdAtPosition(startLineNumber, 1);
193198
if (lines === null) {
194199
return {
195200
supported: false
196201
};
197202
}
198203

199-
return LineCommentCommand._analyzeLines(type, insertSpace, model, lines, startLineNumber, ignoreEmptyLines, ignoreFirstLine, languageConfigurationService);
204+
return LineCommentCommand._analyzeLines(type, insertSpace, model, lines, startLineNumber, ignoreEmptyLines, ignoreFirstLine, languageConfigurationService, languageId);
200205
}
201206

202207
/**

src/vs/editor/contrib/comment/test/browser/lineCommentCommand.test.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ suite('Editor Contrib - Line Comment Command', () => {
4848
(accessor, sel) => new LineCommentCommand(accessor.get(ILanguageConfigurationService), sel, 4, Type.ForceAdd, true, true)
4949
);
5050

51+
const testLineCommentCommandTokenFirstColumn = createTestCommandHelper(
52+
{ lineComment: { comment: '!@#', noIndent: true }, blockComment: ['<!@#', '#@!>'] },
53+
(accessor, sel) => new LineCommentCommand(accessor.get(ILanguageConfigurationService), sel, 4, Type.Toggle, true, true)
54+
);
55+
5156
test('comment single line', function () {
5257
testLineCommentCommand(
5358
[
@@ -81,6 +86,21 @@ suite('Editor Contrib - Line Comment Command', () => {
8186
);
8287
});
8388

89+
test('comment with token column fixed', function () {
90+
testLineCommentCommandTokenFirstColumn(
91+
[
92+
'some text',
93+
'\tsome more text'
94+
],
95+
new Selection(2, 1, 2, 1),
96+
[
97+
'some text',
98+
'!@# \tsome more text'
99+
],
100+
new Selection(2, 5, 2, 5)
101+
);
102+
});
103+
84104
function createSimpleModel(lines: string[]): ISimpleModel {
85105
return {
86106
getLineContent: (lineNumber: number) => {
@@ -110,7 +130,7 @@ suite('Editor Contrib - Line Comment Command', () => {
110130
' ',
111131
' c',
112132
'\t\td'
113-
]), createBasicLinePreflightData(['//', 'rem', '!@#', '!@#']), 1, true, false, disposable.add(new TestLanguageConfigurationService()));
133+
]), createBasicLinePreflightData(['//', 'rem', '!@#', '!@#']), 1, true, false, disposable.add(new TestLanguageConfigurationService()), 'plaintext');
114134
if (!r.supported) {
115135
throw new Error(`unexpected`);
116136
}
@@ -141,7 +161,7 @@ suite('Editor Contrib - Line Comment Command', () => {
141161
' rem ',
142162
' !@# c',
143163
'\t\t!@#d'
144-
]), createBasicLinePreflightData(['//', 'rem', '!@#', '!@#']), 1, true, false, disposable.add(new TestLanguageConfigurationService()));
164+
]), createBasicLinePreflightData(['//', 'rem', '!@#', '!@#']), 1, true, false, disposable.add(new TestLanguageConfigurationService()), 'plaintext');
145165
if (!r.supported) {
146166
throw new Error(`unexpected`);
147167
}

src/vs/monaco.d.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6709,14 +6709,30 @@ declare namespace monaco.languages {
67096709
}>;
67106710
}
67116711

6712+
/**
6713+
* Configuration for line comments.
6714+
*/
6715+
export interface LineCommentConfig {
6716+
/**
6717+
* The line comment token, like `//`
6718+
*/
6719+
comment: string;
6720+
/**
6721+
* Whether the comment token should not be indented and placed at the first column.
6722+
* Defaults to false.
6723+
*/
6724+
noIndent?: boolean;
6725+
}
6726+
67126727
/**
67136728
* Describes how comments for a language work.
67146729
*/
67156730
export interface CommentRule {
67166731
/**
6717-
* The line comment token, like `// this is a comment`
6732+
* The line comment token, like `// this is a comment`.
6733+
* Can be a string or an object with comment and optional noIndent properties.
67186734
*/
6719-
lineComment?: string | null;
6735+
lineComment?: string | LineCommentConfig | null;
67206736
/**
67216737
* The block comment character pair, like `/* block comment *&#47;`
67226738
*/

src/vs/workbench/contrib/codeEditor/common/languageConfigurationExtensionPoint.ts

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,22 @@ export class LanguageConfigurationFileHandler extends Disposable {
161161

162162
let result: CommentRule | undefined = undefined;
163163
if (typeof source.lineComment !== 'undefined') {
164-
if (typeof source.lineComment !== 'string') {
165-
console.warn(`[${languageId}]: language configuration: expected \`comments.lineComment\` to be a string.`);
166-
} else {
164+
if (typeof source.lineComment === 'string') {
167165
result = result || {};
168166
result.lineComment = source.lineComment;
167+
} else if (types.isObject(source.lineComment)) {
168+
const lineCommentObj = source.lineComment as any;
169+
if (typeof lineCommentObj.comment === 'string') {
170+
result = result || {};
171+
result.lineComment = {
172+
comment: lineCommentObj.comment,
173+
noIndent: lineCommentObj.noIndent
174+
};
175+
} else {
176+
console.warn(`[${languageId}]: language configuration: expected \`comments.lineComment.comment\` to be a string.`);
177+
}
178+
} else {
179+
console.warn(`[${languageId}]: language configuration: expected \`comments.lineComment\` to be a string or an object with comment property.`);
169180
}
170181
}
171182
if (typeof source.blockComment !== 'undefined') {
@@ -519,7 +530,7 @@ const schema: IJSONSchema = {
519530
comments: {
520531
default: {
521532
blockComment: ['/*', '*/'],
522-
lineComment: '//'
533+
lineComment: { comment: '//', noIndent: false }
523534
},
524535
description: nls.localize('schema.comments', 'Defines the comment symbols'),
525536
type: 'object',
@@ -536,8 +547,21 @@ const schema: IJSONSchema = {
536547
}]
537548
},
538549
lineComment: {
539-
type: 'string',
540-
description: nls.localize('schema.lineComment', 'The character sequence that starts a line comment.')
550+
type: 'object',
551+
description: nls.localize('schema.lineComment.object', 'Configuration for line comments.'),
552+
properties: {
553+
comment: {
554+
type: 'string',
555+
description: nls.localize('schema.lineComment.comment', 'The character sequence that starts a line comment.')
556+
},
557+
noIndent: {
558+
type: 'boolean',
559+
description: nls.localize('schema.lineComment.noIndent', 'Whether the comment token should not be indented and placed at the first column. Defaults to false.'),
560+
default: false
561+
}
562+
},
563+
required: ['comment'],
564+
additionalProperties: false
541565
}
542566
}
543567
},

0 commit comments

Comments
 (0)