diff --git a/client/images/down-arrow-white.svg b/client/images/down-arrow-white.svg
new file mode 100644
index 00000000..34efd84b
--- /dev/null
+++ b/client/images/down-arrow-white.svg
@@ -0,0 +1,18 @@
+
+
\ No newline at end of file
diff --git a/client/images/right-arrow-white.svg b/client/images/right-arrow-white.svg
new file mode 100644
index 00000000..b789f93d
--- /dev/null
+++ b/client/images/right-arrow-white.svg
@@ -0,0 +1,16 @@
+
+
\ No newline at end of file
diff --git a/client/modules/IDE/components/Editor.jsx b/client/modules/IDE/components/Editor.jsx
index 2bef97c7..00344e98 100644
--- a/client/modules/IDE/components/Editor.jsx
+++ b/client/modules/IDE/components/Editor.jsx
@@ -7,6 +7,11 @@ import 'codemirror/addon/lint/lint';
import 'codemirror/addon/lint/javascript-lint';
import 'codemirror/addon/lint/css-lint';
import 'codemirror/addon/lint/html-lint';
+import 'codemirror/addon/fold/brace-fold';
+import 'codemirror/addon/fold/comment-fold';
+import 'codemirror/addon/fold/foldcode';
+import 'codemirror/addon/fold/foldgutter';
+import 'codemirror/addon/fold/indent-fold';
import 'codemirror/addon/comment/comment';
import 'codemirror/keymap/sublime';
import 'codemirror/addon/search/searchcursor';
@@ -62,7 +67,9 @@ class Editor extends React.Component {
inputStyle: 'contenteditable',
lineWrapping: false,
fixedGutter: false,
- gutters: ['CodeMirror-lint-markers'],
+ foldGutter: true,
+ foldOptions: { widget: '\u2026' },
+ gutters: ['CodeMirror-foldgutter'],
keyMap: 'sublime',
highlightSelectionMatches: true, // highlight current search match
lint: {
@@ -86,6 +93,7 @@ class Editor extends React.Component {
}
});
+
this._cm.setOption('extraKeys', {
[`${metaKey}-Enter`]: () => null,
[`Shift-${metaKey}-Enter`]: () => null,
diff --git a/client/styles/abstracts/_variables.scss b/client/styles/abstracts/_variables.scss
index 69736822..d3a62a22 100644
--- a/client/styles/abstracts/_variables.scss
+++ b/client/styles/abstracts/_variables.scss
@@ -49,6 +49,8 @@ $themes: (
dropdown-color: #414141,
keyboard-shortcut-color: #757575,
nav-hover-color: $p5js-pink,
+ codefold-icon-open: url(../images/down-arrow.svg),
+ codefold-icon-closed: url(../images/right-arrow.svg)
),
dark: (
logo-color: $p5js-pink,
@@ -88,6 +90,8 @@ $themes: (
dropdown-color: #dadada,
keyboard-shortcut-color: #B5B5B5,
nav-hover-color: $p5js-pink,
+ codefold-icon-open: url(../images/down-arrow-white.svg),
+ codefold-icon-closed: url(../images/right-arrow-white.svg)
),
contrast: (
logo-color: $yellow,
@@ -125,7 +129,9 @@ $themes: (
search-background-color: $white,
dropdown-color: #e1e1e1,
keyboard-shortcut-color: #e1e1e1,
- nav-hover-color: $yellow
+ nav-hover-color: $yellow,
+ codefold-icon-open: url(../images/down-arrow-white.svg),
+ codefold-icon-closed: url(../images/right-arrow-white.svg)
)
);
diff --git a/client/styles/components/_editor.scss b/client/styles/components/_editor.scss
index 194264d0..bf317fb0 100644
--- a/client/styles/components/_editor.scss
+++ b/client/styles/components/_editor.scss
@@ -13,17 +13,17 @@
.CodeMirror-linenumber {
width: #{32 / $base-font-size}rem;
- left: 0 !important;
+ left: #{-3 / $base-font-size}rem !important;
@include themify() {
color: getThemifyVariable('inactive-text-color');
}
}
.CodeMirror-lines {
- padding-top: #{25 / $base-font-size}rem;
+ padding-top: #{25 / $base-font-size}rem;
}
-.CodeMirror-line {
+pre.CodeMirror-line {
padding-left: #{5 / $base-font-size}rem;
}
@@ -243,6 +243,40 @@
background: transparent url(../images/exit.svg) no-repeat;
}
+.CodeMirror-foldgutter-open:after {
+ @include themify() {
+ background-image: getThemifyVariable('codefold-icon-open');
+ }
+}
+
+.CodeMirror-foldgutter-folded:after {
+ @include themify() {
+ background-image: getThemifyVariable('codefold-icon-closed');
+ }
+}
+
+.CodeMirror-foldgutter-folded:after,
+.CodeMirror-foldgutter-open:after {
+ background-size: 10px 10px;
+ content: "";
+ padding-left: 15px;
+ background-repeat: no-repeat;
+ background-position: center center;
+}
+
+.CodeMirror-foldmarker {
+ text-shadow: none;
+ border-radius: 5px;
+ opacity: 1;
+ font-weight: normal;
+ display: inline-block;
+ vertical-align: middle;
+ height: 0.85em;
+ line-height: 0.7;
+ padding: 0 #{5 / $base-font-size}rem;
+ font-family: serif;
+}
+
.editor-holder {
height: calc(100% - #{29 / $base-font-size}rem);
width: 100%;
diff --git a/client/styles/components/_p5-contrast-codemirror-theme.scss b/client/styles/components/_p5-contrast-codemirror-theme.scss
index d5a2a997..6ddef26a 100644
--- a/client/styles/components/_p5-contrast-codemirror-theme.scss
+++ b/client/styles/components/_p5-contrast-codemirror-theme.scss
@@ -125,3 +125,8 @@ $p5-contrast-activeline: #999999;
color: $p5-contrast-pink;
font-weight: bold;
}
+
+.cm-s-p5-contrast .CodeMirror-foldmarker {
+ background-color: white;
+ color: #333;
+}
diff --git a/client/styles/components/_p5-dark-codemirror-theme.scss b/client/styles/components/_p5-dark-codemirror-theme.scss
index e727b03f..275d57ff 100644
--- a/client/styles/components/_p5-dark-codemirror-theme.scss
+++ b/client/styles/components/_p5-dark-codemirror-theme.scss
@@ -128,3 +128,8 @@ $p5-dark-activeline: rgb(207, 207, 207);
color: $p5-dark-pink;
font-weight: bold;
}
+
+.cm-s-p5-dark .CodeMirror-foldmarker {
+ background-color: white;
+ color: #333;
+}
diff --git a/client/styles/components/_p5-light-codemirror-theme.scss b/client/styles/components/_p5-light-codemirror-theme.scss
index 0a5fcd78..dbb72dbd 100644
--- a/client/styles/components/_p5-light-codemirror-theme.scss
+++ b/client/styles/components/_p5-light-codemirror-theme.scss
@@ -126,3 +126,8 @@ $p5-light-activeline: rgb(207, 207, 207);
.cm-s-p5-light .cm-p5-variable {
color: $p5-light-pink;
}
+
+.cm-s-p5-light .CodeMirror-foldmarker {
+ background-color: #333;
+ color: white;
+}
diff --git a/client/styles/vendors/_codemirror.scss b/client/styles/vendors/_codemirror.scss
index 1cf66a9f..8938568c 100644
--- a/client/styles/vendors/_codemirror.scss
+++ b/client/styles/vendors/_codemirror.scss
@@ -336,3 +336,33 @@ div.CodeMirror-dragcursors {
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
+
+/* CODE FOLDING (FOLDGUTTER.JS) */
+
+.CodeMirror-foldmarker {
+ text-shadow: -1px 0 #ed225d, 0 1px #ed225d, 1px 0 #ed225d, 0 -1px #ed225d;
+ color: #FFF;
+ /* background-color: rgba(237, 34, 93, 0.42); */
+ /* border-radius: 3px; */
+ font-weight: bold;
+ font-family: arial;
+ line-height: .3;
+ cursor: pointer;
+ opacity: 0.75;
+}
+.CodeMirror-foldgutter {
+ width: 2.7em;
+}
+.CodeMirror-foldgutter-open,
+.CodeMirror-foldgutter-folded {
+ cursor: pointer;
+ padding-bottom: 0.4em;
+ text-align: right;
+ line-height: 1.0;
+}
+.CodeMirror-foldgutter-open:after {
+ content: "\25BE";
+}
+.CodeMirror-foldgutter-folded:after {
+ content: "\25B8";
+}