Make auto-indent configurable (none, preserve, smart).

This commit is contained in:
Martín Lucas Golini
2026-04-12 16:42:54 -03:00
parent 2e481f40f3
commit 382781edec
6 changed files with 131 additions and 11 deletions

View File

@@ -48,6 +48,8 @@ class EE_API TextDocument {
enum class IndentType { IndentSpaces, IndentTabs };
enum class AutoIndentConfig { None, Preserve, Smart };
enum class FindReplaceType { Normal, LuaPattern, RegEx };
enum class LoadStatus { Loaded, Interrupted, Failed };
@@ -477,6 +479,10 @@ class EE_API TextDocument {
void setIndentType( const IndentType& indentType );
const AutoIndentConfig& getAutoIndent() const;
void setAutoIndent( const AutoIndentConfig& autoIndent );
const SyntaxDefinition& getSyntaxDefinition() const;
void setSyntaxDefinition( std::shared_ptr<SyntaxDefinition> definition );
@@ -783,6 +789,7 @@ class EE_API TextDocument {
std::vector<std::pair<String::StringBaseType, String::StringBaseType>> mAutoCloseBracketsPairs;
Uint32 mIndentWidth{ 4 };
IndentType mIndentType{ IndentType::IndentTabs };
AutoIndentConfig mAutoIndent{ AutoIndentConfig::Smart };
Clock mTimer;
std::shared_ptr<SyntaxDefinition> mSyntaxDefinition;
std::string mDefaultFileName;
@@ -876,7 +883,6 @@ class EE_API TextDocument {
TextPosition findPreviousEmptyLines( size_t selIdx );
TextPosition findNextEmptyLines( size_t selIdx );
};
struct TextSearchParams {

View File

@@ -2724,16 +2724,19 @@ void TextDocument::newLine() {
for ( int i = (int)mSelection.size() - 1; i >= 0; --i ) {
TextPosition start = getSelectionIndex( i ).start();
TextPosition indentPos = startOfContent( start );
String indentStr;
if ( indentPos.column() != 0 )
indentStr = line( start.line() ).getText().substr( 0, indentPos.column() );
if ( mAutoIndent != AutoIndentConfig::None ) {
TextPosition indentPos = startOfContent( start );
if ( indentPos.column() != 0 )
indentStr = line( start.line() ).getText().substr( 0, indentPos.column() );
}
String input( "\n" );
input.append( indentStr );
bool isPair = false;
if ( mAutoCloseBrackets && start > startOfDoc() && start < endOfDoc() ) {
if ( mAutoIndent == AutoIndentConfig::Smart && start > startOfDoc() &&
start < endOfDoc() ) {
String::StringBaseType curChar = getChar( start );
String::StringBaseType prevChar = getPrevChar( start );
for ( const auto& pair : mAutoCloseBracketsPairs ) {
@@ -2767,9 +2770,11 @@ void TextDocument::newLineAbove() {
for ( size_t i = 0; i < mSelection.size(); ++i ) {
String input( "\n" );
TextPosition start = getSelectionIndex( i ).start();
TextPosition indent = startOfContent( getSelectionIndex( i ).start() );
if ( indent.column() != 0 )
input.insert( 0, line( start.line() ).getText().substr( 0, indent.column() ) );
if ( mAutoIndent != AutoIndentConfig::None ) {
TextPosition indent = startOfContent( getSelectionIndex( i ).start() );
if ( indent.column() != 0 )
input.insert( 0, line( start.line() ).getText().substr( 0, indent.column() ) );
}
insert( i, { start.line(), 0 }, input );
setSelection( i, { start.line(), (Int64)input.size() } );
}
@@ -3009,6 +3014,14 @@ void TextDocument::setIndentType( const IndentType& indentType ) {
mIndentType = indentType;
}
const TextDocument::AutoIndentConfig& TextDocument::getAutoIndent() const {
return mAutoIndent;
}
void TextDocument::setAutoIndent( const AutoIndentConfig& autoIndent ) {
mAutoIndent = autoIndent;
}
void TextDocument::undo() {
setRunningTransaction( true );
bool stackWasFull = mUndoStack.getMaxStackSize() == mUndoStack.getUndoStackContainer().size();

View File

@@ -44,6 +44,23 @@ CharacterAlignment characterAlignmentFromString( const std::string_view& str ) {
return CharacterAlignment::Left;
}
static EE::UI::Doc::TextDocument::AutoIndentConfig autoIndentFromString( const std::string& str ) {
if ( str == "none" )
return EE::UI::Doc::TextDocument::AutoIndentConfig::None;
if ( str == "preserve" )
return EE::UI::Doc::TextDocument::AutoIndentConfig::Preserve;
return EE::UI::Doc::TextDocument::AutoIndentConfig::Smart;
}
static std::string
autoIndentToString( const EE::UI::Doc::TextDocument::AutoIndentConfig& autoIndent ) {
if ( autoIndent == EE::UI::Doc::TextDocument::AutoIndentConfig::None )
return "none";
if ( autoIndent == EE::UI::Doc::TextDocument::AutoIndentConfig::Preserve )
return "preserve";
return "smart";
}
static PanelPosition panelPositionFromString( const std::string& str ) {
if ( String::toLower( str ) == "right" )
return PanelPosition::Right;
@@ -151,6 +168,7 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath,
doc.forceNewLineAtEndOfFile =
ini.getValueB( "document", "force_new_line_at_end_of_file", false );
doc.autoDetectIndentType = ini.getValueB( "document", "auto_detect_indent_type", true );
doc.autoIndent = autoIndentFromString( ini.getValue( "document", "auto_indent", "smart" ) );
doc.writeUnicodeBOM = ini.getValueB( "document", "write_bom", false );
doc.indentWidth = ini.getValueI( "document", "indent_width", 4 );
doc.indentSpaces = ini.getValueB( "document", "indent_spaces", false );
@@ -226,8 +244,8 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath,
term.colorScheme = ini.getValue( "terminal", "colorscheme", "eterm" );
term.newTerminalOrientation = NewTerminalOrientation::fromString(
ini.getValue( "terminal", "new_terminal_orientation", "vertical" ) );
term.workingDir = TerminalWorkingDir::fromString(
ini.getValue( "terminal", "working_dir", "project" ) );
term.workingDir =
TerminalWorkingDir::fromString( ini.getValue( "terminal", "working_dir", "project" ) );
term.workingDirOther = ini.getValue( "terminal", "working_dir_other", "" );
term.scrollback = ini.getValueI( "terminal", "scrollback", 10000 );
term.unsupportedOSWarnDisabled =
@@ -350,6 +368,7 @@ void AppConfig::save( const std::vector<std::string>& recentFiles,
ini.setValueB( "document", "trim_trailing_whitespaces", doc.trimTrailingWhitespaces );
ini.setValueB( "document", "force_new_line_at_end_of_file", doc.forceNewLineAtEndOfFile );
ini.setValueB( "document", "auto_detect_indent_type", doc.autoDetectIndentType );
ini.setValue( "document", "auto_indent", autoIndentToString( doc.autoIndent ) );
ini.setValueB( "document", "write_bom", doc.writeUnicodeBOM );
ini.setValueI( "document", "indent_width", doc.indentWidth );
ini.setValueB( "document", "tab_stops", doc.tabStops );
@@ -569,6 +588,7 @@ void AppConfig::saveProject( std::string projectFolder, UICodeEditorSplitter* ed
cfg.setValueB( "document", "force_new_line_at_end_of_file",
docConfig.doc.forceNewLineAtEndOfFile );
cfg.setValueB( "document", "auto_detect_indent_type", docConfig.doc.autoDetectIndentType );
cfg.setValue( "document", "auto_indent", autoIndentToString( docConfig.doc.autoIndent ) );
cfg.setValueB( "document", "write_bom", docConfig.doc.writeUnicodeBOM );
cfg.setValueI( "document", "indent_width", docConfig.doc.indentWidth );
cfg.setValueB( "document", "indent_spaces", docConfig.doc.indentSpaces );
@@ -859,6 +879,8 @@ void AppConfig::loadProject( std::string projectFolder, UICodeEditorSplitter* ed
cfg.getValueB( "document", "force_new_line_at_end_of_file", false );
docConfig.doc.autoDetectIndentType =
cfg.getValueB( "document", "auto_detect_indent_type", true );
docConfig.doc.autoIndent =
autoIndentFromString( cfg.getValue( "document", "auto_indent", "smart" ) );
docConfig.doc.writeUnicodeBOM = cfg.getValueB( "document", "write_bom", false );
docConfig.doc.indentWidth = cfg.getValueI( "document", "indent_width", 4 );
docConfig.doc.indentSpaces = cfg.getValueB( "document", "indent_spaces", false );

View File

@@ -116,6 +116,7 @@ struct DocumentConfig {
bool indentSpaces{ false };
bool tabStops{ true };
TextFormat::LineEnding lineEndings{ TextFormat::LineEnding::LF };
TextDocument::AutoIndentConfig autoIndent{ TextDocument::AutoIndentConfig::Smart };
int indentWidth{ 4 };
int tabWidth{ 4 };
int lineBreakingColumn{ 100 };

View File

@@ -2956,6 +2956,7 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) {
: TextDocument::IndentType::IndentTabs );
doc.setIndentWidth( docc.indentWidth );
doc.setAutoDetectIndentType( docc.autoDetectIndentType );
doc.setAutoIndent( docc.autoIndent );
doc.setBOM( docc.writeUnicodeBOM );
doc.getFoldRangeService().setEnabled( config.codeFoldingEnabled );

View File

@@ -343,6 +343,53 @@ UITerminal* SettingsMenu::getCurrentTerminal() const {
UIMenu* SettingsMenu::createDocumentMenu() {
auto shouldCloseCb = []( UIMenuItem* ) -> bool { return false; };
auto setupAutoIndentMenu = [this](
UIPopUpMenu* parentMenu, const std::string& menuId,
std::function<TextDocument::AutoIndentConfig()> getConfig,
std::function<void( TextDocument::AutoIndentConfig )> onClick ) {
UIPopUpMenu* autoIndentMenu = UIPopUpMenu::New();
auto subMenu =
parentMenu->addSubMenu( i18n( "auto_indent", "Auto-Indent" ), nullptr, autoIndentMenu );
subMenu
->setTooltipText(
i18n( "auto_indent_tooltip",
"Configures the automatic indentation behavior when pressing Enter.\n"
"None: No automatic indentation.\n"
"Preserve: Preserves the indentation level of the previous line.\n"
"Smart: Preserves indentation and automatically indents between auto-closed "
"brackets." ) )
->setId( menuId );
subMenu->on( Event::OnMenuShow, [this, autoIndentMenu, getConfig, onClick]( const Event* ) {
if ( autoIndentMenu->getCount() == 0 ) {
autoIndentMenu->addRadioButton( i18n( "auto_indent_none", "None" ) )
->setId( "auto_indent_none" );
autoIndentMenu->addRadioButton( i18n( "auto_indent_preserve", "Preserve" ) )
->setId( "auto_indent_preserve" );
autoIndentMenu->addRadioButton( i18n( "auto_indent_smart", "Smart" ) )
->setId( "auto_indent_smart" );
autoIndentMenu->on( Event::OnItemClicked, [onClick]( const Event* event ) {
const String& text = event->getNode()->asType<UIMenuRadioButton>()->getId();
TextDocument::AutoIndentConfig autoIndent =
text == "auto_indent_none" ? TextDocument::AutoIndentConfig::None
: text == "auto_indent_preserve" ? TextDocument::AutoIndentConfig::Preserve
: TextDocument::AutoIndentConfig::Smart;
onClick( autoIndent );
} );
}
TextDocument::AutoIndentConfig currentConfig = getConfig();
autoIndentMenu->getItemId( "auto_indent_none" )
->asType<UIMenuRadioButton>()
->setActive( currentConfig == TextDocument::AutoIndentConfig::None );
autoIndentMenu->getItemId( "auto_indent_preserve" )
->asType<UIMenuRadioButton>()
->setActive( currentConfig == TextDocument::AutoIndentConfig::Preserve );
autoIndentMenu->getItemId( "auto_indent_smart" )
->asType<UIMenuRadioButton>()
->setActive( currentConfig == TextDocument::AutoIndentConfig::Smart );
} );
return subMenu;
};
mDocMenu = UIPopUpMenu::New();
// **** CURRENT DOCUMENT ****
@@ -355,6 +402,18 @@ UIMenu* SettingsMenu::createDocumentMenu() {
mApp->getConfig().doc.autoDetectIndentType )
->setId( "auto_indent_cur" );
setupAutoIndentMenu(
mDocMenu, "auto_indent_menu_cur",
[this]() {
return mSplitter->curEditorExistsAndFocused()
? mSplitter->getCurEditor()->getDocument().getAutoIndent()
: TextDocument::AutoIndentConfig::Smart;
},
[this]( TextDocument::AutoIndentConfig autoIndent ) {
if ( mSplitter->curEditorExistsAndFocused() )
mSplitter->getCurEditor()->getDocument().setAutoIndent( autoIndent );
} );
UIMenuSubMenu* fileTypeMenu = mDocMenu->addSubMenu(
i18n( "file_type", "File Type" ), findIcon( "file-code" ), createFileTypeMenu( true ) );
@@ -543,6 +602,15 @@ UIMenu* SettingsMenu::createDocumentMenu() {
mApp->getConfig().doc.autoDetectIndentType )
->setId( "auto_indent" );
setupAutoIndentMenu(
mGlobalMenu, "auto_indent_menu", [this]() { return mApp->getConfig().doc.autoIndent; },
[this]( TextDocument::AutoIndentConfig autoIndent ) {
mApp->getConfig().doc.autoIndent = autoIndent;
mSplitter->forEachEditor( [autoIndent]( UICodeEditor* editor ) {
editor->getDocument().setAutoIndent( autoIndent );
} );
} );
UIPopUpMenu* tabTypeMenuGlobal = UIPopUpMenu::New();
tabTypeMenuGlobal->addRadioButton( i18n( "tabs", "Tabs" ) )
->setActive( !mApp->getConfig().doc.indentSpaces )
@@ -803,6 +871,14 @@ UIMenu* SettingsMenu::createDocumentMenu() {
->setId( "auto_indent" )
->setEnabled( !mApp->getProjectConfig().useGlobalSettings );
auto autoIndentProjectSubMenu = setupAutoIndentMenu(
mProjectDocMenu, "auto_indent_menu_project",
[this]() { return mApp->getProjectConfig().doc.autoIndent; },
[this]( TextDocument::AutoIndentConfig autoIndent ) {
mApp->getProjectConfig().doc.autoIndent = autoIndent;
} );
autoIndentProjectSubMenu->setEnabled( !mApp->getProjectConfig().useGlobalSettings );
UIPopUpMenu* tabTypeMenuProject = UIPopUpMenu::New();
tabTypeMenuProject->addRadioButton( i18n( "tabs", "Tabs" ) )
->setActive( !mApp->getProjectConfig().doc.indentSpaces )
@@ -1174,7 +1250,8 @@ UIMenu* SettingsMenu::createTerminalMenu() {
->setId( "configure-terminal-scrollback" );
mTerminalMenu
->add( i18n( "configure_terminal_working_dir", "Configure Terminal Default Working Directory" ),
->add( i18n( "configure_terminal_working_dir",
"Configure Terminal Default Working Directory" ),
findIcon( "terminal" ), getKeybind( "configure-terminal-working-dir" ) )
->setId( "configure-terminal-working-dir" );