home *** CD-ROM | disk | FTP | other *** search
- 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.