예제 #1
0
def get_popup_actions(view):
    data = build_comment_data(view, view.size())
    comment_message = ""

    if not data[0] and not data[1]:
        comment_message = '<p style="font-size: 10px; color: #FFBF00; margin: 0 0 10px 0; padding: 0">ⓘ You must select/install proper syntax in order to add ignore comments.</p>'

    return """
    <div style="display: block; padding: 20px 25px 0">
      {}
      {}
      {}
    </div>

    """.format(
        comment_message,
        get_popup_action("line", "Ignore for line", bool(comment_message)),
        get_popup_action("file", "Ignore for file", bool(comment_message)),
    )
예제 #2
0
def insert_new_line_with_comment(view, edit, point, type, id, target):
    data = build_comment_data(view, target.begin())
    indent = re.findall(r"^\s*", view.substr(view.full_line(point)))[0]
    if data[0]:
        snip = "{0}{1}{2}".format(indent, data[0][0][0], get_ignore_text(type, id))
    elif data[1]:
        snip = "{0}{1} {2} {3}".format(
            indent, data[1][0][0], get_ignore_text(type, id), data[1][0][1]
        )
    view.insert(edit, target.begin(), snip)
    view.sel().clear()
    view.sel().add(
        view.find(
            "<please specify a reason of ignoring this>",
            target.begin(),
            sublime.IGNORECASE,
        )
    )
    update_highlighted_region(view, point, with_new_line=True)
예제 #3
0
    def run(self, edit, width=0, keep_selection=False):
        # use the narrowest ruler from the view if no width specified, or default to 72 if no rulers are enabled
        width = width or next(iter(self.view.settings().get('rulers', [])), 72)
        # determine the indentation style used in the view
        use_spaces = self.view.settings().get('translate_tabs_to_spaces',
                                              False)
        tab_size = self.view.settings().get('tab_size', 4)
        one_level = ' ' * tab_size if use_spaces else '\t'

        # make sure the entire line is selected for each selection region
        # - `remove_line_comment` needs the region to be at the start of the line
        # - `dedent` needs it in order to see what indentation all lines have in common
        # but first, ensure we follow the Principal of Least Surprise by not expanding the selection to lines where only column 0 is selected
        # - related reading: https://forum.sublimetext.com/t/next-line-is-included-when-sorting-a-multi-line-selection/30580
        self.view.run_command('deselect_trailing_newlines')
        if any(sel for sel in self.view.sel() if not sel.empty()):
            self.view.run_command('expand_selection', {'to': 'line'})
        else:
            self.view.run_command('expand_selection_to_paragraph')

        new_sel = list()
        sel_comment_data = list()

        # loop through the selections in reverse order so that the selection positions don't move when the selected text changes size
        for sel in reversed(self.view.sel()):
            # if the selection contains any single line comments, toggle the comments off
            # so the comment tokens won't get wrapped into the middle of the line - we'll reapply them later
            # note the selector doesn't just use `comment.line punctuation.definition.comment`, because C# line documentation comments are scoped as `comment.block.documentation.cs punctuation.definition.comment.documentation.cs`
            comment_punctuation = list(
                find_regions_matching_selector(
                    self.view, sel,
                    'comment punctuation.definition.comment - punctuation.definition.comment.begin - punctuation.definition.comment.end'
                ))
            sel_comment_data.append(
                self.view.substr(comment_punctuation[0]) +
                ' ' if any(comment_punctuation) else None)
            for punctuation in reversed(comment_punctuation):
                # also remove any space after the comment line punctuation, else the `indentation_level` API can return the wrong result...
                if self.view.substr(punctuation.end()) == ' ':
                    punctuation = punctuation.cover(
                        sublime.Region(punctuation.end(),
                                       punctuation.end() + len(' ')))
                self.view.erase(edit, punctuation)

        # loop through the selections in reverse order so that the selection positions don't move when the selected text changes size
        for sel, line_comment in zip(reversed(self.view.sel()),
                                     sel_comment_data):
            # determine how much indentation is at the first selected line
            indentation_level = self.view.indentation_level(sel.begin())
            indentation = one_level * indentation_level

            if line_comment:  # if line comments were removed earlier
                comment_data = build_comment_data(self.view, sel.begin())
                # find the line comment that corresponds to the comment punctuation used, and check if indentation is disabled for it or not
                disable_indent = next(
                    (data[1]
                     for data in comment_data if isinstance(data, tuple)
                     and data[0].strip() == line_comment), False)
                # apply the line comment token as part of the indentation so the text wrapper will re-comment the text for us
                if disable_indent:  # if the line comment token has DISABLE_INDENT set
                    indentation = line_comment + indentation  # apply the indentation after the line comment token
                else:
                    indentation += line_comment  # apply the indentation before the line comment token

            # create a text wrapper that will keep the existing indentation level
            wrapper = textwrap.TextWrapper(
                drop_whitespace=True,
                width=width - (
                    0 if use_spaces else (tab_size - 1) * indentation_level
                ),  # if hard tab characters are used, then we need to pretend the max width is smaller, because here Python counts a tab as a single char. Easier to just not use tabs, people!
                initial_indent=indentation,
                subsequent_indent=indentation,
                expand_tabs=False,
                replace_whitespace=True,
            )
            # unindent the selected text, before then reformatting said text to fill the available (column) space
            # do it on a paragraph by paragraph basis so we don't lose blank line gaps
            text = ''
            for paragraph in textwrap.dedent(
                    self.view.substr(sel)).split('\n\n'):
                if text != '':
                    text += '\n\n'
                text += wrapper.fill(paragraph)

            # replace the selected text with the re-wrapped text
            self.view.replace(edit, sel, text + '\n')
            # resize the selection to match the new wrapped text size - or move it to the end of the wrapped text
            end_pos = sel.begin() + len(text)
            start_pos = sel.begin() if keep_selection else end_pos
            new_sel.append(sublime.Region(start_pos, end_pos))
        self.view.sel().clear()
        self.view.sel().add_all(new_sel)
예제 #4
0
 def _determine_comment_style(self):
     # I'm not exactly sure why this function needs a point.  It seems to
     # return the same value regardless of location for the stuff I've
     # tried.
     (self._lc, self._bc) = comment.build_comment_data(self.view, 0)
예제 #5
0
 def _determine_comment_style(self):
     # I'm not exactly sure why this function needs a point.  It seems to
     # return the same value regardless of location for the stuff I've
     # tried.
     (self._lc, self._bc) = comment.build_comment_data(self.view, 0)
예제 #6
0
 def run(self, edit, width=0):
     # use the narrowest ruler from the view if no width specified, or default to 72 if no rulers are enabled
     width = width or next(iter(self.view.settings().get('rulers', [])), 72)
     # determine the indentation style used in the view
     use_spaces = self.view.settings().get('translate_tabs_to_spaces', False)
     tab_size = self.view.settings().get('tab_size', 4)
     one_level = ' ' * tab_size if use_spaces else '\t'
     
     # make sure the entire line is selected for each selection region
     # - `remove_line_comment` needs the region to be at the start of the line
     # - `dedent` needs it in order to see what indentation all lines have in common
     # but first, ensure we follow the Principal of Least Surprise by not expanding the selection to lines where only column 0 is selected
     # - related reading: https://forum.sublimetext.com/t/next-line-is-included-when-sorting-a-multi-line-selection/30580
     self.view.run_command('deselect_trailing_newlines')
     self.view.run_command('expand_selection', { 'to': 'line' })
     
     new_sel = list()
     sel_comment_data = list()
     
     # loop through the selections in reverse order so that the selection positions don't move when the selected text changes size
     for sel in reversed(self.view.sel()):
         # if the selection contains any single line comments, toggle the comments off
         # so the comment tokens won't get wrapped into the middle of the line - we'll reapply them later
         comment_data = build_comment_data(self.view, sel.begin())
         sel_comment_data.append(comment_data if ToggleCommentCommand.remove_line_comment(None, self.view, edit, comment_data, sel) else None)
     
     # loop through the selections in reverse order so that the selection positions don't move when the selected text changes size
     for sel, comment_data in zip(reversed(self.view.sel()), sel_comment_data):
         # determine how much indentation is at the first selected line
         indentation_level = self.view.indentation_level(sel.begin())
         indentation = one_level * indentation_level
         if comment_data: # if line comments were removed earlier
             line_comments, block_comments = comment_data
             # apply the line comment token as part of the indentation so the text wrapper will re-comment the text for us
             if any(line_comments): # if there is at least one line comment token defined
                 line_comment = line_comments[0] # if there are multiple such line comment tokens we will use the first one
                 if line_comment[1]: # if the line comment token has DISABLE_INDENT set
                     indentation = line_comment[0] + indentation # apply the indentation after the line comment token
                 else:
                     indentation += line_comment[0] # apply the indentation before the line comment token
         
         # create a text wrapper that will keep the existing indentation level
         wrapper = textwrap.TextWrapper(
             drop_whitespace=True,
             width=width - (0 if use_spaces else (tab_size - 1) * indentation_level), # if hard tab characters are used, then we need to pretend the max width is smaller, because here Python counts a tab as a single char. Easier to just not use tabs, people!
             initial_indent=indentation,
             subsequent_indent=indentation,
             expand_tabs=False,
             replace_whitespace=True,
         )
         # unindent the selected text, before then reformatting said text to fill the available (column) space
         # do it on a paragraph by paragraph basis so we don't lose blank line gaps
         text = ''
         for paragraph in textwrap.dedent(self.view.substr(sel)).split('\n\n'):
             if text != '':
                 text += '\n\n'
             text += wrapper.fill(paragraph)
         
         # replace the selected text with the re-wrapped text
         self.view.replace(edit, sel, text + '\n')
         # resize the selection to match the new wrapped text size
         new_sel.append(sublime.Region(sel.begin(), sel.begin() + len(text)))
     self.view.sel().clear()
     self.view.sel().add_all(new_sel)