|
|
|
@ -1280,43 +1280,89 @@ bool Notepad_plus::replaceInOpenedFiles()
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Notepad_plus::wsTabConvert(spaceTab whichWay) |
|
|
|
|
{ |
|
|
|
|
// block selection is not supported
|
|
|
|
|
if ((_pEditView->execute(SCI_GETSELECTIONMODE) == SC_SEL_RECTANGLE) || (_pEditView->execute(SCI_GETSELECTIONMODE) == SC_SEL_THIN)) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
intptr_t tabWidth = _pEditView->execute(SCI_GETTABWIDTH); |
|
|
|
|
intptr_t currentPos = _pEditView->execute(SCI_GETCURRENTPOS); |
|
|
|
|
intptr_t lastLine = _pEditView->lastZeroBasedLineNumber(); |
|
|
|
|
intptr_t docLength = _pEditView->execute(SCI_GETLENGTH) + 1; |
|
|
|
|
if (docLength < 2) |
|
|
|
|
return; |
|
|
|
|
intptr_t currentLine = _pEditView->execute(SCI_LINEFROMPOSITION, currentPos); |
|
|
|
|
intptr_t currentPosInLine = currentPos - _pEditView->execute(SCI_POSITIONFROMLINE, currentLine); |
|
|
|
|
|
|
|
|
|
intptr_t count = 0; |
|
|
|
|
intptr_t column = 0; |
|
|
|
|
intptr_t newCurrentPos = 0; |
|
|
|
|
intptr_t tabStop = tabWidth - 1; // remember, counting from zero !
|
|
|
|
|
bool onlyLeading = false; |
|
|
|
|
vector<int> bookmarks; |
|
|
|
|
vector<int> folding; |
|
|
|
|
intptr_t startLine = 0; |
|
|
|
|
intptr_t endLine = _pEditView->lastZeroBasedLineNumber(); |
|
|
|
|
intptr_t endLineCorrect = endLine; |
|
|
|
|
intptr_t dataLength = _pEditView->execute(SCI_GETLENGTH) + 1; |
|
|
|
|
intptr_t mainSelAnchor = _pEditView->execute(SCI_GETANCHOR); |
|
|
|
|
bool isEntireDoc = (mainSelAnchor == currentPos); |
|
|
|
|
|
|
|
|
|
for (int i=0; i<lastLine; ++i) |
|
|
|
|
// restore original selection if nothing has changed
|
|
|
|
|
auto restoreSelection = [this, mainSelAnchor, currentPos, isEntireDoc]() |
|
|
|
|
{ |
|
|
|
|
if (bookmarkPresent(i)) |
|
|
|
|
bookmarks.push_back(i); |
|
|
|
|
if (!isEntireDoc) |
|
|
|
|
{ |
|
|
|
|
_pEditView->execute(SCI_SETANCHOR, mainSelAnchor); |
|
|
|
|
_pEditView->execute(SCI_SETCURRENTPOS, currentPos); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
if ((_pEditView->execute(SCI_GETFOLDLEVEL, i) & SC_FOLDLEVELHEADERFLAG)) |
|
|
|
|
if (_pEditView->execute(SCI_GETFOLDEXPANDED, i) == 0) |
|
|
|
|
folding.push_back(i); |
|
|
|
|
// auto-expand of partially selected lines
|
|
|
|
|
if (!isEntireDoc) |
|
|
|
|
{ |
|
|
|
|
intptr_t startPos = _pEditView->execute(SCI_GETSELECTIONSTART); |
|
|
|
|
startLine = _pEditView->execute(SCI_LINEFROMPOSITION, startPos); |
|
|
|
|
intptr_t endPos = _pEditView->execute(SCI_GETSELECTIONEND); |
|
|
|
|
endLine = endLineCorrect = _pEditView->execute(SCI_LINEFROMPOSITION, endPos); |
|
|
|
|
|
|
|
|
|
if (startPos != _pEditView->execute(SCI_POSITIONFROMLINE, startLine)) |
|
|
|
|
startPos = _pEditView->execute(SCI_POSITIONFROMLINE, startLine); |
|
|
|
|
|
|
|
|
|
if (endPos == _pEditView->execute(SCI_POSITIONFROMLINE, endLine)) |
|
|
|
|
endLineCorrect = endLine - 1; |
|
|
|
|
else if (endPos < _pEditView->execute(SCI_GETLINEENDPOSITION, endLine)) |
|
|
|
|
endPos = _pEditView->execute(SCI_GETLINEENDPOSITION, endLine); |
|
|
|
|
|
|
|
|
|
dataLength = endPos - startPos + 1; |
|
|
|
|
_pEditView->execute(SCI_SETSEL, startPos, endPos); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char * source = new char[docLength]; |
|
|
|
|
if (source == NULL) |
|
|
|
|
if (dataLength < 2) |
|
|
|
|
{ |
|
|
|
|
restoreSelection(); |
|
|
|
|
return; |
|
|
|
|
_pEditView->execute(SCI_GETTEXT, docLength, reinterpret_cast<LPARAM>(source)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
intptr_t changeDataCount = 0; |
|
|
|
|
intptr_t newCurrentPos = 0; |
|
|
|
|
vector<intptr_t> folding; |
|
|
|
|
|
|
|
|
|
_pEditView->execute(SCI_BEGINUNDOACTION); |
|
|
|
|
|
|
|
|
|
for (intptr_t idx = startLine; idx < endLineCorrect + 1; ++idx) |
|
|
|
|
{ |
|
|
|
|
intptr_t startPos = _pEditView->execute(SCI_POSITIONFROMLINE, idx); |
|
|
|
|
intptr_t endPos = _pEditView->execute(SCI_GETLINEENDPOSITION, idx); |
|
|
|
|
dataLength = endPos - startPos + 1; |
|
|
|
|
|
|
|
|
|
char * source = new char[dataLength]; |
|
|
|
|
if (source == NULL) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
source[dataLength - 1] = '\0'; // make sure to have correct data termination
|
|
|
|
|
_pEditView->execute(SCI_SETTARGETRANGE, startPos, endPos); |
|
|
|
|
_pEditView->execute(SCI_GETTARGETTEXT, 0, reinterpret_cast<LPARAM>(source)); |
|
|
|
|
|
|
|
|
|
intptr_t count = 0; |
|
|
|
|
intptr_t column = 0; |
|
|
|
|
intptr_t tabStop = tabWidth - 1; // remember, counting from zero !
|
|
|
|
|
bool onlyLeading = false; |
|
|
|
|
|
|
|
|
|
if (whichWay == tab2Space) |
|
|
|
|
{ |
|
|
|
|
// count how many tabs are there
|
|
|
|
|
for (const char * ch=source; *ch; ++ch) |
|
|
|
|
for (const char * ch = source; *ch; ++ch) |
|
|
|
|
{ |
|
|
|
|
if (*ch == '\t') |
|
|
|
|
++count; |
|
|
|
@ -1324,18 +1370,19 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
|
|
|
|
|
if (count == 0) |
|
|
|
|
{ |
|
|
|
|
delete [] source; |
|
|
|
|
return; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// allocate tabwidth-1 chars extra per tab, just to be safe
|
|
|
|
|
size_t newlen = docLength + count * (tabWidth - 1) + 1; |
|
|
|
|
char * destination = new char[newlen]; |
|
|
|
|
size_t newLen = dataLength + count * (tabWidth - 1) + 1; |
|
|
|
|
char * destination = new char[newLen]; |
|
|
|
|
if (destination == NULL) |
|
|
|
|
{ |
|
|
|
|
delete [] source; |
|
|
|
|
return; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
char * dest = destination; |
|
|
|
|
intptr_t changeDataLineCount = 0; |
|
|
|
|
|
|
|
|
|
switch (whichWay) |
|
|
|
|
{ |
|
|
|
@ -1350,7 +1397,9 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
|
|
|
|
|
for (int j = 0; j < insertTabs; ++j) |
|
|
|
|
{ |
|
|
|
|
*dest++ = ' '; |
|
|
|
|
if (i <= currentPos) |
|
|
|
|
changeDataCount++; |
|
|
|
|
changeDataLineCount++; |
|
|
|
|
if (idx == currentLine && i < currentPosInLine) |
|
|
|
|
++newCurrentPos; |
|
|
|
|
} |
|
|
|
|
column += insertTabs; |
|
|
|
@ -1358,7 +1407,7 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
|
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
*dest++ = source[i]; |
|
|
|
|
if (i <= currentPos) |
|
|
|
|
if (idx == currentLine && i < currentPosInLine) |
|
|
|
|
++newCurrentPos; |
|
|
|
|
if ((source[i] == '\n') || (source[i] == '\r')) |
|
|
|
|
column = 0; |
|
|
|
@ -1378,7 +1427,7 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
|
|
|
|
|
bool nextChar = false; |
|
|
|
|
int counter = 0; |
|
|
|
|
bool nonSpaceFound = false; |
|
|
|
|
for (int i=0; source[i] != '\0'; ++i) |
|
|
|
|
for (int i = 0; source[i] != '\0'; ++i) |
|
|
|
|
{ |
|
|
|
|
if (nonSpaceFound == false) |
|
|
|
|
{ |
|
|
|
@ -1390,21 +1439,25 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
|
|
|
|
|
if (counter >= 1) // counter is counted from 0, so counter >= max-1
|
|
|
|
|
{ |
|
|
|
|
*dest++ = '\t'; |
|
|
|
|
changeDataCount++; |
|
|
|
|
changeDataLineCount++; |
|
|
|
|
i += counter; |
|
|
|
|
column += counter + 1; |
|
|
|
|
counter = 0; |
|
|
|
|
nextChar = true; |
|
|
|
|
if (i <= currentPos) |
|
|
|
|
if (idx == currentLine && i <= currentPosInLine) |
|
|
|
|
++newCurrentPos; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
else if (source[i+1] == ' ' || source[i+1] == '\t') // if followed by space or TAB, convert even a single space to TAB
|
|
|
|
|
else if (source[i + 1] == ' ' || source[i + 1] == '\t') // if followed by space or TAB, convert even a single space to TAB
|
|
|
|
|
{ |
|
|
|
|
*dest++ = '\t'; |
|
|
|
|
changeDataCount++; |
|
|
|
|
changeDataLineCount++; |
|
|
|
|
i++; |
|
|
|
|
column += 1; |
|
|
|
|
counter = 0; |
|
|
|
|
if (i <= currentPos) |
|
|
|
|
if (idx == currentLine && i <= currentPosInLine) |
|
|
|
|
++newCurrentPos; |
|
|
|
|
} |
|
|
|
|
else // single space, don't convert it to TAB
|
|
|
|
@ -1413,7 +1466,7 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
|
|
|
|
|
column += 1; |
|
|
|
|
counter = 0; |
|
|
|
|
nextChar = true; |
|
|
|
|
if (i <= currentPos) |
|
|
|
|
if (idx == currentLine && i <= currentPosInLine) |
|
|
|
|
++newCurrentPos; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -1431,11 +1484,13 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
|
|
|
|
|
if (source[i] == ' ' && source[i + counter] == '\t') // spaces "absorbed" by a TAB on the right
|
|
|
|
|
{ |
|
|
|
|
*dest++ = '\t'; |
|
|
|
|
changeDataCount++; |
|
|
|
|
changeDataLineCount++; |
|
|
|
|
i += counter; |
|
|
|
|
column = tabStop + 1; |
|
|
|
|
tabStop += tabWidth; |
|
|
|
|
counter = 0; |
|
|
|
|
if (i <= currentPos) |
|
|
|
|
if (idx == currentLine && i <= currentPosInLine) |
|
|
|
|
++newCurrentPos; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
@ -1471,7 +1526,7 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (i <= currentPos) |
|
|
|
|
if (idx == currentLine && i < currentPosInLine) |
|
|
|
|
++newCurrentPos; |
|
|
|
|
} |
|
|
|
|
*dest = '\0'; |
|
|
|
@ -1479,21 +1534,34 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_pEditView->execute(SCI_BEGINUNDOACTION); |
|
|
|
|
_pEditView->execute(SCI_SETTEXT, 0, reinterpret_cast<LPARAM>(destination)); |
|
|
|
|
_pEditView->execute(SCI_GOTOPOS, newCurrentPos); |
|
|
|
|
|
|
|
|
|
for (size_t i=0; i<bookmarks.size(); ++i) |
|
|
|
|
_pEditView->execute(SCI_MARKERADD, bookmarks[i], MARK_BOOKMARK); |
|
|
|
|
if ((_pEditView->execute(SCI_GETFOLDLEVEL, idx) & SC_FOLDLEVELHEADERFLAG)) |
|
|
|
|
if (_pEditView->execute(SCI_GETFOLDEXPANDED, idx) == 0) |
|
|
|
|
folding.push_back(idx); |
|
|
|
|
|
|
|
|
|
for (size_t i=0; i<folding.size(); ++i) |
|
|
|
|
_pEditView->fold(folding[i], false); |
|
|
|
|
|
|
|
|
|
_pEditView->execute(SCI_ENDUNDOACTION); |
|
|
|
|
if (changeDataLineCount) |
|
|
|
|
_pEditView->execute(SCI_REPLACETARGET, static_cast<WPARAM>(-1), reinterpret_cast<LPARAM>(destination)); |
|
|
|
|
|
|
|
|
|
// clean up
|
|
|
|
|
delete [] source; |
|
|
|
|
delete [] destination; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_pEditView->execute(SCI_ENDUNDOACTION); |
|
|
|
|
|
|
|
|
|
if (changeDataCount) |
|
|
|
|
{ |
|
|
|
|
if (!isEntireDoc) |
|
|
|
|
_pEditView->execute(SCI_SETSEL, _pEditView->execute(SCI_POSITIONFROMLINE, startLine), endLineCorrect != endLine ? _pEditView->execute(SCI_POSITIONFROMLINE, endLine) : _pEditView->execute(SCI_GETLINEENDPOSITION, endLine)); |
|
|
|
|
else |
|
|
|
|
_pEditView->execute(SCI_GOTOPOS, _pEditView->execute(SCI_POSITIONFROMLINE, currentLine) + newCurrentPos); |
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < folding.size(); ++i) |
|
|
|
|
_pEditView->fold(folding[i], false); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
restoreSelection(); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Notepad_plus::doTrim(trimOp whichPart) |
|
|
|
|