IDE: Add config for SynEdit wrapped-view

This commit is contained in:
Martin 2025-01-21 11:44:54 +01:00
parent dfadb86949
commit ab35263d34
9 changed files with 305 additions and 6 deletions

View File

@ -184,8 +184,9 @@ const
EdtOptionsCodetools = 600; EdtOptionsCodetools = 600;
EdtOptionsCodeFolding = 700; EdtOptionsCodeFolding = 700;
EdtOptionsCodeFoldingMouse = 701; EdtOptionsCodeFoldingMouse = 701;
EdtOptionsDrawDivider = 800; EdtOptionsLineWrap = 800;
EdtOptionsMultiWindow = 900; EdtOptionsDrawDivider = 900;
EdtOptionsMultiWindow = 1000;
GroupCodetools = 300; GroupCodetools = 300;
CdtOptionsGeneral = 100; CdtOptionsGeneral = 100;

48
ide/SourceSynWrap.pas Normal file
View File

@ -0,0 +1,48 @@
unit SourceSynWrap;
{$mode objfpc}{$H+}
interface
uses SynEditWrappedView, SynEditViewedLineMap, SynEdit, LazSynEditText, SynEditFoldedView, Classes;
type
{ TLazSynSourceEditLineWrapPlugin }
TLazSynSourceEditLineWrapPlugin = class(TLazSynEditLineWrapPlugin)
public
constructor Create(AnOwner: TComponent); override;
end;
implementation
{ TLazSynSourceEditLineWrapPlugin }
constructor TLazSynSourceEditLineWrapPlugin.Create(AnOwner: TComponent);
var
Syn: TSynEdit absolute AnOwner;
Fld: TSynEditStringsLinked;
ALineMapView: TSynEditLineMappingView;
FldIdx: Integer;
begin
Fld := Syn.TextViewsManager.SynTextViewByClass[TSynEditFoldedView];
ALineMapView := TSynEditLineMappingView(Syn.TextViewsManager.SynTextViewByClass[TSynEditLineMappingView]);
if ALineMapView = nil then
ALineMapView := TSynEditLineMappingView.Create
else
Syn.TextViewsManager.RemoveSynTextView(ALineMapView);
if Fld <> nil then
FldIdx := Syn.TextViewsManager.IndexOf(Fld)
else
FldIdx := Syn.TextViewsManager.Count;
Syn.TextViewsManager.AddTextView(ALineMapView, FldIdx);
inherited Create(AnOwner);
end;
end.

View File

@ -64,7 +64,7 @@ uses
SynHighlighterIni, SynHighlighterPo, SynHighlighterPike, SynPluginMultiCaret, SynHighlighterIni, SynHighlighterPo, SynHighlighterPike, SynPluginMultiCaret,
SynEditMarkupFoldColoring, SynEditMarkup, SynGutterLineOverview, SynEditMarkupFoldColoring, SynEditMarkup, SynGutterLineOverview,
SynBeautifierPascal, SynEditTextDynTabExpander, SynEditTextTabExpander, SynBeautifierPascal, SynEditTextDynTabExpander, SynEditTextTabExpander,
SynTextMateSyn, SynEditStrConst, SynHighlighterPosition, SynGutterMarks, SynTextMateSyn, SynEditStrConst, SynHighlighterPosition, SynGutterMarks, SynEditWrappedView,
// codetools // codetools
LinkScanner, CodeToolManager, LinkScanner, CodeToolManager,
// BuildIntf // BuildIntf
@ -1593,6 +1593,11 @@ type
fDbgHintAutoTypeCastClass: Boolean; fDbgHintAutoTypeCastClass: Boolean;
// Code Folding // Code Folding
fReverseFoldPopUpOrder: Boolean; fReverseFoldPopUpOrder: Boolean;
// Wordwrap
FWordWrapCaretWrapPos: TLazSynEditWrapCaretPos;
FWordWrapEnabled: Boolean;
FWordWrapMinWidth: Integer;
fUseTabHistory: Boolean; fUseTabHistory: Boolean;
fMultiCaretOnColumnSelect: Boolean; fMultiCaretOnColumnSelect: Boolean;
@ -1671,6 +1676,12 @@ type
// Code Folding // Code Folding
property ReverseFoldPopUpOrder: Boolean property ReverseFoldPopUpOrder: Boolean
read fReverseFoldPopUpOrder write fReverseFoldPopUpOrder default True; read fReverseFoldPopUpOrder write fReverseFoldPopUpOrder default True;
// wordwrap
property WordWrapEnabled: Boolean read FWordWrapEnabled write FWordWrapEnabled;
property WordWrapCaretWrapPos: TLazSynEditWrapCaretPos read FWordWrapCaretWrapPos write FWordWrapCaretWrapPos;
property WordWrapMinWidth: Integer read FWordWrapMinWidth write FWordWrapMinWidth default 10;
property UseTabHistory: Boolean read fUseTabHistory write fUseTabHistory; property UseTabHistory: Boolean read fUseTabHistory write fUseTabHistory;
property MultiCaretOnColumnSelect: Boolean property MultiCaretOnColumnSelect: Boolean
@ -5464,6 +5475,8 @@ begin
fDbgHintUseBackendDebugConverter := True; fDbgHintUseBackendDebugConverter := True;
// Code folding // Code folding
fReverseFoldPopUpOrder := True; fReverseFoldPopUpOrder := True;
// wordwrap
FWordWrapMinWidth := 10;
// pas highlighter // pas highlighter
fPasExtendedKeywordsMode := False; fPasExtendedKeywordsMode := False;
fPasStringKeywordMode := spsmDefault; fPasStringKeywordMode := spsmDefault;
@ -6818,6 +6831,16 @@ begin
ASynEdit.Gutter.Width := fGutterWidth; ASynEdit.Gutter.Width := fGutterWidth;
if ASynEdit is TIDESynEditor then begin
TIDESynEditor(ASynEdit).WordWrapEnabled := WordWrapEnabled;
TIDESynEditor(ASynEdit).WordWrapCaretWrapPos := WordWrapCaretWrapPos;
TIDESynEditor(ASynEdit).WordWrapMinWidth := WordWrapMinWidth;
if WordWrapEnabled then begin
ASynEdit.Options := ASynEdit.Options - [eoScrollPastEol];
ASynEdit.Options2 := ASynEdit.Options2 - [eoScrollPastEolAddPage, eoScrollPastEolAutoCaret];
end;
end;
ASynEdit.RightEdge := fRightMargin; ASynEdit.RightEdge := fRightMargin;
if fVisibleRightMargin then if fVisibleRightMargin then
ASynEdit.Options := ASynEdit.Options - [eoHideRightMargin] ASynEdit.Options := ASynEdit.Options - [eoHideRightMargin]

View File

@ -0,0 +1,76 @@
object EditorWordWrapOptionsFrame: TEditorWordWrapOptionsFrame
Left = 0
Height = 380
Top = 0
Width = 428
ClientHeight = 380
ClientWidth = 428
TabOrder = 0
DesignLeft = 534
DesignTop = 48
object cbEnableWordWrap: TCheckBox
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 6
Height = 19
Top = 6
Width = 416
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Around = 6
Caption = 'cbEnableWordWrap'
TabOrder = 0
end
object rgCaretWrapPos: TRadioGroup
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = cbEnableWordWrap
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 6
Height = 19
Top = 31
Width = 416
Anchors = [akTop, akLeft, akRight]
AutoFill = True
AutoSize = True
BorderSpacing.Around = 6
Caption = 'rgCaretWrapPos'
ChildSizing.LeftRightSpacing = 6
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
ChildSizing.EnlargeVertical = crsHomogenousChildResize
ChildSizing.ShrinkHorizontal = crsScaleChilds
ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 2
Columns = 2
TabOrder = 1
end
object lbWinWordWrapWidth: TLabel
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = edWinWordWrapWidth
AnchorSideTop.Side = asrCenter
Left = 6
Height = 15
Top = 60
Width = 120
BorderSpacing.Around = 6
Caption = 'lbWinWordWrapWidth'
end
object edWinWordWrapWidth: TSpinEdit
AnchorSideLeft.Control = lbWinWordWrapWidth
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = rgCaretWrapPos
AnchorSideTop.Side = asrBottom
Left = 132
Height = 23
Top = 56
Width = 124
BorderSpacing.Around = 6
MaxValue = 9999
MinValue = 1
TabOrder = 2
Value = 10
end
end

View File

@ -0,0 +1,84 @@
unit editor_wordwrap_options;
{$mode ObjFPC}{$H+}
interface
uses
// LCL
Forms, Controls, StdCtrls, ExtCtrls, Spin,
// IdeIntf
IDEOptEditorIntf, IDEOptionsIntf, SynEditWrappedView,
// IDE
EditorOptions, LazarusIDEStrConsts
;
type
{ TEditorWordWrapOptionsFrame }
TEditorWordWrapOptionsFrame = class(TAbstractIDEOptionsEditor)
cbEnableWordWrap: TCheckBox;
lbWinWordWrapWidth: TLabel;
rgCaretWrapPos: TRadioGroup;
edWinWordWrapWidth: TSpinEdit;
private
public
function GetTitle: String; override;
procedure Setup(ADialog: TAbstractOptionsEditorDialog); override;
procedure ReadSettings(AOptions: TAbstractIDEOptions); override;
procedure WriteSettings(AOptions: TAbstractIDEOptions); override;
class function SupportedOptionsClass: TAbstractIDEOptionsClass; override;
end;
implementation
{$R *.lfm}
{ TEditorWordWrapOptionsFrame }
function TEditorWordWrapOptionsFrame.GetTitle: String;
begin
Result := dlgOptWordWrap;
end;
procedure TEditorWordWrapOptionsFrame.Setup(ADialog: TAbstractOptionsEditorDialog);
begin
cbEnableWordWrap.Caption := dlgOptWordWrapUseWordwrap;
rgCaretWrapPos.Caption := dlgOptWordWrapDisplayCaretAtWrapPositio;
rgCaretWrapPos.Items.Add(dlgOptWordWrapEndOfLine);
rgCaretWrapPos.Items.Add(dlgOptWordWrapStartOfNextLine);
lbWinWordWrapWidth.Caption := dlgOptWordWrapMinimumLineLength;
end;
procedure TEditorWordWrapOptionsFrame.ReadSettings(AOptions: TAbstractIDEOptions);
begin
cbEnableWordWrap.Checked := (AOptions as TEditorOptions).WordWrapEnabled;
case (AOptions as TEditorOptions).WordWrapCaretWrapPos of
wcpEOL: rgCaretWrapPos.ItemIndex := 0;
wcpBOL: rgCaretWrapPos.ItemIndex := 1;
end;
edWinWordWrapWidth.Value := (AOptions as TEditorOptions).WordWrapMinWidth;
end;
procedure TEditorWordWrapOptionsFrame.WriteSettings(AOptions: TAbstractIDEOptions);
begin
(AOptions as TEditorOptions).WordWrapEnabled := cbEnableWordWrap.Checked;
case rgCaretWrapPos.ItemIndex of
0: (AOptions as TEditorOptions).WordWrapCaretWrapPos := wcpEOL;
1: (AOptions as TEditorOptions).WordWrapCaretWrapPos := wcpBOL;
end;
(AOptions as TEditorOptions).WordWrapMinWidth := edWinWordWrapWidth.Value;
end;
class function TEditorWordWrapOptionsFrame.SupportedOptionsClass: TAbstractIDEOptionsClass;
begin
Result := TEditorOptions;
end;
initialization
RegisterIDEOptionsEditor(GroupEditor, TEditorWordWrapOptionsFrame, EdtOptionsLineWrap);
end.

View File

@ -1468,6 +1468,13 @@
<Filename Value="cocoaideformconfig.inc"/> <Filename Value="cocoaideformconfig.inc"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
</Unit> </Unit>
<Unit>
<Filename Value="frames/editor_wordwrap_options.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="EditorWordWrapOptionsFrame"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Frame"/>
</Unit>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -1652,6 +1652,14 @@ resourcestring
dlgCodeFoldEnableHide = 'Hide'; dlgCodeFoldEnableHide = 'Hide';
dlgCodeFoldEnableBoth = 'Both'; dlgCodeFoldEnableBoth = 'Both';
dlgCodeFoldPopUpOrder = 'Reverse fold-order in Popup'; dlgCodeFoldPopUpOrder = 'Reverse fold-order in Popup';
dlgOptWordWrap = 'Word-wrap';
dlgOptWordWrapUseWordwrap = 'Use Word-wrap';
dlgOptWordWrapDisplayCaretAtWrapPositio = 'Display caret at wrap-position...';
dlgOptWordWrapEndOfLine = 'end of line';
dlgOptWordWrapStartOfNextLine = 'start of next line';
dlgOptWordWrapMinimumLineLength = 'Minimum line length';
dlfMousePredefinedScheme = 'Use predefined scheme'; dlfMousePredefinedScheme = 'Use predefined scheme';
dlfNoPredefinedScheme = '< None >'; dlfNoPredefinedScheme = '< None >';
dlfMouseSimpleGenericSect = 'General'; dlfMouseSimpleGenericSect = 'General';

View File

@ -131,7 +131,7 @@ uses
Backup_Options, naming_options, fpdoc_options, idecoolbar_options, editortoolbar_options, Backup_Options, naming_options, fpdoc_options, idecoolbar_options, editortoolbar_options,
editor_display_options, editor_keymapping_options, editor_mouseaction_options, editor_display_options, editor_keymapping_options, editor_mouseaction_options,
editor_mouseaction_options_advanced, editor_color_options, editor_color_tml_options, editor_mouseaction_options_advanced, editor_color_options, editor_color_tml_options,
editor_markup_options, editor_markup_options, editor_wordwrap_options,
editor_markup_userdefined, editor_codetools_options, editor_codefolding_options, editor_markup_userdefined, editor_codetools_options, editor_codefolding_options,
editor_general_misc_options, editor_dividerdraw_options, editor_general_misc_options, editor_dividerdraw_options,
editor_multiwindow_options, editor_indent_options, editor_multiwindow_options, editor_indent_options,

View File

@ -61,8 +61,8 @@ uses
SynEditHighlighter, SynEditHighlighterFoldBase, SynHighlighterPas, SynEditHighlighter, SynEditHighlighterFoldBase, SynHighlighterPas,
SynEditMarkupHighAll, SynEditKeyCmds, SynEditMarkupIfDef, SynEditMiscProcs, SynEditMarkupHighAll, SynEditKeyCmds, SynEditMarkupIfDef, SynEditMiscProcs,
SynPluginMultiCaret, SynEditPointClasses, SynPluginMultiCaret, SynEditPointClasses,
SynEditMarkupFoldColoring, SynEditTextTabExpander, SynEditMouseCmds, SynEditMarkupFoldColoring, SynEditTextTabExpander, SynEditMouseCmds, SynEditWrappedView,
etSrcEditMarks, LazarusIDEStrConsts, SourceMarks; etSrcEditMarks, LazarusIDEStrConsts, SourceMarks, SourceSynWrap;
type type
@ -258,6 +258,7 @@ type
FMarkupIdentComplWindow: TSynMarkupIdentComplWindow; FMarkupIdentComplWindow: TSynMarkupIdentComplWindow;
FShowTopInfo: boolean; FShowTopInfo: boolean;
FFoldView: TSynEditFoldedView; FFoldView: TSynEditFoldedView;
FWrapView: TLazSynSourceEditLineWrapPlugin;
FTopInfoNestList: TLazSynEditNestedFoldsList; FTopInfoNestList: TLazSynEditNestedFoldsList;
FSyncroEdit: TSynPluginSyncroEdit; FSyncroEdit: TSynPluginSyncroEdit;
FTemplateEdit: TSynPluginTemplateEdit; FTemplateEdit: TSynPluginTemplateEdit;
@ -286,12 +287,16 @@ type
function GetOnMultiCaretBeforeCommand: TSynMultiCaretBeforeCommand; function GetOnMultiCaretBeforeCommand: TSynMultiCaretBeforeCommand;
procedure GetTopInfoMarkupForLine(Sender: TObject; {%H-}Line: integer; var Special: boolean; procedure GetTopInfoMarkupForLine(Sender: TObject; {%H-}Line: integer; var Special: boolean;
aMarkup: TSynSelectedColor); aMarkup: TSynSelectedColor);
function GetWordWrapEnabled: Boolean;
procedure SetCaretColor(AValue: TColor); procedure SetCaretColor(AValue: TColor);
procedure SetHighlightUserWordCount(AValue: Integer); procedure SetHighlightUserWordCount(AValue: Integer);
procedure SetOnMultiCaretBeforeCommand(AValue: TSynMultiCaretBeforeCommand); procedure SetOnMultiCaretBeforeCommand(AValue: TSynMultiCaretBeforeCommand);
procedure SetShowTopInfo(AValue: boolean); procedure SetShowTopInfo(AValue: boolean);
procedure SetTopInfoMarkup(AValue: TSynSelectedColor); procedure SetTopInfoMarkup(AValue: TSynSelectedColor);
procedure DoHighlightChanged(Sender: TSynEditStrings; {%H-}AIndex, {%H-}ACount : Integer); procedure DoHighlightChanged(Sender: TSynEditStrings; {%H-}AIndex, {%H-}ACount : Integer);
procedure SetWordWrapCaretWrapPos(AValue: TLazSynEditWrapCaretPos);
procedure SetWordWrapEnabled(AValue: Boolean);
procedure SetWordWrapMinWidth(AValue: Integer);
procedure SrcSynCaretChanged(Sender: TObject); procedure SrcSynCaretChanged(Sender: TObject);
function GetHighlighter: TSynCustomFoldHighlighter; function GetHighlighter: TSynCustomFoldHighlighter;
protected protected
@ -299,6 +304,8 @@ type
function CreateGutter(AOwner : TSynEditBase; ASide: TSynGutterSide; function CreateGutter(AOwner : TSynEditBase; ASide: TSynGutterSide;
ATextDrawer: TheTextDrawer): TSynGutter; override; ATextDrawer: TheTextDrawer): TSynGutter; override;
procedure SetHighlighter(const Value: TSynCustomHighlighter); override; procedure SetHighlighter(const Value: TSynCustomHighlighter); override;
procedure AddLineWrapView;
procedure RemoveLineWrapView;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
@ -331,6 +338,10 @@ type
property OnMultiCaretBeforeCommand: TSynMultiCaretBeforeCommand read GetOnMultiCaretBeforeCommand write SetOnMultiCaretBeforeCommand; property OnMultiCaretBeforeCommand: TSynMultiCaretBeforeCommand read GetOnMultiCaretBeforeCommand write SetOnMultiCaretBeforeCommand;
property CaretStamp: Int64 read FCaretStamp; property CaretStamp: Int64 read FCaretStamp;
property CaretColor: TColor read FCaretColor write SetCaretColor; property CaretColor: TColor read FCaretColor write SetCaretColor;
property WordWrapEnabled: Boolean read GetWordWrapEnabled write SetWordWrapEnabled;
property WordWrapCaretWrapPos: TLazSynEditWrapCaretPos write SetWordWrapCaretWrapPos;
property WordWrapMinWidth: Integer write SetWordWrapMinWidth;
end; end;
TIDESynHighlighterPasRangeList = class(TSynHighlighterPasRangeList) TIDESynHighlighterPasRangeList = class(TSynHighlighterPasRangeList)
@ -1559,6 +1570,29 @@ begin
SrcSynCaretChanged(nil); SrcSynCaretChanged(nil);
end; end;
procedure TIDESynEditor.SetWordWrapCaretWrapPos(AValue: TLazSynEditWrapCaretPos);
begin
if FWrapView <> nil then
FWrapView.CaretWrapPos := AValue;
end;
procedure TIDESynEditor.SetWordWrapEnabled(AValue: Boolean);
begin
if AValue = WordWrapEnabled then
exit;
if AValue then
AddLineWrapView
else
RemoveLineWrapView;
end;
procedure TIDESynEditor.SetWordWrapMinWidth(AValue: Integer);
begin
if FWrapView <> nil then
FWrapView.MinWrapWidth := AValue;
end;
procedure TIDESynEditor.SrcSynCaretChanged(Sender: TObject); procedure TIDESynEditor.SrcSynCaretChanged(Sender: TObject);
function RealTopLine: Integer; function RealTopLine: Integer;
begin begin
@ -1694,6 +1728,11 @@ begin
aMarkup.Assign(FTopInfoMarkup); aMarkup.Assign(FTopInfoMarkup);
end; end;
function TIDESynEditor.GetWordWrapEnabled: Boolean;
begin
Result := FWrapView <> nil;
end;
procedure TIDESynEditor.SetCaretColor(AValue: TColor); procedure TIDESynEditor.SetCaretColor(AValue: TColor);
begin begin
if FCaretColor = AValue then Exit; if FCaretColor = AValue then Exit;
@ -1897,6 +1936,18 @@ begin
end; end;
end; end;
procedure TIDESynEditor.AddLineWrapView;
begin
if FWrapView <> nil then
RemoveLineWrapView;
FWrapView := TLazSynSourceEditLineWrapPlugin.Create(Self);
end;
procedure TIDESynEditor.RemoveLineWrapView;
begin
FreeAndNil(FWrapView);
end;
constructor TIDESynEditor.Create(AOwner: TComponent); constructor TIDESynEditor.Create(AOwner: TComponent);
var var
MarkupFoldColors: TSynEditMarkupFoldColors; MarkupFoldColors: TSynEditMarkupFoldColors;
@ -1967,6 +2018,7 @@ end;
destructor TIDESynEditor.Destroy; destructor TIDESynEditor.Destroy;
begin begin
RemoveLineWrapView;
UnRegisterMouseActionSearchHandler(@CatchMouseForTopInforLine); UnRegisterMouseActionSearchHandler(@CatchMouseForTopInforLine);
ViewedTextBuffer.RemoveChangeHandler(senrHighlightChanged, @DoHighlightChanged); ViewedTextBuffer.RemoveChangeHandler(senrHighlightChanged, @DoHighlightChanged);
HighlightUserWordCount := 0; HighlightUserWordCount := 0;