SynEdit, Gutter: Renamed some of the new methods (Thanks Mark W. for the Feedback)

git-svn-id: trunk@18386 -
This commit is contained in:
martin 2009-01-21 22:47:33 +00:00
parent 5f1115bfee
commit d4af1c75ec
6 changed files with 81 additions and 129 deletions

View File

@ -1554,7 +1554,7 @@ end;
procedure TCustomSynEdit.GetChildren(Proc: TGetChildProc; Root: TComponent); procedure TCustomSynEdit.GetChildren(Proc: TGetChildProc; Root: TComponent);
begin begin
Proc(FGutter.PartList); Proc(FGutter.Parts);
end; end;
procedure TCustomSynEdit.CreateParams(var Params: TCreateParams); procedure TCustomSynEdit.CreateParams(var Params: TCreateParams);
@ -3326,7 +3326,7 @@ var
fMarkupManager.FinishMarkupForRow(FFoldedLinesView.TextIndex[CurLine]+1); fMarkupManager.FinishMarkupForRow(FFoldedLinesView.TextIndex[CurLine]+1);
// codefold draw splitter line // codefold draw splitter line
if Gutter.PartByClassVisible[TSynGutterCodeFolding] if Gutter.CodeFoldPart.Visible
and (FFoldedLinesView.DrawDivider[curLine]) then and (FFoldedLinesView.DrawDivider[curLine]) then
begin begin
ypos := rcToken.Bottom - 1; ypos := rcToken.Bottom - 1;
@ -3431,7 +3431,7 @@ begin
end; end;
// codefold draw splitter line // codefold draw splitter line
if Gutter.PartByClassVisible[TSynGutterCodeFolding] if Gutter.CodeFoldPart(0).Visible
and (FFoldedLinesView.DrawDivider[LastLine]) then and (FFoldedLinesView.DrawDivider[LastLine]) then
begin begin
ypos := rcToken.Bottom - 1; ypos := rcToken.Bottom - 1;
@ -7836,7 +7836,7 @@ end;
procedure TCustomSynEdit.MarkTextAsSaved; procedure TCustomSynEdit.MarkTextAsSaved;
begin begin
TSynEditStringList(fLines).MarkSaved; TSynEditStringList(fLines).MarkSaved;
if fGutter.Visible and fGutter.PartByClassVisible[TSynGutterChanges] then if fGutter.Visible and fGutter.ChangesPart(0).Visible then
InvalidateGutter; // Todo: Make the ChangeGutterPart an observer InvalidateGutter; // Todo: Make the ChangeGutterPart an observer
end; end;

View File

@ -69,7 +69,7 @@ type
default 0; default 0;
property Visible: boolean read FVisible write SetVisible default TRUE; property Visible: boolean read FVisible write SetVisible default TRUE;
property Width: integer read FWidth write SetWidth default 30; property Width: integer read FWidth write SetWidth default 30;
property PartList; property Parts;
end; end;
{ TSynGutterSeparator } { TSynGutterSeparator }
@ -101,11 +101,11 @@ begin
AutoSize := True; AutoSize := True;
if not(csLoading in AOwner.ComponentState) then begin if not(csLoading in AOwner.ComponentState) then begin
TSynGutterMarks.Create(PartList); TSynGutterMarks.Create(Parts);
TSynGutterLineNumber.Create(PartList); TSynGutterLineNumber.Create(Parts);
TSynGutterChanges.Create(PartList); TSynGutterChanges.Create(Parts);
TSynGutterSeparator.Create(PartList); TSynGutterSeparator.Create(Parts);
TSynGutterCodeFolding.Create(PartList); TSynGutterCodeFolding.Create(Parts);
end; end;
end; end;
@ -145,7 +145,7 @@ begin
Result := FLeftOffset + FRightOffset; Result := FLeftOffset + FRightOffset;
for i := PartCount-1 downto 0 do for i := PartCount-1 downto 0 do
Result := Result + Part[i].RealGutterWidth(CharWidth); Result := Result + Parts[i].RealGutterWidth(CharWidth);
end; end;
procedure TSynGutter.SetLeftOffset(Value: integer); procedure TSynGutter.SetLeftOffset(Value: integer);
@ -241,15 +241,15 @@ begin
i := 0; i := 0;
x2 := x; x2 := x;
while i < PartCount-1 do begin while i < PartCount-1 do begin
if Part[i].Visible then begin if Parts[i].Visible then begin
if x2 >= Part[i].Width then if x2 >= Parts[i].Width then
x2 := x2 - Part[i].Width x2 := x2 - Parts[i].Width
else else
break; break;
end; end;
inc(i) inc(i)
end; end;
Part[i].DoOnGutterClick(X, Y); Parts[i].DoOnGutterClick(X, Y);
end; end;
procedure TSynGutter.Paint(Canvas: TCanvas; AClip: TRect; FirstLine, LastLine: integer); procedure TSynGutter.Paint(Canvas: TCanvas; AClip: TRect; FirstLine, LastLine: integer);
@ -279,11 +279,11 @@ begin
for i := 0 to PartCount -1 do for i := 0 to PartCount -1 do
begin begin
if rcLine.Right >= AClip.Right then break; if rcLine.Right >= AClip.Right then break;
if Part[i].Visible then if Parts[i].Visible then
begin begin
rcLine.Left := rcLine.Right; rcLine.Left := rcLine.Right;
rcLine.Right := min(rcLine.Left + Part[i].Width, AClip.Right); rcLine.Right := min(rcLine.Left + Parts[i].Width, AClip.Right);
Part[i].Paint(Canvas, rcLine, FirstLine, LastLine); Parts[i].Paint(Canvas, rcLine, FirstLine, LastLine);
end; end;
end; end;
end; end;
@ -292,33 +292,33 @@ procedure TSynGutter.AutoSizeDigitCount(LinesCount : integer);
var var
i: Integer; i: Integer;
begin begin
for i := 0 to PartByClassCount[TSynGutterLineNumber] - 1 do for i := 0 to Parts.ByClassCount[TSynGutterLineNumber] - 1 do
TSynGutterLineNumber(PartByClass[TSynGutterLineNumber, i]).AutoSizeDigitCount(LinesCount); TSynGutterLineNumber(Parts.ByClass[TSynGutterLineNumber, i]).AutoSizeDigitCount(LinesCount);
end; end;
function TSynGutter.LineNumberPart(Index: Integer = 0): TSynGutterLineNumber; function TSynGutter.LineNumberPart(Index: Integer = 0): TSynGutterLineNumber;
begin begin
Result := TSynGutterLineNumber(PartByClass[TSynGutterLineNumber, Index]); Result := TSynGutterLineNumber(Parts.ByClass[TSynGutterLineNumber, Index]);
end; end;
function TSynGutter.CodeFoldPart(Index: Integer = 0): TSynGutterCodeFolding; function TSynGutter.CodeFoldPart(Index: Integer = 0): TSynGutterCodeFolding;
begin begin
Result := TSynGutterCodeFolding(PartByClass[TSynGutterCodeFolding, Index]); Result := TSynGutterCodeFolding(Parts.ByClass[TSynGutterCodeFolding, Index]);
end; end;
function TSynGutter.ChangesPart(Index: Integer = 0): TSynGutterChanges; function TSynGutter.ChangesPart(Index: Integer = 0): TSynGutterChanges;
begin begin
Result := TSynGutterChanges(PartByClass[TSynGutterChanges, Index]); Result := TSynGutterChanges(Parts.ByClass[TSynGutterChanges, Index]);
end; end;
function TSynGutter.MarksPart(Index: Integer = 0): TSynGutterMarks; function TSynGutter.MarksPart(Index: Integer = 0): TSynGutterMarks;
begin begin
Result := TSynGutterMarks(PartByClass[TSynGutterMarks, Index]); Result := TSynGutterMarks(Parts.ByClass[TSynGutterMarks, Index]);
end; end;
function TSynGutter.SeparatorPart(Index: Integer = 0): TSynGutterSeparator; function TSynGutter.SeparatorPart(Index: Integer = 0): TSynGutterSeparator;
begin begin
Result := TSynGutterSeparator(PartByClass[TSynGutterSeparator, Index]); Result := TSynGutterSeparator(Parts.ByClass[TSynGutterSeparator, Index]);
end; end;
{ TSynGutterSeparator } { TSynGutterSeparator }

View File

@ -27,17 +27,12 @@ type
FColor: TColor; FColor: TColor;
procedure SetColor(const Value: TColor); procedure SetColor(const Value: TColor);
procedure SetGutterParts(const AValue: TSynGutterPartList); procedure SetGutterParts(const AValue: TSynGutterPartList);
function GetPartCount: integer;
function GetPartByClassCount(AClass: TSynGutterPartBaseClass): integer;
function GetPart(Index: Integer): TSynGutterPartBase;
function GetPartByClass(AClass: TSynGutterPartBaseClass; Index: Integer): TSynGutterPartBase;
function GetPartByClassVisible(AClass: TSynGutterPartBaseClass): Boolean;
procedure SetPartByClassVisible(AClass: TSynGutterPartBaseClass; const AValue: Boolean);
protected protected
procedure DoChange(Sender: TObject); virtual; procedure DoChange(Sender: TObject); virtual;
procedure DoDefaultGutterClick(Sender: TObject; X, Y, Line: integer; procedure DoDefaultGutterClick(Sender: TObject; X, Y, Line: integer;
mark: TSynEditMark); virtual; mark: TSynEditMark); virtual;
procedure RegisterNewGutterPartList(APartList: TSynGutterPartList); procedure RegisterNewGutterPartList(APartList: TSynGutterPartList);
function PartCount: integer;
procedure Clear; procedure Clear;
public public
constructor Create(AOwner : TSynEditBase; AFoldedLinesView: TSynEditFoldedView; constructor Create(AOwner : TSynEditBase; AFoldedLinesView: TSynEditFoldedView;
@ -45,16 +40,7 @@ type
destructor Destroy; override; destructor Destroy; override;
procedure Assign(Source: TPersistent); override; procedure Assign(Source: TPersistent); override;
public public
property PartList: TSynGutterPartList read FGutterPartList write SetGutterParts; property Parts: TSynGutterPartList read FGutterPartList write SetGutterParts;
property PartCount: integer read GetPartCount;
property Part[Index: Integer]: TSynGutterPartBase read GetPart;
property PartByClassCount[AClass: TSynGutterPartBaseClass]: integer
read GetPartByClassCount;
property PartByClass[AClass: TSynGutterPartBaseClass; Index: Integer]:
TSynGutterPartBase read GetPartByClass;
// Common PartProprties
property PartByClassVisible[AClass: TSynGutterPartBaseClass]: Boolean
read GetPartByClassVisible write SetPartByClassVisible;
public public
// properties available for the GutterPartClasses // properties available for the GutterPartClasses
property FoldView: TSynEditFoldedView read FFoldView; property FoldView: TSynEditFoldedView read FFoldView;
@ -67,6 +53,8 @@ type
TSynGutterPartList = class(TSynObjectList) TSynGutterPartList = class(TSynObjectList)
private private
FGutter: TSynGutterBase; FGutter: TSynGutterBase;
function GetByClass(AClass: TSynGutterPartBaseClass; Index: Integer): TSynGutterPartBase;
function GetByClassCount(AClass: TSynGutterPartBaseClass): Integer;
function GetPart(Index: Integer): TSynGutterPartBase; function GetPart(Index: Integer): TSynGutterPartBase;
function GetSynEdit: TSynEditBase; function GetSynEdit: TSynEditBase;
procedure PutPart(Index: Integer; const AValue: TSynGutterPartBase); procedure PutPart(Index: Integer; const AValue: TSynGutterPartBase);
@ -78,8 +66,12 @@ type
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
constructor Create(AOwner: TComponent; AGutter: TSynGutterBase); constructor Create(AOwner: TComponent; AGutter: TSynGutterBase);
destructor Destroy; override; destructor Destroy; override;
property Items[Index: Integer]: TSynGutterPartBase property Part[Index: Integer]: TSynGutterPartBase
read GetPart write PutPart; default; read GetPart write PutPart; default;
property ByClassCount[AClass: TSynGutterPartBaseClass]: Integer
read GetByClassCount;
property ByClass[AClass: TSynGutterPartBaseClass; Index: Integer]: TSynGutterPartBase
read GetByClass;
end; end;
{ TSynGutterPartBase } { TSynGutterPartBase }
@ -174,12 +166,7 @@ begin
FGutterPartList.Assign(AValue); FGutterPartList.Assign(AValue);
end; end;
function TSynGutterBase.GetPart(Index: Integer): TSynGutterPartBase; function TSynGutterBase.PartCount: integer;
begin
Result := TSynGutterPartBase(FGutterPartList[Index]);
end;
function TSynGutterBase.GetPartCount: integer;
begin begin
if FGutterPartList <> nil then if FGutterPartList <> nil then
result := FGutterPartList.Count result := FGutterPartList.Count
@ -187,48 +174,6 @@ begin
Result := 0; Result := 0;
end; end;
function TSynGutterBase.GetPartByClassCount(AClass: TSynGutterPartBaseClass): integer;
var
i: Integer;
begin
Result := 0;
for i := 0 to PartCount -1 do
if Part[i] is AClass then
inc(Result);
end;
function TSynGutterBase.GetPartByClass(AClass: TSynGutterPartBaseClass; Index: Integer): TSynGutterPartBase;
var
i: Integer;
begin
for i := 0 to PartCount -1 do
if Part[i] is AClass then begin
if Index = 0 then
exit(Part[i]);
dec(Index);
end;
Result := nil;
end;
function TSynGutterBase.GetPartByClassVisible(AClass: TSynGutterPartBaseClass): Boolean;
var
i: Integer;
begin
for i := 0 to PartCount -1 do
if (Part[i] is AClass) and (Part[i].Visible) then
exit(True);
Result := False;
end;
procedure TSynGutterBase.SetPartByClassVisible(AClass: TSynGutterPartBaseClass; const AValue: Boolean);
var
i: Integer;
begin
for i := 0 to PartCount -1 do
if (Part[i] is AClass) then
Part[i].Visible := AValue;
end;
procedure TSynGutterBase.DoChange(Sender: TObject); procedure TSynGutterBase.DoChange(Sender: TObject);
begin begin
end; end;
@ -393,5 +338,29 @@ begin
BaseItems[Index] := TSynObjectListItem(AValue); BaseItems[Index] := TSynObjectListItem(AValue);
end; end;
function TSynGutterPartList.GetByClass(AClass: TSynGutterPartBaseClass; Index: Integer): TSynGutterPartBase;
var
i: Integer;
begin
for i := 0 to Count -1 do
if Part[i] is AClass then begin
if Index = 0 then
exit(Part[i]);
dec(Index);
end;
Result := nil;
end;
function TSynGutterPartList.GetByClassCount(AClass: TSynGutterPartBaseClass): Integer;
var
i: Integer;
begin
Result := 0;
for i := 0 to Count -1 do
if Part[i] is AClass then
inc(Result);
end;
end. end.

View File

@ -2310,9 +2310,9 @@ procedure TEditorOptions.SetMarkupColors(Syn: TSrcIDEHighlighter; aSynEd: TSynEd
procedure SetGutterColorByClass(AddHilightAttr: TAdditionalHilightAttribute; procedure SetGutterColorByClass(AddHilightAttr: TAdditionalHilightAttribute;
aClass: TSynGutterPartBaseClass); aClass: TSynGutterPartBaseClass);
begin begin
if assigned(ASynEd.Gutter.PartByClass[aClass, 0]) then if assigned(ASynEd.Gutter.Parts.ByClass[aClass, 0]) then
SetMarkupColor(aSynEd.Highlighter, AddHilightAttr, SetMarkupColor(aSynEd.Highlighter, AddHilightAttr,
ASynEd.Gutter.PartByClass[aClass, 0].MarkupInfo); ASynEd.Gutter.Parts.ByClass[aClass, 0].MarkupInfo);
end; end;
begin begin
SetMarkupColor(aSynEd.Highlighter, ahaTextBlock, aSynEd.SelectedColor); SetMarkupColor(aSynEd.Highlighter, ahaTextBlock, aSynEd.SelectedColor);
@ -2364,7 +2364,6 @@ procedure TEditorOptions.GetSynEditSettings(ASynEdit: TSynEdit);
// read synedit settings from config file // read synedit settings from config file
var var
MarkCaret: TSynEditMarkupHighlightAllCaret; MarkCaret: TSynEditMarkupHighlightAllCaret;
GutterPart: TSynGutterPartBase;
begin begin
// general options // general options
ASynEdit.Options := fSynEditOptions; ASynEdit.Options := fSynEditOptions;
@ -2378,26 +2377,21 @@ begin
// Display options // Display options
ASynEdit.Gutter.Visible := fVisibleGutter; ASynEdit.Gutter.Visible := fVisibleGutter;
ASynEdit.Gutter.AutoSize := true; ASynEdit.Gutter.AutoSize := true;
ASynEdit.Gutter.PartByClassVisible[TSynGutterLineNumber] := fShowLineNumbers; ASynEdit.Gutter.LineNumberPart.Visible := fShowLineNumbers;
GutterPart := ASynEdit.Gutter.PartByClass[TSynGutterLineNumber, 0]; ASynEdit.Gutter.LineNumberPart(0).ShowOnlyLineNumbersMultiplesOf :=
if GutterPart <> nil then fShowOnlyLineNumbersMultiplesOf;
TSynGutterLineNumber(GutterPart).ShowOnlyLineNumbersMultiplesOf :=
fShowOnlyLineNumbersMultiplesOf;
//ASynEdit.Gutter.AutoSize:= fShowLineNumbers; //ASynEdit.Gutter.AutoSize:= fShowLineNumbers;
ASynEdit.Gutter.PartByClassVisible[TSynGutterCodeFolding] := FUseCodeFolding; ASynEdit.Gutter.CodeFoldPart.Visible := FUseCodeFolding;
if not FUseCodeFolding then if not FUseCodeFolding then
ASynEdit.UnfoldAll; ASynEdit.UnfoldAll;
ASynEdit.Gutter.Color := fGutterColor; ASynEdit.Gutter.Color := fGutterColor;
ASynEdit.Gutter.Width := fGutterWidth; ASynEdit.Gutter.Width := fGutterWidth;
GutterPart := ASynEdit.Gutter.PartByClass[TSynGutterSeparator, 0]; ASynEdit.Gutter.SeparatorPart.Visible := FGutterSeparatorIndex <> -1;
if GutterPart <> nil then if FGutterSeparatorIndex <> -1 then
begin ASynEdit.Gutter.SeparatorPart(0).Index := FGutterSeparatorIndex;
GutterPart.Visible := FGutterSeparatorIndex <> -1;
if GutterPart.Visible then
GutterPart.Index := FGutterSeparatorIndex;
end;
if fVisibleRightMargin then if fVisibleRightMargin then
ASynEdit.RightEdge := fRightMargin ASynEdit.RightEdge := fRightMargin
else else
@ -2438,7 +2432,6 @@ procedure TEditorOptions.SetSynEditSettings(ASynEdit: TSynEdit);
// copy settings from a synedit to the options // copy settings from a synedit to the options
var var
MarkCaret: TSynEditMarkupHighlightAllCaret; MarkCaret: TSynEditMarkupHighlightAllCaret;
GutterPart: TSynGutterPartBase;
begin begin
// general options // general options
fSynEditOptions := ASynEdit.Options; fSynEditOptions := ASynEdit.Options;
@ -2451,23 +2444,13 @@ begin
// Display options // Display options
fVisibleGutter := ASynEdit.Gutter.Visible; fVisibleGutter := ASynEdit.Gutter.Visible;
fShowLineNumbers := ASynEdit.Gutter.PartByClassVisible[TSynGutterLineNumber]; fShowLineNumbers := ASynEdit.Gutter.LineNumberPart.Visible;
GutterPart := ASynEdit.Gutter.PartByClass[TSynGutterLineNumber, 0]; fShowOnlyLineNumbersMultiplesOf := ASynEdit.Gutter.LineNumberPart(0).ShowOnlyLineNumbersMultiplesOf;
if GutterPart <> nil then FUseCodeFolding := ASynEdit.Gutter.CodeFoldPart.Visible;
fShowOnlyLineNumbersMultiplesOf := TSynGutterLineNumber(GutterPart).ShowOnlyLineNumbersMultiplesOf
else
fShowOnlyLineNumbersMultiplesOf := -1;
FUseCodeFolding := ASynEdit.Gutter.PartByClassVisible[TSynGutterCodeFolding];
fGutterColor := ASynEdit.Gutter.Color; fGutterColor := ASynEdit.Gutter.Color;
fGutterWidth := ASynEdit.Gutter.Width; fGutterWidth := ASynEdit.Gutter.Width;
GutterPart := ASynEdit.Gutter.PartByClass[TSynGutterSeparator, 0]; if ASynEdit.Gutter.SeparatorPart.Visible then
if GutterPart <> nil then FGutterSeparatorIndex := ASynEdit.Gutter.SeparatorPart(0).Index
begin
if GutterPart.Visible then
FGutterSeparatorIndex := GutterPart.Index
else
FGutterSeparatorIndex := -1;
end
else else
FGutterSeparatorIndex := -1; FGutterSeparatorIndex := -1;
fVisibleRightMargin := ASynEdit.RightEdge>0; fVisibleRightMargin := ASynEdit.RightEdge>0;

View File

@ -206,13 +206,13 @@ begin
if PreviewEdits[a] <> nil then if PreviewEdits[a] <> nil then
begin begin
PreviewEdits[a].Gutter.Visible := VisibleGutterCheckBox.Checked; PreviewEdits[a].Gutter.Visible := VisibleGutterCheckBox.Checked;
PreviewEdits[a].Gutter.PartByClassVisible[TSynGutterLineNumber] PreviewEdits[a].Gutter.LineNumberPart.Visible
:= ShowLineNumbersCheckBox.Checked; := ShowLineNumbersCheckBox.Checked;
if Assigned(PreviewEdits[a].Gutter.PartByClass[TSynGutterLineNumber, 0]) then if Assigned(PreviewEdits[a].Gutter.Parts.ByClass[TSynGutterLineNumber, 0]) then
TSynGutterLineNumber(PreviewEdits[a].Gutter.PartByClass[TSynGutterLineNumber, 0]) TSynGutterLineNumber(PreviewEdits[a].Gutter.Parts.ByClass[TSynGutterLineNumber, 0])
.ShowOnlyLineNumbersMultiplesOf := ShowOnlyLineNumbersMultiplesOfSpinEdit.Value; .ShowOnlyLineNumbersMultiplesOf := ShowOnlyLineNumbersMultiplesOfSpinEdit.Value;
Separator := TSynGutterSeparator(PreviewEdits[a].Gutter.PartByClass[TSynGutterSeparator, 0]); Separator := TSynGutterSeparator(PreviewEdits[a].Gutter.Parts.ByClass[TSynGutterSeparator, 0]);
if Assigned(Separator) then if Assigned(Separator) then
begin begin
Separator.Visible := GutterSeparatorIndexSpinBox.Value <> -1; Separator.Visible := GutterSeparatorIndexSpinBox.Value <> -1;

View File

@ -4010,7 +4010,7 @@ begin
// Readonly, ShowLineNumbers // Readonly, ShowLineNumbers
SrcEditMenuReadOnly.MenuItem.Checked:=ASrcEdit.ReadOnly; SrcEditMenuReadOnly.MenuItem.Checked:=ASrcEdit.ReadOnly;
SrcEditMenuShowLineNumbers.MenuItem.Checked := SrcEditMenuShowLineNumbers.MenuItem.Checked :=
EditorComp.Gutter.PartByClassVisible[TSynGutterLineNumber]; EditorComp.Gutter.LineNumberPart.Visible;
UpdateHighlightMenuItems; UpdateHighlightMenuItems;
UpdateEncodingMenuItems; UpdateEncodingMenuItems;
@ -5260,10 +5260,10 @@ begin
MenuItem := Sender as TIDEMenuCommand; MenuItem := Sender as TIDEMenuCommand;
ActEdit:=GetActiveSE; ActEdit:=GetActiveSE;
MenuItem.Checked := MenuItem.Checked :=
not(ActEdit.EditorComponent.Gutter.PartByClassVisible[TSynGutterLineNumber]); not ActEdit.EditorComponent.Gutter.LineNumberPart.Visible;
ShowLineNumbers:=MenuItem.Checked; ShowLineNumbers:=MenuItem.Checked;
for i:=0 to EditorCount-1 do for i:=0 to EditorCount-1 do
Editors[i].EditorComponent.Gutter.PartByClassVisible[TSynGutterLineNumber] Editors[i].EditorComponent.Gutter.LineNumberPart.Visible
:= ShowLineNumbers; := ShowLineNumbers;
EditorOpts.ShowLineNumbers := ShowLineNumbers; EditorOpts.ShowLineNumbers := ShowLineNumbers;
EditorOpts.Save; EditorOpts.Save;