syohex / emacs-counsel-gtags

GNU Global with ivy completion
62 stars 20 forks source link

Does not work for remote files #22

Closed jeberger closed 4 years ago

jeberger commented 7 years ago

Counsel-gtags does not work for remote files opened through tramp. This is because counsel-gtags uses process-lines, which itself relies on call-process, which only works for local files.

Creating a copy of process-lines that uses process-file-shell-command instead of call-process works.

jeberger commented 7 years ago

I was a little pressed for time when I wrote the above report, so here are some more details:

jeberger commented 7 years ago

Since abo-abo/swiper#1233 landed, it works fine with the modified process-lines function below:

(defun counsel-gtags--process-lines (program &rest args)
  "Execute PROGRAM with ARGS, returning its output as a list of lines.
Signal an error if the program returns with a non-zero exit status."
  (with-temp-buffer
    (let ((status (apply 'process-file-shell-command program nil (current-buffer) nil args)))
      (unless (eq status 0)
        (error "%s exited with status %s" program status))
      (goto-char (point-min))
      (let (lines)
        (while (not (eobp))
          (setq lines (cons (buffer-substring-no-properties
                             (line-beginning-position)
                             (line-end-position))
                            lines))
          (forward-line 1))
        (nreverse lines)))))

(defun counsel-gtags--collect-candidates (type tagname encoding extra-options)
  (let ((options (counsel-gtags--command-options type extra-options))
        (default-directory default-directory)
        (coding-system-for-read encoding)
        (coding-system-for-write encoding))
    (apply #'counsel-gtags--process-lines "global" (append (reverse options) (list tagname)))))
daladd commented 7 years ago

Thanks! I was just starting to set up counsel-gtags over tramp this morning!

jeberger commented 7 years ago

@daladd In that case you might also be interested by these:

  (defun jmb/counsel-gtags-find-definition (tagname)
    "Search for TAGNAME definition in tag database.
Prompt for TAGNAME if not given."
    (interactive
     (list (read-string "Find definition for: " (thing-at-point 'symbol))))
    (counsel-gtags--select-file 'definition tagname))

  (defun jmb/counsel-gtags-find-reference (tagname)
    "Search for TAGNAME reference in tag database.
Prompt for TAGNAME if not given."
    (interactive
     (list (read-string "Find reference to: " (thing-at-point 'symbol))))
    (counsel-gtags--select-file 'reference tagname))

  (defun jmb/counsel-gtags-find-symbol (tagname)
    "Search for TAGNAME symbol in tag database.
Prompt for TAGNAME if not given."
    (interactive
     (list (read-string "Find use of: " (thing-at-point 'symbol))))
    (counsel-gtags--select-file 'symbol tagname))

By default, counsel-gtags attempts to load the full list of symbols so that it can complete the symbol you want to look for. When you have a large code base, and even more over Tramp, this can be very slow. The above functions disable completion for the symbol to look up, making it much faster.

jeberger commented 6 years ago

Additionally, the context stack doesn't work for remote files because counsel-gtags--real-file-name returns a path from which remote information has been stripped: for /pscp:user@host:/foo, it only returns /foo, and that is the path pushed on the context stack.

Using (file-truename (buffer-file-name)) instead of (counsel-gtags--real-file-name) in counsel-gtags-push fixes the issue:

(defun counsel-gtags--push (direction)
  "Add new entry to context stack."
  (let ((new-context (list :file (and (buffer-file-name)
                                      (file-truename (buffer-file-name)))
                                      ; (counsel-gtags--real-file-name))
                           :buffer (current-buffer)
                           :line (line-number-at-pos)
                           :direction direction)))
    (setq counsel-gtags--context
          (nthcdr counsel-gtags--context-position counsel-gtags--context))
    ;; We do not want successive entries with from-direction,
    ;; so we remove the old one.
    (let ((prev-context (car counsel-gtags--context)))
      (if (and (eq direction 'from)
               (eq (plist-get prev-context :direction) 'from))
          (pop counsel-gtags--context)))
    (push new-context counsel-gtags--context)
    (setq counsel-gtags--context-position 0)))
syohex commented 4 years ago

This package is no longer maintained. If you have an issue, please send it to https://github.com/FelipeLema/emacs-counsel-gtags