Next / Previous / Contents / Shipman's homepage

5.11. ibp-field-fill: Move to the end of a field

This function always moves the cursor to the end of the current field. It will also fill out the field's contents if it is incomplete.

ibp.el
;; - - -   i b p - f i e l d - f i l l   - - -

(defun ibp-field-fill (field line)
  "If field is not full, fill it.  In any case, move to end of field.

    [ if (line is a ibp-line-object with a tail) ->
        if line.end is inside field ->
          buffer  :=  buffer with ibp-field-fill (field, line.end,
                      field.filler) appended after line.end
          point   :=  field.end
        else ->
          point  :=  field.end ]
----------------------------------------------------------------"

First we open a let scope and define some local variables:

fill-size

If the field is too short, this is the number of characters we have to add to fill it up.

fill-string

If the field is too short, this is the actual content we need to add to fill it up.

field-off

If the field is too short, this is the distance between the start of the field and the end of its current contents.

field-size

Size of the field if full.

ibp.el
  (let (fill-size         ;; Size of fill string to be inserted
        fill-string       ;; Fill string to be inserted
        field-off         ;; Offset within the field to insertion point
        field-size)       ;; Size of the field

If the end of the line is past the end of the field, all we have to do is jump the cursor to the first character after the field, and we're done.

ibp.el
    (if (>= (ibp-line-end line) (ibp-field-end field)) 
        (goto-char (ibp-field-end field))

At this point, we know that the field is not full, so we need to fill it out. We compute the field's size, the offset to the point where we need to add filler content, and the size of the filler content.

ibp.el
      (progn
        ;; [ field-size  :=  size of field
        ;;   field-off   :=  line.end - field.beg
        ;;   fill-size   :=  field.end - line.end ]
        (setq field-size (- (ibp-field-end field) (ibp-field-beg field)))
        (setq field-off  (- (ibp-line-end line) (ibp-field-beg field)))
        (setq fill-size  (- (ibp-field-end field) (ibp-line-end line)))

If the field's definition doesn't specify any particular filler content, we make up a string of spaces. Otherwise, we extract its filler content starting at position field-off. In either case, the filler content to be added is left in fill-string.

ibp.el
        ;; [ if field.filler is nil ->
        ;;     fill-string  :=  a string of fill-size blanks
        ;;   else ->
        ;;     fill-string  :=  field.filler[field.off:field-size] ]
        (setq fill-string
              (if (null (ibp-field-filler field))
                  (make-string fill-size ? )
                (substring (ibp-field-filler field) field-off field-size)))

All that remains is to jump the cursor to the end of the line and append fill-string. The insert function leaves the cursor at the end of the inserted content, which is where we want it.

ibp.el
        ;; [ buffer  :=  buffer with fill-string appended at line.end
        ;;   point   :=  field.end ]
        (goto-char (ibp-line-end line))
        (insert fill-string)))))