[ENHANCEMENT] (Author: Ivan Radic,aka. Loreia L.) Enhance TAB/Space conversion: support UTF8 and to preserve formatting.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1060 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2013-06-18 19:44:32 +00:00
parent d39c743ff4
commit 197a28d1bd

View File

@ -1043,18 +1043,35 @@ bool Notepad_plus::matchInList(const TCHAR *fileName, const vector<generic_strin
return false;
}
void Notepad_plus::wsTabConvert(spaceTab whichWay)
{
int tabWidth = _pEditView->execute(SCI_GETTABWIDTH);
int currentPos = _pEditView->execute(SCI_GETCURRENTPOS);
int lastLine = _pEditView->lastZeroBasedLineNumber();
int docLength = int(_pEditView->execute(SCI_GETLENGTH)) + 1;
if (docLength < 2)
return;
int count = 0;
int column = 0;
int counter = 0;
int newCurrentPos = 0;
int tabStop = tabWidth - 1; // remember, counting from zero !
bool onlyLeading = false;
bool nonSpaceFound = false;
vector<int> bookmarks;
vector<int> folding;
for (int i=0; i<lastLine; ++i)
{
if (bookmarkPresent(i))
bookmarks.push_back(i);
if ((_pEditView->execute(SCI_GETFOLDLEVEL, i) & SC_FOLDLEVELHEADERFLAG))
if (_pEditView->execute(SCI_GETFOLDEXPANDED, i) == 0)
folding.push_back(i);
}
char * source = new char[docLength];
if (source == NULL)
@ -1089,24 +1106,28 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
{
case tab2Space:
{
// rip through each line in the file
for (const char * ch = source; *ch; ++ch)
// rip through each line of the file
for (int i = 0; source[i] != '\0'; ++i)
{
if (*ch == '\t')
if (source[i] == '\t')
{
size_t insertTabs = tabWidth - (column % tabWidth);
for (size_t i = 0; i<insertTabs; ++i)
for (size_t j = 0; j<insertTabs; ++j)
{
*dest++ = ' ';
if (i <= currentPos)
++newCurrentPos;
}
column += insertTabs;
}
else
{
*dest++ = *ch;
if ((*ch == '\n') || (*ch == '\r'))
*dest++ = source[i];
if (i <= currentPos)
++newCurrentPos;
if ((source[i] == '\n') || (source[i] == '\r'))
column = 0;
else
else if ((source[i] & 0xC0) != 0x80) // UTF_8 support: count only bytes that don't start with 10......
++column;
}
}
@ -1120,11 +1141,11 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
case space2TabAll:
{
bool nextChar = false;
for (const char * ch=source; *ch; ++ch)
for (int i=0; source[i] != '\0'; ++i)
{
if (nonSpaceFound == false)
{
while (*(ch + counter) == ' ')
while (source[i + counter] == ' ')
{
if ((column + counter) == tabStop)
{
@ -1132,25 +1153,31 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
if (counter >= 1) // counter is counted from 0, so counter >= max-1
{
*dest++ = '\t';
ch += counter;
i += counter;
column += counter + 1;
counter = 0;
nextChar = true;
if (i <= currentPos)
++newCurrentPos;
break;
}
else if (*(ch+1) == ' ' || *(ch+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';
ch++;
i++;
column += 1;
counter = 0;
if (i <= currentPos)
++newCurrentPos;
}
else // single space, don't convert it to TAB
{
*dest++ = *ch;
*dest++ = source[i];
column += 1;
counter = 0;
nextChar = true;
if (i <= currentPos)
++newCurrentPos;
break;
}
}
@ -1164,13 +1191,15 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
continue;
}
if (*ch == ' ' && *(ch + counter) == '\t') // spaces "absorbed" by a TAB on the right
if (source[i] == ' ' && source[i + counter] == '\t') // spaces "absorbed" by a TAB on the right
{
*dest++ = '\t';
ch += counter;
i += counter;
column = tabStop + 1;
tabStop += tabWidth;
counter = 0;
if (i <= currentPos)
++newCurrentPos;
continue;
}
}
@ -1178,30 +1207,36 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
if (onlyLeading == true && nonSpaceFound == false)
nonSpaceFound = true;
if (*ch == '\n' || *ch == '\r')
if (source[i] == '\n' || source[i] == '\r')
{
*dest++ = *ch;
*dest++ = source[i];
column = 0;
tabStop = tabWidth - 1;
nonSpaceFound = false;
}
else if (*ch == '\t')
else if (source[i] == '\t')
{
*dest++ = *ch;
*dest++ = source[i];
column = tabStop + 1;
tabStop += tabWidth;
counter = 0;
}
else
{
*dest++ = *ch;
++column;
*dest++ = source[i];
counter = 0;
if ((source[i] & 0xC0) != 0x80) // UTF_8 support: count only bytes that don't start with 10......
{
++column;
if (column > 0 && column % tabWidth == 0)
tabStop += tabWidth;
}
}
if (i <= currentPos)
++newCurrentPos;
}
*dest = '\0';
break;
}
@ -1209,6 +1244,14 @@ void Notepad_plus::wsTabConvert(spaceTab whichWay)
_pEditView->execute(SCI_BEGINUNDOACTION);
_pEditView->execute(SCI_SETTEXT, 0, (LPARAM)destination);
_pEditView->execute(SCI_GOTOPOS, newCurrentPos);
for (size_t i=0; i<bookmarks.size(); ++i)
_pEditView->execute(SCI_MARKERADD, bookmarks[i], MARK_BOOKMARK);
for (size_t i=0; i<folding.size(); ++i)
_pEditView->fold(folding[i], false);
_pEditView->execute(SCI_ENDUNDOACTION);
// clean up