Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

kliu: code folding patch

http://code.kliu.org/misc/notepad2/
np2-4.0.22-folding.patch

Signed-off-by: Dan Savilonis <djs@n-cube.org>
  • Loading branch information...
commit bab59182dc714150b5187559db8e494af1c08fc5 1 parent 1a3772c
@djs authored
View
BIN  res/Notepad2.ico
Binary file not shown
View
BIN  res/Toolbar.bmp
Binary file not shown
View
23 src/Edit.c
@@ -4057,24 +4057,9 @@ void EditJumpTo(HWND hwnd,int iNewLine,int iNewCol)
iNewPos = SendMessage(hwnd,SCI_POSITIONAFTER,(WPARAM)iNewPos,0);
}
- SendMessage(hwnd,SCI_SETXCARETPOLICY,CARET_SLOP|CARET_STRICT|CARET_EVEN,50);
- SendMessage(hwnd,SCI_SETYCARETPOLICY,CARET_SLOP|CARET_STRICT|CARET_EVEN,5);
-
iNewPos = min(iNewPos,iLineEndPos);
- SendMessage(hwnd,SCI_GOTOPOS,(WPARAM)iNewPos,0);
+ EditSelectEx(hwnd,-1,iNewPos); // SCI_GOTOPOS(pos) is equivalent to SCI_SETSEL(-1, pos)
SendMessage(hwnd,SCI_CHOOSECARETX,0,0);
-
- //iScrLines = SendMessage(hwnd,SCI_LINESONSCREEN,0,0);
- //iTopLine = SendMessage(hwnd,SCI_GETFIRSTVISIBLELINE,0,0);
- //if (iScrLines > 20) {
- // if (iNewLine - iTopLine < 5)
- // SendMessage(hwnd,SCI_LINESCROLL,0,(LPARAM)max(iNewLine-5,0)-iTopLine);
- // else if (iNewLine - (iTopLine + iScrLines) > -5)
- // SendMessage(hwnd,SCI_LINESCROLL,0,(LPARAM)max(iNewLine-iScrLines+5,0)-iTopLine);
- //}
-
- SendMessage(hwnd,SCI_SETXCARETPOLICY,CARET_SLOP|CARET_EVEN,50);
- SendMessage(hwnd,SCI_SETYCARETPOLICY,CARET_EVEN,0);
}
}
@@ -4092,6 +4077,12 @@ void EditSelectEx(HWND hwnd,int iAnchorPos,int iCurrentPos)
int iNewLine = SendMessage(hwnd,SCI_LINEFROMPOSITION,(WPARAM)iCurrentPos,0);
int iAnchorLine = SendMessage(hwnd,SCI_LINEFROMPOSITION,(WPARAM)iAnchorPos,0);
+ // Ensure that the first and last lines of a selection are always unfolded
+ // This needs to be done *before* the SCI_SETSEL message
+ SciCall_EnsureVisible(iAnchorLine);
+ if (iAnchorLine != iNewLine)
+ SciCall_EnsureVisible(iNewLine);
+
SendMessage(hwnd,SCI_SETXCARETPOLICY,CARET_SLOP|CARET_STRICT|CARET_EVEN,50);
SendMessage(hwnd,SCI_SETYCARETPOLICY,CARET_SLOP|CARET_STRICT|CARET_EVEN,5);
SendMessage(hwnd,SCI_SETSEL,iAnchorPos,iCurrentPos);
View
250 src/Notepad2.c
@@ -53,8 +53,9 @@ HWND hwndMain;
HWND hwndNextCBChain = NULL;
HWND hDlgFindReplace = NULL;
-#define NUMTOOLBITMAPS 23
+#define NUMTOOLBITMAPS 24
#define NUMINITIALTOOLS 24
+#define MARGIN_FOLD_INDEX 2
TBBUTTON tbbMainWnd[] = { {0,IDT_FILE_NEW,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
{1,IDT_FILE_OPEN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
@@ -85,7 +86,8 @@ TBBUTTON tbbMainWnd[] = { {0,IDT_FILE_NEW,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
{19,IDT_EDIT_CLEAR,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
{20,IDT_FILE_PRINT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
{21,IDT_FILE_OPENFAV,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
- {22,IDT_FILE_ADDTOFAV,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0} };
+ {22,IDT_FILE_ADDTOFAV,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
+ {23,IDT_VIEW_TOGGLEFOLDS,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0} };
WCHAR szIniFile[MAX_PATH] = L"";
WCHAR szIniFile2[MAX_PATH] = L"";
@@ -127,6 +129,7 @@ int iLongLineMode;
int iWrapCol = 0;
BOOL bShowSelectionMargin;
BOOL bShowLineNumbers;
+BOOL bShowCodeFolding;
BOOL bViewWhiteSpace;
BOOL bViewEOLs;
int iDefaultEncoding;
@@ -291,6 +294,190 @@ int flagRelaunchElevated = 0;
int flagDisplayHelp = 0;
+//==============================================================================
+//
+// Folding Functions
+//
+//
+typedef enum {
+ EXPAND = 1,
+ SNIFF = 0,
+ FOLD = -1
+} FOLD_ACTION;
+
+#define FOLD_CHILDREN SCMOD_CTRL
+#define FOLD_SIBLINGS SCMOD_SHIFT
+
+BOOL __stdcall FoldToggleNode( int ln, FOLD_ACTION action )
+{
+ BOOL fExpanded = SciCall_GetFoldExpanded(ln);
+
+ if ((action == FOLD && fExpanded) || (action == EXPAND && !fExpanded))
+ {
+ SciCall_ToggleFold(ln);
+ return(TRUE);
+ }
+
+ return(FALSE);
+}
+
+void __stdcall FoldToggleAll( FOLD_ACTION action )
+{
+ BOOL fToggled = FALSE;
+ int lnTotal = SciCall_GetLineCount();
+ int ln;
+
+ for (ln = 0; ln < lnTotal; ++ln)
+ {
+ if (SciCall_GetFoldLevel(ln) & SC_FOLDLEVELHEADERFLAG)
+ {
+ if (action == SNIFF)
+ action = SciCall_GetFoldExpanded(ln) ? FOLD : EXPAND;
+
+ if (FoldToggleNode(ln, action))
+ fToggled = TRUE;
+ }
+ }
+
+ if (fToggled)
+ {
+ SciCall_SetXCaretPolicy(CARET_SLOP|CARET_STRICT|CARET_EVEN,50);
+ SciCall_SetYCaretPolicy(CARET_SLOP|CARET_STRICT|CARET_EVEN,5);
+ SciCall_ScrollCaret();
+ SciCall_SetXCaretPolicy(CARET_SLOP|CARET_EVEN,50);
+ SciCall_SetYCaretPolicy(CARET_EVEN,0);
+ }
+}
+
+void __stdcall FoldPerformAction( int ln, int mode, FOLD_ACTION action )
+{
+ if (action == SNIFF)
+ action = SciCall_GetFoldExpanded(ln) ? FOLD : EXPAND;
+
+ if (mode & (FOLD_CHILDREN | FOLD_SIBLINGS))
+ {
+ // ln/lvNode: line and level of the source of this fold action
+ int lnNode = ln;
+ int lvNode = SciCall_GetFoldLevel(lnNode) & SC_FOLDLEVELNUMBERMASK;
+ int lnTotal = SciCall_GetLineCount();
+
+ // lvStop: the level over which we should not cross
+ int lvStop = lvNode;
+
+ if (mode & FOLD_SIBLINGS)
+ {
+ ln = SciCall_GetFoldParent(lnNode) + 1; // -1 + 1 = 0 if no parent
+ --lvStop;
+ }
+
+ for ( ; ln < lnTotal; ++ln)
+ {
+ int lv = SciCall_GetFoldLevel(ln);
+ BOOL fHeader = lv & SC_FOLDLEVELHEADERFLAG;
+ lv &= SC_FOLDLEVELNUMBERMASK;
+
+ if (lv < lvStop || (lv == lvStop && fHeader && ln != lnNode))
+ return;
+ else if (fHeader && (lv == lvNode || (lv > lvNode && mode & FOLD_CHILDREN)))
+ FoldToggleNode(ln, action);
+ }
+ }
+ else
+ {
+ FoldToggleNode(ln, action);
+ }
+}
+
+void __stdcall FoldClick( int ln, int mode )
+{
+ static struct {
+ int ln;
+ int mode;
+ DWORD dwTickCount;
+ } prev;
+
+ BOOL fGotoFoldPoint = mode & FOLD_SIBLINGS;
+
+ if (!(SciCall_GetFoldLevel(ln) & SC_FOLDLEVELHEADERFLAG))
+ {
+ // Not a fold point: need to look for a double-click
+
+ if ( prev.ln == ln && prev.mode == mode &&
+ GetTickCount() - prev.dwTickCount <= GetDoubleClickTime() )
+ {
+ prev.ln = -1; // Prevent re-triggering on a triple-click
+
+ ln = SciCall_GetFoldParent(ln);
+
+ if (ln >= 0 && SciCall_GetFoldExpanded(ln))
+ fGotoFoldPoint = TRUE;
+ else
+ return;
+ }
+ else
+ {
+ // Save the info needed to match this click with the next click
+ prev.ln = ln;
+ prev.mode = mode;
+ prev.dwTickCount = GetTickCount();
+ return;
+ }
+ }
+
+ FoldPerformAction(ln, mode, SNIFF);
+
+ if (fGotoFoldPoint)
+ EditJumpTo(hwndEdit, ln + 1, 0);
+}
+
+void __stdcall FoldAltArrow( int key, int mode )
+{
+ // Because Alt-Shift is already in use (and because the sibling fold feature
+ // is not as useful from the keyboard), only the Ctrl modifier is supported
+
+ if (bShowCodeFolding && (mode & (SCMOD_ALT | SCMOD_SHIFT)) == SCMOD_ALT)
+ {
+ int ln = SciCall_LineFromPosition(SciCall_GetCurrentPos());
+
+ // Jump to the next visible fold point
+ if (key == SCK_DOWN && !(mode & SCMOD_CTRL))
+ {
+ int lnTotal = SciCall_GetLineCount();
+ for (ln = ln + 1; ln < lnTotal; ++ln)
+ {
+ if ( SciCall_GetFoldLevel(ln) & SC_FOLDLEVELHEADERFLAG &&
+ SciCall_GetLineVisible(ln) )
+ {
+ EditJumpTo(hwndEdit, ln + 1, 0);
+ return;
+ }
+ }
+ }
+
+ // Jump to the previous visible fold point
+ else if (key == SCK_UP && !(mode & SCMOD_CTRL))
+ {
+ for (ln = ln - 1; ln >= 0; --ln)
+ {
+ if ( SciCall_GetFoldLevel(ln) & SC_FOLDLEVELHEADERFLAG &&
+ SciCall_GetLineVisible(ln) )
+ {
+ EditJumpTo(hwndEdit, ln + 1, 0);
+ return;
+ }
+ }
+ }
+
+ // Perform a fold/unfold operation
+ else if (SciCall_GetFoldLevel(ln) & SC_FOLDLEVELHEADERFLAG)
+ {
+ if (key == SCK_LEFT ) FoldPerformAction(ln, mode, FOLD);
+ if (key == SCK_RIGHT) FoldPerformAction(ln, mode, EXPAND);
+ }
+ }
+}
+
+
//=============================================================================
//
@@ -1303,6 +1490,25 @@ LRESULT MsgCreate(HWND hwnd,WPARAM wParam,LPARAM lParam)
//SendMessage(hwndEdit,SCI_SETMARGINWIDTHN,0,
// (bShowLineNumbers)?SendMessage(hwndEdit,SCI_TEXTWIDTH,STYLE_LINENUMBER,(LPARAM)L"_999999_"):0);
+ // Code folding
+ SciCall_SetMarginType(MARGIN_FOLD_INDEX, SC_MARGIN_SYMBOL);
+ SciCall_SetMarginMask(MARGIN_FOLD_INDEX, SC_MASK_FOLDERS);
+ SciCall_SetMarginWidth(MARGIN_FOLD_INDEX, (bShowCodeFolding) ? 11 : 0);
+ SciCall_SetMarginSensitive(MARGIN_FOLD_INDEX, TRUE);
+ SciCall_SetProperty("fold", "1");
+ SciCall_SetProperty("fold.compact", "0");
+ SciCall_SetProperty("fold.comment", "1");
+ SciCall_SetProperty("fold.html", "1");
+ SciCall_SetProperty("fold.preprocessor", "1");
+ SciCall_MarkerDefine(SC_MARKNUM_FOLDEROPEN, SC_MARK_BOXMINUS);
+ SciCall_MarkerDefine(SC_MARKNUM_FOLDER, SC_MARK_BOXPLUS);
+ SciCall_MarkerDefine(SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE);
+ SciCall_MarkerDefine(SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNER);
+ SciCall_MarkerDefine(SC_MARKNUM_FOLDEREND, SC_MARK_BOXPLUSCONNECTED);
+ SciCall_MarkerDefine(SC_MARKNUM_FOLDEROPENMID, SC_MARK_BOXMINUSCONNECTED);
+ SciCall_MarkerDefine(SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNER);
+ SciCall_SetFoldFlags(16);
+
// Nonprinting characters
SendMessage(hwndEdit,SCI_SETVIEWWS,(bViewWhiteSpace)?SCWS_VISIBLEALWAYS:SCWS_INVISIBLE,0);
SendMessage(hwndEdit,SCI_SETVIEWEOL,bViewEOLs,0);
@@ -1845,6 +2051,8 @@ void MsgInitMenu(HWND hwnd,WPARAM wParam,LPARAM lParam)
CheckCmd(hmenu,IDM_VIEW_AUTOINDENTTEXT,bAutoIndent);
CheckCmd(hmenu,IDM_VIEW_LINENUMBERS,bShowLineNumbers);
CheckCmd(hmenu,IDM_VIEW_MARGIN,bShowSelectionMargin);
+ CheckCmd(hmenu,IDM_VIEW_FOLDING,bShowCodeFolding);
+ EnableCmd(hmenu,IDM_VIEW_TOGGLEFOLDS,bShowCodeFolding);
CheckCmd(hmenu,IDM_VIEW_SHOWWHITESPACE,bViewWhiteSpace);
CheckCmd(hmenu,IDM_VIEW_SHOWEOLS,bViewEOLs);
CheckCmd(hmenu,IDM_VIEW_WORDWRAPSYMBOLS,bShowWordWrapSymbols);
@@ -3382,6 +3590,20 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam)
break;
+ case IDM_VIEW_FOLDING:
+ bShowCodeFolding = (bShowCodeFolding) ? FALSE : TRUE;
+ SciCall_SetMarginWidth(MARGIN_FOLD_INDEX, (bShowCodeFolding) ? 11 : 0);
+ UpdateToolbar();
+ if (!bShowCodeFolding)
+ FoldToggleAll(EXPAND);
+ break;
+
+
+ case IDM_VIEW_TOGGLEFOLDS:
+ FoldToggleAll(SNIFF);
+ break;
+
+
case IDM_VIEW_SHOWEOLS:
bViewEOLs = (bViewEOLs) ? FALSE : TRUE;
SendMessage(hwndEdit,SCI_SETVIEWEOL,bViewEOLs,0);
@@ -4341,6 +4563,14 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam)
MessageBeep(0);
break;
+
+ case IDT_VIEW_TOGGLEFOLDS:
+ if (IsCmdEnabled(hwnd,IDM_VIEW_TOGGLEFOLDS))
+ SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_VIEW_TOGGLEFOLDS,1),0);
+ else
+ MessageBeep(0);
+ break;
+
}
return(0);
@@ -4571,6 +4801,16 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam)
iPathNameFormat,bModified || iEncoding != iOriginalEncoding,
IDS_READONLY,bReadOnly,szTitleExcerpt);
break;
+
+ case SCN_MARGINCLICK:
+ if (scn->margin == MARGIN_FOLD_INDEX)
+ FoldClick(SciCall_LineFromPosition(scn->position), scn->modifiers);
+ break;
+
+ case SCN_KEY:
+ // Also see the corresponding patch in scintilla\src\Editor.cxx
+ FoldAltArrow(scn->ch, scn->modifiers);
+ break;
}
break;
@@ -4818,6 +5058,9 @@ void LoadSettings()
bShowLineNumbers = IniSectionGetInt(pIniSection,L"ShowLineNumbers",1);
if (bShowLineNumbers) bShowLineNumbers = 1;
+ bShowCodeFolding = IniSectionGetInt(pIniSection,L"ShowCodeFolding",1);
+ if (bShowCodeFolding) bShowCodeFolding = 1;
+
bViewWhiteSpace = IniSectionGetInt(pIniSection,L"ViewWhiteSpace",0);
if (bViewWhiteSpace) bViewWhiteSpace = 1;
@@ -5063,6 +5306,7 @@ void SaveSettings(BOOL bSaveSettingsNow)
IniSectionSetInt(pIniSection,L"LongLineMode",iLongLineMode);
IniSectionSetInt(pIniSection,L"ShowSelectionMargin",bShowSelectionMargin);
IniSectionSetInt(pIniSection,L"ShowLineNumbers",bShowLineNumbers);
+ IniSectionSetInt(pIniSection,L"ShowCodeFolding",bShowCodeFolding);
IniSectionSetInt(pIniSection,L"ViewWhiteSpace",bViewWhiteSpace);
IniSectionSetInt(pIniSection,L"ViewEOLs",bViewEOLs);
IniSectionSetInt(pIniSection,L"DefaultEncoding",Encoding_MapIniSetting(FALSE,iDefaultEncoding));
@@ -5765,6 +6009,8 @@ void UpdateToolbar()
EnableTool(IDT_EDIT_REPLACE,i /*&& !bReadOnly*/);
EnableTool(IDT_EDIT_CLEAR,i /*&& !bReadOnly*/);
+ EnableTool(IDT_VIEW_TOGGLEFOLDS,bShowCodeFolding);
+
CheckTool(IDT_VIEW_WORDWRAP,fWordWrap);
}
View
8 src/Notepad2.rc
@@ -258,6 +258,9 @@ BEGIN
MENUITEM "Line &Numbers\tCtrl+Shift+N", IDM_VIEW_LINENUMBERS
MENUITEM "Selection &Margin\tCtrl+Shift+M", IDM_VIEW_MARGIN
MENUITEM SEPARATOR
+ MENUITEM "Code &Folding\tCtrl+Shift+Alt+F", IDM_VIEW_FOLDING
+ MENUITEM "&Toggle All Folds\tCtrl+Shift+F", IDM_VIEW_TOGGLEFOLDS
+ MENUITEM SEPARATOR
MENUITEM "Zoom &In\tCtrl++", IDM_VIEW_ZOOMIN
MENUITEM "Zoom &Out\tCtrl+-", IDM_VIEW_ZOOMOUT
MENUITEM "Reset &Zoom\tCtrl+/", IDM_VIEW_RESETZOOM
@@ -388,6 +391,10 @@ BEGIN
"E", IDM_EDIT_URLENCODE, VIRTKEY, SHIFT, CONTROL,
NOINVERT
"F", IDM_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT
+ "F", IDM_VIEW_FOLDING, VIRTKEY, SHIFT, CONTROL, ALT,
+ NOINVERT
+ "F", IDM_VIEW_TOGGLEFOLDS, VIRTKEY, SHIFT, CONTROL,
+ NOINVERT
"G", IDM_EDIT_GOTOLINE, VIRTKEY, CONTROL, NOINVERT
"G", IDM_VIEW_SHOWINDENTGUIDES, VIRTKEY, SHIFT, CONTROL,
NOINVERT
@@ -1426,6 +1433,7 @@ BEGIN
IDT_FILE_PRINT "Print"
IDT_FILE_OPENFAV "Favorites"
IDT_FILE_ADDTOFAV "Add to Favorites"
+ IDT_VIEW_TOGGLEFOLDS "Toggle All Folds"
END
STRINGTABLE
View
35 src/Styles.c
@@ -1442,6 +1442,41 @@ void Style_SetLexer(HWND hwnd,PEDITLEXER pLexNew)
//wsprintf(lexDefault.Styles[12+iIdx].szValue,L"size:0");
}
+ { // set folding style; braces are for scoping only
+ static const int iMarkerIDs[] =
+ {
+ SC_MARKNUM_FOLDEROPEN,
+ SC_MARKNUM_FOLDER,
+ SC_MARKNUM_FOLDERSUB,
+ SC_MARKNUM_FOLDERTAIL,
+ SC_MARKNUM_FOLDEREND,
+ SC_MARKNUM_FOLDEROPENMID,
+ SC_MARKNUM_FOLDERMIDTAIL
+ };
+
+ int i;
+
+ COLORREF clrFore = SciCall_StyleGetFore(STYLE_DEFAULT);
+ COLORREF clrBack = SciCall_StyleGetBack(STYLE_DEFAULT);
+
+ SciCall_SetFoldMarginColour(TRUE, clrBack);
+ SciCall_SetFoldMarginHiColour(TRUE, clrBack);
+
+ // Set marker color to the average of clrFore and clrBack
+ clrFore = (((clrFore & 0xFF0000) + (clrBack & 0xFF0000)) >> 1 & 0xFF0000) |
+ (((clrFore & 0x00FF00) + (clrBack & 0x00FF00)) >> 1 & 0x00FF00) |
+ (((clrFore & 0x0000FF) + (clrBack & 0x0000FF)) >> 1 & 0x0000FF);
+
+ // Rounding hack for pure white against pure black
+ if (clrFore == 0x7F7F7F) clrFore = 0x808080;
+
+ for (i = 0; i < COUNTOF(iMarkerIDs); ++i)
+ {
+ SciCall_MarkerSetBack(iMarkerIDs[i], clrFore);
+ SciCall_MarkerSetFore(iMarkerIDs[i], clrBack);
+ }
+ } // end set folding style
+
if (SendMessage(hwnd,SCI_GETINDENTATIONGUIDES,0,0) != SC_IV_NONE)
Style_SetIndentGuides(hwnd,TRUE);
View
3  src/resource.h
@@ -308,6 +308,8 @@
#define IDM_VIEW_STATUSBAR 40442
#define IDM_VIEW_SAVESETTINGS 40443
#define IDM_VIEW_SAVESETTINGSNOW 40444
+#define IDM_VIEW_FOLDING 40445
+#define IDM_VIEW_TOGGLEFOLDS 40446
#define IDM_HELP_ABOUT 40500
#define IDM_TRAY_RESTORE 40600
#define IDM_TRAY_EXIT 40601
@@ -334,6 +336,7 @@
#define IDT_FILE_PRINT 40720
#define IDT_FILE_OPENFAV 40721
#define IDT_FILE_ADDTOFAV 40722
+#define IDT_VIEW_TOGGLEFOLDS 40723
#define SC_SAVEPOS 40800
#define SC_RESETPOS 40801
#define IDS_ERR_LOADFILE 50000
Please sign in to comment.
Something went wrong with that request. Please try again.