Skip to content

Commit 5c01097

Browse files
committed
code block with suggestion view
1 parent 5f831e1 commit 5c01097

11 files changed

Lines changed: 237 additions & 90 deletions

File tree

extension/src/utils/gitHubReactTextareaHandler.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ export class GitHubReactTextareaHandler {
4949
}
5050

5151
findCommentBoxModule() {
52-
console.log('root')
5352
return this.root.closest<HTMLElement>('[class*="CommentBox-module"]')
5453
}
5554

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
"remark-parse": "catalog:",
8181
"remark-rehype": "catalog:",
8282
"remark-stringify": "catalog:",
83+
"shiki": "^3.20.0",
8384
"solid-codemirror": "^2.3.1",
8485
"solid-confetti-explosion": "^1.1.8",
8586
"solid-js": "catalog:",

pnpm-lock.yaml

Lines changed: 72 additions & 69 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/core/custom/code-block/code-block-node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function defineCodeBlockMarkdown() {
3232
isSuggestion: {
3333
default: false,
3434
},
35-
suggestionConfig: {
35+
suggestChangeConfig: {
3636
default: null,
3737
},
3838
},

src/core/custom/code-block/code-block-view.module.css

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,33 @@
6161
background: var(--button-default-bgColor-hover);
6262
}
6363
}
64+
65+
&.diffOriginal {
66+
background-color: var(--bgColor-default);
67+
border-radius: 0;
68+
margin-bottom: 0 !important;
69+
min-height: 0;
70+
71+
pre {
72+
background-color: var(--diffBlob-deletionLine-bgColor) !important;
73+
border-radius: 0 !important;
74+
padding-block: var(--base-size-8) !important;
75+
}
76+
}
77+
78+
&.diffAdd {
79+
background-color: var(--bgColor-default);
80+
border-top-left-radius: 0;
81+
border-top-right-radius: 0;
82+
margin-bottom: 0 !important;
83+
min-height: 0;
84+
85+
pre {
86+
background-color: var(--diffBlob-additionLine-bgColor) !important;
87+
border-top-left-radius: 0 !important;
88+
border-top-right-radius: 0 !important;
89+
}
90+
}
6491
}
6592

6693
.LanguageSelectorPopover {
@@ -95,3 +122,27 @@
95122
color: var(--fgColor-onEmphasis);
96123
}
97124
}
125+
126+
.suggestChangeContainer {
127+
position: relative;
128+
border: var(--borderWidth-thin, 1px) solid
129+
var(--borderColor-default, var(--color-border-default));
130+
border-radius: var(--borderRadius-medium, 6px);
131+
margin-bottom: var(--base-size-8);
132+
133+
.codeBlockActions {
134+
top: var(--base-size-2);
135+
transform: translateY(calc(var(--base-size-2) / 2));
136+
}
137+
}
138+
139+
.suggestChangeTitle {
140+
color: var(--fgColor-muted);
141+
font-size: var(--text-body-size-small);
142+
font-weight: var(--base-text-weight-normal);
143+
padding-left: var(--base-size-12);
144+
padding-top: var(--base-size-8);
145+
padding-bottom: var(--base-size-8);
146+
border-bottom: var(--borderWidth-thin, 1px) solid
147+
var(--borderColor-default, var(--color-border-default)) !important;
148+
}

src/core/custom/code-block/code-block.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { defineCodeBlockCustomCommands } from './code-block-custom-commands'
2121
import { defineCmCodeBlockPlugin } from './codemirror/cm-code-block-plugin'
2222
import { defineCmCodeBlock } from './codemirror/cm-code-block'
2323
import { defineCodeBlockMarkdown } from './code-block-node'
24+
import { defineCodeBlockSuggestionCommand } from './suggestion/code-block-suggestion-command'
2425

2526
export function defineCodeBlock() {
2627
return union(
@@ -34,5 +35,6 @@ export function defineCodeBlock() {
3435
component: ShikiCodeBlockView,
3536
}),
3637
defineCodeBlockCustomCommands(),
38+
defineCodeBlockSuggestionCommand(),
3739
)
3840
}

src/core/custom/code-block/codemirror/cm-code-block-plugin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export function defineCmCodeBlockPlugin() {
3535
newState.doc.descendants((node, pos) => {
3636
if (
3737
node.type.name === 'codeBlock' &&
38+
!node.attrs.isSuggestion &&
3839
codeMirrorLanguages.includes(node.attrs.language)
3940
) {
4041
modified = true

src/core/custom/code-block/codemirror/cm-code-block.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,15 @@ export function defineCmCodeBlock() {
6565
defining: true,
6666
isolating: true,
6767
marks: '',
68-
attrs: { language: { default: '', validate: 'string' } },
68+
attrs: {
69+
language: { default: '', validate: 'string' },
70+
isSuggestion: {
71+
default: false,
72+
},
73+
suggestionConfig: {
74+
default: null,
75+
},
76+
},
6977
parseDOM: [
7078
{
7179
tag: 'pre',

src/core/custom/code-block/shiki-code-block-view.tsx

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { createMemo } from 'solid-js'
17+
import { Show, createMemo } from 'solid-js'
1818
import { useNodeViewContext } from '@prosemirror-adapter/solid'
1919
import { shikiBundledLanguagesInfo } from 'prosekit/extensions/code-block'
2020

@@ -44,20 +44,54 @@ export default function ShikiCodeBlockView(props: NodeViewContextProps) {
4444

4545
return (
4646
<NodeViewWrapper>
47-
<div class={`highlight ${styles.CodeBlock}`}>
48-
<div class={styles.codeBlockActions} contenteditable={false}>
49-
<CodeBlockLanguageSelector
50-
value={currentValue()}
51-
setLanguage={setLanguage}
52-
/>
53-
<CodeBlockClipboard content={context().node.textContent} />
54-
</div>
47+
<Show
48+
fallback={
49+
<>
50+
<div class={`highlight ${styles.CodeBlock}`}>
51+
<div class={styles.codeBlockActions} contenteditable={false}>
52+
<CodeBlockLanguageSelector
53+
value={currentValue()}
54+
setLanguage={setLanguage}
55+
/>
56+
<CodeBlockClipboard content={context().node.textContent} />
57+
</div>
58+
59+
<pre
60+
ref={props.contentRef}
61+
data-language={context().node.attrs.language}
62+
></pre>
63+
</div>
64+
</>
65+
}
66+
when={context().node.attrs.isSuggestion}
67+
>
68+
<div class={styles.suggestChangeContainer}>
69+
<div class={styles.suggestChangeTitle}>Suggest changes</div>
5570

56-
<pre
57-
ref={props.contentRef}
58-
data-language={context().node.attrs.language}
59-
></pre>
60-
</div>
71+
<div class={styles.codeBlockActions} contenteditable={false}>
72+
<CodeBlockLanguageSelector
73+
value={currentValue()}
74+
setLanguage={setLanguage}
75+
/>
76+
<CodeBlockClipboard content={context().node.textContent} />
77+
</div>
78+
79+
<div class={`highlight ${styles.CodeBlock} ${styles.diffOriginal}`}>
80+
<pre data-language={context().node.attrs.language}>
81+
{
82+
context().node.attrs.suggestChangeConfig
83+
?.sourceContentFromDiffLines
84+
}
85+
</pre>
86+
</div>
87+
<div class={`highlight ${styles.CodeBlock} ${styles.diffAdd}`}>
88+
<pre
89+
ref={props.contentRef}
90+
data-language={context().node.attrs.language}
91+
></pre>
92+
</div>
93+
</div>
94+
</Show>
6195
</NodeViewWrapper>
6296
)
6397
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2025 Riccardo Perra
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { defineCommands, insertNode } from 'prosekit/core'
18+
import { detectLanguageFromFilename } from '../shiki-language-extensions'
19+
import type { SuggestedChangeConfig } from '../../../../editor/utils/loadCodeSuggestionChangesConfig'
20+
21+
export function defineCodeBlockSuggestionCommand() {
22+
return defineCommands({
23+
insertCodeBlockSuggestion: (attrs: {
24+
suggestChange: SuggestedChangeConfig
25+
}) => {
26+
const lang = detectLanguageFromFilename(attrs.suggestChange.filePath!)
27+
return insertNode({
28+
type: 'codeBlock',
29+
attrs: {
30+
code: attrs.suggestChange.sourceContentFromDiffLines || '',
31+
lang: lang || '',
32+
isSuggestion: true,
33+
suggestedChangeConfig: attrs.suggestChange,
34+
},
35+
})
36+
},
37+
})
38+
}

0 commit comments

Comments
 (0)