From b075388a16a8ce07e24062f1f61fad8747eedcbd Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Sun, 20 Nov 2022 00:16:42 +0200 Subject: [PATCH 01/42] Add "Insert Comma" --- package.json | 7 ++++- src/extension.ts | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index fd8fec6..5507a6a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Fix All JSON", "description": "Fix missing and trailing commas on save", "publisher": "zardoy", - "version": "0.0.0-dev", + "version": "0.0.1", "preview": true, "web": true, "keywords": [ @@ -67,6 +67,11 @@ "runOnSave": { "type": "boolean", "default": true + }, + "insertComma": { + "type": "boolean", + "default": true, + "description": "Insert comma after `}`, `]`, `\"` or number" } } } diff --git a/src/extension.ts b/src/extension.ts index 0ab5cba..fee2166 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -2,6 +2,8 @@ import * as vscode from 'vscode' import { getExtensionSetting, registerExtensionCommand } from 'vscode-framework' +const isNumber = (text: string) => !Number.isNaN(Number(text)); + export const activate = () => { vscode.languages.registerCodeActionsProvider( { language: 'jsonc' }, @@ -110,4 +112,81 @@ export const activate = () => { if (!getExtensionSetting('runOnSave') || reason === vscode.TextDocumentSaveReason.AfterDelay) return waitUntil(performFixes()) }) + + vscode.workspace.onDidChangeTextDocument( + ({ contentChanges, document }) => { + if (!getExtensionSetting("insertComma")) { + return; + } + + if ( + document.languageId !== "json" && + document.languageId !== "jsonc" + ) { + return; + } + + if (contentChanges.length === 0) { + return; + } + + const editor = vscode.window.activeTextEditor; + + if ( + document.uri !== editor?.document.uri || + ["output"].includes(editor.document.uri.scheme) + ) { + return; + } + if ( + vscode.workspace.fs.isWritableFileSystem( + document.uri.scheme + ) === false + ) { + return; + } + + const content = contentChanges[0]; + + if (!content) { + return; + } + + if ( + !content.text.startsWith("\n") && + !content.text.startsWith("\r\n") + ) { + return; + } + + const prevLinePosition = document.positionAt(content.rangeOffset); + const prevLine = document.lineAt(prevLinePosition); + const prevLineText = prevLine.text; + + if (prevLineText.trim().startsWith("//")) { + return; + } + + const prevLineLastChar = prevLineText.at(-1); + + if (!prevLineLastChar) { + return; + } + + const isNextLineEmpty = + document.lineAt(prevLinePosition.line + 1).text.trim() === ""; + + const isMatchValue = + prevLineLastChar === "}" || + prevLineLastChar === '"' || + prevLineLastChar === ']' || + isNumber(prevLineLastChar); + + if (isMatchValue && isNextLineEmpty) { + editor.edit((edit) => { + edit.insert(prevLinePosition, ","); + }); + } + } + ); } From e642ff65b8ae33f6aa6d29cf4846afacbe6d123f Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Sun, 20 Nov 2022 00:20:06 +0200 Subject: [PATCH 02/42] Update docs --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5507a6a..e1ab568 100644 --- a/package.json +++ b/package.json @@ -68,10 +68,10 @@ "type": "boolean", "default": true }, - "insertComma": { + "insertCommaAfterEnnter": { "type": "boolean", "default": true, - "description": "Insert comma after `}`, `]`, `\"` or number" + "description": "Insert comma after \"Enter\". Working only if last symbol is `}`, `]`, `\"` or number" } } } From 261fad1424b48e3ac590bbf0b24dd4fa206cb3d7 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Sun, 20 Nov 2022 00:20:29 +0200 Subject: [PATCH 03/42] Fix typo --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e1ab568..f6a2de0 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "type": "boolean", "default": true }, - "insertCommaAfterEnnter": { + "insertCommaAfterEnter": { "type": "boolean", "default": true, "description": "Insert comma after \"Enter\". Working only if last symbol is `}`, `]`, `\"` or number" From 876d6f89b2889825206b69c67a3f5b1792374f5e Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Sun, 20 Nov 2022 11:08:45 +0200 Subject: [PATCH 04/42] Back version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f6a2de0..3cec0de 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Fix All JSON", "description": "Fix missing and trailing commas on save", "publisher": "zardoy", - "version": "0.0.1", + "version": "0.0.0-dev", "preview": true, "web": true, "keywords": [ From cda655d8147e584aa55503f8fc821b8c4d338425 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Sun, 20 Nov 2022 11:10:34 +0200 Subject: [PATCH 05/42] Rename to insertMissingCommaOnEnter --- package.json | 4 ++-- src/extension.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 3cec0de..ff794ea 100644 --- a/package.json +++ b/package.json @@ -68,10 +68,10 @@ "type": "boolean", "default": true }, - "insertCommaAfterEnter": { + "insertMissingCommaOnEnter": { "type": "boolean", "default": true, - "description": "Insert comma after \"Enter\". Working only if last symbol is `}`, `]`, `\"` or number" + "description": "Insert missing comma after \"Enter\". Working only if last symbol is `}`, `]`, `\"` or number" } } } diff --git a/src/extension.ts b/src/extension.ts index fee2166..2d2668c 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -115,7 +115,7 @@ export const activate = () => { vscode.workspace.onDidChangeTextDocument( ({ contentChanges, document }) => { - if (!getExtensionSetting("insertComma")) { + if (!getExtensionSetting("insertMissingCommaOnEnter")) { return; } From e269fa3e8c96ef7dbbe24aab66ce95d22bda5bcb Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Sun, 20 Nov 2022 11:39:53 +0200 Subject: [PATCH 06/42] Advanced support JSONC --- package.json | 1 + pnpm-lock.yaml | 7 +++++++ src/extension.ts | 21 ++++++++++++++++----- src/utils.ts | 7 +++++++ 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 src/utils.ts diff --git a/package.json b/package.json index ff794ea..8bb17af 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "typescript": "^4.5.2" }, "dependencies": { + "strip-json-comments": "^5.0.0", "vscode-framework": "^0.0.18" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9648578..cfc617c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,10 +10,12 @@ specifiers: cross-env: ^7.0.3 eslint: ^8.18.0 eslint-config-zardoy: ^0.2.11 + strip-json-comments: ^5.0.0 typescript: ^4.5.2 vscode-framework: ^0.0.18 dependencies: + strip-json-comments: 5.0.0 vscode-framework: 0.0.18_l3izlp2w2o7lntemhxm5k54lqq devDependencies: @@ -3764,6 +3766,11 @@ packages: engines: {node: '>=8'} dev: true + /strip-json-comments/5.0.0: + resolution: {integrity: sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==} + engines: {node: '>=14.16'} + dev: false + /supports-color/5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} diff --git a/src/extension.ts b/src/extension.ts index 2d2668c..28f3f79 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,8 +1,9 @@ import * as vscode from 'vscode' import { getExtensionSetting, registerExtensionCommand } from 'vscode-framework' +import stripJsonComments from 'strip-json-comments' +import { getTextByLine, isNumber } from './utils'; -const isNumber = (text: string) => !Number.isNaN(Number(text)); export const activate = () => { vscode.languages.registerCodeActionsProvider( @@ -163,16 +164,26 @@ export const activate = () => { const prevLine = document.lineAt(prevLinePosition); const prevLineText = prevLine.text; - if (prevLineText.trim().startsWith("//")) { - return; - } - const prevLineLastChar = prevLineText.at(-1); if (!prevLineLastChar) { return; } + if (document.languageId === 'jsonc') { + if (prevLineText.trim().startsWith("//") || prevLineText.trim().startsWith("/*")) { + return; + } + + const textWithouComments = stripJsonComments(document.getText()); + const prevLineTextWithoutComments = getTextByLine(textWithouComments, prevLinePosition.line)?.trim(); + + + if (prevLineTextWithoutComments !== prevLineText.trim()) { + return; + } + } + const isNextLineEmpty = document.lineAt(prevLinePosition.line + 1).text.trim() === ""; diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..d6c4419 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,7 @@ +export function getTextByLine(text:string, line: number) { + return text.split("\n").at(line); +} + +export function isNumber(text: string) { + return !Number.isNaN(Number(text)); +} From 5ce702d0e153c27d65ced468096cd62d944c9663 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Sun, 20 Nov 2022 12:39:46 +0200 Subject: [PATCH 07/42] Add multicursor support --- src/extension.ts | 80 +++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 28f3f79..a3749e1 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -147,57 +147,55 @@ export const activate = () => { return; } - const content = contentChanges[0]; - - if (!content) { - return; - } - - if ( - !content.text.startsWith("\n") && - !content.text.startsWith("\r\n") - ) { - return; - } + editor.edit((edit) => { + contentChanges.forEach(async (content) => { + if ( + !content.text.startsWith("\n") && + !content.text.startsWith("\r\n") + ) { + return; + } - const prevLinePosition = document.positionAt(content.rangeOffset); - const prevLine = document.lineAt(prevLinePosition); - const prevLineText = prevLine.text; + const prevLinePosition = document.positionAt(content.rangeOffset); - const prevLineLastChar = prevLineText.at(-1); + const prevLine = document.lineAt(prevLinePosition); + const prevLineText = prevLine.text; - if (!prevLineLastChar) { - return; - } + const prevLineLastChar = prevLineText.at(-1); - if (document.languageId === 'jsonc') { - if (prevLineText.trim().startsWith("//") || prevLineText.trim().startsWith("/*")) { - return; - } + if (!prevLineLastChar) { + return; + } - const textWithouComments = stripJsonComments(document.getText()); - const prevLineTextWithoutComments = getTextByLine(textWithouComments, prevLinePosition.line)?.trim(); + if (document.languageId === 'jsonc') { + if (prevLineText.trim().startsWith("//") || prevLineText.trim().startsWith("/*")) { + return; + } + const textWithouComments = stripJsonComments(document.getText()); + const prevLineTextWithoutComments = getTextByLine(textWithouComments, prevLine.lineNumber)?.trim(); - if (prevLineTextWithoutComments !== prevLineText.trim()) { - return; - } - } + if (prevLineTextWithoutComments !== prevLineText.trim()) { + return; + } + } - const isNextLineEmpty = - document.lineAt(prevLinePosition.line + 1).text.trim() === ""; + const isCurrentLineEmpty = + document.lineAt(prevLine.lineNumber + 1).text.trim() === ""; - const isMatchValue = - prevLineLastChar === "}" || - prevLineLastChar === '"' || - prevLineLastChar === ']' || - isNumber(prevLineLastChar); + const isMatchValue = + prevLineLastChar === "}" || + prevLineLastChar === '"' || + prevLineLastChar === ']' || + isNumber(prevLineLastChar); - if (isMatchValue && isNextLineEmpty) { - editor.edit((edit) => { - edit.insert(prevLinePosition, ","); - }); - } + if (isMatchValue && isCurrentLineEmpty) { + // In multicursor mode last character position is broken when I use prevLinePosition, IDK why + const lastCharacterPosition = new vscode.Position(prevLine.lineNumber, prevLine.range.end.character); + edit.insert(lastCharacterPosition, ","); + } + }) + }); } ); } From 71347a24e54b0428b49df78eed270e21b6b6b96b Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Mon, 21 Nov 2022 00:10:48 +0300 Subject: [PATCH 08/42] fix eslint issues --- src/extension.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index a3749e1..4919e8b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,3 +1,4 @@ +/* eslint-disable curly */ import * as vscode from 'vscode' import { getExtensionSetting, registerExtensionCommand } from 'vscode-framework' @@ -139,6 +140,7 @@ export const activate = () => { ) { return; } + if ( vscode.workspace.fs.isWritableFileSystem( document.uri.scheme @@ -147,13 +149,13 @@ export const activate = () => { return; } - editor.edit((edit) => { - contentChanges.forEach(async (content) => { + void editor.edit((edit) => { + for (const content of contentChanges) { if ( !content.text.startsWith("\n") && !content.text.startsWith("\r\n") ) { - return; + continue; } const prevLinePosition = document.positionAt(content.rangeOffset); @@ -164,19 +166,19 @@ export const activate = () => { const prevLineLastChar = prevLineText.at(-1); if (!prevLineLastChar) { - return; + continue; } if (document.languageId === 'jsonc') { if (prevLineText.trim().startsWith("//") || prevLineText.trim().startsWith("/*")) { - return; + continue; } const textWithouComments = stripJsonComments(document.getText()); const prevLineTextWithoutComments = getTextByLine(textWithouComments, prevLine.lineNumber)?.trim(); if (prevLineTextWithoutComments !== prevLineText.trim()) { - return; + continue; } } @@ -194,7 +196,7 @@ export const activate = () => { const lastCharacterPosition = new vscode.Position(prevLine.lineNumber, prevLine.range.end.character); edit.insert(lastCharacterPosition, ","); } - }) + } }); } ); From 7734873337f237a963d2d97024d4b438a0735c64 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Mon, 21 Nov 2022 00:40:34 +0300 Subject: [PATCH 09/42] simplify code --- src/extension.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 4919e8b..1ee13a8 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -122,8 +122,7 @@ export const activate = () => { } if ( - document.languageId !== "json" && - document.languageId !== "jsonc" + !vscode.languages.match(['json', 'jsonc'], document) ) { return; } @@ -158,7 +157,7 @@ export const activate = () => { continue; } - const prevLinePosition = document.positionAt(content.rangeOffset); + const prevLinePosition = content.range.start; const prevLine = document.lineAt(prevLinePosition); const prevLineText = prevLine.text; From 7dc2c580df32643d95f738dce3d290c39ebfd7b4 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Mon, 21 Nov 2022 00:50:15 +0300 Subject: [PATCH 10/42] fix incorrect multicursor insertion --- src/extension.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 1ee13a8..ba9a8ae 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -131,6 +131,8 @@ export const activate = () => { return; } + contentChanges = [...contentChanges].sort((a, b) => a.range.start.compareTo(b.range.start)) + const editor = vscode.window.activeTextEditor; if ( @@ -149,7 +151,7 @@ export const activate = () => { } void editor.edit((edit) => { - for (const content of contentChanges) { + for (const [i, content] of contentChanges.entries()) { if ( !content.text.startsWith("\n") && !content.text.startsWith("\r\n") @@ -159,7 +161,7 @@ export const activate = () => { const prevLinePosition = content.range.start; - const prevLine = document.lineAt(prevLinePosition); + const prevLine = document.lineAt(prevLinePosition.line + i); const prevLineText = prevLine.text; const prevLineLastChar = prevLineText.at(-1); From e0760aba84b36cd3cc7647ea130900db1b379940 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 13:13:31 +0200 Subject: [PATCH 11/42] Fix isNumber --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index d6c4419..0da6a71 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -3,5 +3,5 @@ export function getTextByLine(text:string, line: number) { } export function isNumber(text: string) { - return !Number.isNaN(Number(text)); + return !Number.isNaN(Number.parseInt(text, 10)); } From c75289b76c7725989995e2430857646ca85e0315 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 13:27:45 +0200 Subject: [PATCH 12/42] Move condition to upperScope --- src/extension.ts | 17 +++++++---------- src/utils.ts | 4 ++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index a75c9f4..4bcfdd2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,7 +3,7 @@ import * as vscode from 'vscode' import { getExtensionSetting, registerExtensionCommand } from 'vscode-framework' import stripJsonComments from 'strip-json-comments' -import { getTextByLine, isNumber } from './utils'; +import { getTextByLine, isContainEoL, isNumber } from './utils'; export const activate = () => { @@ -150,16 +150,13 @@ export const activate = () => { return; } - void editor.edit((edit) => { - for (const [i, content] of contentChanges.entries()) { - if ( - !content.text.startsWith("\n") && - !content.text.startsWith("\r\n") - ) { - continue; - } + if (contentChanges.some((change) => !isContainEoL(change.text))) { + return; + } - const prevLinePosition = content.range.start; + void editor.edit((edit) => { + for (const [i, change] of contentChanges.entries()) { + const prevLinePosition = change.range.start; const prevLine = document.lineAt(prevLinePosition.line + i); const prevLineText = prevLine.text; diff --git a/src/utils.ts b/src/utils.ts index 0da6a71..ff3aa32 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,3 +5,7 @@ export function getTextByLine(text:string, line: number) { export function isNumber(text: string) { return !Number.isNaN(Number.parseInt(text, 10)); } + +export function isContainEoL(text: string) { + return text.includes('\n') || text.includes('\n\r') +} From a9b0db788b7a6e7bb76c1dba56edbe1b5fd26089 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 13:33:20 +0200 Subject: [PATCH 13/42] Add support comments in classic JSON --- src/extension.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 4bcfdd2..10cc207 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -167,17 +167,15 @@ export const activate = () => { continue; } - if (document.languageId === 'jsonc') { - if (prevLineText.trim().startsWith("//") || prevLineText.trim().startsWith("/*")) { - continue; - } + if (prevLineText.trim().startsWith("//") || prevLineText.trim().startsWith("/*")) { + continue; + } - const textWithouComments = stripJsonComments(document.getText()); - const prevLineTextWithoutComments = getTextByLine(textWithouComments, prevLine.lineNumber)?.trim(); + const textWithouComments = stripJsonComments(document.getText()); + const prevLineTextWithoutComments = getTextByLine(textWithouComments, prevLine.lineNumber)?.trim(); - if (prevLineTextWithoutComments !== prevLineText.trim()) { - continue; - } + if (prevLineTextWithoutComments !== prevLineText.trim()) { + continue; } const isCurrentLineEmpty = From 08dfcd6b421d5afd72078f8156e69e48ff1710f6 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 13:45:31 +0200 Subject: [PATCH 14/42] Add checking reason --- package.json | 1 + pnpm-lock.yaml | 25 +++++++++++++++++++++++++ src/extension.ts | 8 ++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 800be6c..2e6c02f 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "typescript": "^4.5.2" }, "dependencies": { + "@zardoy/utils": "^0.0.10", "strip-json-comments": "^5.0.0", "vscode-framework": "^0.0.18" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cfc617c..2644421 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,7 @@ specifiers: '@types/node': ^16.11.12 '@types/vscode': ^1.62.0 '@zardoy/tsconfig': ^1.2.2 + '@zardoy/utils': ^0.0.10 cross-env: ^7.0.3 eslint: ^8.18.0 eslint-config-zardoy: ^0.2.11 @@ -15,6 +16,7 @@ specifiers: vscode-framework: ^0.0.18 dependencies: + '@zardoy/utils': 0.0.10 strip-json-comments: 5.0.0 vscode-framework: 0.0.18_l3izlp2w2o7lntemhxm5k54lqq @@ -618,6 +620,16 @@ packages: typescript: 4.5.2 dev: true + /@zardoy/utils/0.0.10: + resolution: {integrity: sha512-Tgk1RPmKl2HMHDOIoFwrRcPQWgSfoIhJZiatR18GVvvjxQ0zZNSR7ZIT6HLHBDXNsFA2aanyQv4GTPe1V8+iMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + escape-string-regexp: 5.0.0 + lodash.compact: 3.0.1 + rambda: 6.9.0 + type-fest: 2.8.0 + dev: false + /accepts/1.3.7: resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==} engines: {node: '>= 0.6'} @@ -1531,6 +1543,11 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + /escape-string-regexp/5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + dev: false + /escodegen/1.14.3: resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} engines: {node: '>=4.0'} @@ -2813,6 +2830,10 @@ packages: p-locate: 5.0.0 dev: false + /lodash.compact/3.0.1: + resolution: {integrity: sha512-2ozeiPi+5eBXW1CLtzjk8XQFhQOEMwwfxblqeq6EGyTxZJ1bPATqilY0e6g2SLQpP4KuMeuioBhEnWz5Pr7ICQ==} + dev: false + /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true @@ -3408,6 +3429,10 @@ packages: through2: 2.0.5 dev: false + /rambda/6.9.0: + resolution: {integrity: sha512-yosVdGg1hNGkXPzqGiOYNEpXKjEOxzUCg2rB0l+NKdyCaSf4z+i5ojbN0IqDSezMMf71YEglI+ZUTgTffn5afw==} + dev: false + /react-is/17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} dev: false diff --git a/src/extension.ts b/src/extension.ts index 10cc207..910944f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,9 +3,9 @@ import * as vscode from 'vscode' import { getExtensionSetting, registerExtensionCommand } from 'vscode-framework' import stripJsonComments from 'strip-json-comments' +import { oneOf } from '@zardoy/utils' import { getTextByLine, isContainEoL, isNumber } from './utils'; - export const activate = () => { vscode.languages.registerCodeActionsProvider( { language: 'jsonc' }, @@ -116,7 +116,7 @@ export const activate = () => { }) vscode.workspace.onDidChangeTextDocument( - ({ contentChanges, document }) => { + ({ contentChanges, document, reason }) => { if (!getExtensionSetting("insertMissingCommaOnEnter")) { return; } @@ -150,6 +150,10 @@ export const activate = () => { return; } + if (oneOf(reason, vscode.TextDocumentChangeReason.Undo, vscode.TextDocumentChangeReason.Redo)) { + return + } + if (contentChanges.some((change) => !isContainEoL(change.text))) { return; } From da41b7565ea0068e3c6893a3c59a84073863d4fa Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 13:46:11 +0200 Subject: [PATCH 15/42] Add undoStopAfter and undoStopBefore --- src/extension.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 910944f..1444b10 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -151,7 +151,7 @@ export const activate = () => { } if (oneOf(reason, vscode.TextDocumentChangeReason.Undo, vscode.TextDocumentChangeReason.Redo)) { - return + return } if (contentChanges.some((change) => !isContainEoL(change.text))) { @@ -197,7 +197,7 @@ export const activate = () => { edit.insert(lastCharacterPosition, ","); } } - }); + }, { undoStopAfter: false, undoStopBefore: false }); } ); } From b2248e97140df142e24f4374f09cc8b80c03d221 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 14:01:24 +0200 Subject: [PATCH 16/42] Add support Inserting comma before comment --- src/extension.ts | 12 ++++++++---- src/utils.ts | 6 +++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 1444b10..5a7045e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -4,7 +4,7 @@ import * as vscode from 'vscode' import { getExtensionSetting, registerExtensionCommand } from 'vscode-framework' import stripJsonComments from 'strip-json-comments' import { oneOf } from '@zardoy/utils' -import { getTextByLine, isContainEoL, isNumber } from './utils'; +import { getTextByLine, isContainEoL, isNumber, startsWithComment } from './utils'; export const activate = () => { vscode.languages.registerCodeActionsProvider( @@ -171,7 +171,7 @@ export const activate = () => { continue; } - if (prevLineText.trim().startsWith("//") || prevLineText.trim().startsWith("/*")) { + if (startsWithComment(prevLine.text.trim())) { continue; } @@ -182,8 +182,11 @@ export const activate = () => { continue; } + const currentLineText = document.lineAt(prevLine.lineNumber + 1).text.trim(); + const isCurrentLineEmpty = - document.lineAt(prevLine.lineNumber + 1).text.trim() === ""; + currentLineText.trim() === ""; + const isCurrentLineBeforeComment = startsWithComment(currentLineText); const isMatchValue = prevLineLastChar === "}" || @@ -191,7 +194,8 @@ export const activate = () => { prevLineLastChar === ']' || isNumber(prevLineLastChar); - if (isMatchValue && isCurrentLineEmpty) { + + if (isMatchValue && (isCurrentLineEmpty || isCurrentLineBeforeComment)) { // In multicursor mode last character position is broken when I use prevLinePosition, IDK why const lastCharacterPosition = new vscode.Position(prevLine.lineNumber, prevLine.range.end.character); edit.insert(lastCharacterPosition, ","); diff --git a/src/utils.ts b/src/utils.ts index ff3aa32..7ef2571 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -export function getTextByLine(text:string, line: number) { +export function getTextByLine(text: string, line: number) { return text.split("\n").at(line); } @@ -9,3 +9,7 @@ export function isNumber(text: string) { export function isContainEoL(text: string) { return text.includes('\n') || text.includes('\n\r') } + +export function startsWithComment(text: string) { + return text.startsWith('//') || text.startsWith('/*'); +} From f9470e4fe3e6efa87a4b7643408baff3a48c2a23 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ <68181944+AgentRBY@users.noreply.github.com> Date: Mon, 21 Nov 2022 18:43:44 +0300 Subject: [PATCH 17/42] Fix typo Co-authored-by: Vitaly --- src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extension.ts b/src/extension.ts index 5a7045e..1f18321 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -175,7 +175,7 @@ export const activate = () => { continue; } - const textWithouComments = stripJsonComments(document.getText()); + const textWithoutComments = stripJsonComments(document.getText()); const prevLineTextWithoutComments = getTextByLine(textWithouComments, prevLine.lineNumber)?.trim(); if (prevLineTextWithoutComments !== prevLineText.trim()) { From b5b386a7b1a8cee2f0715cff03e5015be771af34 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 17:56:30 +0200 Subject: [PATCH 18/42] Refactor and perfomance --- src/extension.ts | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 5a7045e..503f95e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -158,6 +158,14 @@ export const activate = () => { return; } + let temporaryFileWithoutComments: string; + + const getFileContentWithoutComments = () => { + temporaryFileWithoutComments = temporaryFileWithoutComments || stripJsonComments(document.getText()); + + return temporaryFileWithoutComments; + } + void editor.edit((edit) => { for (const [i, change] of contentChanges.entries()) { const prevLinePosition = change.range.start; @@ -175,10 +183,13 @@ export const activate = () => { continue; } - const textWithouComments = stripJsonComments(document.getText()); - const prevLineTextWithoutComments = getTextByLine(textWithouComments, prevLine.lineNumber)?.trim(); + const isMatchValue = + prevLineLastChar === "}" || + prevLineLastChar === '"' || + prevLineLastChar === ']' || + isNumber(prevLineLastChar); - if (prevLineTextWithoutComments !== prevLineText.trim()) { + if (!isMatchValue) { continue; } @@ -188,18 +199,18 @@ export const activate = () => { currentLineText.trim() === ""; const isCurrentLineBeforeComment = startsWithComment(currentLineText); - const isMatchValue = - prevLineLastChar === "}" || - prevLineLastChar === '"' || - prevLineLastChar === ']' || - isNumber(prevLineLastChar); + if (!isCurrentLineEmpty && !isCurrentLineBeforeComment) { + continue; + } + const fileContentWithoutComments = getFileContentWithoutComments(); + const prevLineTextWithoutComments = getTextByLine(fileContentWithoutComments, prevLine.lineNumber)?.trim(); - if (isMatchValue && (isCurrentLineEmpty || isCurrentLineBeforeComment)) { - // In multicursor mode last character position is broken when I use prevLinePosition, IDK why - const lastCharacterPosition = new vscode.Position(prevLine.lineNumber, prevLine.range.end.character); - edit.insert(lastCharacterPosition, ","); + if (prevLineTextWithoutComments !== prevLineText.trim()) { + continue; } + + edit.insert(prevLine.range.end, ","); } }, { undoStopAfter: false, undoStopBefore: false }); } From 77aedc61e99477c1805c3dfa23a1c59db156b37c Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 18:26:12 +0200 Subject: [PATCH 19/42] Support inserting in end of comment --- src/extension.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 503f95e..40bdb02 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -161,7 +161,7 @@ export const activate = () => { let temporaryFileWithoutComments: string; const getFileContentWithoutComments = () => { - temporaryFileWithoutComments = temporaryFileWithoutComments || stripJsonComments(document.getText()); + temporaryFileWithoutComments = temporaryFileWithoutComments || stripJsonComments(document.getText(), { whitespace: false }); return temporaryFileWithoutComments; } @@ -183,16 +183,6 @@ export const activate = () => { continue; } - const isMatchValue = - prevLineLastChar === "}" || - prevLineLastChar === '"' || - prevLineLastChar === ']' || - isNumber(prevLineLastChar); - - if (!isMatchValue) { - continue; - } - const currentLineText = document.lineAt(prevLine.lineNumber + 1).text.trim(); const isCurrentLineEmpty = @@ -204,13 +194,23 @@ export const activate = () => { } const fileContentWithoutComments = getFileContentWithoutComments(); - const prevLineTextWithoutComments = getTextByLine(fileContentWithoutComments, prevLine.lineNumber)?.trim(); + const prevLineTextWithoutComments = getTextByLine(fileContentWithoutComments, prevLine.lineNumber)!; - if (prevLineTextWithoutComments !== prevLineText.trim()) { + const isComment = prevLineTextWithoutComments.trim() !== prevLineText.trim(); + + const isMatchValue = + prevLineLastChar === "}" || + prevLineLastChar === '"' || + prevLineLastChar === ']' || + isNumber(prevLineLastChar); + + if (!isMatchValue && !isComment) { continue; } - edit.insert(prevLine.range.end, ","); + const insertPostion = isComment ? new vscode.Position(prevLine.lineNumber, prevLineTextWithoutComments.length - 1) : prevLine.range.end; + + edit.insert(insertPostion, ","); } }, { undoStopAfter: false, undoStopBefore: false }); } From 3a84ad139a3e87d11226705bfc6bb13ce01bf6f6 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 18:37:26 +0200 Subject: [PATCH 20/42] Minor fix --- src/extension.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 40bdb02..9bc767c 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -173,12 +173,6 @@ export const activate = () => { const prevLine = document.lineAt(prevLinePosition.line + i); const prevLineText = prevLine.text; - const prevLineLastChar = prevLineText.at(-1); - - if (!prevLineLastChar) { - continue; - } - if (startsWithComment(prevLine.text.trim())) { continue; } @@ -198,13 +192,19 @@ export const activate = () => { const isComment = prevLineTextWithoutComments.trim() !== prevLineText.trim(); + const prevLineLastChar = isComment ? prevLineTextWithoutComments.trimEnd().at(-1) : prevLineText.at(-1); + + if (!prevLineLastChar) { + continue; + } + const isMatchValue = prevLineLastChar === "}" || prevLineLastChar === '"' || prevLineLastChar === ']' || isNumber(prevLineLastChar); - if (!isMatchValue && !isComment) { + if (!isMatchValue) { continue; } From fb26614caa0255881db2b411f54412cf52e0ec28 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 18:40:49 +0200 Subject: [PATCH 21/42] Replace trimEnd to trim --- src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extension.ts b/src/extension.ts index 9bc767c..7ca760c 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -192,7 +192,7 @@ export const activate = () => { const isComment = prevLineTextWithoutComments.trim() !== prevLineText.trim(); - const prevLineLastChar = isComment ? prevLineTextWithoutComments.trimEnd().at(-1) : prevLineText.at(-1); + const prevLineLastChar = isComment ? prevLineTextWithoutComments.trim().at(-1) : prevLineText.at(-1); if (!prevLineLastChar) { continue; From 509c76fba36b6e0f86c0ca55d0e937515a7689c2 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 19:08:12 +0200 Subject: [PATCH 22/42] Remove "whitespace: false" --- src/extension.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 7ca760c..4da9b77 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -161,7 +161,7 @@ export const activate = () => { let temporaryFileWithoutComments: string; const getFileContentWithoutComments = () => { - temporaryFileWithoutComments = temporaryFileWithoutComments || stripJsonComments(document.getText(), { whitespace: false }); + temporaryFileWithoutComments = temporaryFileWithoutComments || stripJsonComments(document.getText()); return temporaryFileWithoutComments; } @@ -192,7 +192,7 @@ export const activate = () => { const isComment = prevLineTextWithoutComments.trim() !== prevLineText.trim(); - const prevLineLastChar = isComment ? prevLineTextWithoutComments.trim().at(-1) : prevLineText.at(-1); + const prevLineLastChar = isComment ? prevLineTextWithoutComments.trimEnd().at(-1) : prevLineText.at(-1); if (!prevLineLastChar) { continue; @@ -208,7 +208,7 @@ export const activate = () => { continue; } - const insertPostion = isComment ? new vscode.Position(prevLine.lineNumber, prevLineTextWithoutComments.length - 1) : prevLine.range.end; + const insertPostion = isComment ? new vscode.Position(prevLine.lineNumber, prevLineTextWithoutComments.trimEnd().length) : prevLine.range.end; edit.insert(insertPostion, ","); } From eb659c01c137ac80179b0e63d47b41a1d0c9926f Mon Sep 17 00:00:00 2001 From: Agent_RBY_ <68181944+AgentRBY@users.noreply.github.com> Date: Mon, 21 Nov 2022 20:09:39 +0300 Subject: [PATCH 23/42] Update src/extension.ts Co-authored-by: Vitaly --- src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extension.ts b/src/extension.ts index 4da9b77..d644a01 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -181,7 +181,7 @@ export const activate = () => { const isCurrentLineEmpty = currentLineText.trim() === ""; - const isCurrentLineBeforeComment = startsWithComment(currentLineText); + const isCurrentLineStartsWithComment = startsWithComment(currentLineText); if (!isCurrentLineEmpty && !isCurrentLineBeforeComment) { continue; From db0c26ec6f3cf89b6d5669fdfe91e441eb5bdf12 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 19:11:04 +0200 Subject: [PATCH 24/42] Fix --- src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extension.ts b/src/extension.ts index d644a01..cd6ccf2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -183,7 +183,7 @@ export const activate = () => { currentLineText.trim() === ""; const isCurrentLineStartsWithComment = startsWithComment(currentLineText); - if (!isCurrentLineEmpty && !isCurrentLineBeforeComment) { + if (!isCurrentLineEmpty && !isCurrentLineStartsWithComment) { continue; } From 2b6ac455f166cfa430eb170276e0185e42fc0c8d Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 19:12:43 +0200 Subject: [PATCH 25/42] Replcae to ??= --- src/extension.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index cd6ccf2..ee36bc1 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -158,13 +158,7 @@ export const activate = () => { return; } - let temporaryFileWithoutComments: string; - - const getFileContentWithoutComments = () => { - temporaryFileWithoutComments = temporaryFileWithoutComments || stripJsonComments(document.getText()); - - return temporaryFileWithoutComments; - } + let fileContentWithoutComments: string; void editor.edit((edit) => { for (const [i, change] of contentChanges.entries()) { @@ -187,7 +181,8 @@ export const activate = () => { continue; } - const fileContentWithoutComments = getFileContentWithoutComments(); + fileContentWithoutComments ??= stripJsonComments(document.getText()); + const prevLineTextWithoutComments = getTextByLine(fileContentWithoutComments, prevLine.lineNumber)!; const isComment = prevLineTextWithoutComments.trim() !== prevLineText.trim(); From fa96be2ab3e3895f69ca0639407690534e0cacb7 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Mon, 21 Nov 2022 19:19:47 +0200 Subject: [PATCH 26/42] Refactoring --- src/extension.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index ee36bc1..e38bd8c 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -165,7 +165,6 @@ export const activate = () => { const prevLinePosition = change.range.start; const prevLine = document.lineAt(prevLinePosition.line + i); - const prevLineText = prevLine.text; if (startsWithComment(prevLine.text.trim())) { continue; @@ -185,9 +184,7 @@ export const activate = () => { const prevLineTextWithoutComments = getTextByLine(fileContentWithoutComments, prevLine.lineNumber)!; - const isComment = prevLineTextWithoutComments.trim() !== prevLineText.trim(); - - const prevLineLastChar = isComment ? prevLineTextWithoutComments.trimEnd().at(-1) : prevLineText.at(-1); + const prevLineLastChar = prevLineTextWithoutComments.trimEnd().at(-1); if (!prevLineLastChar) { continue; @@ -203,7 +200,7 @@ export const activate = () => { continue; } - const insertPostion = isComment ? new vscode.Position(prevLine.lineNumber, prevLineTextWithoutComments.trimEnd().length) : prevLine.range.end; + const insertPostion = new vscode.Position(prevLine.lineNumber, prevLineTextWithoutComments.trimEnd().length); edit.insert(insertPostion, ","); } From 12c5e429650a22b722f8dda46aa2e8abb7da0b02 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Tue, 22 Nov 2022 19:12:39 +0200 Subject: [PATCH 27/42] Inline var --- src/extension.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index e38bd8c..aed5a1e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -162,9 +162,7 @@ export const activate = () => { void editor.edit((edit) => { for (const [i, change] of contentChanges.entries()) { - const prevLinePosition = change.range.start; - - const prevLine = document.lineAt(prevLinePosition.line + i); + const prevLine = document.lineAt(change.range.start.line + i); if (startsWithComment(prevLine.text.trim())) { continue; From 04989c8c7e1fd6048469f9e740e3890bab245ca2 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ <68181944+AgentRBY@users.noreply.github.com> Date: Tue, 22 Nov 2022 21:29:20 +0300 Subject: [PATCH 28/42] Update package.json Co-authored-by: Vitaly --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 40f3efe..29b21d9 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "insertMissingCommaOnEnter": { "type": "boolean", "default": true, - "description": "Insert missing comma after \"Enter\". Working only if last symbol is `}`, `]`, `\"` or number" + "description": "Insert missing comma after \"Enter\". Works only if last JSON symbol on the line is `}`, `]`, `\"` or number" } } } From f02eb7a5cd5e5c493ce1c73abf5ca626d981609a Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Tue, 22 Nov 2022 20:35:56 +0200 Subject: [PATCH 29/42] Move to commaOnEnter and prettier all --- src/commaOnEnter.ts | 63 +++++++++++++++++++++++++++++ src/extension.ts | 97 +-------------------------------------------- src/utils.ts | 6 +-- 3 files changed, 68 insertions(+), 98 deletions(-) create mode 100644 src/commaOnEnter.ts diff --git a/src/commaOnEnter.ts b/src/commaOnEnter.ts new file mode 100644 index 0000000..8c3bacd --- /dev/null +++ b/src/commaOnEnter.ts @@ -0,0 +1,63 @@ +import * as vscode from 'vscode' +import stripJsonComments from 'strip-json-comments' +import { oneOf } from '@zardoy/utils' +import { getExtensionSetting } from 'vscode-framework' +import { getTextByLine, isContainEoL, isNumber, startsWithComment } from './utils' + +export default () => { + vscode.workspace.onDidChangeTextDocument(({ contentChanges, document, reason }) => { + if (!getExtensionSetting('insertMissingCommaOnEnter')) return + + if (!vscode.languages.match(['json', 'jsonc'], document)) return + + if (contentChanges.length === 0) return + + contentChanges = [...contentChanges].sort((a, b) => a.range.start.compareTo(b.range.start)) + + const editor = vscode.window.activeTextEditor + + if (document.uri !== editor?.document.uri || ['output'].includes(editor.document.uri.scheme)) return + + if (vscode.workspace.fs.isWritableFileSystem(document.uri.scheme) === false) return + + if (oneOf(reason, vscode.TextDocumentChangeReason.Undo, vscode.TextDocumentChangeReason.Redo)) return + + if (contentChanges.some(change => !isContainEoL(change.text))) return + + let fileContentWithoutComments: string + + void editor.edit( + edit => { + for (const [i, change] of contentChanges.entries()) { + const prevLine = document.lineAt(change.range.start.line + i) + + if (startsWithComment(prevLine.text.trim())) continue + + const currentLineText = document.lineAt(prevLine.lineNumber + 1).text.trim() + + const isCurrentLineEmpty = currentLineText.trim() === '' + const isCurrentLineStartsWithComment = startsWithComment(currentLineText) + + if (!isCurrentLineEmpty && !isCurrentLineStartsWithComment) continue + + fileContentWithoutComments ??= stripJsonComments(document.getText()) + + const prevLineTextWithoutComments = getTextByLine(fileContentWithoutComments, prevLine.lineNumber)! + + const prevLineLastChar = prevLineTextWithoutComments.trimEnd().at(-1) + + if (!prevLineLastChar) continue + + const isMatchValue = prevLineLastChar === '}' || prevLineLastChar === '"' || prevLineLastChar === ']' || isNumber(prevLineLastChar) + + if (!isMatchValue) continue + + const insertPostion = new vscode.Position(prevLine.lineNumber, prevLineTextWithoutComments.trimEnd().length) + + edit.insert(insertPostion, ',') + } + }, + { undoStopAfter: false, undoStopBefore: false }, + ) + }) +} diff --git a/src/extension.ts b/src/extension.ts index aed5a1e..4515590 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,10 +1,6 @@ -/* eslint-disable curly */ - import * as vscode from 'vscode' import { getExtensionSetting, registerExtensionCommand } from 'vscode-framework' -import stripJsonComments from 'strip-json-comments' -import { oneOf } from '@zardoy/utils' -import { getTextByLine, isContainEoL, isNumber, startsWithComment } from './utils'; +import registerCommaOnEnter from './commaOnEnter' export const activate = () => { vscode.languages.registerCodeActionsProvider( @@ -115,94 +111,5 @@ export const activate = () => { waitUntil(performFixes()) }) - vscode.workspace.onDidChangeTextDocument( - ({ contentChanges, document, reason }) => { - if (!getExtensionSetting("insertMissingCommaOnEnter")) { - return; - } - - if ( - !vscode.languages.match(['json', 'jsonc'], document) - ) { - return; - } - - if (contentChanges.length === 0) { - return; - } - - contentChanges = [...contentChanges].sort((a, b) => a.range.start.compareTo(b.range.start)) - - const editor = vscode.window.activeTextEditor; - - if ( - document.uri !== editor?.document.uri || - ["output"].includes(editor.document.uri.scheme) - ) { - return; - } - - if ( - vscode.workspace.fs.isWritableFileSystem( - document.uri.scheme - ) === false - ) { - return; - } - - if (oneOf(reason, vscode.TextDocumentChangeReason.Undo, vscode.TextDocumentChangeReason.Redo)) { - return - } - - if (contentChanges.some((change) => !isContainEoL(change.text))) { - return; - } - - let fileContentWithoutComments: string; - - void editor.edit((edit) => { - for (const [i, change] of contentChanges.entries()) { - const prevLine = document.lineAt(change.range.start.line + i); - - if (startsWithComment(prevLine.text.trim())) { - continue; - } - - const currentLineText = document.lineAt(prevLine.lineNumber + 1).text.trim(); - - const isCurrentLineEmpty = - currentLineText.trim() === ""; - const isCurrentLineStartsWithComment = startsWithComment(currentLineText); - - if (!isCurrentLineEmpty && !isCurrentLineStartsWithComment) { - continue; - } - - fileContentWithoutComments ??= stripJsonComments(document.getText()); - - const prevLineTextWithoutComments = getTextByLine(fileContentWithoutComments, prevLine.lineNumber)!; - - const prevLineLastChar = prevLineTextWithoutComments.trimEnd().at(-1); - - if (!prevLineLastChar) { - continue; - } - - const isMatchValue = - prevLineLastChar === "}" || - prevLineLastChar === '"' || - prevLineLastChar === ']' || - isNumber(prevLineLastChar); - - if (!isMatchValue) { - continue; - } - - const insertPostion = new vscode.Position(prevLine.lineNumber, prevLineTextWithoutComments.trimEnd().length); - - edit.insert(insertPostion, ","); - } - }, { undoStopAfter: false, undoStopBefore: false }); - } - ); + registerCommaOnEnter(); } diff --git a/src/utils.ts b/src/utils.ts index 7ef2571..da0ccba 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,9 +1,9 @@ export function getTextByLine(text: string, line: number) { - return text.split("\n").at(line); + return text.split('\n').at(line) } export function isNumber(text: string) { - return !Number.isNaN(Number.parseInt(text, 10)); + return !Number.isNaN(Number.parseInt(text, 10)) } export function isContainEoL(text: string) { @@ -11,5 +11,5 @@ export function isContainEoL(text: string) { } export function startsWithComment(text: string) { - return text.startsWith('//') || text.startsWith('/*'); + return text.startsWith('//') || text.startsWith('/*') } From 9a0f16d40f97debad23987073a3a381832298763 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Tue, 22 Nov 2022 20:38:50 +0200 Subject: [PATCH 30/42] Prettier --- src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extension.ts b/src/extension.ts index 4515590..36cd0fc 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -111,5 +111,5 @@ export const activate = () => { waitUntil(performFixes()) }) - registerCommaOnEnter(); + registerCommaOnEnter() } From 534611f55c60fe06eb7ed0953a187e3113faa2ab Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Wed, 23 Nov 2022 00:54:25 +0300 Subject: [PATCH 31/42] add comma on enter integration tests --- .vscode/extensions.json | 5 ++ package.json | 5 +- pnpm-lock.yaml | 4 +- test/integration/suite/commaOnEnter.test.ts | 81 +++++++++++++++++++++ test/integration/suite/utils.ts | 18 +++++ 5 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 test/integration/suite/commaOnEnter.test.ts diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..cf0ac02 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "bierner.comment-tagged-templates" + ] +} diff --git a/package.json b/package.json index 29b21d9..482df79 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,7 @@ "@zardoy/tsconfig": "^1.2.2", "chokidar-cli": "^3.0.0", "cross-env": "^7.0.3", + "escape-string-regexp": "4.0.0", "eslint": "^8.18.0", "eslint-config-zardoy": "^0.2.11", "mocha": "^10.1.0", @@ -124,12 +125,12 @@ "typescript": "^4.5.2" }, "dependencies": { - "@zardoy/utils": "^0.0.10", - "strip-json-comments": "^5.0.0", "@vscode/test-electron": "^2.2.0", + "@zardoy/utils": "^0.0.10", "chai": "^4.3.7", "glob": "^8.0.3", "string-dedent": "^3.0.1", + "strip-json-comments": "^5.0.0", "vscode-framework": "^0.0.18" }, "prettier": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0c10e8d..f370eef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,7 @@ specifiers: chai: ^4.3.7 chokidar-cli: ^3.0.0 cross-env: ^7.0.3 + escape-string-regexp: 4.0.0 eslint: ^8.18.0 eslint-config-zardoy: ^0.2.11 glob: ^8.0.3 @@ -41,6 +42,7 @@ devDependencies: '@zardoy/tsconfig': 1.2.2_typescript@4.5.2 chokidar-cli: 3.0.0 cross-env: 7.0.3 + escape-string-regexp: 4.0.0 eslint: 8.18.0 eslint-config-zardoy: 0.2.11_5bodlipddqnyzje6uwgbuntqpu mocha: 10.1.0 @@ -1707,7 +1709,7 @@ packages: dev: false /escape-string-regexp/1.0.5: - resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} /escape-string-regexp/2.0.0: diff --git a/test/integration/suite/commaOnEnter.test.ts b/test/integration/suite/commaOnEnter.test.ts new file mode 100644 index 0000000..7f320cf --- /dev/null +++ b/test/integration/suite/commaOnEnter.test.ts @@ -0,0 +1,81 @@ +import * as vscode from 'vscode' + +import { expect } from 'chai' +import { clearEditorText, stringWithPositions } from './utils' +import dedent from 'string-dedent' + +describe('Comma on Enter', () => { + let document: vscode.TextDocument + let editor: vscode.TextEditor + + // positions markers description: + // | - valid position to insert comma after Enter (adding empty newline below) + // $ - invalid position to insert comma after Enter (adding empty newline below) + // use editor text selection highlighting for faster navigation between positions + const FULL_FIXTURE = dedent/* json */ ` + { + "key1": 43,/*$*/ + "key2": 43/*|*/ + /* key description */ "key3": "test"/*|*/ /* test comment */ // another commend + /*$*/ + "key4": true/*|*/ + "key4": false/*|*/ + } + ` + + const [FULL_FIXTURE_CONTENT, FIXTURE_POSITIONS] = stringWithPositions(FULL_FIXTURE, ['/*|*/', '/*$*/']) + + before(done => { + void vscode.workspace + .openTextDocument({ + content: FULL_FIXTURE_CONTENT, + language: 'jsonc', + }) + .then(async newDocument => { + document = newDocument + editor = await vscode.window.showTextDocument(document) + }) + .then(done) + }) + + const testPosition = (num: number, offset: number, isExpected: boolean) => { + it(`${isExpected ? 'Valid' : 'Invalid'} position ${num}`, async () => { + await clearEditorText(editor, FULL_FIXTURE_CONTENT) + const pos = document.positionAt(offset) + editor.selection = new vscode.Selection(pos, pos) + await vscode.commands.executeCommand('editor.action.insertLineAfter') + if (isExpected) { + // wait for expected changes to be done + await new Promise(resolve => { + const { dispose } = vscode.workspace.onDidChangeTextDocument(() => { + dispose() + resolve() + }) + }) + // assert that comma is inserted at expected marker position + expect(document.getText().at(offset)).to.equal(',') + } else { + // todo would be better to remove timeout in favor of cleaner solution + await new Promise(resolve => { + setTimeout(resolve, 40) + }) + // assert document text remains unchanged (except empty newline that we just added) + expect( + document + .getText() + .split('\n') + .filter((x, i) => i !== editor.selection.active.line) + .join('\n'), + ).to.equal(FULL_FIXTURE_CONTENT) + } + }) + } + + for (const [i, validPosition] of FIXTURE_POSITIONS['/*|*/'].entries()) { + testPosition(i, validPosition, true) + } + + for (const [i, invalidPosition] of FIXTURE_POSITIONS['/*$*/'].entries()) { + testPosition(i, invalidPosition, false) + } +}) diff --git a/test/integration/suite/utils.ts b/test/integration/suite/utils.ts index 5a2f662..e6640f7 100644 --- a/test/integration/suite/utils.ts +++ b/test/integration/suite/utils.ts @@ -1,5 +1,6 @@ import * as vscode from 'vscode' import stringDedent from 'string-dedent' +import escapeStringRegexp from 'escape-string-regexp' export const clearEditorText = async (editor: vscode.TextEditor, resetContent = '') => { await new Promise(resolve => { @@ -23,3 +24,20 @@ export const clearEditorText = async (editor: vscode.TextEditor, resetContent = export const setupFixtureContent = async (editor: vscode.TextEditor, content: string) => { await clearEditorText(editor, stringDedent(content)) } + +export const stringWithPositions = (contents: string, replacements: T[]): [contents: string, positions: Record] => { + const cursorPositions = Object.fromEntries(replacements.map(replacement => [replacement, []])) as Record + const regex = new RegExp(`(?:${replacements.map(replacement => `(${escapeStringRegexp(replacement)})`).join('|')})`) + let currentMatch: RegExpExecArray | null | undefined + while ((currentMatch = regex.exec(contents))) { + const offset = currentMatch.index + const matchLength = currentMatch[0]!.length + contents = contents.slice(0, offset) + contents.slice(offset + matchLength) + for (const [i, val] of currentMatch.slice(1).entries()) { + if (!val) continue + cursorPositions[replacements[i]!]!.push(offset) + break + } + } + return [contents, cursorPositions] +} From 73ba1eb1c9e1b14a5a58ad820e25c85942727e80 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Wed, 23 Nov 2022 00:55:53 +0300 Subject: [PATCH 32/42] fix tests --- src/commaOnEnter.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/commaOnEnter.ts b/src/commaOnEnter.ts index 8c3bacd..cb8c021 100644 --- a/src/commaOnEnter.ts +++ b/src/commaOnEnter.ts @@ -31,8 +31,6 @@ export default () => { for (const [i, change] of contentChanges.entries()) { const prevLine = document.lineAt(change.range.start.line + i) - if (startsWithComment(prevLine.text.trim())) continue - const currentLineText = document.lineAt(prevLine.lineNumber + 1).text.trim() const isCurrentLineEmpty = currentLineText.trim() === '' @@ -42,17 +40,16 @@ export default () => { fileContentWithoutComments ??= stripJsonComments(document.getText()) - const prevLineTextWithoutComments = getTextByLine(fileContentWithoutComments, prevLine.lineNumber)! - - const prevLineLastChar = prevLineTextWithoutComments.trimEnd().at(-1) + const prevLineWithoutComments = getTextByLine(fileContentWithoutComments, prevLine.lineNumber)!.trimEnd() - if (!prevLineLastChar) continue + if (!prevLineWithoutComments) continue - const isMatchValue = prevLineLastChar === '}' || prevLineLastChar === '"' || prevLineLastChar === ']' || isNumber(prevLineLastChar) + const isGoodEnding = + ['}', '"', ']', 'true', 'false'].some(char => prevLineWithoutComments.endsWith(char)) || isNumber(prevLineWithoutComments.at(-1)!) - if (!isMatchValue) continue + if (!isGoodEnding) continue - const insertPostion = new vscode.Position(prevLine.lineNumber, prevLineTextWithoutComments.trimEnd().length) + const insertPostion = new vscode.Position(prevLine.lineNumber, prevLineWithoutComments.length) edit.insert(insertPostion, ',') } From b01fa7eb83f223870ae0ddc9eff2269b3f20fa9e Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Wed, 23 Nov 2022 00:58:35 +0300 Subject: [PATCH 33/42] style: merge some if-return statements to reduce number of lines --- src/commaOnEnter.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/commaOnEnter.ts b/src/commaOnEnter.ts index cb8c021..efd0e9c 100644 --- a/src/commaOnEnter.ts +++ b/src/commaOnEnter.ts @@ -7,20 +7,21 @@ import { getTextByLine, isContainEoL, isNumber, startsWithComment } from './util export default () => { vscode.workspace.onDidChangeTextDocument(({ contentChanges, document, reason }) => { if (!getExtensionSetting('insertMissingCommaOnEnter')) return - - if (!vscode.languages.match(['json', 'jsonc'], document)) return - - if (contentChanges.length === 0) return - - contentChanges = [...contentChanges].sort((a, b) => a.range.start.compareTo(b.range.start)) + if (!vscode.languages.match(['json', 'jsonc'], document) || contentChanges.length === 0) return const editor = vscode.window.activeTextEditor - if (document.uri !== editor?.document.uri || ['output'].includes(editor.document.uri.scheme)) return - - if (vscode.workspace.fs.isWritableFileSystem(document.uri.scheme) === false) return + contentChanges = [...contentChanges].sort((a, b) => a.range.start.compareTo(b.range.start)) - if (oneOf(reason, vscode.TextDocumentChangeReason.Undo, vscode.TextDocumentChangeReason.Redo)) return + if ( + document.uri !== editor?.document.uri || + ['output'].includes(editor.document.uri.scheme) || + vscode.workspace.fs.isWritableFileSystem(document.uri.scheme) === false || + oneOf(reason, vscode.TextDocumentChangeReason.Undo, vscode.TextDocumentChangeReason.Redo) + // eslint-disable-next-line curly + ) { + return + } if (contentChanges.some(change => !isContainEoL(change.text))) return From 9fd0928f6397829ffe46835ce0c59d9f8424cd51 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Wed, 23 Nov 2022 01:02:24 +0300 Subject: [PATCH 34/42] update setting description (again) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1fabfcc..6e2c373 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "insertMissingCommaOnEnter": { "type": "boolean", "default": true, - "description": "Insert missing comma after \"Enter\". Works only if last JSON symbol on the line is `}`, `]`, `\"` or number" + "markdownDescription": "Insert missing comma after \"Enter\". Works only if JSON line ends with `}`, `]`, `\"`, `true`/`false` or number" } } } From 455461bfa80a131a0dddf29a93bc260484ba59a9 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Wed, 23 Nov 2022 01:13:26 +0300 Subject: [PATCH 35/42] ci: try to delay tests --- test/integration/suite/commaOnEnter.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/integration/suite/commaOnEnter.test.ts b/test/integration/suite/commaOnEnter.test.ts index 7f320cf..984ddde 100644 --- a/test/integration/suite/commaOnEnter.test.ts +++ b/test/integration/suite/commaOnEnter.test.ts @@ -34,6 +34,11 @@ describe('Comma on Enter', () => { .then(async newDocument => { document = newDocument editor = await vscode.window.showTextDocument(document) + if (process.env.CI) { + await new Promise(resolve => { + setTimeout(resolve, 1000) + }) + } }) .then(done) }) From 7bedc555ec7aacfea837999800ec3edd96d2f6fe Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Wed, 23 Nov 2022 01:46:43 +0300 Subject: [PATCH 36/42] workaround vscode builtin JSON bug --- test/integration/index.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/integration/index.ts b/test/integration/index.ts index 68779dc..c06ee03 100644 --- a/test/integration/index.ts +++ b/test/integration/index.ts @@ -10,10 +10,17 @@ export const run = async () => { }) const testsRoot = join(__dirname, './suite') await new Promise(resolve => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files: string[]) => { if (err) throw err - for (const file of files) mocha.addFile(join(testsRoot, file)) + const fixedOrderFiles = ['jsonFixes.test.js', 'commaOnEnter.test.js'] + + for (const file of fixedOrderFiles) { + mocha.addFile(join(testsRoot, file)) + } + for (const file of files.filter(file => !fixedOrderFiles.includes(file))) { + mocha.addFile(join(testsRoot, file)) + } mocha.run(failures => { if (failures > 0) { From 7ebb839983a40cd4daf49c9b22cb3be9a62ca8d7 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Wed, 23 Nov 2022 03:00:28 +0300 Subject: [PATCH 37/42] test: avoid falsey triggers because of other test files --- test/integration/suite/commaOnEnter.test.ts | 3 ++- test/integration/suite/jsonFixes.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/test/integration/suite/commaOnEnter.test.ts b/test/integration/suite/commaOnEnter.test.ts index 984ddde..c947447 100644 --- a/test/integration/suite/commaOnEnter.test.ts +++ b/test/integration/suite/commaOnEnter.test.ts @@ -52,7 +52,8 @@ describe('Comma on Enter', () => { if (isExpected) { // wait for expected changes to be done await new Promise(resolve => { - const { dispose } = vscode.workspace.onDidChangeTextDocument(() => { + const { dispose } = vscode.workspace.onDidChangeTextDocument(({ document: changedDocument }) => { + if (changedDocument !== document) return dispose() resolve() }) diff --git a/test/integration/suite/jsonFixes.test.ts b/test/integration/suite/jsonFixes.test.ts index 8aa7964..9ae703c 100644 --- a/test/integration/suite/jsonFixes.test.ts +++ b/test/integration/suite/jsonFixes.test.ts @@ -28,8 +28,8 @@ describe('Json Fixes', () => { for (const [name, content] of Object.entries(jsonFixesFixtures)) { it(`Fix JSON issues: ${name}`, async () => { const diagnosticsChangePromise = new Promise(resolve => { - vscode.languages.onDidChangeDiagnostics(() => { - resolve() + vscode.languages.onDidChangeDiagnostics(({ uris }) => { + if (uris.map(uri => uri.toString()).includes(document.uri.toString())) resolve() }) }) await Promise.all([setupFixtureContent(editor, content.input), diagnosticsChangePromise]) From 6eb46918ac6be33d4fe9992a6d9c2e05f8e9f0b9 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Wed, 23 Nov 2022 03:21:43 +0300 Subject: [PATCH 38/42] ci: try to ignore empty diagnostics update? --- test/integration/suite/jsonFixes.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/integration/suite/jsonFixes.test.ts b/test/integration/suite/jsonFixes.test.ts index 9ae703c..e9e7316 100644 --- a/test/integration/suite/jsonFixes.test.ts +++ b/test/integration/suite/jsonFixes.test.ts @@ -29,7 +29,9 @@ describe('Json Fixes', () => { it(`Fix JSON issues: ${name}`, async () => { const diagnosticsChangePromise = new Promise(resolve => { vscode.languages.onDidChangeDiagnostics(({ uris }) => { - if (uris.map(uri => uri.toString()).includes(document.uri.toString())) resolve() + if (!uris.map(uri => uri.toString()).includes(document.uri.toString())) return + if (vscode.languages.getDiagnostics(document.uri).length === 0) return + resolve() }) }) await Promise.all([setupFixtureContent(editor, content.input), diagnosticsChangePromise]) From 3e41c71e054e0dfd55de202b6e85c16b8cde7030 Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Wed, 23 Nov 2022 23:18:54 +0200 Subject: [PATCH 39/42] Add more tests --- test/integration/suite/commaOnEnter.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/integration/suite/commaOnEnter.test.ts b/test/integration/suite/commaOnEnter.test.ts index c947447..425557f 100644 --- a/test/integration/suite/commaOnEnter.test.ts +++ b/test/integration/suite/commaOnEnter.test.ts @@ -20,6 +20,11 @@ describe('Comma on Enter', () => { /*$*/ "key4": true/*|*/ "key4": false/*|*/ + "key5": []/*|*/ + "key6": {/*$*/ + }/*|*/ + "key7": "/*$*/ value", + // Comment with number 3/*$*/ } ` From db822512539284786a51c1e9f8c7c8870be59dce Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Wed, 23 Nov 2022 23:41:40 +0200 Subject: [PATCH 40/42] Change EoL checking --- src/commaOnEnter.ts | 4 ++-- src/utils.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commaOnEnter.ts b/src/commaOnEnter.ts index efd0e9c..6ab4d48 100644 --- a/src/commaOnEnter.ts +++ b/src/commaOnEnter.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode' import stripJsonComments from 'strip-json-comments' import { oneOf } from '@zardoy/utils' import { getExtensionSetting } from 'vscode-framework' -import { getTextByLine, isContainEoL, isNumber, startsWithComment } from './utils' +import { getTextByLine, isEoL, isNumber, startsWithComment } from './utils' export default () => { vscode.workspace.onDidChangeTextDocument(({ contentChanges, document, reason }) => { @@ -23,7 +23,7 @@ export default () => { return } - if (contentChanges.some(change => !isContainEoL(change.text))) return + if (contentChanges.some(change => !isEoL(change.text))) return let fileContentWithoutComments: string diff --git a/src/utils.ts b/src/utils.ts index da0ccba..3085814 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,8 +6,8 @@ export function isNumber(text: string) { return !Number.isNaN(Number.parseInt(text, 10)) } -export function isContainEoL(text: string) { - return text.includes('\n') || text.includes('\n\r') +export function isEoL(text: string) { + return text.startsWith('\n') && text.trim() === ''; } export function startsWithComment(text: string) { From fd8439f3bebb4b74de7911cd316dec77b872581e Mon Sep 17 00:00:00 2001 From: Agent_RBY_ Date: Thu, 24 Nov 2022 00:21:38 +0200 Subject: [PATCH 41/42] Format --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 3085814..ec61257 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -7,7 +7,7 @@ export function isNumber(text: string) { } export function isEoL(text: string) { - return text.startsWith('\n') && text.trim() === ''; + return text.startsWith('\n') && text.trim() === '' } export function startsWithComment(text: string) { From bc4451bebb1d92d1462600b0206a93285fa40948 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Thu, 24 Nov 2022 01:44:20 +0300 Subject: [PATCH 42/42] adjust tests --- test/integration/suite/commaOnEnter.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/integration/suite/commaOnEnter.test.ts b/test/integration/suite/commaOnEnter.test.ts index 425557f..8457f81 100644 --- a/test/integration/suite/commaOnEnter.test.ts +++ b/test/integration/suite/commaOnEnter.test.ts @@ -9,8 +9,8 @@ describe('Comma on Enter', () => { let editor: vscode.TextEditor // positions markers description: - // | - valid position to insert comma after Enter (adding empty newline below) - // $ - invalid position to insert comma after Enter (adding empty newline below) + // /*|*/ - valid position to insert comma after ctrl+Enter (adding empty newline below) + // /*$*/ - invalid position to insert comma after ctrl+Enter (adding empty newline below) // use editor text selection highlighting for faster navigation between positions const FULL_FIXTURE = dedent/* json */ ` { @@ -23,7 +23,7 @@ describe('Comma on Enter', () => { "key5": []/*|*/ "key6": {/*$*/ }/*|*/ - "key7": "/*$*/ value", + "key7": "value",/*$*/ // Comment with number 3/*$*/ } `