1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
import { lowlight } from 'lowlight/lib/core';
import { textblockTypeInputRule } from '@tiptap/core';
import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants';
import { memoizedGet } from '../services/utils';
import CodeBlockHighlight from './code_block_highlight';
const backtickInputRegex = /^```suggestion[\s\n]$/;
export default CodeBlockHighlight.extend({
name: 'codeSuggestion',
isolating: true,
addOptions() {
return {
lowlight,
config: {},
};
},
addAttributes() {
return {
...this.parent?.(),
language: {
default: 'suggestion',
},
isCodeSuggestion: {
default: true,
},
};
},
addCommands() {
const ext = this;
return {
insertCodeSuggestion: (attributes) => async ({ editor }) => {
// do not insert a new suggestion if already inside a suggestion
if (editor.isActive('codeSuggestion')) return false;
const rawPath = ext.options.config.diffFile.view_path.replace('/blob/', '/raw/');
const allLines = (await memoizedGet(rawPath)).split('\n');
const { line } = ext.options.config;
let { lines } = ext.options.config;
if (!lines.length) lines = [line];
const content = lines.map((l) => allLines[l.new_line - 1]).join('\n');
const lineNumbers = `-${lines.length - 1}+0`;
editor.commands.insertContent({
type: 'codeSuggestion',
attrs: { langParams: lineNumbers, ...attributes },
// empty strings are not allowed in text nodes
content: [{ type: 'text', text: content || ' ' }],
});
return true;
},
};
},
parseHTML() {
return [
{
priority: PARSE_HTML_PRIORITY_HIGHEST,
tag: 'pre[lang="suggestion"]',
},
];
},
addInputRules() {
return [
textblockTypeInputRule({
find: backtickInputRegex,
type: this.type,
getAttributes: () => ({ language: 'suggestion', langParams: '-0+0' }),
}),
];
},
});
|