Menu

#583 change auto indent behavior when indent width != tab width

None
open
auto-indent (1)
5
2017-03-26
2016-04-04
lundril
No

With the current jedit trunk (and also the previous jedit 5.2.0 release) I
get the following behavior when using auto-indent == full and
tab width != indent width.
Here is an example with tab width == 8 and indent width == 4.
t_ marks tab, _ marks a whitespace.

int myfunc(int a)
{
____if (a==5) {
____t_  printf("Hello World\n");
____}
}

But I would like to get (and I think this is also more correct):

int myfunc(int a)
{
____if (a==5) {
t_      printf("Hello World\n");
____}
}

So basically I want that the "printf" line simply uses one TAB and not a
combination of 4 SPACEs + one TAB.

The reason why I think this is more correct is, that when indenting the
whole function with "shift-TAB", then the indentation will be as in the
second example.

1 Attachments

Related

Patches: #583

Discussion

  • Marc Häfner

    Marc Häfner - 2016-04-06

    I'm a bit skeptical about this proposal. I think it's a feature that jEdit tries to keep the indentation consistent, which is relevant when editing other peoples files.

    The required formatting can also be achieved with the Whitespace plugin (on save) which changes all lines consistently and not just the ones that are currently edited.

     
  • Steve

    Steve - 2016-04-07

    I also do not agree with lundril that this is the correct behavior. If you have configured jEdit to indent with spaces, it should definitely no leave the tab in place and suppress the spaces. IMO, the correct “fix” to this problem would be:

    int myfunc(int a)
    {
    _if (a==5) {
    __printf("Hello World\n");
    _}
    }

    The tab should be replaced with the proper spaces.

     
    • Steve

      Steve - 2016-04-07

      (Sorry, formatting got bungled.)

      int myfunc(int a)
      {
      ____if (a==5) {
      ________printf("Hello World\n");
      ____}
      }
      
       
  • lundril

    lundril - 2016-04-07

    A more comprehensive description how to reproduce it.

    Reproduce:
    1. Create new "Untitled" file "In Mode" "C".
    2. Go to "Utilities->Buffer Options", set :
    * "Automatic indentation" := full
    * "Tab width" := 8
    * "Indent width" := 4
    * Soft tabs := UNCHECKED
    * Indent using elastic tabstops := UNCHECKED
    3. Type the following characters into the "untitled" file window (note the missing leading whitespace, this should be done by the auto indentation):

    int myfunc(int a)
    {
    if (a==5) {
    printf("Hello World\n");
    }
    }
    

    The result currently (with jedit 5.2.0 and also tested with Svn rev 24359) is

    int myfunc(int a)
    {
    ____if (a==5) {
    ____t_  printf("Hello World\n");
    ____}
    }
    
     

    Last edit: lundril 2016-04-07
  • lundril

    lundril - 2016-04-07

    Now with the previous explanation how to reproduce:
    @Mark:

    You are right, if I use the WhiteSpace plugin and enable "Tabify/untabify according to soft tabs setting", then when saving the file the indentation will be corrected.

    So this is OK, and I didn't know that before, so thanks.

    But, you argue:

    I think it's a feature that jEdit tries to keep the indentation consistent

    That's exactly my problem.
    I have million lines of code which look like this

    int otherfunc(int x)
    {
    ____if (x==6) {
    t_      printf("foobar\n");
    ____}
    }
    

    I then add another function and get (with the settings mentioned above):

    int otherfunc(int x)
    {
    ____if (x==6) {
    t_      printf("foobar\n");
    ____}
    }
    
    /* function inserted with jEdit auto indent */
    int myfunc(int a)
    {
    ____if (a==5) {
    ____t_  printf("never mind\n");
    ____}
    }
    

    So now I exactly have inconsistent indentation.

    It's interesting that the WhiteSpace plugin will fix this indentation to look exactly as the "otherfunc" indentation, when enabling the right options. But I still would prefer to NOT set this WhiteSpace plugin option and instead directly get correct indentation from the auto indenter.

    The fact that the WhiteSpace plugin already corrects the indentation, also hints that the indentation which the auto indenter uses is at least inconsistent to the indentation the WhiteSpace plugin uses.

    I don't know if I explained my problem better...

     
    • Marc Häfner

      Marc Häfner - 2016-04-07

      I think I understand your particular problem, but as a counterexample in python where your suggested behavior would not be correct:

      #:indentSize=4:tabSize=8:
      if __name__=='__main__':
          if __debug__:
              print("some debug message")
      

      If the indentation in the last line is a tab while the previous line uses spaces python throws a "TabError: inconsistent use of tabs and spaces in indentation" (while spaces followed by a tab work just fine).

      While in your example the currently produced indentation is not consistent with the overall layout of the code, it is in regards to the previous line. And as jEdit is a line-based text editor, it cannot really understand the indentations of the whole file, as would have to, in order to work well with your code and the above example. (And for similar reasons I wouldn't expect the whitespace plugin to not butcher the the python example on save.)

      Given these limitations and the likely scenario that a user might edit a file that does not reflect their current tabs & indent configuration, I think it's a good idea to base any additional indentation on the indentation of the previous line.

       
      • lundril

        lundril - 2016-04-11

        I just tried out some python code.
        It seems it is somewhat more complicated.

        Python 2 actually uses a fixed tab stop size of 8.

        See also here:

        https://docs.python.org/2/reference/lexical_analysis.html#indentation

        First, tabs are replaced (from left to right) by one to eight spaces such that
        the total number of characters up to and including the replacement
        is a multiple of eight

        This also means the following code works for python 2.x (with tab width==8 and indent width ==4):

        1
        2
        3
        4
        5
        6
        7
        8
        9
        #!/usr/bin/python2
        x = 1
        if x>10 :
        ____if x==20 :
        t_      print "Hello 20  A"
        ____else:
        t_      print "Hello >10 B"
        else:
        ____print "Hello <= 10   C"
        

        Python 3.x added the following sentence:

        Indentation is rejected as inconsistent if a source file mixes
        tabs and spaces in a way that makes the meaning dependent
        on the worth of a tab in spaces; a TabError is raised in that case.

        See here:

        https://docs.python.org/3/reference/lexical_analysis.html#indentation

        Now first of all to me it is not clear at all what kind of space/tab mix Python 3.x actually allows (the rule quoted above is hard to interpret).

        I think it would have been much cleaner to simply state that for indentation Python 3.x either requires spaces or TABs, but it does not allow both in the same file (for indentation).

        This seems to be the rule for all Python code written in practice (it either uses only TABs or only SPACEs but never a mixture). Not mixing TAB and SPACEs also seems to be one of the real hard recommendations for Python.

        So as a summary: I am not convinced that Python code will have a problem with the patch I gave. In general it seems to me that the rule for Python is: Make sure tab width == indent width. Then decide to either use "soft tabs" or not.

        Given these limitations and the likely scenario that a user
        might edit a file that does not reflect their
        current tabs & indent configuration, I think it's a good idea to
        base any additional indentation on the indentation of the
        previous line.

        I think I understand what you mean.

        I gave an example which exactly covers the case where a user edits a file which already has a specific tab&indent configuration and the auto-indenter of jEdit does the wrong thing.

        I also think in general you must modify indentation of the preceding line if indent width != tab width and you decrease the indentation level.

        Example: Assume someone has written the following code
        (with indent width == 4, tab width == 8).
        Assume the code was not generated by the auto indent of jEdit 5.2.

        int myfunc(int a,int b)
        {
        ____if (a==5) {
        t_      print("Hello World\n");
        t_      // <- here you now press }
        

        You must modify the preceding TAB and replace it by 4 spaces. That's the only way to create an indentation of 4.

        So if indent width != tab width there are lots of examples where decreasing indentation is not possible without modifying the leading whitespace of the preceding line.

        So if this is already true for decreasing indentation, why is it a problem with doing the same for increasing indentation ?

         
      • Alan Ezust

        Alan Ezust - 2017-03-27

        Actually, I've tried using tabs on one line and space on the other in Python. As long as all lines in the same block are consistent with each other, it should not matter if you use spaces for one level and a combo of spaces and tabs for the other, and just tabs on another.

         
  • lundril

    lundril - 2016-04-07

    @Steve:

    If I only use WhiteSpace and no TAB characters at all, then of course I do not have the problem.

    But I already have got million lines of code, which are NOT WhiteSpace only. These code lines use a mixture of TAB (interpreted with a fixed tab stop size of 8) and WhiteSpace (to generate "half" tab stops).

    I do not want to change these million lines of code to WhiteSpace only, just because the auto indenter of jEdit has a different idea how to indent when "tab width" != "indent width".

     
    • Steve

      Steve - 2016-04-07

      I understand that. I had a bit of a fight with my last design team when I "fixed" 200+ files that people had checked in with a mixture of tab and space indenting. Ultimately, mixing them within a project is painful. Mixing them within a file is BAD, and the person(s) who did it should be whipped senseless with a copy of the coding guidelines. ;-)

      Steve

      -

      From: lundril [mailto:lundril@users.sf.net]
      Sent: Thursday, April 07, 2016 12:24 PM
      To: [jedit:patches]
      Subject: [jedit:patches] #583 change auto indent behavior when indent width != tab width

      @Steve:

      If I only use WhiteSpace and no TAB characters at all, then of course I do not have the problem.

      But I already have got million lines of code, which are NOT WhiteSpace only. These code lines use a mixture of TAB (interpreted with a fixed tab stop size of 8) and WhiteSpace (to generate "half" tab stops).

      I do not want to change these million lines of code to WhiteSpace only, just because the auto indenter of jEdit has a different idea how to indent when "tab width" != "indent width".


      [patches:#583]https://sourceforge.net/p/jedit/patches/583/ change auto indent behavior when indent width != tab width

      Status: open
      Group:
      Labels: auto-indent
      Created: Mon Apr 04, 2016 06:08 PM UTC by lundril
      Last Updated: Thu Apr 07, 2016 06:21 PM UTC
      Owner: nobody
      Attachments:

      With the current jedit trunk (and also the previous jedit 5.2.0 release) I
      get the following behavior when using auto-indent == full and
      tab width != indent width.
      Here is an example with tab width == 8 and indent width == 4.
      t_ marks tab, _ marks a whitespace.

      int myfunc(int a)

      {

      ____if (a==5) {

      ____t_ printf("Hello World\n");

      ____}

      }

      But I would like to get (and I think this is also more correct):

      int myfunc(int a)

      {

      ____if (a==5) {

      t_ printf("Hello World\n");

      ____}

      }

      So basically I want that the "printf" line simply uses one TAB and not a
      combination of 4 SPACEs + one TAB.

      The reason why I think this is more correct is, that when indenting the
      whole function with "shift-TAB", then the indentation will be as in the
      second example.


      Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/jedit/patches/583/

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

       

      Related

      Patches: #583

      • Dale Anson

        Dale Anson - 2016-04-07

        "Mixing them within a file is BAD, and the person(s) who did it should be
        whipped senseless with a copy of the coding guidelines. ;-)"

        +1

        On Thu, Apr 7, 2016 at 12:43 PM, Steve snarum-micron@users.sf.net wrote:

        I understand that. I had a bit of a fight with my last design team when I
        "fixed" 200+ files that people had checked in with a mixture of tab and
        space indenting. Ultimately, mixing them within a project is painful.
        Mixing them within a file is BAD, and the person(s) who did it should be
        whipped senseless with a copy of the coding guidelines. ;-)

        Steve

        -

        From: lundril [mailto:lundril@users.sf.net]
        Sent: Thursday, April 07, 2016 12:24 PM
        To: [jedit:patches]
        Subject: [jedit:patches] #583 change auto indent behavior when indent
        width != tab width

        @Steve:

        If I only use WhiteSpace and no TAB characters at all, then of course I do
        not have the problem.

        But I already have got million lines of code, which are NOT WhiteSpace
        only. These code lines use a mixture of TAB (interpreted with a fixed tab
        stop size of 8) and WhiteSpace (to generate "half" tab stops).

        I do not want to change these million lines of code to WhiteSpace only,
        just because the auto indenter of jEdit has a different idea how to indent
        when "tab width" != "indent width".


        [patches:#583] https://sourceforge.net/p/jedit/patches/583/
        https://sourceforge.net/p/jedit/patches/583/ change auto indent behavior
        when indent width != tab width

        Status: open
        Group:
        Labels: auto-indent
        Created: Mon Apr 04, 2016 06:08 PM UTC by lundril
        Last Updated: Thu Apr 07, 2016 06:21 PM UTC
        Owner: nobody
        Attachments:

        With the current jedit trunk (and also the previous jedit 5.2.0 release) I
        get the following behavior when using auto-indent == full and
        tab width != indent width.
        Here is an example with tab width == 8 and indent width == 4.
        t_ marks tab, _ marks a whitespace.

        int myfunc(int a)

        {

        ____if (a==5) {

        ____t_ printf("Hello World\n");

        ____}

        }

        But I would like to get (and I think this is also more correct):

        int myfunc(int a)

        {

        ____if (a==5) {

        t_ printf("Hello World\n");

        ____}

        }

        So basically I want that the "printf" line simply uses one TAB and not a
        combination of 4 SPACEs + one TAB.

        The reason why I think this is more correct is, that when indenting the
        whole function with "shift-TAB", then the indentation will be as in the
        second example.


        Sent from sourceforge.net because you indicated interest in
        https://sourceforge.net/p/jedit/patches/583/

        To unsubscribe from further messages, please visit
        https://sourceforge.net/auth/subscriptions/


        Status: open
        Group:
        Labels: auto-indent
        Created: Mon Apr 04, 2016 06:08 PM UTC by lundril
        Last Updated: Thu Apr 07, 2016 06:37 PM UTC
        Owner: nobody
        Attachments:

        With the current jedit trunk (and also the previous jedit 5.2.0 release) I
        get the following behavior when using auto-indent == full and
        tab width != indent width.
        Here is an example with tab width == 8 and indent width == 4.
        t_ marks tab, _ marks a whitespace.

        int myfunc(int a)
        {
        _if (a==5) {
        t printf("Hello World\n");
        ____}
        }

        But I would like to get (and I think this is also more correct):

        int myfunc(int a)
        {
        if (a==5) {
        t
        printf("Hello World\n");
        _}
        }

        So basically I want that the "printf" line simply uses one TAB and not a
        combination of 4 SPACEs + one TAB.

        The reason why I think this is more correct is, that when indenting the
        whole function with "shift-TAB", then the indentation will be as in the
        second example.


        Sent from sourceforge.net because you indicated interest in
        https://sourceforge.net/p/jedit/patches/583/

        To unsubscribe from further messages, please visit
        https://sourceforge.net/auth/subscriptions/

         

        Related

        Patches: #583

      • lundril

        lundril - 2016-04-11

        Mixing them within a file is BAD, and the person(s) who did it
        should be whipped senseless with a copy of the coding guidelines. ;-)

        Why I myself agree, just note that it only is BAD, if people cannot agree on how TABs/SPACEs are mixed.

        If you agree that a TAB must be interpreted with tab width == 8 and that TABs are not allowed after the first SPACE, then this works quite fine.

        So I think using TABs+SPACEs requires to be more attentive when editing code, but that's it.

         
  • lundril

    lundril - 2016-04-07

    Note to myself and for discussion:

    Maybe it's better to change the patch I proposed to only do this if "tab width" != "indent width" and "soft tabs" are disabled (which means you need a mixture of TABs + WhiteSpace). This is the only case where there is trouble with the current behavior (and it's also probably a case which only a very few people have, thus nobody complained until now...)

    Other option: Only modify the case where indentation is increased...

     
  • lundril

    lundril - 2016-04-13

    Ok here is another try.

    This patch will keep more of the previous line.
    Meaning: If you have this code fragment: (_ == space, t_ == TAB)

    int func1(int a)
    {
    ____if (a>=5) {
    ____t_  printf("manually inserted leading whitespace chars\n");
    ____t_  if (a>=10) {
    

    Then the auto indenter will now extend the code like this:

    int func1(int a)
    {
    ____if (a>=5) {
    ____t_  printf("manually inserted leading whitespace chars\n");
    ____t_  if (a>=10) {
    ____t_  ____printf("keeps funny whitespace now\n");
    ____t_  ____if (a>=100) {
    ____t_  t_      printf("but continues with TABs\n");
    ____t_  ____}
    ____t_  }
    ____}
    }
    

    I still really would like to see this kind of auto indenter change in jEdit.

    Right now the behavior of selecting a block of code and hitting "shift-TAB" is inconsistent with what the auto indenter does (and I think the "shift-TAB" behavior is correct...)

     
  • Alan Ezust

    Alan Ezust - 2017-03-26
    • assigned_to: Alan Ezust
    • Group: -->
     

Log in to post a comment.