add editor command to sort sel lines, close #78

This commit is contained in:
Basile Burg 2016-07-11 04:57:20 +02:00
parent 0d767dd129
commit 9aebae7f99
5 changed files with 188 additions and 11 deletions

BIN
icons/other/sort_az.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -13,7 +13,7 @@
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
<Resources Count="86">
<Resources Count="87">
<Resource_0 FileName="../icons/window/layout_add.png" Type="RCDATA" ResourceName="LAYOUT_ADD"/>
<Resource_1 FileName="../icons/window/layout.png" Type="RCDATA" ResourceName="LAYOUT"/>
<Resource_2 FileName="../icons/window/application_go.png" Type="RCDATA" ResourceName="APPLICATION_GO"/>
@ -100,6 +100,7 @@
<Resource_83 FileName="../icons/other/case.png" Type="RCDATA" ResourceName="CASE"/>
<Resource_84 FileName="../icons/other/tag_purple.png" Type="RCDATA" ResourceName="TAG_PURPLE"/>
<Resource_85 FileName="../cesetup/version.txt" Type="RCDATA" ResourceName="VERSION"/>
<Resource_86 FileName="../icons/other/sort_az.png" Type="RCDATA" ResourceName="SORT_AZ"/>
</Resources>
</General>
<i18n>

View File

@ -125,6 +125,13 @@ inherited CEEditorWidget: TCEEditorWidget
object MenuItem7: TMenuItem
Caption = '-'
end
object mnuedSortLines: TMenuItem
Caption = 'Sort lines'
OnClick = mnuedSortLinesClick
end
object MenuItem1: TMenuItem
Caption = '-'
end
object mnuedComm: TMenuItem
Caption = 'Comment selected lines'
OnClick = mnuedCommClick

View File

@ -52,9 +52,11 @@ type
{ TCEEditorWidget }
TCEEditorWidget = class(TCEWidget, ICEDocumentObserver, ICEMultiDocHandler, ICEProjectObserver)
MenuItem1: TMenuItem;
MenuItem10: TMenuItem;
MenuItem11: TMenuItem;
MenuItem12: TMenuItem;
mnuedSortLines: TMenuItem;
mnuedNextCarea: TMenuItem;
mnuedPrevCarea: TMenuItem;
mnuedLowcase: TMenuItem;
@ -86,6 +88,7 @@ type
procedure mnuedNextCareaClick(Sender: TObject);
procedure mnuedPrevCareaClick(Sender: TObject);
procedure mnuedLowcaseClick(Sender: TObject);
procedure mnuedSortLinesClick(Sender: TObject);
procedure mnuedUpcaseClick(Sender: TObject);
procedure MenuItem5Click(Sender: TObject);
procedure MenuItem6Click(Sender: TObject);
@ -314,6 +317,7 @@ begin
AssignPng(mnuedLowcase.Bitmap, 'CASE');
AssignPng(mnuedNextCarea.Bitmap, 'GO_NEXT');
AssignPng(mnuedPrevCarea.Bitmap, 'GO_PREVIOUS');
AssignPng(mnuedSortLines.Bitmap, 'SORT_AZ');
//
EntitiesConnector.addObserver(self);
EntitiesConnector.addSingleService(self);
@ -841,6 +845,12 @@ begin
fDoc.CommandProcessor(ecLowerCaseWordOrSel, #0, nil);
end;
procedure TCEEditorWidget.mnuedSortLinesClick(Sender: TObject);
begin
if fDoc.isNotNil then
fDoc.CommandProcessor(ecSortLines, #0, nil);
end;
procedure TCEEditorWidget.mnuedNextCareaClick(Sender: TObject);
begin
if fDoc.isNotNil then

View File

@ -9,7 +9,7 @@ uses
SynEdit, SynPluginSyncroEdit, SynCompletion, SynEditKeyCmds, LazSynEditText,
SynHighlighterLFM, SynEditHighlighter, SynEditMouseCmds, SynEditFoldedView,
SynEditMarks, SynEditTypes, SynHighlighterJScript, SynBeautifier, dialogs,
fpjson, jsonparser, LazUTF8,
fpjson, jsonparser, LazUTF8, LazUTF8Classes, Buttons, StdCtrls,
ce_common, ce_writableComponent, ce_d2syn, ce_txtsyn, ce_dialogs,
ce_sharedres, ce_dlang, ce_stringrange;
@ -120,6 +120,8 @@ type
procedure next;
end;
TSortDialog = class;
TCESynMemo = class(TSynEdit)
private
fFilename: string;
@ -165,6 +167,7 @@ type
fAlwaysAdvancedFeatures: boolean;
fIsProjectDescription: boolean;
fAutoClosedPairs: TAutoClosePairs;
fSortDialog: TSortDialog;
procedure decCallTipsLvl;
procedure setMatchOpts(value: TIdentifierMatchOptions);
function getMouseBytePosition: Integer;
@ -196,6 +199,7 @@ type
procedure gotoToChangedArea(next: boolean);
procedure autoClosePair(value: TAutoClosedPair);
procedure setSelectionOrWordCase(upper: boolean);
procedure sortSelectedLines(descending, caseSensitive: boolean);
protected
procedure DoEnter; override;
procedure DoExit; override;
@ -234,8 +238,8 @@ type
procedure ShowPhobosDoc;
procedure nextChangedArea;
procedure previousChangedArea;
procedure copy;
function implementMain: THasMain;
procedure sortLines;
//
function breakPointsCount: integer;
function breakPointLine(index: integer): integer;
@ -268,6 +272,20 @@ type
property autoClosedPairs: TAutoClosePairs read fAutoClosedPairs write fAutoClosedPairs;
end;
TSortDialog = class(TForm)
private
class var fDescending: boolean;
class var fCaseSensitive: boolean;
fEditor: TCESynMemo;
fCanUndo: boolean;
procedure btnApplyClick(sender: TObject);
procedure btnUndoClick(sender: TObject);
procedure chkCaseSensClick(sender: TObject);
procedure chkDescClick(sender: TObject);
public
constructor construct(editor: TCESynMemo);
end;
procedure SetDefaultCoeditKeystrokes(ed: TSynEdit);
function CustomStringToCommand(const Ident: string; var Int: Longint): Boolean;
@ -292,6 +310,7 @@ const
ecNextChangedArea = ecUserFirst + 16;
ecUpperCaseWordOrSel = ecUserFirst + 17;
ecLowerCaseWordOrSel = ecUserFirst + 18;
ecSortLines = ecUserFirst + 19;
var
D2Syn: TSynD2Syn; // used as model to set the options when no editor exists.
@ -311,6 +330,95 @@ begin
result := inherited CalcHintRect(MaxWidth, AHint, AData);
end;
{$REGION TSortDialog -----------------------------------------------------------}
constructor TSortDialog.construct(editor: TCESynMemo);
var
pnl: TPanel;
begin
inherited Create(nil);
fEditor := editor;
width := 150;
Height:= 95;
FormStyle:= fsStayOnTop;
BorderStyle:= bsToolWindow;
Position:= poScreenCenter;
ShowHint:=true;
with TCheckBox.Create(self) do
begin
parent := self;
BorderSpacing.Around:=2;
OnClick:=@chkCaseSensClick;
Caption:='case sensitive';
checked := fCaseSensitive;
align := alTop;
end;
with TCheckBox.Create(self) do
begin
parent := self;
BorderSpacing.Around:=2;
OnClick:=@chkDescClick;
Caption:='descending';
Checked:= fDescending;
align := alTop;
end;
pnl := TPanel.Create(self);
pnl.Parent := self;
pnl.Align:=alBottom;
pnl.Caption:='';
pnl.Height:= 32;
pnl.BevelOuter:=bvLowered;
with TSpeedButton.Create(self) do
begin
parent := pnl;
BorderSpacing.Around:=2;
OnClick:=@btnUndoClick;
align := alRight;
width := 28;
Hint := 'undo changes';
AssignPng(Glyph, 'ARROW_UNDO');
end;
with TSpeedButton.Create(self) do
begin
parent := pnl;
BorderSpacing.Around:=2;
OnClick:=@btnApplyClick;
align := alRight;
width := 28;
Hint := 'apply sorting';
AssignPng(Glyph, 'ACCEPT');
end;
end;
procedure TSortDialog.btnApplyClick(sender: TObject);
begin
fEditor.sortSelectedLines(fDescending, fCaseSensitive);
fCanUndo:= true;
end;
procedure TSortDialog.btnUndoClick(sender: TObject);
begin
if fCanUndo then
fEditor.undo;
fCanUndo:= false;
end;
procedure TSortDialog.chkCaseSensClick(sender: TObject);
begin
fCaseSensitive := TCheckBox(sender).checked;
end;
procedure TSortDialog.chkDescClick(sender: TObject);
begin
fDescending := TCheckBox(sender).checked;
end;
{$ENDREGION}
{$REGION TCESynMemoCache -------------------------------------------------------}
constructor TCESynMemoCache.create(aComponent: TComponent);
begin
@ -622,6 +730,7 @@ begin
fCallTipStrings.Free;
fLexToks.Clear;
fLexToks.Free;
fSortDialog.Free;
//
if fTempFileName.fileExists then
sysutils.DeleteFile(fTempFileName);
@ -792,6 +901,7 @@ begin
AddKey(ecNextChangedArea, VK_DOWN, [ssAlt], 0, []);
addKey(ecLowerCaseWordOrSel, 0, [], 0, []);
addKey(ecUpperCaseWordOrSel, 0, [], 0, []);
addKey(ecSortLines, 0, [], 0, []);
end;
end;
@ -816,6 +926,7 @@ begin
'ecPreviousChangedArea':begin Int := ecPreviousChangedArea; exit(true); end;
'ecUpperCaseWordOrSel': begin Int := ecUpperCaseWordOrSel; exit(true); end;
'ecLowerCaseWordOrSel': begin Int := ecLowerCaseWordOrSel; exit(true); end;
'ecSortLines': begin Int := ecSortLines; exit(true); end;
else exit(false);
end;
end;
@ -841,6 +952,7 @@ begin
ecPreviousChangedArea:begin Ident := 'ecPreviousChangedArea'; exit(true); end;
ecUpperCaseWordOrSel: begin Ident := 'ecUpperCaseWordOrSel'; exit(true); end;
ecLowerCaseWordOrSel: begin Ident := 'ecLowerCaseWordOrSel'; exit(true); end;
ecSortLines: begin Ident := 'ecSortLines'; exit(true); end;
else exit(false);
end;
end;
@ -898,6 +1010,8 @@ begin
setSelectionOrWordCase(true);
ecLowerCaseWordOrSel:
setSelectionOrWordCase(false);
ecSortLines:
sortLines;
end;
if fOverrideColMode and not SelAvail then
begin
@ -1283,14 +1397,6 @@ begin
OpenURL(pth);
end;
procedure TCESynMemo.copy;
begin
{$IFDEF WINDOWS}
{$ELSE}
// workaround https://github.com/BBasile/Coedit/issues/39
{$ENDIF}
end;
procedure TCESynMemo.nextChangedArea;
begin
gotoToChangedArea(true);
@ -1453,6 +1559,59 @@ begin
EndUndoBlock;
end;
end;
procedure TCESynMemo.sortSelectedLines(descending, caseSensitive: boolean);
var
i,j: integer;
lne: string;
lst: TStringListUTF8;
pt0: TPoint;
begin
if BlockEnd.Y - BlockBegin.Y < 1 then
exit;
lst := TStringListUTF8.Create;
try
BeginUndoBlock;
for i:= BlockBegin.Y-1 to BlockEnd.Y-1 do
lst.Add(lines[i]);
pt0 := BlockBegin;
pt0.X:=1;
ExecuteCommand(ecGotoXY, #0, @pt0);
lst.CaseSensitive:=caseSensitive;
if not caseSensitive then
lst.Sorted:=true;
case descending of
false: for i:= 0 to lst.Count-1 do
begin
ExecuteCommand(ecDeleteLine, #0, nil);
ExecuteCommand(ecInsertLine, #0, nil);
lne := lst[i];
for j := 1 to lne.length do
ExecuteCommand(ecChar, lne[j], nil);
ExecuteCommand(ecDown, #0, nil);
end;
true: for i:= lst.Count-1 downto 0 do
begin
ExecuteCommand(ecDeleteLine, #0, nil);
ExecuteCommand(ecInsertLine, #0, nil);
lne := lst[i];
for j := 1 to lne.length do
ExecuteCommand(ecChar, lne[j], nil);
ExecuteCommand(ecDown, #0, nil);
end;
end;
EndUndoBlock;
finally
lst.Free;
end;
end;
procedure TCESynMemo.sortLines;
begin
if not assigned(fSortDialog) then
fSortDialog := TSortDialog.construct(self);
fSortDialog.Show;
end;
{$ENDREGION}
{$REGION DDoc & CallTip --------------------------------------------------------}