/* o_buffer.cpp * * Copyright (c) 1994-1996, Marko Macek * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * */ #include "fte.h" SearchReplaceOptions LSearch = { 0 }; int suspendLoads = 0; EViewPort *EBuffer::CreateViewPort(EView *V) { V->Port = new EEditPort(this, V); AddView(V); if (Loaded == 0 && !suspendLoads) { Load(); #ifdef CONFIG_OBJ_MESSAGES if (CompilerMsgs) CompilerMsgs->FindFileErrors(this); #endif markIndex.retrieveForBuffer(this); #ifdef CONFIG_HISTORY int r, c; if (RetrieveFPos(FileName, r, c) == 1) SetNearPosR(c, r); //printf("setting to c:%d r:%d f:%s", c, r, FileName); V->Port->GetPos(); V->Port->ReCenter = 1; #endif } return V->Port; } EEditPort::EEditPort(EBuffer *B, EView *V): EViewPort(V) { Buffer = B; Rows = Cols = 0; OldTP.Row = -1; OldTP.Col = -1; GetPos(); TP = B->TP; CP = B->CP; if (V && V->MView && V->MView->Win) { V->MView->ConQuerySize(&Cols, &Rows); Rows--; } } EEditPort::~EEditPort() { StorePos(); } void EEditPort::Resize(int Width, int Height) { Cols = Width; Rows = Height - 1; RedrawAll(); } int EEditPort::SetTop(int Col, int Line) { int A, B; if (Line >= Buffer->VCount) Line = Buffer->VCount - 1; if (Line < 0) Line = 0; A = Line; B = Line + Rows; TP.Row = Line; TP.Col = Col; if (A >= Buffer->VCount) A = Buffer->VCount - 1; if (B >= Buffer->VCount) { B = Buffer->VCount - 1; } Buffer->Draw(Buffer->VToR(A), -1); return 1; } void EEditPort::StorePos() { Buffer->CP = CP; Buffer->TP = TP; } void EEditPort::GetPos() { CP = Buffer->CP; TP = Buffer->TP; } void EEditPort::ScrollY(int Delta) { // optimization // no need to scroll (clear) entire window which we are about to redraw if (Delta >= Rows || -Delta >= Rows) return ; if (Delta < 0) { Delta = -Delta; if (Delta > Rows) return; View->MView->ConScroll(csDown, 0, 0, Cols, Rows, hcPlain_Background, Delta); } else { if (Delta > Rows) return; View->MView->ConScroll(csUp, 0, 0, Cols, Rows, hcPlain_Background, Delta); } } void EEditPort::DrawLine(int L, TDrawBuffer B) { if (L < TP.Row) return; if (L >= TP.Row + Rows) return; if (View->MView->Win->GetViewContext() == View->MView) View->MView->ConPutBox(0, L - TP.Row, Cols, 1, B); // printf("%d %d (%d %d %d %d)\n", 0, L - TP.Row, view->sX, view->sY, view->sW, view->sH); } void EEditPort::RedrawAll() { Buffer->Draw(TP.Row, -1); /// Redraw(0, 0, Cols, Rows); } int EBuffer::GetContext() { return CONTEXT_FILE; } void EEditPort::HandleEvent(TEvent &Event) { EViewPort::HandleEvent(Event); switch (Event.What) { case evKeyDown: { char Ch; if (GetCharFromEvent(Event, &Ch)) { if (Buffer->BeginMacro() == 0) return ; Buffer->TypeChar(Ch); Event.What = evNone; } } break; case evCommand: switch (Event.Msg.Command) { case cmVScrollUp: Buffer->ScrollDown(1); Event.What = evNone; break; case cmVScrollDown: Buffer->ScrollUp(1); Event.What = evNone; break; case cmVScrollPgUp: Buffer->ScrollDown(Rows); Event.What = evNone; break; case cmVScrollPgDn: Buffer->ScrollUp(Rows); Event.What = evNone; break; case cmVScrollMove: { int ypos; // fprintf(stderr, "Pos = %d\n\x7", Event.Msg.Param1); ypos = Buffer->CP.Row - TP.Row; Buffer->SetNearPos(Buffer->CP.Col, Event.Msg.Param1 + ypos); SetTop(TP.Col, Event.Msg.Param1); RedrawAll(); } Event.What = evNone; break; case cmHScrollLeft: Buffer->ScrollRight(1); Event.What = evNone; break; case cmHScrollRight: Buffer->ScrollLeft(1); Event.What = evNone; break; case cmHScrollPgLt: Buffer->ScrollRight(Cols); Event.What = evNone; break; case cmHScrollPgRt: Buffer->ScrollLeft(Cols); Event.What = evNone; break; case cmHScrollMove: { int xpos; xpos = Buffer->CP.Col - TP.Col; Buffer->SetNearPos(Event.Msg.Param1 + xpos, Buffer->CP.Row); SetTop(Event.Msg.Param1, TP.Row); RedrawAll(); } Event.What = evNone; break; } break; case evMouseDown: case evMouseMove: case evMouseAuto: case evMouseUp: HandleMouse(Event); break; } } void EEditPort::HandleMouse(TEvent &Event) { int x, y, xx, yy, W, H; View->MView->ConQuerySize(&W, &H); x = Event.Mouse.X; y = Event.Mouse.Y; if (Event.What != evMouseDown || y < H - 1) { xx = x + TP.Col; yy = y + TP.Row; if (yy >= Buffer->VCount) yy = Buffer->VCount - 1; if (yy < 0) yy = 0; if (xx < 0) xx = 0; switch (Event.What) { case evMouseDown: if (Event.Mouse.Y == H - 1) break; if (View->MView->Win->CaptureMouse(1)) View->MView->MouseCaptured = 1; else break; View->MView->MouseMoved = 0; if (Event.Mouse.Buttons == 1) { Buffer->SetNearPos(xx, yy); switch (Event.Mouse.Count % 5) { case 1: break; case 2: Buffer->BlockSelectWord(); break; case 3: Buffer->BlockSelectLine(); break; case 4: Buffer->BlockSelectPara(); break; } // Window->Buffer->Redraw(); if (SystemClipboard) { Buffer->NextCommand(); Buffer->BlockCopy(0); } Event.What = evNone; } else if (Event.Mouse.Buttons == 2) { Buffer->SetNearPos(xx, yy); } break; case evMouseAuto: case evMouseMove: if (View->MView->MouseCaptured) { if (Event.Mouse.Buttons == 1) { if (!View->MView->MouseMoved) { if (Event.Mouse.KeyMask == kfCtrl) Buffer->BlockMarkColumn(); else if (Event.Mouse.KeyMask == kfAlt) Buffer->BlockMarkLine(); else Buffer->BlockMarkStream(); Buffer->BlockUnmark(); if (Event.What == evMouseMove) View->MView->MouseMoved = 1; } Buffer->BlockExtendBegin(); Buffer->SetNearPos(xx, yy); Buffer->BlockExtendEnd(); } else if (Event.Mouse.Buttons == 2) { if (Event.Mouse.KeyMask == kfAlt) { } else { Buffer->SetNearPos(xx, yy); } } Event.What = evNone; } break; /* case evMouseAuto: if (View->MView->MouseCaptured) { Event.What = evNone; } break;*/ case evMouseUp: if (View->MView->MouseCaptured) View->MView->Win->CaptureMouse(0); else break; View->MView->MouseCaptured = 0; if (Event.Mouse.Buttons == 1) { if (View->MView->MouseMoved) if (SystemClipboard) { Buffer->NextCommand(); Buffer->BlockCopy(0); } } if (Event.Mouse.Buttons == 2) { if (!View->MView->MouseMoved) { EEventMap *Map = View->MView->Win->GetEventMap(); const char *MName = 0; if (Map) MName = Map->GetMenu(EM_LocalMenu); if (MName == 0) MName = "Local"; View->MView->Win->Parent->PopupMenu(MName); } } if (Event.Mouse.Buttons == 4) { if (SystemClipboard) { Buffer->NextCommand(); if (Event.Mouse.KeyMask == 0) Buffer->BlockPasteStream(); else if (Event.Mouse.KeyMask == kfCtrl) Buffer->BlockPasteColumn(); else if (Event.Mouse.KeyMask == kfAlt) Buffer->BlockPasteLine(); } } Event.What = evNone; break; } } } void EEditPort::UpdateView() { Buffer->Redraw(); } void EEditPort::RepaintView() { RedrawAll(); } void EEditPort::UpdateStatus() { } void EEditPort::RepaintStatus() { //Buffer->Redraw(); } EEventMap *EBuffer::GetEventMap() { return FindActiveMap(Mode); } int EBuffer::BeginMacro() { return NextCommand(); } int EBuffer::ExecCommand(int Command, ExState &State) { switch (Command) { case ExMoveUp: return MoveUp(); case ExMoveDown: return MoveDown(); case ExMoveLeft: return MoveLeft(); case ExMoveRight: return MoveRight(); case ExMovePrev: return MovePrev(); case ExMoveNext: return MoveNext(); case ExMoveWordLeft: return MoveWordLeft(); case ExMoveWordRight: return MoveWordRight(); case ExMoveWordPrev: return MoveWordPrev(); case ExMoveWordNext: return MoveWordNext(); case ExMoveWordEndLeft: return MoveWordEndLeft(); case ExMoveWordEndRight: return MoveWordEndRight(); case ExMoveWordEndPrev: return MoveWordEndPrev(); case ExMoveWordEndNext: return MoveWordEndNext(); case ExMoveWordOrCapLeft: return MoveWordOrCapLeft(); case ExMoveWordOrCapRight: return MoveWordOrCapRight(); case ExMoveWordOrCapPrev: return MoveWordOrCapPrev(); case ExMoveWordOrCapNext: return MoveWordOrCapNext(); case ExMoveWordOrCapEndLeft: return MoveWordOrCapEndLeft(); case ExMoveWordOrCapEndRight: return MoveWordOrCapEndRight(); case ExMoveWordOrCapEndPrev: return MoveWordOrCapEndPrev(); case ExMoveWordOrCapEndNext: return MoveWordOrCapEndNext(); case ExMoveLineStart: return MoveLineStart(); case ExMoveLineEnd: return MoveLineEnd(); case ExMovePageStart: return MovePageStart(); case ExMovePageEnd: return MovePageEnd(); case ExMovePageUp: return MovePageUp(); case ExMovePageDown: return MovePageDown(); case ExMovePageLeft: return MovePageLeft(); case ExMovePageRight: return MovePageEnd(); case ExMoveFileStart: return MoveFileStart(); case ExMoveFileEnd: return MoveFileEnd(); case ExMoveBlockStart: return MoveBlockStart(); case ExMoveBlockEnd: return MoveBlockEnd(); case ExMoveFirstNonWhite: return MoveFirstNonWhite(); case ExMoveLastNonWhite: return MoveLastNonWhite(); case ExMovePrevEqualIndent: return MovePrevEqualIndent(); case ExMoveNextEqualIndent: return MoveNextEqualIndent(); case ExMovePrevTab: return MovePrevTab(); case ExMoveNextTab: return MoveNextTab(); case ExMoveTabStart: return MoveTabStart(); case ExMoveTabEnd: return MoveTabEnd(); case ExMoveLineTop: return MoveLineTop(); case ExMoveLineCenter: return MoveLineCenter(); case ExMoveLineBottom: return MoveLineBottom(); case ExMoveBeginOrNonWhite: return MoveBeginOrNonWhite(); case ExMoveBeginLinePageFile: return MoveBeginLinePageFile(); case ExMoveEndLinePageFile: return MoveEndLinePageFile(); case ExScrollLeft: return ScrollLeft(State); case ExScrollRight: return ScrollRight(State); case ExScrollDown: return ScrollDown(State); case ExScrollUp: return ScrollUp(State); case ExKillLine: return KillLine(); case ExKillChar: return KillChar(); case ExKillCharPrev: return KillCharPrev(); case ExKillWord: return KillWord(); case ExKillWordPrev: return KillWordPrev(); case ExKillWordOrCap: return KillWordOrCap(); case ExKillWordOrCapPrev: return KillWordOrCapPrev(); case ExKillToLineStart: return KillToLineStart(); case ExKillToLineEnd: return KillToLineEnd(); case ExKillBlock: return KillBlock(); case ExBackSpace: return BackSpace(); case ExDelete: return Delete(); case ExCharCaseUp: return CharCaseUp(); case ExCharCaseDown: return CharCaseDown(); case ExCharCaseToggle: return CharCaseToggle(); case ExLineCaseUp: return LineCaseUp(); case ExLineCaseDown: return LineCaseDown(); case ExLineCaseToggle: return LineCaseToggle(); case ExLineInsert: return LineInsert(); case ExLineAdd: return LineAdd(); case ExLineSplit: return LineSplit(); case ExLineJoin: return LineJoin(); case ExLineNew: return LineNew(); case ExLineIndent: return LineIndent(); case ExLineTrim: return LineTrim(); case ExLineCenter: return LineCenter(); case ExInsertSpacesToTab: { int no; if(State.GetIntParam(View, &no) == 0) no = 0; return InsertSpacesToTab(no); } case ExInsertTab: return InsertTab(); case ExInsertSpace: return InsertSpace(); case ExWrapPara: #ifdef CONFIG_WORDWRAP return WrapPara(); #else return ErFAIL; #endif case ExInsPrevLineChar: return InsPrevLineChar(); case ExInsPrevLineToEol: return InsPrevLineToEol(); case ExLineDuplicate: return LineDuplicate(); case ExBlockBegin: return BlockBegin(); case ExBlockEnd: return BlockEnd(); case ExBlockUnmark: return BlockUnmark(); case ExBlockCut: return BlockCut(0); case ExBlockCopy: return BlockCopy(0); case ExBlockCutAppend: return BlockCut(1); case ExBlockCopyAppend: return BlockCopy(1); case ExClipClear: return ClipClear(); case ExBlockPaste: return BlockPaste(); case ExBlockKill: return BlockKill(); case ExBlockIndent: { int saved_persistence, ret_code; saved_persistence = BFI(this, BFI_PersistentBlocks); BFI_SET(this, BFI_PersistentBlocks, 1); ret_code = BlockIndent(); BFI_SET(this, BFI_PersistentBlocks, saved_persistence); return ret_code; } case ExBlockUnindent: { int saved_persistence, ret_code; saved_persistence = BFI(this, BFI_PersistentBlocks); BFI_SET(this, BFI_PersistentBlocks, 1); ret_code = BlockUnindent(); BFI_SET(this, BFI_PersistentBlocks, saved_persistence); return ret_code; } case ExBlockClear: return BlockClear(); case ExBlockMarkStream: return BlockMarkStream(); case ExBlockMarkLine: return BlockMarkLine(); case ExBlockMarkColumn: return BlockMarkColumn(); case ExBlockCaseUp: return BlockCaseUp(); case ExBlockCaseDown: return BlockCaseDown(); case ExBlockCaseToggle: return BlockCaseToggle(); case ExBlockExtendBegin: return BlockExtendBegin(); case ExBlockExtendEnd: return BlockExtendEnd(); case ExBlockReIndent: return BlockReIndent(); case ExBlockSelectWord: return BlockSelectWord(); case ExBlockSelectLine: return BlockSelectLine(); case ExBlockSelectPara: return BlockSelectPara(); case ExBlockUnTab: return BlockUnTab(); case ExBlockEnTab: return BlockEnTab(); #ifdef CONFIG_UNDOREDO case ExUndo: return Undo(); case ExRedo: return Redo(); #else case ExUndo: return ErFAIL; case ExRedo: return ErFAIL; #endif case ExMatchBracket: return MatchBracket(); case ExMovePrevPos: return MovePrevPos(); case ExMoveSavedPosCol: return MoveSavedPosCol(); case ExMoveSavedPosRow: return MoveSavedPosRow(); case ExMoveSavedPos: return MoveSavedPos(); case ExSavePos: return SavePos(); case ExCompleteWord: return CompleteWord(); case ExBlockPasteStream: return BlockPasteStream(); case ExBlockPasteLine: return BlockPasteLine(); case ExBlockPasteColumn: return BlockPasteColumn(); case ExShowPosition: return ShowPosition(); case ExFoldCreate: return FoldCreate(VToR(CP.Row)); case ExFoldDestroy: return FoldDestroy(VToR(CP.Row)); case ExFoldDestroyAll: return FoldDestroyAll(); case ExFoldPromote: return FoldPromote(VToR(CP.Row)); case ExFoldDemote: return FoldDemote(VToR(CP.Row)); case ExFoldOpen: return FoldOpen(VToR(CP.Row)); case ExFoldOpenNested: return FoldOpenNested(); case ExFoldClose: return FoldClose(VToR(CP.Row)); case ExFoldOpenAll: return FoldOpenAll(); case ExFoldCloseAll: return FoldCloseAll(); case ExFoldToggleOpenClose: return FoldToggleOpenClose(); case ExFoldCreateAtRoutines: return FoldCreateAtRoutines(); case ExMoveFoldTop: return MoveFoldTop(); case ExMoveFoldPrev: return MoveFoldPrev(); case ExMoveFoldNext: return MoveFoldNext(); case ExFileSave: return Save(); case ExFilePrint: return FilePrint(); case ExBlockPrint: return BlockPrint(); case ExBlockTrim: return BlockTrim(); case ExFileTrim: return FileTrim(); case ExHilitWord: #ifdef CONFIG_WORD_HILIT return HilitWord(); #else return ErFAIL; #endif case ExSearchWordPrev: return SearchWord(SEARCH_BACK | SEARCH_NEXT); case ExSearchWordNext: return SearchWord(SEARCH_NEXT); case ExHilitMatchBracket: return HilitMatchBracket(); case ExToggleAutoIndent: return ToggleAutoIndent(); case ExToggleInsert: return ToggleInsert(); case ExToggleExpandTabs: return ToggleExpandTabs(); case ExToggleShowTabs: return ToggleShowTabs(); case ExToggleUndo: return ToggleUndo(); case ExToggleReadOnly: return ToggleReadOnly(); case ExToggleKeepBackups: return ToggleKeepBackups(); case ExToggleMatchCase: return ToggleMatchCase(); case ExToggleBackSpKillTab: return ToggleBackSpKillTab(); case ExToggleDeleteKillTab: return ToggleDeleteKillTab(); case ExToggleSpaceTabs: return ToggleSpaceTabs(); case ExToggleIndentWithTabs: return ToggleIndentWithTabs(); case ExToggleBackSpUnindents: return ToggleBackSpUnindents(); case ExToggleWordWrap: return ToggleWordWrap(); case ExToggleTrim: return ToggleTrim(); case ExToggleShowMarkers: return ToggleShowMarkers(); case ExSetLeftMargin: return SetLeftMargin(); case ExSetRightMargin: return SetRightMargin(); case ExSetIndentWithTabs: return SetIndentWithTabs(State); // stuff with UI case ExMoveToLine: return MoveToLine(State); case ExMoveToColumn: return MoveToColumn(State); case ExFoldCreateByRegexp: return FoldCreateByRegexp(State); #ifdef CONFIG_BOOKMARKS case ExPlaceBookmark: return PlaceBookmark(State); case ExRemoveBookmark: return RemoveBookmark(State); case ExGotoBookmark: return GotoBookmark(State); #else case ExPlaceBookmark: return ErFAIL; case ExRemoveBookmark: return ErFAIL; case ExGotoBookmark: return ErFAIL; #endif case ExPlaceGlobalBookmark: return PlaceGlobalBookmark(State); case ExPushGlobalBookmark: return PushGlobalBookmark(); case ExInsertString: return InsertString(State); case ExSelfInsert: return SelfInsert(State); case ExFileReload: return FileReload(State); case ExFileSaveAs: return FileSaveAs(State); case ExFileWriteTo: return FileWriteTo(State); case ExBlockRead: return BlockRead(State); case ExBlockReadStream: return BlockReadStream(State); case ExBlockReadLine: return BlockReadLine(State); case ExBlockReadColumn: return BlockReadColumn(State); case ExBlockWrite: return BlockWrite(State); case ExBlockSort: return BlockSort(0); case ExBlockSortReverse: return BlockSort(1); case ExFind: return Find(State); case ExFindReplace: return FindReplace(State); case ExFindRepeat: return FindRepeat(State); case ExFindRepeatOnce: return FindRepeatOnce(State); case ExFindRepeatReverse: return FindRepeatReverse(State); case ExSearch: return Search(State); case ExSearchB: return SearchB(State); case ExSearchRx: return SearchRx(State); case ExSearchAgain: return SearchAgain(State); case ExSearchAgainB: return SearchAgainB(State); case ExSearchReplace: return SearchReplace(State); case ExSearchReplaceB: return SearchReplaceB(State); case ExSearchReplaceRx: return SearchReplaceRx(State); case ExInsertChar: return InsertChar(State); case ExTypeChar: return TypeChar(State); case ExChangeMode: return ChangeMode(State); //case ExChangeKeys: return ChangeKeys(State); case ExChangeFlags: return ChangeFlags(State); case ExChangeTabSize: return ChangeTabSize(State); case ExChangeLeftMargin: return ChangeLeftMargin(State); case ExChangeRightMargin: return ChangeRightMargin(State); case ExASCIITable: #ifdef CONFIG_I_ASCII return ASCIITable(State); #else return ErFAIL; #endif case ExCharTrans: return CharTrans(State); case ExLineTrans: return LineTrans(State); case ExBlockTrans: return BlockTrans(State); #ifdef CONFIG_TAGS case ExTagFind: return FindTag(State); case ExTagFindWord: return FindTagWord(State); #endif case ExSetCIndentStyle: return SetCIndentStyle(State); case ExBlockMarkFunction: return BlockMarkFunction(); case ExIndentFunction: return IndentFunction(); case ExMoveFunctionPrev: return MoveFunctionPrev(); case ExMoveFunctionNext: return MoveFunctionNext(); case ExInsertDate: return InsertDate(State); case ExInsertUid: return InsertUid(); case ExShowHelpWord: return ShowHelpWord(State); } return EModel::ExecCommand(Command, State); } void EBuffer::HandleEvent(TEvent &Event) { EModel::HandleEvent(Event); } int EBuffer::MoveToLine(ExState &State) { int No = 0; if (State.GetIntParam(View, &No) == 0) { char Num[10]; sprintf(Num, "%d", VToR(CP.Row) + 1); if (View->MView->Win->GetStr("Goto Line", sizeof(Num), Num, HIST_POSITION) == 0) return 0; No = atol(Num); } return SetNearPosR(CP.Col, No - 1); } int EBuffer::MoveToColumn(ExState &State) { int No = 0; if (State.GetIntParam(View, &No) == 0) { char Num[10]; sprintf(Num, "%d", CP.Col + 1); if (View->MView->Win->GetStr("Goto Column", 8, Num, HIST_POSITION) == 0) return 0; No = atol(Num); } return SetNearPos(No - 1, CP.Row); } int EBuffer::FoldCreateByRegexp(ExState &State) { char strbuf[1024] = ""; if (State.GetStrParam(View, strbuf, sizeof(strbuf)) == 0) { if (View->MView->Win->GetStr("Create Fold Regexp", sizeof(strbuf), strbuf, HIST_REGEXP) == 0) return 0; } return FoldCreateByRegexp(strbuf); } #ifdef CONFIG_BOOKMARKS int EBuffer::PlaceBookmark(ExState &State) { char name[256] = ""; EPoint P = CP; P.Row = VToR(P.Row); if (State.GetStrParam(View, name, sizeof(name)) == 0) if (View->MView->Win->GetStr("Place Bookmark", sizeof(name), name, HIST_BOOKMARK) == 0) return 0; return PlaceBookmark(name, P); } int EBuffer::RemoveBookmark(ExState &State) { char name[256] = ""; if (State.GetStrParam(View, name, sizeof(name)) == 0) if (View->MView->Win->GetStr("Remove Bookmark", sizeof(name), name, HIST_BOOKMARK) == 0) return 0; return RemoveBookmark(name); } int EBuffer::GotoBookmark(ExState &State) { char name[256] = ""; if (State.GetStrParam(View, name, sizeof(name)) == 0) if (View->MView->Win->GetStr("Goto Bookmark", sizeof(name), name, HIST_BOOKMARK) == 0) return 0; return GotoBookmark(name); } #endif int EBuffer::PlaceGlobalBookmark(ExState &State) { char name[256] = ""; EPoint P = CP; P.Row = VToR(P.Row); if (State.GetStrParam(View, name, sizeof(name)) == 0) if (View->MView->Win->GetStr("Place Global Bookmark", sizeof(name), name, HIST_BOOKMARK) == 0) return 0; if (markIndex.insert(name, this, P) == 0) { Msg(S_ERROR, "Error placing global bookmark %s.", name); } return 1; } int EBuffer::PushGlobalBookmark() { EPoint P = CP; P.Row = VToR(P.Row); EMark *m = markIndex.pushMark(this, P); if (m) Msg(S_INFO, "Placed bookmark %s", m->getName()); return m ? 1 : 0; } int EBuffer::InsertChar(ExState &State) { char Ch; int No; if (State.GetIntParam(View, &No) == 0) { TEvent E; E.What = evKeyDown; E.Key.Code = View->MView->Win->GetChar("Quote Char:"); if (!GetCharFromEvent(E, &Ch)) return 0; No = Ch; } if (No < 0 || No > 255) return 0; Ch = char(No); return InsertChar(Ch); } int EBuffer::TypeChar(ExState &State) { char Ch; int No; if (State.GetIntParam(View, &No) == 0) { TEvent E; E.What = evKeyDown; E.Key.Code = View->MView->Win->GetChar(0); if (!GetCharFromEvent(E, &Ch)) return 0; No = Ch; } if (No < 0 || No > 255) return 0; Ch = char(No); return TypeChar(Ch); } int EBuffer::InsertString(ExState &State) { char strbuf[1024] = ""; if (State.GetStrParam(View, strbuf, sizeof(strbuf)) == 0) { if (View->MView->Win->GetStr("Insert String", sizeof(strbuf), strbuf, HIST_DEFAULT) == 0) return 0; } return InsertString(strbuf, strlen(strbuf)); } extern int LastEventChar; int EBuffer::SelfInsert(ExState &/*State*/) { if (LastEventChar != -1) return TypeChar(char(LastEventChar)); return 0; } int EBuffer::FileReload(ExState &/*State*/) { if (Modified) { switch (View->MView->Win->Choice(GPC_ERROR, "File Modified", 2, "&Reload", "&Cancel", "%s", FileName)) { case 0: break; case 1: case -1: default: return 0; } } // GetNewNumber(); return Reload(); } int EBuffer::FileSaveAs(char *FName) { char Name[MAXPATH]; if (ExpandPath(FName, Name) == -1) { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Invalid path: %s.", FName); return 0; } if (FindFile(Name) == 0) { if (FileExists(Name)) { switch (View->MView->Win->Choice(GPC_ERROR, "File Exists", 2, "&Overwrite", "&Cancel", "%s", Name)) { case 0: break; case 1: case -1: default: return 0; } } free(FileName); FileName = strdup(Name); UpdateTitle(); return Save(); } else { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Already editing '%s.'", Name); return 0; } } int EBuffer::FileSaveAs(ExState &State) { char FName[MAXPATH]; strcpy(FName, FileName); if (State.GetStrParam(View, FName, sizeof(FName)) == 0) if (View->MView->Win->GetFile("Save As", sizeof(FName), FName, HIST_PATH, GF_SAVEAS) == 0) return 0; return FileSaveAs(FName); } int EBuffer::FileWriteTo(char *FName) { char Name[MAXPATH]; if (ExpandPath(FName, Name) == -1) { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Invalid path: %s.", FName); return 0; } if (FindFile(Name) == 0) { if (FileExists(Name)) { switch (View->MView->Win->Choice(GPC_ERROR, "File Exists", 2, "&Overwrite", "&Cancel", "%s", Name)) { case 0: break; case 1: case -1: default: return 0; } } return SaveTo(Name); } else { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Already editing '%s.'", Name); return 0; } } int EBuffer::FileWriteTo(ExState &State) { char FName[MAXPATH]; strcpy(FName, FileName); if (State.GetStrParam(View, FName, sizeof(FName)) == 0) if (View->MView->Win->GetFile("Write To", sizeof(FName), FName, HIST_PATH, GF_SAVEAS) == 0) return 0; return FileWriteTo(FName); } int EBuffer::BlockReadX(ExState &State, int blockMode) { char Name[MAXPATH]; char FName[MAXPATH]; if (JustDirectory(FileName, FName) == -1) return 0; SlashDir(FName); if (State.GetStrParam(View, FName, sizeof(FName)) == 0) if (View->MView->Win->GetFile("Read block", sizeof(FName), FName, HIST_PATH, GF_OPEN) == 0) return 0; if (ExpandPath(FName, Name) == -1) { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Invalid path: %s.", FName); return 0; } return BlockReadFrom(FName, blockMode); } int EBuffer::BlockRead(ExState &State) { return BlockReadX(State, BlockMode); } int EBuffer::BlockReadStream(ExState &State) { return BlockReadX(State, bmStream); } int EBuffer::BlockReadLine(ExState &State) { return BlockReadX(State, bmLine); } int EBuffer::BlockReadColumn(ExState &State) { return BlockReadX(State, bmColumn); } int EBuffer::BlockWrite(ExState &State) { char Name[MAXPATH]; char FName[MAXPATH]; int Append = 0; if (JustDirectory(FileName, FName) == -1) return 0; SlashDir(FName); if (State.GetStrParam(View, FName, sizeof(FName)) == 0) if (View->MView->Win->GetFile("Write block", sizeof(FName), FName, HIST_PATH, GF_SAVEAS) == 0) return 0; if (ExpandPath(FName, Name) == -1) { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Invalid path: %s.", FName); return 0; } if (FindFile(Name) == 0) { if (FileExists(Name)) { switch (View->MView->Win->Choice(GPC_ERROR, "File Exists", 3, "&Overwrite", "&Append", "&Cancel", "%s", Name)) { case 0: break; case 1: Append = 1; break; case 2: case -1: default: return 0; } } } else { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Already editing '%s.'", Name); return 0; } return BlockWriteTo(Name, Append); } int EBuffer::Find(ExState &State) { char find[MAXSEARCH+1] = ""; char options[32] = ""; if (State.GetStrParam(View, find, sizeof(find)) != 0) { if (State.GetStrParam(View, options, sizeof(options)) == 0) strcpy(options, BFS(this, BFS_DefFindOpt)); LSearch.ok = 0; strcpy(LSearch.strSearch, find); LSearch.strReplace[0] = 0; LSearch.Options = 0; if (ParseSearchOptions(0, options, LSearch.Options) == 0) return 0; LSearch.ok = 1; } else if ((HaveGUIDialogs & GUIDLG_FIND) && GUIDialogs) { LSearch.ok = 0; LSearch.strSearch[0] = 0; LSearch.strReplace[0] = 0; LSearch.Options = 0; if (BFS(this, BFS_DefFindOpt)) strcpy(options, BFS(this, BFS_DefFindOpt)); if (ParseSearchOptions(0, options, LSearch.Options) == 0) LSearch.Options = 0; if (DLGGetFind(View->MView->Win, LSearch) == 0) return 0; } else { if (BFS(this, BFS_DefFindOpt)) strcpy(options, BFS(this, BFS_DefFindOpt)); if (View->MView->Win->GetStr("Find", sizeof(find), find, HIST_SEARCH) == 0) return 0; if (View->MView->Win->GetStr("Options (All/Block/Cur/Delln/Glob/Igncase/Joinln/Rev/Word/regX)", sizeof(options), options, HIST_SEARCHOPT) == 0) return 0; LSearch.ok = 0; strcpy(LSearch.strSearch, find); LSearch.strReplace[0] = 0; LSearch.Options = 0; if (ParseSearchOptions(0, options, LSearch.Options) == 0) return 0; LSearch.ok = 1; } if (LSearch.ok == 0) return 0; LSearch.Options |= SEARCH_CENTER; if (Find(LSearch) == 0) return 0; return 1; } int EBuffer::FindReplace(ExState &State) { char find[MAXSEARCH+1] = ""; char replace[MAXSEARCH+1] = ""; char options[32] = ""; if (State.GetStrParam(View, find, sizeof(find)) != 0) { if (State.GetStrParam(View, replace, sizeof(replace)) == 0) return 0; if (State.GetStrParam(View, options, sizeof(options)) == 0) return 0; LSearch.ok = 0; strcpy(LSearch.strSearch, find); strcpy(LSearch.strReplace, replace); LSearch.Options = 0; if (ParseSearchOptions(1, options, LSearch.Options) == 0) return 0; LSearch.Options |= SEARCH_REPLACE; LSearch.ok = 1; } else if ((HaveGUIDialogs & GUIDLG_FINDREPLACE) && GUIDialogs) { LSearch.ok = 0; LSearch.strSearch[0] = 0; LSearch.strReplace[0] = 0; LSearch.Options = 0; if (BFS(this, BFS_DefFindReplaceOpt)) strcpy(options, BFS(this, BFS_DefFindReplaceOpt)); if (ParseSearchOptions(1, options, LSearch.Options) == 0) LSearch.Options = 0; if (DLGGetFindReplace(View->MView->Win, LSearch) == 0) return 0; } else { if (BFS(this, BFS_DefFindReplaceOpt)) strcpy(options, BFS(this, BFS_DefFindReplaceOpt)); if (State.GetStrParam(View, find, sizeof(find)) == 0) if (View->MView->Win->GetStr("Find", sizeof(find), find, HIST_SEARCH) == 0) return 0; if (State.GetStrParam(View, replace, sizeof(replace)) == 0) if (View->MView->Win->GetStr("Replace", sizeof(replace), replace, HIST_SEARCH) == 0) return 0; if (State.GetStrParam(View, options, sizeof(options)) == 0) if (View->MView->Win->GetStr("Options (All/Block/Cur/Delln/Glob/Igncase/Joinln/Rev/Noask/Word/regX)", sizeof(options), options, HIST_SEARCHOPT) == 0) return 0; LSearch.ok = 0; strcpy(LSearch.strSearch, find); strcpy(LSearch.strReplace, replace); LSearch.Options = 0; if (ParseSearchOptions(1, options, LSearch.Options) == 0) return 0; LSearch.Options |= SEARCH_REPLACE; LSearch.ok = 1; } if (LSearch.ok == 0) return 0; LSearch.Options |= SEARCH_CENTER; if (Find(LSearch) == 0) return 0; return 1; } int EBuffer::FindRepeat(ExState &State) { if (LSearch.ok == 0) return Find(State); LSearch.Options |= SEARCH_NEXT; LSearch.Options &= ~SEARCH_GLOBAL; if (Find(LSearch) == 0) return 0; return 1; } int EBuffer::FindRepeatReverse(ExState &State) { int rc; if (LSearch.ok == 0) return Find(State); LSearch.Options |= SEARCH_NEXT; LSearch.Options &= ~SEARCH_GLOBAL; LSearch.Options ^= SEARCH_BACK; rc = Find(LSearch); LSearch.Options ^= SEARCH_BACK; return rc; } int EBuffer::FindRepeatOnce(ExState &State) { if (LSearch.ok == 0) return Find(State); LSearch.Options |= SEARCH_NEXT; LSearch.Options &= ~SEARCH_GLOBAL; LSearch.Options &= ~SEARCH_ALL; if (Find(LSearch) == 0) return 0; return 1; } int EBuffer::ChangeMode(ExState &State) { char Mode[32] = ""; int rc; if (State.GetStrParam(View, Mode, sizeof(Mode)) == 0) if (View->MView->Win->GetStr("Mode", sizeof(Mode), Mode, HIST_SETUP) == 0) return 0; rc = ChangeMode(Mode); FullRedraw(); return rc; } int EBuffer::ChangeKeys(ExState &State) { int rc; char Mode[32] = ""; if (State.GetStrParam(View, Mode, sizeof(Mode)) == 0) if (View->MView->Win->GetStr("Mode", sizeof(Mode), Mode, HIST_SETUP) == 0) return 0; rc = ChangeKeys(Mode); FullRedraw(); return rc; } int EBuffer::ChangeFlags(ExState &State) { int rc; char Mode[32] = ""; if (State.GetStrParam(View, Mode, sizeof(Mode)) == 0) if (View->MView->Win->GetStr("Mode", sizeof(Mode), Mode, HIST_SETUP) == 0) return 0; rc = ChangeFlags(Mode); FullRedraw(); return rc; } int EBuffer::ChangeTabSize(ExState &State) { int No; if (State.GetIntParam(View, &No) == 0) { char Num[10]; sprintf(Num, "%d", BFI(this, BFI_TabSize)); if (View->MView->Win->GetStr("TabSize", sizeof(Num), Num, HIST_SETUP) == 0) return 0; No = atol(Num); } if (No < 1) return 0; if (No > 32) return 0; BFI(this, BFI_TabSize) = No; FullRedraw(); return 1; } int EBuffer::SetIndentWithTabs(ExState &State) { int No; if (State.GetIntParam(View, &No) == 0) return 0; Flags.num[BFI_IndentWithTabs] = No ? 1 : 0; return 1; } int EBuffer::ChangeRightMargin(ExState &State) { char Num[10]; int No; if (State.GetIntParam(View, &No) == 0) { sprintf(Num, "%d", BFI(this, BFI_RightMargin) + 1); if (View->MView->Win->GetStr("RightMargin", sizeof(Num), Num, HIST_SETUP) == 0) return 0; No = atol(Num) - 1; } if (No <= 1) return 0; BFI(this, BFI_RightMargin) = No; Msg(S_INFO, "RightMargin set to %d.", No + 1); return 1; } int EBuffer::ChangeLeftMargin(ExState &State) { char Num[10]; int No; if (State.GetIntParam(View, &No) == 0) { sprintf(Num, "%d", BFI(this, BFI_LeftMargin) + 1); if (View->MView->Win->GetStr("LeftMargin", sizeof(Num), Num, HIST_SETUP) == 0) return 0; No = atol(Num) - 1; } if (No < 0) return 0; BFI(this, BFI_LeftMargin) = No; Msg(S_INFO, "LeftMargin set to %d.", No + 1); return 1; } int EBuffer::CanQuit() { if (Modified) return 0; else return 1; } int EBuffer::ConfQuit(GxView *V, int multiFile) { if (Modified) { if (multiFile) { switch (V->Choice(GPC_ERROR, "File Modified", 5, "&Save", "&As", "A&ll", "&Discard", "&Cancel", "%s", FileName)) { case 0: /* Save */ if (Save() == 0) return 0; break; case 1: /* As */ { char FName[MAXPATH]; strcpy(FName, FileName); if (V->GetFile("Save As", sizeof(FName), FName, HIST_PATH, GF_SAVEAS) == 0) return 0; if (FileSaveAs(FName) == 0) return 0; } break; case 2: /* Save all */ return -2; case 3: /* Discard */ break; case 4: /* Cancel */ case -1: default: return 0; } }else { switch (V->Choice(GPC_ERROR, "File Modified", 4, "&Save", "&As", "&Discard", "&Cancel", "%s", FileName)) { case 0: /* Save */ if (Save() == 0) return 0; break; case 1: /* As */ { char FName[MAXPATH]; strcpy(FName, FileName); if (V->GetFile("Save As", sizeof(FName), FName, HIST_PATH, GF_SAVEAS) == 0) return 0; if (FileSaveAs(FName) == 0) return 0; } break; case 2: /* Discard */ break; case 3: /* Cancel */ case -1: default: return 0; } } } return 1; } void EBuffer::GetName(char *AName, int MaxLen) { strncpy(AName, FileName, MaxLen); AName[MaxLen - 1] = 0; } void EBuffer::GetPath(char *APath, int MaxLen) { JustDirectory(FileName, APath); } void EBuffer::GetInfo(char *AInfo, int MaxLen) { sprintf(AInfo, "%2d %04d:%03d%c%-150s ", ModelNo, 1 + CP.Row, 1 + CP.Col, Modified ? '*': ' ', FileName); } void EBuffer::GetTitle(char *ATitle, int MaxLen, char *ASTitle, int SMaxLen) { char *p; strncpy(ATitle, FileName, MaxLen - 1); ATitle[MaxLen - 1] = 0; p = SepRChr(FileName); if (p) { strncpy(ASTitle, p + 1, SMaxLen - 1); ASTitle[SMaxLen - 1] = 0; } else { strncpy(ASTitle, FileName, SMaxLen - 1); ASTitle[SMaxLen - 1] = 0; } } #ifdef CONFIG_I_ASCII int EBuffer::ASCIITable(ExState &/*State*/) { int rc; rc = View->MView->Win->PickASCII(); if (rc != -1) return InsertChar(char(rc)); return 0; } #endif int EBuffer::ScrollLeft(ExState &State) { int Cols; if (State.GetIntParam(View, &Cols) == 0) Cols = 8; return ScrollLeft(Cols); } int EBuffer::ScrollRight(ExState &State) { int Cols; if (State.GetIntParam(View, &Cols) == 0) Cols = 8; return ScrollRight(Cols); } int EBuffer::ScrollDown(ExState &State) { int Rows; if (State.GetIntParam(View, &Rows) == 0) Rows = 1; return ScrollDown(Rows); } int EBuffer::ScrollUp(ExState &State) { int Rows; if (State.GetIntParam(View, &Rows) == 0) Rows = 1; return ScrollUp(Rows); } #ifdef CONFIG_TAGS int EBuffer::FindTag(ExState &State) { char Tag[MAXSEARCH] = ""; if (State.GetStrParam(View, Tag, sizeof(Tag)) == 0) if (View->MView->Win->GetStr("Find tag", sizeof(Tag), Tag, HIST_SEARCH) == 0) return 0; int j = 2; while (j--) { int i; i = TagFind(this, View, Tag); if (i > 0) return 1; else if (j && (i < 0)) { /* Try autoload tags */ if (View->ExecCommand(ExTagLoad, State) == 0) break; } else { Msg(S_INFO, "Tag '%s' not found.", Tag); break; } } return 0; } #endif // these two will probably be replaced in the future int EBuffer::InsertDate(ExState &State) { char strArg[128] = ""; char buf[128], *p; time_t t; time(&t); if (State.GetStrParam(View, strArg, sizeof(strArg))) { struct tm *tt = localtime(&t); strftime(buf, sizeof(buf), strArg, tt); buf[sizeof(buf) - 1] = 0; } else { //** 012345678901234567890123 //** Wed Jan 02 02:23:54 1991 p = ctime(&t); sprintf(buf, "%.10s %.4s", p, p + 20); } puts(buf); return InsertString(buf, strlen(buf)); } int EBuffer::InsertUid() { char *p = getenv("USER"); if (p == 0) p = getenv("NAME"); if (p == 0) p = getenv("ID"); // mostly for Windows. Why they can't just be standard, I don't know... if (p == 0) p = getenv("USERNAME"); if (p == 0) { Msg(S_INFO, "User ID not set ($USER)."); //return 0; p = "UNKNOWN USER"; } return InsertString(p, strlen(p)); } int EBuffer::ShowHelpWord(ExState &State) { //** Code for BlockSelectWord to find the word under the cursor, const char *achr = "+-_."; // these are accepted characters char buf[128]; int Y = VToR(CP.Row); PELine L = RLine(Y); int P; P = CharOffset(L, CP.Col); // fix \b for the case of CATBS for(int i = 0; i < P; i++) { //printf("%d - %d %d %c %c\n", i, P, L->Chars[i], //L->Chars[i], L->Chars[P]); if ((L->Chars[i] == '\b') && (P < (L->Count - 2))) P += 2; } size_t len = 0; if (P < L->Count) { // To start of word, while ((P > 0) && ((L->Chars[P - 1] == '\b') || isalnum(L->Chars[P - 1]) || (strchr(achr, L->Chars[P - 1]) != NULL))) P--; // '_' for underline is hidden in achr if ((P < (L->Count - 1)) && (L->Chars[P] == '\b')) P++; // To end of word, while ((len < (sizeof(buf) - 1)) && (P < L->Count)) { if (((P + 1) < L->Count) && (L->Chars[P + 1] == '\b')) P += 2; else if (isalnum(L->Chars[P]) || (strchr(achr, L->Chars[P]) != NULL)) buf[len++] = L->Chars[P++]; else break; } } buf[len] = 0; //printf("Word: %s\n", buf); //if (buf[0] == 0) { // Msg(INFO, "No valid word under the cursor."); // return 0; //} return View->SysShowHelp(State, buf[0] ? buf : 0); } int EBuffer::GetStrVar(int var, char *str, int buflen) { assert(buflen >= 0); if (buflen == 0) return 0; //puts("variable EBuffer\x7"); switch (var) { case mvFilePath: //puts("variable FilePath\x7"); strncpy(str, FileName, buflen); str[buflen - 1] = 0; return 1; case mvFileName: JustFileName(FileName, str); return 1; case mvFileDirectory: JustDirectory(FileName, str); return 1; case mvFileBaseName: { char buf[MAXPATH]; char *dot, *dot2; JustFileName(FileName, buf); dot = strchr(buf, '.'); while ((dot2 = strchr(dot + 1, '.')) != NULL) dot = dot2; if (dot) *dot = 0; strcpy(str, buf); } return 1; case mvFileExtension: { char buf[MAXPATH]; char *dot, *dot2; JustFileName(FileName, buf); dot = strchr(buf, '.'); while ((dot2 = strchr(dot + 1, '.')) != NULL) dot = dot2; if (dot) strcpy(str, dot); else str[0] = 0; } return 1; case mvChar: case mvWord: case mvLine: return 0; } return EModel::GetStrVar(var, str, buflen); } int EBuffer::GetIntVar(int var, int *value) { switch (var) { case mvCurRow: *value = VToR(CP.Row) + 1; return 1; case mvCurCol: *value = CP.Col; return 1; } return EModel::GetIntVar(var, value); }