Skip to content

Commit d180b10

Browse files
committed
feat(codemirror): shift + click selection
1 parent a338012 commit d180b10

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

src/lib/editorManager.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import sidebarApps from "sidebarApps";
22
import { indentUnit } from "@codemirror/language";
33
import { search } from "@codemirror/search";
4-
import { Compartment, EditorState, Prec, StateEffect } from "@codemirror/state";
4+
import {
5+
Compartment,
6+
EditorSelection,
7+
EditorState,
8+
Prec,
9+
StateEffect,
10+
} from "@codemirror/state";
511
import { oneDark } from "@codemirror/theme-one-dark";
612
import {
713
EditorView,
@@ -172,6 +178,37 @@ async function EditorManager($header, $body) {
172178
},
173179
);
174180

181+
let shiftClickSelectionExtension;
182+
{
183+
const pointerIdMap = new Map();
184+
shiftClickSelectionExtension = EditorView.domEventHandlers({
185+
pointerup(event, view) {
186+
if (!appSettings.value.shiftClickSelection) return;
187+
if (!(event.isTrusted && event.isPrimary)) return;
188+
if (!event.shiftKey && quickTools.$footer.dataset.shift == null) return;
189+
const { pointerId } = event;
190+
const tid = setTimeout(() => pointerIdMap.delete(pointerId), 1001);
191+
pointerIdMap.set(pointerId, [view.state.selection.main.anchor, tid]);
192+
},
193+
click(event, view) {
194+
const { pointerId } = event;
195+
if (!pointerIdMap.has(pointerId)) return false;
196+
const [anchor, tid] = pointerIdMap.get(pointerId);
197+
clearTimeout(tid);
198+
pointerIdMap.delete(pointerId);
199+
view.dispatch({
200+
selection: EditorSelection.range(
201+
anchor,
202+
view.state.selection.main.anchor,
203+
),
204+
userEvent: "select.extend",
205+
});
206+
event.preventDefault();
207+
return true;
208+
},
209+
});
210+
}
211+
175212
const touchSelectionUpdateExtension = EditorView.updateListener.of(
176213
(update) => {
177214
if (!touchSelectionController) return;
@@ -725,6 +762,7 @@ async function EditorManager($header, $body) {
725762
fixedHeightTheme,
726763
scrollPastEnd(),
727764
pointerCursorVisibilityExtension,
765+
shiftClickSelectionExtension,
728766
touchSelectionUpdateExtension,
729767
search(),
730768
// Ensure read-only can be toggled later via compartment
@@ -1088,6 +1126,7 @@ async function EditorManager($header, $body) {
10881126
fixedHeightTheme,
10891127
scrollPastEnd(),
10901128
pointerCursorVisibilityExtension,
1129+
shiftClickSelectionExtension,
10911130
touchSelectionUpdateExtension,
10921131
search(),
10931132
// Keep dynamic compartments across state swaps

0 commit comments

Comments
 (0)