Repository: spyder-ide/spyder

Issue:
Enabling or disabling "Show blank spaces" causes Spyder to perma-hang
## Description

### What steps will reproduce the problem?

<!--- You can use Markdown here --->

"Show blank spaces" works fine when already enabled or disabled at startup, and I am able to enable and disable it with minimal lag with a single 50 line file open. However, if I e.g. have even just `mainwindow.py` open and nothing else and enable/disable it, either from the Source menu or from Spyder's preferences, Spyder becomes completely unreponsive, hangs and usually never recovers, at least after waiting several minutes. Over dozens of tests, occasionally it does work right away or after a short delay for no obvious reason but that seems to be more the exception than the rule, as aside from on the one short file it didn't work more than a few times out of those.



## Versions

* Spyder version: 4.0.0.dev0 badc02a25
* Python version: 3.7.5
* Qt version: 5.9.6
* PyQt5 version: 5.9.2
* Operating System: Windows 8.1

### Dependencies

```
cloudpickle >=0.5.0          :  0.7.0 (OK)
pygments >=2.0               :  2.3.1 (OK)
qtconsole >=4.6.0            :  4.6.0 (OK)
nbconvert >=4.0              :  5.4.0 (OK)
sphinx >=0.6.6               :  1.8.4 (OK)
pylint >=0.25                :  2.2.2 (OK)
psutil >=0.3                 :  5.6.3 (OK)
qtawesome >=0.5.7            :  0.6.0 (OK)
qtpy >=1.5.0                 :  1.9.0 (OK)
pickleshare >=0.4            :  0.7.5 (OK)
zmq >=17                     :  17.1.2 (OK)
chardet >=2.0.0              :  3.0.4 (OK)
numpydoc >=0.6.0             :  0.8.0 (OK)
spyder_kernels >=1.8.0;<2.0.0:  1.8.0 (OK)
qdarkstyle >=2.7             :  2.7 (OK)
atomicwrites >=1.2.0         :  1.3.0 (OK)
diff_match_patch >=20181111  :  20181111 (OK)
intervaltree                 :  None (OK)
watchdog                     :  None (OK)
keyring                      :  None (OK)
pexpect >=4.4.0              :  4.7.0 (OK)
pympler                      :  None (OK)
sympy >=0.7.3                :  1.3 (OK)
cython >=0.21                :  0.29.4 (OK)
IPython >=4.0                :  7.2.0 (OK)
matplotlib >=2.0.0           :  3.0.2 (OK)
pandas >=0.13.1              :  0.24.2 (OK)
numpy >=1.7                  :  1.15.4 (OK)
scipy >=0.17.0               :  1.2.0 (OK)
pyls >=0.31.0;<0.32.0        :  0.31.0 (OK)
rtree >=0.8.3                :  0.8.3 (OK)
```



Discussion:

Resolving patch:
diff --git a/spyder/plugins/editor/widgets/codeeditor.py b/spyder/plugins/editor/widgets/codeeditor.py
--- a/spyder/plugins/editor/widgets/codeeditor.py
+++ b/spyder/plugins/editor/widgets/codeeditor.py
@@ -1570,10 +1570,7 @@ def intelligent_backtab(self):
             self.unindent()
 
     def rehighlight(self):
-        """
-        Rehighlight the whole document to rebuild outline explorer data
-        and import statements data from scratch
-        """
+        """Rehighlight the whole document."""
         if self.highlighter is not None:
             self.highlighter.rehighlight()
         if self.highlight_current_cell_enabled:
diff --git a/spyder/utils/syntaxhighlighters.py b/spyder/utils/syntaxhighlighters.py
--- a/spyder/utils/syntaxhighlighters.py
+++ b/spyder/utils/syntaxhighlighters.py
@@ -185,7 +185,7 @@ def __init__(self, parent, font=None, color_scheme='Spyder'):
         self.setup_formats(font)
 
         self.cell_separators = None
-        self.fold_detector = None
+        self.request_folding = True
         self.editor = None
         self.patterns = DEFAULT_COMPILED_PATTERNS
 
@@ -290,20 +290,12 @@ def highlightBlock(self, text):
         :param text: text to highlight.
         """
         self.highlight_block(text)
-        if self.editor:
-            if self.editor.folding_supported and self.editor.code_folding:
-                diff, _ = self.editor.text_diff
-                if len(diff) > 0:
-                    self.editor.request_folding()
-
-        # Process blocks for fold detection
-        # current_block = self.currentBlock()
-        # previous_block = self._find_prev_non_blank_block(current_block)
-        # if self.editor:
-        #     if self.fold_detector is not None:
-        #         self.fold_detector._editor = weakref.ref(self.editor)
-        #         self.fold_detector.process_block(
-        #             current_block, previous_block, text)
+        if self.request_folding:
+            if self.editor is not None:
+                if self.editor.folding_supported and self.editor.code_folding:
+                    diff, _ = self.editor.text_diff
+                    if len(diff) > 0:
+                        self.editor.request_folding()
 
     def highlight_block(self, text):
         """
@@ -368,7 +360,9 @@ def highlight_extras(self, text, offset=0):
 
     def rehighlight(self):
         QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
+        self.request_folding = False
         QSyntaxHighlighter.rehighlight(self)
+        self.request_folding = True
         QApplication.restoreOverrideCursor()
 
 


Test patch: