oleg-shilo / sublime-codemap

CodeMap - is a ST3 plugin for showing the code tree representing the code structure of the active view/document
MIT License
41 stars 4 forks source link

Functions in a python class are not indented in the CodeMap interface if tabs are used to indent #24

Closed lcorcodilos closed 2 months ago

lcorcodilos commented 6 years ago

Thanks for the tool! It's been very useful in organizing and understanding other people's code.

I've been working with with two very similar scripts in python but written by different people and noticed that CodeMap was treating them differently. They each have identical lines:

class ClassName():
    def __init__(self,...):
        ...
    def func1(self,...):
        ...

But one person indented using spaces and one with tabs. If the indentations are spaces, CodeMap displays:

class ClassName()   :##
    def __init__()  :##
    def func1()     :##
    ....

But if the indentations are tabs, CodeMap displays:

class ClassName()   :##
def __init__()      :##
def func1()         :##
....

It's very minor but is this something that could be fixed? Thanks again for the hard work!

oleg-shilo commented 6 years ago

Thank you. Fixed in the latest v1.013.0 release

Acecool commented 6 years ago

Here's what I'm using for XCodeMapper ( Dev name ) to detect the type of indentation a file is using.

        ## For Each Line...
        for _line_number, _line in enumerate( _lines, 1 ):
            ##
            _code = _line.strip( )
            _code_search = _code
            _code_lstrip = _line.lstrip( )
            _code_rstrip = _line.rstrip( )

            ## Grab the difference between a left-stripped bit of code and non-stripped to count how many spaces or tabs there are...
            _depth = len( _line ) - len( _code_lstrip )

            ## Determine Indentation Character Type and Quantity - if tabs, then set indent-length to the value to 1 so no division occurs - if spaces are used then set to number of spaces used so we can use that to divide to ensure accurate indentation occurs..
            ## If they're using spaces, we divide _depth by the tabs-to-spaces value ( default 4 - however if they're using 2 spaces per indent we catch and log it by setting a value the FIRST time indents are seen )
            if ( _depth > 0 and self.GetIndentLength( ) == 0 ):
                ## Grab the indent chars
                _indent_chars = Acecool.string.Strip( _line, _depth, len( _line ) - 1 )

                ## Debugging...
                self.print( 'Indentation', ' >> Depth: ' + str( _depth ) + ' / using chars: "' + _indent_chars + '"' )

                ## Determine if spaces are used to indent the file
                if ( _indent_chars == Acecool.string.repeat( ' ', _depth ) ):
                    print( ' >> Syntax > Indentation > Using ' + str( _depth ) + '  spaces per Indentation!' )
                    self.SetIndentLength( _depth )
                ## Determine if Tabs are used to indent the file
                elif ( _indent_chars == Acecool.string.repeat( '    ', _depth ) ):
                    print( ' >> Syntax > Indentation > Using ' + str( _depth ) + ' tabs per indentation!' )
                    self.SetIndentLength( _depth )

            ## If IndentLength has been set, and it is over 0, then use it to divide...
            if ( self.GetIndentLength( ) > 0 ):
                ## Set the depth by using the depth provided and dividing by the number of spaces, if spaces are used for indentation, or by 1 for tabs ie nothing...
                self.SetDepth( int( _depth / self.GetIndentLength( ) ) )
            else:
                self.SetDepth( _depth )

I could've used SubStr to grab the first few chars - Strip does the same thing except instead of grabbing it cuts out... Acecool.string.repeat is a simple helper to repeat chars per - the 2 ifs are using one space and one tab to then check which type is used...

IndentLength is set to 0 by default and once set the logic doesn't run again - if I wanted to support dual indent-typed files - I'd have to remove the IndentLength == 0 and have another accessor to log the first size for tabs or spaces, and then log the first of the other and then check to see if something shorter is ever used....

SetDepth is a helper function because of a lot of callback functions it can be used in... GetIndentLength is to set how many spaces are used ( 2, 4, 8 are the typical values ) - I don't have support for dual-char indented files ( python supports it, but to me it looks ugly - I also prefer tabs because the file size can increase by hundreds of KB for a file that is only a few thousand lines if you use spaces to indent )..

I use an indent config var to determine how to indent in the panel:

## CFG_INDENT_CHARS                             = '\t'
CFG_INDENT_CHARS                                = '    '

I use spaces for indentation in output so I can copy / paste code, or examples, in Steam as Steam doesn't like tabs. But anything can be used from that point...

Either way, I figured this may be helpful to your integration of support... This is going to be in my next version as right now, space tabbed files end up being indented numerous times... I'm also adding in better support for the class function table and children displays...