Enabling semantic-mode in emacs-lisp buffers
Eric Ludlam <[email protected]> Sat, 12 Oct 2019 09:24:33 -0400
| Newsgroups | gmane.emacs.cedet |
|---|---|
| Message-ID | <[email protected]> |
Hi all,
I'm finally updating to using a version of CEDET that's built into
Emacs. With the version from source-forge, emacs-lisp buffers used
CEDET features by default, but this is not the case with the version
built into Emacs. I feel it's important to include emacs lisp because
other modes like srecode and some decoration features depend on it.
My assumption is that this was left out on-purpose, so I enabled it (see
first part of patch below) and started using it and looking to see what
annoying things might have caused this to be removed.
If you have any reasons why emacs-lisp-mode shoult stay unsupported by
semantic by default (aside from what I'm fixing below) please let me
know what they are. Maybe I can fix them.
What I did find is a problem where completion-at-point (which I was
using via company-mode) started parsing piles of files from Emacs' lisp
directories.
The second part of the below patch fixes this problem. It also speeds
things up a bunch which is nice.
Repro steps:
emacs -q
M-x semantic-mode RET
;; Edit /tmp/foo.el
;; Type in: ;; comment a
;; put cursor directly after "a"
M-x completion-at-point RET
You'll see a ton of parsing messages from semantic rolling by. Hit C-g
and don't wait for it. This is a worst-case scenario.
;; Exit emacs
In ~/.emacs.d/semanticdb you'll see lots of your emacs files tag caches
stored away. Delete them. Apply the patch.
When you try again, there may be a message or 2 rolling by but no
parsing. In addition, no extra semanticdb files should be saved.
How this patch works (if you care):
The semantic parser parses buffers for tags. semanticdb is a tool that
makes it possible to search tags from multiple files from multiple
directories. It caches these into files in .emacs.d to speed up usage
in future sessions, and allows searching of tags in files not in buffers.
For Emacs lisp, there is a special database used during search that uses
Emacs' internal symbol lookup to find tags that haven't been parsed. It
can find the files they come from, and read tags from those files if
needed. (ie - if you want to jump to that tag.) Completion doesn't need
that feature. To convert the found tags from Emacs' internal search
format to be useful, they need to be normalized, and that process was
loading and parsing the extra files.
This isn't necessary for completion, so instead of loading the tags, the
patched normalization process for emacs-lisp just saves the filename in
the found tag and moves on. The part the converts the tag list into the
completion list then needs to access that filename more generically for
cases where a found tag is already in a buffer.
An alternative to the below patch, or perhaps in addition to it, would
be to remove the (require 'semantic/db-el) from the end of
semantic/bovine/el.el. There are many very good emacs-lisp based tools
these days, so this feature is probably not necessary unless you are
bought into the CEDET modes specifically.
Thanks for any input
Eric
diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el
index 0b878cae52..e92c1ed363 100644
--- a/lisp/cedet/semantic.el
+++ b/lisp/cedet/semantic.el
@@ -269,6 +269,7 @@ semantic-inhibit-functions
(defcustom semantic-new-buffer-setup-functions
'((c-mode . semantic-default-c-setup)
(c++-mode . semantic-default-c-setup)
+ (emacs-lisp-mode . semantic-default-elisp-setup)
(html-mode . semantic-default-html-setup)
(java-mode . wisent-java-default-setup)
(js-mode . wisent-javascript-setup-parser)
diff --git a/lisp/cedet/semantic/db-el.el b/lisp/cedet/semantic/db-el.el
index 39d61fe789..70f023750c 100644
--- a/lisp/cedet/semantic/db-el.el
+++ b/lisp/cedet/semantic/db-el.el
@@ -176,15 +176,22 @@ emacs-lisp-mode
;; Is it a .gz file?
(setq file (concat file ".gz"))))
- (let* ((tab (semanticdb-file-table-object file))
+ ;; Use DONTLOAD opt for finding table obj associated w/ these tags.
+ ;; If we did load these syms, then simple completions for "a" for
+ ;; as-you-type completion systems will load half the libraries in
+ ;; emacs.
+ (let* ((tab (semanticdb-file-table-object file t))
(newtags (when tab (semanticdb-find-tags-by-name-method
tab (semantic-tag-name tag))))
(match nil))
- ;; We might not have a parsed tag in this file, because it
- ;; might be generated through a macro like defstruct.
+ ;; We might not have a parsed tag in this file due to
+ ;; specifying DONTLOAD above, or the tag was generated with a
+ ;; macro. In that case, just use our found tag, and store
+ ;; the filename in it.
(if (null newtags)
- (setq match tag)
- ;; Find the best match.
+ ;; In this case
+ (setq match (semantic--tag-put-property tag :filename file))
+ ;; Find the best match in the found tags.
(dolist (T newtags)
(when (semantic-tag-similar-p T tag)
(setq match T)))
diff --git a/lisp/cedet/semantic/db-find.el b/lisp/cedet/semantic/db-find.el
index 18c749b098..114534bbf0 100644
--- a/lisp/cedet/semantic/db-find.el
+++ b/lisp/cedet/semantic/db-find.el
@@ -882,7 +882,7 @@ semanticdb-strip-find-results
;; Find-file-match allows a tool to make sure the tag is
;; 'live', somewhere in a buffer.
(cond ((eq find-file-match 'name)
- (or (semantic--tag-get-property ntag :filename)
+ (or (semantic-tag-file-name ntag)
(let ((f (semanticdb-full-filename nametable)))
(semantic--tag-put-property ntag :filename f))))
((and find-file-match ntab)