universal-ctags / citre

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

[Question] is citre-tags-file-alist gone? #180

Open masatake opened 1 month ago

masatake commented 1 month ago

Today, I did cd citre; git update. Then, citre didn't work. I found that citre-tags-file-alist is gone. I have added more than 100 elements on the list...

After some studying the latest citre, It seems that I should put a tag file for the source tree ~/.cache/tags with specially encoded file name like !home!yamato!var!cpython!.tags. Am I correct?

I will learn the way to run ctire ctags for generating and managing tag files as a ctags user. However, I, as a ctags developer, would like to establish the workflow generating a tag file by running ctags directly.

The source tree I want to inspect is on a read-only file system.

AmaiKinono commented 1 month ago

See the documentation. We've switched from citre-tags-file-alist to a directory-local variable citre-tags-file as it's the built-in way to set things based on directory.

If you can't put .dir-locals.el in a directory, according to https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html, you can use dir-locals-set-class-variables to set it in your config. But I think the best way for you may be adding a custom function in find-file-hook and setting citre-tags-file in it according to the directory. You can reuse citre-tags-file-alist this way.

masatake commented 1 month ago

Thank you. I should read the document before opening this issue. I'm using ctags and readtags commands directly. Therefore, I like ~/.cache/tags/ scheme.

What citre does in citre--encode-path-to-filename and citre--decode-filename-to-path is a protocol between citre and external tools.

I want to have a shell command just doing encoding:

$ citre-encode /home/yamato/var/linux
!home!yamato!var!linux!.tags

So I can do ctags -R -o ~/.cache/tags/$(citre-encode ~/src) ~/src.

$ citre encode /home/yamato/var/linux
!home!yamato!var!linux!.tags

is more joyful.

Just for "encode", we can reimplement the encode function in any language. Using emacsclient is another choice. But if we assume users are using GNU/Linux, d-bus is yet another choice.

masatake commented 1 month ago

After thinking again, ~/.cache/tags/ is not only about citre but all tools related to tags files. We can assume it is a protocol between tags(5) generators and client tools.

I want to add -O option to ctags and -T option for readtags.

If -O dir is given to ctags, the option is translated to -o ~/.cache/tags/...~.tags. If -T dir is given to readtags, the option is translated to -t ~/.cache/tags/...~.tags.

AmaiKinono commented 1 month ago

Ah, this idea is quite similar to what GNU Global has implemented. In gtags (which generates the database) manpage:

-O, --objdir
       Use BSD-style obj directory as the location of tag files.
       If GTAGSOBJDIRPREFIX is set and $GTAGSOBJDIRPREFIX directory exists,
       gtags creates $GTAGSOBJDIRPREFIX/<current directory> directory
       and makes tag files in it.
       Though you can use MAKEOBJDIRPREFIX instead of GTAGSOBJDIRPREFIX,
       it is deprecated.
       If dbpath is specified, this option is ignored.

In global (which reads the database) manpage:

GTAGSOBJDIRPREFIX, MAKEOBJDIRPREFIX
        If eigher of the two variable is set, it is used as the prefix of BSD-style objdir.
        The former is given priority. The default is ´/usr/obj´.

The convert style is different from Citre. Database of /path/to/project will be put in $GTAGSOBJDIRPREFIX/path/to/project. I remember this causes problem on Windows, maybe because the colon sign in file path is invalid.

masatake commented 1 month ago

I'm enjoying utilizing the default directory feature:

$ (cd ~/.cache/tags; du -h -c)
511G    .
511G    total

For making tag files in batch mode, I'm using shell functions in a script running ctags:

encode0()
{
    local d=$1
    echo $(tr / '!' <<<"$d")'!'
}

encode_tag_file()
{
    local d=$1
    echo "${root_tag_file}"/$(encode0 "$d").tags
}

@AmaiKinono, I got a question about encoding:

citre--encode-path-to-filename encodes /home/yamato/var/linux to !home!yamato!var!linux!.tags. Why did you think the last '!' was needed?

I think !home!yamato!var!linux.tags is enough. Any hidden requirements for the last !?

AmaiKinono commented 1 month ago

It's actually not a requirement, but caused by accident.

citre--encode-path-to-filename just replaces the slashes:

(citre--encode-path-to-filename "/home/yamato/var/linux")
;; => "!home!yamato!var!linux"
citre--encode-path-to-filename "/home/yamato/var/linux/")
;; => "!home!yamato!var!linux!"

I've checked the call sites. In the code, the directory is given by citre-current-dir and read-direcrory-name, which both return a path ends with /, so there's a trailing !.

This seems to be a fragile behavior. I do think we should have a more clear specification about the encoded file name.