📄 syneditsearcher.pas
字号:
{-------------------------------------------------------------------------------
单元: SynEditSearcher.pas
作者: 姚乔锋
日期: 2005-05-17 17:20
说明: 实现SynEdit的搜索简化
版本: 1.00
-------------------------------------------------------------------------------}
unit SynEditSearcher;
interface
uses
SysUtils, Classes, Controls, Forms, Windows, Dialogs, Graphics,
SynMsgDialog, SynEditStrRes, SynEdit, SynEditPrint, SynEditTypes,
SynEditMiscClasses, SynEditSearch, SynEditRegexSearch;
type
// 搜索对话框
TSynSearchDialog = class(TForm)
public
procedure SetSearchData(const FindText, ReplaceText : string;
FindHistory, ReplaceHistory : TStrings;
const SearchOptions : TSynSearchOptions;
const RegexSearch : Boolean); virtual;
procedure getSearchData(var FindText, ReplaceText : string;
FindHistory, ReplaceHistory : TStrings;
var SearchOptions : TSynSearchOptions;
var RegexSearch : Boolean); virtual;
end;
TSynSearchDialogClass = class of TSynSearchDialog;
// 实现搜索
TSynEditSearcher = class(TPersistent)
private
FFindText, FReplaceText : string;
FFindHistory, FReplaceHistory : TStrings;
FSearchOptions : TSynSearchOptions;
FRegexSearch : Boolean;
FSynSearch: TSynEditSearch;
FSynRegexSearch: TSynEditRegexSearch;
function CreateFindDialog : TSynSearchDialog;
function CreateReplaceDialog : TSynSearchDialog;
procedure OnReplaceText(Sender: TObject; const ASearch, AReplace:
string; Line, Column: integer; var Action: TSynReplaceAction);
public
constructor Create; virtual;
destructor Destroy; override;
procedure Search(
SynEdit : TcustomSynEdit;
FindText, ReplaceText: string;
SearchOptions : TSynSearchOptions;
RegexSearch : Boolean);
procedure Find(SynEdit : TcustomSynEdit);
procedure FindNext(SynEdit : TcustomSynEdit);
procedure FindLast(SynEdit : TcustomSynEdit);
procedure FindNextForWord(SynEdit : TcustomSynEdit);
procedure FindLastForWord(SynEdit : TcustomSynEdit);
procedure Replace(SynEdit : TcustomSynEdit);
procedure ReplaceNext(SynEdit : TcustomSynEdit);
procedure ReplaceLast(SynEdit : TcustomSynEdit);
end;
var
Searcher : TSynEditSearcher;
FindDialogClass, ReplaceDialogClass : TSynSearchDialogClass;
implementation
{ TSynEditSearcher }
constructor TSynEditSearcher.Create;
begin
inherited;
FFindHistory := TStringList.Create;
FReplaceHistory := TStringList.Create;
FSynSearch:= TSynEditSearch.Create(nil);
FSynRegexSearch:= TSynEditRegexSearch.Create(nil);
FRegexSearch := true;
end;
function TSynEditSearcher.CreateFindDialog: TSynSearchDialog;
begin
result := FindDialogClass.Create(nil);
end;
function TSynEditSearcher.CreateReplaceDialog: TSynSearchDialog;
begin
result := ReplaceDialogClass.Create(nil);
end;
destructor TSynEditSearcher.Destroy;
begin
inherited;
FFindHistory.Free;
FReplaceHistory.Free;
FSynSearch.Free;
FSynRegexSearch.Free;
end;
procedure TSynEditSearcher.OnReplaceText(Sender: TObject; const ASearch,
AReplace: string; Line, Column: integer; var Action: TSynReplaceAction);
var
APos: TPoint;
begin
with TSynEdit(Sender) do
APos := ClientToScreen(RowColumnToPixels(BufferToDisplayPos(
BufferCoord(Column, Line+1))));
case MessageDlgPos(format(sReplacePromptText, [ASearch, AReplace]),
sReplacePromptTitle, mtConfirmation, [sReplacePromptYesBtn,
sReplacePromptSkipBtn, sReplacePromptAllBtn, sReplacePromptCancelBtn ],
1, 4, APos.X, APos.Y) of
1: Action := raReplace;
3: Action := raReplaceAll;
2: Action := raSkip;
else Action := raCancel;
end;
end;
procedure TSynEditSearcher.Find(SynEdit : TcustomSynEdit);
var
s : string;
begin
with CreateFindDialog do
begin
Exclude(FSearchOptions, ssoReplace);
Exclude(FSearchOptions, ssoReplaceall);
If SynEdit.SelAvail then
s := SynEdit.SelText else
s := FFindText;
SetSearchData(s, '', FFindHistory, nil, FSearchOptions, FRegexSearch);
IF ShowModal = mrOk then
begin
GetSearchData(FFindText, s, FFindHistory, nil, FSearchOptions, FRegexSearch);
Hide;
Search(SynEdit, FFindText, '', FSearchOptions, FRegexSearch);
end;
free;
end;
end;
procedure TSynEditSearcher.FindLast(SynEdit : TcustomSynEdit);
begin
If FFindText = '' then Find(SynEdit)
else Search(SynEdit, FFindText, '', FSearchOptions + [ssoBackwards] -
[ssoReplace, ssoReplaceAll], fRegexSearch);
end;
procedure TSynEditSearcher.FindLastForWord(SynEdit : TcustomSynEdit);
begin
If FFindText = '' then Find(SynEdit)
else Search(SynEdit, FFindText, '', fSearchOptions + [ssoBackwards, ssoWholeWord] -
[ssoReplace, ssoReplaceAll], fRegexSearch);
end;
procedure TSynEditSearcher.FindNext(SynEdit : TcustomSynEdit);
begin
If FFindText = '' then Find(SynEdit)
else Search(SynEdit, FFindText, '', fSearchOptions -
[ssoReplace, ssoReplaceAll, ssoBackwards], fRegexSearch);
end;
procedure TSynEditSearcher.FindNextForWord(SynEdit : TcustomSynEdit);
begin
If FFindText = '' then Find(SynEdit)
else Search(SynEdit, FFindText, '', fSearchOptions + [ssoWholeWord] -
[ssoReplace, ssoReplaceAll, ssoBackwards], fRegexSearch);
end;
procedure TSynEditSearcher.Replace(SynEdit : TcustomSynEdit);
var
s : string;
begin
with CreateReplaceDialog do
begin
Exclude(FSearchOptions, ssoReplace);
Exclude(FSearchOptions, ssoReplaceall);
If SynEdit.SelAvail then
s := SynEdit.SelText else
s := FFindText;
SetSearchData(s, FReplaceText, FFindHistory, FReplaceHistory,
FSearchOptions, FRegexSearch);
IF ShowModal in [mrOk, mrall] then
begin
GetSearchData(FFindText, FReplaceText, FFindHistory, FReplaceHistory,
FSearchOptions, FRegexSearch);
If modalResult = mrOk then
Include(FSearchOptions, ssoReplace);
If modalResult = mrall then
Include(FSearchOptions, ssoReplaceall);
hide;
Search(SynEdit, FFindText, FReplaceText, FSearchOptions, FRegexSearch);
end;
free;
end;
end;
procedure TSynEditSearcher.ReplaceLast(SynEdit : TcustomSynEdit);
begin
If FFindText = '' then Replace(SynEdit)
else Search(SynEdit, FFindText, FReplaceText, FSearchOptions -
[ssoReplaceall] + [ssoReplace, ssoBackwards], FRegexSearch);
end;
procedure TSynEditSearcher.ReplaceNext(SynEdit : TcustomSynEdit);
begin
If FFindText = '' then Replace(SynEdit)
else Search(SynEdit, FFindText, FReplaceText, FSearchOptions + [ssoReplace] -
[ssoReplaceall, ssoBackwards], FRegexSearch);
end;
procedure TSynEditSearcher.Search(
SynEdit : TcustomSynEdit;
FindText, ReplaceText: string;
SearchOptions : TSynSearchOptions;
RegexSearch : Boolean);
var
P : integer;
oldEvent : TReplaceTextEvent;
begin
with SynEdit do
begin
oldEvent := OnReplaceText;
OnReplaceText := self.OnReplaceText;
if RegexSearch then
SearchEngine := FSynRegexSearch else
SearchEngine := FSynSearch;
if SearchReplace(FindText, ReplaceText, SearchOptions) = 0 then
begin
MessageBeep(MB_ICONASTERISK);
ShowMessage(format(sNotFindText, [FindText]));
if ssoBackwards in SearchOptions then
BlockEnd := BlockBegin else
BlockBegin := BlockEnd;
CaretXY := BlockBegin;
end;
OnReplaceText := oldEvent;
end;
P := FFindHistory.IndexOf(FindText);
If P > -1 then FFindHistory.Delete(P);
FFindHistory.Insert(0, FindText);
FFindText := FindText;
If (ssoReplace in SearchOptions) or (ssoReplaceAll in SearchOptions) then
begin
P := FReplaceHistory.IndexOf(ReplaceText);
If P > -1 then FReplaceHistory.Delete(P);
FReplaceHistory.Insert(0, ReplaceText);
FReplaceText := ReplaceText;
end;
end;
{ TSynSearchDialog }
procedure TSynSearchDialog.getSearchData(var FindText, ReplaceText: string;
FindHistory, ReplaceHistory: TStrings;
var SearchOptions: TSynSearchOptions; var RegexSearch: Boolean);
begin
end;
procedure TSynSearchDialog.SetSearchData(const FindText,
ReplaceText: string; FindHistory, ReplaceHistory: TStrings;
const SearchOptions: TSynSearchOptions; const RegexSearch: Boolean);
begin
end;
initialization
Searcher := TSynEditSearcher.Create;
finalization
Searcher.Free;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -