diff --git a/src/ce_dlang.pas b/src/ce_dlang.pas index d7bb29e4..a978bc46 100644 --- a/src/ce_dlang.pas +++ b/src/ce_dlang.pas @@ -71,6 +71,7 @@ type fColumnIndex: Integer; fAbsoluteIndex: Integer; fReaderHead: PChar; + fPreviousLineColum: Integer; function getColAndLine: TPoint; public constructor Create(const aText: PChar; const aColAndLine: TPoint); @@ -219,26 +220,30 @@ end; function TReaderHead.Next: PChar; begin - Inc(fReaderHead); - Inc(fAbsoluteIndex); - Inc(fColumnIndex); if (fReaderHead^ = #10) then begin Inc(fLineIndex); - fColumnIndex := 0; + fPreviousLineColum := fColumnIndex; + fColumnIndex := -1; end; + Inc(fReaderHead); + Inc(fAbsoluteIndex); + Inc(fColumnIndex); exit(fReaderHead); end; function TReaderHead.previous: PChar; begin - // note: it breaks the column but not the line count Dec(fReaderHead); Dec(fColumnIndex); Dec(fAbsoluteIndex); + if (fReaderHead^ = #10) then + begin + Dec(fLineIndex); + fColumnIndex:= fPreviousLineColum; + end; exit(fReaderHead); end; - {$ENDREGION} {$REGION TD2Dictionary----------------------------------------------------------} @@ -349,7 +354,7 @@ var function isOutOfBound: boolean; begin - exit(reader.AbsoluteIndex > length(aText)) + exit(reader.AbsoluteIndex >= length(aText)) end; procedure addToken(aTk: TLexTokenKind); @@ -359,6 +364,7 @@ var ptk := new(PLexToken); ptk^.kind := aTk; ptk^.position := reader.LineAnColumn; + ptk^.position.X -= length(identifier); ptk^.Data := identifier; aList.Add(ptk); end; @@ -386,9 +392,9 @@ begin // skip blanks while isWhite(reader.head^) do begin - reader.Next; if isOutOfBound then exit; + reader.Next; end; // line comment diff --git a/src/ce_editor.lfm b/src/ce_editor.lfm index caad8351..959a512c 100644 --- a/src/ce_editor.lfm +++ b/src/ce_editor.lfm @@ -1,25 +1,25 @@ inherited CEEditorWidget: TCEEditorWidget Left = 704 - Height = 406 + Height = 434 Top = 245 Width = 465 Caption = 'Source editor' - ClientHeight = 406 + ClientHeight = 434 ClientWidth = 465 inherited Back: TPanel - Height = 406 + Height = 434 Width = 465 - ClientHeight = 406 + ClientHeight = 434 ClientWidth = 465 inherited Content: TPanel - Height = 406 + Height = 434 Width = 465 - ClientHeight = 406 + ClientHeight = 434 ClientWidth = 465 object editorStatus: TStatusBar[0] Left = 0 Height = 20 - Top = 384 + Top = 412 Width = 465 AutoSize = False BorderSpacing.Bottom = 2 @@ -49,6 +49,9 @@ inherited CEEditorWidget: TCEEditorWidget inherited contextMenu: TPopupMenu left = 24 top = 16 + object MenuItem2: TMenuItem[0] + Caption = 'New Item1' + end end object macRecorder: TSynMacroRecorder[2] RecordShortCut = 0 @@ -83,19 +86,38 @@ inherited CEEditorWidget: TCEEditorWidget Caption = 'Redo' OnClick = mnuedRedoClick end + object mnuedPrev: TMenuItem + Caption = 'Previous location' + OnClick = mnuedPrevClick + end + object mnuedNext: TMenuItem + Caption = 'Next location' + OnClick = mnuedNextClick + end object MenuItem7: TMenuItem Caption = '-' end + object mneEdComm: TMenuItem + Caption = 'Comment' + OnClick = mneEdCommClick + end + object mnEdInvAllNone: TMenuItem + Caption = 'Invert version all none' + OnClick = mnEdInvAllNoneClick + end + object MenuItem1: TMenuItem + Caption = '-' + end object mnuedJum2Decl: TMenuItem Caption = 'Jump to declaration' OnClick = mnuedJum2DeclClick end object mnuedCallTip: TMenuItem - Caption = 'show call tips' + Caption = 'Show call tips' OnClick = mnuedCallTipClick end object mnuedDdoc: TMenuItem - Caption = 'show ddoc' + Caption = 'Show ddoc' OnClick = mnuedDdocClick end end diff --git a/src/ce_editor.pas b/src/ce_editor.pas index 0832896c..ff6b852b 100644 --- a/src/ce_editor.pas +++ b/src/ce_editor.pas @@ -16,6 +16,12 @@ type { TCEEditorWidget } TCEEditorWidget = class(TCEWidget, ICEMultiDocObserver, ICEMultiDocHandler, ICEProjectObserver) + MenuItem1: TMenuItem; + MenuItem2: TMenuItem; + mnEdInvAllNone: TMenuItem; + mneEdComm: TMenuItem; + mnuedPrev: TMenuItem; + mnuedNext: TMenuItem; mnuedCallTip: TMenuItem; mnuedDdoc: TMenuItem; mnuedCopy: TMenuItem; @@ -29,6 +35,10 @@ type macRecorder: TSynMacroRecorder; editorStatus: TStatusBar; mnuEditor: TPopupMenu; + procedure mnEdInvAllNoneClick(Sender: TObject); + procedure mneEdCommClick(Sender: TObject); + procedure mnuedPrevClick(Sender: TObject); + procedure mnuedNextClick(Sender: TObject); procedure mnuedCallTipClick(Sender: TObject); procedure mnuedCopyClick(Sender: TObject); procedure mnuedCutClick(Sender: TObject); @@ -126,6 +136,8 @@ begin AssignPng(mnuedRedo.Bitmap, 'arrow_redo'); AssignPng(mnuedJum2Decl.Bitmap, 'arrow_shoe'); AssignPng(mnuedCopy.Bitmap, 'copy'); + AssignPng(mnuedNext.Bitmap, 'go_next'); + AssignPng(mnuedPrev.Bitmap, 'go_previous'); // EntitiesConnector.addObserver(self); EntitiesConnector.addSingleService(self); @@ -545,27 +557,51 @@ end; {$REGION Editor context menu ---------------------------------------------------} procedure TCEEditorWidget.mnuedCopyClick(Sender: TObject); begin - if fDoc = nil then exit; - fDoc.ExecuteCommand(ecCopy, '', nil); + if fDoc.isNotNil then + fDoc.ExecuteCommand(ecCopy, '', nil); end; procedure TCEEditorWidget.mnuedCallTipClick(Sender: TObject); begin - if fDoc = nil then exit; + if fDoc.isNil then exit; mnuEditor.Close; fDoc.hideDDocs; fDoc.showCallTips; end; +procedure TCEEditorWidget.mneEdCommClick(Sender: TObject); +begin + if fDoc.isNotNil then + fDoc.CommandProcessor(ecCommentSelection, '', nil); +end; + +procedure TCEEditorWidget.mnuedPrevClick(Sender: TObject); +begin + if fDoc.isNotNil then + fDoc.CommandProcessor(ecPreviousLocation, '', nil); +end; + +procedure TCEEditorWidget.mnuedNextClick(Sender: TObject); +begin + if fDoc.isNotNil then + fDoc.CommandProcessor(ecNextLocation, '', nil); +end; + +procedure TCEEditorWidget.mnEdInvAllNoneClick(Sender: TObject); +begin + if fDoc.isNotNil then + fDoc.CommandProcessor(ecSwapVersionAllNone, '', nil); +end; + procedure TCEEditorWidget.mnuedCutClick(Sender: TObject); begin - if fDoc = nil then exit; - fDoc.ExecuteCommand(ecCut, '', nil); + if fDoc.isNotNil then + fDoc.ExecuteCommand(ecCut, '', nil); end; procedure TCEEditorWidget.mnuedDdocClick(Sender: TObject); begin - if fDoc = nil then exit; + if fDoc.isNil then exit; mnuEditor.Close; fDoc.hideCallTips; fDoc.showDDocs; @@ -573,31 +609,31 @@ end; procedure TCEEditorWidget.mnuedPasteClick(Sender: TObject); begin - if fDoc = nil then exit; - fDoc.ExecuteCommand(ecPaste, '', nil); + if fDoc.isNotNil then + fDoc.ExecuteCommand(ecPaste, '', nil); end; procedure TCEEditorWidget.mnuedUndoClick(Sender: TObject); begin - if fDoc = nil then exit; - fDoc.ExecuteCommand(ecUndo, '', nil); + if fDoc.isNotNil then + fDoc.ExecuteCommand(ecUndo, '', nil); end; procedure TCEEditorWidget.mnuedRedoClick(Sender: TObject); begin - if fDoc = nil then exit; - fDoc.ExecuteCommand(ecRedo, '', nil); + if fDoc.isNotNil then + fDoc.ExecuteCommand(ecRedo, '', nil); end; procedure TCEEditorWidget.mnuedJum2DeclClick(Sender: TObject); begin - if fDoc = nil then exit; - getSymbolLoc; + if fDoc.isNotNil then + getSymbolLoc; end; procedure TCEEditorWidget.mnuEditorPopup(Sender: TObject); begin - if fDoc = nil then exit; + if fDoc.isNil then exit; // mnuedCut.Enabled:=fDOc.SelAvail; mnuedPaste.Enabled:=fDoc.CanPaste; diff --git a/src/ce_synmemo.pas b/src/ce_synmemo.pas index a53a5807..fef54c17 100644 --- a/src/ce_synmemo.pas +++ b/src/ce_synmemo.pas @@ -193,6 +193,7 @@ type procedure save; procedure saveTempFile; // + procedure invertVersionAllNone; procedure showCallTips; procedure hideCallTips; procedure showDDocs; @@ -240,6 +241,7 @@ const ecShowCallTips = ecUserFirst + 8; ecCurlyBraceClose = ecUserFirst + 9; ecCommentSelection = ecUserFirst + 10; + ecSwapVersionAllNone = ecUserFirst + 11; var D2Syn: TSynD2Syn; // used as model to set the options when no editor exists. @@ -724,6 +726,7 @@ begin AddKey(ecShowCallTips, 0, [], 0, []); AddKey(ecCurlyBraceClose, 0, [], 0, []); AddKey(ecCommentSelection, ord('/'), [ssCtrl], 0, []); + AddKey(ecSwapVersionAllNone, 0, [], 0, []); end; end; @@ -740,6 +743,7 @@ begin 'ecShowCallTips': begin Int := ecShowCallTips; exit(true); end; 'ecCurlyBraceClose': begin Int := ecCurlyBraceClose; exit(true); end; 'ecCommentSelection': begin Int := ecCommentSelection; exit(true); end; + 'ecSwapVersionAllNone': begin Int := ecSwapVersionAllNone; exit(true); end; else exit(false); end; end; @@ -757,6 +761,7 @@ begin ecShowCallTips: begin Ident := 'ecShowCallTips'; exit(true); end; ecCurlyBraceClose: begin Ident := 'ecCurlyBraceClose'; exit(true); end; ecCommentSelection: begin Ident := 'ecCommentSelection'; exit(true); end; + ecSwapVersionAllNone: begin Ident := 'ecSwapVersionAllNone'; exit(true); end; else exit(false); end; end; @@ -893,6 +898,8 @@ begin curlyBraceCloseAndIndent(self); ecCommentSelection: commentSelection(self); + ecSwapVersionAllNone: + invertVersionAllNone; end; if fOverrideColMode and not SelAvail then begin @@ -900,6 +907,74 @@ begin Options := Options - [eoScrollPastEol]; end; end; + +procedure TCESynMemo.invertVersionAllNone; +var + i: integer; + c: char; + tok, tok1, tok2, tok3: PLexToken; + pt, cp, st, nd: TPoint; + sel: boolean; +begin + fLexToks.Clear; + lex(lines.Text, fLexToks); + cp := CaretXY; + if SelAvail then + begin + sel := true; + st := BlockBegin; + nd := BlockEnd; + end else + begin + sel := false; + st := Point(0,0); + nd := Point(0,0); + end; + for i := fLexToks.Count-1 downto 2 do + begin + tok := PLexToken(fLexToks[i]); + // + if sel and ((tok^.position.Y < st.Y) + or (tok^.position.Y > nd.Y)) then + continue; + if ((tok^.Data <> 'all') and (tok^.Data <> 'none')) + or (tok^.kind <> ltkIdentifier) or (i < 2) then + continue; + // + if i = 2 then + tok1 := nil + else + tok1 := PLexToken(fLexToks[i-3]); + tok2 := PLexToken(fLexToks[i-2]); + tok3 := PLexToken(fLexToks[i-1]); + // + if ((tok2^.kind = ltkKeyword) and (tok2^.data = 'version') + and (tok3^.kind = ltkSymbol) and (tok3^.data = '(')) + or ((tok1 <> nil) and (tok1^.kind = ltkKeyword) and (tok1^.data = 'version') + and (tok3^.kind = ltkComment) and + (tok2^.kind = ltkSymbol) and (tok2^.data = '(')) then + begin + pt := tok^.position; + pt.X += 1; + BeginUndoBlock; + ExecuteCommand(ecGotoXY, '', @pt); + case tok^.Data of + 'all': + begin + for c in 'all' do ExecuteCommand(ecDeleteChar, '', nil); + for c in 'none' do ExecuteCommand(ecChar, c, nil); + end; + 'none': + begin + for c in 'none' do ExecuteCommand(ecDeleteChar, '', nil); + for c in 'all' do ExecuteCommand(ecChar, c, nil); + end; + end; + EndUndoBlock; + end; + end; + CaretXY := cp; +end; {$ENDREGIOn} {$REGION DDoc & CallTip --------------------------------------------------------}