Function: ispell-process-line
ispell-process-line is a byte-compiled function defined in
ispell.el.gz.
Signature
(ispell-process-line STRING SHIFT)
Documentation
Send STRING, a line of text, to ispell and process the result.
This will modify the buffer for spelling errors. Requires variables ISPELL-START and ISPELL-END to be defined in its dynamic scope. Returns the sum SHIFT due to changes in word replacements.
Source Code
;; Defined in /usr/src/emacs/lisp/textmodes/ispell.el.gz
(defun ispell-process-line (string shift)
"Send STRING, a line of text, to ispell and process the result.
This will modify the buffer for spelling errors.
Requires variables ISPELL-START and ISPELL-END to be defined in its
dynamic scope.
Returns the sum SHIFT due to changes in word replacements."
;;(declare special ispell-start ispell-end)
(let (poss accept-list)
(if (not (numberp shift))
(setq shift 0))
;; send string to spell process and get input.
(ispell-send-string string)
(while (progn
(ispell-accept-output)
;; Last item of output contains a blank line.
(not (string= "" (car ispell-filter)))))
;; parse all inputs from the stream one word at a time.
;; Place in FIFO order and remove the blank item.
(setq ispell-filter (nreverse (cdr ispell-filter)))
(while (and (not ispell-quit) ispell-filter)
;; get next word, accounting for accepted words and start shifts
(setq poss (ispell-parse-output (car ispell-filter)
accept-list shift))
(if (and poss (listp poss)) ; spelling error occurred.
;; Whenever we have misspellings, we can change
;; the buffer. Keep boundaries as markers.
;; Markers can move with highlighting! This destroys
;; end of region markers line-end and ispell-region-end
(let ((word-start
;; There is a -1 offset here as the string is escaped
;; with '^' to prevent us accidentally sending any
;; ispell commands.
(copy-marker (+ ispell-start -1 (car (cdr poss)))))
(word-len (length (car poss)))
(line-end (copy-marker ispell-end))
(line-start (copy-marker ispell-start))
recheck-region replace)
(goto-char word-start)
;; Adjust the horizontal scroll & point
(ispell-horiz-scroll)
(goto-char (+ word-len word-start))
(ispell-horiz-scroll)
(goto-char word-start)
(ispell-horiz-scroll)
;; Alignment cannot be tracked and this error will occur when
;; `query-replace' makes multiple corrections on the starting line.
(or (ispell-looking-at (car poss))
;; This error occurs due to filter pipe problems
(let* ((ispell-pipe-word (car poss))
(actual-point (marker-position word-start))
(actual-line (line-number-at-pos actual-point))
(actual-column (save-excursion (goto-char actual-point)
(current-column))))
(ispell-print-if-debug
"ispell-process-line: Ispell misalignment error:
[Word from ispell pipe]: [%s], actual (point,line,column): (%s,%s,%s)\n"
ispell-pipe-word actual-point actual-line actual-column)
(error (concat "Ispell misalignment: word "
"`%s' point %d; probably incompatible versions")
ispell-pipe-word actual-point)))
;; ispell-cmd-loop can go recursive & change buffer
(if ispell-keep-choices-win
(setq replace (ispell-command-loop
(car (cdr (cdr poss)))
(car (cdr (cdr (cdr poss))))
(car poss) (marker-position word-start)
(+ word-len (marker-position word-start))))
(save-window-excursion
(setq replace (ispell-command-loop
(car (cdr (cdr poss)))
(car (cdr (cdr (cdr poss))))
(car poss) (marker-position word-start)
(+ word-len (marker-position word-start))))))
(goto-char word-start)
;; Recheck when query replace edit changes misspelled word.
;; Error in tex mode when a potential math mode change exists.
(if (and replace (listp replace) (= 2 (length replace)))
(if (and (eq ispell-parser 'tex)
(string-match "[\\][]()[]\\|\\\\begin\\|\\$"
(regexp-quote string)))
(error
"Don't start query replace on a line with math characters"
)
(set-marker line-end (point))
(setq ispell-filter nil
recheck-region t)))
;; Insert correction if needed.
(cond
((or (null replace)
(equal 0 replace)) ; ACCEPT/INSERT
(if (equal 0 replace) ; BUFFER-LOCAL DICT ADD
(ispell-add-per-file-word-list (car poss)))
;; Do not recheck accepted word on this line.
(setq accept-list (cons (car poss) accept-list)))
(t ; Replacement word selected or entered.
(delete-region (point) (+ word-len (point)))
(if (not (listp replace))
(progn
(insert replace) ; Insert dictionary word.
(ispell-send-replacement (car poss) replace)
(setq accept-list (cons replace accept-list)))
(let ((replace-word (car replace)))
;; Recheck hand entered replacement word.
(insert replace-word)
(ispell-send-replacement (car poss) replace-word)
(if (car (cdr replace))
(save-window-excursion
(delete-other-windows) ; to correctly show help.
;; Assume case-replace &
;; case-fold-search correct?
(query-replace (car poss) (car replace) t)))
(goto-char word-start)
;; Do not recheck if already accepted.
(if (member replace-word accept-list)
(setq accept-list (cons replace-word accept-list)
replace replace-word)
(let ((region-end (copy-marker ispell-region-end)))
(setq recheck-region ispell-filter
ispell-filter nil ; Save filter.
shift 0 ; Already accounted.
shift (ispell-region
word-start
(+ word-start (length replace-word))
t shift))
(if (null shift) ; Quitting check.
(setq shift 0))
(set-marker ispell-region-end region-end)
(set-marker region-end nil)
(setq ispell-filter recheck-region
recheck-region nil
replace replace-word)))))
(setq shift (+ shift (- (length replace) word-len)))))
(if (not ispell-quit)
(let (message-log-max)
(message
"Continuing spelling check using %s with %s dictionary..."
(file-name-nondirectory ispell-program-name)
(or ispell-current-dictionary "default"))))
(sit-for 0)
(setq ispell-start (marker-position line-start)
ispell-end (marker-position line-end))
;; Adjust markers when end of region lost from highlighting.
(if (and (not recheck-region)
(< ispell-end (+ word-start word-len)))
(setq ispell-end (+ word-start word-len)))
(if (= word-start ispell-region-end)
(set-marker ispell-region-end (+ word-start word-len)))
;; Going out of scope - unneeded.
(set-marker line-start nil)
(set-marker word-start nil)
(set-marker line-end nil)))
;; Finished with misspelling!
(setq ispell-filter (cdr ispell-filter)))
shift))