Skip to content

Commit

Permalink
Add menu items so all VK_OEM based shortcuts which depend on the keyb…
Browse files Browse the repository at this point in the history
…oard layout can be seen by the user.
  • Loading branch information
martijnlaan committed Jun 28, 2024
1 parent cf2f86e commit 0887ace
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 84 deletions.
12 changes: 12 additions & 0 deletions Projects/Src/CompForm.dfm
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,14 @@ object CompileForm: TCompileForm
object N13: TMenuItem
Caption = '-'
end
object EFoldLine: TMenuItem
Caption = 'Fol&d Line'
OnClick = EFoldOrUnfoldLineClick
end
object EUnfoldLine: TMenuItem
Caption = '&Unfold Line'
OnClick = EFoldOrUnfoldLineClick
end
object EGoto: TMenuItem
Caption = '&Go to Line...'
ShortCut = 16455
Expand All @@ -524,6 +532,10 @@ object CompileForm: TCompileForm
Caption = 'Complete &Word'
OnClick = ECompleteWordClick
end
object EToggleLinesComment: TMenuItem
Caption = 'Toggle Lines Comment'
OnClick = EToggleLinesCommentClick
end
end
object VMenu: TMenuItem
Caption = '&View'
Expand Down
182 changes: 102 additions & 80 deletions Projects/Src/CompForm.pas
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ TCompileForm = class(TUIStateForm)
VWordWrap: TMenuItem;
N25: TMenuItem;
ESelectAllFindMatches: TMenuItem;
EToggleLinesComment: TMenuItem;
EFoldLine: TMenuItem;
EUnfoldLine: TMenuItem;
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FExitClick(Sender: TObject);
procedure FOpenMainFileClick(Sender: TObject);
Expand Down Expand Up @@ -359,6 +362,8 @@ TCompileForm = class(TUIStateForm)
procedure FClearRecentClick(Sender: TObject);
procedure VWordWrapClick(Sender: TObject);
procedure ESelectAllFindMatchesClick(Sender: TObject);
procedure EToggleLinesCommentClick(Sender: TObject);
procedure EFoldOrUnfoldLineClick(Sender: TObject);
private
{ Private declarations }
FMemos: TList<TCompScintEdit>; { FMemos[0] is the main memo and FMemos[1] the preprocessor output memo - also see MemosTabSet comment above }
Expand Down Expand Up @@ -1132,80 +1137,6 @@ procedure TCompileForm.MemoKeyDown(Sender: TObject; var Key: Word;
AMemo.ScrollCaretIntoView;
end;

procedure ToggleLinesComment(const AMemo: TCompScintEdit);
begin
{ Based on SciTE 5.50's SciTEBase::StartBlockComment - only toggles comments
for the main selection }

var Selection := AMemo.Selection;
var CaretPosition := AMemo.CaretPosition;
// checking if caret is located in _beginning_ of selected block
var MoveCaret := CaretPosition < Selection.EndPos;
var SelStartLine := AMemo.GetLineFromPosition(Selection.StartPos);
var SelEndLine := AMemo.GetLineFromPosition(Selection.EndPos);
var Lines := SelEndLine - SelStartLine;
var FirstSelLineStart := AMemo.GetPositionFromLine(SelStartLine);
// "caret return" is part of the last selected line
if (Lines > 0) and (Selection.EndPos = AMemo.GetPositionFromLine(SelEndLine)) then
Dec(SelEndLine);
{ We rely on the styler to identify [Code] section lines, but we
may be searching into areas that haven't been styled yet }
AMemo.StyleNeeded(Selection.EndPos);
AMemo.BeginUndoAction;
try
var LastLongCommentLength := 0;
for var I := SelStartLine to SelEndLine do begin
var LineIndent := AMemo.GetLineIndentPosition(I);
var LineEnd := AMemo.GetLineEndPosition(I);
var LineBuf := AMemo.GetTextRange(LineIndent, LineEnd);
// empty lines are not commented
if LineBuf = '' then
Continue;
var Comment: String;
if LineBuf.StartsWith('//') or
(FMemosStyler.GetSectionFromLineState(AMemo.Lines.State[I]) = scCode) then
Comment := '//'
else
Comment := ';';
var LongComment := Comment + ' ';
LastLongCommentLength := Length(LongComment);
if LineBuf.StartsWith(Comment) then begin
var CommentLength := Length(Comment);
if LineBuf.StartsWith(LongComment) then begin
// Removing comment with space after it.
CommentLength := Length(LongComment);
end;
AMemo.Selection := TScintRange.Create(LineIndent, LineIndent + CommentLength);
AMemo.SelText := '';
if I = SelStartLine then // is this the first selected line?
Dec(Selection.StartPos, CommentLength);
Dec(Selection.EndPos, CommentLength); // every iteration
Continue;
end;
if I = SelStartLine then // is this the first selected line?
Inc(Selection.StartPos, Length(LongComment));
Inc(Selection.EndPos, Length(LongComment)); // every iteration
AMemo.CallStr(SCI_INSERTTEXT, LineIndent, AMemo.ConvertStringToRawString(LongComment));
end;
// after uncommenting selection may promote itself to the lines
// before the first initially selected line;
// another problem - if only comment symbol was selected;
if Selection.StartPos < FirstSelLineStart then begin
if Selection.StartPos >= Selection.EndPos - (LastLongCommentLength - 1) then
Selection.EndPos := FirstSelLineStart;
Selection.StartPos := FirstSelLineStart;
end;
if MoveCaret then begin
// moving caret to the beginning of selected block
AMemo.CaretPosition := Selection.EndPos;
AMemo.CaretPositionWithSelectFromAnchor := Selection.StartPos;
end else
AMemo.Selection := Selection;
finally
AMemo.EndUndoAction;
end;
end;

procedure AddCursor(const AMemo: TCompScintEdit; const Up: Boolean);
begin
{ Does not try to keep the main selection. }
Expand Down Expand Up @@ -1363,12 +1294,14 @@ procedure TCompileForm.MemoKeyDown(Sender: TObject; var Key: Word;
ESelectAllOccurrencesClick(Self);
ccSelectAllFindMatches:
ESelectAllFindMatchesClick(Self);
ccUnfoldLine, ccFoldLine:
FActiveMemo.FoldLine(FActiveMemo.CaretLine, ComplexCommand = ccFoldLine);
ccFoldLine:
EFoldOrUnfoldLineClick(EFoldLine);
ccUnfoldLine:
EFoldOrUnfoldLineClick(EUnfoldLine);
ccSimplifySelection:
SimplifySelection(FActiveMemo);
ccToggleLinesComment:
ToggleLinesComment(FActiveMemo);
EToggleLinesCommentClick(Self); //GetCompexCommand already checked ReadOnly for us
ccAddCursorUp, ccAddCursorDown:
AddCursor(FActiveMemo, ComplexCommand = ccAddCursorUp);
else
Expand Down Expand Up @@ -2313,6 +2246,9 @@ procedure TCompileForm.SyncEditorOptions;
SetFakeShortCut(ESelectNextOccurrence, FMainMemo.GetComplexCommandShortCut(ccSelectNextOccurrence));
SetFakeShortCut(ESelectAllOccurrences, FMainMemo.GetComplexCommandShortCut(ccSelectAllOccurrences));
SetFakeShortCut(ESelectAllFindMatches, FMainMemo.GetComplexCommandShortCut(ccSelectAllFindMatches));
SetFakeShortCut(EFoldLine, FMainMemo.GetComplexCommandShortCut(ccFoldLine));
SetFakeShortCut(EUnfoldLine, FMainMemo.GetComplexCommandShortCut(ccUnfoldLine));
SetFakeShortCut(EToggleLinesComment, FMainMemo.GetComplexCommandShortCut(ccToggleLinesComment));
end;

Memo.UseFolding := FOptions.UseFolding;
Expand Down Expand Up @@ -2808,8 +2744,13 @@ procedure TCompileForm.EMenuClick(Sender: TObject);
EFindNext.Enabled := MemoHasFocus;
EFindPrevious.Enabled := MemoHasFocus;
EReplace.Enabled := MemoHasFocus and not MemoIsReadOnly;
EFoldLine.Visible := FOptions.UseFolding;
EFoldLine.Enabled := MemoHasFocus;
EUnfoldLine.Visible := EFoldLine.Visible;
EUnfoldLine.Enabled := EFoldLine.Enabled;
EGoto.Enabled := MemoHasFocus;
ECompleteWord.Enabled := MemoHasFocus and not MemoIsReadOnly;
EToggleLinesComment.Enabled := not MemoIsReadOnly;

ApplyMenuBitmaps(Sender as TMenuItem);
end;
Expand Down Expand Up @@ -2875,6 +2816,82 @@ procedure TCompileForm.ESelectNextOccurrenceClick(Sender: TObject);
FActiveMemo.SelectNextOccurrence(GetWordOccurrenceFindOptions);
end;

procedure TCompileForm.EToggleLinesCommentClick(Sender: TObject);
begin
var AMemo := FActiveMemo;

{ Based on SciTE 5.50's SciTEBase::StartBlockComment - only toggles comments
for the main selection }

var Selection := AMemo.Selection;
var CaretPosition := AMemo.CaretPosition;
// checking if caret is located in _beginning_ of selected block
var MoveCaret := CaretPosition < Selection.EndPos;
var SelStartLine := AMemo.GetLineFromPosition(Selection.StartPos);
var SelEndLine := AMemo.GetLineFromPosition(Selection.EndPos);
var Lines := SelEndLine - SelStartLine;
var FirstSelLineStart := AMemo.GetPositionFromLine(SelStartLine);
// "caret return" is part of the last selected line
if (Lines > 0) and (Selection.EndPos = AMemo.GetPositionFromLine(SelEndLine)) then
Dec(SelEndLine);
{ We rely on the styler to identify [Code] section lines, but we
may be searching into areas that haven't been styled yet }
AMemo.StyleNeeded(Selection.EndPos);
AMemo.BeginUndoAction;
try
var LastLongCommentLength := 0;
for var I := SelStartLine to SelEndLine do begin
var LineIndent := AMemo.GetLineIndentPosition(I);
var LineEnd := AMemo.GetLineEndPosition(I);
var LineBuf := AMemo.GetTextRange(LineIndent, LineEnd);
// empty lines are not commented
if LineBuf = '' then
Continue;
var Comment: String;
if LineBuf.StartsWith('//') or
(FMemosStyler.GetSectionFromLineState(AMemo.Lines.State[I]) = scCode) then
Comment := '//'
else
Comment := ';';
var LongComment := Comment + ' ';
LastLongCommentLength := Length(LongComment);
if LineBuf.StartsWith(Comment) then begin
var CommentLength := Length(Comment);
if LineBuf.StartsWith(LongComment) then begin
// Removing comment with space after it.
CommentLength := Length(LongComment);
end;
AMemo.Selection := TScintRange.Create(LineIndent, LineIndent + CommentLength);
AMemo.SelText := '';
if I = SelStartLine then // is this the first selected line?
Dec(Selection.StartPos, CommentLength);
Dec(Selection.EndPos, CommentLength); // every iteration
Continue;
end;
if I = SelStartLine then // is this the first selected line?
Inc(Selection.StartPos, Length(LongComment));
Inc(Selection.EndPos, Length(LongComment)); // every iteration
AMemo.CallStr(SCI_INSERTTEXT, LineIndent, AMemo.ConvertStringToRawString(LongComment));
end;
// after uncommenting selection may promote itself to the lines
// before the first initially selected line;
// another problem - if only comment symbol was selected;
if Selection.StartPos < FirstSelLineStart then begin
if Selection.StartPos >= Selection.EndPos - (LastLongCommentLength - 1) then
Selection.EndPos := FirstSelLineStart;
Selection.StartPos := FirstSelLineStart;
end;
if MoveCaret then begin
// moving caret to the beginning of selected block
AMemo.CaretPosition := Selection.EndPos;
AMemo.CaretPositionWithSelectFromAnchor := Selection.StartPos;
end else
AMemo.Selection := Selection;
finally
AMemo.EndUndoAction;
end;
end;

procedure TCompileForm.ESelectAllFindMatchesClick(Sender: TObject);
begin
{ Might be called even if ESelectAllFindMatches.Enabled would be False in EMenuClick }
Expand Down Expand Up @@ -3477,6 +3494,11 @@ procedure TCompileForm.EFindNextOrPreviousClick(Sender: TObject);
end;
end;

procedure TCompileForm.EFoldOrUnfoldLineClick(Sender: TObject);
begin
FActiveMemo.FoldLine(FActiveMemo.CaretLine, Sender = EFoldLine);
end;

procedure TCompileForm.FindNext(const ReverseDirection: Boolean);
var
StartPos, EndPos: Integer;
Expand Down Expand Up @@ -5727,7 +5749,7 @@ procedure TCompileForm.UpdateKeyMapping;
KeyMappedMenu.Key.ShortCut := ShortCut;
if ToolButton <> nil then begin
var MenuItem := KeyMappedMenu.Key;
ToolButton.Hint := Format('%s (%s)', [RemoveAccelChar(MenuItem.Caption), ShortCutToText(ShortCut)]);
ToolButton.Hint := Format('%s (%s)', [RemoveAccelChar(MenuItem.Caption), NewShortCutToText(ShortCut)]);
end;
FKeyMappedMenus.Add(ShortCut, ToolButton);
end;
Expand Down Expand Up @@ -5758,9 +5780,9 @@ procedure TCompileForm.UpdateKeyMapping;
raise Exception.Create('Unknown FOptions.KeyMappingType');
end;

BackNavButton.Hint := Format('Back (%s)', [ShortCutToText(FBackNavButtonShortCut)]);
BackNavButton.Hint := Format('Back (%s)', [NewShortCutToText(FBackNavButtonShortCut)]);
FKeyMappedMenus.Add(FBackNavButtonShortCut, nil);
ForwardNavButton.Hint := Format('Forward (%s)', [ShortCutToText(FForwardNavButtonShortCut)]);
ForwardNavButton.Hint := Format('Forward (%s)', [NewShortCutToText(FForwardNavButtonShortCut)]);
FKeyMappedMenus.Add(FForwardNavButtonShortCut, nil);
end;

Expand Down
6 changes: 4 additions & 2 deletions Projects/Src/CompScintEdit.pas
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,10 @@ procedure TCompScintEdit.UpdateComplexCommands;
FComplexCommands.Clear;
FComplexCommandsReversed.Clear;

{ VK_OEM_1 is ;, VK_OEM_6 is ], VK_OEM_4 is [, VK_OEM_2 is /
See https://code.visualstudio.com/docs/getstarted/keybindings#_keyboard-layouts }
{ Normally VK_OEM_1 is ;, VK_OEM_6 is ], VK_OEM_4 is [, and VK_OEM_2 is /
See CompFunc's NewShortcutToText for how it's is handled when they are different.
Note: all VK_OEM shortcuts must have a menu item so the user can see what the
shortcut is for their kayboard layout. }

if FKeyMappingType = kmtVSCode then begin
{ Use freed Ctrl+D and Ctrl+Shift+L }
Expand Down
4 changes: 2 additions & 2 deletions whatsnew.htm
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@
<p>Other editor changes:</p>
<ul>
<li>Added support for Visual Studio Code-style keyboard and mouse shortcuts, like Ctrl+D to Add Next Occurrence, Ctrl+Shift+K to delete a line and Alt+Click to add an additional cursor.<br />To activate this use the <i>Options</i> menu item in the <i>Tools</i> menu to set the new <i>Keys</i> option in the <i>Editor</i> group to <i>Visual Studio Code</i>.<br />The updated <a href="https://jrsoftware.org/ishelp/index.php?topic=compformshortcuts">Compiler IDE Keyboard And Mouse Commands</a> help topic lists all differences with the classic keyboard and mouse shortcuts.</li>
<li>Added new <i>Enable section folding</i> option which allows you to temporarily hide sections while editing by clicking the new minus or plus icons in the editor's gutter or by using the new keyboard shortcuts (Ctrl+Shift+[ to fold and Ctrl+Shift+] to unfold). Enabled by default.</li>
<li>Added new <i>Enable section folding</i> option which allows you to temporarily hide sections while editing by clicking the new minus or plus icons in the editor's gutter or by using the new keyboard shortcuts (Ctrl+Shift+[ to fold and Ctrl+Shift+] to unfold) or menu items. Enabled by default.</li>
<li>The editor's gutter now shows change history to keep track of saved and unsaved modifications.</li>
<li>The editor's font now defaults to Consolas if available, consistent with most other modern editors.</li>
<li>The editor can now be scrolled horizontally instead of vertically by holding the Shift key while rotating the mouse wheel. Horizontal scroll wheels are now also supported.</li>
<li>Cut (Ctrl+X or Shift+Delete) and Copy (Ctrl+C or Ctrl+Insert) now cut or copy the entire line if there's no selection, consistent with most other modern editors.</li>
<li>Added shortcuts to move selected lines up or down (Alt+Up and Alt+Down).</li>
<li>Added shortcut to toggle lines comment (Ctrl+/).</li>
<li>Added shortcut and menu item to toggle lines comment (Ctrl+/).</li>
<li>Added a right-click popup menu to the editor's gutter column for breakpoints.</li>
</ul>
<p>Other changes:</p>
Expand Down

0 comments on commit 0887ace

Please sign in to comment.