Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request: filename related functions in readtags expressions #3168

Open
AmaiKinono opened this issue Sep 27, 2021 · 6 comments
Open

Request: filename related functions in readtags expressions #3168

AmaiKinono opened this issue Sep 27, 2021 · 6 comments
Milestone

Comments

@AmaiKinono
Copy link
Member

AmaiKinono commented Sep 27, 2021

Currently I don't know what exactly is needed, but there are 2 motivations behind this request, I hope they can guide us.

resolve relative file name

When finding definitions, the user may want to exclude file-local symbols that's not in current file. The predicate "not in current file" is actually not a simple one. Here's a one generated by Citre (if you are interested, it's in here)

(or (and $input (eq? $input "/path/to/test.el"))
    (and $input (eq? $input "test.el"))
    (and $input ((string->regexp "(^|/)..?/test\\.el$"
                                 :case-fold false)
                 $input)))

Suppose the current file is /path/to/test.el, and TAG_PROC_CWD is /path/to/, then the input field of this file should either be test.el (when its relative) or /path/to/test.el (when its absolute). So where does the regexp matching against (^|/)..?/test\\.el$ comes from?

This is because a user reported that if you tag the current dir by:

$ ctags -R ./

You get tags like this:

citre-put-property      ./citre-common.el

I soon realized that the input field can look like anything, e.g., you can feed a path like ../../path/to/ to the ctags command, and it could mean the same as /path/to.

At the end, what I did is: when there's a /./ or /../ in the input field, and it ends with test.el, we think it is the file /path/to/test.el. This is not correct, but is the best I can do for now.

Since there are infinite possibilities, direct matching against the input field simply can't solve the problem. We must somehow transform $input to a standard representation, then match against it.

Sort by nearness

This is a very nice feature I found in GNU Global. I'll paste its documentation here:

-N, --nearness[=start]
       Use Nearness sort method (sorting by closest from start) for the output.
       By default, alphabetical sort method is used.
       This option is effective for the tag search command, -P command
       and -g command. As an exception, -g command ignores this
       option when files are specified by arguments.
       The nearness is defined by how many parent directories to go up to reach
       the target. The result of nearness sort is concatenation of the following
       ([0]-[n]) in this order. The default of start is the current directory.
       
       [0] If the start is a file, output of local search in the file.
       [1] Output of local search in the start directory except for [0].
       [2] Output of local search in the parent directory except for [0]-[1].
       [3] Output of local search in the grandparent directory except for [0]-[2].
       ... (repeat until the project root directory)
       [n] Output of local search in the project root directory except for [0]-[n-1].
       
       In each directory, they are sorted by alphabetical order.

Simply puts it, file that are "near" to the current file is put above those "far" from the current file. This is handy when finding references, but I think readtags could also benefit from this, since:

  1. uctags supports some reference tags, like references to C macros.
  2. Normally we structure our project so that closely related code are put in the same file, code that are not very closely related are put in the same directory, then the same module, then different modules... So when there are multiple definitions found for a symbol, the "nearer" it is to the current file, the more possible its the definition we want.
@masatake
Copy link
Member

@masatake
Copy link
Member

masatake commented Feb 4, 2022

I assume "resolve relative file name" can be solved easily.
I will work on after working on OpenAPI parser.
Sorry to be late to respond.
I have been thinking about "Sort by nearness". This one looks hard.

@AmaiKinono
Copy link
Member Author

I have been thinking about "Sort by nearness". This one looks hard.

Maybe it's not that hard ;) Here's a prototype in Elisp:

(defun common-prefix-length (str1 str2)
  (pcase (compare-strings str1 nil nil
                          str2 nil nil)
    ('t (length str1))
    ((and result (guard (< result 0))) (- -1 result))
    ((and result (guard (> result 0))) (- result 1))))

(defun file-nearness (start to)
  (let* ((start (expand-file-name start))
         (to (expand-file-name to))
         (common-prefix-length (common-prefix-length start to))
         (rest-part (substring start common-prefix-length))
         (separators 0))
    (if (= common-prefix-length (length start) (length to))
        0
      (dotimes (i (length rest-part))
        (when (memq (aref rest-part i) '(?/ ?\\))
          (setq separators (1+ separators))))
      (1+ separators))))

(file-nearness "~/path/to/abc.c" "~/path/to/abc.c")
;; => 0
(file-nearness "~/path/to/abc.c" "~/path/to/a.h")
;; => 1
(file-nearness "~/path/to/abc.c" "~/path/to/foo/abc.c")
;; => 1
(file-nearness "~/path/to/abc.c" "~/path/too/abc.c")
;; => 2
(file-nearness "~/path/to/abc.c" "~/foo")
;; => 3

@masatake
Copy link
Member

masatake commented Feb 4, 2022

I misunderstood the issue; it seems that we have to add an operator.

masatake added a commit to masatake/ctags that referenced this issue Mar 10, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,
* update the readtags.1 man page,
* consider Windows, and
* add test cases.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
@masatake
Copy link
Member

I implemented -c option for resolve relative file name.

masatake added a commit to masatake/ctags that referenced this issue Sep 17, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,
* update the readtags.1 man page,
* consider Windows, and
* add test cases.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Sep 18, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,
* update the readtags.1 man page,
* consider Windows, and
* add test cases.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Sep 18, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,
* update the readtags.1 man page,
* consider Windows, and
* add test cases.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Sep 18, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,
* update the readtags.1 man page,
* consider Windows, and
* add test cases.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Sep 25, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,
* update the readtags.1 man page,
* consider Windows, and
* add test cases.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Oct 9, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,
* update the readtags.1 man page,
* consider Windows, and
* add test cases.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Oct 10, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Oct 10, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Oct 14, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Oct 15, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Oct 24, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Oct 24, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
@masatake masatake added this to the 6.1 milestone Dec 17, 2022
masatake added a commit to masatake/ctags that referenced this issue Dec 31, 2022
Partially close universal-ctags#3168.

TODO:
* revise code,

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Apr 29, 2023
Partially close universal-ctags#3168.

TODO:
* revise code,

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Apr 29, 2023
Partially close universal-ctags#3168.

TODO:
* revise code,

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
masatake added a commit to masatake/ctags that referenced this issue Apr 29, 2023
Partially close universal-ctags#3168.

TODO:
* revise code,

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
@masatake masatake reopened this May 8, 2023
@masatake masatake modified the milestones: 6.1, 6.2 May 8, 2023
@masatake
Copy link
Member

masatake commented May 8, 2023

"Sort by nearness" is not solved yet.

@masatake masatake modified the milestones: 6.2, 6.3 Feb 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants