diff --git a/src/Edit.c b/src/Edit.c index 2a05b4667..2e99d6bd6 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -2966,9 +2966,10 @@ void EditToggleLineComments(HWND hwnd, LPCWSTR pwszComment, BOOL bInsertAtStart) for (DocLn iLine = iLineStart; iLine <= iLineEnd; iLine++) { const DocPos iIndentPos = SciCall_GetLineIndentPosition(iLine); + if (iIndentPos == SciCall_GetLineEndPosition(iLine)) { - SciCall_InsertText(SciCall_FindColumn(iLine, iIndentPos), mszComment); - iSelEndOffset += cchComment; + // don't set comment char on "empty" (white-space only) lines + //~iAction = 1; continue; } @@ -3319,7 +3320,7 @@ void EditStripLastCharacter(HWND hwnd, BOOL bIgnoreSelection, BOOL bTrailingBlan DocPos i = end; while (--i >= 0) { const char ch = g_pTempLineBuffer[i]; - if ((ch == '\t') || (ch == ' ')) { + if (IsWhiteSpace(ch)) { g_pTempLineBuffer[i] = '\0'; } else @@ -3329,9 +3330,8 @@ void EditStripLastCharacter(HWND hwnd, BOOL bIgnoreSelection, BOOL bTrailingBlan g_pTempLineBuffer[++i] = g_pTempLineBuffer[end++]; // add "\r\n" if anny } diff = len - (++i); - len = i; SciCall_SetTargetRange(selTargetStart, selTargetEnd); - SciCall_ReplaceTarget(len, g_pTempLineBuffer); + SciCall_ReplaceTarget(-1, g_pTempLineBuffer); } } else { @@ -3400,7 +3400,7 @@ void EditStripLastCharacter(HWND hwnd, BOOL bIgnoreSelection, BOOL bTrailingBlan char ch = '\0'; do { ch = SciCall_GetCharAt(--i); - } while ((i >= iStartPos) && ((ch == ' ') || (ch == '\t'))); + } while ((i >= iStartPos) && IsWhiteSpace(ch)); if ((++i) < iEndPos) { SciCall_SetTargetRange(i, iEndPos); SciCall_ReplaceTarget(0, ""); @@ -3426,105 +3426,172 @@ void EditStripLastCharacter(HWND hwnd, BOOL bIgnoreSelection, BOOL bTrailingBlan // void EditCompressSpaces(HWND hwnd) { - if (SciCall_IsSelectionRectangle()) { - MsgBox(MBWARN, IDS_SELRECT); - return; - } - - const DocPos iCurPos = SciCall_GetCurrentPos(); - const DocPos iAnchorPos = SciCall_GetAnchor(); - const DocPos iSelStartPos = SciCall_GetSelectionStart(); - const DocPos iSelEndPos = SciCall_GetSelectionEnd(); - const DocPos iSelLength = (iSelEndPos - iSelStartPos); - - const DocLn iLineStart = SciCall_LineFromPosition(iSelStartPos); - const DocLn iLineEnd = SciCall_LineFromPosition(iSelEndPos); - const DocPos iTxtLength = SciCall_GetTextLength(); const BOOL bIsSelEmpty = SciCall_IsSelectionEmpty(); - const char* pszIn = NULL; - char* pszOut = NULL; - BOOL bIsLineStart = TRUE; - BOOL bIsLineEnd = TRUE; + if (SciCall_IsSelectionRectangle()) { + if (bIsSelEmpty) { + return; + } - BOOL bModified = FALSE; - - DocPos cch = 0; - if (bIsSelEmpty) { - pszIn = (const char*)SciCall_GetCharacterPointer(); - cch = iTxtLength; - pszOut = LocalAlloc(GPTR, cch+1); - } - else { - pszIn = (const char*)SciCall_GetRangePointer(iSelStartPos, iSelLength); - cch = SciCall_GetSelText(NULL) - 1; - pszOut = LocalAlloc(LPTR,cch+1); - bIsLineStart = (iSelStartPos == SciCall_PositionFromLine(iLineStart)); - bIsLineEnd = (iSelEndPos == SciCall_GetLineEndPosition(iLineEnd)); - } - - if (pszIn && pszOut) { - char* co = (char*)pszOut; - DocPos remWSuntilCaretPos = 0; - for (int i = 0; i < cch; ++i) { - if (pszIn[i] == ' ' || pszIn[i] == '\t') { - if (pszIn[i] == '\t') { bModified = TRUE; } - while (pszIn[i+1] == ' ' || pszIn[i+1] == '\t') { - if (bIsSelEmpty && (i < iSelStartPos)) { ++remWSuntilCaretPos; } - ++i; - bModified = TRUE; + const DocPosU selCount = (DocPosU)SendMessage(hwnd, SCI_GETSELECTIONS, 0, 0); + for (DocPosU s = 0; s < selCount; ++s) + { + const DocPos selCaretPos = SciCall_GetSelectionNCaret(s); + const DocPos selAnchorPos = SciCall_GetSelectionNAnchor(s); + const DocPos vSpcCaretPos = SciCall_GetSelectionNCaretVirtualSpace(s); + const DocPos vSpcAnchorPos = SciCall_GetSelectionNAnchorVirtualSpace(s); + + const DocPos selTargetStart = (selAnchorPos < selCaretPos) ? selAnchorPos : selCaretPos; + const DocPos selTargetEnd = (selAnchorPos < selCaretPos) ? selCaretPos : selAnchorPos; + const DocPos vSpcLength = (selAnchorPos < selCaretPos) ? (vSpcCaretPos - vSpcAnchorPos) : (vSpcAnchorPos - vSpcCaretPos); + + DocPos diff = 0; + DocPos len = 0; + + len = (selTargetEnd - selTargetStart); + if ((len >= 0) && (len < TEMPLINE_BUFFER)) + { + char* pText = SciCall_GetRangePointer(selTargetStart, len + 1); + const char* pEnd = (pText + len); + DocPos i = 0; + while (pText < pEnd) { + const char ch = *pText++; + if (IsWhiteSpace(ch)) { + g_pTempLineBuffer[i++] = ' '; + while (IsWhiteSpace(*pText)) { ++pText; } + } + else { g_pTempLineBuffer[i++] = ch; } } - if (!bIsLineStart && ((pszIn[i + 1] != '\n') && (pszIn[i + 1] != '\r'))) { - *co++ = ' '; + g_pTempLineBuffer[i] = '\0'; + diff = len - i; + SciCall_SetTargetRange(selTargetStart, selTargetEnd); + SciCall_ReplaceTarget(-1, g_pTempLineBuffer); + } + + if (selAnchorPos <= selCaretPos) { + SciCall_SetSelectionNAnchor(s, selAnchorPos); + if ((len > 0) && (vSpcLength > 0)) { + SciCall_SetSelectionNCaret(s, selCaretPos - diff); + SciCall_SetSelectionNAnchorVirtualSpace(s, vSpcAnchorPos - diff); + SciCall_SetSelectionNCaretVirtualSpace(s, vSpcCaretPos + diff); } else { - bModified = TRUE; + SciCall_SetSelectionNCaret(s, selCaretPos); + SciCall_SetSelectionNAnchorVirtualSpace(s, vSpcAnchorPos); + SciCall_SetSelectionNCaretVirtualSpace(s, vSpcCaretPos); } } else { - bIsLineStart = (pszIn[i] == '\n' || pszIn[i] == '\r') ? TRUE : FALSE; - *co++ = pszIn[i]; - } - } - - if (bIsLineEnd && (co > pszOut) && (*(co-1) == ' ')) { - if (bIsSelEmpty && ((cch-1) < iSelStartPos)) { --remWSuntilCaretPos; } - *--co = '\0'; - bModified = TRUE; - } - - if (bModified) { - - EditEnterTargetTransaction(); - - if (!SciCall_IsSelectionEmpty()) { - SendMessage(hwnd, SCI_TARGETFROMSELECTION, 0, 0); - } - else { - SendMessage(hwnd, SCI_SETTARGETRANGE, 0, iTxtLength); - } - SendMessage(hwnd, SCI_REPLACETARGET, (WPARAM)-1, (LPARAM)pszOut); - - EditLeaveTargetTransaction(); - - const DocPos iNewLen = StringCchLenA(pszOut, LocalSize(pszOut)); - - if (iCurPos < iAnchorPos) { - EditSelectEx(hwnd, iCurPos + iNewLen, iCurPos); - } - else if (iCurPos > iAnchorPos) { - EditSelectEx(hwnd, iAnchorPos, iAnchorPos + iNewLen); - } - else { // empty selection - DocPos iNewPos = iCurPos; - if (iCurPos > 0) { - iNewPos = SciCall_PositionBefore(SciCall_PositionAfter(iCurPos - remWSuntilCaretPos)); + SciCall_SetSelectionNCaret(s, selCaretPos); + if ((len > 0) && (vSpcLength > 0)) { + SciCall_SetSelectionNAnchor(s, selAnchorPos - diff); + SciCall_SetSelectionNCaretVirtualSpace(s, vSpcCaretPos - diff); + SciCall_SetSelectionNAnchorVirtualSpace(s, vSpcAnchorPos + diff); + } + else { + SciCall_SetSelectionNAnchor(s, selAnchorPos); + SciCall_SetSelectionNCaretVirtualSpace(s, vSpcCaretPos); + SciCall_SetSelectionNAnchorVirtualSpace(s, vSpcAnchorPos); } - EditSelectEx(hwnd, iNewPos, iNewPos); } - } + } // for() + + } + else // SC_SEL_LINES | SC_SEL_STREAM + { + const DocPos iCurPos = SciCall_GetCurrentPos(); + const DocPos iAnchorPos = SciCall_GetAnchor(); + const DocPos iSelStartPos = SciCall_GetSelectionStart(); + const DocPos iSelEndPos = SciCall_GetSelectionEnd(); + const DocPos iSelLength = (iSelEndPos - iSelStartPos); + + const DocLn iLineStart = SciCall_LineFromPosition(iSelStartPos); + const DocLn iLineEnd = SciCall_LineFromPosition(iSelEndPos); + const DocPos iTxtLength = SciCall_GetTextLength(); + + BOOL bIsLineStart = TRUE; + BOOL bIsLineEnd = TRUE; + BOOL bModified = FALSE; + + const char* pszIn = NULL; + char* pszOut = NULL; + DocPos cch = 0; + if (bIsSelEmpty) { + pszIn = (const char*)SciCall_GetCharacterPointer(); + cch = iTxtLength; + pszOut = AllocMem(cch + 1, HEAP_ZERO_MEMORY); + } + else { + pszIn = (const char*)SciCall_GetRangePointer(iSelStartPos, iSelLength); + cch = SciCall_GetSelText(NULL) - 1; + pszOut = AllocMem(cch + 1, HEAP_ZERO_MEMORY); + bIsLineStart = (iSelStartPos == SciCall_PositionFromLine(iLineStart)); + bIsLineEnd = (iSelEndPos == SciCall_GetLineEndPosition(iLineEnd)); + } + + if (pszIn && pszOut) { + char* co = (char*)pszOut; + DocPos remWSuntilCaretPos = 0; + for (int i = 0; i < cch; ++i) { + if (IsWhiteSpace(pszIn[i])) { + if (pszIn[i] == '\t') { bModified = TRUE; } + while (IsWhiteSpace(pszIn[i + 1])) { + if (bIsSelEmpty && (i < iSelStartPos)) { ++remWSuntilCaretPos; } + ++i; + bModified = TRUE; + } + if (!bIsLineStart && ((pszIn[i + 1] != '\n') && (pszIn[i + 1] != '\r'))) { + *co++ = ' '; + } + else { + bModified = TRUE; + } + } + else { + bIsLineStart = (pszIn[i] == '\n' || pszIn[i] == '\r') ? TRUE : FALSE; + *co++ = pszIn[i]; + } + } + + if (bIsLineEnd && (co > pszOut) && (*(co - 1) == ' ')) { + if (bIsSelEmpty && ((cch - 1) < iSelStartPos)) { --remWSuntilCaretPos; } + *--co = '\0'; + bModified = TRUE; + } + + if (bModified) { + + EditEnterTargetTransaction(); + + if (!SciCall_IsSelectionEmpty()) { + SciCall_TargetFromSelection(); + } + else { + SciCall_SetTargetRange(0, iTxtLength); + } + SciCall_ReplaceTarget(-1, pszOut); + + EditLeaveTargetTransaction(); + + const DocPos iNewLen = StringCchLenA(pszOut, LocalSize(pszOut)); + + if (iCurPos < iAnchorPos) { + EditSelectEx(hwnd, iCurPos + iNewLen, iCurPos); + } + else if (iCurPos > iAnchorPos) { + EditSelectEx(hwnd, iAnchorPos, iAnchorPos + iNewLen); + } + else { // empty selection + DocPos iNewPos = iCurPos; + if (iCurPos > 0) { + iNewPos = SciCall_PositionBefore(SciCall_PositionAfter(iCurPos - remWSuntilCaretPos)); + } + EditSelectEx(hwnd, iNewPos, iNewPos); + } + } + } + if (pszOut) { FreeMem(pszOut); } } - if (pszOut) { LocalFree(pszOut); } } diff --git a/src/Helpers.c b/src/Helpers.c index 91857c90f..cb5cbb89c 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -2347,29 +2347,6 @@ HWND CreateThemedDialogParam( * / -/** - * Is the character an octal digit? - */ -static BOOL IsOctalDigit(char ch) { - return ch >= '0' && ch <= '7'; -} - -/** - * If the character is an hexa digit, get its value. - */ -static int GetHexDigit(char ch) { - if (ch >= '0' && ch <= '9') { - return ch - '0'; - } - if (ch >= 'A' && ch <= 'F') { - return ch - 'A' + 10; - } - if (ch >= 'a' && ch <= 'f') { - return ch - 'a' + 10; - } - return -1; -} - /** * Convert C style \a, \b, \f, \n, \r, \t, \v, \xhh and \uhhhh into their indicated characters. */ diff --git a/src/Helpers.h b/src/Helpers.h index 6a57aead5..b2cff8e00 100644 --- a/src/Helpers.h +++ b/src/Helpers.h @@ -365,6 +365,36 @@ __forceinline int _StringCchCmpINW(PCNZWCH s1,int l1,PCNZWCH s2,int l2) { #define StringCchCompareIX(s1,s2) StringCchCompareIXA((s1),(s2)) #endif + + +/** +* Is the character a white space char? +*/ +__forceinline bool IsWhiteSpace(char ch) { + return ((ch == ' ') || (ch == '\t')); +} + + +/** +* Is the character an octal digit? +*/ +__forceinline bool IsOctalDigit(char ch) { + return ch >= '0' && ch <= '7'; +} + + +/** +* If the character is an hexa digit, get its value. +*/ +__forceinline int GetHexDigit(char ch) { + if (ch >= '0' && ch <= '9') { return ch - '0'; } + if (ch >= 'A' && ch <= 'F') { return ch - 'A' + 10; } + if (ch >= 'a' && ch <= 'f') { return ch - 'a' + 10; } + return -1; +} + + + void UrlUnescapeEx(LPWSTR, LPWSTR, DWORD*); // -------------------------------------------------------------------------------------------------------------------------------- diff --git a/src/SciCall.h b/src/SciCall.h index e64b4d158..c853463f4 100644 --- a/src/SciCall.h +++ b/src/SciCall.h @@ -219,7 +219,7 @@ DeclareSciCallR1(DocLineFromVisible, DOCLINEFROMVISIBLE, DocLn, DocLn, line) DeclareSciCallR1(GetLineIndentPosition, GETLINEINDENTPOSITION, DocPos, DocLn, line) -DeclareSciCallR2(GetRangePointer, GETRANGEPOINTER, const char*, DocPos, start, DocPos, length) +DeclareSciCallR2(GetRangePointer, GETRANGEPOINTER, char* const, DocPos, start, DocPos, length) DeclareSciCallR0(GetCharacterPointer, GETCHARACTERPOINTER, const char*)