diff --git a/Components/ScintEdit.pas b/Components/ScintEdit.pas index 5b5246455..f05769399 100644 --- a/Components/ScintEdit.pas +++ b/Components/ScintEdit.pas @@ -65,6 +65,7 @@ TScintRangeList = class(TList) TScintRectangle = record Left, Top, Right, Bottom: Integer; end; + TScintSelectionMode = (ssmStream, ssmRectangular, ssmLines, ssmThinRectangular); TScintStyleNumber = 0..StyleNumbers-1; TScintVirtualSpaceOption = (svsRectangularSelection, svsUserAccessible, svsNoWrapLineStart); @@ -79,6 +80,8 @@ TScintRangeToFormat = record TScintEditStrings = class; TScintCustomStyler = class; + EScintEditError = class(Exception); + TScintEdit = class(TWinControl) private FAcceptDroppedFiles: Boolean; @@ -135,6 +138,7 @@ TScintEdit = class(TWinControl) function GetSelectionAnchorPosition(Selection: Integer): Integer; function GetSelectionCaretPosition(Selection: Integer): Integer; function GetSelectionCount: Integer; + function GetSelectionMode: TScintSelectionMode; function GetSelText: String; function GetTopLine: Integer; function GetZoom: Integer; @@ -157,6 +161,7 @@ TScintEdit = class(TWinControl) procedure SetSelection(const Value: TScintRange); procedure SetSelectionAnchorPosition(Selection: Integer; const AnchorPos: Integer); procedure SetSelectionCaretPosition(Selection: Integer; const CaretPos: Integer); + procedure SetSelectionMode(const Value: TScintSelectionMode); procedure SetSelText(const Value: String); procedure SetStyler(const Value: TScintCustomStyler); procedure SetTabWidth(const Value: Integer); @@ -185,7 +190,8 @@ TScintEdit = class(TWinControl) procedure CheckPosRange(const StartPos, EndPos: Integer); procedure CreateParams(var Params: TCreateParams); override; procedure CreateWnd; override; - class procedure Error(const S: String); + class function GetErrorException(const S: String): EScintEditError; + class procedure Error(const S: String); overload; class procedure ErrorFmt(const S: String; const Args: array of const); function GetMainSelection: Integer; function GetTarget: TScintRange; @@ -316,6 +322,7 @@ TScintEdit = class(TWinControl) property SelectionAnchorPosition[Selection: Integer]: Integer read GetSelectionAnchorPosition write SetSelectionAnchorPosition; property SelectionCaretPosition[Selection: Integer]: Integer read GetSelectionCaretPosition write SetSelectionCaretPosition; property SelectionCount: Integer read GetSelectionCount; + property SelectionMode: TScintSelectionMode read GetSelectionMode write SetSelectionMode; property SelText: String read GetSelText write SetSelText; property Styler: TScintCustomStyler read FStyler write SetStyler; property TopLine: Integer read GetTopLine write SetTopLine; @@ -462,8 +469,6 @@ TScintPixmap = class property Pixmap: Pointer read GetPixmap; end; - EScintEditError = class(Exception); - function ScintRawStringIsBlank(const S: TScintRawString): Boolean; implementation @@ -743,9 +748,14 @@ procedure TScintEdit.EndUndoAction; Call(SCI_ENDUNDOACTION, 0, 0); end; +class function TScintEdit.GetErrorException(const S: String): EScintEditError; +begin + Result := EScintEditError.Create('TScintEdit error: ' + S); +end; + class procedure TScintEdit.Error(const S: String); begin - raise EScintEditError.Create('TScintEdit error: ' + S); + raise GetErrorException(S); end; class procedure TScintEdit.ErrorFmt(const S: String; const Args: array of const); @@ -856,8 +866,9 @@ function TScintEdit.GetLineEndings: TScintLineEndings; case Call(SCI_GETEOLMODE, 0, 0) of SC_EOL_CR: Result := sleCR; SC_EOL_LF: Result := sleLF; + SC_EOL_CRLF: Result := sleCRLF; else - Result := sleCRLF; + raise GetErrorException('Unexpected SCI_GETEOLMODE result'); end; end; @@ -1077,6 +1088,18 @@ function TScintEdit.GetSelectionCount: Integer; Result := Call(SCI_GETSELECTIONS, 0, 0); end; +function TScintEdit.GetSelectionMode: TScintSelectionMode; +begin + case Call(SCI_GETSELECTIONMODE, 0, 0) of + SC_SEL_STREAM: Result := ssmStream; + SC_SEL_RECTANGLE: Result := ssmRectangular; + SC_SEL_LINES: Result := ssmLines; + SC_SEL_THIN: Result := ssmThinRectangular; + else + raise GetErrorException('Unexpected SCI_GETSELECTIONMODE result'); + end; +end; + function TScintEdit.GetSelText: String; begin Result := ConvertRawStringToString(GetRawSelText); @@ -1536,6 +1559,21 @@ procedure TScintEdit.SetSelectionCaretPosition(Selection: Integer; Call(SCI_SETSELECTIONNCARET, Selection, CaretPos); end; +procedure TScintEdit.SetSelectionMode(const Value: TScintSelectionMode); +begin + var Mode: Integer; + if Value = ssmStream then + Mode := SC_SEL_STREAM + else if Value = ssmRectangular then + Mode := SC_SEL_RECTANGLE + else if Value = ssmLines then + Mode := SC_SEL_LINES + else + Mode := SC_SEL_THIN; + { Note this uses *CHANGE* and not *SET* } + Call(SCI_CHANGESELECTIONMODE, Mode, 0); +end; + procedure TScintEdit.SetSelText(const Value: String); begin SetRawSelText(ConvertStringToRawString(Value)); diff --git a/Projects/Src/CompForm.pas b/Projects/Src/CompForm.pas index e3e147243..95d444f9c 100644 --- a/Projects/Src/CompForm.pas +++ b/Projects/Src/CompForm.pas @@ -2807,6 +2807,18 @@ procedure TCompileForm.HDocClick(Sender: TObject); procedure TCompileForm.MemoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin + if Key in [VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_HOME, VK_END] then begin + var Memo := Sender as TScintEdit; + if Memo.SelectionMode in [ssmRectangular, ssmThinRectangular] then begin + { Allow left/right/etc. navigation with rectangular selection, see + https://sourceforge.net/p/scintilla/feature-requests/1275/ and + https://sourceforge.net/p/scintilla/bugs/2412/#cb37 + Notepad++ calls this "Enable Column Selection to Multi-editing" which + is on by default and in VSCode and VS it's also on by default. } + Memo.SelectionMode := ssmStream; + end; + end; + if Key = VK_F1 then begin var HelpFile := GetHelpFile; if Assigned(HtmlHelp) then begin diff --git a/whatsnew.htm b/whatsnew.htm index 5f68b86a8..b144fb064 100644 --- a/whatsnew.htm +++ b/whatsnew.htm @@ -38,9 +38,9 @@
  • Added shortcut to add the next occurrence of the current word or selected text as an additional selection (Alt+Shift+.).
  • Added shortcut to select all occurrences of the current word or selected text (Alt+Shift+;).
  • Added shortcuts to add a word or line as an additional selection (Ctrl+Double Click and Ctrl+Triple Click).
  • -
  • Multiple selection now works over horizontal movement and selection commands.
  • -
  • Multiple selection now works over line up and down movement and selection commands.
  • +
  • Multiple selection now works over Left, Right, Up, Down, Home and End navigation and selection commands.
  • Multiple selection now works over word and line deletion commands, and line end insertion.
  • +
  • Left, Right, etc. navigation with rectangular selection is now allowed which completes "true" multi-caret editing support.
  • When autocompleting with multiple selections present, the autocompleted text now goes into each selection.
  • Other changes: