diff --git a/src/editor/codemirror/edits.ts b/src/editor/codemirror/edits.ts index ad56721a2..0469b5ba4 100644 --- a/src/editor/codemirror/edits.ts +++ b/src/editor/codemirror/edits.ts @@ -112,6 +112,21 @@ export const calculateChanges = ( } else { mainFrom = state.doc.line(line).from; } + // Determine if code is being appended to previous block and indent accordingly. + const previousLineNum = line - 1; + if (previousLineNum >= 1 && previousLineNum <= state.doc.lines) { + const previousLine = state.doc.line(previousLineNum); + const currentLineIsBlank = lineIsBlank(state, line); + const previousLineIsBlank = lineIsBlank(state, previousLineNum); + mainIndent = + !previousLineIsBlank && currentLineIsBlank + ? previousLine.text.match(/^(\s*)/)?.[0] ?? "" + : ""; + // Special case where body code does not yet exist but should be indented. + if (previousLine.text.trim().endsWith(":") && currentLineIsBlank) { + mainIndent += " "; + } + } } } else { // When no line is specified, insert before the code (not just after the imports). @@ -126,7 +141,7 @@ export const calculateChanges = ( ) { mainCode = removeCommonIndent(mainCode.slice(whileTrueLine.length)); } - mainIndent = insertLine.text.match(/^(\s*)/)?.[0] ?? ""; + mainIndent += insertLine.text.match(/^(\s*)/)?.[0] ?? ""; mainChange = { from: mainFrom, insert: mainPreceedingWhitespace + indentBy(mainCode, mainIndent) + "\n", @@ -153,6 +168,16 @@ export const calculateChanges = ( }); }; +/** + * Determines if the line contains any code. + */ +const lineIsBlank = (state: EditorState, line: number): boolean => { + if (line <= state.doc.lines) { + return state.doc.line(line).text.trim() === ""; + } + return false; +}; + const calculateNewSelection = ( mainCode: string, type: CodeInsertType,