1513 lines
48 KiB
C++
1513 lines
48 KiB
C++
/* 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);
|
|
}
|