Skip to content

Commit 60f85b7

Browse files
1 parent 0e7c3ea commit 60f85b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1877
-383
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
tags: [documentation]
3+
pullRequest: 3016
4+
---
5+
6+
- Visualize scope tests in docs. Visualizes scope fixtures on [cursorless.org/docs/user/languages](https://www.cursorless.org/docs/user/languages).

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
},
5252
"pnpm": {
5353
"patchedDependencies": {
54+
"@shikijs/core": "patches/@shikijs__core.patch",
5455
"@types/[email protected]": "patches/@[email protected]",
5556
5657
}

packages/common/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,16 @@
2525
"watch": "pnpm run --filter @cursorless/common --parallel '/^watch:.*/'"
2626
},
2727
"dependencies": {
28+
"itertools": "2.4.1",
2829
"lodash-es": "4.17.21",
30+
"tinycolor2": "1.6.0",
2931
"vscode-uri": "3.1.0"
3032
},
3133
"devDependencies": {
3234
"@types/js-yaml": "4.0.9",
3335
"@types/lodash-es": "4.17.12",
3436
"@types/mocha": "10.0.10",
37+
"@types/tinycolor2": "1.4.6",
3538
"cross-spawn": "7.0.6",
3639
"fast-check": "4.1.1",
3740
"js-yaml": "4.1.0",

packages/common/src/cursorlessCommandIds.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export const cursorlessCommandIds = [
5454
"cursorless.toggleDecorations",
5555
"cursorless.showScopeVisualizer",
5656
"cursorless.hideScopeVisualizer",
57+
"cursorless.scopeVisualizer.openUrl",
5758
"cursorless.tutorial.start",
5859
"cursorless.tutorial.next",
5960
"cursorless.tutorial.previous",
@@ -100,6 +101,7 @@ export const cursorlessCommandDescriptions: Record<
100101
["cursorless.hideScopeVisualizer"]: new VisibleCommand(
101102
"Hide the scope visualizer",
102103
),
104+
["cursorless.scopeVisualizer.openUrl"]: new VisibleCommand("Open in browser"),
103105
["cursorless.analyzeCommandHistory"]: new VisibleCommand(
104106
"Analyze collected command history",
105107
),

packages/common/src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ export * from "./scopeSupportFacets/languageScopeSupport";
3434
export * from "./scopeSupportFacets/PlaintextScopeSupportFacetInfos";
3535
export * from "./scopeSupportFacets/scopeSupportFacetInfos";
3636
export * from "./scopeSupportFacets/scopeSupportFacets.types";
37+
export * from "./scopeVisualizerUtil/decorationStyle.types";
38+
export * from "./scopeVisualizerUtil/decorationUtil";
39+
export * from "./scopeVisualizerUtil/generateDecorationsForCharacterRange";
40+
export * from "./scopeVisualizerUtil/generateDecorationsForLineRange";
3741
export * from "./StoredTargetKey";
3842
export * from "./testUtil/asyncSafety";
3943
export * from "./testUtil/extractTargetedMarks";
@@ -93,6 +97,7 @@ export * from "./types/Token";
9397
export * from "./types/TreeSitter";
9498
export * from "./types/tutorial.types";
9599
export * from "./util";
100+
export * from "./util/blendColors";
96101
export * from "./util/clientSupportsFallback";
97102
export * from "./util/CompositeKeyDefaultMap";
98103
export * from "./util/CompositeKeyMap";
@@ -105,7 +110,6 @@ export * from "./util/Notifier";
105110
export * from "./util/object";
106111
export * from "./util/omitByDeep";
107112
export * from "./util/prettifyLanguageName";
108-
export * from "./util/range";
109113
export * from "./util/regex";
110114
export * from "./util/selectionsEqual";
111115
export * from "./util/serializedMarksToTokenHats";
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import type { Range } from "../types/Range";
2+
3+
export interface StyledRange {
4+
style: DecorationStyle;
5+
range: Range;
6+
}
7+
8+
export interface DecorationStyle {
9+
top: BorderStyle;
10+
bottom: BorderStyle;
11+
left: BorderStyle;
12+
right: BorderStyle;
13+
isWholeLine?: boolean;
14+
}
15+
16+
export enum BorderStyle {
17+
porous = "dashed",
18+
solid = "solid",
19+
none = "none",
20+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { BorderStyle } from "./decorationStyle.types";
2+
import type { DecorationStyle } from "./decorationStyle.types";
3+
4+
export const BORDER_WIDTH = "1px";
5+
export const BORDER_RADIUS = "2px";
6+
7+
export function getBorderStyle(borders: DecorationStyle): string {
8+
return [borders.top, borders.right, borders.bottom, borders.left].join(" ");
9+
}
10+
11+
export function getBorderColor(
12+
solidColor: string,
13+
porousColor: string,
14+
borders: DecorationStyle,
15+
): string {
16+
return [
17+
borders.top === BorderStyle.solid ? solidColor : porousColor,
18+
borders.right === BorderStyle.solid ? solidColor : porousColor,
19+
borders.bottom === BorderStyle.solid ? solidColor : porousColor,
20+
borders.left === BorderStyle.solid ? solidColor : porousColor,
21+
].join(" ");
22+
}
23+
24+
export function getBorderRadius(borders: DecorationStyle): string {
25+
return [
26+
getSingleCornerBorderRadius(borders.top, borders.left),
27+
getSingleCornerBorderRadius(borders.top, borders.right),
28+
getSingleCornerBorderRadius(borders.bottom, borders.right),
29+
getSingleCornerBorderRadius(borders.bottom, borders.left),
30+
].join(" ");
31+
}
32+
33+
export function useSingleCornerBorderRadius(
34+
side1: BorderStyle,
35+
side2: BorderStyle,
36+
): boolean {
37+
// We only round the corners if both sides are solid, as that makes them look
38+
// more finished, whereas we want the dotted borders to look unfinished / cut
39+
// off.
40+
return side1 === BorderStyle.solid && side2 === BorderStyle.solid;
41+
}
42+
43+
export function getSingleCornerBorderRadius(
44+
side1: BorderStyle,
45+
side2: BorderStyle,
46+
) {
47+
return useSingleCornerBorderRadius(side1, side2) ? BORDER_RADIUS : "0px";
48+
}
Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import type { Range, TextEditor } from "@cursorless/common";
2-
import { getLineRanges } from "@cursorless/common";
1+
import type { Range } from "../../types/Range";
32
import type { StyledRange } from "../decorationStyle.types";
43
import { BorderStyle } from "../decorationStyle.types";
54
import { handleMultipleLines } from "./handleMultipleLines";
@@ -10,7 +9,7 @@ import { handleMultipleLines } from "./handleMultipleLines";
109
* that the range is visually distinct from adjacent ranges but looks continuous.
1110
*/
1211
export function* generateDecorationsForCharacterRange(
13-
editor: TextEditor,
12+
getLineRanges: (range: Range) => Range[],
1413
range: Range,
1514
): Iterable<StyledRange> {
1615
if (range.isSingleLine) {
@@ -26,5 +25,15 @@ export function* generateDecorationsForCharacterRange(
2625
return;
2726
}
2827

29-
yield* handleMultipleLines(getLineRanges(editor, range));
28+
// A list of ranges, one for each line in the given range, with the first and
29+
// last ranges trimmed to the start and end of the given range.
30+
const lineRanges = getLineRanges(range);
31+
32+
lineRanges[0] = lineRanges[0].with(range.start);
33+
lineRanges[lineRanges.length - 1] = lineRanges[lineRanges.length - 1].with(
34+
undefined,
35+
range.end,
36+
);
37+
38+
yield* handleMultipleLines(lineRanges);
3039
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Range } from "@cursorless/common";
1+
import type { Range } from "../..";
22

33
/**
44
* Generates a line info for each line in the given range, which includes
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import assert from "assert";
2+
import { map } from "itertools";
3+
import { Range } from "../..";
24
import { BorderStyle } from "../decorationStyle.types";
35
import { handleMultipleLines } from "./handleMultipleLines";
4-
import { Range } from "@cursorless/common";
5-
import { map } from "itertools";
66

77
const solid = BorderStyle.solid;
88
const porous = BorderStyle.porous;

0 commit comments

Comments
 (0)