Repository: spyder-ide/spyder

Issue:
Error in display of tabulator in editor
### Issue Report Checklist

* [x] Searched the [issues page](https://github.com/spyder-ide/spyder/issues?q=is%3Aissue) for similar reports
* [x] Read the relevant sections of the [Spyder Troubleshooting Guide](https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ) and followed its advice
* [x] Reproduced the issue after updating with ``conda update spyder`` (or ``pip``, if not using Anaconda)
* [x] Could not reproduce inside ``jupyter qtconsole`` (if console-related)
* [x] Tried basic troubleshooting (if a bug/error)
    * [x] Restarted Spyder
    * [x] Reset preferences with ``spyder --reset``
    * [x] Reinstalled the latest version of [Anaconda](https://www.anaconda.com/download/)
    * [x] Tried the other applicable steps from the Troubleshooting Guide
* [x] Completed the **Problem Description**, **Steps to Reproduce** and **Version** sections below


## Problem Description
The Spyder editor does not display tabulators right.


### What steps reproduce the problem?

1. open Spyder with default settings
2. load the attached file into Spyder editor
[temp.txt](https://github.com/spyder-ide/spyder/files/2187784/temp.txt)


3. see it?

### What is the expected output? What do you see instead?
A Tab should be EXACTLY 4 spaces wide, as configured in the settings. But in appears more like ~4.5 spaces making lines not aligned

## Versions

* Spyder version: 3.2.6
* Python version: 3.6.5
* Qt version: 5.9.5
* PyQt version: 5.10.1
* Operating System name/version: Ubuntu 18.04 LTS

### Dependencies
```
IPython >=4.0    :  5.5.0 (OK)
cython >=0.21    :  None (NOK)
jedi >=0.9.0     :  0.11.1 (OK)
nbconvert >=4.0  :  5.3.1 (OK)
numpy >=1.7      :  1.13.3 (OK)
pandas >=0.13.1  :  None (NOK)
psutil >=0.3     :  5.4.2 (OK)
pycodestyle >=2.3:  2.3.1 (OK)
pyflakes >=0.6.0 :  1.6.0 (OK)
pygments >=2.0   :  2.2.0 (OK)
pylint >=0.25    :  1.8.3 (OK)
qtconsole >=4.2.0:  4.3.1 (OK)
rope >=0.9.4     :  0.10.5 (OK)
sphinx >=0.6.6   :  1.6.7 (OK)
sympy >=0.7.3    :  None (NOK)

```



Discussion:
> But in appears more like ~4.5 spaces making lines not aligned

Please post a screenshot because I don't understand what you mean by `4.5` spaces.
Sceenshot:

![bildschirmfoto von 2018-07-12 16-56-54](https://user-images.githubusercontent.com/10723283/42641403-ca02fc22-85f4-11e8-820c-7ee7e79857f9.png)

The same file with a different editor (Geany):

![bildschirmfoto von 2018-07-12 16-59-23](https://user-images.githubusercontent.com/10723283/42641571-1d833394-85f5-11e8-830d-6b53aa737da5.png)

I can't reproduce this

![seleccion_006](https://user-images.githubusercontent.com/365293/42660644-743ae474-85f1-11e8-945d-7bb1f30954f4.png)

so it looks like a problem with the font you choose.
I get it in spyder 4 on Ubuntu 16.04.

It's a mix of spaces and tabs which isn't clear without downloading the text file.

Ubuntu Mono(size 11):
![spyder_tabs](https://user-images.githubusercontent.com/10513354/42662207-f546d6c6-85ed-11e8-89e3-280488071b28.png)

Monospace:
![tab s monospace](https://user-images.githubusercontent.com/10513354/42662531-2e6cc0e0-85ef-11e8-9357-d4782b1daa55.png)

New Courier:
![courier](https://user-images.githubusercontent.com/10513354/42662534-32ef9c1e-85ef-11e8-8c1e-4f34468b878b.png)

Turning on or off show spaces has no effect.

Font size does matter
Ubuntu Mono(size:10):
![font_size](https://user-images.githubusercontent.com/10513354/42662734-ff7d5fb4-85ef-11e8-8f6a-8cb98228fdfe.png)




Mixing spaces and tabs is a very bad idea, so I'd be in favor of closing this one. Realistically we also don't have time to invest in fixing this one.

What do you say @bcolsen?
>Mixing spaces and tabs is a very bad idea, so I'd be in favor of closing this one.

This is not really a case of mixing spaces and tabs. The bug is there when you just use tabs (also a bad idea) The current way tabs are drawn would make it quite difficult to use the editor. The spacing can be off by 1.5 spaces depending on the font and size(Monospace 12) :

![tabs](https://user-images.githubusercontent.com/10513354/42715672-408467e4-86b5-11e8-9de7-0c9ed7809e85.png)

The two sections should be identical. Notice how the guides don't work either. This is a rendering bug that could impact code readability if you use tabs.

>Realistically we also don't have time to invest in fixing this one.

This is true, but this bug should be kept as reference to the issue.  I don't use tabs so it's low on my priorities 

> The bug is there when you just use tabs (also a bad idea)
Well, in my opinion it is a bad idea to use SPACES to indent, but that's a different discussion. Everyone should have the choice of using tabs OR spaces. It is true that mixing spaces and tabs does not make sense, I just used them in the example to make the problem clear.

The point is, that a program editor has to use a monospace font and render it correctly in order to make things line up. But in Spyder editor this does not work when using tabs. So in my opinion this is a SEVERE bug.

I mean, this is a text editor. If this was a MINOR bug, what are your SEVERE bugs that you have to fix first??? Not being able to load a text file?


@bcolsen: Did you find a combination of font and font size so that the editor is usable again?
> So in my opinion this is a SEVERE bug.

You're welcome to fix it. I consider this low priority because you're the first person to report it.
> You're welcome to fix it.

OK, I will give it a try. Can you give me a hint where to start? Which file is responsible for rendering the editor window content?
For the record, I can reproduce it on Spyder 3.3.0 on Win8.1/Python 3.6.6/Qt 5.6 as well. 

I'm not as familiar with the details of the underpinnings as some, but the [Editor widget](https://github.com/spyder-ide/spyder/blob/3.x/spyder/widgets/editor.py) would be one place to start. Since this is a bug, if it ends up being straightforward you could probably justify fixing this on ``3.x``, in my opinion.

Resolving patch:
diff --git a/spyder/widgets/editor.py b/spyder/widgets/editor.py
--- a/spyder/widgets/editor.py
+++ b/spyder/widgets/editor.py
@@ -1067,8 +1067,8 @@ def set_tab_stop_width_spaces(self, tab_stop_width_spaces):
         self.tab_stop_width_spaces = tab_stop_width_spaces
         if self.data:
             for finfo in self.data:
-                finfo.editor.setTabStopWidth(tab_stop_width_spaces
-                                             * self.fontMetrics().width('9'))
+                finfo.editor.tab_stop_width_spaces = tab_stop_width_spaces
+                finfo.editor.update_tab_stop_width_spaces()
 
     def set_help_enabled(self, state):
         self.help_enabled = state
diff --git a/spyder/widgets/sourcecode/base.py b/spyder/widgets/sourcecode/base.py
--- a/spyder/widgets/sourcecode/base.py
+++ b/spyder/widgets/sourcecode/base.py
@@ -293,8 +293,8 @@ def set_tab_stop_width_spaces(self, tab_stop_width_spaces):
         self.update_tab_stop_width_spaces()
 
     def update_tab_stop_width_spaces(self):
-        self.setTabStopWidth(self.fontMetrics().width(
-                '9' * self.tab_stop_width_spaces))
+        self.setTabStopWidth(self.fontMetrics().width(' ')
+                             * self.tab_stop_width_spaces)
 
     def set_palette(self, background, foreground):
         """
diff --git a/spyder/widgets/sourcecode/codeeditor.py b/spyder/widgets/sourcecode/codeeditor.py
--- a/spyder/widgets/sourcecode/codeeditor.py
+++ b/spyder/widgets/sourcecode/codeeditor.py
@@ -709,7 +709,6 @@ def setup_editor(self, linenumbers=True, language=None, markers=False,
         self.set_add_colons_enabled(add_colons)
         self.set_auto_unindent_enabled(auto_unindent)
         self.set_indent_chars(indent_chars)
-        self.set_tab_stop_width_spaces(tab_stop_width_spaces)
 
         # Scrollbar flag area
         self.set_scrollflagarea_enabled(scrollflagarea)
@@ -753,6 +752,9 @@ def setup_editor(self, linenumbers=True, language=None, markers=False,
         elif color_scheme is not None:
             self.set_color_scheme(color_scheme)
 
+        # Set tab spacing after font is set
+        self.set_tab_stop_width_spaces(tab_stop_width_spaces)
+
         self.toggle_wrap_mode(wrap)
 
     def set_tab_mode(self, enable):


Test patch: