@chengzhao-dev/dsh-cpp-workflow 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +2 -2
- package/README.md +2 -2
- package/lib/client.js +306 -119
- package/lib/comment-policy.js +6 -0
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -19,13 +19,13 @@ The exception material follows the C++ Core Guidelines' Error handling section a
|
|
|
19
19
|
Pinned npm install:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.6.
|
|
22
|
+
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.6.1
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
The matching Git tag:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.6.
|
|
28
|
+
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.6.1
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
The desktop app owns the `desktop` profile. If the command-line `add` is rejected, add the plugin in the app settings and use the same pinned npm version. A Git tag install uses the prebuilt `lib/` committed in the repository and runs no build on the target machine; the package has no install script that needs approval.
|
package/README.md
CHANGED
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
npm 安装钉死版本:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.6.
|
|
22
|
+
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.6.1
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
同版本的 Git 标签:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.6.
|
|
28
|
+
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.6.1
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
桌面应用独占 `desktop` profile。命令行 `add` 被拒绝时,在应用设置里添加插件,地址填同一个 npm 版本。Git 标签安装使用仓库内已构建的 `lib/`,不在目标机器上重新构建;包内也不含需要授权执行的安装脚本。
|
package/lib/client.js
CHANGED
|
@@ -57,6 +57,8 @@ const TAG_LABEL = {
|
|
|
57
57
|
tparam: '@tparam',
|
|
58
58
|
retval: '@retval',
|
|
59
59
|
};
|
|
60
|
+
/** 预览里的示例摘要:用户没填 @brief 时用它,避免预览出现空标签。 */
|
|
61
|
+
const SAMPLE_BRIEF = '定义井字棋棋盘、格子坐标与格子类型。';
|
|
60
62
|
/** 出厂配置:文件头只留 @file 与 @brief,契约标签全开,隐私标签全关。 */
|
|
61
63
|
const DEFAULT_CONFIG = {
|
|
62
64
|
brief: { enabled: true, value: '' },
|
|
@@ -120,6 +122,10 @@ function renderFileHeader(raw, fileName) {
|
|
|
120
122
|
function previewParts(raw, sampleName) {
|
|
121
123
|
const config = normalizeConfig(raw);
|
|
122
124
|
const header = renderFileHeader(config, sampleName || 'board.h');
|
|
125
|
+
// 预览是示例:@brief 开着但用户没填句子时,用示例文件自己的摘要顶替。
|
|
126
|
+
const briefIndex = header.indexOf('/// @brief');
|
|
127
|
+
if (briefIndex !== -1)
|
|
128
|
+
header[briefIndex] = `/// @brief ${SAMPLE_BRIEF}`;
|
|
123
129
|
const contract = [];
|
|
124
130
|
if (config.param)
|
|
125
131
|
contract.push('/// @param position 目标行列坐标。');
|
|
@@ -199,14 +205,21 @@ const STRINGS = {
|
|
|
199
205
|
title: '文档注释',
|
|
200
206
|
intro: '文件头与函数契约默认写出哪些 Doxygen 标签。配置只影响代理写注释的默认值,不改已有源码。',
|
|
201
207
|
header: '文件头',
|
|
208
|
+
headerHint: '每个手写源文件开头的一段 ///;带值的标签填写后写出,@brief 留空由文件自述。',
|
|
202
209
|
contract: '函数契约',
|
|
210
|
+
contractHint: '声明注释里的参数与失败方式;关闭后不再要求写出这些标签。',
|
|
203
211
|
extra: '更多标签',
|
|
204
212
|
extraHint: '默认关闭;需要时在单个函数上补写。',
|
|
205
213
|
file: '@file',
|
|
214
|
+
fixed: '自动',
|
|
206
215
|
fileHint: '固定为当前文件名,不参与配置。',
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
216
|
+
briefHint: '一句话说明本文件定义或实现什么;留空则由每个文件自己写。',
|
|
217
|
+
authorHint: '作者署名;留空不写。',
|
|
218
|
+
dateHint: '创建或修改日期;留空不写。',
|
|
219
|
+
copyrightHint: '版权声明;留空不写。',
|
|
220
|
+
versionHint: '文件版本号;留空不写。',
|
|
221
|
+
emptyValue: '留空不写',
|
|
222
|
+
briefEmpty: '留空则由文件自述',
|
|
210
223
|
preview: '预览',
|
|
211
224
|
previewHint: '示例文件名 board.h;预览随开关即时更新。',
|
|
212
225
|
save: '保存',
|
|
@@ -217,6 +230,7 @@ const STRINGS = {
|
|
|
217
230
|
loading: '正在读取配置…',
|
|
218
231
|
unreadable: '当前账户不能修改这份配置。',
|
|
219
232
|
readOnly: '此处只显示出厂值。要修改配置,请到「插件」页打开 dsh-cpp-workflow 的配置卡片。',
|
|
233
|
+
openSettings: '打开插件配置',
|
|
220
234
|
noForm: '这个入口没有可写表单,配置在插件页修改。',
|
|
221
235
|
},
|
|
222
236
|
en: {
|
|
@@ -224,14 +238,21 @@ const STRINGS = {
|
|
|
224
238
|
title: 'Documentation comments',
|
|
225
239
|
intro: 'Which Doxygen tags the agent writes by default. This changes defaults only; existing sources are untouched.',
|
|
226
240
|
header: 'File header',
|
|
241
|
+
headerHint: 'The /// block at the top of every hand-written source; value tags are written only when filled.',
|
|
227
242
|
contract: 'Function contract',
|
|
243
|
+
contractHint: 'Parameter and failure tags in declaration comments; turning one off stops requiring it.',
|
|
228
244
|
extra: 'More tags',
|
|
229
245
|
extraHint: 'Off by default; add them per function when needed.',
|
|
230
246
|
file: '@file',
|
|
247
|
+
fixed: 'Auto',
|
|
231
248
|
fileHint: 'Always the current file name; not configurable.',
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
249
|
+
briefHint: 'One sentence about what this file defines; leave empty and each file writes its own.',
|
|
250
|
+
authorHint: 'Author credit; left empty, omitted.',
|
|
251
|
+
dateHint: 'Creation or change date; left empty, omitted.',
|
|
252
|
+
copyrightHint: 'Copyright notice; left empty, omitted.',
|
|
253
|
+
versionHint: 'File version; left empty, omitted.',
|
|
254
|
+
emptyValue: 'Empty means omit',
|
|
255
|
+
briefEmpty: 'Empty: the file writes its own',
|
|
235
256
|
preview: 'Preview',
|
|
236
257
|
previewHint: 'Sample name board.h; the preview follows the switches.',
|
|
237
258
|
save: 'Save',
|
|
@@ -242,6 +263,7 @@ const STRINGS = {
|
|
|
242
263
|
loading: 'Reading configuration…',
|
|
243
264
|
unreadable: 'This account cannot edit the configuration.',
|
|
244
265
|
readOnly: 'Showing factory defaults. Edit the dsh-cpp-workflow card on the Plugins page.',
|
|
266
|
+
openSettings: 'Open plugin settings',
|
|
245
267
|
noForm: 'This entry has no writable form; edit it on the Plugins page.',
|
|
246
268
|
},
|
|
247
269
|
}
|
|
@@ -256,84 +278,152 @@ function t() {
|
|
|
256
278
|
}
|
|
257
279
|
|
|
258
280
|
const palette = {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
281
|
+
label: 'var(--dsw-alias-label-primary, inherit)',
|
|
282
|
+
muted: 'var(--dsw-alias-label-secondary, #6b7280)',
|
|
283
|
+
faint: 'var(--dsw-alias-label-tertiary, #8b93a1)',
|
|
284
|
+
line: 'var(--dsw-alias-border-l2, rgba(127, 127, 127, 0.24))',
|
|
285
|
+
surface: 'var(--dsw-alias-bg-layer-2, rgba(127, 127, 127, 0.06))',
|
|
286
|
+
field: 'var(--dsw-alias-bg-layer-1, rgba(127, 127, 127, 0.04))',
|
|
287
|
+
brand: 'var(--dsw-alias-brand-primary, #4f6bed)',
|
|
262
288
|
mono: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',
|
|
263
289
|
}
|
|
264
290
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
291
|
+
const hintStyle = () => ({ margin: '2px 0 0', fontSize: 12, lineHeight: 1.55, color: palette.muted })
|
|
292
|
+
const labelCellStyle = () => ({
|
|
293
|
+
padding: '10px 0',
|
|
294
|
+
fontFamily: palette.mono,
|
|
295
|
+
fontSize: 12.5,
|
|
296
|
+
lineHeight: '20px',
|
|
297
|
+
color: palette.label,
|
|
298
|
+
whiteSpace: 'nowrap',
|
|
299
|
+
borderBottom: `1px solid ${palette.line}`,
|
|
300
|
+
})
|
|
301
|
+
const controlCellStyle = () => ({
|
|
302
|
+
padding: '10px 0',
|
|
303
|
+
minWidth: 0,
|
|
304
|
+
borderBottom: `1px solid ${palette.line}`,
|
|
305
|
+
})
|
|
306
|
+
const gridStyle = () => ({ display: 'grid', gridTemplateColumns: '92px minmax(0, 1fr)', columnGap: 14 })
|
|
279
307
|
|
|
280
|
-
function
|
|
308
|
+
function Toggle(props) {
|
|
281
309
|
return h(
|
|
282
|
-
'
|
|
283
|
-
{
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
checked: Boolean(props.checked),
|
|
310
|
+
'button',
|
|
311
|
+
{
|
|
312
|
+
type: 'button',
|
|
313
|
+
role: 'switch',
|
|
314
|
+
'aria-checked': Boolean(props.checked),
|
|
315
|
+
'aria-label': props.label,
|
|
287
316
|
disabled: Boolean(props.disabled),
|
|
288
|
-
|
|
289
|
-
style: {
|
|
317
|
+
onClick: () => props.onChange(!props.checked),
|
|
318
|
+
style: {
|
|
319
|
+
flex: 'none',
|
|
320
|
+
width: 34,
|
|
321
|
+
height: 20,
|
|
322
|
+
padding: 0,
|
|
323
|
+
border: 0,
|
|
324
|
+
borderRadius: 999,
|
|
325
|
+
position: 'relative',
|
|
326
|
+
cursor: props.disabled ? 'default' : 'pointer',
|
|
327
|
+
opacity: props.disabled ? 0.5 : 1,
|
|
328
|
+
background: props.checked ? palette.brand : 'var(--dsw-alias-bg-layer-4, rgba(127, 127, 127, 0.35))',
|
|
329
|
+
transition: 'background-color 0.15s ease',
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
h('span', {
|
|
333
|
+
'aria-hidden': 'true',
|
|
334
|
+
style: {
|
|
335
|
+
position: 'absolute',
|
|
336
|
+
top: 2,
|
|
337
|
+
left: props.checked ? 16 : 2,
|
|
338
|
+
width: 16,
|
|
339
|
+
height: 16,
|
|
340
|
+
borderRadius: '50%',
|
|
341
|
+
background: '#fff',
|
|
342
|
+
boxShadow: '0 1px 2px rgba(0, 0, 0, 0.25)',
|
|
343
|
+
transition: 'left 0.15s ease',
|
|
344
|
+
},
|
|
290
345
|
}),
|
|
291
|
-
h('span', { style: { fontSize: 13, fontFamily: palette.mono } }, props.label),
|
|
292
346
|
)
|
|
293
347
|
}
|
|
294
348
|
|
|
295
|
-
function
|
|
349
|
+
function TagRow(props) {
|
|
296
350
|
const s = props.strings
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
h(
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
h('p', { style: hintStyle() },
|
|
351
|
+
return [
|
|
352
|
+
h('div', { key: `${props.tag}-label`, style: labelCellStyle() }, props.label),
|
|
353
|
+
h(
|
|
354
|
+
'div',
|
|
355
|
+
{ key: `${props.tag}-control`, style: controlCellStyle() },
|
|
356
|
+
h(
|
|
357
|
+
'div',
|
|
358
|
+
{ style: { display: 'flex', alignItems: 'center', gap: 10, minHeight: 22, flexWrap: 'wrap' } },
|
|
359
|
+
props.control,
|
|
360
|
+
),
|
|
361
|
+
props.hint ? h('p', { style: hintStyle() }, props.hint) : null,
|
|
308
362
|
),
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
363
|
+
]
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function ValueRow(props) {
|
|
367
|
+
const s = props.strings
|
|
368
|
+
return h(TagRow, {
|
|
369
|
+
tag: props.tag,
|
|
370
|
+
label: TAG_LABEL[props.tag],
|
|
371
|
+
strings: s,
|
|
372
|
+
hint: props.hint,
|
|
373
|
+
control: [
|
|
374
|
+
h(Toggle, {
|
|
375
|
+
key: 'toggle',
|
|
376
|
+
label: props.label || TAG_LABEL[props.tag],
|
|
377
|
+
checked: props.entry.enabled,
|
|
378
|
+
disabled: props.disabled,
|
|
379
|
+
onChange: (enabled) => !props.disabled && props.onChange({ ...props.entry, enabled }),
|
|
380
|
+
}),
|
|
381
|
+
h('input', {
|
|
382
|
+
key: 'input',
|
|
383
|
+
type: 'text',
|
|
384
|
+
value: props.entry.value,
|
|
385
|
+
placeholder: props.tag === 'brief' ? s.briefEmpty : s.emptyValue,
|
|
386
|
+
disabled: props.disabled || !props.entry.enabled,
|
|
387
|
+
'aria-label': TAG_LABEL[props.tag],
|
|
388
|
+
onChange: (event) => props.onChange({ ...props.entry, value: event.target.value }),
|
|
389
|
+
style: {
|
|
390
|
+
flex: '1 1 180px',
|
|
391
|
+
minWidth: 0,
|
|
392
|
+
maxWidth: 320,
|
|
393
|
+
fontSize: 13,
|
|
394
|
+
padding: '4px 8px',
|
|
395
|
+
borderRadius: 6,
|
|
396
|
+
border: `1px solid ${palette.line}`,
|
|
397
|
+
background: props.entry.enabled && !props.disabled ? palette.field : 'transparent',
|
|
398
|
+
color: props.entry.enabled ? 'inherit' : palette.muted,
|
|
399
|
+
fontFamily: palette.mono,
|
|
400
|
+
},
|
|
401
|
+
}),
|
|
402
|
+
],
|
|
403
|
+
})
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function FlagRow(props) {
|
|
407
|
+
return h(TagRow, {
|
|
408
|
+
tag: props.tag,
|
|
409
|
+
label: TAG_LABEL[props.tag],
|
|
410
|
+
strings: props.strings,
|
|
411
|
+
hint: props.hint,
|
|
412
|
+
control: h(Toggle, {
|
|
413
|
+
label: TAG_LABEL[props.tag],
|
|
414
|
+
checked: Boolean(props.checked),
|
|
415
|
+
disabled: props.disabled,
|
|
416
|
+
onChange: (value) => !props.disabled && props.onChange(value),
|
|
326
417
|
}),
|
|
327
|
-
)
|
|
418
|
+
})
|
|
328
419
|
}
|
|
329
420
|
|
|
330
421
|
function Preview(props) {
|
|
331
422
|
const s = props.strings
|
|
332
|
-
const text = previewText(props.config, SAMPLE_FILE)
|
|
333
423
|
return h(
|
|
334
424
|
'section',
|
|
335
|
-
{ 'aria-label': s.preview, style: { marginTop:
|
|
336
|
-
h('h4', { style: { margin: '0 0 4px', fontSize: 13, fontWeight: 600 } }, s.preview),
|
|
425
|
+
{ 'aria-label': s.preview, style: { marginTop: 20 } },
|
|
426
|
+
h('h4', { style: { margin: '0 0 4px', fontSize: 13, fontWeight: 600, color: palette.label } }, s.preview),
|
|
337
427
|
h('p', { style: hintStyle() }, s.previewHint),
|
|
338
428
|
h(
|
|
339
429
|
'pre',
|
|
@@ -349,9 +439,10 @@ function Preview(props) {
|
|
|
349
439
|
lineHeight: 1.65,
|
|
350
440
|
fontFamily: palette.mono,
|
|
351
441
|
whiteSpace: 'pre',
|
|
442
|
+
color: palette.label,
|
|
352
443
|
},
|
|
353
444
|
},
|
|
354
|
-
|
|
445
|
+
previewText(props.config, SAMPLE_FILE),
|
|
355
446
|
),
|
|
356
447
|
)
|
|
357
448
|
}
|
|
@@ -421,74 +512,127 @@ function ConfigPage(props) {
|
|
|
421
512
|
|
|
422
513
|
const editable = Boolean(form)
|
|
423
514
|
const editableReady = editable && ready
|
|
424
|
-
const
|
|
515
|
+
const header = [
|
|
516
|
+
{ tag: 'brief', hint: s.briefHint },
|
|
517
|
+
{ tag: 'author', hint: s.authorHint },
|
|
518
|
+
{ tag: 'date', hint: s.dateHint },
|
|
519
|
+
{ tag: 'copyright', hint: s.copyrightHint },
|
|
520
|
+
{ tag: 'version', hint: s.versionHint },
|
|
521
|
+
]
|
|
522
|
+
const contractHints = { param: TAG_TEXT.param, returns: TAG_TEXT.returns, throws: TAG_TEXT.throws }
|
|
523
|
+
const extraHints = { note: TAG_TEXT.note, see: TAG_TEXT.see, pre: TAG_TEXT.pre, post: TAG_TEXT.post, tparam: TAG_TEXT.tparam, retval: TAG_TEXT.retval }
|
|
425
524
|
|
|
426
525
|
return h(
|
|
427
526
|
'div',
|
|
428
|
-
{ style: { display: 'flex', flexDirection: 'column',
|
|
429
|
-
h('h3', { style: { margin: '0 0
|
|
527
|
+
{ style: { display: 'flex', flexDirection: 'column', padding: '4px 0 12px', maxWidth: 720, color: palette.label } },
|
|
528
|
+
h('h3', { style: { margin: '0 0 4px', fontSize: 15, fontWeight: 600 } }, s.title),
|
|
430
529
|
h('p', { style: hintStyle() }, s.intro),
|
|
431
530
|
!editable
|
|
432
|
-
? h(
|
|
531
|
+
? h(
|
|
532
|
+
'div',
|
|
533
|
+
{ style: { display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap', marginTop: 8 } },
|
|
534
|
+
h('p', { role: 'status', style: { ...hintStyle(), margin: 0 } }, s.readOnly),
|
|
535
|
+
props.openPluginPage
|
|
536
|
+
? h('button', { type: 'button', onClick: props.openPluginPage, style: secondaryButton(true) }, s.openSettings)
|
|
537
|
+
: null,
|
|
538
|
+
)
|
|
433
539
|
: null,
|
|
434
540
|
editable && !ready && status !== 'missing'
|
|
435
541
|
? h('p', { role: 'status', style: hintStyle() }, status === 'loading' ? s.loading : s.unreadable)
|
|
436
542
|
: null,
|
|
437
543
|
h(
|
|
438
|
-
'
|
|
439
|
-
{ style: {
|
|
440
|
-
h('
|
|
544
|
+
'section',
|
|
545
|
+
{ style: { marginTop: 18 } },
|
|
546
|
+
h('h4', { style: { margin: '0 0 4px', fontSize: 13, fontWeight: 600 } }, s.header),
|
|
547
|
+
h('p', { style: hintStyle() }, s.headerHint),
|
|
441
548
|
h(
|
|
442
549
|
'div',
|
|
443
|
-
{ style:
|
|
444
|
-
h(
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
550
|
+
{ role: 'group', 'aria-label': s.header, style: { ...gridStyle(), marginTop: 8 } },
|
|
551
|
+
h(
|
|
552
|
+
'div',
|
|
553
|
+
{ key: 'file-label', style: labelCellStyle() },
|
|
554
|
+
s.file,
|
|
555
|
+
),
|
|
556
|
+
h(
|
|
557
|
+
'div',
|
|
558
|
+
{ key: 'file-control', style: controlCellStyle() },
|
|
559
|
+
h(
|
|
560
|
+
'div',
|
|
561
|
+
{ style: { display: 'flex', alignItems: 'center', gap: 10, minHeight: 22 } },
|
|
562
|
+
h(
|
|
563
|
+
'span',
|
|
564
|
+
{
|
|
565
|
+
style: {
|
|
566
|
+
fontSize: 12,
|
|
567
|
+
lineHeight: '20px',
|
|
568
|
+
padding: '0 8px',
|
|
569
|
+
borderRadius: 999,
|
|
570
|
+
border: `1px solid ${palette.line}`,
|
|
571
|
+
color: palette.muted,
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
s.fixed,
|
|
575
|
+
),
|
|
576
|
+
h('code', { style: { fontSize: 12.5, fontFamily: palette.mono, color: palette.muted } }, SAMPLE_FILE),
|
|
577
|
+
),
|
|
578
|
+
h('p', { style: hintStyle() }, s.fileHint),
|
|
579
|
+
),
|
|
580
|
+
...header.flatMap(({ tag, hint }) =>
|
|
581
|
+
h(ValueRow, {
|
|
582
|
+
key: tag,
|
|
583
|
+
tag,
|
|
584
|
+
hint,
|
|
585
|
+
strings: s,
|
|
586
|
+
disabled: !editable,
|
|
587
|
+
entry: draft[tag],
|
|
588
|
+
onChange: (entry) => update({ [tag]: entry }),
|
|
589
|
+
}),
|
|
590
|
+
),
|
|
455
591
|
),
|
|
456
592
|
),
|
|
457
593
|
h(
|
|
458
|
-
'
|
|
459
|
-
{ style: {
|
|
460
|
-
h('
|
|
594
|
+
'section',
|
|
595
|
+
{ style: { marginTop: 20 } },
|
|
596
|
+
h('h4', { style: { margin: '0 0 4px', fontSize: 13, fontWeight: 600 } }, s.contract),
|
|
597
|
+
h('p', { style: hintStyle() }, s.contractHint),
|
|
461
598
|
h(
|
|
462
599
|
'div',
|
|
463
|
-
{
|
|
464
|
-
...CONTRACT_TAGS.
|
|
465
|
-
h(
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}),
|
|
473
|
-
|
|
474
|
-
),
|
|
600
|
+
{ role: 'group', 'aria-label': s.contract, style: { ...gridStyle(), marginTop: 8 } },
|
|
601
|
+
...CONTRACT_TAGS.flatMap((tag) =>
|
|
602
|
+
h(FlagRow, {
|
|
603
|
+
key: tag,
|
|
604
|
+
tag,
|
|
605
|
+
hint: contractHints[tag],
|
|
606
|
+
strings: s,
|
|
607
|
+
disabled: !editable,
|
|
608
|
+
checked: draft[tag],
|
|
609
|
+
onChange: (value) => update({ [tag]: value }),
|
|
610
|
+
}),
|
|
475
611
|
),
|
|
476
612
|
),
|
|
477
613
|
),
|
|
478
614
|
h(
|
|
479
|
-
'
|
|
480
|
-
{ style: { marginTop:
|
|
481
|
-
h('summary', { style: { cursor: 'pointer', fontSize: 13, fontWeight: 600 } }, s.extra),
|
|
482
|
-
h('p', { style: hintStyle() }, s.extraHint),
|
|
615
|
+
'section',
|
|
616
|
+
{ style: { marginTop: 20, paddingTop: 12, borderTop: `1px solid ${palette.line}` } },
|
|
483
617
|
h(
|
|
484
|
-
'
|
|
485
|
-
{
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
618
|
+
'details',
|
|
619
|
+
{},
|
|
620
|
+
h(
|
|
621
|
+
'summary',
|
|
622
|
+
{ style: { cursor: 'pointer', fontSize: 13, fontWeight: 600, listStylePosition: 'inside' } },
|
|
623
|
+
s.extra,
|
|
624
|
+
),
|
|
625
|
+
h('p', { style: hintStyle() }, s.extraHint),
|
|
626
|
+
h(
|
|
627
|
+
'div',
|
|
628
|
+
{ role: 'group', 'aria-label': s.extra, style: { ...gridStyle(), marginTop: 8 } },
|
|
629
|
+
...EXTRA_TAGS.flatMap((tag) =>
|
|
630
|
+
h(FlagRow, {
|
|
631
|
+
key: tag,
|
|
632
|
+
tag,
|
|
633
|
+
hint: extraHints[tag],
|
|
634
|
+
strings: s,
|
|
635
|
+
disabled: !editable,
|
|
492
636
|
checked: draft[tag],
|
|
493
637
|
onChange: (value) => update({ [tag]: value }),
|
|
494
638
|
}),
|
|
@@ -500,14 +644,24 @@ function ConfigPage(props) {
|
|
|
500
644
|
editable
|
|
501
645
|
? h(
|
|
502
646
|
'div',
|
|
503
|
-
{
|
|
647
|
+
{
|
|
648
|
+
style: {
|
|
649
|
+
display: 'flex',
|
|
650
|
+
alignItems: 'center',
|
|
651
|
+
gap: 10,
|
|
652
|
+
marginTop: 18,
|
|
653
|
+
paddingTop: 12,
|
|
654
|
+
borderTop: `1px solid ${palette.line}`,
|
|
655
|
+
flexWrap: 'wrap',
|
|
656
|
+
},
|
|
657
|
+
},
|
|
504
658
|
h(
|
|
505
659
|
'button',
|
|
506
660
|
{
|
|
507
661
|
type: 'button',
|
|
508
662
|
onClick: save,
|
|
509
663
|
disabled: busy || !editableReady || !dirty,
|
|
510
|
-
style:
|
|
664
|
+
style: primaryButton(dirty && editableReady && !busy),
|
|
511
665
|
},
|
|
512
666
|
s.save,
|
|
513
667
|
),
|
|
@@ -517,7 +671,7 @@ function ConfigPage(props) {
|
|
|
517
671
|
type: 'button',
|
|
518
672
|
onClick: reset,
|
|
519
673
|
disabled: busy || !dirty,
|
|
520
|
-
style:
|
|
674
|
+
style: secondaryButton(dirty && !busy),
|
|
521
675
|
},
|
|
522
676
|
s.reset,
|
|
523
677
|
),
|
|
@@ -527,12 +681,45 @@ function ConfigPage(props) {
|
|
|
527
681
|
)
|
|
528
682
|
}
|
|
529
683
|
|
|
530
|
-
function
|
|
684
|
+
function primaryButton(enabled) {
|
|
685
|
+
return {
|
|
686
|
+
fontSize: 13,
|
|
687
|
+
lineHeight: '20px',
|
|
688
|
+
padding: '5px 14px',
|
|
689
|
+
borderRadius: 6,
|
|
690
|
+
border: '1px solid transparent',
|
|
691
|
+
background: enabled ? palette.brand : 'var(--dsw-alias-bg-layer-3, rgba(127, 127, 127, 0.2))',
|
|
692
|
+
color: enabled ? '#fff' : palette.muted,
|
|
693
|
+
cursor: enabled ? 'pointer' : 'default',
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
function secondaryButton(enabled) {
|
|
698
|
+
return {
|
|
699
|
+
fontSize: 13,
|
|
700
|
+
lineHeight: '20px',
|
|
701
|
+
padding: '5px 14px',
|
|
702
|
+
borderRadius: 6,
|
|
703
|
+
border: `1px solid ${palette.line}`,
|
|
704
|
+
background: 'transparent',
|
|
705
|
+
color: enabled ? palette.label : palette.muted,
|
|
706
|
+
cursor: enabled ? 'pointer' : 'default',
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
function page(ownerProps, openPluginPage) {
|
|
531
711
|
const props = ownerProps || {}
|
|
532
|
-
return h(ConfigPage, { ...props,
|
|
712
|
+
return h(ConfigPage, { ...props, openPluginPage })
|
|
533
713
|
}
|
|
534
714
|
|
|
535
715
|
function apply(ctx) {
|
|
716
|
+
let openPluginPage
|
|
717
|
+
try {
|
|
718
|
+
const navigation = typeof ctx.get === 'function' ? ctx.get('pluginNavigation') : undefined
|
|
719
|
+
if (navigation && typeof navigation.openBundle === 'function') {
|
|
720
|
+
openPluginPage = () => navigation.openBundle(PACKAGE_NAME)
|
|
721
|
+
}
|
|
722
|
+
} catch {}
|
|
536
723
|
ctx.slots.inject('settings.section', () =>
|
|
537
724
|
ctx.slots.register(
|
|
538
725
|
{
|
|
@@ -541,7 +728,7 @@ function apply(ctx) {
|
|
|
541
728
|
order: 60,
|
|
542
729
|
label: () => t().nav,
|
|
543
730
|
},
|
|
544
|
-
(ownerProps) => page(ownerProps,
|
|
731
|
+
(ownerProps) => page(ownerProps, openPluginPage),
|
|
545
732
|
),
|
|
546
733
|
)
|
|
547
734
|
ctx.slots.inject('plugins.bundle.config', () =>
|
|
@@ -551,7 +738,7 @@ function apply(ctx) {
|
|
|
551
738
|
key: PACKAGE_NAME,
|
|
552
739
|
label: () => t().nav,
|
|
553
740
|
},
|
|
554
|
-
(ownerProps) => (ownerProps && ownerProps.view === 'summary' ? null : page(ownerProps,
|
|
741
|
+
(ownerProps) => (ownerProps && ownerProps.view === 'summary' ? null : page(ownerProps, undefined)),
|
|
555
742
|
),
|
|
556
743
|
)
|
|
557
744
|
}
|
package/lib/comment-policy.js
CHANGED
|
@@ -50,6 +50,8 @@ export const TAG_LABEL = {
|
|
|
50
50
|
tparam: '@tparam',
|
|
51
51
|
retval: '@retval',
|
|
52
52
|
};
|
|
53
|
+
/** 预览里的示例摘要:用户没填 @brief 时用它,避免预览出现空标签。 */
|
|
54
|
+
export const SAMPLE_BRIEF = '定义井字棋棋盘、格子坐标与格子类型。';
|
|
53
55
|
/** 出厂配置:文件头只留 @file 与 @brief,契约标签全开,隐私标签全关。 */
|
|
54
56
|
export const DEFAULT_CONFIG = {
|
|
55
57
|
brief: { enabled: true, value: '' },
|
|
@@ -113,6 +115,10 @@ export function renderFileHeader(raw, fileName) {
|
|
|
113
115
|
export function previewParts(raw, sampleName) {
|
|
114
116
|
const config = normalizeConfig(raw);
|
|
115
117
|
const header = renderFileHeader(config, sampleName || 'board.h');
|
|
118
|
+
// 预览是示例:@brief 开着但用户没填句子时,用示例文件自己的摘要顶替。
|
|
119
|
+
const briefIndex = header.indexOf('/// @brief');
|
|
120
|
+
if (briefIndex !== -1)
|
|
121
|
+
header[briefIndex] = `/// @brief ${SAMPLE_BRIEF}`;
|
|
116
122
|
const contract = [];
|
|
117
123
|
if (config.param)
|
|
118
124
|
contract.push('/// @param position 目标行列坐标。');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chengzhao-dev/dsh-cpp-workflow",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "写 C++ 源码、配 CMake、用 Clang 构建;文档注释统一为 /// Doxygen,文件头标签可在设置里改。 · Write C++ sources, configure CMake, and build with Clang; /// Doxygen comments, with file-header tags you can change in Settings.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|