Repository: spyder-ide/spyder

Issue:
Can't close any editor tab when in debug mode
## Description

### What steps will reproduce the problem?

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

Tabs can't be closed when code is run in debug mode.



## Versions

* Spyder version: 4.1.3 
* Python version: 3.7.7
* Qt version: 5.9.6
* PyQt5 version: 5.9.2
* Operating System: Linux 5.3.0-53-generic

### Dependencies

```

# Mandatory:
atomicwrites >=1.2.0           :  1.3.0 (OK)
chardet >=2.0.0                :  3.0.4 (OK)
cloudpickle >=0.5.0            :  1.4.0 (OK)
diff_match_patch >=20181111    :  20181111 (OK)
intervaltree                   :  None (OK)
IPython >=4.0                  :  7.13.0 (OK)
jedi =0.15.2                   :  0.15.2 (OK)
keyring                        :  None (OK)
nbconvert >=4.0                :  5.6.1 (OK)
numpydoc >=0.6.0               :  0.9.2 (OK)
parso =0.5.2                   :  0.5.2 (OK)
pexpect >=4.4.0                :  4.8.0 (OK)
pickleshare >=0.4              :  0.7.5 (OK)
psutil >=5.3                   :  5.7.0 (OK)
pygments >=2.0                 :  2.6.1 (OK)
pylint >=0.25                  :  2.4.4 (OK)
pyls >=0.31.9;<0.32.0          :  0.31.10 (OK)
qdarkstyle >=2.8               :  2.8.1 (OK)
qtawesome >=0.5.7              :  0.7.0 (OK)
qtconsole >=4.6.0              :  4.7.3 (OK)
qtpy >=1.5.0                   :  1.9.0 (OK)
rtree >=0.8.3                  :  0.9.4 (OK)
sphinx >=0.6.6                 :  3.0.3 (OK)
spyder_kernels >=1.9.1;<1.10.0 :  1.9.1 (OK)
watchdog                       :  None (OK)
xdg >=0.26                     :  0.26 (OK)
zmq >=17                       :  18.1.1 (OK)

# Optional:
cython >=0.21                  :  0.29.17 (OK)
matplotlib >=2.0.0             :  3.1.3 (OK)
numpy >=1.7                    :  1.18.1 (OK)
pandas >=0.13.1                :  1.0.3 (OK)
scipy >=0.17.0                 :  1.4.1 (OK)
sympy >=0.7.3                  :  1.5.1 (OK)
```



Discussion:
@ma-sadeghi thanks for your report.

Could you please post an animations using https://www.cockos.com/licecap/ or similar to better understand the current issue.

Thanks!
@goanpeca There you go:
![gif](https://i.imgur.com/DjlBF0K.gif)
This is done by design in order to prevent that a console goes out of sync with the file it's being debugged on it. So you need to go out of the debugger in order to close your file.

@goanpeca, perhaps we should show a message about this?
1 Like a popup? Or 
2 something that gets printed to the console the user is working?

Probably 2 would be nicer and less invasive?
Yeah, I agree with point 2, good idea!

Resolving patch:
diff --git a/spyder/plugins/editor/plugin.py b/spyder/plugins/editor/plugin.py
--- a/spyder/plugins/editor/plugin.py
+++ b/spyder/plugins/editor/plugin.py
@@ -85,6 +85,7 @@ class Editor(SpyderPluginWidget):
     breakpoints_saved = Signal()
     run_in_current_extconsole = Signal(str, str, str, bool, bool)
     open_file_update = Signal(str)
+    sig_file_debug_message_requested = Signal()
 
     # This signal is fired for any focus change among all editor stacks
     sig_editor_focus_changed = Signal()
@@ -2060,8 +2061,10 @@ def can_close_file(self, filename=None):
         if debugging and 'fname' in last_pdb_step and filename:
             if osp.normcase(last_pdb_step['fname']) == osp.normcase(filename):
                 can_close = False
+                self.sig_file_debug_message_requested.emit()
         elif debugging:
             can_close = False
+            self.sig_file_debug_message_requested.emit()
         return can_close
 
     @Slot()
diff --git a/spyder/plugins/ipythonconsole/plugin.py b/spyder/plugins/ipythonconsole/plugin.py
--- a/spyder/plugins/ipythonconsole/plugin.py
+++ b/spyder/plugins/ipythonconsole/plugin.py
@@ -128,6 +128,9 @@ def __init__(self, parent, testing=False, test_dir=None,
 
         self.tabwidget.set_close_function(self.close_client)
 
+        self.main.editor.sig_file_debug_message_requested.connect(
+            self.print_debug_file_msg)
+
         if sys.platform == 'darwin':
             tab_container = QWidget()
             tab_container.setObjectName('tab-container')
@@ -1602,3 +1605,12 @@ def _remove_old_stderr_files(self):
                         os.remove(osp.join(tmpdir, fname))
                     except Exception:
                         pass
+
+    def print_debug_file_msg(self):
+        """Print message in the current console when a file can't be closed."""
+        debug_msg = _('<br><hr>'
+                      '\nThe current file cannot be closed because it is '
+                      'in debug mode. \n'
+                      '<hr><br>')
+        self.get_current_client().shellwidget._append_html(
+                    debug_msg, before_prompt=True)


Test patch:
diff --git a/spyder/plugins/ipythonconsole/tests/test_ipython_config_dialog.py b/spyder/plugins/ipythonconsole/tests/test_ipython_config_dialog.py
--- a/spyder/plugins/ipythonconsole/tests/test_ipython_config_dialog.py
+++ b/spyder/plugins/ipythonconsole/tests/test_ipython_config_dialog.py
@@ -21,6 +21,7 @@
 
 class MainWindowMock:
     register_shortcut = Mock()
+    editor = Mock()
 
 
 @pytest.mark.parametrize(