@wenaixi/dsh-prompt-history 2.2.0 → 2.2.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/CHANGELOG.md +9 -1
- package/lib/client.js +31 -7
- package/lib/types/client/feedback.d.ts +1 -1
- package/package.json +1 -1
- package/src/client/InputHistory.tsx +3 -0
- package/src/client/feedback.ts +35 -4
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [2.2.1] - 2026-10-06
|
|
8
|
+
|
|
9
|
+
### 修复
|
|
10
|
+
|
|
11
|
+
- **双击 Esc 关闭时 Esc 让位宿主**:`doubleEsc=false` 时连按 Esc 不再被插件消费,宿主自行关闭其浮层/菜单。
|
|
12
|
+
- **宽屏历史面板右侧完整预览**:窗口 ≥1000px 时在列表右侧显示高亮条目的完整内容(最多 6 行,超出显示 `… +N more lines`),对齐 Claude Code `HistorySearchDialog` 的 preview。
|
|
13
|
+
|
|
7
14
|
## [2.2.0] - 2026-10-06
|
|
8
15
|
|
|
9
16
|
### 变更
|
|
@@ -257,7 +264,8 @@
|
|
|
257
264
|
|
|
258
265
|
- 选中即复制(任意选中方式)。
|
|
259
266
|
|
|
260
|
-
[Unreleased]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.2.
|
|
267
|
+
[Unreleased]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.2.1...HEAD
|
|
268
|
+
[2.2.1]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.2.0...v2.2.1
|
|
261
269
|
[2.2.0]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.1.0...v2.2.0
|
|
262
270
|
[2.1.0]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.0.2...v2.1.0
|
|
263
271
|
[2.0.2]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.0.1...v2.0.2
|
package/lib/client.js
CHANGED
|
@@ -285,6 +285,7 @@ window.__ModuleLoader__.load({
|
|
|
285
285
|
let historyPanel = null;
|
|
286
286
|
let historyList = null;
|
|
287
287
|
let historyFoot = null;
|
|
288
|
+
let historyPreview = null;
|
|
288
289
|
let historyRefs = null;
|
|
289
290
|
/** Remove the history list panel and detach its outside-click listener (idempotent). */
|
|
290
291
|
function hideHistoryPanel() {
|
|
@@ -295,6 +296,7 @@ window.__ModuleLoader__.load({
|
|
|
295
296
|
}
|
|
296
297
|
historyList = null;
|
|
297
298
|
historyFoot = null;
|
|
299
|
+
historyPreview = null;
|
|
298
300
|
historyRefs = null;
|
|
299
301
|
}
|
|
300
302
|
/** Close the panel when a pointer lands outside both it and the composer. */
|
|
@@ -343,12 +345,16 @@ window.__ModuleLoader__.load({
|
|
|
343
345
|
const ROW_ACTIVE_CSS = "background:var(--dsw-specific-menu-hover);color:var(--dsw-alias-label-primary);border-left-color:var(--dsw-static-blue-500);";
|
|
344
346
|
const AGE_CSS = `flex:none;font:11px/1.5 ui-monospace,SFMono-Regular,Consolas,monospace;min-width:${AGE_WIDTH}ch;text-align:right;color:var(--dsw-alias-label-tertiary);`;
|
|
345
347
|
const ROW_TEXT_CSS = "min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;";
|
|
348
|
+
/** 宽屏阈值:Claude Code 终端列数 ≥100,web 用像素近似。 */
|
|
349
|
+
const WIDE_MIN_PX = 1e3;
|
|
350
|
+
/** 预览最多行数,对齐 Claude Code PREVIEW_ROWS=6。 */
|
|
351
|
+
const PREVIEW_ROWS = 6;
|
|
346
352
|
/**
|
|
347
353
|
* Open the history list above the composer card.
|
|
348
354
|
*
|
|
349
355
|
* 只做渲染与鼠标交互:键盘(过滤、移动、回填、关闭)在 InputHistory.tsx 里处理,
|
|
350
356
|
* 因为焦点必须留在输入框,宿主 Menu 的方向键行走(依赖真实焦点)用不上。
|
|
351
|
-
*
|
|
357
|
+
* 列表按最新在顶渲染;宽屏(≥1000px)时右侧显示高亮条目的完整内容预览。
|
|
352
358
|
*
|
|
353
359
|
* @param view - 命中文本、相对时间、高亮位置与计数。
|
|
354
360
|
* @param refs - 提交与关闭回调。
|
|
@@ -359,25 +365,34 @@ window.__ModuleLoader__.load({
|
|
|
359
365
|
el.className = HISTORY_CLASS;
|
|
360
366
|
el.style.cssText = PANEL_CSS;
|
|
361
367
|
el.setAttribute("role", "listbox");
|
|
368
|
+
const body = document.createElement("div");
|
|
369
|
+
body.style.cssText = "display:flex;align-items:stretch;";
|
|
362
370
|
const list = document.createElement("div");
|
|
363
|
-
list.style.cssText = "max-height:240px;overflow-y:auto;overscroll-behavior:contain;";
|
|
371
|
+
list.style.cssText = "flex:1 1 0;min-width:0;max-height:240px;overflow-y:auto;overscroll-behavior:contain;";
|
|
364
372
|
list.setAttribute("role", "presentation");
|
|
373
|
+
const preview = document.createElement("div");
|
|
374
|
+
preview.className = "dsh-ph-history-preview";
|
|
375
|
+
preview.style.cssText = "display:none;flex:1 1 0;min-width:0;max-height:240px;overflow-y:auto;padding:7px 12px;border-left:1px solid var(--dsw-alias-border-l2);font:12.5px/1.6 inherit;color:var(--dsw-alias-label-secondary);white-space:pre-wrap;word-break:break-word;";
|
|
376
|
+
body.append(list, preview);
|
|
365
377
|
const foot = document.createElement("div");
|
|
366
378
|
foot.style.cssText = "padding:5px 12px;font:11px/1.5 ui-monospace,SFMono-Regular,Consolas,monospace;color:var(--dsw-alias-label-tertiary);border-top:1px solid var(--dsw-alias-border-l2);";
|
|
367
|
-
el.append(
|
|
379
|
+
el.append(body, foot);
|
|
368
380
|
document.body.appendChild(el);
|
|
369
381
|
historyPanel = el;
|
|
370
382
|
historyList = list;
|
|
371
383
|
historyFoot = foot;
|
|
384
|
+
historyPreview = preview;
|
|
372
385
|
document.addEventListener("pointerdown", onHistoryOutsidePointer, true);
|
|
373
386
|
}
|
|
374
387
|
const el = historyPanel;
|
|
375
388
|
const list = historyList;
|
|
376
389
|
const foot = historyFoot;
|
|
377
|
-
|
|
390
|
+
const preview = historyPreview;
|
|
391
|
+
if (el === null || list === null || foot === null || preview === null) return;
|
|
378
392
|
historyRefs = refs;
|
|
379
393
|
list.replaceChildren();
|
|
380
|
-
view.texts.slice(0, HISTORY_MAX_ROWS)
|
|
394
|
+
const rows = view.texts.slice(0, HISTORY_MAX_ROWS);
|
|
395
|
+
rows.forEach((text, i) => {
|
|
381
396
|
const row = document.createElement("button");
|
|
382
397
|
row.type = "button";
|
|
383
398
|
row.id = `${HISTORY_CLASS}-row-${i}`;
|
|
@@ -404,6 +419,13 @@ window.__ModuleLoader__.load({
|
|
|
404
419
|
if (view.highlight >= 0) el.setAttribute("aria-activedescendant", `${HISTORY_CLASS}-row-${view.highlight}`);
|
|
405
420
|
else el.removeAttribute("aria-activedescendant");
|
|
406
421
|
foot.textContent = view.shown === 0 ? T("history.noMatch") : `${view.shown} / ${view.total} ${T("history.hint")}`;
|
|
422
|
+
preview.style.display = window.innerWidth >= WIDE_MIN_PX ? "block" : "none";
|
|
423
|
+
preview.replaceChildren();
|
|
424
|
+
if (view.highlight >= 0 && view.highlight < rows.length) {
|
|
425
|
+
const lines = (rows[view.highlight] ?? "").split("\n");
|
|
426
|
+
preview.textContent = lines.slice(0, PREVIEW_ROWS).join("\n");
|
|
427
|
+
if (lines.length > PREVIEW_ROWS) preview.append(`\n… +${lines.length - PREVIEW_ROWS} ${T("history.moreLines")}`);
|
|
428
|
+
}
|
|
407
429
|
placeHistoryPanel(el);
|
|
408
430
|
const active = list.querySelector(`#${HISTORY_CLASS}-row-${view.highlight}`);
|
|
409
431
|
if (active instanceof HTMLElement) active.scrollIntoView({ block: "nearest" });
|
|
@@ -1154,8 +1176,10 @@ window.__ModuleLoader__.load({
|
|
|
1154
1176
|
return;
|
|
1155
1177
|
}
|
|
1156
1178
|
if (e.key !== "Escape") lastEscapeRef.current = 0;
|
|
1157
|
-
else if (!prefs.doubleEsc)
|
|
1158
|
-
|
|
1179
|
+
else if (!prefs.doubleEsc) {
|
|
1180
|
+
lastEscapeRef.current = 0;
|
|
1181
|
+
return;
|
|
1182
|
+
} else {
|
|
1159
1183
|
const now = performance.now();
|
|
1160
1184
|
const doubled = isDoubleEscape(lastEscapeRef.current, now);
|
|
1161
1185
|
if (live.draft !== "") {
|
|
@@ -37,7 +37,7 @@ export declare function hideHistoryPanel(): void;
|
|
|
37
37
|
*
|
|
38
38
|
* 只做渲染与鼠标交互:键盘(过滤、移动、回填、关闭)在 InputHistory.tsx 里处理,
|
|
39
39
|
* 因为焦点必须留在输入框,宿主 Menu 的方向键行走(依赖真实焦点)用不上。
|
|
40
|
-
*
|
|
40
|
+
* 列表按最新在顶渲染;宽屏(≥1000px)时右侧显示高亮条目的完整内容预览。
|
|
41
41
|
*
|
|
42
42
|
* @param view - 命中文本、相对时间、高亮位置与计数。
|
|
43
43
|
* @param refs - 提交与关闭回调。
|
package/package.json
CHANGED
|
@@ -459,7 +459,10 @@ export function InputHistory(props: InputHistoryProps) {
|
|
|
459
459
|
if (e.key !== 'Escape') {
|
|
460
460
|
lastEscapeRef.current = 0
|
|
461
461
|
} else if (!prefs.doubleEsc) {
|
|
462
|
+
// 双击 Esc 关闭:Esc 完全交还宿主(不提示、
|
|
463
|
+
// 不消费)。宿主会自行关闭其浮层/菜单。
|
|
462
464
|
lastEscapeRef.current = 0
|
|
465
|
+
return
|
|
463
466
|
} else {
|
|
464
467
|
const now = performance.now()
|
|
465
468
|
const doubled = isDoubleEscape(lastEscapeRef.current, now)
|
package/src/client/feedback.ts
CHANGED
|
@@ -145,6 +145,7 @@ interface HistoryPanelRefs {
|
|
|
145
145
|
let historyPanel: HTMLDivElement | null = null
|
|
146
146
|
let historyList: HTMLDivElement | null = null
|
|
147
147
|
let historyFoot: HTMLDivElement | null = null
|
|
148
|
+
let historyPreview: HTMLDivElement | null = null
|
|
148
149
|
let historyRefs: HistoryPanelRefs | null = null
|
|
149
150
|
|
|
150
151
|
/** Remove the history list panel and detach its outside-click listener (idempotent). */
|
|
@@ -156,6 +157,7 @@ export function hideHistoryPanel(): void {
|
|
|
156
157
|
}
|
|
157
158
|
historyList = null
|
|
158
159
|
historyFoot = null
|
|
160
|
+
historyPreview = null
|
|
159
161
|
historyRefs = null
|
|
160
162
|
}
|
|
161
163
|
|
|
@@ -222,12 +224,17 @@ const AGE_CSS = 'flex:none;font:11px/1.5 ui-monospace,SFMono-Regular,Consolas,mo
|
|
|
222
224
|
|
|
223
225
|
const ROW_TEXT_CSS = 'min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;'
|
|
224
226
|
|
|
227
|
+
/** 宽屏阈值:Claude Code 终端列数 ≥100,web 用像素近似。 */
|
|
228
|
+
const WIDE_MIN_PX = 1000
|
|
229
|
+
/** 预览最多行数,对齐 Claude Code PREVIEW_ROWS=6。 */
|
|
230
|
+
const PREVIEW_ROWS = 6
|
|
231
|
+
|
|
225
232
|
/**
|
|
226
233
|
* Open the history list above the composer card.
|
|
227
234
|
*
|
|
228
235
|
* 只做渲染与鼠标交互:键盘(过滤、移动、回填、关闭)在 InputHistory.tsx 里处理,
|
|
229
236
|
* 因为焦点必须留在输入框,宿主 Menu 的方向键行走(依赖真实焦点)用不上。
|
|
230
|
-
*
|
|
237
|
+
* 列表按最新在顶渲染;宽屏(≥1000px)时右侧显示高亮条目的完整内容预览。
|
|
231
238
|
*
|
|
232
239
|
* @param view - 命中文本、相对时间、高亮位置与计数。
|
|
233
240
|
* @param refs - 提交与关闭回调。
|
|
@@ -238,23 +245,34 @@ export function showHistoryPanel(view: HistoryPanelView, refs: HistoryPanelRefs)
|
|
|
238
245
|
el.className = HISTORY_CLASS
|
|
239
246
|
el.style.cssText = PANEL_CSS
|
|
240
247
|
el.setAttribute('role', 'listbox')
|
|
248
|
+
const body = document.createElement('div')
|
|
249
|
+
body.style.cssText = 'display:flex;align-items:stretch;'
|
|
241
250
|
const list = document.createElement('div')
|
|
242
|
-
list.style.cssText = 'max-height:240px;overflow-y:auto;overscroll-behavior:contain;'
|
|
251
|
+
list.style.cssText = 'flex:1 1 0;min-width:0;max-height:240px;overflow-y:auto;overscroll-behavior:contain;'
|
|
243
252
|
list.setAttribute('role', 'presentation')
|
|
253
|
+
const preview = document.createElement('div')
|
|
254
|
+
preview.className = 'dsh-ph-history-preview'
|
|
255
|
+
preview.style.cssText = 'display:none;flex:1 1 0;min-width:0;max-height:240px;overflow-y:auto;' +
|
|
256
|
+
'padding:7px 12px;border-left:1px solid var(--dsw-alias-border-l2);' +
|
|
257
|
+
'font:12.5px/1.6 inherit;color:var(--dsw-alias-label-secondary);white-space:pre-wrap;' +
|
|
258
|
+
'word-break:break-word;'
|
|
259
|
+
body.append(list, preview)
|
|
244
260
|
const foot = document.createElement('div')
|
|
245
261
|
foot.style.cssText = 'padding:5px 12px;font:11px/1.5 ui-monospace,SFMono-Regular,Consolas,monospace;' +
|
|
246
262
|
'color:var(--dsw-alias-label-tertiary);border-top:1px solid var(--dsw-alias-border-l2);'
|
|
247
|
-
el.append(
|
|
263
|
+
el.append(body, foot)
|
|
248
264
|
document.body.appendChild(el)
|
|
249
265
|
historyPanel = el
|
|
250
266
|
historyList = list
|
|
251
267
|
historyFoot = foot
|
|
268
|
+
historyPreview = preview
|
|
252
269
|
document.addEventListener('pointerdown', onHistoryOutsidePointer, true)
|
|
253
270
|
}
|
|
254
271
|
const el = historyPanel
|
|
255
272
|
const list = historyList
|
|
256
273
|
const foot = historyFoot
|
|
257
|
-
|
|
274
|
+
const preview = historyPreview
|
|
275
|
+
if (el === null || list === null || foot === null || preview === null) return
|
|
258
276
|
historyRefs = refs
|
|
259
277
|
|
|
260
278
|
list.replaceChildren()
|
|
@@ -288,6 +306,19 @@ export function showHistoryPanel(view: HistoryPanelView, refs: HistoryPanelRefs)
|
|
|
288
306
|
? T('history.noMatch')
|
|
289
307
|
: `${view.shown} / ${view.total} ${T('history.hint')}`
|
|
290
308
|
|
|
309
|
+
// 宽屏右侧预览:显示高亮条目的完整文本,超过 6 行截断 + 「… +N more lines」。
|
|
310
|
+
preview.style.display = window.innerWidth >= WIDE_MIN_PX ? 'block' : 'none'
|
|
311
|
+
preview.replaceChildren()
|
|
312
|
+
if (view.highlight >= 0 && view.highlight < rows.length) {
|
|
313
|
+
const text = rows[view.highlight] ?? ''
|
|
314
|
+
const lines = text.split('\n')
|
|
315
|
+
const shown = lines.slice(0, PREVIEW_ROWS)
|
|
316
|
+
preview.textContent = shown.join('\n')
|
|
317
|
+
if (lines.length > PREVIEW_ROWS) {
|
|
318
|
+
preview.append(`\n… +${lines.length - PREVIEW_ROWS} ${T('history.moreLines')}`)
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
291
322
|
placeHistoryPanel(el)
|
|
292
323
|
// 高亮项滚进可视区,但不抢焦点。
|
|
293
324
|
const active = list.querySelector(`#${HISTORY_CLASS}-row-${view.highlight}`)
|