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

eglot with ido and imenu #535

Closed
aramirez opened this issue Sep 8, 2020 · 6 comments
Closed

eglot with ido and imenu #535

aramirez opened this issue Sep 8, 2020 · 6 comments

Comments

@aramirez
Copy link

aramirez commented Sep 8, 2020

I am using the function ido-imenu

(defun ido-imenu ()
"Update the imenu index and then use ido to select a symbol to navigate to.
Symbols matching the text at point are put first in the completion list."
(interactive)
(imenu--make-index-alist)
(let ((name-and-pos '())
(symbol-names '()))
(flet ((addsymbols (symbol-list)
(when (listp symbol-list)
(dolist (symbol symbol-list)
(let ((name nil) (position nil))
(cond
((and (listp symbol) (imenu--subalist-p symbol))
(addsymbols symbol))

                          ((listp symbol)
                           (setq name (car symbol))
                           (setq position (cdr symbol)))

                          ((stringp symbol)
                           (setq name symbol)
                           (setq position (get-text-property 1 'org-imenu-marker symbol))))

                         (unless (or (null position) (null name))
                           (add-to-list 'symbol-names name)
                           (add-to-list 'name-and-pos (cons name position))))))))
  (addsymbols imenu--index-alist))
;; If there are matching symbols at point, put them at the beginning of `symbol-names'.
(let ((symbol-at-point (thing-at-point 'symbol)))
  (when symbol-at-point
    (let* ((regexp (concat (regexp-quote symbol-at-point) "$"))
           (matching-symbols (delq nil (mapcar (lambda (symbol)
                                                 (if (string-match regexp symbol) symbol))
                                               symbol-names))))
      (when matching-symbols
        (sort matching-symbols (lambda (a b) (> (length a) (length b))))
        (mapc (lambda (symbol) (setq symbol-names (cons symbol (delete symbol symbol-names))))
              matching-symbols)))))
(let* ((selected-symbol (ido-completing-read "Symbol? " symbol-names))
       (position (cdr (assoc selected-symbol name-and-pos))))
  (goto-char position))))

On this source code:
--8<---------------cut here---------------start------------->8---
#include <stdio.h>

void main() {
int var;
var = 10;
double dvar;
dvar = 0;
dvar = dvar + var;
}

void functx() {

}
--8<---------------cut here---------------end--------------->8---

In GNU Emacs 27.1 (build 1, armv7l-unknown-linux-gnueabihf, X toolkit, Xaw3d scroll bars)
System Description: Arch Linux ARM

This is my eglot version:
--8<---------------cut here---------------start------------->8---
eglot-20200830.1254
--8<---------------cut here---------------end--------------->8---

And I am getting this error:
--8<---------------cut here---------------start------------->8---
Debugger entered--Lisp error: (wrong-type-argument integer-or-marker-p ([(:kind 12 :name functx :range (:end (:character 0 :line 12) :start (:character 0 :line 10)) :selectionRange (:end (:character 11 :line 10) :start (:character 5 :line 10)))] #f(compiled-function (name one-obj-array) #<bytecode -0x1ffffffff9beac48>)))
goto-char(([(:kind 12 :name functx :range (:end (:character 0 :line 12) :start (:character 0 :line 10)) :selectionRange (:end (:character 11 :line 10) :start (:character 5 :line 10)))] #f(compiled-function (name one-obj-array) #<bytecode -0x1ffffffff9beac48>)))
(let* ((selected-symbol (ido-completing-read Symbol? symbol-names)) (position (cdr (assoc selected-symbol name-and-pos)))) (goto-char position))
(let ((name-and-pos 'nil) (symbol-names 'nil)) (flet ((addsymbols (symbol-list) (when (listp symbol-list) (dolist (symbol symbol-list) (let (... ...) (cond ... ... ...) (unless ... ... ...)))))) (addsymbols imenu--index-alist)) (let ((symbol-at-point (thing-at-point 'symbol))) (if symbol-at-point (progn (let* ((regexp (concat ... )) (matching-symbols (delq nil ...))) (if matching-symbols (progn (sort matching-symbols ...) (mapc ... matching-symbols))))))) (let* ((selected-symbol (ido-completing-read Symbol? symbol-names)) (position (cdr (assoc selected-symbol name-and-pos)))) (goto-char position)))
emacswiki/ido-imenu()
funcall-interactively(emacswiki/ido-imenu)
call-interactively(emacswiki/ido-imenu nil nil)
command-execute(emacswiki/ido-imenu)
--8<---------------cut here---------------end--------------->8---

Best Regards

@aramirez
Copy link
Author

aramirez commented Sep 8, 2020

I am testing with:
emacs -Q -l /tmp/emacsq-test-eglot.el

this is the contenf of file emacsq-test-eglot.el:
(defun emacswiki/ido-imenu ()
"Update the imenu index and then use ido to select a symbol to navigate to.
Symbols matching the text at point are put first in the completion list."
(interactive)
(imenu--make-index-alist)
(let ((name-and-pos '())
(symbol-names '()))
(flet ((addsymbols (symbol-list)
(when (listp symbol-list)
(dolist (symbol symbol-list)
(let ((name nil) (position nil))
(cond
((and (listp symbol) (imenu--subalist-p symbol))
(addsymbols symbol))

                          ((listp symbol)
                           (setq name (car symbol))
                           (setq position (cdr symbol)))

                          ((stringp symbol)
                           (setq name symbol)
                           (setq position (get-text-property 1 'org-imenu-marker symbol))))

                         (unless (or (null position) (null name))
                           (add-to-list 'symbol-names name)
                           (add-to-list 'name-and-pos (cons name position))))))))
  (addsymbols imenu--index-alist))
;; If there are matching symbols at point, put them at the beginning of `symbol-names'.
(let ((symbol-at-point (thing-at-point 'symbol)))
  (when symbol-at-point
    (let* ((regexp (concat (regexp-quote symbol-at-point) "$"))
           (matching-symbols (delq nil (mapcar (lambda (symbol)
                                                 (if (string-match regexp symbol) symbol))
                                               symbol-names))))
      (when matching-symbols
        (sort matching-symbols (lambda (a b) (> (length a) (length b))))
        (mapc (lambda (symbol) (setq symbol-names (cons symbol (delete symbol symbol-names))))
              matching-symbols)))))
(let* ((selected-symbol (ido-completing-read "Symbol? " symbol-names))
       (position (cdr (assoc selected-symbol name-and-pos))))
  (goto-char position))))

(defun s-load-now/eglot ()
"eglot "
(interactive)
(when (and (file-exists-p "/.emacs.d/elpa/flymake") (file-exists-p "/.emacs.d/elpa/project")(file-exists-p "/.emacs.d/elpa/xref")(file-exists-p "/.emacs.d/elpa/eldoc")(file-exists-p "/.emacs.d/elpa/eglot"))
(add-to-list 'load-path "
/.emacs.d/elpa/flymake")
(add-to-list 'load-path "/.emacs.d/elpa/project")
(add-to-list 'load-path "
/.emacs.d/elpa/xref")
(add-to-list 'load-path "/.emacs.d/elpa/eldoc")
(add-to-list 'load-path "
/.emacs.d/elpa/eglot")
(require (quote eglot))
(add-to-list 'eglot-server-programs '((c-mode) "clangd"))
)
)

(require 'cl)
(s-load-now/eglot)
(find-file "/tmp/test_eglot.c")
(global-set-key (kbd "C-x i") 'emacswiki/ido-imenu)
; it works fine if first i run emacswiki/ido-imenu ; and after it M-x eglot;
; problem happens when I do M-x eglot first; and then M-x emacswiki/ido-imenu

@joaotavora
Copy link
Owner

joaotavora commented Sep 8, 2020 via email

@muffinmad
Copy link
Collaborator

@aramirez

Does your code handle special elements from imenu--index-alist? From imenu--index-alist docstring:

Special elements look like
(INDEX-NAME POSITION FUNCTION ARGUMENTS...).
To "go to" a special element means applying FUNCTION to
INDEX-NAME, POSITION, and the ARGUMENTS.

Related issues in other packages:
colonelpanic8/flimenu#6
bmag/imenu-list#58

@aramirez
Copy link
Author

aramirez commented Sep 8, 2020 via email

@joaotavora
Copy link
Owner

joaotavora commented Sep 8, 2020 via email

@Ergus
Copy link

Ergus commented Sep 11, 2020

Hi Joao:

I made this very straight forward function for @aramirez to reproduce the ido-imenu behavior in fido-mode. It seems to work with almost anything else except eglot. The function is just a filter for the output of imenu--make-index-alist to "flatten" the output of the function.

;; Same flet code in your function
(defun my-filter (symbol-list)
   (let (name position name-and-pos)
     (dolist (symbol symbol-list)
       (setq name nil
             position nil)
       (cond
        ((listp symbol)
         (if (imenu--subalist-p symbol)
             (my-filter symbol)
           (setq name (car symbol))
           (setq position (cdr symbol))))

        ((stringp symbol)
         (setq name symbol)
         (setq position (get-text-property 1 'org-imenu-marker symbol))))

       (when (and position name)
         (add-to-list 'name-and-pos (cons name position))))
     name-and-pos))

;; Filter the output of imenu--make-index-alist 
(advice-add 'imenu--make-index-alist :filter-return #'my-filter)

He said that this worked even with LSP. Do you have an idea why it is failing with eglot?

Best,
Ergus

joaotavora added a commit that referenced this issue Sep 8, 2022
Fix #758, #536, #535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example #758, #536, #535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change
bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 18, 2022
Fix joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change
bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 19, 2022
Fix joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change
bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 19, 2022
Fix #758, #536, #535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example #758, #536, #535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change

#758: joaotavora/eglot#758
#536: joaotavora/eglot#536
#535: joaotavora/eglot#535
#758: joaotavora/eglot#758
#536: joaotavora/eglot#536
#535: joaotavora/eglot#535
jollaitbot pushed a commit to sailfishos-mirror/emacs that referenced this issue Oct 12, 2022
Fix joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change
jollaitbot pushed a commit to sailfishos-mirror/emacs that referenced this issue Oct 20, 2022
Fix joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change
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

4 participants