mirror of https://github.com/buggins/dlangui.git
highlight selected word occurences in text editor - close #420
This commit is contained in:
parent
2a78f1d9d1
commit
d61d3ee1a4
|
@ -1167,6 +1167,20 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
requestActionsUpdate();
|
requestActionsUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected dstring _textToHighlight;
|
||||||
|
protected uint _textToHighlightOptions;
|
||||||
|
|
||||||
|
/// text pattern to highlight - e.g. for search
|
||||||
|
@property dstring textToHighlight() {
|
||||||
|
return _textToHighlight;
|
||||||
|
}
|
||||||
|
/// set text to highlight -- e.g. for search
|
||||||
|
void setTextToHighlight(dstring pattern, uint textToHighlightOptions) {
|
||||||
|
_textToHighlight = pattern;
|
||||||
|
_textToHighlightOptions = textToHighlightOptions;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
protected void selectWordByMouse(int x, int y) {
|
protected void selectWordByMouse(int x, int y) {
|
||||||
TextPosition oldCaretPos = _caretPos;
|
TextPosition oldCaretPos = _caretPos;
|
||||||
TextPosition newPos = clientToTextPos(Point(x,y));
|
TextPosition newPos = clientToTextPos(Point(x,y));
|
||||||
|
@ -2742,57 +2756,65 @@ class EditBox : EditWidgetBase {
|
||||||
super.measure(parentWidth, parentHeight);
|
super.measure(parentWidth, parentHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected dstring _textToHighlight;
|
|
||||||
protected uint _textToHighlightOptions;
|
|
||||||
|
|
||||||
/// text pattern to highlight - e.g. for search
|
|
||||||
@property dstring textToHighlight() {
|
|
||||||
return _textToHighlight;
|
|
||||||
}
|
|
||||||
/// set text to highlight -- e.g. for search
|
|
||||||
void setTextToHighlight(dstring pattern, uint textToHighlightOptions) {
|
|
||||||
_textToHighlight = pattern;
|
|
||||||
_textToHighlightOptions = textToHighlightOptions;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void highlightTextPattern(DrawBuf buf, int lineIndex, Rect lineRect, Rect visibleRect) {
|
protected void highlightTextPattern(DrawBuf buf, int lineIndex, Rect lineRect, Rect visibleRect) {
|
||||||
if (!_textToHighlight.length)
|
dstring pattern = _textToHighlight;
|
||||||
|
uint options = _textToHighlightOptions;
|
||||||
|
if (!pattern.length) {
|
||||||
|
// support highlighting selection text - if whole word is selected
|
||||||
|
if (_selectionRange.empty || !_selectionRange.singleLine)
|
||||||
|
return;
|
||||||
|
if (_selectionRange.start.line >= _content.length)
|
||||||
|
return;
|
||||||
|
dstring selLine = _content.line(_selectionRange.start.line);
|
||||||
|
int start = _selectionRange.start.pos;
|
||||||
|
int end = _selectionRange.end.pos;
|
||||||
|
if (start >= selLine.length)
|
||||||
|
return;
|
||||||
|
pattern = selLine[start .. end];
|
||||||
|
if (!isWordChar(pattern[0]) || !isWordChar(pattern[$-1]))
|
||||||
|
return;
|
||||||
|
if (!isWholeWord(selLine, start, end))
|
||||||
|
return;
|
||||||
|
// whole word is selected - enable highlight for it
|
||||||
|
options = TextSearchFlag.CaseSensitive | TextSearchFlag.WholeWords;
|
||||||
|
}
|
||||||
|
if (!pattern.length)
|
||||||
return;
|
return;
|
||||||
dstring lineText = _content.line(lineIndex);
|
dstring lineText = _content.line(lineIndex);
|
||||||
if (lineText.length < _textToHighlight.length)
|
if (lineText.length < pattern.length)
|
||||||
return;
|
return;
|
||||||
ptrdiff_t start = 0;
|
ptrdiff_t start = 0;
|
||||||
import std.string : indexOf, CaseSensitive, Yes, No;
|
import std.string : indexOf, CaseSensitive, Yes, No;
|
||||||
bool caseSensitive = (_textToHighlightOptions & TextSearchFlag.CaseSensitive) != 0;
|
bool caseSensitive = (options & TextSearchFlag.CaseSensitive) != 0;
|
||||||
bool wholeWords = (_textToHighlightOptions & TextSearchFlag.WholeWords) != 0;
|
bool wholeWords = (options & TextSearchFlag.WholeWords) != 0;
|
||||||
bool selectionOnly = (_textToHighlightOptions & TextSearchFlag.SelectionOnly) != 0;
|
bool selectionOnly = (options & TextSearchFlag.SelectionOnly) != 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ptrdiff_t pos = lineText[start .. $].indexOf(_textToHighlight, caseSensitive ? Yes.caseSensitive : No.caseSensitive);
|
ptrdiff_t pos = lineText[start .. $].indexOf(pattern, caseSensitive ? Yes.caseSensitive : No.caseSensitive);
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
break;
|
break;
|
||||||
// found text to highlight
|
// found text to highlight
|
||||||
start += pos;
|
start += pos;
|
||||||
if (!wholeWords || isWholeWord(lineText, start, start + _textToHighlight.length)) {
|
if (!wholeWords || isWholeWord(lineText, start, start + pattern.length)) {
|
||||||
TextRange r = TextRange(TextPosition(lineIndex, cast(int)start), TextPosition(lineIndex, cast(int)(start + _textToHighlight.length)));
|
TextRange r = TextRange(TextPosition(lineIndex, cast(int)start), TextPosition(lineIndex, cast(int)(start + pattern.length)));
|
||||||
uint color = r.isInsideOrNext(caretPos) ? _searchHighlightColorCurrent : _searchHighlightColorOther;
|
uint color = r.isInsideOrNext(caretPos) ? _searchHighlightColorCurrent : _searchHighlightColorOther;
|
||||||
highlightLineRange(buf, lineRect, color, r);
|
highlightLineRange(buf, lineRect, color, r);
|
||||||
}
|
}
|
||||||
start += _textToHighlight.length;
|
start += pattern.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isWordChar(dchar ch) {
|
static bool isWordChar(dchar ch) {
|
||||||
if (ch >= 'a' && ch <= 'z')
|
if (ch >= 'a' && ch <= 'z')
|
||||||
return false;
|
return true;
|
||||||
if (ch >= 'A' && ch <= 'Z')
|
if (ch >= 'A' && ch <= 'Z')
|
||||||
return false;
|
return true;
|
||||||
if (ch == '_')
|
if (ch == '_')
|
||||||
return false;
|
return true;
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
static bool isValidWordBound(dchar innerChar, dchar outerChar) {
|
static bool isValidWordBound(dchar innerChar, dchar outerChar) {
|
||||||
return isWordChar(innerChar) || isWordChar(outerChar);
|
return !isWordChar(innerChar) || !isWordChar(outerChar);
|
||||||
}
|
}
|
||||||
/// returns true if selected range of string is whole word
|
/// returns true if selected range of string is whole word
|
||||||
static bool isWholeWord(dstring lineText, size_t start, size_t end) {
|
static bool isWholeWord(dstring lineText, size_t start, size_t end) {
|
||||||
|
@ -3509,7 +3531,7 @@ class FindPanel : HorizontalLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
_editor.setTextToHighlight(null, false);
|
_editor.setTextToHighlight(null, 0);
|
||||||
_editor.closeFindPanel();
|
_editor.closeFindPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue