mirror of https://gitlab.com/basile.b/dexed.git
r11
This commit is contained in:
parent
a522efb185
commit
fdadfc810b
|
@ -5,7 +5,7 @@ Coedit is a simple IDE for the [D2](http://dlang.org) lang. (**Co** mpile & **Ed
|
|||
|
||||
Current features
|
||||
----------------
|
||||
- multi platform (Win/Linux/Macos).
|
||||
- multi platform (Win/Linux).
|
||||
- projects.
|
||||
- multiple project configurations (set of switches and options).
|
||||
- compile, run directly from the UI.
|
||||
|
@ -34,7 +34,7 @@ Coedit must be build from the sources:
|
|||
- both [dmd](http://dlang.org/download.html) and [Lazarus](http://www.lazarus.freepascal.org) must be setup.
|
||||
- open "coedit.lpr" in *Lazarus*, set the build mode to *Release*
|
||||
- press the Run button (or build)
|
||||
- in coedit open *"lazproj\test\coeditproj\test.coedit"* from the project menu.
|
||||
- run coedit and project, open *"lazproj\test\coeditproj\test.coedit"* from the project menu to give a brief try.
|
||||
|
||||
Preview
|
||||
-------
|
||||
|
|
|
@ -54,7 +54,8 @@
|
|||
<CompilerMessages>
|
||||
<MsgFileName Value=""/>
|
||||
</CompilerMessages>
|
||||
<CustomOptions Value="-dDEBUG"/>
|
||||
<CustomOptions Value="-dDEBUG
|
||||
-dUSE_DICT_LINKEDCHARMAP"/>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
|
@ -74,7 +75,7 @@
|
|||
<CodeGeneration>
|
||||
<SmartLinkUnit Value="True"/>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="2"/>
|
||||
<OptimizationLevel Value="3"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
|
@ -95,7 +96,8 @@
|
|||
<CompilerMessages>
|
||||
<MsgFileName Value=""/>
|
||||
</CompilerMessages>
|
||||
<CustomOptions Value="-dRELEASE"/>
|
||||
<CustomOptions Value="-dRELEASE
|
||||
-dUSE_DICT_LINKEDCHARMAP"/>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
|
@ -250,6 +252,7 @@
|
|||
<CompilerMessages>
|
||||
<MsgFileName Value=""/>
|
||||
</CompilerMessages>
|
||||
<CustomOptions Value="-dUSE_DICT_LINKEDCHARMAP"/>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
|
|
|
@ -7,6 +7,10 @@ interface
|
|||
uses
|
||||
Classes, SysUtils, ActnList, dialogs, forms;
|
||||
|
||||
const
|
||||
|
||||
DdiagFilter = 'D source|*.d|D interface|*.di|All files|*.*';
|
||||
|
||||
type
|
||||
|
||||
(**
|
||||
|
@ -275,9 +279,4 @@ begin
|
|||
{$HINTS ON}{$WARNINGS ON}
|
||||
end;
|
||||
|
||||
operator =(lhs,rhs: TPoint): boolean;
|
||||
begin
|
||||
exit( (lhs.x = rhs.x) and (lhs.y = rhs.y) );
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
149
src/ce_d2syn.pas
149
src/ce_d2syn.pas
|
@ -39,22 +39,46 @@ const
|
|||
|
||||
type
|
||||
|
||||
|
||||
{$IFDEF USE_DICT_LINKEDCHARMAP}
|
||||
PCharMap = ^TCharMap;
|
||||
TCharMap = record
|
||||
chars: array [Byte] of PCharMap;
|
||||
end;
|
||||
|
||||
// slightly fatest then a hash-based-dictionary but huge memory use.
|
||||
TD2Dictionary = object
|
||||
private
|
||||
fRoot: TCharMap;
|
||||
fTerm: NativeInt;
|
||||
fFreeList: array of pointer;
|
||||
fLongest, fShortest: NativeInt;
|
||||
procedure addEntry(const aValue: string);
|
||||
public
|
||||
constructor create;
|
||||
destructor destroy;
|
||||
function find(const aValue: string): boolean;
|
||||
end;
|
||||
{$ELSE} {$IFDEF USE_DICT_GPERF}
|
||||
// TODO: a perfect hash dictionnary based on gperf
|
||||
{$ELSE}
|
||||
TD2DictionaryEntry = record
|
||||
filled: Boolean;
|
||||
values: array of string;
|
||||
end;
|
||||
|
||||
// TODO: rather gperf ?
|
||||
TD2Dictionary = object
|
||||
private
|
||||
fLongest: NativeInt;
|
||||
fEntries: array[0..255] of TD2DictionaryEntry;
|
||||
fLongest, fShortest: NativeInt;
|
||||
fEntries: array[Byte] of TD2DictionaryEntry;
|
||||
function toHash(const aValue: string): Byte;
|
||||
procedure addEntry(const aValue: string);
|
||||
public
|
||||
constructor create;
|
||||
destructor destroy;
|
||||
function find(const aValue: string): boolean;
|
||||
end;
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
TTokenKind = (tkCommt, tkIdent, tkKeywd, tkStrng, tkBlank, tkSymbl, tkNumbr, tkCurrI);
|
||||
|
||||
|
@ -98,7 +122,7 @@ type
|
|||
procedure setCurrIdent(const aValue: string);
|
||||
procedure doChanged;
|
||||
published
|
||||
// Defines which kind of ranges can be folded, among curly brackets, block comments and nested comments
|
||||
// Defines which kind of range can be folded, among curly brackets, block comments and nested comments
|
||||
property FoldKinds: TFoldKinds read fFoldKinds write setFoldKinds;
|
||||
property WhiteAttrib: TSynHighlighterAttributes read fWhiteAttrib write setWhiteAttrib;
|
||||
property NumbrAttrib: TSynHighlighterAttributes read fNumbrAttrib write setNumbrAttrib;
|
||||
|
@ -217,70 +241,120 @@ begin
|
|||
result := (s = '>>>=') or (s = '!<>=');
|
||||
end;
|
||||
|
||||
{$IFDEF USE_DICT_LINKEDCHARMAP}
|
||||
constructor TD2Dictionary.create;
|
||||
var
|
||||
value: string;
|
||||
i: NativeInt;
|
||||
begin
|
||||
fTerm := 1;
|
||||
for i := 0 to 255 do fRoot.chars[i] := nil;
|
||||
for value in D2Kw do
|
||||
addEntry(value);
|
||||
end;
|
||||
|
||||
destructor TD2Dictionary.destroy;
|
||||
var
|
||||
i: NativeInt;
|
||||
begin
|
||||
for i := 0 to high(fFreeList) do
|
||||
FreeMem(fFreeList[i]);
|
||||
end;
|
||||
|
||||
procedure TD2Dictionary.addEntry(const aValue: string);
|
||||
var
|
||||
len, i, j: NativeInt;
|
||||
currMap: PCharMap;
|
||||
newMap: PCharMap;
|
||||
begin
|
||||
len := length(aValue);
|
||||
if len > fLongest then fLongest := len;
|
||||
if len < fShortest then fShortest := len;
|
||||
currMap := @fRoot;
|
||||
for i := 1 to len do
|
||||
begin
|
||||
if (currMap^.chars[Byte(aValue[i])] = nil) then
|
||||
begin
|
||||
newMap := new(PCharMap);
|
||||
for j := 0 to 255 do newMap^.chars[j] := nil;
|
||||
setLength(fFreeList, length(fFreeList) + 1);
|
||||
fFreeList[high(fFreeList)] := newMap;
|
||||
currMap^.chars[Byte(aValue[i])] := newMap;
|
||||
end;
|
||||
if i < len then currMap := currMap^.chars[Byte(aValue[i])];
|
||||
end;
|
||||
currMap^.chars[0] := @fTerm;
|
||||
end;
|
||||
|
||||
function TD2Dictionary.find(const aValue: string): boolean;
|
||||
var
|
||||
len, i: NativeInt;
|
||||
currMap: PCharMap;
|
||||
begin
|
||||
len := length(aValue);
|
||||
if len > fLongest then exit(false);
|
||||
if len < fShortest then exit(false);
|
||||
currMap := @fRoot;
|
||||
for i := 1 to len do
|
||||
begin
|
||||
if currMap^.chars[Byte(aValue[i])] = nil then exit(false);
|
||||
if i < len then currMap := currMap^.chars[Byte(aValue[i])];
|
||||
end;
|
||||
exit( currMap^.chars[0] = @fTerm );
|
||||
end;
|
||||
{$ELSE}
|
||||
constructor TD2Dictionary.create;
|
||||
var
|
||||
value: string;
|
||||
begin
|
||||
for value in D2Kw do
|
||||
begin
|
||||
addEntry(value);
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TD2Dictionary.destroy;
|
||||
begin
|
||||
end;
|
||||
|
||||
{$IFDEF DEBUG}{$R-}{$ENDIF}
|
||||
function TD2Dictionary.toHash(const aValue: string): Byte;
|
||||
var
|
||||
i, len: Integer;
|
||||
i: Integer;
|
||||
begin
|
||||
result := 0;
|
||||
len := length(aValue);
|
||||
for i := 1 to len do
|
||||
result += (Byte(aValue[i]) shl i) xor 63;
|
||||
for i := 1 to length(aValue) do
|
||||
result += (Byte(aValue[i]) shl (4 and (1-i))) xor 25;
|
||||
end;
|
||||
{$IFDEF DEBUG}{$R+}{$ENDIF}
|
||||
|
||||
procedure TD2Dictionary.addEntry(const aValue: string);
|
||||
var
|
||||
hash: word;
|
||||
hash: Byte;
|
||||
begin
|
||||
if find(aValue) then
|
||||
exit;
|
||||
|
||||
if find(aValue) then exit;
|
||||
hash := toHash(aValue);
|
||||
assert(hash < 1024);
|
||||
|
||||
fEntries[hash].filled := true;
|
||||
setLength(fEntries[hash].values, length(fEntries[hash].values) + 1);
|
||||
fEntries[hash].values[high(fEntries[hash].values)] := aValue;
|
||||
if fLongest <= length(aValue) then
|
||||
fLongest := length(aValue);
|
||||
if fShortest >= length(aValue) then
|
||||
fShortest := length(aValue);
|
||||
end;
|
||||
|
||||
function TD2Dictionary.find(const aValue: string): boolean;
|
||||
var
|
||||
hash: word;
|
||||
hash: Byte;
|
||||
i: NativeInt;
|
||||
begin
|
||||
if length(aValue) > fLongest then
|
||||
result := false
|
||||
else
|
||||
begin
|
||||
hash := toHash(aValue);
|
||||
if (not fEntries[hash].filled) then
|
||||
result := false else
|
||||
begin
|
||||
for i:= 0 to high(fEntries[hash].values) do
|
||||
begin
|
||||
if fEntries[hash].values[i] = aValue then
|
||||
begin
|
||||
result := true;
|
||||
exit;
|
||||
end;
|
||||
result := false;
|
||||
end
|
||||
end;
|
||||
end;
|
||||
result := false;
|
||||
if length(aValue) > fLongest then exit;
|
||||
if length(aValue) < fShortest then exit;
|
||||
hash := toHash(aValue);
|
||||
if (not fEntries[hash].filled) then exit(false);
|
||||
for i:= 0 to high(fEntries[hash].values) do
|
||||
if fEntries[hash].values[i] = aValue then exit(true);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
constructor TSynD2Syn.create(aOwner: TComponent);
|
||||
|
@ -342,6 +416,7 @@ end;
|
|||
|
||||
destructor TSynD2Syn.destroy;
|
||||
begin
|
||||
fKeyWords.destroy;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
|
|
|
@ -620,6 +620,15 @@ object CEMainForm: TCEMainForm
|
|||
object MenuItem21: TMenuItem
|
||||
Caption = '-'
|
||||
end
|
||||
object MenuItem54: TMenuItem
|
||||
Action = actEdIndent
|
||||
end
|
||||
object MenuItem53: TMenuItem
|
||||
Action = actEdUnIndent
|
||||
end
|
||||
object MenuItem52: TMenuItem
|
||||
Caption = '-'
|
||||
end
|
||||
object MenuItem22: TMenuItem
|
||||
Action = actEdMacStartStop
|
||||
Bitmap.Data = {
|
||||
|
@ -1663,6 +1672,20 @@ object CEMainForm: TCEMainForm
|
|||
ImageIndex = 21
|
||||
OnExecute = actProjRunWithArgsExecute
|
||||
end
|
||||
object actEdIndent: TAction
|
||||
Category = 'Edit'
|
||||
Caption = 'Indent'
|
||||
ImageIndex = 16
|
||||
OnExecute = actEdIndentExecute
|
||||
ShortCut = 24649
|
||||
end
|
||||
object actEdUnIndent: TAction
|
||||
Category = 'Edit'
|
||||
Caption = 'Unindent'
|
||||
ImageIndex = 17
|
||||
OnExecute = actEdUnIndentExecute
|
||||
ShortCut = 24661
|
||||
end
|
||||
end
|
||||
object imgList: TImageList
|
||||
left = 64
|
||||
|
|
|
@ -44,6 +44,8 @@ type
|
|||
actEdUndo: TAction;
|
||||
actEdPaste: TAction;
|
||||
actEdCopy: TAction;
|
||||
actEdIndent: TAction;
|
||||
actEdUnIndent: TAction;
|
||||
Actions: TActionList;
|
||||
ApplicationProperties1: TApplicationProperties;
|
||||
imgList: TImageList;
|
||||
|
@ -93,6 +95,9 @@ type
|
|||
MenuItem49: TMenuItem;
|
||||
MenuItem50: TMenuItem;
|
||||
MenuItem51: TMenuItem;
|
||||
MenuItem52: TMenuItem;
|
||||
MenuItem53: TMenuItem;
|
||||
MenuItem54: TMenuItem;
|
||||
mnuItemWin: TMenuItem;
|
||||
MenuItem4: TMenuItem;
|
||||
MenuItem5: TMenuItem;
|
||||
|
@ -106,6 +111,7 @@ type
|
|||
procedure actFileCompAndRunExecute(Sender: TObject);
|
||||
procedure actFileCompAndRunWithArgsExecute(Sender: TObject);
|
||||
procedure actFileSaveAllExecute(Sender: TObject);
|
||||
procedure actEdIndentExecute(Sender: TObject);
|
||||
procedure actProjCompAndRunWithArgsExecute(Sender: TObject);
|
||||
procedure actProjCompileAndRunExecute(Sender: TObject);
|
||||
procedure actProjCompileExecute(Sender: TObject);
|
||||
|
@ -131,6 +137,7 @@ type
|
|||
procedure actProjSaveExecute(Sender: TObject);
|
||||
procedure actEdUndoExecute(Sender: TObject);
|
||||
procedure actProjSourceExecute(Sender: TObject);
|
||||
procedure actEdUnIndentExecute(Sender: TObject);
|
||||
procedure FormDropFiles(Sender: TObject; const FileNames: array of String);
|
||||
procedure FormShow(Sender: TObject);
|
||||
private
|
||||
|
@ -285,6 +292,8 @@ begin
|
|||
{$ENDIF}
|
||||
actEdMacPlay.Enabled := true;
|
||||
actEdMacStartStop.Enabled := true;
|
||||
actEdIndent.Enabled := true;
|
||||
actEdUnIndent.Enabled := true;
|
||||
//
|
||||
actFileCompAndRun.Enabled := true;
|
||||
actFileCompAndRunWithArgs.Enabled := true;
|
||||
|
@ -303,6 +312,8 @@ begin
|
|||
{$ENDIF}
|
||||
actEdMacPlay.Enabled := false;
|
||||
actEdMacStartStop.Enabled := false;
|
||||
actEdIndent.Enabled := false;
|
||||
actEdUnIndent.Enabled := false;
|
||||
//
|
||||
actFileCompAndRun.Enabled := false;
|
||||
actFileCompAndRunWithArgs.Enabled := false;
|
||||
|
@ -474,7 +485,7 @@ begin
|
|||
//
|
||||
with TOpenDialog.Create(nil) do
|
||||
try
|
||||
filter := 'D source|*.d|D interface|*.di|all files|*.*';
|
||||
filter := DdiagFilter;
|
||||
if execute then
|
||||
begin
|
||||
openFile(filename);
|
||||
|
@ -512,10 +523,9 @@ begin
|
|||
//
|
||||
with TSaveDialog.Create(nil) do
|
||||
try
|
||||
Filter := DdiagFilter;
|
||||
if execute then
|
||||
begin
|
||||
saveFileAs(fEditWidg.editorIndex, filename);
|
||||
end;
|
||||
finally
|
||||
free;
|
||||
end;
|
||||
|
@ -640,7 +650,21 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TCEMainForm.actEdIndentExecute(Sender: TObject);
|
||||
var
|
||||
curr: TCESynMemo;
|
||||
begin
|
||||
curr := fEditWidg.currentEditor;
|
||||
if assigned(curr) then curr.ExecuteCommand(ecBlockIndent, '', nil);
|
||||
end;
|
||||
|
||||
procedure TCEMainForm.actEdUnIndentExecute(Sender: TObject);
|
||||
var
|
||||
curr: TCESynMemo;
|
||||
begin
|
||||
curr := fEditWidg.currentEditor;
|
||||
if assigned(curr) then curr.ExecuteCommand(ecBlockUnIndent, '', nil);
|
||||
end;
|
||||
{$ENDREGION}
|
||||
|
||||
{$REGION run ******************************************************************}
|
||||
|
|
|
@ -4,6 +4,10 @@ unit ce_project;
|
|||
|
||||
interface
|
||||
|
||||
// TODO: pre/post compilation shell-script / process
|
||||
// TODO: run opts, newConsole, catch output, etc
|
||||
// TODO: configuration templates
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ce_dmdwrap;
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ interface
|
|||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, TreeFilterEdit, Forms, Controls, Graphics,
|
||||
actnlist, Dialogs, ExtCtrls, ComCtrls, Menus, Buttons, ce_project, ce_widget;
|
||||
actnlist, Dialogs, ExtCtrls, ComCtrls, Menus, Buttons, ce_project,
|
||||
ce_common, ce_widget;
|
||||
|
||||
type
|
||||
{ TCEProjectInspectWidget }
|
||||
|
@ -166,7 +167,7 @@ begin
|
|||
//
|
||||
with TOpenDialog.Create(nil) do
|
||||
try
|
||||
filter := 'D source|*.d|D interface|*.di|all files|*.*';
|
||||
filter := DdiagFilter;
|
||||
if execute then
|
||||
fProject.addSource(filename);
|
||||
finally
|
||||
|
|
|
@ -1,48 +1,37 @@
|
|||
inherited CESearchWidget: TCESearchWidget
|
||||
Left = 1338
|
||||
Height = 276
|
||||
Top = 697
|
||||
Width = 405
|
||||
Left = 1468
|
||||
Height = 237
|
||||
Top = 516
|
||||
Width = 394
|
||||
Caption = 'Search & replace'
|
||||
ClientHeight = 276
|
||||
ClientWidth = 405
|
||||
ClientHeight = 237
|
||||
ClientWidth = 394
|
||||
inherited Back: TPanel
|
||||
Height = 276
|
||||
Width = 405
|
||||
ClientHeight = 276
|
||||
ClientWidth = 405
|
||||
Height = 237
|
||||
Width = 394
|
||||
ClientHeight = 237
|
||||
ClientWidth = 394
|
||||
inherited Content: TPanel
|
||||
Height = 276
|
||||
Width = 405
|
||||
ClientHeight = 276
|
||||
ClientWidth = 405
|
||||
Height = 237
|
||||
Width = 394
|
||||
ClientHeight = 237
|
||||
ClientWidth = 394
|
||||
object cbToFind: TComboBox[0]
|
||||
Left = 4
|
||||
Height = 23
|
||||
Top = 4
|
||||
Width = 397
|
||||
Width = 386
|
||||
Align = alTop
|
||||
BorderSpacing.Around = 4
|
||||
ItemHeight = 15
|
||||
OnChange = cbToFindChange
|
||||
TabOrder = 0
|
||||
end
|
||||
object cbReplaceWth: TComboBox[1]
|
||||
Left = 4
|
||||
Height = 23
|
||||
Top = 31
|
||||
Width = 397
|
||||
Align = alTop
|
||||
BorderSpacing.Around = 4
|
||||
ItemHeight = 15
|
||||
OnChange = cbReplaceWthChange
|
||||
TabOrder = 1
|
||||
end
|
||||
object btnFind: TBitBtn[2]
|
||||
object btnFind: TBitBtn[1]
|
||||
Left = 4
|
||||
Height = 24
|
||||
Top = 192
|
||||
Width = 397
|
||||
Top = 153
|
||||
Width = 386
|
||||
Align = alBottom
|
||||
BorderSpacing.Around = 4
|
||||
Caption = 'btnFind'
|
||||
|
@ -82,13 +71,13 @@ inherited CESearchWidget: TCESearchWidget
|
|||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
|
||||
}
|
||||
TabOrder = 2
|
||||
TabOrder = 1
|
||||
end
|
||||
object btnReplace: TBitBtn[3]
|
||||
object btnReplace: TBitBtn[2]
|
||||
Left = 4
|
||||
Height = 24
|
||||
Top = 220
|
||||
Width = 397
|
||||
Top = 181
|
||||
Width = 386
|
||||
Align = alBottom
|
||||
BorderSpacing.Around = 4
|
||||
Caption = 'btnReplace'
|
||||
|
@ -128,19 +117,19 @@ inherited CESearchWidget: TCESearchWidget
|
|||
4766E69547FFE69A4EFFE2904122FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
|
||||
}
|
||||
TabOrder = 3
|
||||
TabOrder = 2
|
||||
end
|
||||
object grpOpts: TGroupBox[4]
|
||||
object grpOpts: TGroupBox[3]
|
||||
Left = 4
|
||||
Height = 130
|
||||
Top = 58
|
||||
Width = 397
|
||||
Height = 88
|
||||
Top = 61
|
||||
Width = 386
|
||||
Align = alClient
|
||||
BorderSpacing.Around = 4
|
||||
Caption = 'Options'
|
||||
ClientHeight = 112
|
||||
ClientWidth = 393
|
||||
TabOrder = 4
|
||||
ClientHeight = 70
|
||||
ClientWidth = 382
|
||||
TabOrder = 3
|
||||
object chkWWord: TCheckBox
|
||||
Left = 8
|
||||
Height = 19
|
||||
|
@ -184,11 +173,11 @@ inherited CESearchWidget: TCESearchWidget
|
|||
TabOrder = 4
|
||||
end
|
||||
end
|
||||
object btnReplaceAll: TBitBtn[5]
|
||||
object btnReplaceAll: TBitBtn[4]
|
||||
Left = 4
|
||||
Height = 24
|
||||
Top = 248
|
||||
Width = 397
|
||||
Top = 209
|
||||
Width = 386
|
||||
Align = alBottom
|
||||
BorderSpacing.Around = 4
|
||||
Caption = 'btnReplaceAll'
|
||||
|
@ -228,12 +217,49 @@ inherited CESearchWidget: TCESearchWidget
|
|||
4766E69547FFE69A4EFFE2904122FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
|
||||
}
|
||||
TabOrder = 4
|
||||
end
|
||||
object Panel1: TPanel[5]
|
||||
Left = 4
|
||||
Height = 26
|
||||
Top = 31
|
||||
Width = 386
|
||||
Align = alTop
|
||||
BorderSpacing.Around = 4
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 26
|
||||
ClientWidth = 386
|
||||
TabOrder = 5
|
||||
object cbReplaceWth: TComboBox
|
||||
Left = 90
|
||||
Height = 23
|
||||
Top = 0
|
||||
Width = 296
|
||||
Align = alClient
|
||||
ItemHeight = 15
|
||||
OnChange = cbReplaceWthChange
|
||||
TabOrder = 0
|
||||
end
|
||||
object chkEnableRep: TCheckBox
|
||||
Left = 0
|
||||
Height = 26
|
||||
Top = 0
|
||||
Width = 90
|
||||
Align = alLeft
|
||||
Caption = 'Replace with '
|
||||
OnChange = chkEnableRepChange
|
||||
TabOrder = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
inherited contextMenu: TPopupMenu
|
||||
left = 216
|
||||
top = 16
|
||||
end
|
||||
object imgList: TImageList[2]
|
||||
left = 32
|
||||
left = 248
|
||||
top = 16
|
||||
Bitmap = {
|
||||
4C690200000010000000100000007B7977007B7977007B7977FF73716FFF6D6B
|
||||
69FF696665FF625F5EFF615E5D007E7C7A007B7977FF73716FFF6D6B69FF6966
|
||||
|
|
|
@ -19,6 +19,7 @@ type
|
|||
btnReplaceAll: TBitBtn;
|
||||
cbToFind: TComboBox;
|
||||
cbReplaceWth: TComboBox;
|
||||
chkEnableRep: TCheckBox;
|
||||
chkPrompt: TCheckBox;
|
||||
chkWWord: TCheckBox;
|
||||
chkBack: TCheckBox;
|
||||
|
@ -26,8 +27,10 @@ type
|
|||
chkCaseSens: TCheckBox;
|
||||
grpOpts: TGroupBox;
|
||||
imgList: TImageList;
|
||||
Panel1: TPanel;
|
||||
procedure cbReplaceWthChange(Sender: TObject);
|
||||
procedure cbToFindChange(Sender: TObject);
|
||||
procedure chkEnableRepChange(Sender: TObject);
|
||||
private
|
||||
fEditor: TCESynMemo;
|
||||
fToFind: string;
|
||||
|
@ -35,6 +38,7 @@ type
|
|||
fActFindNext, fActReplaceNext: TAction;
|
||||
fActReplaceAll: TAction;
|
||||
fSearchMru, fReplaceMru: TMruList;
|
||||
fCancelAll: boolean;
|
||||
function getOptions: TSynSearchOptions;
|
||||
procedure actFindNextExecute(sender: TObject);
|
||||
procedure actReplaceAllExecute(sender: TObject);
|
||||
|
@ -56,24 +60,24 @@ implementation
|
|||
|
||||
constructor TCESearchWidget.Create(aOwner: TComponent);
|
||||
begin
|
||||
inherited;
|
||||
fID := 'ID_FIND';
|
||||
//
|
||||
fSearchMru := TMruList.Create;
|
||||
fReplaceMru:= TMruList.Create;
|
||||
//
|
||||
fActFindNext := TAction.Create(self);
|
||||
fActFindNext.Caption := 'Find';
|
||||
fActFindNext.OnExecute := @actFindNextExecute;
|
||||
btnFind.Action := fActFindNext;
|
||||
fActReplaceNext := TAction.Create(self);
|
||||
fActReplaceNext.Caption := 'Replace';
|
||||
fActReplaceNext.OnExecute := @actReplaceNextExecute;
|
||||
btnReplace.Action := fActReplaceNext;
|
||||
fActReplaceAll := TAction.Create(self);
|
||||
fActReplaceAll.Caption := 'Replace all';
|
||||
fActReplaceAll.OnExecute := @actReplaceAllExecute;
|
||||
inherited;
|
||||
fID := 'ID_FIND';
|
||||
//
|
||||
btnFind.Action := fActFindNext;
|
||||
btnReplace.Action := fActReplaceNext;
|
||||
btnReplaceAll.Action := fActReplaceAll;
|
||||
//
|
||||
fSearchMru := TMruList.Create;
|
||||
fReplaceMru:= TMruList.Create;
|
||||
end;
|
||||
|
||||
destructor TCESearchWidget.Destroy;
|
||||
|
@ -101,6 +105,12 @@ begin
|
|||
fToFind := cbToFind.Text;
|
||||
end;
|
||||
|
||||
procedure TCESearchWidget.chkEnableRepChange(Sender: TObject);
|
||||
begin
|
||||
if Updating then exit;
|
||||
UpdateByEvent;
|
||||
end;
|
||||
|
||||
procedure TCESearchWidget.cbReplaceWthChange(Sender: TObject);
|
||||
begin
|
||||
if Updating then exit;
|
||||
|
@ -109,7 +119,7 @@ end;
|
|||
|
||||
function TCESearchWidget.getOptions: TSynSearchOptions;
|
||||
begin
|
||||
result := [];
|
||||
result := [ssoRegExpr];
|
||||
if chkWWord.Checked then result += [ssoWholeWord];
|
||||
if chkBack.Checked then result += [ssoBackwards];
|
||||
if chkCaseSens.Checked then result += [ssoMatchCase];
|
||||
|
@ -160,23 +170,45 @@ begin
|
|||
begin
|
||||
if fEditor.SearchReplace(fToFind, fReplaceWth, opts) = 0
|
||||
then break;
|
||||
if fCancelAll then
|
||||
begin
|
||||
fCancelAll := false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
fEditor.OnReplaceText := nil;
|
||||
UpdateByEvent;
|
||||
end;
|
||||
|
||||
function dlgReplaceAll: TModalResult;
|
||||
const
|
||||
Btns = [mbYes, mbNo, mbYesToAll, mbNoToAll];
|
||||
begin
|
||||
exit( MessageDlg('Coedit', 'Replace this match ?', mtConfirmation, Btns, ''));
|
||||
end;
|
||||
|
||||
procedure TCESearchWidget.replaceEvent(Sender: TObject; const ASearch, AReplace:
|
||||
string; Line, Column: integer; var ReplaceAction: TSynReplaceAction);
|
||||
begin
|
||||
ReplaceAction := raSkip;
|
||||
if dlgOkCancel('Replace this match ?') = mrOK then
|
||||
ReplaceAction := raReplace;
|
||||
case dlgReplaceAll of
|
||||
mrYes: ReplaceAction := raReplace;
|
||||
mrNo: ReplaceAction := raSkip;
|
||||
mrYesToAll: ReplaceAction := raReplaceAll;
|
||||
mrCancel, mrClose, mrNoToAll:
|
||||
begin
|
||||
ReplaceAction := raCancel;
|
||||
fCancelAll := true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCESearchWidget.UpdateByEvent;
|
||||
begin
|
||||
fActFindNext.Enabled := fEditor <> nil;
|
||||
fActReplaceNext.Enabled := fEditor <> nil;
|
||||
fActReplaceNext.Enabled := (fEditor <> nil) and (chkEnableRep.Checked);
|
||||
fActReplaceAll.Enabled := (fEditor <> nil) and (chkEnableRep.Checked);
|
||||
cbReplaceWth.Enabled := (fEditor <> nil) and (chkEnableRep.Checked);
|
||||
cbToFind.Enabled := fEditor <> nil;
|
||||
//
|
||||
cbToFind.Items.Assign(fSearchMru);
|
||||
cbReplaceWth.Items.Assign(fReplaceMru);
|
||||
|
|
|
@ -38,7 +38,8 @@ begin
|
|||
TabWidth := 4;
|
||||
Options :=
|
||||
[ eoAutoIndent, eoBracketHighlight, eoGroupUndo, eoTabsToSpaces,
|
||||
eoTrimTrailingSpaces, eoDragDropEditing, eoShowCtrlMouseLinks];
|
||||
eoTrimTrailingSpaces, eoDragDropEditing, eoShowCtrlMouseLinks,
|
||||
eoEnhanceHomeKey, eoTabIndent];
|
||||
Options2 := [eoEnhanceEndKey, eoFoldedCopyPaste, eoOverwriteBlock];
|
||||
//
|
||||
Gutter.LineNumberPart.ShowOnlyLineNumbersMultiplesOf := 5;
|
||||
|
|
|
@ -9,6 +9,8 @@ uses
|
|||
|
||||
type
|
||||
|
||||
// TODO: interface for document content access/modification
|
||||
|
||||
(**
|
||||
* An implementer is informed when a new document is added, focused or closed.
|
||||
*)
|
||||
|
|
Loading…
Reference in New Issue