mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-29 20:32:44 +08:00
简化RunCode编码参数结构,新增ScriptEditor组件,优化CodeEditor代码提示
This commit is contained in:
parent
680360ef2c
commit
1d9a675803
@ -12,8 +12,36 @@
|
|||||||
<script>
|
<script>
|
||||||
import * as monaco from "monaco-editor";
|
import * as monaco from "monaco-editor";
|
||||||
import { toRaw } from "vue";
|
import { toRaw } from "vue";
|
||||||
|
import importAll from "js/common/importAll.js";
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
|
||||||
export default {
|
// 批量导入声明文件
|
||||||
|
let apis = importAll(
|
||||||
|
require.context("!raw-loader!plugins/monaco/types/", false, /\.ts$/)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 批量导入关键字补全
|
||||||
|
let languageCompletions = importAll(
|
||||||
|
require.context("plugins/monaco/completions/", false, /\.js$/)
|
||||||
|
);
|
||||||
|
|
||||||
|
let monacoCompletionProviders = {};
|
||||||
|
|
||||||
|
// 声明文件映射
|
||||||
|
const typeDefinitions = {
|
||||||
|
javascript: ["lib.es5.d.ts", "common.d.ts", "node.api.d.ts", "electron.d.ts"],
|
||||||
|
quickcommand: [
|
||||||
|
"lib.es5.d.ts",
|
||||||
|
"common.d.ts",
|
||||||
|
"node.api.d.ts",
|
||||||
|
"electron.d.ts",
|
||||||
|
"quickcommand.api.d.ts",
|
||||||
|
"utools.api.d.ts",
|
||||||
|
"shortcode.api.d.ts",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
name: "CodeEditor",
|
name: "CodeEditor",
|
||||||
props: {
|
props: {
|
||||||
// v-model 绑定值
|
// v-model 绑定值
|
||||||
@ -24,12 +52,12 @@ export default {
|
|||||||
// 编程语言
|
// 编程语言
|
||||||
language: {
|
language: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "plaintext",
|
default: "javascript",
|
||||||
},
|
},
|
||||||
// 编辑器高度
|
// 编辑器高度
|
||||||
height: {
|
height: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "200px",
|
default: "300px",
|
||||||
},
|
},
|
||||||
// 编辑器主题
|
// 编辑器主题
|
||||||
theme: {
|
theme: {
|
||||||
@ -128,6 +156,18 @@ export default {
|
|||||||
monaco.editor.setTheme(newValue ? "vs-dark" : "vs");
|
monaco.editor.setTheme(newValue ? "vs-dark" : "vs");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
language: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newValue) {
|
||||||
|
if (this.editor) {
|
||||||
|
const language = ["webjavascript", "quickcommand"].includes(newValue)
|
||||||
|
? "javascript"
|
||||||
|
: newValue;
|
||||||
|
monaco.editor.setModelLanguage(this.rawEditor().getModel(), language);
|
||||||
|
this.loadTypes();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initEditor();
|
this.initEditor();
|
||||||
@ -141,16 +181,22 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
// 初始化编辑器
|
// 初始化编辑器
|
||||||
initEditor() {
|
initEditor() {
|
||||||
|
const language = ["webjavascript", "quickcommand"].includes(this.language)
|
||||||
|
? "javascript"
|
||||||
|
: this.language;
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
...this.defaultOptions,
|
...this.defaultOptions,
|
||||||
...this.options,
|
...this.options,
|
||||||
value: this.value || "",
|
value: this.value || "",
|
||||||
language: this.language,
|
language,
|
||||||
theme: this.theme,
|
theme: this.theme,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.editor = monaco.editor.create(this.$refs.editorContainer, options);
|
this.editor = monaco.editor.create(this.$refs.editorContainer, options);
|
||||||
this.listenEditorValue();
|
this.listenEditorValue();
|
||||||
|
this.loadTypes();
|
||||||
|
this.registerLanguage();
|
||||||
|
|
||||||
// 初始化完成后立即触发一次布局更新
|
// 初始化完成后立即触发一次布局更新
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
@ -211,13 +257,129 @@ export default {
|
|||||||
this.editor.focus();
|
this.editor.focus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
registerLanguage() {
|
||||||
|
let that = this;
|
||||||
|
const identifierPattern = "([a-zA-Z_]\\w*)";
|
||||||
|
let getTokens = (code) => {
|
||||||
|
let identifier = new RegExp(identifierPattern, "g");
|
||||||
|
let tokens = [];
|
||||||
|
let array1;
|
||||||
|
while ((array1 = identifier.exec(code)) !== null) {
|
||||||
|
tokens.push(array1[0]);
|
||||||
|
}
|
||||||
|
return Array.from(new Set(tokens));
|
||||||
|
};
|
||||||
|
let createDependencyProposals = (range, keyWords, editor, curWord) => {
|
||||||
|
let keys = [];
|
||||||
|
// fix getValue of undefined
|
||||||
|
let tokens = getTokens(toRaw(editor).getModel()?.getValue());
|
||||||
|
// 自定义变量、字符串
|
||||||
|
for (const item of tokens) {
|
||||||
|
if (item != curWord.word) {
|
||||||
|
keys.push({
|
||||||
|
label: item,
|
||||||
|
kind: monaco.languages.CompletionItemKind.Text,
|
||||||
|
documentation: "",
|
||||||
|
insertText: item,
|
||||||
|
range: range,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 关键字、函数
|
||||||
|
Object.keys(keyWords).forEach((ItemKind) => {
|
||||||
|
keyWords[ItemKind].forEach((item) => {
|
||||||
|
keys.push({
|
||||||
|
label: item,
|
||||||
|
kind: monaco.languages.CompletionItemKind[ItemKind],
|
||||||
|
documentation: "",
|
||||||
|
insertText: item,
|
||||||
|
range: range,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return keys;
|
||||||
|
};
|
||||||
|
// 注册 applescript
|
||||||
|
monaco.languages.register({
|
||||||
|
id: "applescript",
|
||||||
|
});
|
||||||
|
// 注册自动补全
|
||||||
|
Object.keys(languageCompletions).forEach((language) => {
|
||||||
|
// 防止自动补全被多次注册
|
||||||
|
if (monacoCompletionProviders[language]) return;
|
||||||
|
monaco.languages.registerCompletionItemProvider(language, {
|
||||||
|
provideCompletionItems: function (model, position) {
|
||||||
|
var word = model.getWordUntilPosition(position);
|
||||||
|
var range = {
|
||||||
|
startLineNumber: position.lineNumber,
|
||||||
|
endLineNumber: position.lineNumber,
|
||||||
|
startColumn: word.startColumn,
|
||||||
|
endColumn: word.endColumn,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
suggestions: createDependencyProposals(
|
||||||
|
range,
|
||||||
|
languageCompletions[language].default,
|
||||||
|
toRaw(that.editor),
|
||||||
|
word
|
||||||
|
),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
monacoCompletionProviders[language] = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
loadTypes() {
|
||||||
|
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
||||||
|
noSemanticValidation: true,
|
||||||
|
noSyntaxValidation: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
target: monaco.languages.typescript.ScriptTarget.ES6,
|
||||||
|
allowNonTsExtensions: true,
|
||||||
|
allowJs: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// webjavascript 使用默认配置
|
||||||
|
if (this.language === "webjavascript") {
|
||||||
|
monaco.languages.typescript.javascriptDefaults.setCompilerOptions(
|
||||||
|
options
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他语言根据语言加载对应的声明文件
|
||||||
|
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||||
|
...options,
|
||||||
|
lib: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const files = typeDefinitions[this.language] || [];
|
||||||
|
const declarations = files.map((file) => {
|
||||||
|
try {
|
||||||
|
return require(`!raw-loader!plugins/monaco/types/${file}`).default;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`Failed to load type definition: ${file}`, e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (declarations.length > 0) {
|
||||||
|
// 添加声明文件
|
||||||
|
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
||||||
|
declarations.join("\n"),
|
||||||
|
"api.d.ts"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
showPlaceholder() {
|
showPlaceholder() {
|
||||||
return this.placeholder && (!this.value || this.value.trim() === "");
|
return this.placeholder && (!this.value || this.value.trim() === "");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -246,7 +408,6 @@ export default {
|
|||||||
.placeholder {
|
.placeholder {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
color: #535353;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@ -254,10 +415,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.code-editor:focus-within .placeholder {
|
.code-editor:focus-within .placeholder {
|
||||||
opacity: 1;
|
opacity: 0.3;
|
||||||
}
|
|
||||||
|
|
||||||
.body--dark .placeholder {
|
|
||||||
color: #666;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from "vue";
|
import { defineComponent, defineAsyncComponent } from "vue";
|
||||||
// 导入OptionEditor之外的通用组件,因为他还要被OptionEditor使用,防止循环引用
|
// 导入OptionEditor之外的通用组件,因为他还要被OptionEditor使用,防止循环引用
|
||||||
import VariableInput from "components/composer/common/VariableInput.vue";
|
import VariableInput from "components/composer/common/VariableInput.vue";
|
||||||
import NumberInput from "components/composer/common/NumberInput.vue";
|
import NumberInput from "components/composer/common/NumberInput.vue";
|
||||||
@ -22,8 +22,10 @@ import ButtonGroup from "components/composer/common/ButtonGroup.vue";
|
|||||||
import ControlInput from "components/composer/common/ControlInput.vue";
|
import ControlInput from "components/composer/common/ControlInput.vue";
|
||||||
import CheckGroup from "components/composer/common/CheckGroup.vue";
|
import CheckGroup from "components/composer/common/CheckGroup.vue";
|
||||||
import CheckButton from "components/composer/common/CheckButton.vue";
|
import CheckButton from "components/composer/common/CheckButton.vue";
|
||||||
import CodeEditor from "components/composer/common/CodeEditor.vue";
|
|
||||||
import { QInput, QSelect, QToggle, QCheckbox } from "quasar";
|
import { QInput, QSelect, QToggle, QCheckbox } from "quasar";
|
||||||
|
const CodeEditor = defineAsyncComponent(() =>
|
||||||
|
import("components/composer/common/CodeEditor.vue")
|
||||||
|
);
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "ParamInput",
|
name: "ParamInput",
|
||||||
@ -36,11 +38,11 @@ export default defineComponent({
|
|||||||
ControlInput,
|
ControlInput,
|
||||||
CheckGroup,
|
CheckGroup,
|
||||||
CheckButton,
|
CheckButton,
|
||||||
CodeEditor,
|
|
||||||
QToggle,
|
QToggle,
|
||||||
QInput,
|
QInput,
|
||||||
QSelect,
|
QSelect,
|
||||||
QCheckbox,
|
QCheckbox,
|
||||||
|
CodeEditor,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
config: {
|
config: {
|
||||||
|
266
src/components/composer/script/ScriptEditor.vue
Normal file
266
src/components/composer/script/ScriptEditor.vue
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
<template>
|
||||||
|
<div class="script-editor">
|
||||||
|
<!-- 代码编辑器 -->
|
||||||
|
<CodeEditor
|
||||||
|
:model-value="argvs.code"
|
||||||
|
@update:modelValue="updateArgvs('code', $event)"
|
||||||
|
:language="argvs.language"
|
||||||
|
/>
|
||||||
|
<div class="row q-col-gutter-sm">
|
||||||
|
<!-- 语言选择 -->
|
||||||
|
<q-select
|
||||||
|
:model-value="argvs.language"
|
||||||
|
@update:modelValue="updateArgvs('language', $event)"
|
||||||
|
:options="Object.keys(programs).slice(2, -1)"
|
||||||
|
label="编程语言"
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
class="col-6"
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<q-avatar size="sm" square>
|
||||||
|
<img :src="programs[argvs.language].icon" />
|
||||||
|
</q-avatar>
|
||||||
|
</template>
|
||||||
|
<template v-slot:option="scope">
|
||||||
|
<q-item v-bind="scope.itemProps">
|
||||||
|
<q-item-section avatar>
|
||||||
|
<img width="24" :src="programs[scope.opt].icon" />
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label v-html="scope.opt" />
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</template>
|
||||||
|
</q-select>
|
||||||
|
|
||||||
|
<!-- 编码设置 -->
|
||||||
|
<q-select
|
||||||
|
class="col-3"
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
:model-value="argvs.scriptCode"
|
||||||
|
@update:modelValue="updateArgvs('scriptCode', $event)"
|
||||||
|
label="脚本文件编码"
|
||||||
|
:options="charsetOptions"
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
/>
|
||||||
|
<q-select
|
||||||
|
class="col-3"
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
:model-value="argvs.outputCode"
|
||||||
|
@update:modelValue="updateArgvs('outputCode', $event)"
|
||||||
|
label="命令行输出编码"
|
||||||
|
:options="charsetOptions"
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row q-col-gutter-sm">
|
||||||
|
<div class="col-6">
|
||||||
|
<ArrayEditor
|
||||||
|
topLabel="脚本参数"
|
||||||
|
:model-value="argvs.args"
|
||||||
|
@update:modelValue="updateArgvs('args', $event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- 终端运行设置 -->
|
||||||
|
<div class="col-6">
|
||||||
|
<BorderLabel label="终端运行设置">
|
||||||
|
<div class="row q-col-gutter-sm">
|
||||||
|
<CheckButton
|
||||||
|
:model-value="!!argvs.runInTerminal"
|
||||||
|
@update:modelValue="toggleTerminal"
|
||||||
|
label="在终端中运行"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<template v-if="argvs.runInTerminal">
|
||||||
|
<VariableInput
|
||||||
|
:model-value="argvs.runInTerminal.dir"
|
||||||
|
@update:modelValue="updateTerminal('dir', $event)"
|
||||||
|
:options="{
|
||||||
|
dialog: {
|
||||||
|
type: 'open',
|
||||||
|
properties: ['openDirectory'],
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
label="运行目录"
|
||||||
|
/>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row q-col-gutter-sm">
|
||||||
|
<q-select
|
||||||
|
:model-value="argvs.runInTerminal.windows"
|
||||||
|
@update:modelValue="updateTerminal('windows', $event)"
|
||||||
|
:options="windowsTerminalOptions"
|
||||||
|
label="Windows终端"
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
class="col-6"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<q-select
|
||||||
|
:model-value="argvs.runInTerminal.macos"
|
||||||
|
@update:modelValue="updateTerminal('macos', $event)"
|
||||||
|
:options="macosTerminalOptions"
|
||||||
|
label="macOS终端"
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
class="col-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</BorderLabel>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import { newVarInputVal } from "js/composer/varInputValManager";
|
||||||
|
import CodeEditor from "components/composer/common/CodeEditor.vue";
|
||||||
|
import VariableInput from "components/composer/common/VariableInput.vue";
|
||||||
|
import ArrayEditor from "components/composer/common/ArrayEditor.vue";
|
||||||
|
import BorderLabel from "components/composer/common/BorderLabel.vue";
|
||||||
|
import CheckButton from "components/composer/common/CheckButton.vue";
|
||||||
|
import { parseFunction, stringifyArgv } from "js/composer/formatString";
|
||||||
|
import programs from "js/options/programs";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "ScriptEditor",
|
||||||
|
components: {
|
||||||
|
CodeEditor,
|
||||||
|
VariableInput,
|
||||||
|
ArrayEditor,
|
||||||
|
BorderLabel,
|
||||||
|
CheckButton,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
modelValue: Object,
|
||||||
|
},
|
||||||
|
emits: ["update:modelValue"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
defaultArgvs: {
|
||||||
|
code: "",
|
||||||
|
language: "python",
|
||||||
|
args: [],
|
||||||
|
scriptCode: null,
|
||||||
|
outputCode: null,
|
||||||
|
runInTerminal: null,
|
||||||
|
},
|
||||||
|
programs: programs,
|
||||||
|
windowsTerminalOptions: ["wt", "cmd"],
|
||||||
|
macosTerminalOptions: ["warp", "iterm", "terminal"],
|
||||||
|
charsetOptions: [
|
||||||
|
{ label: "自动", value: null },
|
||||||
|
{ label: "UTF-8", value: "utf-8" },
|
||||||
|
{ label: "GBK", value: "gbk" },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
argvs() {
|
||||||
|
return (
|
||||||
|
this.modelValue.argvs ||
|
||||||
|
this.parseCodeToArgvs(this.modelValue.code) ||
|
||||||
|
this.defaultArgvs
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
parseCodeToArgvs(code) {
|
||||||
|
if (!code) return this.defaultArgvs;
|
||||||
|
try {
|
||||||
|
const variableFormatPaths = ["arg1.args[*]"];
|
||||||
|
const result = parseFunction(code, { variableFormatPaths });
|
||||||
|
if (!result) return this.defaultArgvs;
|
||||||
|
|
||||||
|
const [scriptCode, options] = result.argvs;
|
||||||
|
return {
|
||||||
|
code: scriptCode,
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error("解析参数失败:", e);
|
||||||
|
return this.defaultArgvs;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
generateCode(argvs = this.argvs) {
|
||||||
|
const options = {
|
||||||
|
language: argvs.language,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argvs.scriptCode) {
|
||||||
|
options.scriptCode = argvs.scriptCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argvs.outputCode) {
|
||||||
|
options.outputCode = argvs.outputCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argvs.args?.length) {
|
||||||
|
options.args = argvs.args;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argvs.runInTerminal) {
|
||||||
|
options.runInTerminal = { ...argvs.runInTerminal };
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${this.modelValue.value}(${stringifyArgv(
|
||||||
|
argvs.code
|
||||||
|
)}, ${stringifyArgv(options)})`;
|
||||||
|
},
|
||||||
|
getSummary(argvs) {
|
||||||
|
return `运行${argvs.language}代码`;
|
||||||
|
},
|
||||||
|
updateArgvs(key, value) {
|
||||||
|
const newArgvs = { ...this.argvs, [key]: value };
|
||||||
|
this.updateModelValue(newArgvs);
|
||||||
|
},
|
||||||
|
toggleTerminal(value) {
|
||||||
|
const newArgvs = { ...this.argvs };
|
||||||
|
newArgvs.runInTerminal = value
|
||||||
|
? { dir: newVarInputVal("str", "") }
|
||||||
|
: null;
|
||||||
|
this.updateModelValue(newArgvs);
|
||||||
|
},
|
||||||
|
updateTerminal(key, value) {
|
||||||
|
const newTerminal = { ...this.argvs.runInTerminal, [key]: value };
|
||||||
|
const newArgvs = { ...this.argvs, runInTerminal: newTerminal };
|
||||||
|
this.updateModelValue(newArgvs);
|
||||||
|
},
|
||||||
|
updateModelValue(argvs) {
|
||||||
|
this.$emit("update:modelValue", {
|
||||||
|
...this.modelValue,
|
||||||
|
summary: this.getSummary(argvs),
|
||||||
|
code: this.generateCode(argvs),
|
||||||
|
argvs,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||||
|
if (!this.modelValue.code) {
|
||||||
|
this.updateModelValue(argvs);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.script-editor {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -273,9 +273,8 @@ export default {
|
|||||||
* @param options 选项
|
* @param options 选项
|
||||||
* @param options.language 编程语言
|
* @param options.language 编程语言
|
||||||
* @param options.args 脚本参数
|
* @param options.args 脚本参数
|
||||||
* @param options.charset 编码
|
* @param options.scriptCode 脚本文件编码
|
||||||
* @param options.charset.scriptCode 脚本编码
|
* @param options.outputCode 命令行输出编码
|
||||||
* @param options.charset.outputCode 输出编码
|
|
||||||
* @param options.runInTerminal 终端运行参数,不传则不在终端运行
|
* @param options.runInTerminal 终端运行参数,不传则不在终端运行
|
||||||
* @param options.runInTerminal.dir 运行目录
|
* @param options.runInTerminal.dir 运行目录
|
||||||
* @param options.runInTerminal.windows windows使用的终端,默认wt
|
* @param options.runInTerminal.windows windows使用的终端,默认wt
|
||||||
@ -286,11 +285,20 @@ export default {
|
|||||||
const isWin = window.utools.isWindows();
|
const isWin = window.utools.isWindows();
|
||||||
const {
|
const {
|
||||||
language = isWin ? "cmd" : "shell",
|
language = isWin ? "cmd" : "shell",
|
||||||
charset = {},
|
|
||||||
args = [],
|
args = [],
|
||||||
runInTerminal,
|
runInTerminal,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
|
if (!options.scriptCode) {
|
||||||
|
options.scriptCode = ["cmd", "powershell"].includes(language)
|
||||||
|
? "gbk"
|
||||||
|
: "utf-8";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.outputCode) {
|
||||||
|
options.outputCode = isWin ? "gbk" : "utf-8";
|
||||||
|
}
|
||||||
|
|
||||||
// 兼容编排,传入true时,使用默认终端
|
// 兼容编排,传入true时,使用默认终端
|
||||||
const runInTerminalOptions =
|
const runInTerminalOptions =
|
||||||
runInTerminal === true ? {} : runInTerminal;
|
runInTerminal === true ? {} : runInTerminal;
|
||||||
@ -306,23 +314,20 @@ export default {
|
|||||||
}
|
}
|
||||||
const argsStr = args.map(unescapeAndQuote).join(" ");
|
const argsStr = args.map(unescapeAndQuote).join(" ");
|
||||||
|
|
||||||
const defaultCharset =
|
|
||||||
isWin && ["cmd", "powershell"].includes(language) ? "gbk" : "utf-8";
|
|
||||||
|
|
||||||
const { scriptCode = defaultCharset, outputCode = defaultCharset } =
|
|
||||||
charset;
|
|
||||||
|
|
||||||
window.runCodeFile(
|
window.runCodeFile(
|
||||||
code,
|
code,
|
||||||
{
|
{
|
||||||
...programs[language],
|
...programs[language],
|
||||||
charset: { scriptCode, outputCode },
|
charset: {
|
||||||
|
scriptCode: options.scriptCode,
|
||||||
|
outputCode: options.outputCode,
|
||||||
|
},
|
||||||
scptarg: argsStr,
|
scptarg: argsStr,
|
||||||
},
|
},
|
||||||
runInTerminalOptions,
|
runInTerminalOptions,
|
||||||
(result, err) => (err ? reject(err) : reslove(result))
|
(result, err) => (err ? reject(err) : reslove(result)),
|
||||||
|
false
|
||||||
);
|
);
|
||||||
false;
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,3 +55,7 @@ export const SelectListEditor = defineAsyncComponent(() =>
|
|||||||
export const ReturnEditor = defineAsyncComponent(() =>
|
export const ReturnEditor = defineAsyncComponent(() =>
|
||||||
import("components/composer/script/ReturnEditor.vue")
|
import("components/composer/script/ReturnEditor.vue")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const ScriptEditor = defineAsyncComponent(() =>
|
||||||
|
import("components/composer/script/ScriptEditor.vue")
|
||||||
|
);
|
||||||
|
@ -311,6 +311,7 @@ export const browserCommands = {
|
|||||||
{
|
{
|
||||||
label: "脚本内容",
|
label: "脚本内容",
|
||||||
component: "CodeEditor",
|
component: "CodeEditor",
|
||||||
|
language: "webjavascript",
|
||||||
icon: "code",
|
icon: "code",
|
||||||
width: 12,
|
width: 12,
|
||||||
placeholder: "输入JavaScript代码,使用return返回结果",
|
placeholder: "输入JavaScript代码,使用return返回结果",
|
||||||
@ -382,6 +383,7 @@ export const browserCommands = {
|
|||||||
config: [
|
config: [
|
||||||
{
|
{
|
||||||
component: "CodeEditor",
|
component: "CodeEditor",
|
||||||
|
language: "css",
|
||||||
icon: "style",
|
icon: "style",
|
||||||
width: 12,
|
width: 12,
|
||||||
placeholder: "输入CSS代码",
|
placeholder: "输入CSS代码",
|
||||||
|
@ -1,26 +1,10 @@
|
|||||||
import programs from "js/options/programs";
|
|
||||||
|
|
||||||
export const scriptCommands = {
|
export const scriptCommands = {
|
||||||
label: "编程相关",
|
label: "编程相关",
|
||||||
icon: "integration_instructions",
|
icon: "integration_instructions",
|
||||||
commands: [
|
commands: [
|
||||||
{
|
|
||||||
value: "",
|
|
||||||
label: "赋值",
|
|
||||||
icon: "script",
|
|
||||||
outputVariable: "value",
|
|
||||||
saveOutput: true,
|
|
||||||
config: [
|
|
||||||
{
|
|
||||||
label: "值或表达式",
|
|
||||||
component: "VariableInput",
|
|
||||||
width: 12,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
value: "injectJs",
|
value: "injectJs",
|
||||||
label: "注入JS脚本",
|
label: "注入JS代码",
|
||||||
icon: "script",
|
icon: "script",
|
||||||
neverHasOutput: true,
|
neverHasOutput: true,
|
||||||
isExpression: true,
|
isExpression: true,
|
||||||
@ -28,6 +12,7 @@ export const scriptCommands = {
|
|||||||
{
|
{
|
||||||
label: "JS脚本",
|
label: "JS脚本",
|
||||||
component: "CodeEditor",
|
component: "CodeEditor",
|
||||||
|
language: "quickcommand",
|
||||||
placeholder:
|
placeholder:
|
||||||
"共享当前上下文,支持utools,quickcommand,quickcomposer等接口",
|
"共享当前上下文,支持utools,quickcommand,quickcomposer等接口",
|
||||||
width: 12,
|
width: 12,
|
||||||
@ -36,53 +21,10 @@ export const scriptCommands = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "quickcommand.runCode",
|
value: "quickcommand.runCode",
|
||||||
label: "执行代码",
|
label: "运行脚本",
|
||||||
icon: "script",
|
component: "ScriptEditor",
|
||||||
|
desc: "运行各种编程语言的代码",
|
||||||
isAsync: true,
|
isAsync: true,
|
||||||
outputVariable: "result",
|
|
||||||
saveOutput: true,
|
|
||||||
config: [
|
|
||||||
{
|
|
||||||
label: "脚本",
|
|
||||||
component: "CodeEditor",
|
|
||||||
placeholder: "需要本机安装了对应的解释器/编译器",
|
|
||||||
width: 12,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: "OptionEditor",
|
|
||||||
width: 12,
|
|
||||||
options: {
|
|
||||||
language: {
|
|
||||||
label: "语言",
|
|
||||||
component: "QSelect",
|
|
||||||
icon: "language",
|
|
||||||
options: Object.keys(programs).slice(2, -1),
|
|
||||||
width: 8,
|
|
||||||
},
|
|
||||||
runInTerminal: {
|
|
||||||
label: "终端运行",
|
|
||||||
icon: "terminal",
|
|
||||||
component: "CheckButton",
|
|
||||||
width: 4,
|
|
||||||
},
|
|
||||||
args: {
|
|
||||||
topLabel: "参数",
|
|
||||||
icon: "data_array",
|
|
||||||
component: "ArrayEditor",
|
|
||||||
width: 12,
|
|
||||||
},
|
|
||||||
charset: {
|
|
||||||
label: "编码",
|
|
||||||
icon: "abc",
|
|
||||||
component: "DictEditor",
|
|
||||||
options: {
|
|
||||||
optionKeys: ["scriptCode", "outputCode"],
|
|
||||||
},
|
|
||||||
width: 12,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "return",
|
value: "return",
|
||||||
|
@ -655,9 +655,8 @@ interface quickcommandApi {
|
|||||||
* @param options 选项
|
* @param options 选项
|
||||||
* @param options.language 编程语言,不传时则根据操作系统选择cmd或是shell
|
* @param options.language 编程语言,不传时则根据操作系统选择cmd或是shell
|
||||||
* @param options.args 脚本参数
|
* @param options.args 脚本参数
|
||||||
* @param options.charset 编码,不传时则根据操作系统及语言选择utf-8或是gbk
|
* @param options.scriptCode 脚本文件编码
|
||||||
* @param options.charset.scriptCode 脚本编码
|
* @param options.outputCode 命令行输出编码
|
||||||
* @param options.charset.outputCode 输出编码
|
|
||||||
* @param options.runInTerminal 终端运行参数,不传则不在终端运行
|
* @param options.runInTerminal 终端运行参数,不传则不在终端运行
|
||||||
* @param options.runInTerminal.dir 运行目录
|
* @param options.runInTerminal.dir 运行目录
|
||||||
* @param options.runInTerminal.windows windows使用的终端,默认wt
|
* @param options.runInTerminal.windows windows使用的终端,默认wt
|
||||||
@ -700,10 +699,8 @@ interface quickcommandApi {
|
|||||||
| "csharp"
|
| "csharp"
|
||||||
| "c";
|
| "c";
|
||||||
args?: string[];
|
args?: string[];
|
||||||
charset?: {
|
|
||||||
scriptCode?: string;
|
scriptCode?: string;
|
||||||
outputCode?: string;
|
outputCode?: string;
|
||||||
};
|
|
||||||
runInTerminal?: {
|
runInTerminal?: {
|
||||||
dir?: string;
|
dir?: string;
|
||||||
windows?: "wt" | "cmd";
|
windows?: "wt" | "cmd";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user