📄 editor.pas
字号:
unit Editor;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, Menus,utils, mwCustomEdit, mwHighlighter,
typinfo, DFMUtils, ImgList, dmDfmSyn, mwPasSyn, mwCompletionProposal;
type
TWrAction= (wrInsert, wrDelete, wrRename);
TUnitState=(usNone, usNew,usOpen,usSave,usChange);
TParserUnit = class(TObject)
private
fUnitName:string;
fUnitState : TUnitState;
fUnitSource:TStringList;
procedure SetUnitName(FileName:string);
protected
function GetStrPos(const Str:string):Integer;
public
constructor Create(const FileName:string);
destructor Destroy; override;
procedure SetUnitSource(List: TStrings);
property UnitName : string read fUnitName write SetUnitName;
property UnitState : TUnitState read fUnitState write fUnitState;
property UnitSource : TStringList read fUnitSource write fUnitSource;
end;
TEditorForm = class(TForm)
StatusBar: TStatusBar;
PageControl1: TPageControl;
OpenDialog1: TOpenDialog;
MsgViewPopupMenu: TPopupMenu;
mvViewSourceItem: TMenuItem;
mvAltViewSourceItem: TMenuItem;
mvEditSourceItem: TMenuItem;
mvAltEditSourceItem: TMenuItem;
N3: TMenuItem;
ClearCompilerMessagesItem: TMenuItem;
ClearSearchResultsItem: TMenuItem;
EditorLocalMenu: TPopupMenu;
ecClosePage: TMenuItem;
ecOpenFileAtCursor: TMenuItem;
ecNewEditWindow: TMenuItem;
ecBrowseSymbolAtCursor: TMenuItem;
ecTopicSearch: TMenuItem;
ecAddtoInterface: TMenuItem;
ecToggleBreakpoint: TMenuItem;
ecGotoCursor: TMenuItem;
ecEvaluateModify: TMenuItem;
ecAddWatchAtCursor: TMenuItem;
MenuItem1: TMenuItem;
ecViewAsFormItem: TMenuItem;
ecReadOnlyItem: TMenuItem;
ecMessageView: TMenuItem;
MenuItem2: TMenuItem;
ecPropertiesItem: TMenuItem;
SmallGutterImages: TImageList;
LargeGutterImages: TImageList;
PasSyn: TmwPasSyn;
N1: TMenuItem;
ToggleBookmakrs1: TMenuItem;
GotoBookamrks1: TMenuItem;
Bookamrk01: TMenuItem;
Bookmark11: TMenuItem;
Bookmark21: TMenuItem;
Bookmark31: TMenuItem;
Bookmark41: TMenuItem;
Bookmark51: TMenuItem;
Bookmark61: TMenuItem;
Bookmark71: TMenuItem;
Bookmark81: TMenuItem;
Bookmark91: TMenuItem;
Bookmark01: TMenuItem;
Bookmark12: TMenuItem;
Bookmark22: TMenuItem;
Bookmark32: TMenuItem;
Bookmark42: TMenuItem;
Bookmark52: TMenuItem;
Bookmark62: TMenuItem;
Bookmark72: TMenuItem;
Bookmark82: TMenuItem;
Bookmark92: TMenuItem;
DfmSyn: TdmDfmSyn;
MwCompletionProposal1: TMwCompletionProposal;
mwAutoComplete1: TmwAutoComplete;
ecViewExplorerItem: TMenuItem;
ecViewCodeTemplate: TMenuItem;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure PageControl1Change(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure ecClosePageClick(Sender: TObject);
procedure ecOpenFileAtCursorClick(Sender: TObject);
procedure ecReadOnlyItemClick(Sender: TObject);
procedure Bookamrk01Click(Sender: TObject);
procedure Bookmark01Click(Sender: TObject);
procedure ecTopicSearchClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ecViewAsFormItemClick(Sender: TObject);
procedure MwCompletionProposal1Execute(Sender: TObject);
procedure PasSynToken(Sender: TObject; TokenKind: Integer;
TokenText: String; LineNo: Integer);
procedure ecViewExplorerItemClick(Sender: TObject);
procedure ecViewCodeTemplateClick(Sender: TObject);
procedure MwCompletionProposal1CodeCompletion(var Value: String;
var X: Integer);
private
{ Private declarations }
ParserUnit: TParserUnit;
function GetStringPos(const S:string; WholeWord: Boolean):Integer;
procedure CaretInfo;
function IsIncludeUnit(UnitName:string): Boolean;
procedure ReplaceSelText(Replace:string);
function GetEventHandlerPosition(const EventName:string):Integer;
protected
procedure OnGetMinMaxInfo(var msg : TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
procedure CodeTemplateValidate(Sender: TObject);
public
{ Public declarations }
procedure WriteComponentCode(Component:string;ComponentClass:
TComponentClass;Action:TWrAction);
procedure WriteEventCode(Event:string);
procedure GotoLine(PasEdit:TmwCustomEdit;Line:Integer);
function GetLinkEditor:TmwCustomEdit;
function SetFocusEventHandler(const EventName:string):Boolean;
procedure RenameUnit(UnitName:string);
procedure NewSheet(const FileName:string);
function GetCursorWord:string;
function GetLinkWithFile(const FileName:string): TmwCustomEdit;
procedure CheckUseUnit(Component: TComponent);
procedure AddUseUnit(UnitName:string);
procedure StatusChangeHandler(Sender: TObject; Changes: TmwStatusChanges);
end;
TParseState = (psIdle, psInClassDef, psProcSeen, psWaitForSymbol);
var
EditorForm: TEditorForm;
ParseState: TParseState;
ProcedureName: string;
CompletionProposalForm: TCompletionProposalForm;
implementation
uses MainForm,Uconst, utype, Proxy, ObjectInspec;
var
Insert:boolean;
{$R *.DFM}
{TParserUnit}
constructor TParserUnit.Create(const FileName:string);
begin
fUnitState:= usNone;
FUnitSource:= TStringList.Create;
end;
destructor TParserUnit.Destroy;
begin
FUnitSource.Free;
inherited;
end;
function TParserUnit.GetStrPos(const Str:string):Integer;
// unit 家胶俊辑 漂沥茄 巩磊凯捞 乐绰 青阑 舅妨霖促.
var
I:Integer;
begin
Result:=-1;
for I:=0 to UnitSource.Count-1 do
if Pos(Str,UnitSource[I])>0 then
begin
Result:=I;
Exit;
end;
end;
procedure TParserUnit.SetUnitName(FileName:string);
begin
if FileName = '' then Exit;
if fUnitName <> FileName then
begin
fUnitName:= FileName;
if FileExists(FileName) then
fUnitSource.LoadFromFile(FileName);
end;
end;
procedure TParserUnit.SetUnitSource(List: TStrings);
begin
if Assigned(List) then fUnitSource.Assign(List);
end;
{TEditorForm}
procedure TEditorForm.OnGetMinMaxInfo(var msg : TWMGetMinMaxInfo);
// Editor狼 汽阑 弥措拳且 锭, 汽狼 农扁甫 皋牢汽阑 力寇茄 康开栏肺 汲沥茄促.
begin
inherited;
msg.MinMaxInfo^.ptMaxPosition.y := Top;
msg.MinMaxInfo^.ptMaxTrackSize.x := Screen.Width;
msg.MinMaxInfo^.ptMaxTrackSize.y := Screen.Height - Top;
end;
procedure TEditorForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
I,SaveResp:integer;
FileName:string;
begin
for I := PageControl1.PageCount-1 downto 0 do
begin
FileName:=(PageControl1.Pages[I]).Caption;
if (PageControl1.Pages[I].Controls[0] as TmwCustomEdit).Modified then
begin
SaveResp := MessageDlg(Format('Save Changes to %s?',
[ExtractFilename(FileName)]), mtWarning, mbYesNoCancel, 0);
case SaveResp of
idYes: FMainForm.SaveFile(ProjectPath+Caption);
idNo: ;
idCancel: Abort;
end;
end;
end;
end;
procedure TEditorForm.PageControl1Change(Sender: TObject);
begin
// set caption to active filename
if ExtractFileExt(PageControl1.ActivePage.Caption)= '' then
// if active file is pascal file, then add extension '.pas'
Caption:=PageControl1.ActivePage.Caption+'.pas'
else Caption:=PageControl1.ActivePage.Caption;
FMainForm.ActiveUnit:=
FMainForm.OpenUnitList[PageControl1.ActivePage.Controls[0].Tag].FileName;
ActivePasEditor:= TmwCustomEdit(PageControl1.ActivePage.Controls[0]);
end;
procedure TEditorForm.WriteComponentCode(Component:string;ComponentClass:
TComponentClass;Action:TWrAction);
// Write/Modify code for component when created, deleted, modified
const
ClassName= 'TForm';
var
InsertPos: Integer;
PasEdit: TmwCustomEdit;
begin
PasEdit:= GetLinkEditor;
if Action = wrInsert then
InsertPos:= GetStringPos(ClassName, False) // search position for inserting
else
InsertPos:= GetStringPos(Component, False);
if InsertPos = 0 then Exit;
case Action of
wrInsert: // insert code
begin
PasEdit.Lines.Insert(InsertPos+1,' '+Component+':'+ComponentClass.ClassName+';');
end;
wrDelete: // delete code
PasEdit.Lines.Delete(InsertPos);
end;
end;
function TEditorForm.GetStringPos(const S:string; WholeWord: Boolean):Integer;
// Return row position that include text S
var
I: Integer;
PasEdit: TmwCustomEdit;
begin
Result:=0;
PasEdit:= GetLinkEditor;
with PasEdit do
begin
for I:=0 to Lines.Count-1 do
begin
if WholeWord then
begin
if CompareText(S, Trim(Lines[I])) = 0 then
begin
Result:= I;
Exit;
end;
end
else
begin
if Pos(S,Lines[I])>0 then
begin
Result:= I;
Exit;
end;
end;
end;
end;
end;
function TEditorForm.GetEventHandlerPosition(const EventName:string):Integer;
// Return event handler's row position
var
I: Integer;
PasEdit: TmwCustomEdit;
begin
Result:= 0;
PasEdit:= GetLinkEditor;
with PasEdit do
begin
for I:=Lines.Count - 1 downto 0 do
begin
if Pos(EventName, Lines[I])> 0 then
begin
Result:= I;
Exit;
end;
end;
end;
end;
// Write event handler code for Event
procedure TEditorForm.WriteEventCode(Event:string);
var
PasEdit: TmwCustomEdit;
InsertPos: Integer;
begin
SetFocus;
PasEdit:= GetLinkEditor;
with PasEdit.Lines do
begin
// write event handler declare code
InsertPos:= GetStringPos('private', True);
if InsertPos <> 0 then
Insert(InsertPos, Ident + Ident + 'procedure ' + Event);
// write event handler definition code
Insert(Count-2, '');
Insert(Count-2, 'procedure '+'T'+ FMainForm.ActiveForm.Name+'.'+Event);
Insert(Count-2, 'begin');
Insert(Count-2, '');
Insert(Count-2, 'end;');
end;
PasEdit.SetFocus;
GotoLine(PasEdit, PasEdit.Lines.Count-3);
end;
procedure TEditorForm.GotoLine(PasEdit:TmwCustomEdit;Line:Integer);
begin
// goto line number Line
PasEdit.CaretX:= 0;
PasEdit.CaretY:= Line;
end;
function TEditorForm.GetLinkEditor:TmwCustomEdit;
var
I:Integer;
FileName:string;
begin
// Get active editor linked with active form
Result:=TmwCustomEdit(PageControl1.ActivePage.Controls[0]);
for I:=0 to PageControl1.PageCount-1 do
begin
FileName:= ExtractFileName(FMainForm.ActiveUnit);
if TTabSheet(PageControl1.Pages[I]).Caption = FileName then
Result:= TmwCustomEdit(PageControl1.Pages[I].Controls[0]);
end;
end;
function TEditorForm.SetFocusEventHandler(const EventName:string):Boolean;
// Find event handler position at editor, then move caret to the position
var
PasEdit: TmwCustomEdit;
FindPos:Integer;
begin
Result:= True;
SetFocus;
PasEdit:= GetLinkEditor;
FindPos:= GetEventHandlerPosition(EventName);
PasEdit.SetFocus;
GotoLine(PasEdit, FindPos + 3);
Result:= (FindPos <> 0);
end;
procedure TEditorForm.RenameUnit(UnitName:string);
// Rename active unit name to UnitName
var
PasEdit:TmwCustomEdit;
Name:string;
Po: Integer;
begin
PasEdit:= GetLinkWithFile(UnitName);
if PasEdit = nil then Exit;
Po:= ParserUnit.GetStrPos('unit');
if Po = -1 then Exit;
Name:= PasEdit.Lines[Po];
if Pos('unit', Name) > 0 then
PasEdit.Lines[Po]:= Format('%s %s;',['unit',GetNetFileName(UnitName)]);
end;
procedure TEditorForm.FormActivate(Sender: TObject);
begin
FMainForm.ToggleFormUnit:= False;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -