Skip to content

Commit 9132652

Browse files
authored
Merge pull request #2838 from codecrafters-io/code-mirror/add-highlighted-ranges
Add `highlightedRanges` support to CodeMirror
2 parents f931a88 + 2de8749 commit 9132652

19 files changed

+327
-11
lines changed

app/components/code-mirror.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
{{did-update this.optionDidChange "editable" @editable}}
1212
{{did-update this.optionDidChange "foldGutter" @foldGutter}}
1313
{{did-update this.optionDidChange "highlightActiveLine" @highlightActiveLine}}
14+
{{did-update this.optionDidChange "highlightedRanges" @highlightedRanges}}
1415
{{did-update this.optionDidChange "highlightNewlines" @highlightNewlines}}
1516
{{did-update this.optionDidChange "highlightSelectionMatches" @highlightSelectionMatches}}
1617
{{did-update this.optionDidChange "highlightSpecialChars" @highlightSpecialChars}}

app/components/code-mirror.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { markdown } from '@codemirror/lang-markdown';
3939
import { highlightNewlines } from 'codecrafters-frontend/utils/code-mirror-highlight-newlines';
4040
import { collapseUnchangedGutter } from 'codecrafters-frontend/utils/code-mirror-collapse-unchanged-gutter';
4141
import { highlightActiveLineGutter as highlightActiveLineGutterRS } from 'codecrafters-frontend/utils/code-mirror-gutter-rs';
42+
import { highlightRanges } from 'codecrafters-frontend/utils/code-mirror-highlight-ranges';
4243

4344
function generateHTMLElement(src: string): HTMLElement {
4445
const div = document.createElement('div');
@@ -52,12 +53,17 @@ enum FoldGutterIcon {
5253
Collapsed = '<svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible; cursor: pointer;"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg>',
5354
}
5455

56+
export type LineRange = { startLine: number; endLine: number };
57+
5558
type DocumentUpdateCallback = (newValue: string) => void;
5659

57-
type Argument = boolean | string | number | undefined | Extension | DocumentUpdateCallback;
60+
type Argument = boolean | string | number | undefined | Extension | DocumentUpdateCallback | LineRange[];
5861

5962
type OptionHandler = (args: Signature['Args']['Named']) => Extension[] | Promise<Extension[]>;
6063

64+
/**
65+
* Order of keys in this object matters, do not sort alphabetically
66+
*/
6167
const OPTION_HANDLERS: { [key: string]: OptionHandler } = {
6268
allowMultipleSelections: ({ allowMultipleSelections }) => [EditorState.allowMultipleSelections.of(!!allowMultipleSelections)],
6369
autocompletion: ({ autocompletion: enabled }) => (enabled ? [autocompletion(), keymap.of(completionKeymap)] : []),
@@ -69,6 +75,7 @@ const OPTION_HANDLERS: { [key: string]: OptionHandler } = {
6975
editable: ({ editable }) => [EditorView.editable.of(!!editable)],
7076
highlightActiveLine: ({ highlightActiveLine: enabled }) =>
7177
enabled ? [highlightActiveLine(), highlightActiveLineGutter(), highlightActiveLineGutterRS()] : [],
78+
highlightedRanges: ({ highlightedRanges }) => (highlightedRanges ? highlightRanges(highlightedRanges) : []),
7279
highlightNewlines: ({ highlightNewlines: enabled }) => (enabled ? [highlightNewlines()] : []),
7380
highlightSelectionMatches: ({ highlightSelectionMatches: enabled }) => (enabled ? [highlightSelectionMatches()] : []),
7481
highlightSpecialChars: ({ highlightSpecialChars: enabled }) => (enabled ? [highlightSpecialChars()] : []),
@@ -240,6 +247,10 @@ export interface Signature {
240247
* Enable inline highlighting of changes in the diff
241248
*/
242249
highlightChanges?: boolean;
250+
/**
251+
* Enable highlighting of specified line ranges
252+
*/
253+
highlightedRanges?: LineRange[];
243254
/**
244255
* Enable highlighting of new line symbols
245256
*/

app/components/file-contents-card.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
@editable={{false}}
5454
@readOnly={{true}}
5555
@highlightActiveLine={{false}}
56+
@highlightedRanges={{@highlightedRanges}}
5657
@highlightSelectionMatches={{true}}
5758
@highlightSpecialChars={{true}}
5859
@highlightTrailingWhitespace={{true}}

app/components/file-contents-card.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { service } from '@ember/service';
33
import Component from '@glimmer/component';
44
import { tracked } from '@glimmer/tracking';
55
import type DarkModeService from 'codecrafters-frontend/services/dark-mode';
6+
import type { LineRange } from 'codecrafters-frontend/components/code-mirror';
67
import { codeCraftersDark, codeCraftersLight } from 'codecrafters-frontend/utils/code-mirror-themes';
78

89
interface Signature {
@@ -34,6 +35,10 @@ interface Signature {
3435
* Show a tooltip in the header when collapsible & collapsed
3536
*/
3637
headerTooltipText?: string;
38+
/**
39+
* Enable highlighting of specified line ranges
40+
*/
41+
highlightedRanges?: LineRange[];
3742
/**
3843
* Scroll the component into view after it's collapsed
3944
*/

app/components/file-diff-card.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
@drawSelection={{true}}
1818
@rectangularSelection={{true}}
1919
@readOnly={{true}}
20+
@highlightedRanges={{@highlightedRanges}}
2021
@highlightSelectionMatches={{true}}
2122
@highlightSpecialChars={{true}}
2223
@theme={{this.codeMirrorTheme}}

app/components/file-diff-card.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { service } from '@ember/service';
22
import Component from '@glimmer/component';
33
import type DarkModeService from 'codecrafters-frontend/services/dark-mode';
4+
import type { LineRange } from 'codecrafters-frontend/components/code-mirror';
45
import { codeCraftersDark, codeCraftersLight } from 'codecrafters-frontend/utils/code-mirror-themes';
56

67
interface Signature {
@@ -20,6 +21,10 @@ interface Signature {
2021
* Always render CodeMirror/SyntaxHighlightedDiff using Dark Theme
2122
*/
2223
forceDarkTheme?: boolean;
24+
/**
25+
* Enable highlighting of specified line ranges
26+
*/
27+
highlightedRanges?: LineRange[];
2328
/**
2429
* Override language auto-detected from `filename` and set it manually
2530
*/

app/controllers/demo/code-mirror.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const OPTION_DEFAULTS = {
4444
foldGutter: true,
4545
highlightActiveLine: true,
4646
highlightChanges: false,
47+
highlightedRanges: false,
4748
highlightNewlines: false,
4849
highlightSelectionMatches: true,
4950
highlightSpecialChars: true,
@@ -100,6 +101,7 @@ export default class DemoCodeMirrorController extends Controller {
100101
'foldGutter',
101102
'highlightActiveLine',
102103
'highlightChanges',
104+
'highlightedRanges',
103105
'highlightNewlines',
104106
'highlightSelectionMatches',
105107
'highlightSpecialChars',
@@ -152,6 +154,7 @@ export default class DemoCodeMirrorController extends Controller {
152154
@tracked foldGutter = OPTION_DEFAULTS.foldGutter;
153155
@tracked highlightActiveLine = OPTION_DEFAULTS.highlightActiveLine;
154156
@tracked highlightChanges = OPTION_DEFAULTS.highlightChanges;
157+
@tracked highlightedRanges = OPTION_DEFAULTS.highlightedRanges;
155158
@tracked highlightNewlines = OPTION_DEFAULTS.highlightNewlines;
156159
@tracked highlightSelectionMatches = OPTION_DEFAULTS.highlightSelectionMatches;
157160
@tracked highlightSpecialChars = OPTION_DEFAULTS.highlightSpecialChars;

app/controllers/demo/file-contents-card.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import EXAMPLE_DOCUMENTS, { ExampleDocument } from 'codecrafters-frontend/utils/
55

66
const OPTION_DEFAULTS = {
77
headerTooltipText: false,
8+
highlightedRanges: false,
89
isCollapsed: false,
910
isCollapsible: false,
1011
scrollIntoViewOnCollapse: true,
@@ -16,6 +17,7 @@ export default class DemoFileContentsCardController extends Controller {
1617

1718
@tracked documents: ExampleDocument[] = EXAMPLE_DOCUMENTS;
1819
@tracked headerTooltipText: boolean = OPTION_DEFAULTS.headerTooltipText;
20+
@tracked highlightedRanges: boolean = OPTION_DEFAULTS.highlightedRanges;
1921
@tracked isCollapsed: boolean = OPTION_DEFAULTS.isCollapsed;
2022
@tracked isCollapsible: boolean = OPTION_DEFAULTS.isCollapsible;
2123
@tracked scrollIntoViewOnCollapse: boolean = OPTION_DEFAULTS.scrollIntoViewOnCollapse;

app/controllers/demo/file-diff-card.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import EXAMPLE_DOCUMENTS, { DiffBasedExampleDocument } from 'codecrafters-fronte
55

66
const OPTION_DEFAULTS = {
77
forceDarkTheme: false,
8+
highlightedRanges: false,
89
selectedDocumentIndex: 1,
910
useCodeMirror: true,
1011
};
@@ -13,6 +14,7 @@ export default class DemoFileDiffCardController extends Controller {
1314
@tracked documents: DiffBasedExampleDocument[] = EXAMPLE_DOCUMENTS;
1415

1516
@tracked forceDarkTheme: boolean = OPTION_DEFAULTS.forceDarkTheme;
17+
@tracked highlightedRanges: boolean = OPTION_DEFAULTS.highlightedRanges;
1618
@tracked selectedDocumentIndex: number = OPTION_DEFAULTS.selectedDocumentIndex;
1719
@tracked useCodeMirror: boolean = OPTION_DEFAULTS.useCodeMirror;
1820

app/routes/demo/code-mirror.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const QUERY_PARAMS = [
1515
'filename',
1616
'foldGutter',
1717
'highlightActiveLine',
18+
'highlightedRanges',
1819
'highlightChanges',
1920
'highlightNewlines',
2021
'highlightSelectionMatches',

0 commit comments

Comments
 (0)