[NEW_FEATURE] (Author: Loreia) Enhance TAB2SPACE and SPACE2TAB features.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@944 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2012-08-25 19:23:16 +00:00
parent e08e566e19
commit e86940390f
6 changed files with 483 additions and 331 deletions

View File

@ -1033,42 +1033,177 @@ bool Notepad_plus::matchInList(const TCHAR *fileName, const vector<generic_strin
return false;
}
void Notepad_plus::wsTabConvert(bool tab2ws)
void Notepad_plus::wsTabConvert(spaceTab whichWay)
{
generic_string tab = TEXT(" ");
generic_string blank2search = tab;
generic_string blank2replace = tab;
// Get tab size (ws length)
int tabWidth = _pEditView->execute(SCI_GETTABWIDTH);
generic_string ws(tabWidth, ' ');
int docLength = int(_pEditView->execute(SCI_GETLENGTH)) + 1;
if (docLength < 2)
return;
int count = 0;
int column = 0;
int counter = 0;
int tabStop = tabWidth - 1; // remember, counting from zero !
bool onlyLeading = false;
bool nonSpaceFound = false;
// tab2ws or ws2tab ?
if (tab2ws)
char * source = new char[docLength];
if (source == NULL)
return;
_pEditView->execute(SCI_GETTEXT, docLength, (LPARAM)source);
if (whichWay == tab2Space)
{
blank2replace = ws;
// count how many tabs are there
for (const char * ch=source; *ch; ++ch)
{
if (*ch == '\t')
++count;
}
if (count == 0)
{
delete [] source;
return;
}
}
// allocate tabwidth-1 chars extra per tab, just to be safe
size_t newlen = docLength + count * (tabWidth - 1) + 1;
char * destination = new char[newlen];
if (destination == NULL)
{
delete [] source;
return;
}
char * dest = destination;
switch (whichWay)
{
case tab2Space:
{
// rip through each line in the file
for (const char * ch = source; *ch; ++ch)
{
if (*ch == '\t')
{
size_t insertTabs = tabWidth - (column % tabWidth);
for (size_t i = 0; i<insertTabs; ++i)
{
*dest++ = ' ';
}
column += insertTabs;
}
else
{
blank2search= ws;
*dest++ = *ch;
if ((*ch == '\n') || (*ch == '\r'))
column = 0;
else
++column;
}
FindOption env;
env._str2Search = blank2search;
env._str4Replace = blank2replace;
env._searchType = FindRegex;
// do the replacement
_pEditView->execute(SCI_BEGINUNDOACTION);
_findReplaceDlg.processAll(ProcessReplaceAll, &env, true);
// if white space to TAB, we replace the remain white spaces by TAB
if (!tab2ws)
}
*dest = '\0';
break;
}
case space2TabLeading:
{
env._str2Search = TEXT(" +");
_findReplaceDlg.processAll(ProcessReplaceAll, &env, true);
onlyLeading = true;
}
case space2TabAll:
{
bool nextChar = false;
for (const char * ch=source; *ch; ++ch)
{
if (nonSpaceFound == false)
{
while (*(ch + counter) == ' ')
{
if ((column + counter) == tabStop)
{
tabStop += tabWidth;
if (counter >= 1) // counter is counted from 0, so counter >= max -1
{
*dest++ = '\t';
ch += counter;
column += counter + 1;
counter = 0;
nextChar = true;
break;
}
else if (*(ch+1) == ' ' || *(ch+1) == '\t') // if followed by space or TAB, convert even a single space to TAB
{
*dest++ = '\t';
ch++;
column += 1;
counter = 0;
}
else // single space, don't convert it to TAB
{
*dest++ = *ch;
column += 1;
counter = 0;
nextChar = true;
break;
}
}
else
++counter;
}
if (nextChar == true)
{
nextChar = false;
continue;
}
if (*ch == ' ' && *(ch + counter) == '\t') // spaces "absorbed" by a TAB on the right
{
*dest++ = '\t';
ch += counter;
column = tabStop + 1;
tabStop += tabWidth;
counter = 0;
continue;
}
}
if (onlyLeading == true && nonSpaceFound == false)
nonSpaceFound = true;
if (*ch == '\n' || *ch == '\r')
{
*dest++ = *ch;
column = 0;
tabStop = tabWidth - 1;
nonSpaceFound = false;
}
else if (*ch == '\t')
{
*dest++ = *ch;
column = tabStop + 1;
tabStop += tabWidth;
counter = 0;
}
else
{
*dest++ = *ch;
++column;
counter = 0;
if (column > 0 && column % tabWidth == 0)
tabStop += tabWidth;
}
}
*dest = '\0';
break;
}
}
_pEditView->execute(SCI_BEGINUNDOACTION);
_pEditView->execute(SCI_SETTEXT, 0, (LPARAM)destination);
_pEditView->execute(SCI_ENDUNDOACTION);
// clean up
delete [] source;
delete [] destination;
}
void Notepad_plus::doTrim(trimOp whichPart)
@ -1484,6 +1619,7 @@ void Notepad_plus::checkClipboard()
bool canPaste = (_pEditView->execute(SCI_CANPASTE) != 0);
enableCommand(IDM_EDIT_CUT, hasSelection, MENU | TOOLBAR);
enableCommand(IDM_EDIT_COPY, hasSelection, MENU | TOOLBAR);
enableCommand(IDM_EDIT_PASTE, canPaste, MENU | TOOLBAR);
enableCommand(IDM_EDIT_DELETE, hasSelection, MENU | TOOLBAR);
enableCommand(IDM_EDIT_UPPERCASE, hasSelection, MENU);
@ -4488,6 +4624,7 @@ int Notepad_plus::getLangFromMenuName(const TCHAR * langName)
generic_string Notepad_plus::getLangFromMenu(const Buffer * buf)
{
int id;
generic_string userLangName;
const int nbChar = 32;

View File

@ -151,6 +151,12 @@ enum trimOp {
lineEol = 2
};
enum spaceTab {
tab2Space = 0,
space2TabLeading = 1,
space2TabAll = 2
};
struct TaskListInfo;
struct VisibleGUIConf {
@ -599,7 +605,7 @@ private:
bool goToNextIndicator(int indicID2Search, bool isWrap = true) const;
int wordCount();
void wsTabConvert(bool whichWay);
void wsTabConvert(spaceTab whichWay);
void doTrim(trimOp whichPart);
void launchAnsiCharPanel();
void launchClipboardHistoryPanel();

View File

@ -280,7 +280,8 @@ BEGIN
MENUITEM "Remove Unnecessary Blank and EOL", IDM_EDIT_TRIMALL
MENUITEM SEPARATOR
MENUITEM "TAB to Space", IDM_EDIT_TAB2SW
MENUITEM "Space to TAB", IDM_EDIT_SW2TAB
MENUITEM "Space to TAB (All)", IDM_EDIT_SW2TAB_ALL
MENUITEM "Space to TAB (Leading)", IDM_EDIT_SW2TAB_LEADING
END
POPUP "Paste Special"
BEGIN

View File

@ -879,11 +879,15 @@ void Notepad_plus::command(int id)
break;
case IDM_EDIT_TAB2SW:
wsTabConvert(true);
wsTabConvert(tab2Space);
break;
case IDM_EDIT_SW2TAB:
wsTabConvert(false);
case IDM_EDIT_SW2TAB_LEADING:
wsTabConvert(space2TabLeading);
break;
case IDM_EDIT_SW2TAB_ALL:
wsTabConvert(space2TabAll);
break;
case IDM_EDIT_SETREADONLY:
@ -2376,7 +2380,8 @@ void Notepad_plus::command(int id)
case IDM_EDIT_EOL2WS:
case IDM_EDIT_TRIMALL:
case IDM_EDIT_TAB2SW:
case IDM_EDIT_SW2TAB:
case IDM_EDIT_SW2TAB_ALL:
case IDM_EDIT_SW2TAB_LEADING:
case IDM_EDIT_SETREADONLY :
case IDM_EDIT_FULLPATHTOCLIP :
case IDM_EDIT_FILENAMETOCLIP :

View File

@ -103,7 +103,8 @@ WinMenuKeyDefinition winKeyDefs[] = {
{VK_NULL, IDM_EDIT_EOL2WS, false, false, false, NULL},
{VK_NULL, IDM_EDIT_TRIMALL, false, false, false, NULL},
{VK_NULL, IDM_EDIT_TAB2SW, false, false, false, NULL},
{VK_NULL, IDM_EDIT_SW2TAB, false, false, false, NULL},
{VK_NULL, IDM_EDIT_SW2TAB_ALL, false, false, false, NULL},
{VK_NULL, IDM_EDIT_SW2TAB_LEADING, false, false, false, NULL},
{VK_C, IDM_EDIT_COLUMNMODE, false, true, false, NULL},
{VK_U, IDM_EDIT_UPPERCASE, true, false, true, NULL},

View File

@ -88,7 +88,9 @@
#define IDM_EDIT_EOL2WS (IDM_EDIT + 44)
#define IDM_EDIT_TRIMALL (IDM_EDIT + 45)
#define IDM_EDIT_TAB2SW (IDM_EDIT + 46)
#define IDM_EDIT_SW2TAB (IDM_EDIT + 47)
#define IDM_EDIT_SW2TAB_LEADING (IDM_EDIT + 53)
#define IDM_EDIT_SW2TAB_ALL (IDM_EDIT + 54)
//#define IDM_EDIT_SW2TAB (IDM_EDIT + 47)
// Menu macro
#define IDM_MACRO_SAVECURRENTMACRO (IDM_EDIT + 25)