This function tries to find which tail field contains the
cursor, and returns an ibp-field-object if
successful. If the cursor is not within any tail field,
it returns nil.
This function assumes that ibp-field-list
is globally defined as a list of field-def
objects that describe the format of the tail fields.
;; - - - i b p - b r a c k e t - t a i l - f i e l d - - -
(defun ibp-bracket-tail-field (line)
"Finds the tail field containing point, if any.
[ if (line is a ibp-line-object for the line containing point)
and (line is a type that has a tail) ->
if point is within a tail field ->
return an ibp-field-object describing that field
else ->
return nil ]
----------------------------------------------------------------"
First we open a let scope, and define some
local variables:
flag
Set initially to 'scanning, this
variable is changed to 'found if we
found the correct field, or 'not-found if we go past the end of the line.
fieldx
Points to the current element of ibp-field-list.
n-fields
Points to the last+1 element of ibp-field-list.
field-def
Holds the current field-def object
from ibp-field-list.
f-beg
Holds the position of the beginning of the current field.
f-end
Holds the last+1 position of the current field.
f-len
Holds the length of the current field.
(let (flag ;; Changing this value exits the while loop
fieldx ;; Indexes ibp-field-list
n-fields ;; Index of last element of ibp-field-list
field-def ;; Holds each field-def object in turn
f-beg ;; Walks the start columns of each field
f-end ;; End of the current field
f-len) ;; Length of the current field
We set up initial values before walking the record.
;; [ flag := 'scanning
;; fieldx := 0
;; n-fields := index of last element of ibp-field-list
;; f-beg := location of tail of line ]
(setq flag 'scanning)
(setq fieldx 0)
(setq n-fields (length ibp-field-list))
(setq f-beg (ibp-line-tail line))
The while loop runs until the value of
flag is changed to something other than
'scanning.
;; [ if point is within a field whose length is given in
;; elements fieldx through (n-fields - 1) of ibp-field-list ->
;; flag := 'found
;; f-beg := position of the start of that field
;; f-end := position of the end of that field
;; else ->
;; flag := 'not-found
;; f-beg := anything
;; f-end := anything ]
(while (eq flag 'scanning)
Here is the intended function for the body of this loop:
;; [ if fieldx >= n-fields ->
;; flag := 'not-found
;; else if point is within a field starting at f-beg and having
;; length field-lengths[fieldx] ->
;; flag := 'found
;; else ->
;; f-beg := f-beg + ibp-field-list[fieldx].len
;; fieldx := fieldx + 1 ]
If fieldx has exceeded the number of
fields in ibp-field-list, set flag to 'not-found, and we are done.
(if (>= fieldx n-fields)
(setq flag 'not-found)
The progn construct executes all the
functions inside it, and returns the value of the last
one. First we set up the values of the loop variables by
extracting them from the fieldxth element of ibp-field-list.
(progn ;; The field exists, is point in it?
(setq field-def (elt ibp-field-list fieldx))
(setq f-len (ibp-field-def-len field-def)) ;; Get the length...
(setq f-end (+ f-beg f-len)) ;; ...and end of next field
If the cursor is at or beyond f-beg, and
it is before f-end, we have found the
field containing the cursor; we set flag
to 'found so the loop will terminate
successfully.
(if (and (>= (point) f-beg) ;; Is f-beg<=point<f-end?
(< (point) f-end))
(setq flag 'found) ;; Yes, found it
If the cursor isn't in the current field, move f-beg to the end of the field, increment fieldx, and go around the loop again.
(progn ;; No, keep looking
(setq f-beg f-end)
(setq fieldx (1+ fieldx)))))))
If the loop terminated unsuccessfully, flag will now be 'not-found, so we should
return nil to signify that we couldn't
find the cursor's field. If it was successful, we
package up an ibp-field-object made from the
current field beginning and end positions, along with the
default field content from ibp-field-list,
and return that to the caller.
;; [ if flag is 'not-found ->
;; return nil
;; else ->
;; return an ibp-field-object whose .beg=f-beg, .end=f-end,
;; and .filler=ibp-field-list[fieldx].filler ]
(if (eq flag 'not-found)
nil
(ibp-field-object f-beg f-end
(ibp-field-def-filler (elt ibp-field-list fieldx))))))