continuedev / continue

⏩ Continue is the leading open-source AI code assistant. You can connect any models and any context to build custom autocomplete and chat experiences inside VS Code and JetBrains
https://docs.continue.dev/
Apache License 2.0
18.97k stars 1.62k forks source link

[BUG] Code Block Display and Diff Generation Issue with /edit Command in Markdown Documents #738

Open LangLangBart opened 10 months ago

LangLangBart commented 10 months ago

Before submitting your bug report

Relevant environment info

- Continue: v0.9.4

Description

When a user writes a code block in a markdown document and later uses the /edit slash command on this code block, the code block isn't accurately displayed in the code preview and is entirely eliminated from the resulting diff.


Possible solution idea?

The display problem of the code block within your preview might be resolved for most cases by using an increased number of backticks.

In markdown, typically a single backtick starts inline code and three backticks start a code block. However, you can use any number of backticks, just ensure the number of backticks used to start and end a code block is the same.

For example, this code block starts and ends with nine backticks, and everything inside is properly displayed. If I had used only eight backticks, the last code block would not render properly in markdown.

This is a code block with 3 backticks
```js
const factorialize = x => x < 1 ? 1 : factorialize(x - 1) * x;
factorialize(5); // 120

This is a code block with 8 backticks

const even = n => n >= 0 ? (!(n % 2) && console.log(n, 'is even'), even(n - 1)) : null;
even(3);
// 2 is even
// 0 is even

The change below ensures that a code block, marked by three backticks, is not removed from the diff.
However, more changes are required to fully resolve this issue. These include updating the
documentation and templates, and fixing the preview code when highlighted in the 'continue'
extension. 

```diff
--- a/core/commands/slash/edit.ts
+++ b/core/commands/slash/edit.ts
@@ -188,7 +188,7 @@ function isEndLine(line: string) {

 function lineToBeIgnored(line: string, isFirstLine: boolean = false): boolean {
   return (
-    line.includes("```") ||
+    line.includes("````") ||
     line.includes("<modified_code_to_edit>") ||
     line.includes("<file_prefix>") ||
     line.includes("</file_prefix>") ||

The idea of using extra backticks in markdown for properly formatting inline code or code blocks was obtained from a video[^1] produced by a VSCode maintainer who also developed numerous VSCode markdown extensions[^2].

[^1]: YouTube: Markdown Tips — Using backticks in inline code [^2]: Publisher Matt Bierner - Visual Studio Marketplace

To reproduce

  1. Create a markdown file that includes some text and a code block as shown below:
To print Abbreviated weekday name:
```bash
date +"%a"


~~2. Highlight the code block you've written and use the `/edit` command to modify it. Note that the preview will not display your code block correctly.~~ 

==> **Addressed in #742**

<img src="https://github.com/continuedev/continue/assets/92653266/aee2d7e1-635b-4421-800a-e53558fd8267" width="400">

3. Observe that the diff generated no longer includes the lines that initiate and end the code block.

<img src="https://github.com/continuedev/continue/assets/92653266/3941dce8-7dce-4ff4-8cdb-48d9726dde09" width="800">

### Log output

_No response_
LangLangBart commented 10 months ago

This change correctly displays a codeblock with three backticks in the preview. However, the same issue may arise if a user uses four backticks.

--- a/gui/src/components/markdown/CodeSnippetPreview.tsx
+++ b/gui/src/components/markdown/CodeSnippetPreview.tsx
@@ -138,9 +138,9 @@ function CodeSnippetPreview(props: CodeSnippetPreviewProps) {
       </PreviewMarkdownHeader>
       <pre className="m-0" ref={codeBlockRef}>
         <StyledMarkdownPreview
-          source={`\`\`\`${getMarkdownLanguageTagForFile(
+          source={`\`\`\`\`${getMarkdownLanguageTagForFile(
             props.item.description
-          )}\n${props.item.content}\n\`\`\``}
+          )}\n${props.item.content}\n\`\`\`\``}
           maxHeight={MAX_PREVIEW_HEIGHT}
           showCodeBorder={false}
         />

@sestinj, could the solution be to find the maximum number of consecutive backticks used and then use one more backtick?