Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Editor loses indentation when pressing ENTER on empty line with whitespace #64

@fcoury

Description

@fcoury

Description

The editor incorrectly resets the cursor to column 0 when pressing ENTER on a line that contains only whitespace (indentation spaces). This breaks the expected flow when writing code, as users expect the indentation level to be maintained.

Steps to Reproduce

  1. Open a file with the following content:
fn name() {
    let a = 1;
    |
}
  1. With the cursor on the let a = 1; line, press o to create a new line below
  2. The cursor is correctly positioned at the indentation level (4 spaces in)
  3. Press ENTER without typing anything
  4. Bug: The cursor jumps to column 0 instead of maintaining the indentation

Expected Behavior

When pressing ENTER on a line that contains only whitespace (indentation), the cursor should maintain the current indentation level on the new line.

Actual Behavior

The cursor resets to column 0, losing all indentation.

Root Cause Analysis

After investigating the codebase, I found two issues:

  1. Editor::current_line_indentation() - This method returns 0 for lines containing only whitespace because line.chars().position(|c| !c.is_whitespace()) returns None when no non-whitespace character is found.

  2. Buffer::insert() with newlines - When inserting a newline character, if the cursor position exceeds the current line length, the method clamps the position to the line length (0 for empty lines), causing text to be inserted at position 0.

Proposed Fix

The fix involves two changes:

  1. Update current_line_indentation() to handle whitespace-only lines:
fn current_line_indentation(&self) -> usize {
    let line = self.current_buffer().line(self.cursor.y);
    
    // If line only contains whitespace, return its length
    if line.chars().all(|c| c.is_whitespace()) {
        line.len_chars()
    } else {
        line.chars().position(|c| !c.is_whitespace()).unwrap_or(0)
    }
}
  1. Update Buffer::insert() to pad with spaces when cursor exceeds line length:
// In the newline handling section
if self.cursor.x > line_len {
    // Pad with spaces before inserting newline
    let padding = " ".repeat(self.cursor.x - line_len);
    self.rope.insert(char_idx, &padding);
    char_idx += padding.len();
}

Impact

This bug affects the editing experience when writing structured code (functions, loops, conditionals) where maintaining indentation across empty lines is important for code readability and structure.

Environment

  • Red editor (latest commit: 8eab0cd)
  • Affects all file types with indentation-based formatting

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions