> 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)))))