From 3a4604a1f7b794633fc4dd398f8f5961e3fc25b1 Mon Sep 17 00:00:00 2001 From: ChenCMD Date: Tue, 8 Mar 2022 04:40:44 +0900 Subject: [PATCH 1/8] :children_crossing: Set prefill to input of expressionReplacer --- src/commands/multiLineGenerator/replacer/expression.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/multiLineGenerator/replacer/expression.ts b/src/commands/multiLineGenerator/replacer/expression.ts index 41fe3e5..aef8f57 100644 --- a/src/commands/multiLineGenerator/replacer/expression.ts +++ b/src/commands/multiLineGenerator/replacer/expression.ts @@ -4,7 +4,7 @@ import { listenInput } from '../../../utils'; import { Replacer } from '../types/Replacer'; export const expressionReplacer: Replacer = async (insertString, insertCount) => { - const expression = await listenInput(locale('expression.expression')); + const expression = await listenInput(locale('expression.expression'), undefined, '2x + 22'); const ans: string[] = []; try { @@ -18,7 +18,7 @@ export const expressionReplacer: Replacer = async (insertString, insertCount) => ans.push(insertString.replace(/%r/g, replaceData)); } // eslint-disable-next-line @typescript-eslint/no-explicit-any - } catch (e: any) { + } catch { throw new ParsingError(locale('error.not-expression')); } return ans; From 261a9c8907e7b83a15c394303069a955ad791363 Mon Sep 17 00:00:00 2001 From: ChenCMD Date: Tue, 8 Mar 2022 04:50:06 +0900 Subject: [PATCH 2/8] :bug: Fix paddingLength in serialNumberReplacer not work --- .../replacer/serialNumber.ts | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/commands/multiLineGenerator/replacer/serialNumber.ts b/src/commands/multiLineGenerator/replacer/serialNumber.ts index e13d00e..f80c013 100644 --- a/src/commands/multiLineGenerator/replacer/serialNumber.ts +++ b/src/commands/multiLineGenerator/replacer/serialNumber.ts @@ -3,9 +3,13 @@ import { makeExtendQuickPickItem } from '../../../types'; import { numberValidator, listenInput, listenPickItem, parseRadixFloat, stringValidator } from '../../../utils'; import { Replacer } from '../types/Replacer'; -const operators = ['+', '-', '*', '/'] as const; -type Operator = typeof operators[number]; -const operatorMap = new Map(operators.map(v => [v, v])); +type OpFunc = (a: number, b: number) => number; +const operatorMap = new Map([ + ['+', (a, b) => a + b], + ['-', (a, b) => a - b], + ['*', (a, b) => a * b], + ['/', (a, b) => a / b] +]); /* * 質問.1 基数 @@ -15,17 +19,17 @@ const operatorMap = new Map(operators.map(v => [v, v])); * 質問.5 0埋めの桁数 * */ -export const serialNumberReplacer: Replacer = async (insertString, insertCount) => { +export const serialNumberReplacer: Replacer = async (_insertString, insertCount) => { const radix = parseInt(await listenInput(locale('serial-number.radix'), v => numberValidator(v, { min: 2, max: 36, allowFloat: false }), 10)); const start = parseRadixFloat(await listenInput(locale('serial-number.start'), v => numberValidator(v, { radix }), 0), radix); - const { extend: operator } = await listenPickItem(locale('serial-number.operator'), makeExtendQuickPickItem(operatorMap, false), false); + const { label: operator, extend: opFunc } = await listenPickItem(locale('serial-number.operator'), makeExtendQuickPickItem(operatorMap, false), false); const step = parseRadixFloat(await listenInput(locale('serial-number.step'), v => { const res = numberValidator(v, { radix }); if (res) return res; if (operator === '/' && parseRadixFloat(v, radix) === 0) return locale('error.cant-divided-by-zero'); return undefined; }, 1), radix); - const paddingLength = parseInt(await listenInput(locale('serial-number.padding-length'), v => numberValidator(v, { radix, min: 0 }), 0), radix); + const paddingLength = parseInt(await listenInput(locale('serial-number.padding-length'), v => numberValidator(v, { radix, min: -1 }), -1), radix); const paddingChar = paddingLength >= 1 ? await listenInput(locale('serial-number.padding-char'), v => stringValidator(v, { minLength: 1, maxLength: 1 })) : '0'; @@ -33,21 +37,13 @@ export const serialNumberReplacer: Replacer = async (insertString, insertCount) const ans: string[] = []; let replaceValue = start; for (let i = 0; i < insertCount; i++) { - const replaceStr = replaceValue.toString(radix); - ans.push(insertString.replace(/%r/g, replaceStr.length <= paddingLength - ? `${paddingChar.repeat(paddingLength)}${replaceStr}`.slice(-paddingLength) - : replaceStr - )); - replaceValue = safeEval(replaceValue, operator, step); + ans.push(replaceValue.toString(radix)); + replaceValue = opFunc(replaceValue, step); } - return ans; -}; -function safeEval(a: number, operator: Operator, b: number): number { - switch (operator) { - case '+': return a + b; - case '-': return a - b; - case '*': return a * b; - case '/': return a / b; - } -} \ No newline at end of file + const maxLength = ans.reduce((a, b) => Math.max(a, b.length), 0); + + return paddingLength !== -1 + ? ans.map(str => paddingChar.repeat(maxLength - str.length + paddingLength) + str) + : ans; +}; \ No newline at end of file From d6f08a8a15883f526aed9eb8127230ca1b1c0522 Mon Sep 17 00:00:00 2001 From: ChenCMD Date: Tue, 8 Mar 2022 04:50:28 +0900 Subject: [PATCH 3/8] :recycle: Mini refactor --- src/commands/multiLineGenerator/replacer/string.ts | 5 +---- src/utils/vscodeWrapper.ts | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/commands/multiLineGenerator/replacer/string.ts b/src/commands/multiLineGenerator/replacer/string.ts index 605ba68..84e57b2 100644 --- a/src/commands/multiLineGenerator/replacer/string.ts +++ b/src/commands/multiLineGenerator/replacer/string.ts @@ -4,8 +4,5 @@ import { Replacer } from '../types/Replacer'; export const stringReplacer: Replacer = async (insertString, _, { extensionUri }) => { const replaceStrings = await listenInputMultiLine(extensionUri, locale('string.string')); - const ans: string[] = []; - for (const line of replaceStrings.split('\n')) - ans.push(insertString.replace(/%r/g, line)); - return ans; + return replaceStrings.split('\n').map(l => insertString.replace(/%r/g, l)); }; \ No newline at end of file diff --git a/src/utils/vscodeWrapper.ts b/src/utils/vscodeWrapper.ts index e248066..7798e63 100644 --- a/src/utils/vscodeWrapper.ts +++ b/src/utils/vscodeWrapper.ts @@ -54,7 +54,7 @@ export async function listenInput( } export function numberValidator(str: string, { radix = 10, allowFloat, min, max }: { radix?: number, allowFloat?: boolean, min?: number, max?: number } = {}): undefined | string { - if (!getRadixRegExp(radix, allowFloat !== false).test(str)) return locale('error.invalid-number'); + if (!getRadixRegExp(radix, allowFloat ?? true).test(str)) return locale('error.invalid-number'); if (min && min > parseRadixFloat(str, radix)) return locale('error.number-too-small', min); if (max && max < parseRadixFloat(str, radix)) return locale('error.number-too-large', max); return undefined; From 8251060f766db57a789ffde3d1f009380117bfec Mon Sep 17 00:00:00 2001 From: ChenCMD Date: Tue, 8 Mar 2022 05:00:29 +0900 Subject: [PATCH 4/8] :children_crossing: reduce question --- src/commands/multiLineGenerator/main.ts | 6 +++--- src/commands/multiLineGenerator/replacer/index.ts | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/commands/multiLineGenerator/main.ts b/src/commands/multiLineGenerator/main.ts index 0ba3721..9eed6b5 100644 --- a/src/commands/multiLineGenerator/main.ts +++ b/src/commands/multiLineGenerator/main.ts @@ -23,12 +23,12 @@ export async function generateMultiLine(ctx: FeatureContext): Promise { // 挿入する文字列の質問 const insertString = await listenInput(locale('insert-string'), v => stringValidator(v, { emptyMessage: locale('error.input-blank', locale('insert-string')) }), '%r'); + // 置換方法の選択 + const { extend: [replacer, insertCountRequired] } = await listenPickItem('', makeExtendQuickPickItem(getReplacerMap()), false); // 挿入する回数 - const insertCount = selections.length === 1 + const insertCount = insertCountRequired && selections.length === 1 ? parseInt(await listenInput(locale('insert-count'), v => numberValidator(v, { min: 1 }))) : selections.length; - // 置換方法の選択 - const { extend: replacer } = await listenPickItem('', makeExtendQuickPickItem(getReplacerMap()), false); // 置換方法毎の処理 const editData = await replacer(insertString, insertCount, ctx); // 置換 diff --git a/src/commands/multiLineGenerator/replacer/index.ts b/src/commands/multiLineGenerator/replacer/index.ts index f4c7445..95a289e 100644 --- a/src/commands/multiLineGenerator/replacer/index.ts +++ b/src/commands/multiLineGenerator/replacer/index.ts @@ -4,11 +4,11 @@ import { serialNumberReplacer } from './serialNumber'; import { stringReplacer } from './string'; import { tagsReplacer } from './tags'; -export function getReplacerMap(): Map { +export function getReplacerMap(): Map { return new Map([ - ['replacer.string', stringReplacer], - ['replacer.tags', tagsReplacer], - ['replacer.serial-number', serialNumberReplacer], - ['replacer.expression', expressionReplacer] + ['replacer.string', [stringReplacer, false]], + ['replacer.tags', [tagsReplacer, false]], + ['replacer.serial-number', [serialNumberReplacer, true]], + ['replacer.expression', [expressionReplacer, true]] ]); } \ No newline at end of file From 7d94c7be907ec7b8c279d1280ad17b86846a0065 Mon Sep 17 00:00:00 2001 From: ChenCMD Date: Tue, 8 Mar 2022 06:07:05 +0900 Subject: [PATCH 5/8] =?UTF-8?q?:children=5Fcrossing:=20=E8=A4=87=E9=9B=91?= =?UTF-8?q?=E3=81=AA=E5=BC=8F=E3=81=8C=E6=9B=B8=E3=81=91=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../multiLineGenerator/replacer/expression.ts | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/commands/multiLineGenerator/replacer/expression.ts b/src/commands/multiLineGenerator/replacer/expression.ts index aef8f57..46a8d95 100644 --- a/src/commands/multiLineGenerator/replacer/expression.ts +++ b/src/commands/multiLineGenerator/replacer/expression.ts @@ -1,25 +1,37 @@ import { locale } from '../../../locales'; import { ParsingError } from '../../../types'; -import { listenInput } from '../../../utils'; +import { listenInput, numberValidator, stringValidator } from '../../../utils'; import { Replacer } from '../types/Replacer'; export const expressionReplacer: Replacer = async (insertString, insertCount) => { - const expression = await listenInput(locale('expression.expression'), undefined, '2x + 22'); + const expression = await listenInput(locale('expression.expression'), undefined, 'y = 2x + 1'); + const paddingLength = parseInt(await listenInput(locale('serial-number.padding-length'), v => numberValidator(v, { min: -1 }), -1), 10); + const paddingChar = paddingLength >= 1 + ? await listenInput(locale('serial-number.padding-char'), v => stringValidator(v, { minLength: 1, maxLength: 1 })) + : '0'; const ans: string[] = []; try { for (let i = 1; i < insertCount + 1; i++) { - const replaceData = eval(expression + const replaceData: number = eval(expression .replace(/\s/g, '') - .replace(/\dx/g, m => `(${m.slice(0, 1)}*x)`) - .replace(/[^+\-*/]\(/g, m => `${m.slice(0, 1)}*(`) + .replace(/^.*=/, '') .replace(/\^/g, '**') - .replace(/x/g, i.toString())); - ans.push(insertString.replace(/%r/g, replaceData)); + .replace(/\dx/g, m => `${m.slice(0, 1)}*x`) + .replace(/^[x0-9]\(/g, m => `${m.slice(0, 1)}*(`) + .replace(/[0-9]\(/g, m => `${m.slice(0, 1)}*(`) + .replace(/[^a-zA-Z.]x\(/g, m => `${m.slice(0, 2)}*(`) + .replace(/[^a-zA-Z.]x/g, m => `${m.slice(0, 1)}${i.toString()}`)); + ans.push(insertString.replace(/%r/g, replaceData.toString(10))); } // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch { throw new ParsingError(locale('error.not-expression')); } - return ans; + + const maxLength = ans.reduce((a, b) => Math.max(a, b.length), 0); + + return paddingLength !== -1 + ? ans.map(str => paddingChar.repeat(maxLength - str.length + paddingLength) + str) + : ans; }; \ No newline at end of file From 3066b7f74c9d6f768a3b6d2e23c36e88350cfeed Mon Sep 17 00:00:00 2001 From: ChenCMD Date: Tue, 8 Mar 2022 06:12:35 +0900 Subject: [PATCH 6/8] =?UTF-8?q?:memo:=20README(ja)=E3=82=92=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README_ja.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/README_ja.md b/README_ja.md index c036c65..e29e0c0 100644 --- a/README_ja.md +++ b/README_ja.md @@ -17,6 +17,11 @@ - [データパックテンプレートの作成](#データパックテンプレートの作成) - [リソースパスのコピー](#リソースパスのコピー) - [素早いファイルの作成](#素早いファイルの作成) + - [複数行の一括入力](#複数行の一括入力) + - [文字列](#文字列) + - [データパックタグ](#データパックタグ) + - [連続した値](#連続した値) + - [数式](#数式) - [計算式のscore operationへの変換](#計算式のscore-operationへの変換) - [推奨事項](#推奨事項) - [謝辞](#謝辞) @@ -70,6 +75,56 @@ MC Datapack UtilityはVSCode Marketplaceからインストールすることが ![gif](https://raw.githubusercontent.com/ChenCMD/MC-Datapack-Utility/master/images/createFile.gif) +## 複数行の一括入力 + +何らかの規則性のある複数行を記述するのが面倒? + +`Alt + Shift + D -> Alt + Shift + M`を押しましょう。 +この機能を使うと、いくつかの質問に答えるだけで複数行をカーソルの位置に生成することができます。 + +選択によって最初の質問の`%r`の置換方法が変わります。以下はその種類です。 + +### 文字列 + +`%r`を自由な文字列で置換します。 +入力された文字列は行毎に解釈され、置換されます。 + +この置換方法はカーソルの個数によって挙動が異なるため注意してください。 + +#### カーソルの個数による生成時の挙動の差異 + +| カーソルが一個の時の挙動 | カーソルが複数個の時の挙動 | +| :--------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | +| カーソルの行を始めとして入力行数だけ生成 | 入力行数とカーソルの数が異なる場合: それぞれの箇所に入力内容が生成
入力行数とカーソルの数が同一の場合: カーソルの配置順に入力内容を1行ずつ生成 | + +### データパックタグ + +`%r`をデータパックタグの`values`で置換します。 + +この置換方法はカーソルの個数によって挙動が異なるため注意してください。 + +#### カーソルの個数による生成時の挙動の差異 + +| カーソルが一個の時の挙動 | カーソルが複数個の時の挙動 | +| :------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| カーソルの行を始めとしてタグの要素数だけ生成 | タグの要素数とカーソルの数が異なる場合: それぞれの箇所にタグの要素が生成
タグの要素数とカーソルの数が同一の場合: カーソルの配置順にタグの要素を1行ずつ生成 | + +### 連続した値 + +`%r`を一定の連続した値で置換します。 + +注意事項: `値を先頭埋めする長さ`が`-1`の場合、先頭埋めは行われません。 + +### 数式 + +`%r`を関数より算出される値で置換します。 +`Math.min(,)`や`Math.floor()`などが利用可能です。 + + +注意事項: `値を先頭埋めする長さ`が`-1`の場合、先頭埋めは行われません。 + + + ## 計算式のscore operationへの変換 scoreboard players operationで計算式を作るのが面倒? From 00dd4975befb287217582e14a7ba6830831331a5 Mon Sep 17 00:00:00 2001 From: ChenCMD Date: Tue, 8 Mar 2022 06:23:31 +0900 Subject: [PATCH 7/8] =?UTF-8?q?:globe=5Fwith=5Fmeridians:=20=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/en.json | 6 +++--- src/locales/ja.json | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index 7a11c8d..a2ad60f 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -59,7 +59,7 @@ "error.string-too-long": "The string must be shorter than %0%.", "error.string-too-short": "The string must be longer than %0%.", "error.unexpected-character": "%0% cannot be used.", - "expression.expression": "Number expression", + "expression.expression": "Expression", "formula-to-score-operation.complete-text": "If u wish, u can change both SCORE HOLDERs' NAME and the SCORE OBJECT", "formula-to-score-operation.formula": "Formula", "formula-to-score-operation.illegal-formula": "Invalid expression.", @@ -108,9 +108,9 @@ "punc.quote": "“%0%”", "quote": "a quote (“'” or “\"”)", "rename": "Rename", - "replacer.expression": "Number expression", + "replacer.expression": "Expression", "replacer.serial-number": "Consecutive values", - "replacer.string": "String", + "replacer.string": "Strings", "replacer.tags": "Datapack tag", "reselect": "Reselect", "select": "Select", diff --git a/src/locales/ja.json b/src/locales/ja.json index 2f8afbb..4f3eeed 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -59,7 +59,7 @@ "error.string-too-long": "文字列は%0%よりも短い必要があります。", "error.string-too-short": "文字列は%0%よりも長い必要があります。", "error.unexpected-character": "%0%は使用できません。", - "expression.expression": "数式", + "expression.expression": "式", "formula-to-score-operation.complete-text": "必要に応じて、スコアホルダー名とスコアオブジェクトを変更することができます", "formula-to-score-operation.formula": "計算式", "formula-to-score-operation.illegal-formula": "無効な式です。", @@ -108,7 +108,7 @@ "punc.quote": "「%0%」", "quote": "引用符 (‘'’ か ‘\"’)", "rename": "名前を変更", - "replacer.expression": "数式", + "replacer.expression": "式", "replacer.serial-number": "連続した値", "replacer.string": "文字列", "replacer.tags": "データパックタグ", From 5e629eb525380ecb6702589140ed65b2c88a8d8f Mon Sep 17 00:00:00 2001 From: ChenCMD Date: Tue, 8 Mar 2022 06:24:03 +0900 Subject: [PATCH 8/8] :memo: Update README --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ README_ja.md | 2 +- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 756fbab..8693484 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,11 @@ This extension provides several useful features for Datapack development. - [Creating a datapack template](#creating-a-datapack-template) - [Copy resourcePath](#copy-resourcepath) - [Quick file creation](#quick-file-creation) + - [Batch input of multiple lines](#batch-input-of-multiple-lines) + - [Strings](#strings) + - [Datapack tag](#datapack-tag) + - [Consecutive values](#consecutive-values) + - [Expression](#expression) - [Converting formulas to score operation](#converting-formulas-to-score-operation) - [Recommendations](#recommendations) - [Special Thanks](#special-thanks) @@ -70,6 +75,53 @@ You can create a file with the contents described by describing it. ![gif](https://raw.githubusercontent.com/ChenCMD/MC-Datapack-Utility/master/images/createFile.gif) +## Batch input of multiple lines + +Having trouble describing multiple lines with some regularity? + +Press `Alt + Shift + D -> Alt + Shift + M`. +This function allows you to generate multiple lines at the cursor position by simply answering a few questions. + +Depending on your choice, the method of replacing the `%r` in the first question will change. Here are the types + +### Strings + +Replace `%r` with any string. +The input string is interpreted line by line and replaced. + +Note that this substitution method behaves differently depending on the number of cursors. + +#### Difference in behavior when generating depending on the number of cursors + +| Behavior with a single cursor | Behavior with multiple cursors | +| :---------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Generate as many input lines as there are starting with the cursor line | If the number of input lines and the number of cursors are different:
input content is generated at each location
If the number of input lines and the number of cursors are the same:
input content is generated one line at a time in the order of cursor placement. | + +### Datapack tag + +Replace `%r` with the data pack tag `values`. + +Note that this substitution method behaves differently depending on the number of cursors. + +#### Difference in behavior when generating depending on the number of cursors + +| Behavior with a single cursor | Behavior with multiple cursors | +| :------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Generate as many tag elements as there are, starting with the cursor line | If the number of tag elements and the cursor are different:
a tag element is generated at each location
If the number of tag elements and the cursor are the same:
a tag element is generated one line at a time in the order in which the cursor is placed. | + +### Consecutive values + +Replace `%r` with a constant, continuous value. + +Note: If the `Length to pad the value at the beginning` is `-1`, no prefill is performed. + +### Expression + +Replace `%r` with the value calculated from the expression. +`Math.min(
,)`, `Math.floor()`, etc. are available. + +Note: If the `Length to pad the value at the beginning` is `-1`, no prefill is performed. + ## Converting formulas to score operation Too much trouble creating a formula in the scoreboard players operation? diff --git a/README_ja.md b/README_ja.md index e29e0c0..a83089f 100644 --- a/README_ja.md +++ b/README_ja.md @@ -77,7 +77,7 @@ MC Datapack UtilityはVSCode Marketplaceからインストールすることが ## 複数行の一括入力 -何らかの規則性のある複数行を記述するのが面倒? +規則性を持った複数行を記述するのが面倒? `Alt + Shift + D -> Alt + Shift + M`を押しましょう。 この機能を使うと、いくつかの質問に答えるだけで複数行をカーソルの位置に生成することができます。