Add a setting for the default tabstop width.

Review Request #14361 — Created March 4, 2025 and submitted

Information

Review Board
release-7.x
839

Reviewers

One frequent request is to have the ability to show tabstops as
something other than 8 characters. When we first started getting this
request, the tab-size CSS rule was very poorly supported, and so there
wasn't much we could do. Many years later, it's been properly
implemented in all the browsers we care about, so it's well past time to
support this use case.

This change lays the framework for doing this, and implements the bare
minimum case of setting a global default for the tabstop size. This
involves several pieces:

  • A new extra dict has been added to the diff file context and plumbed
    through the diff viewer, views, and JS model.
  • A new setting for the default has been added to siteconfig and the
    DiffSettings object. The settings has been plumbed through a few
    more places in order to get it where it needs to go for this.
  • Plumb the diff settings/tab size through into the chunk and opcode
    generators, so that they will take it into account (for things like
    indentation change markers).
  • The DiffReviewableView will check if there's a tab_size key in the
    extra object, and use that to set the CSS for the file.

A natural future enhancement to this is to add an extension hook that
can modify the DiffSettings for an individual file, which will allow us
to build an extension that could do things like use .editorconfig files
in order to manage this on a per-path or per-file-type basis. It might
also be nice to give the user some kind of UI for changing the displayed
tabstop width for a file on the client side.

While in here, this fixes up a typo in the diff settings form, and the
diff settings form documentation.

  • Set the tabstop setting to various options (empty, 0, 4, 8, 12) and
    saw that it was properly reflected in the diff viewer for a change
    involving tabs.
  • Tested that indentation change markers worked correctly with different
    tabstop settings, including 1 and 2 characters (where the marker is
    truncated to fit in the space).
  • Ran unit tests.
Summary ID
Add a setting for the default tabstop width.
One frequent request is to have the ability to show tabstops as something other than 8 characters. When we first started getting this request, the `tab-size` CSS rule was very poorly supported, and so there wasn't much we could do. Many years later, it's been properly implemented in all the browsers we care about, so it's well past time to support this use case. This change lays the framework for doing this, and implements the bare minimum case of setting a global default for the tabstop size. This involves several pieces: - A new `extra` dict has been added to the diff file context and plumbed through the diff viewer, views, and JS model. - A new setting for the default has been added to siteconfig and the `DiffSettings` object. The settings has been plumbed through a few more places in order to get it where it needs to go for this. - Plumb the diff settings/tab size through into the chunk and opcode generators, so that they will take it into account (for things like indentation change markers). - The `DiffReviewableView` will check if there's a `tab_size` key in the `extra` object, and use that to set the CSS for the file. A natural future enhancement to this is to add an extension hook that can modify the DiffSettings for an individual file, which will allow us to build an extension that could do things like use `.editorconfig` files in order to manage this on a per-path or per-file-type basis. It might also be nice to give the user some kind of UI for changing the displayed tabstop width for a file on the client side. While in here, this fixes up a typo in the diff settings form, and the diff settings form documentation. Testing Done: - Set the tabstop setting to various options (empty, 0, 4, 8, 12) and saw that it was properly reflected in the diff viewer for a change involving tabs. - Tested that indentation change markers worked correctly with different tabstop settings, including 1 and 2 characters (where the marker is truncated to fit in the space). - Ran unit tests. Addresses bug 839.
a46adda8039b221464322c4c7749a42b45a43acf
Description From Last Updated

We should have documentation for this new setting in the /admin/configuration/diffviewer-settings/ docs page.

maubinmaubin

I think it'd be good to add a DiffSettingsTests unit test where you set the tab size to 0, and …

maubinmaubin

continuation line missing indentation or outdented Column: 5 Error code: E122

reviewbotreviewbot

missing whitespace around parameter equals Column: 51 Error code: E252

reviewbotreviewbot

missing whitespace around parameter equals Column: 52 Error code: E252

reviewbotreviewbot

I feel like we should set this default in reviewboard.admin.siteconfig. Add a diffviewer_default_tab_size entry there and set it to DiffOpcodeGenerator.TAB_SIZE, …

maubinmaubin

If we do set the default tab size in siteconfig, then we probably don't need to do this here? And …

maubinmaubin

Can you add a Version Added here.

maubinmaubin

Can you add a Version Added here.

maubinmaubin

Should be two blank lines between content and reference definitions.

chipx86chipx86

I think we can just make implementations plural. Also, missing a trailing period.

chipx86chipx86

Should probably use Sequence instead of list.

chipx86chipx86

Sequence here as well.

chipx86chipx86

Can you update this to use the standard typed function indentation form?

chipx86chipx86

I think this is missing Version Added.

chipx86chipx86

These should be the same import group.

chipx86chipx86

Thinking DiffSettings should define a DEFAULT_TAB_SIZE, and then we can reference this here and assign the others to alias that. …

chipx86chipx86

This could be one statement now.

chipx86chipx86

Should this be Mapping? Unless we mutate it later.

chipx86chipx86

We're missing **kwargs in the docs here.

chipx86chipx86

Might as well cut out the middle man and change this to DiffSettings.DEFAULT_TAB_SIZE now.

maubinmaubin

Same here and below.

maubinmaubin
There are no open issues
Checks run (1 failed, 1 succeeded)
flake8 failed.
JSHint passed.

flake8

david
maubin
  1. 
      
  2. Show all issues

    We should have documentation for this new setting in the /admin/configuration/diffviewer-settings/ docs page.

    1. Wow, that whole doc is pretty out of date. Will get it fixed up to match the modern form.

  3. Show all issues

    I think it'd be good to add a DiffSettingsTests unit test where you set the tab size to 0, and assert that it gets changed to None.

  4. Show all issues

    I feel like we should set this default in reviewboard.admin.siteconfig. Add a diffviewer_default_tab_size entry there and set it to DiffOpcodeGenerator.TAB_SIZE, so that we can expect there to be a default value in siteconfig if we're ever working with tab sizes outside of this class.

  5. reviewboard/diffviewer/chunk_generator.py (Diff revision 2)
     
     
     
    Show all issues

    If we do set the default tab size in siteconfig, then we probably don't need to do this here? And could maybe get rid of the TAB_SIZE attribute here altogether, so that we only have one default value to manage.

    1. We still want to handle blank/zero values. I'll move that into DiffSettings, though.

  6. reviewboard/diffviewer/settings.py (Diff revision 2)
     
     
    Show all issues

    Can you add a Version Added here.

  7. reviewboard/reviews/views/diffviewer.py (Diff revision 2)
     
     
     
    Show all issues

    Can you add a Version Added here.

  8. 
      
david
chipx86
  1. 
      
  2. Show all issues

    Should be two blank lines between content and reference definitions.

  3. Show all issues

    I think we can just make implementations plural.

    Also, missing a trailing period.

  4. reviewboard/diffviewer/chunk_generator.py (Diff revision 3)
     
     
     
    Show all issues

    Should probably use Sequence instead of list.

  5. Show all issues

    Sequence here as well.

  6. reviewboard/diffviewer/chunk_generator.py (Diff revision 3)
     
     
     
     
     
     
     
     
    Show all issues

    Can you update this to use the standard typed function indentation form?

  7. reviewboard/diffviewer/diffutils.py (Diff revision 3)
     
     
     
    Show all issues

    I think this is missing Version Added.

  8. reviewboard/diffviewer/opcode_generator.py (Diff revision 3)
     
     
     
     
     
    Show all issues

    These should be the same import group.

  9. reviewboard/diffviewer/settings.py (Diff revision 3)
     
     
     
     
     
    Show all issues

    Thinking DiffSettings should define a DEFAULT_TAB_SIZE, and then we can reference this here and assign the others to alias that. That way the default lives in one place and we don't have to lazily-import (I think?).

  10. reviewboard/diffviewer/views.py (Diff revision 3)
     
     
     
    Show all issues

    This could be one statement now.

  11. reviewboard/diffviewer/views.py (Diff revision 3)
     
     
    Show all issues

    Should this be Mapping? Unless we mutate it later.

  12. reviewboard/diffviewer/views.py (Diff revision 3)
     
     
    Show all issues

    We're missing **kwargs in the docs here.

  13. 
      
david
maubin
  1. 
      
  2. reviewboard/admin/siteconfig.py (Diff revision 4)
     
     
    Show all issues

    Might as well cut out the middle man and change this to DiffSettings.DEFAULT_TAB_SIZE now.

  3. Show all issues

    Same here and below.

  4. 
      
david
maubin
  1. Ship It!
  2. 
      
chipx86
  1. Ship It!
  2. 
      
david
Review request changed
Status:
Completed
Change Summary:
Pushed to release-7.x (16d0713)
Loading...