@kerebron/extension-codejar 0.4.27 → 0.4.28

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.
@@ -0,0 +1,18 @@
1
+ import { Plugin, PluginKey } from 'prosemirror-state';
2
+ import type { NodeType } from 'prosemirror-model';
3
+ import { type CoreEditor } from '@kerebron/editor';
4
+ import { type CommandFactories, type CommandShortcuts } from '@kerebron/editor/commands';
5
+ import { NodeCodeBlock } from '@kerebron/extension-basic-editor/NodeCodeBlock';
6
+ export declare const codeJarBlockKey: PluginKey<any>;
7
+ export interface NodeCodeJarConfig {
8
+ readOnly?: boolean;
9
+ languageWhitelist?: string[];
10
+ }
11
+ export declare class NodeCodeJar extends NodeCodeBlock {
12
+ config: NodeCodeJarConfig;
13
+ constructor(config: NodeCodeJarConfig);
14
+ getCommandFactories(editor: CoreEditor, type: NodeType): Partial<CommandFactories>;
15
+ getKeyboardShortcuts(): Partial<CommandShortcuts>;
16
+ getProseMirrorPlugins(): Plugin[];
17
+ }
18
+ //# sourceMappingURL=NodeCodeJar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeCodeJar.d.ts","sourceRoot":"","sources":["../src/NodeCodeJar.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,MAAM,EACN,SAAS,EAGV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAI/E,eAAO,MAAM,eAAe,gBAAkC,CAAC;AAwB/D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,qBAAa,WAAY,SAAQ,aAAa;IACvB,MAAM,EAAE,iBAAiB;gBAAzB,MAAM,EAAE,iBAAiB;IAIrC,mBAAmB,CAC1B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC;IAWnB,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAUjD,qBAAqB,IAAI,MAAM,EAAE;CA0B3C"}
@@ -0,0 +1,69 @@
1
+ import { Plugin, PluginKey, Selection, } from 'prosemirror-state';
2
+ import { getShadowRoot } from '@kerebron/editor/utilities';
3
+ import { getLangsList } from '@kerebron/wasm';
4
+ import { NodeCodeBlock } from '@kerebron/extension-basic-editor/NodeCodeBlock';
5
+ import { codeJarBlockNodeView } from './codeJarBlockNodeView.js';
6
+ export const codeJarBlockKey = new PluginKey('code-jar-block');
7
+ function arrowHandler(dir) {
8
+ return (state, dispatch, view) => {
9
+ if (state.selection.empty && view.endOfTextblock(dir)) {
10
+ let side = dir == 'left' || dir == 'up' ? -1 : 1;
11
+ let $head = state.selection.$head;
12
+ let nextPos = Selection.near(state.doc.resolve(side > 0 ? $head.after() : $head.before()), side);
13
+ if (nextPos.$head && nextPos.$head.parent.type.name == 'code_block') {
14
+ dispatch(state.tr.setSelection(nextPos));
15
+ return true;
16
+ }
17
+ }
18
+ return false;
19
+ };
20
+ }
21
+ export class NodeCodeJar extends NodeCodeBlock {
22
+ config;
23
+ constructor(config) {
24
+ super(config);
25
+ this.config = config;
26
+ }
27
+ getCommandFactories(editor, type) {
28
+ return {
29
+ 'setCodeBlock': (lang) => editor.commandFactories.setBlockType(type, { lang }),
30
+ // ArrowLeft: () => arrowHandler('left'),
31
+ // ArrowRight: () => arrowHandler('right'),
32
+ // ArrowUp: () => arrowHandler('up'),
33
+ // ArrowDown: () => arrowHandler('down'),
34
+ };
35
+ }
36
+ getKeyboardShortcuts() {
37
+ return {
38
+ 'Shift-Ctrl-"': 'setCodeBlock',
39
+ 'ArrowLeft': 'ArrowLeft',
40
+ 'ArrowRight': 'ArrowRight',
41
+ 'ArrowUp': 'ArrowUp',
42
+ 'ArrowDown': 'ArrowDown',
43
+ };
44
+ }
45
+ getProseMirrorPlugins() {
46
+ const shadowRoot = getShadowRoot(this.editor.config.element);
47
+ const settings = {
48
+ languageWhitelist: this.config.languageWhitelist || getLangsList(),
49
+ shadowRoot,
50
+ readOnly: this.editor.config.readOnly || this.config.readOnly,
51
+ undo: () => {
52
+ this.editor.chain().undo().run();
53
+ },
54
+ redo: () => {
55
+ this.editor.chain().redo().run();
56
+ },
57
+ };
58
+ return [
59
+ new Plugin({
60
+ key: codeJarBlockKey,
61
+ props: {
62
+ nodeViews: {
63
+ [this.name]: codeJarBlockNodeView(settings, this.editor),
64
+ },
65
+ },
66
+ }),
67
+ ];
68
+ }
69
+ }
@@ -0,0 +1,11 @@
1
+ import { type Parser } from '@kerebron/tree-sitter';
2
+ import { Decorator } from './Decorator.js';
3
+ export declare class TreeSitterHighlighter {
4
+ parser: Parser | undefined;
5
+ hightligtScm: string | undefined;
6
+ cdnUrl?: string | undefined;
7
+ lang?: string;
8
+ init(lang: string): Promise<boolean>;
9
+ highlight(code: string, decorator: Decorator): string;
10
+ }
11
+ //# sourceMappingURL=TreeSitterHighlighter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TreeSitterHighlighter.d.ts","sourceRoot":"","sources":["../src/TreeSitterHighlighter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAQlE,OAAO,EAAoB,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE7D,qBAAa,qBAAqB;IAChC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,MAAM,CAAC,qBAAiC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IAER,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgC1C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS;CAoC7C"}
@@ -0,0 +1,62 @@
1
+ import { createParser } from '@kerebron/tree-sitter';
2
+ import { fetchTextResource, fetchWasm, getLangTreeSitter, } from '@kerebron/wasm';
3
+ export class TreeSitterHighlighter {
4
+ parser;
5
+ hightligtScm;
6
+ cdnUrl = 'http://localhost:8000/wasm/';
7
+ lang;
8
+ async init(lang) {
9
+ this.lang = lang;
10
+ if (!lang) {
11
+ this.parser = undefined;
12
+ this.hightligtScm = undefined;
13
+ return true;
14
+ }
15
+ const treeSitterConfig = getLangTreeSitter(lang, this.cdnUrl);
16
+ const wasmUrl = treeSitterConfig.files[0]; // TODO add support for split parsers like markdown
17
+ const highlightUrl = treeSitterConfig.queries['highlights.scm'];
18
+ try {
19
+ const wasm = await fetchWasm(wasmUrl);
20
+ this.parser = await createParser(wasm);
21
+ this.hightligtScm = await fetchTextResource(highlightUrl);
22
+ }
23
+ catch (err) {
24
+ console.error('Error init highlight for: ' + lang, err);
25
+ }
26
+ if (!this.parser) {
27
+ console.warn('Parser not inited');
28
+ return false;
29
+ }
30
+ if (!this.hightligtScm) {
31
+ console.warn('hightligtScm not inited');
32
+ return false;
33
+ }
34
+ return true;
35
+ }
36
+ highlight(code, decorator) {
37
+ if (!this.lang || !this.parser || !this.hightligtScm) {
38
+ decorator.decorationGroups['highlight'] = [];
39
+ return decorator.highlight(code);
40
+ }
41
+ const tree = this.parser.parse(code);
42
+ const root = tree.rootNode;
43
+ const highlightsQuery = root.query(this.hightligtScm);
44
+ const captures = [];
45
+ for (const item of highlightsQuery) {
46
+ captures.push(...item.captures);
47
+ }
48
+ const decorations = [];
49
+ for (const capture of captures) {
50
+ const { node, name } = capture; // name is the capture like "@string"
51
+ const startIndex = node.startIndex;
52
+ const endIndex = node.endIndex;
53
+ decorations.push({
54
+ startIndex,
55
+ endIndex,
56
+ className: 'ts-' + name.replaceAll('.', '_'),
57
+ });
58
+ }
59
+ decorator.decorationGroups['highlight'] = decorations;
60
+ return decorator.highlight(code);
61
+ }
62
+ }
@@ -0,0 +1,2 @@
1
+ export declare const dntGlobalThis: Omit<typeof globalThis, never>;
2
+ //# sourceMappingURL=_dnt.shims.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dnt.shims.d.ts","sourceRoot":"","sources":["../src/_dnt.shims.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,gCAA2C,CAAC"}
@@ -0,0 +1,57 @@
1
+ const dntGlobals = {};
2
+ export const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
3
+ function createMergeProxy(baseObj, extObj) {
4
+ return new Proxy(baseObj, {
5
+ get(_target, prop, _receiver) {
6
+ if (prop in extObj) {
7
+ return extObj[prop];
8
+ }
9
+ else {
10
+ return baseObj[prop];
11
+ }
12
+ },
13
+ set(_target, prop, value) {
14
+ if (prop in extObj) {
15
+ delete extObj[prop];
16
+ }
17
+ baseObj[prop] = value;
18
+ return true;
19
+ },
20
+ deleteProperty(_target, prop) {
21
+ let success = false;
22
+ if (prop in extObj) {
23
+ delete extObj[prop];
24
+ success = true;
25
+ }
26
+ if (prop in baseObj) {
27
+ delete baseObj[prop];
28
+ success = true;
29
+ }
30
+ return success;
31
+ },
32
+ ownKeys(_target) {
33
+ const baseKeys = Reflect.ownKeys(baseObj);
34
+ const extKeys = Reflect.ownKeys(extObj);
35
+ const extKeysSet = new Set(extKeys);
36
+ return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
37
+ },
38
+ defineProperty(_target, prop, desc) {
39
+ if (prop in extObj) {
40
+ delete extObj[prop];
41
+ }
42
+ Reflect.defineProperty(baseObj, prop, desc);
43
+ return true;
44
+ },
45
+ getOwnPropertyDescriptor(_target, prop) {
46
+ if (prop in extObj) {
47
+ return Reflect.getOwnPropertyDescriptor(extObj, prop);
48
+ }
49
+ else {
50
+ return Reflect.getOwnPropertyDescriptor(baseObj, prop);
51
+ }
52
+ },
53
+ has(_target, prop) {
54
+ return prop in extObj || prop in baseObj;
55
+ },
56
+ });
57
+ }
@@ -0,0 +1,6 @@
1
+ import { Node } from 'prosemirror-model';
2
+ import { Decoration, DecorationSource, EditorView, NodeView } from 'prosemirror-view';
3
+ import { CoreEditor } from '@kerebron/editor';
4
+ import { NodeCodeJarConfig } from './NodeCodeJar.js';
5
+ export declare const codeJarBlockNodeView: (settings: NodeCodeJarConfig, editor: CoreEditor) => (node: Node, view: EditorView, getPos: () => number | undefined, decorations: readonly Decoration[], innerDecorations: DecorationSource) => NodeView;
6
+ //# sourceMappingURL=codeJarBlockNodeView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeJarBlockNodeView.d.ts","sourceRoot":"","sources":["../src/codeJarBlockNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,UAAU,EAEV,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAc7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAkUrD,eAAO,MAAM,oBAAoB,EAAE,CACjC,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,UAAU,KACf,CACH,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,MAAM,GAAG,SAAS,EAChC,WAAW,EAAE,SAAS,UAAU,EAAE,EAClC,gBAAgB,EAAE,gBAAgB,KAC/B,QAgBJ,CAAC"}
@@ -0,0 +1,253 @@
1
+ import { PositionMapper } from '@kerebron/extension-markdown/PositionMapper';
2
+ import { toRawTextResult } from '@kerebron/editor/utilities';
3
+ import { CodeJar } from './CodeJar.js';
4
+ import { computeChange, forwardSelection, valueChanged } from './utils.js';
5
+ import { TreeSitterHighlighter } from './TreeSitterHighlighter.js';
6
+ import { Decorator } from './Decorator.js';
7
+ import { initLineNumbers, lineNumberOptions, refreshNumbers, } from './codeJarLineNumbers.js';
8
+ class CodeJarBlockNodeView {
9
+ node;
10
+ view;
11
+ getPos;
12
+ config;
13
+ editor;
14
+ dom;
15
+ codeJar;
16
+ updating;
17
+ element;
18
+ highlighter;
19
+ decorator;
20
+ languageDropDown;
21
+ lineNumbers;
22
+ source;
23
+ extensionLsp;
24
+ lang = 'plaintext';
25
+ uri = 'file:///' + Math.random() + '.ts';
26
+ diagListener;
27
+ constructor(node, view, getPos, config, editor) {
28
+ this.node = node;
29
+ this.view = view;
30
+ this.getPos = getPos;
31
+ this.config = config;
32
+ this.editor = editor;
33
+ this.updating = false;
34
+ const dom = document.createElement('div');
35
+ this.dom = dom;
36
+ dom.className = 'codejar-root';
37
+ this.languageDropDown = this.addLanguageDropDown();
38
+ const root = (editor.view && 'root' in editor.view)
39
+ ? editor.view.root
40
+ : document || document;
41
+ this.element = document.createElement('div');
42
+ this.element.classList.add('codejar');
43
+ this.codeJar = new CodeJar(this.element, (element) => this.highlight(element), {
44
+ tab: ' ',
45
+ indentOn: new RegExp('^(?!)'),
46
+ moveToNewLine: new RegExp('^(?!)'),
47
+ history: false,
48
+ readOnly: this.config.readOnly,
49
+ });
50
+ this.codeJar.onUpdate(() => {
51
+ if (!this.updating) {
52
+ const textUpdate = this.codeJar.toString();
53
+ valueChanged(textUpdate, this.node, getPos, view);
54
+ if (document.activeElement === this.element) {
55
+ forwardSelection(this.codeJar, view, getPos);
56
+ }
57
+ }
58
+ const client = this.extensionLsp?.getClient(this.lang);
59
+ if (client) {
60
+ client.workspace.changedFile(this.uri);
61
+ }
62
+ });
63
+ this.highlighter = new TreeSitterHighlighter();
64
+ this.highlighter.cdnUrl = this.editor.config.cdnUrl;
65
+ this.decorator = new Decorator();
66
+ dom.append(this.element);
67
+ this.lineNumbers = initLineNumbers(this.element, lineNumberOptions);
68
+ this.source = {
69
+ ui: this.editor.ui,
70
+ getMappedContent: async () => {
71
+ const editor = this.editor;
72
+ const result = toRawTextResult(this.codeJar.toString(), 0);
73
+ const mapper = new PositionMapper(editor, result.rawTextMap);
74
+ return {
75
+ ...result,
76
+ mapper,
77
+ };
78
+ },
79
+ };
80
+ this.extensionLsp = editor.getExtension('lsp');
81
+ let lastDiag = 0;
82
+ this.diagListener = (event) => {
83
+ const detail = event.detail;
84
+ if (detail.params.uri !== this.uri) {
85
+ return;
86
+ }
87
+ event.preventDefault();
88
+ lastDiag = +Date();
89
+ const client = this.extensionLsp?.getClient(this.lang);
90
+ if (client) {
91
+ const file = client.workspace.getFile(this.uri);
92
+ if (file) {
93
+ const { mapper } = file;
94
+ console.debug({
95
+ diagnostics: detail.params.diagnostics,
96
+ mapper,
97
+ });
98
+ const diagnostics = detail.params.diagnostics;
99
+ const decors = [];
100
+ for (const diag of diagnostics) {
101
+ const startIndex = mapper.fromLineChar(diag.range.start.line, diag.range.start.character);
102
+ const endIndex = mapper.fromLineChar(diag.range.end.line, diag.range.end.character);
103
+ decors.push({
104
+ startIndex,
105
+ endIndex,
106
+ className: 'kb-lsp__error',
107
+ title: diag.message || '',
108
+ });
109
+ }
110
+ this.decorator.decorationGroups.innerDiag = decors;
111
+ this.highlight(this.element);
112
+ }
113
+ }
114
+ };
115
+ }
116
+ addLanguageDropDown() {
117
+ const select = document.createElement('select');
118
+ select.classList.add('codejar-select');
119
+ for (const lang of [''].concat(this.config.languageWhitelist || [])) {
120
+ const option = document.createElement('option');
121
+ option.value = lang;
122
+ option.innerText = lang;
123
+ select.appendChild(option);
124
+ }
125
+ this.dom.appendChild(select);
126
+ select.addEventListener('change', async () => {
127
+ const lang = select.value;
128
+ const pos = this.getPos();
129
+ if (pos) {
130
+ this.view.dispatch(this.view.state.tr.setNodeMarkup(pos, undefined, {
131
+ ...this.node.attrs,
132
+ lang,
133
+ }));
134
+ }
135
+ await this.setLang(lang);
136
+ });
137
+ return select;
138
+ }
139
+ async setLang(lang) {
140
+ this.languageDropDown.value = lang || '';
141
+ await this.highlighter.init(lang);
142
+ this.highlight(this.element);
143
+ this.lang = lang;
144
+ const client = this.extensionLsp?.getClient(this.lang);
145
+ if (client) {
146
+ client.addEventListener('textDocument/publishDiagnostics', this.diagListener);
147
+ client.connect(this.uri, this.source);
148
+ client.workspace.openFile(this.uri, lang, this.source);
149
+ }
150
+ }
151
+ async init() {
152
+ this.codeJar.updateCode(this.node.textContent, false);
153
+ if (this.node.attrs.lang) {
154
+ await this.setLang(this.node.attrs.lang);
155
+ }
156
+ }
157
+ setSelection(anchor, head) {
158
+ this.element.focus();
159
+ this.updating = true;
160
+ const pos = this.getPos();
161
+ if (pos) {
162
+ anchor -= pos;
163
+ head -= pos;
164
+ const posJar = {
165
+ start: Math.min(anchor, head),
166
+ end: Math.max(anchor, head),
167
+ dir: (anchor <= head) ? '->' : '<-',
168
+ };
169
+ this.codeJar.restore(posJar);
170
+ }
171
+ this.updating = false;
172
+ }
173
+ highlight(editor) {
174
+ // const highlight = withLineNumbers((element) => this.highlight(element));
175
+ if (!this.highlighter) {
176
+ editor.innerHTML = editor.textContent;
177
+ }
178
+ else {
179
+ const content = editor.textContent;
180
+ editor.innerHTML = this.highlighter.highlight(content, this.decorator) ||
181
+ content;
182
+ }
183
+ refreshNumbers(this.lineNumbers, editor);
184
+ }
185
+ update(updateNode, _decorations, innerDecorations) {
186
+ const codeDecorations = [];
187
+ innerDecorations
188
+ .forEachSet((set) => set.find()
189
+ .map((d) => {
190
+ codeDecorations.push(d);
191
+ }));
192
+ const decors = [];
193
+ for (const cd of codeDecorations) {
194
+ if ('type' in cd) {
195
+ const type = cd.type;
196
+ decors.push({
197
+ startIndex: cd.from,
198
+ endIndex: cd.to,
199
+ className: type?.attrs?.class || '',
200
+ title: type?.attrs?.title || '',
201
+ });
202
+ }
203
+ }
204
+ this.decorator.decorationGroups.diag = decors;
205
+ const oldNode = this.node;
206
+ const content = this.codeJar.toString();
207
+ const change = computeChange(content, updateNode.textContent);
208
+ if (change) {
209
+ const pos = this.codeJar.save();
210
+ this.updating = true;
211
+ this.codeJar.updateCode(updateNode.textContent, true);
212
+ this.updating = false;
213
+ // TODO fix for yjs collab
214
+ // change.from, change.to, change.text.length
215
+ if (pos) {
216
+ this.codeJar.restore(pos);
217
+ }
218
+ }
219
+ this.node = updateNode;
220
+ if (updateNode.attrs.lang !== oldNode.attrs.lang) {
221
+ this.setLang(updateNode.attrs.lang);
222
+ }
223
+ return true;
224
+ }
225
+ selectNode() {
226
+ this.element.focus();
227
+ }
228
+ stopEvent(_e) {
229
+ return true;
230
+ }
231
+ ignoreMutation() {
232
+ return true;
233
+ }
234
+ destroy() {
235
+ const client = this.extensionLsp?.getClient(this.lang);
236
+ if (client) {
237
+ if (this.uri) {
238
+ client.disconnect(this.uri);
239
+ }
240
+ if (this.diagListener) {
241
+ client.removeEventListener('textDocument/publishDiagnostics', this.diagListener);
242
+ }
243
+ }
244
+ this.codeJar.destroy();
245
+ }
246
+ }
247
+ export const codeJarBlockNodeView = (settings, editor) => {
248
+ return (pmNode, view, getPos) => {
249
+ const plugin = new CodeJarBlockNodeView(pmNode, view, getPos, settings, editor);
250
+ plugin.init();
251
+ return plugin;
252
+ };
253
+ };
@@ -0,0 +1,13 @@
1
+ type Options = {
2
+ class: string;
3
+ wrapClass: string;
4
+ width: string;
5
+ backgroundColor: string;
6
+ color: string;
7
+ };
8
+ export declare const lineNumberOptions: Options;
9
+ export declare function withLineNumbers(highlight: (e: HTMLElement) => void, options?: Partial<Options>): (editor: HTMLElement) => void;
10
+ export declare function refreshNumbers(lineNumbers: HTMLElement, editor: HTMLElement): void;
11
+ export declare function initLineNumbers(editor: HTMLElement, opts: Options): HTMLElement;
12
+ export {};
13
+ //# sourceMappingURL=codeJarLineNumbers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeJarLineNumbers.d.ts","sourceRoot":"","sources":["../src/codeJarLineNumbers.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,OAM/B,CAAC;AAEF,wBAAgB,eAAe,CAC7B,SAAS,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,EACnC,OAAO,GAAE,OAAO,CAAC,OAAO,CAAM,IAGb,QAAQ,WAAW,UAwBrC;AAED,wBAAgB,cAAc,CAC5B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,WAAW,QAapB;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,OAAO,GACZ,WAAW,CA0Db"}
@@ -0,0 +1,85 @@
1
+ // This class was copied from https://github.com/antonmedv/codejar/blob/3.7.0/linenumbers.ts
2
+ // and applied with further improvements and fixes
3
+ export const lineNumberOptions = {
4
+ class: 'codejar-linenumbers',
5
+ wrapClass: 'codejar-wrap',
6
+ width: '35px',
7
+ backgroundColor: 'rgba(128, 128, 128, 0.15)',
8
+ color: '',
9
+ };
10
+ export function withLineNumbers(highlight, options = {}) {
11
+ let lineNumbers;
12
+ return function (editor) {
13
+ highlight(editor);
14
+ if (!lineNumbers) {
15
+ lineNumbers = initLineNumbers(editor, {
16
+ ...lineNumberOptions,
17
+ ...options,
18
+ });
19
+ editor.addEventListener('scroll', () => lineNumbers.style.top = `-${editor.scrollTop}px`);
20
+ }
21
+ const code = editor.textContent || '';
22
+ const linesCount = code.replace(/\n$/g, '').split('\n').length;
23
+ let text = '';
24
+ for (let i = 0; i < linesCount; i++) {
25
+ text += `${i + 1}\n`;
26
+ }
27
+ lineNumbers.innerText = text;
28
+ };
29
+ }
30
+ export function refreshNumbers(lineNumbers, editor) {
31
+ const code = editor.textContent || '';
32
+ const linesCount = code.replace(/\n$/g, '').split('\n').length;
33
+ let text = '';
34
+ for (let i = 0; i < linesCount; i++) {
35
+ text += `${i + 1}\n`;
36
+ }
37
+ lineNumbers.innerText = text;
38
+ // Hack editor styles
39
+ editor.style.paddingLeft = `calc(40px + 5px)`;
40
+ }
41
+ export function initLineNumbers(editor, opts) {
42
+ const css = getComputedStyle(editor);
43
+ const wrap = document.createElement('div');
44
+ wrap.className = opts.wrapClass;
45
+ wrap.style.position = 'relative';
46
+ const innerWrap = document.createElement('div');
47
+ innerWrap.className = 'codejar-linenumbers-inner-wrap';
48
+ innerWrap.style.background = css.background;
49
+ innerWrap.style.marginTop = css.borderTopWidth;
50
+ innerWrap.style.marginBottom = css.borderBottomWidth;
51
+ innerWrap.style.marginLeft = css.borderLeftWidth;
52
+ innerWrap.style.borderTopLeftRadius = css.borderTopLeftRadius;
53
+ innerWrap.style.borderBottomLeftRadius = css.borderBottomLeftRadius;
54
+ const gutter = document.createElement('div');
55
+ gutter.className = opts.class;
56
+ innerWrap.appendChild(gutter);
57
+ wrap.appendChild(innerWrap);
58
+ // Add own styles
59
+ gutter.style.width = opts.width;
60
+ gutter.style.overflow = 'hidden';
61
+ gutter.style.backgroundColor = opts.backgroundColor;
62
+ // Copy editor styles
63
+ gutter.style.fontFamily = css.fontFamily;
64
+ gutter.style.fontSize = css.fontSize;
65
+ gutter.style.lineHeight = css.lineHeight;
66
+ gutter.style.paddingTop = `calc(${css.paddingTop})`;
67
+ gutter.style.paddingLeft = css.paddingLeft;
68
+ gutter.style.borderTopLeftRadius = css.borderTopLeftRadius;
69
+ gutter.style.borderBottomLeftRadius = css.borderBottomLeftRadius;
70
+ // Add line numbers
71
+ const lineNumbers = document.createElement('div');
72
+ lineNumbers.setAttribute('class', 'codejar-linenumber');
73
+ lineNumbers.style.color = opts.color || css.color;
74
+ lineNumbers.style.setProperty('mix-blend-mode', 'unset');
75
+ gutter.appendChild(lineNumbers);
76
+ // Tweak editor styles
77
+ editor.style.paddingLeft =
78
+ `calc(${opts.width} + ${gutter.style.paddingLeft} + 5px)`;
79
+ editor.style.whiteSpace = 'pre';
80
+ // Swap editor with a wrap
81
+ editor.parentNode.insertBefore(wrap, editor);
82
+ wrap.appendChild(editor);
83
+ editor.addEventListener('scroll', () => lineNumbers.style.top = `-${editor.scrollTop}px`);
84
+ return lineNumbers;
85
+ }
package/esm/mod.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './ExtensionCodeJar.js';
2
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC"}
package/esm/mod.js ADDED
@@ -0,0 +1 @@
1
+ export * from './ExtensionCodeJar.js';
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/esm/utils.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { Node } from 'prosemirror-model';
2
+ import { EditorView } from 'prosemirror-view';
3
+ import { CodeJar } from './CodeJar.js';
4
+ import { TextSelection } from 'prosemirror-state';
5
+ export declare function computeChange(oldVal: string, newVal: string): {
6
+ from: number;
7
+ to: number;
8
+ text: string;
9
+ } | null;
10
+ export declare const valueChanged: (textUpdate: string, node: Node, getPos: () => number | undefined, view: EditorView) => void;
11
+ export declare const forwardSelection: (codejar: CodeJar, pmView: EditorView, getPos: () => number | undefined) => void;
12
+ export declare const asProseMirrorSelection: (pmDoc: Node, codejar: CodeJar, getPos: () => number | undefined) => TextSelection;
13
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;SAoB3D;AAED,eAAO,MAAM,YAAY,GACvB,YAAY,MAAM,EAClB,MAAM,IAAI,EACV,QAAQ,MAAM,MAAM,GAAG,SAAS,EAChC,MAAM,UAAU,SAkBjB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,SAAS,OAAO,EAChB,QAAQ,UAAU,EAClB,QAAQ,MAAM,MAAM,GAAG,SAAS,SAOjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,OAAO,IAAI,EACX,SAAS,OAAO,EAChB,QAAQ,MAAM,MAAM,GAAG,SAAS,kBASjC,CAAC"}