[Python] Edit > Block Comment doesn't use triple double-quotes
-
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.
-
@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 >>>
-
@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 thecommentLine="#"
in that line, addcommentStart=""""" commentEnd="""""
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. :-(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:
-
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
-
@Alan-Kilborn Thank you. Too bad because I like it better to comment a block.
-
@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)… -
@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 thelangs.xml
to allow you to use the block-comment feature in Notepad++ to do that wrapping. -
@PeterJones said:
edit
%AppData%\Notepad++\langs.xml
: go to the<Language name="python"
… line; after thecommentLine="#"
in that line, addcommentStart=""""" commentEnd="""""
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; {three}START-BC '.format(three=quot3) 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:
Since we’ve already selected (partially, but wholly works too) these lines, we just run the script to obtain:
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 anif
,elif
orelse
into a comment.Now let’s remove it; place the caret here for example (it could be placed anywhere on line 85):
and run the script again to be back to where we started:
-