dexed/src/ce_dfmt.pas

228 lines
6.3 KiB
Plaintext

unit ce_dfmt;
{$I ce_defines.inc}
interface
uses
Classes, SysUtils, FileUtil, RTTIGrids, Forms, Controls, Graphics, ExtCtrls,
Menus, Buttons, process, ce_widget, ce_interfaces, ce_observer, ce_synmemo,
ce_writableComponent, ce_common, ce_sharedres, PropEdits, ObjectInspector;
type
DfmtEol = (cr, lf, crlf);
DfmtIdentstyle = (tab, space);
DfmtBraceStyle = (allman, otbs, stroustrup);
// wraps dfmt options to build the command line with ease
// and allows to save the options between session.
TCEDmtWrapper = class(TWritableLfmTextComponent)
private
fEol: DfmtEol;
fTabStyle: DfmtIdentstyle;
fIdentSize: integer;
fTabWidth: integer;
fHardLLen: integer;
fSoftLLen: integer;
fBraceStyle: DfmtBraceStyle;
fSpaceCast: boolean;
fSplitOp: boolean;
fCompactLbl: boolean;
fSpaceSelImp: boolean;
published
property endOfline: DfmtEol read fEol write fEol default lf;
property identationStyle: DfmtIdentstyle read fTabStyle write fTabStyle default space;
property identSize: integer read fIdentSize write fIdentSize default 4;
property tabWidth: integer read fTabWidth write fTabWidth default 8;
property hardLineLen: integer read fHardLLen write fHardLLen default 120;
property softLineLen: integer read fSoftLLen write fSoftLLen default 80;
property braceStyle: DfmtBraceStyle read fBraceStyle write fBraceStyle default allman;
property spaceAfterCast: boolean read fSpaceCast write fSpaceCast default true;
property spaceAfterImport: boolean read fSpaceSelImp write fSpaceSelImp default true;
property splitOpAtPrevLine: boolean read fSplitOp write fSplitOp default true;
property compactLabeledStatements: boolean read fCompactLbl write fCompactLbl default true;
public
constructor create(AOwner: TComponent); override;
procedure getCommandLine(str: TStrings);
end;
{ TCEDfmtWidget }
TCEDfmtWidget = class(TCEWidget, ICEMultiDocObserver)
btnApply: TSpeedButton;
btnCancel: TSpeedButton;
pnlFooter: TPanel;
dfmtOptionEditor: TTIPropertyGrid;
procedure dfmtOptionEditorEditorFilter(Sender: TObject;
aEditor: TPropertyEditor; var aShow: boolean);
private
fDoc: TCESynMemo;
fBackup: TStringList;
fDmtWrapper: TCEDmtWrapper;
//
procedure docNew(aDoc: TCESynMemo);
procedure docFocused(aDoc: TCESynMemo);
procedure docChanged(aDoc: TCESynMemo);
procedure docClosing(aDoc: TCESynMemo);
//
procedure doApply(sender: TObject);
procedure doCancel(sender: TObject);
public
constructor create(aOwner: TComponent); override;
destructor destroy; override;
end;
implementation
{$R *.lfm}
const
optFname = 'dfmt.txt';
{$REGION Standard Comp/Obj------------------------------------------------------}
constructor TCEDfmtWidget.create(aOwner: TComponent);
var
fname: string;
begin
inherited;
fDmtWrapper := TCEDmtWrapper.Create(self);
fBackup := TStringList.Create;
//
fname := getCoeditDocPath + optFname;
if fileExists(fname) then
fDmtWrapper.loadFromFile(fname);
//
btnCancel.OnClick := @doCancel;
btnApply.OnClick := @doApply;
AssignPng(btnCancel, 'cancel');
AssignPng(btnApply, 'accept');
//
dfmtOptionEditor.TIObject := fDmtWrapper;
end;
destructor TCEDfmtWidget.destroy;
begin
dfmtOptionEditor.TIObject := nil;
fDmtWrapper.saveToFile(getCoeditDocPath + optFname);
fBackup.Free;
inherited;
end;
constructor TCEDmtWrapper.create(AOwner: TComponent);
begin
inherited;
fEol := lf;
fTabStyle := DfmtIdentstyle.space;
fIdentSize := 4;
fTabWidth := 8;
fHardLLen := 120;
fSoftLLen := 80;
fBraceStyle := DfmtBraceStyle.allman;
fSpaceCast := true;
fSpaceSelImp := true;
fSplitOp := true;
fCompactLbl := true;
end;
procedure TCEDfmtWidget.dfmtOptionEditorEditorFilter(Sender: TObject;
aEditor: TPropertyEditor; var aShow: boolean);
begin
case aEditor.GetName of
'Tag', 'Name': aShow := false;
else aShow := true;
end;
end;
{$ENDREGION}
{$REGION ICEMultiDocObserver ---------------------------------------------------}
procedure TCEDfmtWidget.docNew(aDoc: TCESynMemo);
begin
fDoc := aDoc;
end;
procedure TCEDfmtWidget.docFocused(aDoc: TCESynMemo);
begin
if aDoc = fDoc
then exit;
fDoc := aDoc;
end;
procedure TCEDfmtWidget.docChanged(aDoc: TCESynMemo);
begin
end;
procedure TCEDfmtWidget.docClosing(aDoc: TCESynMemo);
begin
if fDoc <> aDoc then
exit;
fDoc := nil;
end;
{$ENDREGION}
{$REGION Dfmt things -----------------------------------------------------------}
procedure TCEDmtWrapper.getCommandLine(str: TStrings);
const
eol: array[DfmtEol] of string = ('cr', 'lf', 'crlf');
falsetrue: array[boolean] of string = ('false', 'true');
idtstyle: array[DfmtIdentstyle] of string = ('tab', 'space');
brc: array[DfmtBraceStyle] of string = ('allman', 'otbs', 'stroustrup');
begin
str.Add('--end_of_line=' + eol[endOfline]);
str.Add('--max_line_length=' + intToStr(hardLineLen));
str.Add('--soft_max_line_length=' + intToStr(softLineLen));
str.Add('--indent_size=' + intToStr(identSize));
str.Add('--indent_style=' + idtstyle[identationStyle]);
str.Add('--tab_width=' + intToStr(tabWidth));
str.Add('--brace_style=' + brc[braceStyle]);
str.Add('--split_operator_at_line_end=' + falsetrue[splitOpAtPrevLine]);
str.Add('--space_after_cast=' + falsetrue[spaceAfterCast]);
str.Add('--selective_import_space=' + falsetrue[spaceAfterImport]);
str.Add('--compact_labeled_statements=' + falsetrue[compactLabeledStatements]);
end;
procedure TCEDfmtWidget.doApply(sender: TObject);
var
inp: string;
prc: TProcess;
str: TStringList;
begin
if not assigned(fDoc) then
exit;
fBackup.Assign(fDoc.Lines);
prc := TProcess.create(nil);
try
fDmtWrapper.getCommandLine(prc.Parameters);
prc.Options:= prc.Options + [poUsePipes, poStderrToOutPut];
prc.Executable:= exeFullName('dfmt' + exeExt);
prc.Execute;
inp := fDoc.Lines.Text;
prc.Input.Write(inp[1], length(inp));
prc.CloseInput;
while prc.Running do (*!*);
try
str := TStringList.Create;
processOutputToStrings(prc,str);
fDoc.SelectAll;
fDoc.SelText:= str.Text;
except
fDoc.Lines.Assign(fBackup);
end;
finally
prc.free;
str.free;
end;
end;
procedure TCEDfmtWidget.doCancel(sender: TObject);
begin
if not assigned(fDoc) then
exit;
fDoc.Lines.Assign(fBackup);
end;
{$ENDREGION}
end.