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 a cons cell where the car is sum SHIFT due to changes in word replacements, and the cdr is the location of the final word that was queried about.

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 a cons cell where the `car' is sum SHIFT due to changes
in word replacements, and the `cdr' is the location of the final
word that was queried about."
  ;;(declare special ispell-start ispell-end)
  (let (poss accept-list max-word)
    (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)))
            (setq max-word (marker-position word-start))
            ;; 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)))
    (cons shift max-word)))