forked from OSchip/llvm-project
[Editline] Redesign automatic indentation fix command for robustness
The FixIndentationCommand implementation has proven to be fragile across various libedit iterations. This patch reworks the command to use the same basic strategy as when moving between lines in a multi-line edit session: when indentation changes are required, exit line editing completely and restart with amended content. This approach won't be susceptible to subtle behavior differences libedit has introduced over time. llvm-svn: 255548
This commit is contained in:
parent
798ea5b6ff
commit
a11959dbf7
lldb/source/Host/common
|
@ -863,37 +863,50 @@ Editline::NextLineCommand (int ch)
|
|||
unsigned char
|
||||
Editline::FixIndentationCommand (int ch)
|
||||
{
|
||||
if (!m_fix_indentation_callback)
|
||||
if (!m_fix_indentation_callback)
|
||||
return CC_NORM;
|
||||
|
||||
// Insert the character by hand prior to correction
|
||||
|
||||
// Insert the character typed before proceeding
|
||||
EditLineCharType inserted[] = { (EditLineCharType)ch, 0 };
|
||||
el_winsertstr (m_editline, inserted);
|
||||
SaveEditedLine();
|
||||
StringList lines = GetInputAsStringList (m_current_line_index + 1);
|
||||
|
||||
// Determine the cursor position
|
||||
LineInfoW * info = const_cast<LineInfoW *>(el_wline (m_editline));
|
||||
int cursor_position = info->cursor - info->buffer;
|
||||
|
||||
|
||||
// Save the edits and determine the correct indentation level
|
||||
SaveEditedLine();
|
||||
StringList lines = GetInputAsStringList (m_current_line_index + 1);
|
||||
int indent_correction = m_fix_indentation_callback (this, lines, cursor_position, m_fix_indentation_callback_baton);
|
||||
|
||||
// Adjust the input buffer to correct indentation
|
||||
|
||||
// If it is already correct no special work is needed
|
||||
if (indent_correction == 0)
|
||||
return CC_REFRESH;
|
||||
|
||||
// Change the indentation level of the line
|
||||
std::string currentLine = lines.GetStringAtIndex (m_current_line_index);
|
||||
if (indent_correction > 0)
|
||||
{
|
||||
info->cursor = info->buffer;
|
||||
el_winsertstr (m_editline, EditLineStringType (indent_correction, EditLineCharType(' ')).c_str());
|
||||
currentLine = currentLine.insert (0, indent_correction, ' ');
|
||||
}
|
||||
else if (indent_correction < 0)
|
||||
else
|
||||
{
|
||||
// Delete characters for the unindentation AND including the character we just added.
|
||||
el_wdeletestr (m_editline, -indent_correction + 1);
|
||||
|
||||
// Rewrite the character that caused the unindentation.
|
||||
el_winsertstr (m_editline, inserted);
|
||||
currentLine = currentLine.erase (0, -indent_correction);
|
||||
}
|
||||
info->cursor = info->buffer + cursor_position + indent_correction;
|
||||
return CC_REFRESH;
|
||||
#if LLDB_EDITLINE_USE_WCHAR
|
||||
m_input_lines[m_current_line_index] = m_utf8conv.from_bytes (currentLine);
|
||||
#else
|
||||
m_input_lines[m_current_line_index] = currentLine;
|
||||
#endif
|
||||
|
||||
// Update the display to reflect the change
|
||||
MoveCursor (CursorLocation::EditingCursor, CursorLocation::EditingPrompt);
|
||||
DisplayInput (m_current_line_index);
|
||||
|
||||
// Reposition the cursor back on the original line and prepare to restart editing
|
||||
// with a new cursor position
|
||||
SetCurrentLine (m_current_line_index);
|
||||
MoveCursor (CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
|
||||
m_revert_cursor_index = cursor_position + indent_correction;
|
||||
return CC_NEWLINE;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
|
|
Loading…
Reference in New Issue