🐛 fix(vscode): 代码阅读按 ⌘↓ 跳高亮不再来回闪,筛选栏加上上一处、下一处
This commit is contained in:
1 parent
70a53e5a68
commit
b16cc6409e
8 files changed
+221
-36
No files matched your search
@@ -129,31 +129,55 @@ export const KEY_SCROLL_MS = 500
|
||||
export interface ScrollPosition { x: number, y: number }
|
||||
|
||||
/**
|
||||
* 跳到下一处 / 上一处的命令由 VS Code 的快捷键系统触发,页面不知道绑的是哪个键,浏览器对这个键自己的动作(⌘↓ 滚到底)拦不住;
|
||||
* 它还可能早于命令开始,也可能晚于命令(实测命令十几毫秒就到,滚动动画再过一帧才开始)。所以不管哪个键:
|
||||
* 默认的「下一处 / 上一处」快捷键:mac 是 ⌘↓ / ⌘↑,别的系统是 ctrl。
|
||||
* 只用来取消浏览器滚到底 / 滚到顶,不拿它判断命令到了没有(命令是 VS Code 发来的)。
|
||||
*/
|
||||
export function occurrenceJumpKey(
|
||||
event: { key: string, metaKey: boolean, ctrlKey: boolean, altKey: boolean, shiftKey: boolean },
|
||||
mac: boolean,
|
||||
): boolean {
|
||||
if (event.altKey || event.shiftKey || (event.key !== 'ArrowDown' && event.key !== 'ArrowUp'))
|
||||
return false
|
||||
return mac ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳到下一处 / 上一处的命令由 VS Code 的快捷键系统触发。默认的 ⌘↓ / ⌘↑(Windows 是 ctrl)在能跳的时候会取消浏览器滚到底 / 滚到顶,
|
||||
* 但用户改过快捷键时别的键仍会自己滚,而且可能早于或晚于命令。所以任何键:
|
||||
* 按键那一刻记下页面滚在哪(press);命令发来时先回到那里(take)再滚到目标;跳完守住跳到的位置(hold),
|
||||
* 按键后 KEY_SCROLL_MS 内浏览器自己滚走了就拉回来(scrolled)。
|
||||
* 按键后点了鼠标、滚了滚轮、又按了键,或跳转隔了 KEY_TO_COMMAND_MS 以上才来(从命令面板运行),都不算这个键触发的。
|
||||
* 我们自己滚到的位置用 own 记下(拉回时差的那一像素、滚进视口),对应的滚动事件不算浏览器滚走;事件可能晚于滚动调用才到。
|
||||
* 按键后点了鼠标、滚了滚轮、又按了键,或跳转隔了 KEY_TO_COMMAND_MS 以上才来(从命令面板运行),都不算这个键触发的。筛选栏上的按钮另走,不经过这里。
|
||||
*/
|
||||
export class KeyScroll {
|
||||
private pressed: { position: ScrollPosition, at: number } | undefined
|
||||
private held: { position: ScrollPosition, until: number } | undefined
|
||||
/** 我们自己滚到的位置。守着的这段时间里,落到这里不算浏览器把页面滚走。 */
|
||||
private owned: ScrollPosition[] = []
|
||||
|
||||
/** 按下任何键(照常交给浏览器和 VS Code 处理)时记下页面滚在哪。 */
|
||||
press(position: ScrollPosition, at: number): void {
|
||||
this.pressed = { position, at }
|
||||
this.held = undefined
|
||||
this.owned = []
|
||||
}
|
||||
|
||||
forget(): void {
|
||||
this.pressed = undefined
|
||||
this.held = undefined
|
||||
this.owned = []
|
||||
}
|
||||
|
||||
/** 记下我们马上要滚到的位置。滚动事件晚到也认。 */
|
||||
own(position: ScrollPosition): void {
|
||||
this.owned.push(position)
|
||||
}
|
||||
|
||||
/** 跳转发来时:刚按过键就交出按键那一刻的位置(只交一次),从这时起守住它,直到跳完换成跳到的位置。 */
|
||||
take(now: number): ScrollPosition | undefined {
|
||||
const pressed = this.pressed
|
||||
this.pressed = undefined
|
||||
this.owned = []
|
||||
this.held = pressed && now - pressed.at <= KEY_TO_COMMAND_MS ? { position: pressed.position, until: pressed.at + KEY_SCROLL_MS } : undefined
|
||||
return this.held?.position
|
||||
}
|
||||
@@ -164,13 +188,16 @@ export class KeyScroll {
|
||||
this.held = { ...this.held, position }
|
||||
}
|
||||
|
||||
/** 页面滚动了:还在守着、又被浏览器滚走了,给出要拉回的位置。 */
|
||||
/** 页面滚动了:还在守着、又被浏览器滚走了,给出要拉回的位置。我们自己滚到的位置不算。 */
|
||||
scrolled(position: ScrollPosition, now: number): ScrollPosition | undefined {
|
||||
const held = this.held
|
||||
if (!held || now > held.until) {
|
||||
this.held = undefined
|
||||
this.owned = []
|
||||
return undefined
|
||||
}
|
||||
if (this.owned.some(item => item.x === position.x && item.y === position.y))
|
||||
return undefined
|
||||
return held.position.x === position.x && held.position.y === position.y ? undefined : held.position
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user