• Login
Community
  • Login

[Python] Edit > Block Comment doesn't use triple double-quotes

Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
9 Posts 3 Posters 998 Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S
    Shohreh
    last edited by Dec 17, 2024, 4:37 PM

    Hell,

    After selecting a block of code and hitting Edit > Comment/Uncomment > Block Comment, I expected N++ to use the “triple double-quote” syntax, but instead, if prepends each line with a pound sign:

    """
    some
    block
    comment
    """
    

    Do I need to edit N++'s configuration?

    Thank you.

    860dde93-955d-46ab-b279-c9904c2daf4e-image.png

    P 2 Replies Last reply Dec 17, 2024, 5:52 PM Reply Quote 0
    • P
      PeterJones @Shohreh
      last edited by PeterJones Dec 17, 2024, 6:12 PM Dec 17, 2024, 5:52 PM

      @Shohreh said in [Python] Edit > Block Comment doesn't use triple double-quotes:

      Do I need to edit N++'s configuration?

      Right now, there is no way in native Notepad++ to change a configuration for what gets used for the block comment action for a given language. (And I don’t know of a plugin that will; I cannot even think of a way with the PythonScript or other scripting plugin to change the native behavior. Sorry. Obviously, with the PythonScript plugin, one could define a separate command, and give it a keyboard shortcut, to insert the “”" before and after the selected text, which might be sufficient for you)

      And technically, that syntax is “docstring” syntax in Python, not actually a comment, though many people use it as such. But I have run across when trying to put psuedo-unicode escapes \uVWXYZ that go outside of the range that it likes, and when I put it in a docstring instead of a comment, the python parser complained about invalid unicode character, because it’s actually interpreting that section as a string internally, rather than just ignoring commented text, so I had to change from using a docstring to using individual comments. Thus, my “and technically” isn’t just me being pedantic; it has real implications that have influenced me and made me change my code in the past:

      c:> python
      Python 3.12.0 (tags/v3.12.0:0fb18b0, Oct  2 2023, 13:03:39) [MSC v.1935 64 bit (AMD64)] on win32
      Type "help", "copyright", "credits" or "license" for more information.
      >>> # \u+2611other
      >>> """
      ... \u+2611other
      ... """
        File "<stdin>", line 1
          """
          ^^
      SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 1-2: truncated \uXXXX escape
      >>>
      
      1 Reply Last reply Reply Quote 1
      • P
        PeterJones @Shohreh
        last edited by PeterJones Dec 17, 2024, 6:33 PM Dec 17, 2024, 6:17 PM

        @Shohreh ,

        Right now, there is no way in native Notepad++ to change a configuration for what gets used for the block comment action for a given language.

        Well, I was wrong (hence, I crossed it out). I started peeking into the source code to see how block comments were implemented, and got a hint that led me to a solution:

        Following the User Manual’s advice for editing Notepad++ config files , edit %AppData%\Notepad++\langs.xml: go to the <Language name="python" ... line; after the commentLine="#" in that line, add commentStart="&quot;&quot;&quot;" commentEnd="&quot;&quot;&quot;" and save; exit Notepad++ and restart, and now when you use Block Comment, it will use the triple-quote as the start and end.

        I had forgotten that was defined in the langs.xml file. Sorry for the original misinformation.

        —
        update: D’OH! It’s even implied in the User Manual already, so I really should have known/remembered it. :-(

        b3f36bb4-4b4a-466c-8e0e-63535dd7e06d-image.png

        I will, however, clarify the UM to make it 100% obvious which attributes apply to which.

        _update 2: coming soon to a User Manual near you:

        e2c8e5e2-47d5-4366-a3aa-feaa63cf9ce8-image.png

        1 Reply Last reply Reply Quote 3
        • A
          Alan Kilborn
          last edited by Dec 17, 2024, 6:46 PM

          In addition to what @PeterJones said:

          • triple-quoted strings are NOT comments (this is just to reinforce what Peter already said, for emphasis!)
          • if you ever have any \ in the line(s) you are trying to use this method of “commenting” on, you will very likely run into trouble (Python 3 will give you errors when you run your code) – you’d have better luck with a raw triple-quoted string, i.e., r"""I am a comment"""
          • indentation must be correct for this – you can’t, in a block of code that is indented, start one of these ‘comments’ at an arbitrary indentation level – it must match the indentation level of the surrounding lines of code
          S 1 Reply Last reply Dec 19, 2024, 1:47 PM Reply Quote 5
          • S
            Shohreh @Alan Kilborn
            last edited by Dec 19, 2024, 1:47 PM

            @Alan-Kilborn Thank you. Too bad because I like it better to comment a block.

            A P 2 Replies Last reply Dec 19, 2024, 2:39 PM Reply Quote 0
            • A
              Alan Kilborn @Shohreh
              last edited by Dec 19, 2024, 2:39 PM

              @Shohreh said in [Python] Edit > Block Comment doesn't use triple double-quotes:

              I like it better to comment a block.

              Well, that’s fine; you can certainly make use of it.
              My main point was to point out further caveats for its usage (in addition to what Peter said).

              BTW, I tried Peter’s advice for changing langs.xml, and the advice is sound as to the “how to”, but the result for Python is lacking (not Peter’s fault)…

              1 Reply Last reply Reply Quote 0
              • P
                PeterJones @Shohreh
                last edited by Dec 19, 2024, 2:40 PM

                @Shohreh said in [Python] Edit > Block Comment doesn't use triple double-quotes:

                Too bad because I like it better to comment a block.

                If you want, you can use the docstring for pseudo-comments – many python programmers do – but you just have to understand that the Python interpreter treats them differently than a # comment, so you have to maintain valid string syntax in any block of text that you put between """ markers; if you are willing to accept that limitation, then feel free to use docstrings for comments – and feel free to update the langs.xml to allow you to use the block-comment feature in Notepad++ to do that wrapping.

                A 1 Reply Last reply Dec 23, 2024, 12:59 PM Reply Quote 2
                • A
                  Alan Kilborn @PeterJones
                  last edited by PeterJones Jan 2, 2025, 8:19 PM Dec 23, 2024, 12:59 PM

                  @PeterJones said:

                  edit %AppData%\Notepad++\langs.xml: go to the <Language name="python" … line; after the commentLine="#" in that line, add commentStart="&quot;&quot;&quot;" commentEnd="&quot;&quot;&quot;"

                  feel free to update the langs.xml to allow you to use the block-comment feature in Notepad++ to do that wrapping.

                  The basic problem with that…as I alluded to before when I said:

                  …but the result for Python is lacking

                  …is that it often gives an unsatisfying result. For instance, click and drag in the line number margin to select some lines, and then invoke Block Comment. When I do this, I don’t even obtain code that is syntactically correct. I could hand-adjust it to be correct, but…yuck.

                  Much better would be a script that would toggle these triple-quoted string “comments”.


                  Here’s a script I call PythonBlockCommentToggle.py:

                  # -*- coding: utf-8 -*-
                  from __future__ import print_function  # Python2 vestige!
                  
                  #########################################
                  #
                  #  PythonBlockCommentToggle (PBCT)
                  #
                  #########################################
                  
                  # note:
                  #  This script was developed and tested under Python3 64-bit on unicode (non-ANSI) encoded data.
                  #  It may work as-is using Python2 and/or ANSI-encoded data and/or 32-bits, but that would be incidental.
                  
                  # references:
                  #  https://community.notepad-plus-plus.org/topic/26463/python-edit-block-comment-doesn-t-use-triple-double-quotes
                  #  for newbie info on PythonScripts, see https://community.notepad-plus-plus.org/topic/23039/faq-desk-how-to-install-and-run-a-script-in-pythonscript
                  
                  #-------------------------------------------------------------------------------
                  
                  from Npp import *
                  
                  #-------------------------------------------------------------------------------
                  
                  def lines_touched_by_single_stream_selection():
                      retval = ()
                      rect_sel_mode = editor.getSelectionMode() in [ SELECTIONMODE.RECTANGLE, SELECTIONMODE.THIN ]
                      if rect_sel_mode or editor.getSelections() > 1 or editor.getSelectionEmpty() or len(editor.getSelText()) == 0: return retval
                      sel_start_pos = editor.getSelectionStart()
                      sel_end_pos = editor.getSelectionEnd()
                      line_start = editor.lineFromPosition(sel_start_pos)
                      line_end = editor.lineFromPosition(sel_end_pos)
                      # if caret at end of selection is selecting nothing on the caret's line, don't consider that line as part of the selection:
                      if sel_end_pos == editor.positionFromLine(line_end): line_end -= 1
                      # if very last line of file is somehow part of the selection, don't consider that line as part of the selection if there is nothing on it:
                      elif editor.lineLength(line_end) == 0: line_end -= 1  # note: the last line of a file is the only one that can possibly have length of 0
                      retval = (line_start, line_end)
                      return retval
                  
                  #-------------------------------------------------------------------------------
                  
                  class PBCT(object):
                  
                      def __init__(self):
                  
                          if notepad.getLangType() != LANGTYPE.PYTHON: return
                  
                          quot3 = '"' * 3
                          quot3_comment_start = 'pass; r{three}START-BC '.format(three=quot3)  # moderator fixed
                          quot3_comment_end = ' END-BC{three}'.format(three=quot3)
                          apos3 = "'" * 3
                          apos3_comment_start = quot3_comment_start.replace(quot3, apos3)
                          apos3_comment_end = quot3_comment_end.replace(quot3, apos3)
                  
                          line_span_tup = lines_touched_by_single_stream_selection()
                  
                          if len(line_span_tup) == 0:
                  
                              curr_pos = editor.getCurrentPos()
                              first_line = editor.lineFromPosition(curr_pos)
                              start_line_p1 = editor.getLineIndentPosition(first_line)
                              start_line_p2 = editor.getLineEndPosition(first_line)
                              didnt_do_anything = True
                              end_comment = quot3_comment_end
                              find_result_tup = editor.findText(FINDOPTION.MATCHCASE, start_line_p1, start_line_p2, quot3_comment_start)
                              if find_result_tup is None:
                                  end_comment = apos3_comment_end
                                  find_result_tup = editor.findText(FINDOPTION.MATCHCASE, start_line_p1, start_line_p2, apos3_comment_start)
                              if find_result_tup is not None:
                                  (start_comment_p1, start_comment_p2) = find_result_tup
                                  if start_comment_p1 == start_line_p1:
                                      find_result_tup = editor.findText(FINDOPTION.MATCHCASE, start_comment_p2, editor.getLength(), end_comment)
                                      if find_result_tup is not None:
                                          (end_comment_p1, end_comment_p2) = find_result_tup
                                          editor.beginUndoAction()
                                          editor.deleteRange(end_comment_p1, end_comment_p2 - end_comment_p1)
                                          editor.deleteRange(start_comment_p1, start_comment_p2 - start_comment_p1)
                                          editor.endUndoAction()
                                          didnt_do_anything = False
                              if didnt_do_anything:
                                  self.mb('Make a stream selection to block-comment the lines of that selection; to remove later, '
                                      'run with no selection (i.e., just the caret) on FIRST line of the block-comment.')
                  
                          elif len(line_span_tup) >= 2:
                  
                              ( first_line, second_line ) = line_span_tup
                              start_line_p1 = editor.getLineIndentPosition(first_line)
                              start_line_p2 = editor.getLineEndPosition(second_line)
                              text_to_be_commented = editor.getTextRange(start_line_p1, start_line_p2)
                              if quot3 in text_to_be_commented and apos3 in text_to_be_commented:
                                  self.mb('Cannot turn the block of selected lines into a comment; a triple-quoted string is present in selected lines.')
                                  return
                              use_quot3 = quot3 not in text_to_be_commented
                              comment_start = quot3_comment_start if use_quot3 else apos3_comment_start
                              comment_end = quot3_comment_end if use_quot3 else apos3_comment_end
                              editor.beginUndoAction()
                              editor.insertText(start_line_p2, comment_end)
                              editor.insertText(start_line_p1, comment_start)
                              editor.endUndoAction()
                  
                      def mb(self, msg, flags=0, title=''):  # a message-box function
                          return notepad.messageBox(msg, title, flags)
                  
                  #-------------------------------------------------------------------------------
                  
                  if __name__ == '__main__': PBCT()
                  

                  How to use:

                  To comment lines:

                  • select (even partially) the lines you want to “comment out”
                  • run the script

                  To remove the commenting:

                  • put the caret (note: don’t select any text) on the FIRST line of the commented section
                  • run the script

                  Here is an example:

                  We want to “comment out” these lines:

                  0d21b935-f304-434b-9517-13b6d0f73430-image.png

                  Since we’ve already selected (partially, but wholly works too) these lines, we just run the script to obtain:

                  5eeba629-7f44-4e63-adfa-5a2bfee4dd3f-image.png

                  You can see the orange text is the comment, but what is the pass; text before it? Well, this keeps the code syntactically correct if you want to turn an entire indented block after an if, elif or else into a comment.

                  Now let’s remove it; place the caret here for example (it could be placed anywhere on line 85):

                  83fbca9a-a014-4cd4-acaa-554dfce2c19b-image.png

                  and run the script again to be back to where we started:

                  9820c254-028b-4f3b-a147-3e091318f45b-image.png

                  —
                  2025-01-02: moderator added the missing r per comment below, so that copy/paste of code would work right

                  A 1 Reply Last reply Jan 2, 2025, 8:15 PM Reply Quote 3
                  • A Alan Kilborn referenced this topic on Dec 23, 2024, 12:59 PM
                  • A
                    Alan Kilborn @Alan Kilborn
                    last edited by Alan Kilborn Jan 2, 2025, 8:31 PM Jan 2, 2025, 8:15 PM

                    In the script code, I accidentally left out the r I was preaching about earlier.

                    quot3_comment_start = 'pass; {three}START-BC '.format(three=quot3)

                    should be:

                    quot3_comment_start = 'pass; r{three}START-BC '.format(three=quot3)

                    See the r? I bolded it in the revised line of code. :-)


                    BTW, I added the START-BC (start block comment) and END-BC (end block comment) text in there so one can be sure that the triple quoted string stuff really IS temporarily commented out code. If you don’t want that, just remove the text of those strings from the source code for the script.

                    1 Reply Last reply Reply Quote 1
                    4 out of 9
                    • First post
                      4/9
                      Last post
                    The Community of users of the Notepad++ text editor.
                    Powered by NodeBB | Contributors