Function: thai-forward-word-update-info
thai-forward-word-update-info is a byte-compiled function defined in
thai-word.el.gz.
Signature
(thai-forward-word-update-info VEC LIMIT)
Source Code
;; Defined in /usr/src/emacs/lisp/language/thai-word.el.gz
;; Move point forward to the end of Thai word which follows point and
;; update VEC. VEC is a vector of three elements used to cache word
;; end positions. The Nth element, if non-nil, is a list of end
;; points of the Nth word, or t indicating that there is no Thai
;; character. LIMIT limits the point movement.
(defun thai-forward-word-update-info (vec limit)
(let ((pos (point))
v0 v1 v2 v3
second-best
tried
positions)
(if
;; If four succeeding Thai words are found, throw t, otherwise
;; throw nil.
(catch 'tag
;; Start with first vector element.
(setq v0 (aref vec 0))
(unless v0
;; Update VEC if V0 is empty.
(setq v0 (thai-find-word-ends pos limit))
(aset vec 0 v0)
(aset vec 1 nil))
;; In case we haven't found any wordbreaks resp. point has
;; reached LIMIT, exit the catch body.
(if (symbolp v0) ; i.e. nil or t?
(throw 'tag nil))
;; OK, V0 holds possible word ends for the current position.
;; We save V0 for later reference.
(setq tried v0)
(setq v1 (aref vec 1))
;; Now we try all end word positions to find the next word.
(while v0
(setq pos (car v0))
(unless v1
;; Update VEC if V1 is empty, ignoring positions already
;; found -- for Thai, we need the longest match, so if
;; we have
;;
;; start(long-word) = start(short-word1)
;; end(short-word1) = start(short-word2)
;; end(short-word2) = end(long-word)
;;
;; only long-word is used.
(setq v1 (thai-find-word-ends pos limit tried))
(aset vec 1 v1)
(aset vec 2 nil))
;; If point has reached LIMIT, exit the catch body.
(if (eq v1 t)
(throw 'tag t))
;; Save SECOND-BEST, if this hasn't been done already.
;; The `second best' solution is the end position of the
;; longest first word followed by the longest second word.
(or second-best
(not v1)
(setq second-best (cons v0 v1)))
;; Update the already tried end word positions.
(setq tried (append tried v1))
;; Now repeat the whole process to find a third word.
(when v1
(setq v2 (aref vec 2))
(while v1
(setq pos (car v1))
(unless v2
(setq v2 (thai-find-word-ends pos limit tried))
(aset vec 2 v2))
(if (eq v2 t)
(throw 'tag t))
(setq tried (append tried v2))
;; And the same for a fourth word.
(while v2
(setq pos (car v2))
(setq v3 (thai-find-word-ends pos limit tried))
(if v3
(throw 'tag t))
(setq v2 (cdr v2)))
(setq v1 (cdr v1))))
(setq v0 (cdr v0)))
;; No success.
nil)
(progn
;; We found four succeeding Thai words (or LIMIT has been
;; reached). Move to the end of the first word.
(goto-char (car v0))
;; Update VEC for the next function call. If no larger word
;; positions have been found, set the corresponding vector
;; element to nil.
(if (and (consp v1) (< (car v1) (car (aref vec 1))))
(aset vec 0 nil)
(aset vec 0 v1)
(if (and (consp v2) (< (car v2) (car (aref vec 2))))
(aset vec 1 nil)
(aset vec 1 v2)
(aset vec 2 v3)))) ; exit function successfully
;; We didn't find four consecutive words. If we have found a
;; `second best' solution and the length of those two words is
;; longer than the longest word we can see at the current point,
;; adopt the second best solution. This decision is based on
;; heuristic tests.
(if (and second-best
(< (car (aref vec 0)) (car (cdr second-best))))
(progn
(goto-char (car (car second-best)))
(aset vec 0 (cdr second-best)))
;; We finally failed to find a word break. For Thai, the best
;; solution is to extend the first longest word so that the
;; end point starts a second word.
(setq pos (or (car (aref vec 0)) pos))
(while (and (< pos limit)
(not (setq positions (thai-find-word-ends pos limit))))
(setq pos (1+ pos)))
(goto-char pos)
(aset vec 0 positions))
(aset vec 1 nil)
nil)))