universal-ctags / citre

A superior code reading & auto-completion tool with pluggable backends.
GNU General Public License v3.0
326 stars 26 forks source link

Question: the logic of citre--find-tags-by-tags-file-alist #112

Closed masatake closed 2 years ago

masatake commented 2 years ago
(defun citre--find-tags-by-tags-file-alist (dir project alist)
  "Find the tags file of DIR by ALIST.
ALIST meets the requirements of `citre-tags-file-alist'.  DIR is
an absolute path.  Relative paths in the alist are expanded
against PROJECT, an absolute path."
  (let* ((dir (file-truename dir))
         (expand-file-name-against-project
          (lambda (file)
            (if (file-name-absolute-p file)
                ;; Convert ~/foo to /home/user/foo
                (expand-file-name file)
              (when project
                (expand-file-name file project)))) ))

I wonder why the file, true for (file-name-absolute-p file), is passed to expand-file-name.

The 2nd argument for expand-file-name can be null. So we can define expand-file-name-against-project like:

(defun citre--find-tags-by-tags-file-alist (dir project alist)
  "Find the tags file of DIR by ALIST.
ALIST meets the requirements of `citre-tags-file-alist'.  DIR is
an absolute path.  Relative paths in the alist are expanded
against PROJECT, an absolute path."
  (let* ((dir (file-truename dir))
         (expand-file-name-against-project
          (lambda (file)
            (expand-file-name file project))))
...

However, I'm not sure.

I got this question when I used "~" is used in the dir component of citre-tags-file-alist.

masatake commented 2 years ago

I misunderstood the code; (file-name-ansolute-p "~") returned t. I assumed it returned nil.

AmaiKinono commented 2 years ago

Interesting question ;)

See docs/developer-manual/contribution-guide.md:

absolute/full/canonical path: Full path is like absolute path, but things like ~, ~USER is expanded. Canonical path further resolves the symbolic links, so there's only one unique canonical path for one file.

I don't know if "canonical path" is a canonical name, but it appears in the docstring of expand-file-name:

(expand-file-name NAME &optional DEFAULT-DIRECTORY)

Convert filename NAME to absolute, and canonicalize it.

I'd really like a function similar to expand-file-name in readtags, so we can solve the "resolve relative file name" problem in https://github.com/universal-ctags/ctags/issues/3168: we can expand the file name in the client tool, then comparing it with (expand-file-name $input).

It seems Emacs implements expand-file-name from scratch. realpath is a POSIX standard function that claims to do the same thing: "return the canonicalized absolute pathname", but it doesn't have an argument like default-directory.