search & replace widg, add visual feedback will typing in the input field

This commit is contained in:
Basile Burg 2024-01-21 20:51:08 +01:00
parent 58332062d1
commit f349dee6a4
6 changed files with 87 additions and 70 deletions

View File

@ -1,5 +1,9 @@
# v3.9.27-devel # v3.9.27-devel
## Enhancements
- Search & Replace, add visual feedback in the editor.
## Bugs fixed ## Bugs fixed
- Mini-explorer, clearing the filter had for effect to scan the root folder instead of the selected one. (#129) - Mini-explorer, clearing the filter had for effect to scan the root folder instead of the selected one. (#129)

View File

@ -2965,7 +2965,7 @@ begin
if fDoc.SelAvail then if fDoc.SelAvail then
str := fDoc.SelText str := fDoc.SelText
else else
str := fDoc.Identifier; str := fDoc.HighlightedIdent;
ffindwidg.cbToFind.Text := str; ffindwidg.cbToFind.Text := str;
ffindwidg.cbToFindChange(nil); ffindwidg.cbToFindChange(nil);
ffindwidg.cbToFind.SetFocus; ffindwidg.cbToFind.SetFocus;

View File

@ -8,12 +8,13 @@ inherited SearchWidget: TSearchWidget
ClientWidth = 422 ClientWidth = 422
inherited Content: TPanel inherited Content: TPanel
Height = 293 Height = 293
Top = 36
Width = 422 Width = 422
ClientHeight = 293 ClientHeight = 293
ClientWidth = 422 ClientWidth = 422
object cbToFind: TComboBox[0] object cbToFind: TComboBox[0]
Left = 4 Left = 4
Height = 27 Height = 30
Top = 4 Top = 4
Width = 414 Width = 414
Align = alTop Align = alTop
@ -22,15 +23,15 @@ inherited SearchWidget: TSearchWidget
BorderSpacing.Around = 4 BorderSpacing.Around = 4
ItemHeight = 0 ItemHeight = 0
MaxLength = 128 MaxLength = 128
TabOrder = 0
OnChange = cbToFindChange OnChange = cbToFindChange
OnKeyDown = cbToFindKeyDown OnKeyDown = cbToFindKeyDown
OnSelect = cbToFindChange OnSelect = cbToFindChange
TabOrder = 0
end end
object btnFind: TBitBtn[1] object btnFind: TBitBtn[1]
Left = 4 Left = 4
Height = 27 Height = 32
Top = 169 Top = 149
Width = 414 Width = 414
Align = alBottom Align = alBottom
AutoSize = True AutoSize = True
@ -40,8 +41,8 @@ inherited SearchWidget: TSearchWidget
end end
object btnReplace: TBitBtn[2] object btnReplace: TBitBtn[2]
Left = 4 Left = 4
Height = 27 Height = 32
Top = 231 Top = 221
Width = 414 Width = 414
Align = alBottom Align = alBottom
AutoSize = True AutoSize = True
@ -51,21 +52,21 @@ inherited SearchWidget: TSearchWidget
end end
object grpOpts: TGroupBox[3] object grpOpts: TGroupBox[3]
Left = 4 Left = 4
Height = 99 Height = 73
Top = 66 Top = 72
Width = 414 Width = 414
Align = alClient Align = alClient
AutoSize = True AutoSize = True
BorderSpacing.Around = 4 BorderSpacing.Around = 4
Caption = 'Options' Caption = 'Options'
ClientHeight = 80 ClientHeight = 54
ClientWidth = 410 ClientWidth = 412
TabOrder = 4 TabOrder = 4
object FlowPanel1: TFlowPanel object FlowPanel1: TFlowPanel
Left = 0 Left = 0
Height = 80 Height = 54
Top = 0 Top = 0
Width = 410 Width = 412
Align = alClient Align = alClient
AutoSize = True AutoSize = True
BevelOuter = bvNone BevelOuter = bvNone
@ -105,9 +106,9 @@ inherited SearchWidget: TSearchWidget
TabOrder = 0 TabOrder = 0
object chkRegex: TCheckBox object chkRegex: TCheckBox
Left = 0 Left = 0
Height = 22 Height = 23
Top = 0 Top = 0
Width = 100 Width = 94
Anchors = [] Anchors = []
Caption = 'allow regex' Caption = 'allow regex'
Checked = True Checked = True
@ -116,27 +117,27 @@ inherited SearchWidget: TSearchWidget
end end
object chkPrompt: TCheckBox object chkPrompt: TCheckBox
Left = 0 Left = 0
Height = 22 Height = 23
Top = 23 Top = 24
Width = 71 Width = 72
Anchors = [] Anchors = []
Caption = 'prompt' Caption = 'prompt'
TabOrder = 1 TabOrder = 1
end end
object chkCaseSens: TCheckBox object chkCaseSens: TCheckBox
Left = 0 Left = 94
Height = 22 Height = 23
Top = 46 Top = 0
Width = 117 Width = 107
Anchors = [] Anchors = []
Caption = 'case sensitive' Caption = 'case sensitive'
TabOrder = 2 TabOrder = 2
end end
object chkFromCur: TCheckBox object chkFromCur: TCheckBox
Left = 117 Left = 94
Height = 22 Height = 23
Top = 0 Top = 24
Width = 99 Width = 96
Anchors = [] Anchors = []
Caption = 'from cursor' Caption = 'from cursor'
Checked = True Checked = True
@ -144,19 +145,19 @@ inherited SearchWidget: TSearchWidget
TabOrder = 3 TabOrder = 3
end end
object chkBack: TCheckBox object chkBack: TCheckBox
Left = 117 Left = 201
Height = 22 Height = 23
Top = 23 Top = 0
Width = 87 Width = 84
Anchors = [] Anchors = []
Caption = 'backward' Caption = 'backward'
TabOrder = 4 TabOrder = 4
end end
object chkWWord: TCheckBox object chkWWord: TCheckBox
Left = 117 Left = 201
Height = 22 Height = 23
Top = 46 Top = 24
Width = 99 Width = 96
Anchors = [] Anchors = []
Caption = 'whole word' Caption = 'whole word'
Checked = True Checked = True
@ -167,8 +168,8 @@ inherited SearchWidget: TSearchWidget
end end
object btnReplaceAll: TBitBtn[4] object btnReplaceAll: TBitBtn[4]
Left = 4 Left = 4
Height = 27 Height = 32
Top = 262 Top = 257
Width = 414 Width = 414
Align = alBottom Align = alBottom
AutoSize = True AutoSize = True
@ -178,69 +179,69 @@ inherited SearchWidget: TSearchWidget
end end
object Panel1: TPanel[5] object Panel1: TPanel[5]
Left = 4 Left = 4
Height = 27 Height = 30
Top = 35 Top = 38
Width = 414 Width = 414
Align = alTop Align = alTop
AutoSize = True AutoSize = True
BorderSpacing.Around = 4 BorderSpacing.Around = 4
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 27 ClientHeight = 30
ClientWidth = 414 ClientWidth = 414
TabOrder = 5 TabOrder = 5
object cbReplaceWth: TComboBox object cbReplaceWth: TComboBox
Left = 111 Left = 104
Height = 27 Height = 30
Top = 0 Top = 0
Width = 303 Width = 310
Align = alClient Align = alClient
AutoComplete = True AutoComplete = True
AutoCompleteText = [cbactEnabled, cbactEndOfLineComplete, cbactSearchCaseSensitive, cbactSearchAscending] AutoCompleteText = [cbactEnabled, cbactEndOfLineComplete, cbactSearchCaseSensitive, cbactSearchAscending]
ItemHeight = 0 ItemHeight = 0
MaxLength = 128 MaxLength = 128
TabOrder = 1
OnChange = cbReplaceWthChange OnChange = cbReplaceWthChange
OnKeyDown = cbReplaceWthKeyDown OnKeyDown = cbReplaceWthKeyDown
OnSelect = cbReplaceWthChange OnSelect = cbReplaceWthChange
TabOrder = 1
end end
object chkEnableRep: TCheckBox object chkEnableRep: TCheckBox
Left = 0 Left = 0
Height = 27 Height = 30
Top = 0 Top = 0
Width = 111 Width = 104
Align = alLeft Align = alLeft
Caption = 'Replace with ' Caption = 'Replace with '
OnChange = chkEnableRepChange
TabOrder = 0 TabOrder = 0
OnChange = chkEnableRepChange
end end
end end
object Panel2: TPanel[6] object Panel2: TPanel[6]
Left = 4 Left = 4
Height = 27 Height = 32
Top = 200 Top = 185
Width = 414 Width = 414
Align = alBottom Align = alBottom
AutoSize = True AutoSize = True
BorderSpacing.Around = 4 BorderSpacing.Around = 4
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 27 ClientHeight = 32
ClientWidth = 414 ClientWidth = 414
TabOrder = 6 TabOrder = 6
object btnFindAll: TBitBtn object btnFindAll: TBitBtn
Left = 0 Left = 0
Height = 27 Height = 32
Top = 0 Top = 0
Width = 402 Width = 398
Align = alClient Align = alClient
AutoSize = True AutoSize = True
Caption = 'btnFindAll' Caption = 'btnFindAll'
TabOrder = 0 TabOrder = 0
end end
object btnAllScope: TBitBtn object btnAllScope: TBitBtn
Left = 404 Left = 400
Height = 27 Height = 32
Top = 0 Top = 0
Width = 10 Width = 14
Align = alRight Align = alRight
AutoSize = True AutoSize = True
BorderSpacing.Left = 2 BorderSpacing.Left = 2
@ -256,7 +257,7 @@ inherited SearchWidget: TSearchWidget
Left = 216 Left = 216
Top = 16 Top = 16
end end
object imgList: TImageList[2] object imgList: TImageList[3]
Left = 248 Left = 248
Top = 16 Top = 16
Bitmap = { Bitmap = {

View File

@ -762,6 +762,8 @@ begin
fToFind := cbToFind.Text; fToFind := cbToFind.Text;
fHasSearched := false; fHasSearched := false;
updateImperative; updateImperative;
if fDoc.isAssigned and (not chkRegex.Checked) then
fDoc.HighlightedIdent := fToFind;
end; end;
procedure TSearchWidget.cbToFindKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure TSearchWidget.cbToFindKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

View File

@ -209,8 +209,8 @@ begin
fSymbols[CFF] := fDoc.fileName; fSymbols[CFF] := fDoc.fileName;
fSymbols[CFR] := fSymbols[CFF].stripFileExt + exeExt; fSymbols[CFR] := fSymbols[CFF].stripFileExt + exeExt;
fSymbols[CFP] := fSymbols[CFF].extractFilePath; fSymbols[CFP] := fSymbols[CFF].extractFilePath;
if fDoc.Identifier.isNotEmpty then if fDoc.HighlightedIdent.isNotEmpty then
fSymbols[CI] := fDoc.Identifier; fSymbols[CI] := fDoc.HighlightedIdent;
fSymbols[CL] := fDoc.LineText; fSymbols[CL] := fDoc.LineText;
fSymbols[CS] := fDoc.SelText; fSymbols[CS] := fDoc.SelText;
end; end;

View File

@ -201,7 +201,7 @@ type
fCacheLoaded: boolean; fCacheLoaded: boolean;
fIsDSource: boolean; fIsDSource: boolean;
fFocusForInput: boolean; fFocusForInput: boolean;
fIdentifier: string; fHighlightedIdent: string;
fTempFileName: string; fTempFileName: string;
fMultiDocSubject: TObject; fMultiDocSubject: TObject;
fDefaultFontSize: Integer; fDefaultFontSize: Integer;
@ -267,7 +267,7 @@ type
procedure setMatchOpts(value: TIdentifierMatchOptions); procedure setMatchOpts(value: TIdentifierMatchOptions);
function getMouseBytePosition: Integer; function getMouseBytePosition: Integer;
procedure changeNotify(Sender: TObject); procedure changeNotify(Sender: TObject);
procedure highlightCurrentIdentifier; procedure highlightCurrentIdentifier(fromEditor: boolean = true);
procedure saveCache; procedure saveCache;
procedure loadCache; procedure loadCache;
class procedure cleanCache; static; class procedure cleanCache; static;
@ -321,6 +321,7 @@ type
procedure debugBreak(const fname: string; line: integer; reason: TDebugBreakReason); procedure debugBreak(const fname: string; line: integer; reason: TDebugBreakReason);
function breakPointsCount: integer; function breakPointsCount: integer;
procedure tryToPatchMixedIndentation; procedure tryToPatchMixedIndentation;
procedure setHighligthedIdent(value: string);
protected protected
procedure DoEnter; override; procedure DoEnter; override;
procedure DoExit; override; procedure DoExit; override;
@ -388,7 +389,7 @@ type
procedure scrollCentered(down: boolean); procedure scrollCentered(down: boolean);
// //
property IdentifierMatchOptions: TIdentifierMatchOptions read fMatchOpts write setMatchOpts; property IdentifierMatchOptions: TIdentifierMatchOptions read fMatchOpts write setMatchOpts;
property Identifier: string read fIdentifier; property HighlightedIdent: string read fHighlightedIdent write setHighligthedIdent;
property fileName: string read fFilename; property fileName: string read fFilename;
property modified: boolean read fModified; property modified: boolean read fModified;
property tempFilename: string read fTempFileName; property tempFilename: string read fTempFileName;
@ -3372,14 +3373,23 @@ begin
fIsDSource := Highlighter = fD2Highlighter; fIsDSource := Highlighter = fD2Highlighter;
end; end;
procedure TDexedMemo.highlightCurrentIdentifier; procedure TDexedMemo.setHighligthedIdent(value: string);
begin
if fHighlightedIdent = value then
exit;
fHighlightedIdent := value;
highlightCurrentIdentifier(false);
end;
procedure TDexedMemo.highlightCurrentIdentifier(fromEditor: boolean = true);
var var
s: string; s: string;
i: integer; i: integer;
begin begin
fIdentifier := GetWordAtRowCol(LogicalCaretXY); if fromEditor then
if (fIdentifier.length > 2) and (not SelAvail) then fHighlightedIdent := GetWordAtRowCol(LogicalCaretXY);
SetHighlightSearch(fIdentifier, fMatchIdentOpts) if (fHighlightedIdent.length > 2) and (not SelAvail) then
SetHighlightSearch(fHighlightedIdent, fMatchIdentOpts)
else if SelAvail and (BlockBegin.Y = BlockEnd.Y) then else if SelAvail and (BlockBegin.Y = BlockEnd.Y) then
begin begin
s := SelText; s := SelText;