> How does Masatake's completion mechanism work?

I cannot explain well. It means Matthieu's one is much better than
mine:) I read his code and it is obvious that his code is much
better than mine.

However, mine has some advantages(I know Matthieu wrote his code
was not completed):

1. Separation "--" and "/" handling
   His completion engine didn't take care about it.
   
2. Tree building control
   His completion engine always used cached data in the 
   archive-tree. In my code, typing "return" means
   rebuilding cache.

3. Subtree completion
   In his completion engine, the user always had to input
    from archive. Even xtla requires just revision name.
   
I've solved 1 and 2.
You can force rebuild archive-tree by C-u tab.

To avoid confusion, I have not commit my modification to my tree.
Matthieu, if you approve my change on your code, could you reflect
my change on your tree? I'd like to try 3. after getting approval
from you about 1. and 2.

;; Other draft proposal for a reading engine.

;;Currently only able to read a full revision starting from nothing.

(defun tla--completion (string predicate what)
  (let* ((target target)
         ;; Whether using the current tree or not.
         ;; Tab key with C-u forces rebuilding tree.
         ;; --- Masatake
         (use-cache (not current-prefix-arg))
         (splited (tla--name-split string))
         ;; Ignore an empty string when calculating current-level.
         (current-level (+ (length (delete nil (substitute nil "" splited :test 
'equal)))
                           ;; If a separator "--" or "/" is given, increment
                           ;; current-level. --- Masatake
                           (if (tla--name-final-separator string)
                               1 0)))
         (archive  (tla-archive-name  splited))
         (category (tla-category-name splited))
         (branch   (tla-branch-name   splited))
         (version  (tla-version-name  splited))
         (revision (tla-revision-name splited))
         (completions
          (progn
            (unless use-cache (message "Building cache..."))
          (case current-level
            (5 (tla--archive-tree-build-revisions archive
                                                  category
                                                  branch version
                                                  use-cache)
               (cdr (tla--archive-tree-get-version archive category
                                                   branch version)))
            (4 (tla--archive-tree-build-versions archive category
                                                 branch
                                                 use-cache)
               (cdr (tla--archive-tree-get-branch archive category
                                                  branch)))
            (3 (tla--archive-tree-build-branches archive
                                                 category
                                                 use-cache)
               (cdr (tla--archive-tree-get-category archive category)))
            (2 (tla--archive-tree-build-categories archive
                                                   use-cache)
               (cddr (tla--archive-tree-get-archive archive)))
            (1 (tla--archive-tree-build-archives
                use-cache)
               tla--archive-tree)
            ;; If no string is given, force build archive lists.
            ;; --- Masatake
            (0 (tla--archive-tree-build-archives nil)
               tla--archive-tree)))
          ))
    (unless use-cache
      (message "Building cache...done")
      (sit-for 1)
      (message nil))
    (funcall (if (eq what t) 'all-completions 'try-completion)
             string
             (mapcar (lambda (x)
                       (list (tla--name-construct
                              (delete nil (list (when category archive)
                                                (when branch category)
                                                (when version branch)
                                                (when revision version)
                                                (concat
                                                 (car x)
                                                 ;;
                                                 ;; Append a separator for the 
completions.
                                                 ;;
                                                 (if (member current-level
                                                             (if (eq target 
'archive)
                                                                 '()
                                                               '(0 1)))
                                                     "/"
                                                   (if (member current-level
                                                               (case target
                                                                 (category '())
                                                                 (branch '(2))
                                                                 (version '(2 
3))
                                                                 (revision '(2 
3 4))))
                                                       "--"
                                                     "")))
                                                )))))
                     completions)
             predicate)))


(defvar tla--read-archive-category-branch-version-revision-history
  nil)
(defun tla--complete (target history-var &optional prompt )
  (let ((target target)
        (result (completing-read
                 (if prompt prompt (concat (symbol-name target) ": "))
                  'tla--completion
                  nil nil nil
                  history-var)))
    (when (not (string= result ""))
      result)))
(defun tla--complete-revision (&optional prompt)
  (tla--complete 'revision
                 'tla--read-archive-category-branch-version-revision-history
                 prompt))

(defun tla--name-final-separator (name)
  "Check whether NAME is ended with tla's separator \"--\" or \"/\".
If NAME is ended with a separator, return the separator.
Else return nil."
  (if (or (null name) (equal "" name))
      ""
    (when (stringp name)
      (cond
       ((string-match ".*/.*--$" name) "--")
       ((string-match "/$" name) "/")
       (t nil)))))

Reply via email to