Don't highlight html escapes in completion.
Resolves #4199. To avoid accidentally highlighting characters that were introduced by html escaping the text before feeding it to setHtml, we can't just escape the whole string before adding the highlighting. Instead, we need to break the string up on the pattern, format and escape the individual parts, then join them back together. re.escape includes empty strings if there is a match at the start/end, which ensures that matches always land on odd indices: https://docs.python.org/3/library/re.html#re.split > If there are capturing groups in the separator and it matches at the > start of the string, the result will start with an empty string. The > same holds for the end of the string
This commit is contained in:
parent
4f99af5876
commit
102c6b99dd
@ -202,11 +202,16 @@ class CompletionItemDelegate(QStyledItemDelegate):
|
|||||||
pattern = view.pattern
|
pattern = view.pattern
|
||||||
columns_to_filter = index.model().columns_to_filter(index)
|
columns_to_filter = index.model().columns_to_filter(index)
|
||||||
if index.column() in columns_to_filter and pattern:
|
if index.column() in columns_to_filter and pattern:
|
||||||
repl = r'<span class="highlight">\g<0></span>'
|
pat = '({})'.format(re.escape(pattern).replace(r'\ ', r'|'))
|
||||||
pat = html.escape(re.escape(pattern), quote=False).replace(
|
parts = re.split(pat, self._opt.text, flags=re.IGNORECASE)
|
||||||
r'\ ', r'|')
|
fmt = '<span class="highlight">{}</span>'
|
||||||
txt = html.escape(self._opt.text, quote=False)
|
escape = lambda s: html.escape(s, quote=False)
|
||||||
text = re.sub(pat, repl, txt, flags=re.IGNORECASE)
|
highlight = lambda s: fmt.format(escape(s))
|
||||||
|
# matches are at every odd index
|
||||||
|
text = ''.join([
|
||||||
|
highlight(s) if i % 2 == 1 else escape(s)
|
||||||
|
for i, s in enumerate(parts)
|
||||||
|
])
|
||||||
self._doc.setHtml(text)
|
self._doc.setHtml(text)
|
||||||
else:
|
else:
|
||||||
self._doc.setPlainText(self._opt.text)
|
self._doc.setPlainText(self._opt.text)
|
||||||
|
@ -90,6 +90,7 @@ def delegate(mock_style_option, mock_text_document, config_stub, mocker, view):
|
|||||||
# https://github.com/qutebrowser/qutebrowser/issues/4199
|
# https://github.com/qutebrowser/qutebrowser/issues/4199
|
||||||
('foo', "'foo'", "'{foo}'"),
|
('foo', "'foo'", "'{foo}'"),
|
||||||
('x', "'x'", "'{x}'"),
|
('x', "'x'", "'{x}'"),
|
||||||
|
('lt', "<lt", "<{lt}"),
|
||||||
])
|
])
|
||||||
def test_paint(delegate, painter, view, mock_style_option, mock_text_document,
|
def test_paint(delegate, painter, view, mock_style_option, mock_text_document,
|
||||||
pat, txt_in, txt_out):
|
pat, txt_in, txt_out):
|
||||||
|
Loading…
Reference in New Issue
Block a user