2
2
import * as vscode from 'vscode' ;
3
3
4
4
export async function activate ( context : vscode . ExtensionContext ) {
5
+ devMode = context . extensionMode === vscode . ExtensionMode . Development ;
6
+
5
7
let semicolonAtPosition = vscode . commands . registerTextEditorCommand ( 'auto-semicolon-vscode.position-insert-semicolon' ,
6
8
( editor : vscode . TextEditor , textEdit : vscode . TextEditorEdit ) => {
7
9
return semicolonCommand ( editor , textEdit ) ;
@@ -33,16 +35,18 @@ export function deactivate() { }
33
35
type RegExpMatchArrayWithIndex = RegExpMatchArray & { index : number } ;
34
36
35
37
// these variables will fill later
38
+ let devMode = false ;
36
39
let autoSemicolonFormatsIncluded = true ;
37
40
let autoMoveFormatsIncluded = false ;
38
41
let commentDelimiter = '//' ;
42
+ let commentDelimiterIndex = - 1 ;
39
43
40
44
41
45
type StringDictionary = {
42
- [ key : string ] : string ;
46
+ [ key : string ] : string ;
43
47
} ;
44
48
45
- const languagesDelimiter :StringDictionary = {
49
+ const languagesDelimiter : StringDictionary = {
46
50
"dotenv" : '#' ,
47
51
"dockerfile" : '#' ,
48
52
"snippets" : '#' ,
@@ -72,14 +76,7 @@ function isForStatementIgnored() {
72
76
return getConfig ( ) . supportedLanguageId . ignores . theForStatement ;
73
77
}
74
78
75
- function isUnallowdEndsIncluded ( lineText : string ) {
76
- let pos = lineText . lastIndexOf ( commentDelimiter ) ;
77
-
78
- // it it commented
79
- if ( pos >= 0 ) {
80
- lineText = lineText . substring ( 0 , pos ) ;
81
- }
82
-
79
+ function isUnallowedEndsIncluded ( lineText : string ) {
83
80
let lastCharacter = lineText [ lineText . length - 1 ] ;
84
81
85
82
let unallowedEnds = getConfig ( ) . autoInsertSemicolon . unallowedEnds . split ( "," ) ;
@@ -132,6 +129,11 @@ function semicolonCommand(editor: vscode.TextEditor, textEdit: vscode.TextEditor
132
129
function autoSemicolonCommand ( editor : vscode . TextEditor , textEdit : vscode . TextEditorEdit , forceToEnd : boolean ) {
133
130
const selections : vscode . Selection [ ] = [ ] ;
134
131
const languageId = vscode . window . activeTextEditor ?. document . languageId ;
132
+
133
+ autoSemicolonFormatsIncluded = isAutoSemicolonLanguageIdIncluded ( languageId ) ;
134
+ autoMoveFormatsIncluded = isAutoMoveLanguageIdIncluded ( languageId ) ;
135
+ commentDelimiter = getCommentDelimiter ( languageId ) ;
136
+
135
137
editor . edit ( ( ) => {
136
138
try {
137
139
editor . selections . forEach ( ( selection ) => {
@@ -142,10 +144,7 @@ function autoSemicolonCommand(editor: vscode.TextEditor, textEdit: vscode.TextEd
142
144
let position : vscode . Position ;
143
145
let match ;
144
146
145
- autoSemicolonFormatsIncluded = isAutoSemicolonLanguageIdIncluded ( languageId ) ;
146
- autoMoveFormatsIncluded = isAutoMoveLanguageIdIncluded ( languageId ) ;
147
- commentDelimiter = getCommentDelimiter ( languageId ) ;
148
-
147
+ commentDelimiterIndex = indexTagOutOfQuotes ( lineText , commentDelimiter ) ;
149
148
position = newPosition ( line , selection . active . character + 1 ) ;
150
149
151
150
if ( lineText . length === 0 || ! languageId ) {
@@ -154,7 +153,7 @@ function autoSemicolonCommand(editor: vscode.TextEditor, textEdit: vscode.TextEd
154
153
} else if ( ! autoSemicolonFormatsIncluded && ! autoMoveFormatsIncluded ) {
155
154
textEdit . insert ( selection . active , ';' ) ;
156
155
157
- } else if ( ! forceToEnd && isCommented ( lineText , currentPos ) ) {
156
+ } else if ( ! forceToEnd && commentDelimiterIndex >= 0 && commentDelimiterIndex < currentPos ) {
158
157
textEdit . insert ( selection . active , ';' ) ;
159
158
160
159
} else if ( ! forceToEnd && isQuotesIgnored ( ) && isInStringLiteral ( lineText , currentPos ) ) {
@@ -174,7 +173,7 @@ function autoSemicolonCommand(editor: vscode.TextEditor, textEdit: vscode.TextEd
174
173
let length = line . range . end . character + 1 ;
175
174
if ( isBetweenTags ( '{' , '}' , lineText , currentPos ) ) {
176
175
length = putSemicolonBefore ( '}' , textEdit , selection , line ) ;
177
- } else if ( ! isUnallowdEndsIncluded ( lineText ) || currentPos === line . text . length ) {
176
+ } else if ( ! isUnallowedEndsIncluded ( lineText ) || currentPos === line . text . length ) {
178
177
length = autoSemicolonBeforeComment ( textEdit , selection , line ) + 1 ;
179
178
}
180
179
@@ -183,17 +182,20 @@ function autoSemicolonCommand(editor: vscode.TextEditor, textEdit: vscode.TextEd
183
182
} else {
184
183
// just move to the end
185
184
let length = line . range . end . character + 1 ;
185
+ if ( autoMoveFormatsIncluded ) {
186
+ length = lineText . substring ( 0 , commentDelimiterIndex ) . trimEnd ( ) . length ;
187
+ }
186
188
position = newPosition ( line , length ) ;
187
189
}
188
190
189
191
selection = new vscode . Selection ( position , position ) ;
190
192
selections . push ( selection ) ;
191
- } catch ( error ) {
192
- // logIt(error.message);
193
+ } catch ( error : any ) {
194
+ logIt ( error . message ) ;
193
195
}
194
196
} ) ;
195
- } catch ( error ) {
196
- // logIt(error.message);
197
+ } catch ( error : any ) {
198
+ logIt ( error . message ) ;
197
199
}
198
200
} ) . then ( ( ) => {
199
201
editor . selections = selections ;
@@ -215,7 +217,7 @@ function putSemicolonBefore(tag: string, textEdit: vscode.TextEditorEdit, select
215
217
const lineTextTrimmed = lineText . substring ( 0 , posClose ) . trimEnd ( ) ;
216
218
length = lineTextTrimmed . length ;
217
219
218
- if ( ! isUnallowdEndsIncluded ( lineTextTrimmed ) || currentPos === line . text . length ) {
220
+ if ( ! isUnallowedEndsIncluded ( lineTextTrimmed ) || currentPos === line . text . length ) {
219
221
lineText = lineText . replace ( lineTextTrimmed , lineTextTrimmed + ';' ) ;
220
222
length += 1 ;
221
223
textEdit . delete ( new vscode . Selection ( newPosition ( line , 0 ) , newPosition ( line , line . text . length ) ) ) ;
@@ -234,14 +236,13 @@ function putSemicolonBefore(tag: string, textEdit: vscode.TextEditorEdit, select
234
236
function autoSemicolonBeforeComment ( textEdit : vscode . TextEditorEdit , selection : vscode . Selection , line : vscode . TextLine , justMove : boolean = false ) : number {
235
237
let lineText = line . text . trimEnd ( ) ;
236
238
const currentPos = selection . active . character ;
237
- const posClose = lineText . indexOf ( commentDelimiter , currentPos ) ;
238
239
let length = lineText . length ;
239
240
240
- if ( posClose >= 0 ) {
241
- const lineTextTrimmed = lineText . substring ( 0 , posClose ) . trimEnd ( ) ;
241
+ if ( commentDelimiterIndex >= 0 ) {
242
+ const lineTextTrimmed = lineText . substring ( 0 , commentDelimiterIndex ) . trimEnd ( ) ;
242
243
length = lineTextTrimmed . length ;
243
244
244
- if ( ! isUnallowdEndsIncluded ( lineTextTrimmed ) || currentPos === length ) {
245
+ if ( ! isUnallowedEndsIncluded ( lineTextTrimmed ) || currentPos === length ) {
245
246
lineText = lineText . replace ( lineTextTrimmed , lineTextTrimmed + ';' ) ;
246
247
length += 1 ;
247
248
textEdit . delete ( new vscode . Selection ( newPosition ( line , 0 ) , newPosition ( line , line . text . length ) ) ) ;
@@ -294,8 +295,27 @@ function getCommentDelimiter(languageId: string | undefined): string {
294
295
return delimiterDefault ;
295
296
}
296
297
297
- function isCommented ( lineText : string , currentPos : number ) : boolean {
298
- return lineText . lastIndexOf ( commentDelimiter , currentPos ) >= 0 ;
298
+ function indexTagOutOfQuotes ( line : string , tag : string ) : number {
299
+ const regex = new RegExp ( `${ commentDelimiter } (?!['"\`]\S)` , 'g' ) ;
300
+ const matches = [ ] ;
301
+
302
+ let match ;
303
+ while ( ( match = regex . exec ( line ) ) !== null ) {
304
+ // Check the preceding characters
305
+ const precedingChars = line . slice ( 0 , match . index ) ;
306
+ const quoteCount = ( precedingChars . match ( / [ ' " ` ] / g) || [ ] ) . length ;
307
+
308
+ // If the count of quotes is even, add the match
309
+ if ( quoteCount % 2 == 0 ) {
310
+ matches . push ( match ) ;
311
+ }
312
+ }
313
+
314
+ if ( matches . length == 0 ) {
315
+ return - 1 ;
316
+ }
317
+
318
+ return matches [ 0 ] . index ;
299
319
}
300
320
301
321
function findTheForStatement ( lineText : string , currentPos : number ) : string [ ] | null {
@@ -338,9 +358,11 @@ function isEmpty(value: string | any[] | null | undefined): boolean {
338
358
return ( value == null || value . length === 0 ) ;
339
359
}
340
360
341
- async function logIt ( message : string | any [ ] | null | undefined ) {
342
- console . log ( message ) ;
343
- // vscode.window.showWarningMessage(message?.toString());
361
+ async function logIt ( message : string | any | any [ ] | null | undefined ) {
362
+ if ( devMode ) {
363
+ console . log ( message ) ;
364
+ // vscode.window.showWarningMessage(message?.toString());
365
+ }
344
366
}
345
367
346
368
async function taskChecker ( context : vscode . ExtensionContext ) {
0 commit comments