Edit Book: Add a "Smart Comment" tool to easily comment/uncomment text

Press Ctrl+` to trigger the tool, or add the tool to your toolbar via
Preferences->Toolbar->Tools for all editors

It will either insert comments around the selected text or uncomment an
existing comment if the cursor is inside one.
This commit is contained in:
Kovid Goyal 2015-11-04 10:16:52 +05:30
parent 32b00774da
commit 1bb87b7677
4 changed files with 55 additions and 1 deletions

View File

@ -56,7 +56,7 @@ d['global_tools_toolbar'] = [
'manage-fonts', 'smarten-punctuation', 'remove-unused-css', 'show-reports'
]
d['global_plugins_toolbar'] = []
d['editor_common_toolbar'] = [('editor-' + x) if x else None for x in ('undo', 'redo', None, 'cut', 'copy', 'paste')]
d['editor_common_toolbar'] = [('editor-' + x) if x else None for x in ('undo', 'redo', None, 'cut', 'copy', 'paste', 'smart-comment')]
d['editor_css_toolbar'] = ['pretty-current', 'insert-image']
d['editor_xml_toolbar'] = ['pretty-current', 'insert-tag']
d['editor_html_toolbar'] = ['fix-html-current', 'pretty-current', 'insert-image', 'insert-hyperlink', 'insert-tag', 'change-paragraph']

View File

@ -0,0 +1,45 @@
#!/usr/bin/env python2
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
from __future__ import (unicode_literals, division, absolute_import,
print_function)
from PyQt5.Qt import QTextCursor
opening_map = {
'css':'/*',
'html':'<!--',
'xml':'<!--',
'javascript':'/*',
}
closing_map = {
'css':'*/',
'html':'-->',
'xml':'-->',
'javascript':'*/',
}
def apply_smart_comment(editor, opening='/*', closing='*/', line_comment=None):
doc = editor.document()
c = QTextCursor(editor.textCursor())
c.clearSelection()
before_opening = doc.find(opening, c, doc.FindBackward | doc.FindCaseSensitively)
before_closing = doc.find(closing, c, doc.FindBackward | doc.FindCaseSensitively)
after_opening = doc.find(opening, c, doc.FindCaseSensitively)
after_closing = doc.find(closing, c, doc.FindCaseSensitively)
in_block_comment = (not before_opening.isNull() and (before_closing.isNull() or before_opening.position() >= before_closing.position())) and \
(not after_closing.isNull() and (after_opening.isNull() or after_closing.position() <= after_opening.position()))
if in_block_comment:
before_opening.removeSelectedText(), after_closing.removeSelectedText()
return
c = QTextCursor(editor.textCursor())
left, right = min(c.position(), c.anchor()), max(c.position(), c.anchor())
c.beginEditBlock()
c.setPosition(right), c.insertText(closing)
c.setPosition(left), c.insertText(opening)
c.endEditBlock()
def smart_comment(editor, syntax):
apply_smart_comment(editor, opening=opening_map.get(syntax, '/*'), closing=closing_map.get(syntax, '*/'))

View File

@ -323,6 +323,10 @@ class TextEdit(PlainTextEdit):
self.update_extra_selections()
return count
def smart_comment(self):
from calibre.gui2.tweak_book.editor.comments import smart_comment
smart_comment(self, self.syntax)
def find(self, pat, wrap=False, marked=False, complete=False, save_match=None):
if marked:
return self.find_in_marked(pat, wrap=wrap, save_match=save_match)

View File

@ -83,6 +83,11 @@ def register_text_editor_actions(_reg, palette):
ac = reg('insert-link', _('Insert &hyperlink'), ('insert_hyperlink',), 'insert-hyperlink', (), _('Insert hyperlink'), syntaxes=('html',))
ac.setToolTip(_('<h3>Insert hyperlink</h3>Insert a hyperlink into the text'))
ac = reg(create_icon('/*'), _('Smart &comment'), ('smart_comment',), 'editor-smart-comment', ('Ctrl+`',), _(
'Smart comment (toggle block comments)'), syntaxes=())
ac.setToolTip(_('<h3>Smart comment</h3>Comment or uncomment text<br><br>'
'If the cursor is inside an existing block comment, uncomment it, otherwise comment out the selected text.'))
for i, name in enumerate(('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p')):
text = ('&' + name) if name == 'p' else (name[0] + '&' + name[1])
desc = _('Convert the paragraph to &lt;%s&gt;') % name