home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
editors
/
ae.arj
/
AE2.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-02-27
|
17KB
|
462 lines
unit AE2 ;
{$B-}
{$I-}
{$S+}
{$V-}
{-----------------------------------------------------------------------------}
{ This unit contains all movement procedures. }
{ All procedures operate on the current workspace (indicated by CurrentWsnr), }
{ unless specified otherwise. }
{-----------------------------------------------------------------------------}
interface
uses Crt,Dos,AE0,AE1 ;
procedure Home (var P:Position) ;
procedure EndOfLine (var P:Position) ;
procedure CalculateColnr (var P:position) ;
procedure SkipDown (var P:Position ; Distance:word) ;
procedure SkipUp (var P:Position ; Distance:word) ;
procedure WordDown (var P:Position) ;
procedure WordUp (var P:Position) ;
procedure LineDown (var P:Position) ;
procedure LineUp (var P:Position) ;
procedure SearchUp (Target:string ; var P:Position ; LimitIndex:word) ;
procedure SearchDown (Target:string ; var P:Position ; LimitIndex:word) ;
procedure SearchString (Target:string ; var P:Position) ;
procedure MatchBracketsDown (OpenBracket,CloseBracket:char ; var P:Position) ;
procedure MatchBracketsUp (OpenBracket,CloseBracket:char ; var P:Position) ;
implementation
{-----------------------------------------------------------------------------}
{ Sets P to the first column of the line it is pointing to }
{-----------------------------------------------------------------------------}
procedure Home (var P:Position) ;
begin
Dec (P.Index,P.Colnr-1) ;
P.Colnr := 1 ;
end ;
{-----------------------------------------------------------------------------}
{ Sets P to the last column of the line it is pointing to (CR or end of file) }
{-----------------------------------------------------------------------------}
procedure EndOfLine (var P:Position) ;
begin
with Workspace[CurrentWsnr] do
begin
while (Buffer^[P.Index] <> CR) and
(P.Index < Buffersize) do
begin
Inc (P.Index) ;
Inc (P.Colnr) ;
end ;
end ; { of with }
end ;
{-----------------------------------------------------------------------------}
{ Re-calculates the column number by searching for a previous line feed }
{-----------------------------------------------------------------------------}
procedure CalculateColnr (var P:position) ;
begin
with Workspace[CurrentWsnr] do
begin
if P.Linenr = 1
then P.Colnr := P.Index
else begin
P.Colnr := 1 ;
while (Buffer^[P.Index-P.Colnr] <> CR) do Inc (P.Colnr) ;
if Buffer^[P.Index-P.Colnr+1] = LF
then Dec (P.Colnr) ;
end ;
end ;
end ;
{-----------------------------------------------------------------------------}
{ Skips P <Distance> positions downward, adjusting line and column number. }
{ If the end of the buffer is reached, the procedure stops. }
{-----------------------------------------------------------------------------}
procedure SkipDown (var P:Position ; Distance:word) ;
var Counter : word ;
begin
with Workspace[CurrentWsnr] do
begin
for Counter := 1 to Distance do
begin
if P.Index = BufferSize then Exit ;
if Buffer^[P.Index] = CR
then begin
Inc (P.Linenr) ;
if Buffer^[P.Index+1] = LF
then P.Colnr := 0
else P.Colnr := 1 ;
end
else Inc (P.Colnr) ;
Inc (P.Index) ;
end ;
end ;
end ;
{-----------------------------------------------------------------------------}
{ Skips P <Distance> positions upward, adjusting line and column number. }
{ If the start of the buffer is reached, the procedure stops. }
{-----------------------------------------------------------------------------}
procedure SkipUp (var P:Position ; Distance:word) ;
var Counter : word ;
begin
with Workspace[CurrentWsnr] do
begin
if Distance < P.Colnr
then begin
{ P will remain within current line }
Dec (P.Colnr,Distance) ;
Dec (P.Index,Distance) ;
end
else begin
if P.Index <= Distance
then begin
{ go to start of buffer }
P.Index := 1 ;
P.Colnr := 1 ;
Exit ;
end ;
for Counter := 1 to Distance do
begin
Dec (P.Index) ;
if Buffer^[P.Index] = CR
then Dec (P.Linenr) ;
end ;
CalculateColnr (P) ;
end ;
end ;
end ;
{-----------------------------------------------------------------------------}
{ Skips P downward until the beginning of the next word in the text. }
{-----------------------------------------------------------------------------}
procedure WordDown (var P:Position) ;
begin
with Workspace[CurrentWsnr] do
begin
while not ((Buffer^[P.Index] in WordSeparators) or
(P.Index = BufferSize)) do
begin
Inc (P.Colnr) ;
Inc (P.Index) ;
end ;
while (Buffer^[P.Index] in WordSeparators) and
(P.Index < BufferSize) do
begin
if Buffer^[P.Index] = CR
then begin
Inc (P.Linenr) ;
if Buffer^[P.Index+1] = LF
then P.Colnr := 0
else P.Colnr := 1 ;
end
else Inc (P.Colnr) ;
Inc (P.Index) ;
end ;
end ;
end ;
{-----------------------------------------------------------------------------}
{ Skips P upward until the beginning of the previous word in the text. }
{-----------------------------------------------------------------------------}
procedure WordUp (var P:Position) ;
begin
with Workspace[CurrentWsnr] do
begin
if P.Index > 1
then begin
repeat Dec (P.Index) ;
if Buffer^[P.Index] = CR
then Dec (P.Linenr) ;
until ((not (Buffer^[P.Index] in WordSeparators)) or
(P.Index = 1)) ;
while ((not (Buffer^[P.Index] in WordSeparators)) and
(P.Index > 0)) do
begin
Dec (P.Index) ;
end ;
Inc (P.Index) ;
CalculateColnr (P) ;
end ;
end ;
end ;
{-----------------------------------------------------------------------------}
{ Skips P downward to the first column of the next line. }
{ If the end of the buffer is reached, the procedure stops. }
{-----------------------------------------------------------------------------}
procedure LineDown (var P:Position) ;
var StartIndex : word ;
begin
StartIndex := P.Index ;
with Workspace[CurrentWsnr] do
begin
while (Buffer^[P.Index] <> CR) and (P.Index < BufferSize) do
Inc (P.Index) ;
if (Buffer^[P.Index] = CR)
then begin
Inc (P.Index) ;
if Buffer^[P.Index] = LF
then Inc (P.Index) ;
P.Colnr := 1 ;
Inc (P.Linenr) ;
end
else Inc (P.Colnr,P.Index-StartIndex) ;
end ;
end ;
{-----------------------------------------------------------------------------}
{ Skips P upward to the first column of the previous line. }
{ If the start of the buffer is reached, the procedure stops. }
{-----------------------------------------------------------------------------}
procedure LineUp (var P:Position) ;
begin
if P.Linenr = 1
then Dec (P.Index,P.Colnr-1)
else with workspace[CurrentWsnr] do
begin
{ go past carriage return at start of current line }
Dec (P.Index,P.Colnr+1) ;
if Buffer^[P.Index+1] = LF then Dec (P.Index) ;
{ find start of line }
while (Buffer^[P.Index] <> CR) and (P.Index > 0) do
Dec (P.Index) ;
if Buffer^[P.Index+1] = LF
then Inc (P.Index,2)
else Inc (P.Index) ;
Dec (P.Linenr) ;
end ;
P.Colnr := 1 ;
end ;
{-----------------------------------------------------------------------------}
{ Searches downward for the string <Target>. On exit, P points to the first }
{ character of the string in the text buffer, if the string is found before }
{ index <LimitIndex> is reached. Otherwise, P will point to <LimitIndex>. }
{ The value of global variable Found will be set accordingly. }
{-----------------------------------------------------------------------------}
procedure SearchDown (Target:string ; var P:Position ; LimitIndex:word) ;
var Counter : byte ;
begin
Found := False ;
with Workspace[Currentwsnr] do
begin
if IgnoreCase
then begin
{ case-insensitive search }
Target := UpperCase (Target) ;
while (not Found) and (P.Index <= LimitIndex) do
begin
{ search text for first character of Target }
repeat if Buffer^[P.Index] = CR
then Inc (P.Linenr) ;
Inc (P.Index) ;
until (UpCase(Buffer^[P.Index]) = Target[1]) or
(P.Index > LimitIndex) ;
Counter := 2 ;
{ check if following characters are equal to Target }
while (UpCase(Buffer^[P.Index+Counter-1]) = Target[Counter])
and (Counter <= Length(Target)) do
Inc (Counter) ;
Found := (Counter > Length(Target)) and
((P.Index + Length(Target) - 1) <= LimitIndex)
end ; { of while }
end { of case-insensitive search }
else begin
{ normal search }
while (not Found) and (P.Index <= LimitIndex) do
begin
{ search text for first character of Target }
repeat if Buffer^[P.Index] = CR
then Inc (P.Linenr) ;
Inc (P.Index) ;
until (Buffer^[P.Index] = Target[1]) or
(P.Index > LimitIndex) ;
Counter := 2 ;
{ check if following characters are equal to Target }
while (Buffer^[P.Index+Counter-1] = Target[Counter]) and
(Counter <= Length(Target)) do
Inc (Counter) ;
Found := (Counter > Length(Target)) and
((P.Index + Length(Target) - 1) <= LimitIndex)
end ; { of while }
end ; { of normal search }
CalculateColnr (P) ;
end ; { of with }
end ; { of procedure }
{-----------------------------------------------------------------------------}
{ Searches upward for the string <Target>. On exit, P points to the first }
{ character of the string in the text buffer, if the string is found before }
{ index <LimitIndex> is reached. Otherwise, P will point to <LimitIndex>. }
{ The value of global variable Found will be set accordingly. }
{-----------------------------------------------------------------------------}
procedure SearchUp (Target:string ; var P:Position ; LimitIndex:word) ;
var Counter : word ;
begin
Found := False ;
with Workspace[CurrentWsnr] do
begin
if IgnoreCase
then begin
{ case-insensitive search }
Target := UpperCase (Target) ;
while (not Found) and (P.Index >= LimitIndex) do
begin
{ search text for first character of Target }
repeat Dec (P.Index) ;
if Buffer^[P.Index] = CR
then Dec (P.Linenr) ;
until (UpCase(Buffer^[P.Index]) = Target[1]) or
(P.Index < LimitIndex) ;
Counter := 2 ;
{ check if following characters are equal to Target }
while (UpCase(Buffer^[P.Index+Counter-1]) =
Target[Counter]) and
(Counter <= Length(Target)) do
Inc (Counter) ;
Found := (Counter > Length(Target)) and
(P.Index >= LimitIndex) ;
end ; { of while }
end { of case-insensitive search }
else begin
{ normal search }
while (not Found) and (P.Index >= LimitIndex) do
begin
{ search text for first character of Target }
repeat Dec (P.Index) ;
if Buffer^[P.Index] = CR
then Dec (P.Linenr) ;
until (Buffer^[P.Index] = Target[1]) or
(P.Index < LimitIndex) ;
Counter := 2 ;
{ check if following characters are equal to Target }
while (Buffer^[P.Index+Counter-1] = Target[Counter]) and
(Counter <= Length(Target)) do
Inc (Counter) ;
Found := (Counter > Length(Target)) and
(P.Index >= LimitIndex) ;
end ; { of while }
end { of normal search } ;
CalculateColnr (P) ;
end ; { of with }
end ; { of procedure }
{-----------------------------------------------------------------------------}
{ Performs a general search for <Target> according to the search options }
{ that are stored in global boolean variables. (Searching is done by calling }
{ SearchDown or SearchUp.) If Target is found, P will point to the first }
{ character. }
{-----------------------------------------------------------------------------}
procedure SearchString (Target:string ; var P:Position) ;
begin
if Length(Target) = 0
then Found := False
else begin
with Workspace[CurrentWsnr] do
begin
if ReverseSearch
then SearchUp (Target,P,1)
else SearchDown (Target,P,BufferSize-1) ;
end ; { of with }
end ;
end ;
{-----------------------------------------------------------------------------}
{ Searches downward for an occurrence of CloseBracket in the buffer, }
{ matching the OpenBracket that P is assumed to point at when the procedure }
{ is called. If no matching bracket is found, P will point to the end of the }
{ buffer, and Found is set to False. }
{-----------------------------------------------------------------------------}
procedure MatchBracketsDown (OpenBracket,CloseBracket:char ; var P:Position) ;
var Level : integer ;
{ Level keeps track of the nesting level of the brackets }
begin
Level := 1 ;
with Workspace[CurrentWsnr] do
begin
while (Level > 0) and (P.Index < BufferSize) do
begin
if Buffer^[P.Index] = CR
then Inc (P.Linenr) ;
Inc (P.Index) ;
if Buffer^[P.Index] = OpenBracket then Inc (Level) ;
if Buffer^[P.Index] = CloseBracket then Dec (Level) ;
end ; { of while }
CalculateColnr (P) ;
end ;
Found := (Level = 0) ;
end ;
{-----------------------------------------------------------------------------}
{ Searches upward for an occurrence of CloseBracket in the buffer, matching }
{ the OpenBracket that P is assumed to point at when the procedure is called. }
{ If no matching bracket is found, P will point to the start of the }
{ buffer, and Found is set to False. }
{-----------------------------------------------------------------------------}
procedure MatchBracketsUp (OpenBracket,CloseBracket:char ; var P:Position) ;
var Level : integer ;
{ Level keeps track of the nesting level of the brackets }
begin
Level := -1 ;
with Workspace[CurrentWsnr] do
begin
while (Level < 0) and (P.Index > 1) do
begin
Dec (P.Index) ;
if Buffer^[P.Index] = CR
then Dec (P.Linenr) ;
if Buffer^[P.Index] = OpenBracket then Inc (Level) ;
if Buffer^[P.Index] = CloseBracket then Dec (Level) ;
end ; { of while }
CalculateColnr (P) ;
end ;
Found := (Level = 0) ;
end ;
{-----------------------------------------------------------------------------}
end.