Search code examples
pycharmcommentsappearance

Removing ragged lines in (Python) comments


PyCharm can can wrap code lines that are longer than some number n(=67 for this example), e.g.

# this is a really really really really really really really really really really really really really really long comment

becomes

# this is a really really really really really really really really
# really really really really really really long comment

**Is there a "converse" functionality?* Often, because of adding and removing ideas from comments, they that end up looking really bad and ragged like this:

# this is a the first idea.
# more bla bla, but still relating to first idea. bla bla.
# other bla bla.
# second brilliant idea. oh no, actually it breaks something, so watch out!

I would like Pycharm (potentially by incorporating plugins) to be able to reformat these comments (filling the maximum line length) to look like this:

# this is a the first idea. more bla bla, but still relating to first 
# idea. bla bla. other bla bla. second brilliant idea. oh no, actually
# it breaks something, so watch out!

If Pycharm doesn't have this, do you know of a textprocessor that can do this?


Solution

  • This cannot be done in pycharm by default. There is no such plugin available. You can see the answer in a similar thread

    Wrapping comments with line breaks in PyCharm

    Now your below options to consider

    • Write something in sed or awk, but then this wont work on windows directly
    • Write a plugin for PyCharm. This has a huge learning curve and too much effort
    • Write a script to do what you want

    I would choose the last option as it is the fastest possible solution in terms of effort. You can choose the language you want, I choose Python, since we know Python will be present when formatting the Python file for use in Pycharm.

    So the idea of the script is to merge continuous comment, and then wrap them based on the column width

    # this is a test
    # this is a best.
    # This could be even worst when this is not even good.
    # Why should one do it using whatever they have done
    import io, re
    from textwrap import TextWrapper
    
    import os
    
    current_file = __file__
    
    f = io.open(current_file, 'r')
    comment_pattern = re.compile(r"^(\s*)#(.*)")
    
    in_comment = False
    
    
    def spit_formatted_comments(initial_space, current_comment):
        if current_comment:
            wrapper = TextWrapper(initial_indent=initial_space + "#",
                                  subsequent_indent=initial_space + "# ")
    
            wrapper.width = 80
            data = wrapper.wrap(" ".join(current_comment))
            print(os.linesep.join(data))
    
    
    for line in f:
        match = comment_pattern.findall(line)
    
        if match:
            if not in_comment:
                in_comment = True
                current_comment = []
                initial_space = match[0][0]
    
            current_comment.append(match[0][1])
        elif in_comment:
            in_comment = False
            spit_formatted_comments(initial_space, current_comment)
            current_comment = []
            print(line, end='')
        else:
            print(line, end='')
    
    spit_formatted_comments(initial_space, current_comment)
    
    f.close()
    # this is a last line comment to check border
    

    The output of the same is

    # this is a test  this is a best.  This could be even worst when this is not
    # even good.  Why should one do it using whatever they have done
    import io, re
    from textwrap import TextWrapper
    
    import os
    
    current_file = __file__
    
    f = io.open(current_file, 'r')
    comment_pattern = re.compile(r"^(\s*)#(.*)")
    
    in_comment = False
    
    
    def spit_formatted_comments(initial_space, current_comment):
        if current_comment:
            wrapper = TextWrapper(initial_indent=initial_space + "#",
                                  subsequent_indent=initial_space + "# ")
    
            wrapper.width = 80
            data = wrapper.wrap(" ".join(current_comment))
            print(os.linesep.join(data))
    
    
    for line in f:
        match = comment_pattern.findall(line)
    
        if match:
            if not in_comment:
                in_comment = True
                current_comment = []
                initial_space = match[0][0]
    
            current_comment.append(match[0][1])
        elif in_comment:
            in_comment = False
            spit_formatted_comments(initial_space, current_comment)
            current_comment = []
            print(line, end='')
        else:
            print(line, end='')
    
    spit_formatted_comments(initial_space, current_comment)
    
    f.close()
    # this is a last line comment to check border