@@ -1567,7 +1567,7 @@ TextPosition TextDocument::positionOffset( TextPosition position, TextPosition o
15671567 return sanitizePosition ( position + offset );
15681568}
15691569
1570- bool TextDocument::replaceLine ( const Int64& lineNum, const String& text ) {
1570+ bool TextDocument::replaceLine ( Int64 lineNum, const String& text ) {
15711571 if ( lineNum >= 0 && lineNum < (Int64)linesCount () ) {
15721572 TextRange oldSelection = getSelection ();
15731573 setSelection ( { startOfLine ( { lineNum, 0 } ), endOfLine ( { lineNum, 0 } ) } );
@@ -2200,6 +2200,12 @@ void TextDocument::deleteToNextChar() {
22002200 mergeSelection ();
22012201}
22022202
2203+ void TextDocument::deleteToStartOfLine () {
2204+ for ( size_t i = 0 ; i < mSelection .size (); ++i )
2205+ deleteTo ( i, startOfLine ( getSelectionIndex ( i ).start () ) );
2206+ mergeSelection ();
2207+ }
2208+
22032209void TextDocument::deleteToEndOfLine () {
22042210 for ( size_t i = 0 ; i < mSelection .size (); ++i )
22052211 deleteTo ( i, endOfLine ( getSelectionIndex ( i ).start () ) );
@@ -4111,6 +4117,21 @@ void TextDocument::fromBase64() {
41114117 }
41124118}
41134119
4120+ void TextDocument::trimTrailingWhitespace () {
4121+ BoolScopedOpOptional op ( !mDoingTextInput , mDoingTextInput , true );
4122+ for ( size_t i = 0 ; i < linesCount (); i++ ) {
4123+ safeLineOp ( i, [&]( TextDocumentLine& op ) {
4124+ if ( op.size () > 1 && ( op[op.size () - 2 ] == ' ' || op[op.size () - 2 ] == ' \t ' ) ) {
4125+ String text ( op.getText () );
4126+ text.pop_back (); // Remove '\n'
4127+ while ( !text.empty () && ( text.back () == ' ' || text.back () == ' \t ' ) )
4128+ text.pop_back ();
4129+ replaceLine ( i, text );
4130+ }
4131+ } );
4132+ }
4133+ }
4134+
41144135void TextDocument::initializeCommands () {
41154136 mCommands [" reset" ] = [this ] { reset (); };
41164137 mCommands [" save" ] = [this ] { save (); };
@@ -4119,6 +4140,7 @@ void TextDocument::initializeCommands() {
41194140 mCommands [" delete-to-next-word" ] = [this ] { deleteToNextWord (); };
41204141 mCommands [" delete-to-next-char" ] = [this ] { deleteToNextChar (); };
41214142 mCommands [" delete-current-line" ] = [this ] { deleteCurrentLine (); };
4143+ mCommands [" delete-to-start-of-line" ] = [this ] { deleteToStartOfLine (); };
41224144 mCommands [" delete-to-end-of-line" ] = [this ] { deleteToEndOfLine (); };
41234145 mCommands [" delete-selection" ] = [this ] { deleteSelection (); };
41244146 mCommands [" delete-word" ] = [this ] { deleteWord (); };
@@ -4174,6 +4196,7 @@ void TextDocument::initializeCommands() {
41744196 mCommands [" unescape" ] = [this ] { unescape (); };
41754197 mCommands [" to-base64" ] = [this ] { toBase64 (); };
41764198 mCommands [" from-base64" ] = [this ] { fromBase64 (); };
4199+ mCommands [" trim-trailing-whitespace" ] = [this ] { trimTrailingWhitespace (); };
41774200
41784201 if ( TEXT_DOCUMENT_COMMANDS.empty () ) {
41794202 for ( const auto & [cmd, _] : mCommands )
0 commit comments