mirror of
https://github.com/purocean/yn.git
synced 2026-09-24 15:46:02 +08:00
feat(macro): add global macro replacement setting
This commit is contained in:
@@ -598,6 +598,10 @@ Using macro replacement may lead to inaccurate correspondence between source cod
|
||||
|
||||
The `define` field can define some text replacement mappings. Supports definition in another file, supports macro expressions. For details, please refer to the Front Matter at the top of this document.
|
||||
|
||||
::: tip
|
||||
You can define global macros in the <a href="javascript: ctx.setting.showSettingPanel('macros')">settings</a>. But you still need to define `enableMacro: true` in Front Matter.
|
||||
:::
|
||||
|
||||
- App Name: --APP_NAME--
|
||||
- App Version: --APP_VERSION--
|
||||
- From Another File: --TEST_DEFINE--
|
||||
|
||||
@@ -598,6 +598,10 @@ Yank Note 允许你在页面中嵌入宏,用以动态地替换文档。
|
||||
|
||||
Front Matter 中的 `define` 字段可以定义一些文本替换映射。支持在另一个文件定义,支持宏表达式。具体可参考本文件顶部 Front Matter 部分。
|
||||
|
||||
::: tip
|
||||
你还可以在设置中配置 *<a href="javascript: ctx.setting.showSettingPanel('macros')">全局宏替换</a>* ,这样所有文档都可以使用。不过,你仍然需要在 Front Matter 中定义 `enableMacro: true`。
|
||||
:::
|
||||
|
||||
- 应用名: --APP_NAME--
|
||||
- 应用版本: --APP_VERSION--
|
||||
- 另一个文件的定义: --TEST_DEFINE--
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { escapeRegExp, omit } from 'lodash-es'
|
||||
import frontMatter from 'front-matter'
|
||||
import type { Plugin } from '@fe/context'
|
||||
import type { Doc } from '@fe/types'
|
||||
import type { BuildInSettings, Doc } from '@fe/types'
|
||||
import type { MenuItem } from '@fe/services/status-bar'
|
||||
import { render } from '@fe/services/view'
|
||||
import { t } from '@fe/services/i18n'
|
||||
@@ -23,6 +23,7 @@ const magicNewline = '--yn-macro-new-line--'
|
||||
|
||||
const AsyncFunction = Object.getPrototypeOf(async () => 0).constructor
|
||||
let macroOuterVars = {}
|
||||
let globalMacroReplacement: Record<string, string> = {}
|
||||
|
||||
const globalVars = {
|
||||
$export: exportVar,
|
||||
@@ -95,7 +96,7 @@ function transform (
|
||||
callback?: (result: Result | Promise<Result>, match: string, matchPos: number) => void
|
||||
},
|
||||
) {
|
||||
const define = { ...vars.define, ...options.cache.$define }
|
||||
const define = { ...globalMacroReplacement, ...vars.define, ...options.cache.$define }
|
||||
vars.define = define
|
||||
const keys = Object.keys(define)
|
||||
if (keys.length) {
|
||||
@@ -421,5 +422,69 @@ export default {
|
||||
[/=\]/, { token: 'keyword', next: '@pop', nextEmbedded: '@pop' }]
|
||||
]
|
||||
})
|
||||
|
||||
ctx.setting.changeSchema(schema => {
|
||||
schema.groups.push({ label: 'T_setting-panel.tabs.macros', value: 'macros' })
|
||||
schema.properties.macros = {
|
||||
defaultValue: [],
|
||||
type: 'array',
|
||||
title: 'T_setting-panel.schema.repos.repos',
|
||||
format: 'table',
|
||||
group: 'macros',
|
||||
items: {
|
||||
type: 'object',
|
||||
title: 'T_setting-panel.schema.macros.macros',
|
||||
properties: {
|
||||
match: {
|
||||
type: 'string',
|
||||
title: 'T_setting-panel.schema.macros.match',
|
||||
defaultValue: '',
|
||||
maxLength: 50,
|
||||
options: {
|
||||
inputAttributes: { placeholder: 'T_setting-panel.schema.macros.match-placeholder' }
|
||||
},
|
||||
},
|
||||
replace: {
|
||||
type: 'string',
|
||||
title: 'T_setting-panel.schema.macros.replace',
|
||||
defaultValue: '',
|
||||
format: 'textarea',
|
||||
options: {
|
||||
inputAttributes: {
|
||||
placeholder: 'T_setting-panel.schema.macros.replace-placeholder',
|
||||
style: 'height: auto; resize: vertical; min-height: 37px;',
|
||||
rows: 1,
|
||||
}
|
||||
},
|
||||
}
|
||||
} as any
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
ctx.registerHook('SETTING_BEFORE_WRITE', ({ settings }) => {
|
||||
if (settings.macros && Array.isArray(settings.macros)) {
|
||||
settings.macros = settings.macros.filter(x => x.match && x.replace)
|
||||
}
|
||||
})
|
||||
|
||||
function buildGlobalMacroReplacement (settings: BuildInSettings) {
|
||||
const macros = settings.macros || []
|
||||
globalMacroReplacement = {}
|
||||
macros.forEach(x => {
|
||||
globalMacroReplacement[x.match] = x.replace
|
||||
})
|
||||
}
|
||||
|
||||
ctx.registerHook('SETTING_FETCHED', ({ settings }) => {
|
||||
buildGlobalMacroReplacement(settings)
|
||||
}, true)
|
||||
|
||||
ctx.registerHook('SETTING_CHANGED', ({ changedKeys, settings }) => {
|
||||
if (changedKeys.includes('macros')) {
|
||||
buildGlobalMacroReplacement(settings)
|
||||
ctx.view.render()
|
||||
}
|
||||
})
|
||||
}
|
||||
} as Plugin
|
||||
|
||||
@@ -498,7 +498,7 @@ export async function writeSettings (settings: Record<string, any>) {
|
||||
delete data.theme
|
||||
}
|
||||
|
||||
triggerHook('SETTING_BEFORE_WRITE', { settings } as any)
|
||||
triggerHook('SETTING_BEFORE_WRITE', { settings: data } as any)
|
||||
|
||||
await api.writeSettings(data)
|
||||
return await fetchSettings()
|
||||
|
||||
@@ -58,7 +58,7 @@ export default function startup () {
|
||||
const doc = getLastOpenFile()
|
||||
switchDoc(doc)
|
||||
|
||||
function changeLanguage ({ settings }: { settings: BuildInSettings }) {
|
||||
function changeLanguage ({ settings }: { settings: Partial<BuildInSettings> }) {
|
||||
if (settings.language && settings.language !== getLanguage()) {
|
||||
setLanguage(settings.language)
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ export type FileSort = { by: 'mtime' | 'birthtime' | 'name' | 'serial', order: '
|
||||
export type ThemeName = 'system' | 'dark' | 'light'
|
||||
export type LanguageName = 'system' | Language
|
||||
export type ExportType = 'print' | 'pdf' | 'docx' | 'html' | 'rst' | 'adoc'
|
||||
export type SettingGroup = 'repos' | 'appearance' | 'editor' | 'image' | 'proxy' | 'other'
|
||||
export type SettingGroup = 'repos' | 'appearance' | 'editor' | 'image' | 'proxy' | 'other' | 'macros'
|
||||
export type RegistryHostname = 'registry.npmjs.org' | 'registry.npmmirror.com'
|
||||
|
||||
export type PrintOpts = {
|
||||
@@ -233,6 +233,7 @@ export interface Extension {
|
||||
|
||||
export interface BuildInSettings {
|
||||
'repos': Repo[],
|
||||
'macros': { match: string, replace: string }[],
|
||||
'theme': ThemeName,
|
||||
'language': LanguageName,
|
||||
'auto-save': number,
|
||||
@@ -381,7 +382,7 @@ export type BuildInHookTypes = {
|
||||
SETTING_PANEL_BEFORE_SHOW: {},
|
||||
SETTING_CHANGED: { changedKeys: (keyof BuildInSettings)[], oldSettings: BuildInSettings, settings: BuildInSettings }
|
||||
SETTING_FETCHED: { settings: BuildInSettings, oldSettings: BuildInSettings },
|
||||
SETTING_BEFORE_WRITE: { settings: BuildInSettings },
|
||||
SETTING_BEFORE_WRITE: { settings: Partial<BuildInSettings> },
|
||||
EXTENSION_READY: { extensions: Extension[] },
|
||||
CODE_RUNNER_CHANGE: { type: 'register' | 'remove' },
|
||||
PLUGIN_HOOK: {
|
||||
|
||||
@@ -347,6 +347,7 @@ const data = {
|
||||
'editor': 'Editor',
|
||||
'image': 'Image',
|
||||
'proxy': 'Proxy',
|
||||
'macros': 'Macro',
|
||||
'other': 'Other',
|
||||
},
|
||||
'schema': {
|
||||
@@ -404,6 +405,13 @@ const data = {
|
||||
'bypass-list': 'Bypass List',
|
||||
'pac-url': 'PAC URL',
|
||||
},
|
||||
'macros': {
|
||||
'macros': 'Macros',
|
||||
'match': 'Match',
|
||||
'replace': 'Replace',
|
||||
'match-placeholder': '%foo%',
|
||||
'replace-placeholder': '%foo% -> BAR',
|
||||
},
|
||||
}
|
||||
},
|
||||
'quick-open': {
|
||||
|
||||
@@ -397,6 +397,13 @@ const data: BaseLanguage = {
|
||||
'bypass-list': 'Bypass List',
|
||||
'pac-url': 'PAC URL',
|
||||
},
|
||||
'macros': {
|
||||
'macros': '宏',
|
||||
'match': '匹配',
|
||||
'replace': '替换',
|
||||
'match-placeholder': '%foo%',
|
||||
'replace-placeholder': '%foo% -> BAR',
|
||||
},
|
||||
},
|
||||
'tabs': {
|
||||
'repos': '仓库',
|
||||
@@ -404,6 +411,7 @@ const data: BaseLanguage = {
|
||||
'editor': '编辑器',
|
||||
'image': '图片',
|
||||
'proxy': '代理',
|
||||
'macros': '宏替换',
|
||||
'other': '其他',
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user