%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% TEXT-COMMANDS.SL - NMODE Sentence, Paragraph, Filling, and Formatting
%
% Author: Jeff Soreff
% Hewlett-Packard/CRC
% Date: 8 December 1982
% Revised: 1 February 1983
% Revised: 2 March 1983
%
% 2-Mar-83 Jeff Soreff
% Mark-paragraph-command was altered to push the current position
% onto the ring of marks before marking the paragraph.
% 15-Feb-83 Jeff Soreff
% Bugs were removed from fill-comment-command and from next-char-list.
% A test for arriving at a line end was added to fill-comment-command
% in the while loop which locates the fill prefix to be used. It fixed an
% infinite loop in this while which occurred when one did a
% fill-comment-command while on the last line in the buffer, if the
% prefix-finding loop got to the buffer's end. An at-line-end? test was used
% instead of an at-buffer-end? test since the fill prefix found should never
% go over a line.
% In next-char-list the initialization of final-char-pos was changed
% from 0 to char-count. This removed a bug that led to setting the point
% at the start of a prefixed line after a fill which moved point to the first
% availible position on that new line. Point should have been left AFTER the
% prefix. Changing the initialization of final-char-position allows
% next-char-list to accurately account for the spaces taken up by the prefix,
% since this count is passed to its char-count argument.
% 1-Feb-83 Alan Snyder
% Changed literal ^L in source to #\FF.
% 30-Dec-82 Alan Snyder
% Extended C-X = to set the current line number if a command number is
% given.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(CompileTime (load extended-char fast-strings fast-int))
(fluid '(nmode-current-buffer text-mode fill-prefix fill-column
nmode-command-argument nmode-command-argument-given nmode-command-number-given
nmode-command-killed sentence-terminators sentence-extenders))
(setf sentence-terminators '(#/! #/. #/?))
(setf sentence-extenders '(#/' #/" #/) #/]))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% User/Enhancer option sensitive function:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The text-justifier function may be altered if one wishes to have the
% same flexibility as EMACS'S TECO search strings provide.
(de text-justifier-command? ()
% This function checks to see if the rest of the line is a text
% justifier command. It returns a boolean and leaves point alone.
(= (next-character) #/.))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Start of Sentence Functions and Associated Support Functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(de valid-sentence-end? ()
% This function checks that a sentence is followed by two blanks, a
% newline or a blank and a newline. It advances point one space.
% It returns a boolean value.
(if (at-line-end?) t
(move-forward)
(and (= (previous-character) #\blank)
(or (at-line-end?)(= (next-character) #\blank)))))
(de move-to-end-of-last-sentence ()
% This function moves point to the end of the preceding sentence,
% after extenders. This function does not return a useful value
(while (not
(or (at-buffer-start?)
(when
% This when returns true if it hits a valid sentence end.
(member (previous-character) sentence-terminators)
(let ((scan-place (buffer-get-position)))
(while
(member (next-character) sentence-extenders)
(move-forward))
(let* ((tentative-sentence-end (buffer-get-position))
(true-end (valid-sentence-end?)))
(buffer-set-position
(if true-end tentative-sentence-end scan-place))
true-end)))))
(move-backward)))
(de start-of-last-sentence ()
% This function restores point to its former place. It returns the
% location of the start of the preceding sentence.
(let ((place (buffer-get-position))(start nil)(end nil))
(move-to-end-of-last-sentence)
(setf end (buffer-get-position))
(skip-forward-blanks) % possibly past starting position this time
(setf start (buffer-get-position))
(when (buffer-position-lessp place start)
(buffer-set-position end) % end of last sentence, after extenders
(while % push back past extenders
(member (previous-character) sentence-extenders)
(move-backward))
(move-backward) % push back past sentence terminator character
(move-to-end-of-last-sentence)
(skip-forward-blanks)
(setf start (buffer-get-position)))
(buffer-set-position place)
start))
(de end-of-next-sentence ()
% This function restores point to its former place. It returns the
% location of the end of the next sentence.
(let ((place (buffer-get-position)))
(while (not
% the next sexp detects sentence ends and moves point to them
(or (at-buffer-end?)
(when % note that this returns (valid-sentence-end?)'s value
(member (next-character) sentence-terminators)
(move-forward)
(while
(member (next-character) sentence-extenders)
(move-forward))
(let ((tentative-sentence-end (buffer-get-position)))
(if (valid-sentence-end?)
(buffer-set-position tentative-sentence-end))))))
(move-forward))
(prog1
(buffer-get-position)
(buffer-set-position place))))
(de forward-one-sentence ()
% This function moves point to the end of the next sentence or
% paragraph, whichever one is closer, and does not return a useful
% value.
(let ((sentence-end (end-of-next-sentence)))
(if (at-line-end?)(move-forward)) % kludge to get around xtra newline
(forward-one-paragraph)
(if (at-line-start?)(move-backward)) % kludge to get around xtra newline
(let ((paragraph-end (buffer-get-position)))
(buffer-set-position
(if (buffer-position-lessp sentence-end paragraph-end)
% "closer" is "earlier" or "before", in this case
sentence-end paragraph-end)))))
(de backward-one-sentence ()
% This function moves point to the start of the preceding sentence
% or paragraph, whichever one is closer. It does not return a useful
% value
(let ((sentence-start (start-of-last-sentence)))
(skip-backward-blanks)
(backward-one-paragraph)
(skip-forward-blanks)
(let ((paragraph-start (buffer-get-position)))
(buffer-set-position
(if (buffer-position-lessp sentence-start paragraph-start)
% "closer" is "later" or "after", in this case
paragraph-start sentence-start)))))
(de forward-sentence-command ()
% If nmode-command-argument is positive this function moves point
% forward by nmode-command-argument sentences , leaving it at the
% end of a sentence. If nmode-command-argument is negative it moves
% backwards by abs(nmode-command-argument) sentences, leaving it at
% the start of a sentence. This function does not return a useful
% value.
(if (minusp nmode-command-argument)
(for (from i 1 (- nmode-command-argument) 1)
(do (backward-one-sentence)))
(for (from i 1 nmode-command-argument 1)
(do (forward-one-sentence)))))
(de backward-sentence-command ()
% If nmode-command-argument is positive this function moves point
% backward by nmode-command-argument sentences , leaving it at the
% start of a sentence. If nmode-command-argument is negative it
% moves forwards by abs(nmode-command-argument) sentences, leaving
% it at the end of a sentence. This function does not return a
% useful value.
(if (minusp nmode-command-argument)
(for (from i 1 (- nmode-command-argument) 1)
(do (forward-one-sentence)))
(for (from i 1 nmode-command-argument 1)
(do (backward-one-sentence)))))
(de kill-sentence-command ()
% This function kills whatever forward-sentence-command jumps over.
% It leaves point after the killed text. This function is sensitive
% to the nmode command argument through forward-sentence-command.
(let ((place (buffer-get-position)))
(forward-sentence-command)
(update-kill-buffer (extract-region t place (buffer-get-position)))
(setf nmode-command-killed t)))
(de backward-kill-sentence-command ()
% This function kills whatever backward-sentence-command jumps over.
% It leaves point after the killed text. This function is sensitive
% to the nmode command argument through forward-sentence-command.
(let ((place (buffer-get-position)))
(backward-sentence-command)
(update-kill-buffer (extract-region t place (buffer-get-position)))
(setf nmode-command-killed t)))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Start of Paragraph Functions and Associated Support Functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(de rest-of-current-line-blank? ()
% This function detects if the rest of the line is blank. It
% returns a boolean value. It restores point.
(let ((last-position (buffer-get-position)))
(while (and (not (at-line-end?))
(char-blank? (next-character)))
(move-forward))
(prog1 (at-line-end?)
(buffer-get-position last-position))))
(de mismatched-prefix? ()
% This function checks to see if there is a fill prefix which
% doesn't match the start of the current line. It leaves point at
% the start of the current line if there is a mismatch, or just
% after the prefix if matched. It returns t if there is a fill
% prefix which does NOT match the line's start.
(move-to-start-of-line)
(when fill-prefix
(let ((start-line (buffer-get-position)))
(move-over-characters
(string-length % count of characters in fill-prefix
(getv fill-prefix 0)))
(when (not (text-equal
(extract-text nil
start-line
(buffer-get-position))
fill-prefix))
(buffer-set-position start-line)
t))))
(de pseudo-blank-line? ()
% This function tests to see if the current line should be kept out
% of paragraphs. It tests for: lines which don't match an existing
% fill prefix, blank lines, lines with only the fill prefix present,
% text justifier commands, and properly prefixed text justifier
% commands. It only checks for the text justifier commands in text
% mode. It leaves point at the start of the current line and
% returns a boolean value.
(or (mismatched-prefix?)
(prog1
(or (and (text-justifier-command?)
(eq text-mode (=> nmode-current-buffer mode)))
(rest-of-current-line-blank?))
(move-to-start-of-line))))
(de pseudo-indented-line? ()
% This function looks for page break characters or (in text mode)
% indentation (after a fill prefix, if present) which signal the
% start of a real paragraph. It always leaves point at the start of
% the current line and returns a boolean.
(prog1 (or
(= #\FF (next-character)) % page break character
(progn (mismatched-prefix?)
(and (char-blank? (next-character))
(eq text-mode (=> nmode-current-buffer mode)))))
(move-to-start-of-line)))
(de start-line-paragraph? ()
% This function tests the current line to see if it is the first
% line (not counting an empty line) in a paragraph. It leaves point
% at the start of line and returns a boolean value.
(and (not (pseudo-blank-line?))
(or (pseudo-indented-line?)
% next sexp checks for a previous blank line
(if (current-line-is-first?)
t
(move-to-previous-line)
(prog1
(pseudo-blank-line?)
(move-to-next-line))))))
(de end-line-paragraph? ()
% This function tests the current line to see if it is the last line
% in a paragraph. It leaves point at the start of line and returns
% a boolean value.
(and (not (pseudo-blank-line?))
% The next sexp checks for the two things on the next line of
% text that can end a paragraph: a blank line or an indented
% line which would start a new paragraph.
(if (current-line-is-last?)
t
(move-to-next-line)
(prog1
(or (pseudo-indented-line?)
(pseudo-blank-line?))
(move-to-previous-line)))))
(de forward-one-paragraph ()
% This function moves point to the end of the next or current
% paragraph, as EMACS defines it. This is either start of the line
% after the last line with any characters or, if the paragraph
% extends to the end of the buffer, then the end of the last line
% with characters. This function returns a boolean which is true if
% the function was stopped by a real paragraph end, rather than by
% the buffer's end.
(let ((true-end nil))
(while (not (or (setf true-end (end-line-paragraph?))
(current-line-is-last?)))
(move-to-next-line))
(move-to-next-line)
true-end))
(de forward-paragraph-command ()
% If nmode-command-argument is positive this function moves point
% forward by nmode-command-argument paragraphs , leaving it at the
% end of a paragraph. If nmode-command-argument is negative it moves
% backwards by abs(nmode-command-argument) paragraphs, leaving it at
% the start of a paragraph. This function does not return a useful
% value.
(if (minusp nmode-command-argument)
(for (from i 1 (- nmode-command-argument) 1)
(do (backward-one-paragraph)))
(for (from i 1 nmode-command-argument 1)
(do (forward-one-paragraph)))))
(de backward-one-paragraph ()
% This function moves point backward to the start of the previous
% paragraph. It returns a boolean which is true if the function was
% stopped by a real paragraph's start, instead of by the buffer's
% start.
(if (and (at-line-start?) % if past start of start line, don't miss
(start-line-paragraph?)) % start of current paragraph
(move-to-previous-line))
(let ((real-start nil))
(while (not (or (setf real-start (start-line-paragraph?))
(current-line-is-first?)))
(move-to-previous-line))
(unless (current-line-is-first?) % this sexp gets previous empty line on
(move-to-previous-line)
(unless (current-line-empty?)
(move-to-next-line)))
real-start))
(de backward-paragraph-command ()
% If nmode-command-argument is positive this function moves point
% backward by nmode-command-argument paragraphs , leaving it at the
% start of a paragraph. If nmode-command-argument is negative it
% moves forwards by abs(nmode-command-argument) paragraphs, leaving
% it at the end of a paragraph. This function does not return a
% useful value.
(if (minusp nmode-command-argument)
(for (from i 1 (- nmode-command-argument) 1)
(do (forward-one-paragraph)))
(for (from i 1 nmode-command-argument 1)
(do (backward-one-paragraph)))))
(de paragraph-limits ()
% This function returns a list of positions marking the next
% paragraph. Only real paragraph limits are returned. If there is
% only stuff that should be excluded from a paragraph between point
% and the end or the start of the buffer, then the appropriate limit
% of the paragraph is filled with the current buffer position. This
% function restores point.
(let* ((temp (buffer-get-position))(top temp)(bottom temp))
(when (forward-one-paragraph)
(setf bottom (buffer-get-position)))
(when (backward-one-paragraph)
(setf top (buffer-get-position)))
(buffer-set-position temp)
(list top bottom)))
(de mark-paragraph-command ()
% This function sets the mark to the end of the next paragraph, and
% moves point to its start. It returns nothing useful.
(let ((pair (paragraph-limits)))
(set-mark-from-point)
(buffer-set-position (first pair))
(set-mark (second pair))))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Start of Fill Functions and Associated Support Functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(de next-char-list (end char-count init-pos)
% This function returns a list, the first element of which is a list
% of characters, with their order the reverse of that in the
% original text, spaces squeezed to a single space between words,
% and with two spaces between sentences. The second element on the
% list returned is how far along the new line the position
% corresponding to "init-pos" wound up. Point is left after the
% last character packed in but before "end" or the next nonblank
% character.
(let* ((from-end-last-blanks 0)
(from-start-last-blanks 0)
(final-char-pos char-count)
(line-not-full (lessp char-count fill-column))
(first-end (buffer-get-position))
(next-sentence-wont-exhaust-region
(not (buffer-position-lessp end first-end)))
(new-char (next-character))
(line-list ()))
% start of loop for successive sentences
(while (and next-sentence-wont-exhaust-region line-not-full)
% The next sexp checks to see if the next sentence fits within
% the main region (from initial "point" to "end") with a
% character to spare for the next sentence iteration.
(let* ((next-sentence-end (end-of-next-sentence)))
(setf next-sentence-wont-exhaust-region
(not (buffer-position-lessp end next-sentence-end)))
(setf first-end (if next-sentence-wont-exhaust-region
next-sentence-end end)))
(skip-forward-blanks) % ignore blanks just before next sentence
% start of loop for successive characters
(while (and (setf line-not-full (or (lessp char-count fill-column)
% next sexp allows oversize words
(eq char-count from-end-last-blanks)))
(not (buffer-position-lessp first-end
(buffer-get-position))))
(setf new-char
% character compression sexp
(let ((next (next-character)))
(if (not (= (skip-forward-blanks)
next))
#\blank
(move-forward)
next)))
(setq line-list (cons new-char line-list))
(incr char-count)
(when (buffer-position-lessp (buffer-get-position) init-pos)
(setf final-char-pos char-count))
(cond ((= new-char #\blank)
(setf from-end-last-blanks 0)
(setf from-start-last-blanks 1))
(t % normal character
(incr from-end-last-blanks)
(incr from-start-last-blanks))))
% The next sexp terminates sentences properly.
(when (and line-not-full next-sentence-wont-exhaust-region)
(setf line-list (append '(#\blank #\blank) line-list))
(incr char-count 2)
(setf from-end-last-blanks 0)
(setf from-start-last-blanks 2)))
% The next sexp trims off the last partial word or extra blank(s).
(when (or (char-blank? (car line-list)) % extra blank(s)
(not (or line-not-full % last partial word
(at-line-end?)
(char-blank? (next-character)))))
(for (from i 1 from-start-last-blanks 1)
(do (setf line-list (cdr line-list))))
(move-over-characters (- from-end-last-blanks)))
% guarantee that buffer-position is left at or before end
(if (buffer-position-lessp end (buffer-get-position))
(buffer-set-position end))
(list line-list final-char-pos)))
(de justify (input desired-length)
% This function pads its input with blanks and reverses it. It
% leaves point alone.
(let*
((input-length (length input))
(output ())
(needed-blanks (- desired-length input-length))
% total number needed to fill out line
(input-blanks % count preexisting blanks in input
(for (in char input)
(with blanks)
(count (= char #\blank) blanks)
(returns blanks))))
(for (in char input)
(with (added-blanks 0) % number of new blanks added so far
(handled-blanks 0)) % number of input blanks considered so far
(do
(setf output (cons char output))
(when (= char #\blank)
(incr handled-blanks)
% calculate number of new blanks needed here
% fraction of original blanks passed=handled-blanks/input-blanks
% blanks needed here~fraction*[needed-blanks(for whole line)]-(added-blanks)
(let ((new-blanks (- (/ (* needed-blanks handled-blanks)
input-blanks)
added-blanks)))
(when (> new-blanks 0)
(for (from new 1 new-blanks 1)
(do
(setf output (cons #\blank output))))
(incr added-blanks new-blanks))))))
output))
(de position-adjusted-for-prefix (position)
% This is a pure function which returns a position, corrected for
% the length of the prefix on the position's line.
(let ((current-place (buffer-get-position)))
(buffer-set-position position)
(mismatched-prefix?)
(let ((prefix-length-or-zero (current-char-pos)))
(buffer-set-position current-place)
(let ((adjusted-char-pos (- (buffer-position-column position)
prefix-length-or-zero)))
(if (< adjusted-char-pos 0)(setf adjusted-char-pos 0))
(buffer-position-create (buffer-position-line position)
adjusted-char-pos)))))
(de remove-prefix-from-region (start end)
% The main effect of this function is to strip the fill prefix off a
% region in the buffer. this function does not return a useful value
% or move point.
(let ((current-place (buffer-get-position)))
(buffer-set-position start)
(if (current-line-empty?)(move-to-next-line))
(while (not (buffer-position-lessp end (buffer-get-position)))
(setf start (buffer-get-position))
(unless (or
(mismatched-prefix?)
(buffer-position-lessp end (buffer-get-position)))
(extract-text t start (buffer-get-position)))
(move-to-next-line))
(buffer-set-position current-place)))
(de fill-directed-region (start end init-pos)
% The main effect of this function is to replace text with filled or
% justified text. This function returns a list. The first element
% is the increase in the number of lines in the text due to filling.
% The second element is the filled position equivalent to "init-pos"
% in the original text. The point is left at the end of the new
% text
(let ((modified-flag (=> nmode-current-buffer modified?))
(old-text (extract-text nil start end))
(final-pos init-pos)
(adj-end (position-adjusted-for-prefix end))
(adj-init-pos (position-adjusted-for-prefix init-pos)))
(when fill-prefix (remove-prefix-from-region start end))
(setf end adj-end)
(buffer-set-position start)
(let*
((list-of-new-lines (when % handles first blank line
(current-line-empty?)
(move-to-next-line)
'("")))
(new-packed-line '(nil 0))
(prefix-list
(if fill-prefix
(string-to-list
(getv fill-prefix 0))))
(prefix-column (map-char-to-column
(list2string prefix-list)
(length prefix-list)))
(new-line nil)
(place (buffer-get-position)) % handles indentation
(junk (skip-forward-blanks)) % handles indentation
(start-char-pos (+ (current-display-column) % handles indentation
prefix-column)) % and first time switch
(indent-list (string-to-list % handles indentation
(getv (extract-text
nil place (buffer-get-position)) 0))))
(while
(let* ((after-line-start (buffer-position-lessp
(buffer-get-position) adj-init-pos))
(new-packed-line
(next-char-list end start-char-pos adj-init-pos))
(before-line-end (buffer-position-lessp
adj-init-pos (buffer-get-position))))
(when (and after-line-start before-line-end)
(setf final-pos (buffer-position-create
(+ (buffer-position-line start)
(length list-of-new-lines))
(second new-packed-line))))
% test that anything is left in the region, as well as getting line
(setf new-line (first new-packed-line)))
(setf new-line
(list2string
(append % add in fill prefix and indentation
(append prefix-list
(unless (= start-char-pos prefix-column) indent-list))
(if (and nmode-command-argument-given % triggers justification
(not (or % don't justify the last line in a paragraph
(buffer-position-lessp end (buffer-get-position))
(at-buffer-end?))))
(justify new-line (- fill-column start-char-pos))
(reverse new-line)))))
(setf list-of-new-lines (cons new-line list-of-new-lines))
% only the first line in a paragraph is indented
(setf start-char-pos prefix-column))
(setf list-of-new-lines (cons (list2string nil) list-of-new-lines))
% The last line in the new paragraph is added in last setf.
(let ((line-change 0)
(new-text (list2vector (reverse list-of-new-lines))))
(when list-of-new-lines
(extract-text t start end)
(setf line-change
(- (size new-text)
(size old-text)))
(insert-text new-text)
(if (and (not modified-flag)
(text-equal new-text old-text))
(=> nmode-current-buffer set-modified? nil)))
(list line-change final-pos)))))
(de clip-region (limits region)
% This is a pure function with no side effects. It returns the
% "region" position pair, sorted so that first buffer position is
% the first element, and clipped so that the region returned is
% between the buffer-positions in "limits".
(let ((limit-pair (if (buffer-position-lessp (cadr limits) (car limits))
(reverse limits) limits))
(region-pair (copy
(if (buffer-position-lessp (cadr region) (car region))
(reverse region) region))))
(if (buffer-position-lessp (car region-pair) (car limit-pair))
(setf (car region-pair) (car limit-pair)))
(if (buffer-position-lessp (cadr region-pair) (car limit-pair))
(setf (cadr region-pair) (car limit-pair)))
(if (buffer-position-lessp (cadr limit-pair) (car region-pair))
(setf (car region-pair) (cadr limit-pair)))
(if (buffer-position-lessp (cadr limit-pair) (cadr region-pair))
(setf (cadr region-pair) (cadr limit-pair)))
region-pair))
(de fill-region-command ()
% This function replaces the text between point and the current mark
% with a filled version of the same text. It leaves the
% buffer-position at the end of the new text. It does not return
% anything useful.
(let* ((current-place (buffer-get-position))
(limits (list (current-mark) current-place)))
(setf limits
(if (buffer-position-lessp (car limits) (cadr limits))
limits (reverse limits)))
(buffer-set-position (car limits))
(let ((at-limits nil)(new-region nil)(lines-advance 0))
(while (not at-limits) % paragraph loop
(setf new-region (paragraph-limits))
(setf new-region (clip-region limits new-region))
(setf at-limits (= (car new-region) (cadr new-region)))
(unless at-limits
(setf lines-advance
(first (fill-directed-region % expansion-of-text-information used
(car new-region) (cadr new-region) current-place)))
(setf limits % compensate for expansion of filled text
(list (first limits)
(let ((bottom (second limits)))
(buffer-position-create
(+ lines-advance (buffer-position-line bottom))
(buffer-position-column bottom))))))
(setf limits % guarantee that no text is filled twice
(list (buffer-get-position)(second limits)))))))
(de fill-paragraph-command ()
% This function replaces the next paragraph with filled version. It
% leaves point at the a point bearing the same relation to the
% filled text that the old point did to the old text. It does not
% return a useful value.
(let* ((current-place (buffer-get-position))
(pos-list (paragraph-limits)))
(buffer-set-position (second (fill-directed-region
(first pos-list)
(second pos-list)
current-place)))))
(de fill-comment-command ()
% This function creates a temporary fill prefix from the start of
% the current line. It replaces the surrounding paragraph
% (determined using fill-prefix) with a filled version. It leaves
% point at the a position bearing the same relation to the filled
% text that the old point did to the old text. It does not return a
% useful value.
(let ((current-place (buffer-get-position)))
(move-to-start-of-line)
(let ((place (buffer-get-position))) % get fill prefix ends set up
(skip-forward-blanks-in-line)
(while (not (or (alphanumericp (next-character))
(at-line-end?)
(char-blank? (next-character))))
(move-forward))
(skip-forward-blanks-in-line)
(let* ((fill-prefix (extract-text nil place (buffer-get-position)))
(pos-list (paragraph-limits)))
(if (buffer-position-lessp (first pos-list) current-place)
(buffer-set-position (second (fill-directed-region
(first pos-list)
(second pos-list)
current-place)))
(buffer-set-position current-place))))))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Start of Misc Functions and Associated Support Functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(de center-current-line ()
% This function trims and centers the current line. It does not
% return a useful value. It leaves point at a point in the text
% equivalent to that before centering.
(current-line-strip-indent)
(let ((current-place (buffer-get-position)))
(move-to-end-of-line)
(strip-previous-blanks)
(buffer-set-position current-place))
(let ((needed-blanks (/ (- fill-column (current-display-column)) 2)))
(unless (minusp needed-blanks)
(indent-current-line needed-blanks))))
(de center-line-command ()
% This function centers a number of lines, depending on the
% argument. It leaves point at the end of the last line centered.
% It does not return a useful value.
(center-current-line)
(when (> (abs nmode-command-argument) 1)
(if (minusp nmode-command-argument)
(for (from i 2 (- nmode-command-argument) 1)
(do (move-to-previous-line)
(center-current-line)))
(for (from i 2 nmode-command-argument 1)
(do (move-to-next-line)
(center-current-line))))))
(de what-cursor-position-command ()
% This function tells the user where they are in the buffer or sets
% point to the specified line number. It does not return a useful
% value.
(cond
(nmode-command-number-given
(set-line-pos nmode-command-argument)
)
(t
(write-message
(if (at-buffer-end?)
(bldmsg "X=%w Y=%w line=%w (%w percent of %w lines)"
(current-display-column)
(- (current-line-pos)(current-window-top-line))
(current-line-pos)
(/ (* 100 (current-line-pos))
(current-buffer-visible-size))
(current-buffer-visible-size))
(bldmsg "X=%w Y=%w CH=%w line=%w (%w percent of %w lines)"
(current-display-column)
(- (current-line-pos)(current-window-top-line))
(next-character) % omitted at end of buffer
(current-line-pos)
(/ (* 100 (current-line-pos))
(current-buffer-visible-size))
(current-buffer-visible-size))))
)))