* Add/remove an element into/from a cons. @ 2021-10-26 2:05 Hongyi Zhao 2021-10-26 4:57 ` Tassilo Horn 0 siblings, 1 reply; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 2:05 UTC (permalink / raw) To: help-gnu-emacs How can I add/remove an element into/from a cons, taking the following one as an example: ```emacs-lisp (setq company-backends '((company-tabnine :separate company-capf company-dabbrev company-keywords company-files company-ispell))) ``` How can I remove `company-ispell` from and re-add it into the company-backends defined above? Regards, HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 2:05 Add/remove an element into/from a cons Hongyi Zhao @ 2021-10-26 4:57 ` Tassilo Horn 2021-10-26 5:40 ` Hongyi Zhao 0 siblings, 1 reply; 26+ messages in thread From: Tassilo Horn @ 2021-10-26 4:57 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs Hongyi Zhao <hongyi.zhao@gmail.com> writes: > How can I add/remove an element into/from a cons, taking the following > one as an example: > > ```emacs-lisp > (setq company-backends '((company-tabnine :separate company-capf > company-dabbrev company-keywords company-files company-ispell))) > ``` > > How can I remove `company-ispell` from and re-add it into the > company-backends defined above? You can use `setf' with the place being the alist entry like this (company-backends replaced with th/test in my example): --8<---------------cut here---------------start------------->8--- (setq th/test '(( company-tabnine :separate company-capf company-dabbrev company-keywords company-files company-ispell))) (let ((place (assoc 'company-tabnine th/test))) (setf place (remove 'company-ispell place))) --8<---------------cut here---------------end--------------->8--- HTH, Tassilo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 4:57 ` Tassilo Horn @ 2021-10-26 5:40 ` Hongyi Zhao 2021-10-26 5:42 ` Hongyi Zhao 0 siblings, 1 reply; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 5:40 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs On Tue, Oct 26, 2021 at 12:58 PM Tassilo Horn <tsdh@gnu.org> wrote: > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > How can I add/remove an element into/from a cons, taking the following > > one as an example: > > > > ```emacs-lisp > > (setq company-backends '((company-tabnine :separate company-capf > > company-dabbrev company-keywords company-files company-ispell))) > > ``` > > > > How can I remove `company-ispell` from and re-add it into the > > company-backends defined above? > > You can use `setf' with the place being the alist entry like this > (company-backends replaced with th/test in my example): > > --8<---------------cut here---------------start------------->8--- > (setq th/test '(( company-tabnine :separate company-capf company-dabbrev > company-keywords company-files company-ispell))) > > (let ((place (assoc 'company-tabnine th/test))) > (setf place (remove 'company-ispell place))) > --8<---------------cut here---------------end--------------->8--- Yes. It does the trick: `C-j' (setq th/test '((company-tabnine :separate company-capf company-dabbrev company-keywords company-ispell company-files))) ;; ((company-tabnine :separate company-capf company-dabbrev company-keywords company-ispell company-files)) `C-j' (setq th/test (let ((place (assoc 'company-tabnine th/test))) (setf place (remove 'company-ispell place)))) ;; (company-tabnine :separate company-capf company-dabbrev company-keywords company-files) But how to add it back to the alist? HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 5:40 ` Hongyi Zhao @ 2021-10-26 5:42 ` Hongyi Zhao 2021-10-26 6:07 ` Hongyi Zhao 2021-10-26 6:08 ` Tassilo Horn 0 siblings, 2 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 5:42 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs On Tue, Oct 26, 2021 at 1:40 PM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Tue, Oct 26, 2021 at 12:58 PM Tassilo Horn <tsdh@gnu.org> wrote: > > > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > > > How can I add/remove an element into/from a cons, taking the following > > > one as an example: > > > > > > ```emacs-lisp > > > (setq company-backends '((company-tabnine :separate company-capf > > > company-dabbrev company-keywords company-files company-ispell))) > > > ``` > > > > > > How can I remove `company-ispell` from and re-add it into the > > > company-backends defined above? > > > > You can use `setf' with the place being the alist entry like this > > (company-backends replaced with th/test in my example): > > > > --8<---------------cut here---------------start------------->8--- > > (setq th/test '(( company-tabnine :separate company-capf company-dabbrev > > company-keywords company-files company-ispell))) > > > > (let ((place (assoc 'company-tabnine th/test))) > > (setf place (remove 'company-ispell place))) > > --8<---------------cut here---------------end--------------->8--- > > Yes. It does the trick: > > `C-j' (setq th/test '((company-tabnine :separate company-capf company-dabbrev > company-keywords company-ispell company-files))) > > ;; ((company-tabnine :separate company-capf company-dabbrev > company-keywords company-ispell company-files)) > > > `C-j' (setq th/test (let ((place (assoc 'company-tabnine th/test))) > (setf place (remove 'company-ispell place)))) > > ;; (company-tabnine :separate company-capf company-dabbrev > company-keywords company-files) > > But how to add it back to the alist? I mean: But how to add it back to its original position in the list? ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 5:42 ` Hongyi Zhao @ 2021-10-26 6:07 ` Hongyi Zhao 2021-10-26 6:18 ` Tassilo Horn 2021-10-26 6:08 ` Tassilo Horn 1 sibling, 1 reply; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 6:07 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs On Tue, Oct 26, 2021 at 1:42 PM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Tue, Oct 26, 2021 at 1:40 PM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > > On Tue, Oct 26, 2021 at 12:58 PM Tassilo Horn <tsdh@gnu.org> wrote: > > > > > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > > > > > How can I add/remove an element into/from a cons, taking the following > > > > one as an example: > > > > > > > > ```emacs-lisp > > > > (setq company-backends '((company-tabnine :separate company-capf > > > > company-dabbrev company-keywords company-files company-ispell))) > > > > ``` > > > > > > > > How can I remove `company-ispell` from and re-add it into the > > > > company-backends defined above? > > > > > > You can use `setf' with the place being the alist entry like this > > > (company-backends replaced with th/test in my example): > > > > > > --8<---------------cut here---------------start------------->8--- > > > (setq th/test '(( company-tabnine :separate company-capf company-dabbrev > > > company-keywords company-files company-ispell))) > > > > > > (let ((place (assoc 'company-tabnine th/test))) > > > (setf place (remove 'company-ispell place))) > > > --8<---------------cut here---------------end--------------->8--- > > > > Yes. It does the trick: > > > > `C-j' (setq th/test '((company-tabnine :separate company-capf company-dabbrev > > company-keywords company-ispell company-files))) > > > > ;; ((company-tabnine :separate company-capf company-dabbrev > > company-keywords company-ispell company-files)) > > > > > > `C-j' (setq th/test (let ((place (assoc 'company-tabnine th/test))) > > (setf place (remove 'company-ispell place)))) > > > > ;; (company-tabnine :separate company-capf company-dabbrev > > company-keywords company-files) > > > > But how to add it back to the alist? > > I mean: But how to add it back to its original position in the list? BTW, I want to use the above trick to simplify the following function but failed: (setq company-backends '((company-tabnine :separate company-dabbrev company-keywords company-files company-ispell company-capf))) (defun my-scratch-init () (with-current-buffer "*scratch*" (setq-local company-backends '((company-tabnine :separate company-capf company-dabbrev company-keywords company-files))) )) ==> (defun my-scratch-init () (with-current-buffer "*scratch*" (setq-local company-backends (let ((place (assoc 'company-tabnine company-backends))) (setf place (remove 'company-ispell place)))) )) HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 6:07 ` Hongyi Zhao @ 2021-10-26 6:18 ` Tassilo Horn 2021-10-26 6:30 ` Hongyi Zhao 2021-10-26 6:39 ` Hongyi Zhao 0 siblings, 2 replies; 26+ messages in thread From: Tassilo Horn @ 2021-10-26 6:18 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs Hongyi Zhao <hongyi.zhao@gmail.com> writes: > (defun my-scratch-init () > (with-current-buffer "*scratch*" > (setq-local company-backends (let ((place (assoc 'company-tabnine > company-backends))) > (setf place (remove 'company-ispell place)))) > )) setf returns the new value, so here you are setting company-backends to the modified alist entry, not the alist itself. This should work: --8<---------------cut here---------------start------------->8--- (defun my-scratch-init () (with-current-buffer "*scratch*" ;; Ensure it has a local variable. Not sure if it has by default... (make-local-variable 'company-backends) (let ((place (assoc 'company-tabnine company-backends))) (setf place (remove 'company-ispell place))))) --8<---------------cut here---------------end--------------->8--- Bye, Tassilo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 6:18 ` Tassilo Horn @ 2021-10-26 6:30 ` Hongyi Zhao 2021-10-26 6:39 ` Hongyi Zhao 1 sibling, 0 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 6:30 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs On Tue, Oct 26, 2021 at 2:21 PM Tassilo Horn <tsdh@gnu.org> wrote: > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > (defun my-scratch-init () > > (with-current-buffer "*scratch*" > > (setq-local company-backends (let ((place (assoc 'company-tabnine > > company-backends))) > > (setf place (remove 'company-ispell place)))) > > )) > > setf returns the new value, so here you are setting company-backends to > the modified alist entry, not the alist itself. This should work: > > --8<---------------cut here---------------start------------->8--- > (defun my-scratch-init () > (with-current-buffer "*scratch*" > ;; Ensure it has a local variable. Not sure if it has by default... > (make-local-variable 'company-backends) > (let ((place (assoc 'company-tabnine company-backends))) > (setf place (remove 'company-ispell place))))) > --8<---------------cut here---------------end--------------->8--- It doesn't work. The variable hasn't been revised when I'm switch to scratch buffer. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 6:18 ` Tassilo Horn 2021-10-26 6:30 ` Hongyi Zhao @ 2021-10-26 6:39 ` Hongyi Zhao 1 sibling, 0 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 6:39 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs On Tue, Oct 26, 2021 at 2:21 PM Tassilo Horn <tsdh@gnu.org> wrote: > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > (defun my-scratch-init () > > (with-current-buffer "*scratch*" > > (setq-local company-backends (let ((place (assoc 'company-tabnine > > company-backends))) > > (setf place (remove 'company-ispell place)))) > > )) > > setf returns the new value, so here you are setting company-backends to > the modified alist entry, not the alist itself. This should work: > > --8<---------------cut here---------------start------------->8--- > (defun my-scratch-init () > (with-current-buffer "*scratch*" > ;; Ensure it has a local variable. Not sure if it has by default... The default value is set this way, as I've posted: (setq company-backends '((company-tabnine :separate company-dabbrev company-keywords company-files company-ispell company-capf))) > (make-local-variable 'company-backends) > (let ((place (assoc 'company-tabnine company-backends))) > (setf place (remove 'company-ispell place))))) > --8<---------------cut here---------------end--------------->8--- > > Bye, > Tassilo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 5:42 ` Hongyi Zhao 2021-10-26 6:07 ` Hongyi Zhao @ 2021-10-26 6:08 ` Tassilo Horn 2021-10-26 6:17 ` Hongyi Zhao 1 sibling, 1 reply; 26+ messages in thread From: Tassilo Horn @ 2021-10-26 6:08 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs Hongyi Zhao <hongyi.zhao@gmail.com> writes: >> > > How can I add/remove an element into/from a cons, taking the >> > > following one as an example: >> > > >> > > ```emacs-lisp >> > > (setq company-backends '((company-tabnine :separate company-capf >> > > company-dabbrev company-keywords company-files company-ispell))) >> > > ``` >> > > >> > > How can I remove `company-ispell` from and re-add it into the >> > > company-backends defined above? >> > >> > You can use `setf' with the place being the alist entry like this >> > (company-backends replaced with th/test in my example): >> > >> > --8<---------------cut here---------------start------------->8--- >> > (setq th/test '(( company-tabnine :separate company-capf company-dabbrev >> > company-keywords company-files company-ispell))) >> > >> > (let ((place (assoc 'company-tabnine th/test))) >> > (setf place (remove 'company-ispell place))) >> > --8<---------------cut here---------------end--------------->8--- >> >> Yes. It does the trick: >> >> `C-j' (setq th/test '((company-tabnine :separate company-capf company-dabbrev >> company-keywords company-ispell company-files))) >> >> ;; ((company-tabnine :separate company-capf company-dabbrev >> company-keywords company-ispell company-files)) >> >> >> `C-j' (setq th/test (let ((place (assoc 'company-tabnine th/test))) >> (setf place (remove 'company-ispell place)))) >> >> ;; (company-tabnine :separate company-capf company-dabbrev >> company-keywords company-files) >> >> But how to add it back to the alist? > > I mean: But how to add it back to its original position in the list? This would add it again as the last element: --8<---------------cut here---------------start------------->8--- (let ((place (assoc 'company-tabnine th/test))) (setf place (append place '(company-ispell)))) --8<---------------cut here---------------end--------------->8--- Bye, Tassilo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 6:08 ` Tassilo Horn @ 2021-10-26 6:17 ` Hongyi Zhao 2021-10-26 6:22 ` Tassilo Horn 2021-10-26 6:22 ` Hongyi Zhao 0 siblings, 2 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 6:17 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs On Tue, Oct 26, 2021 at 2:09 PM Tassilo Horn <tsdh@gnu.org> wrote: > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > >> > > How can I add/remove an element into/from a cons, taking the > >> > > following one as an example: > >> > > > >> > > ```emacs-lisp > >> > > (setq company-backends '((company-tabnine :separate company-capf > >> > > company-dabbrev company-keywords company-files company-ispell))) > >> > > ``` > >> > > > >> > > How can I remove `company-ispell` from and re-add it into the > >> > > company-backends defined above? > >> > > >> > You can use `setf' with the place being the alist entry like this > >> > (company-backends replaced with th/test in my example): > >> > > >> > --8<---------------cut here---------------start------------->8--- > >> > (setq th/test '(( company-tabnine :separate company-capf company-dabbrev > >> > company-keywords company-files company-ispell))) > >> > > >> > (let ((place (assoc 'company-tabnine th/test))) > >> > (setf place (remove 'company-ispell place))) > >> > --8<---------------cut here---------------end--------------->8--- > >> > >> Yes. It does the trick: > >> > >> `C-j' (setq th/test '((company-tabnine :separate company-capf company-dabbrev > >> company-keywords company-ispell company-files))) > >> > >> ;; ((company-tabnine :separate company-capf company-dabbrev > >> company-keywords company-ispell company-files)) > >> > >> > >> `C-j' (setq th/test (let ((place (assoc 'company-tabnine th/test))) > >> (setf place (remove 'company-ispell place)))) > >> > >> ;; (company-tabnine :separate company-capf company-dabbrev > >> company-keywords company-files) > >> > >> But how to add it back to the alist? > > > > I mean: But how to add it back to its original position in the list? > > This would add it again as the last element: > > --8<---------------cut here---------------start------------->8--- > (let ((place (assoc 'company-tabnine th/test))) > (setf place (append place '(company-ispell)))) > --8<---------------cut here---------------end--------------->8--- Thanks. But the push doesn't work: (let ((place (assoc 'company-tabnine th/test))) (setf place (push place '(company-ispell)))) Debugger entered--Lisp error: (wrong-number-of-arguments (lambda (command &optional arg &rest ignored) "`company-mode' completion backend using Ispell." (interactive (list 'interactive)) (cond ((eql command 'interactive) (company-begin-backend 'company-ispell)) ((eql command 'prefix) (if (company-ispell-available) (progn (company-grab-word)))) ((eql command 'candidates) (let ((words (company-ispell--lookup-words arg ...)) (completion-ignore-case t)) (if (string= arg "") words (all-completions arg words)))) ((eql command 'kind) 'text) ((eql command 'sorted) t) ((eql command 'ignore-case) 'keep-prefix))) 0) company-ispell() (let* ((v (company-ispell))) (\(setf\ quote\) (cons place 'v) v)) (setq place (let* ((v (company-ispell))) (\(setf\ quote\) (cons place 'v) v))) (let ((place (assoc 'company-tabnine th/test))) (setq place (let* ((v (company-ispell))) (\(setf\ quote\) (cons place 'v) v)))) (progn (let ((place (assoc 'company-tabnine th/test))) (setq place (let* ((v (company-ispell))) (\(setf\ quote\) (cons place 'v) v))))) elisp--eval-last-sexp(nil) eval-last-sexp(nil) funcall-interactively(eval-last-sexp nil) command-execute(eval-last-sexp) HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 6:17 ` Hongyi Zhao @ 2021-10-26 6:22 ` Tassilo Horn 2021-10-26 8:12 ` Hongyi Zhao 2021-10-26 6:22 ` Hongyi Zhao 1 sibling, 1 reply; 26+ messages in thread From: Tassilo Horn @ 2021-10-26 6:22 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs, Stefan Monnier Hongyi Zhao <hongyi.zhao@gmail.com> writes: >> This would add it again as the last element: >> >> --8<---------------cut here---------------start------------->8--- >> (let ((place (assoc 'company-tabnine th/test))) >> (setf place (append place '(company-ispell)))) >> --8<---------------cut here---------------end--------------->8--- > > Thanks. But the push doesn't work: > > (let ((place (assoc 'company-tabnine th/test))) > (setf place (push place '(company-ispell)))) Have a look at the docs. `push' wants the place as second element, and then you don't need the `setf' anyway. --8<---------------cut here---------------start------------->8--- (let ((place (assoc 'company-tabnine th/test))) (push 'company-ispell place)) --8<---------------cut here---------------end--------------->8--- But note that `push' will add it to the front of the list. Hm, I just saw that none of my code actually works, i.e., it does not alter the value of `th/test'. --8<---------------cut here---------------start------------->8--- (setq th/test '((company-tabnine :separate company-capf company-dabbrev company-keywords company-files company-ispell))) (let ((place (assoc 'company-tabnine th/test))) (setf place (remove 'company-ispell place))) (let ((place (assoc 'company-tabnine th/test))) (setf place (append place '(company-ispell)))) (let ((place (assoc 'company-tabnine th/test))) (push 'company-ispell place)) --8<---------------cut here---------------end--------------->8--- Aren't alist entries setf-able places? It seems so, at least: (let ((val (assoc 'company-tabnine th/test))) (setf (assoc 'company-tabnine th/test) (remove 'company-ispell val))) signals a void-function error. Ah, now I got it. You must use `alist-get' instead of `assoc' and not bind the place to a variable but use it explicitly as the first argument of `setf' which makes sense given that `setf' is a macro determining the place from its first argument. So these do actually work: --8<---------------cut here---------------start------------->8--- (setf (alist-get 'company-tabnine th/test) (remove 'company-ispell (alist-get 'company-tabnine th/test))) (setf (alist-get 'company-tabnine th/test) (append (alist-get 'company-tabnine th/test) '(company-ispell))) (push 'company-ispell (alist-get 'company-tabnine th/test)) --8<---------------cut here---------------end--------------->8--- Bye, Tassilo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 6:22 ` Tassilo Horn @ 2021-10-26 8:12 ` Hongyi Zhao 2021-10-26 8:15 ` Tassilo Horn 0 siblings, 1 reply; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 8:12 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs, Stefan Monnier On Tue, Oct 26, 2021 at 3:09 PM Tassilo Horn <tsdh@gnu.org> wrote: > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > >> This would add it again as the last element: > >> > >> --8<---------------cut here---------------start------------->8--- > >> (let ((place (assoc 'company-tabnine th/test))) > >> (setf place (append place '(company-ispell)))) > >> --8<---------------cut here---------------end--------------->8--- > > > > Thanks. But the push doesn't work: > > > > (let ((place (assoc 'company-tabnine th/test))) > > (setf place (push place '(company-ispell)))) > > Have a look at the docs. `push' wants the place as second element, and > then you don't need the `setf' anyway. > > --8<---------------cut here---------------start------------->8--- > (let ((place (assoc 'company-tabnine th/test))) > (push 'company-ispell place)) > --8<---------------cut here---------------end--------------->8--- > > But note that `push' will add it to the front of the list. > > Hm, I just saw that none of my code actually works, i.e., it does not > alter the value of `th/test'. > > --8<---------------cut here---------------start------------->8--- > (setq th/test '((company-tabnine :separate company-capf company-dabbrev company-keywords company-files company-ispell))) > > (let ((place (assoc 'company-tabnine th/test))) > (setf place (remove 'company-ispell place))) > > (let ((place (assoc 'company-tabnine th/test))) > (setf place (append place '(company-ispell)))) > > (let ((place (assoc 'company-tabnine th/test))) > (push 'company-ispell place)) > --8<---------------cut here---------------end--------------->8--- > > Aren't alist entries setf-able places? It seems so, at least: > > (let ((val (assoc 'company-tabnine th/test))) > (setf (assoc 'company-tabnine th/test) > (remove 'company-ispell val))) > > signals a void-function error. > > Ah, now I got it. You must use `alist-get' instead of `assoc' and not > bind the place to a variable but use it explicitly as the first argument > of `setf' which makes sense given that `setf' is a macro determining the > place from its first argument. So these do actually work: > > --8<---------------cut here---------------start------------->8--- > (setf (alist-get 'company-tabnine th/test) > (remove 'company-ispell (alist-get 'company-tabnine th/test))) > > (setf (alist-get 'company-tabnine th/test) > (append (alist-get 'company-tabnine th/test) > '(company-ispell))) > > (push 'company-ispell (alist-get 'company-tabnine th/test)) > --8<---------------cut here---------------end--------------->8--- I tried with the following function: ```emacs-lisp (use-package company-tabnine :init (setq company-backends '((company-tabnine :separate company-dabbrev company-keywords company-files company-ispell company-capf))) :hook (emacs-lisp-mode . hz/scratch-init) :config (defun hz/scratch-init () (with-current-buffer "*scratch*" (make-local-variable 'company-backends) (setf (alist-get 'company-tabnine company-backends) (remove 'company-ispell (alist-get 'company-tabnine company-backends))) )) ``` The above method will set the correct company-backends when I'm on scratch buffer. But I also find that when I switch to other buffers, says, AUCTeX based LaTeX-mode, the company-backends settings still remains the same, and can't be restored to the default configuration, i.e., the following: (setq company-backends '((company-tabnine :separate company-dabbrev company-keywords company-files company-ispell company-capf))) HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 8:12 ` Hongyi Zhao @ 2021-10-26 8:15 ` Tassilo Horn 2021-10-26 9:26 ` Hongyi Zhao 2021-10-26 12:36 ` Stefan Monnier 0 siblings, 2 replies; 26+ messages in thread From: Tassilo Horn @ 2021-10-26 8:15 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs, Stefan Monnier Hongyi Zhao <hongyi.zhao@gmail.com> writes: > I tried with the following function: > > ```emacs-lisp > (defun hz/scratch-init () > (with-current-buffer "*scratch*" > (make-local-variable 'company-backends) > (setf (alist-get 'company-tabnine company-backends) > (remove 'company-ispell (alist-get 'company-tabnine > company-backends))) > )) > ``` > > The above method will set the correct company-backends when I'm on > scratch buffer. But I also find that when I switch to other buffers, > says, AUCTeX based LaTeX-mode, the company-backends settings still > remains the same, You mean, the above function changes the value not only in *scratch* but all buffers? That shouldn't happen, I'd say, as the function explicitly makes `company-backends' buffer-local in *scratch* before modifying it. In any case, I think it would be more valuable for any of us if you'd start a discussion with a statement on what you want to achieve instead of some non-working snippet of code where the intent is to be interpreted by the reader. Bye, Tassilo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 8:15 ` Tassilo Horn @ 2021-10-26 9:26 ` Hongyi Zhao 2021-10-26 9:31 ` Hongyi Zhao 2021-10-26 18:56 ` Tassilo Horn 2021-10-26 12:36 ` Stefan Monnier 1 sibling, 2 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 9:26 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs, Stefan Monnier On Tue, Oct 26, 2021 at 4:59 PM Tassilo Horn <tsdh@gnu.org> wrote: > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > I tried with the following function: > > > > ```emacs-lisp > > (defun hz/scratch-init () > > (with-current-buffer "*scratch*" > > (make-local-variable 'company-backends) > > (setf (alist-get 'company-tabnine company-backends) > > (remove 'company-ispell (alist-get 'company-tabnine > > company-backends))) > > )) > > ``` > > > > The above method will set the correct company-backends when I'm on > > scratch buffer. But I also find that when I switch to other buffers, > > says, AUCTeX based LaTeX-mode, the company-backends settings still > > remains the same, > > You mean, the above function changes the value not only in *scratch* but > all buffers? After using the above function, it disables me to check the value of `company-backends' when I switch from scratch to other buffers. The following message will be triggered when I call `C-h v company-backends RET': Type "q" to restore previous buffer, SPC to scroll help. > That shouldn't happen, I'd say, as the function explicitly > makes `company-backends' buffer-local in *scratch* before modifying it. > > In any case, I think it would be more valuable for any of us if you'd > start a discussion with a statement on what you want to achieve instead > of some non-working snippet of code where the intent is to be > interpreted by the reader. I'm using company-tabnine package and the following company-backends setting: (setq company-backends '((company-tabnine :separate company-dabbrev company-keywords company-files company-ispell company-capf))) I want to disable the company-ispell backend when I'm in emacs-lisp-mode. The following function will do the trick: (defun hz/scratch-init () (with-current-buffer "*scratch*" (setq-local company-backends '((company-tabnine :separate company-capf company-dabbrev company-keywords company-files))) )) (add-hook 'emacs-lisp-mode-hook #'hz/scratch-init) But as I've posted here, considering that I've also had a definite company-backends setting, so I want to remove the company-ispell from it programmatically. I hope this time I've clearly stated my intention. HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 9:26 ` Hongyi Zhao @ 2021-10-26 9:31 ` Hongyi Zhao 2021-10-26 18:56 ` Tassilo Horn 1 sibling, 0 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 9:31 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs, Stefan Monnier On Tue, Oct 26, 2021 at 5:26 PM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > But as I've posted here, considering that I've also had a definite > company-backends setting, so I want to remove the company-ispell from > it programmatically. > > I hope this time I've clearly stated my intention. The background of the whole question comes from here [1]. [1] https://github.com/company-mode/company-mode/issues/1130#issuecomment-950331890 HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 9:26 ` Hongyi Zhao 2021-10-26 9:31 ` Hongyi Zhao @ 2021-10-26 18:56 ` Tassilo Horn 2021-10-27 1:39 ` Hongyi Zhao 1 sibling, 1 reply; 26+ messages in thread From: Tassilo Horn @ 2021-10-26 18:56 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs, Stefan Monnier Hongyi Zhao <hongyi.zhao@gmail.com> writes: >> You mean, the above function changes the value not only in *scratch* >> but all buffers? > > After using the above function, it disables me to check the value of > `company-backends' when I switch from scratch to other buffers. What? > The following message will be triggered when I call `C-h v > company-backends RET': > > Type "q" to restore previous buffer, SPC to scroll help. Yes, but how does that message hinder you from checking the value of `company-backends'? > I'm using company-tabnine package and the following company-backends > setting: > > (setq company-backends '((company-tabnine :separate company-dabbrev > company-keywords company-files company-ispell company-capf))) > > I want to disable the company-ispell backend when I'm in > emacs-lisp-mode. The following function will do the trick: > > (defun hz/scratch-init () > (with-current-buffer "*scratch*" > (setq-local company-backends > '((company-tabnine :separate company-capf > company-dabbrev company-keywords company-files))) > )) > > (add-hook 'emacs-lisp-mode-hook #'hz/scratch-init) Well, your function will always run when `emacs-lisp-mode' or a mode derived from it, like `lisp-interaction-mode', the major-mode of *scratch*, is activated. But it evaluates that code always in *scratch* which defeats the purpose of disabling company-ispell in every buffer having `emacs-lisp-mode' as major-mode. > But as I've posted here, considering that I've also had a definite > company-backends setting, so I want to remove the company-ispell from > it programmatically. > > I hope this time I've clearly stated my intention. I guess so. In certain modes, you would like to have `company-ispell' removed from the company-tabnine entry of company-backends. Right? In that respect, I think a function like --8<---------------cut here---------------start------------->8--- (defun hz/company-tabnine-remove-company-ispell () (make-local-variable 'company-backends) (setf (alist-get 'company-tabnine company-backends) (remove 'company-ispell (alist-get 'company-tabnine company-backends)))) --8<---------------cut here---------------end--------------->8--- should do the trick. However, I can imagine that you might not be able to use it in major-mode hooks such as `emacs-lisp-mode' due to ordering issues, i.e., I can easily imagine that `company-mode' (and this company-tabnine thingy) is initialized *after* the major-mode hook has run because usually, you activate minor-modes in major-mode hooks. In that case you would try to remove before the company-tabnine entry has been added to company-backends. That's all just guesswork since I don't use company. Bye, Tassilo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 18:56 ` Tassilo Horn @ 2021-10-27 1:39 ` Hongyi Zhao 2021-10-27 4:54 ` Hongyi Zhao 0 siblings, 1 reply; 26+ messages in thread From: Hongyi Zhao @ 2021-10-27 1:39 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs, Stefan Monnier On Wed, Oct 27, 2021 at 3:19 AM Tassilo Horn <tsdh@gnu.org> wrote: > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > >> You mean, the above function changes the value not only in *scratch* > >> but all buffers? > > > > After using the above function, it disables me to check the value of > > `company-backends' when I switch from scratch to other buffers. > > What? > > > The following message will be triggered when I call `C-h v > > company-backends RET': > > > > Type "q" to restore previous buffer, SPC to scroll help. > > Yes, but how does that message hinder you from checking the value of > `company-backends'? I can't reproduce this now. > > I'm using company-tabnine package and the following company-backends > > setting: > > > > (setq company-backends '((company-tabnine :separate company-dabbrev > > company-keywords company-files company-ispell company-capf))) > > > > I want to disable the company-ispell backend when I'm in > > emacs-lisp-mode. The following function will do the trick: > > > > (defun hz/scratch-init () > > (with-current-buffer "*scratch*" > > (setq-local company-backends > > '((company-tabnine :separate company-capf > > company-dabbrev company-keywords company-files))) > > )) > > > > (add-hook 'emacs-lisp-mode-hook #'hz/scratch-init) > > Well, your function will always run when `emacs-lisp-mode' or a mode > derived from it, like `lisp-interaction-mode', the major-mode of > *scratch*, is activated. But it evaluates that code always in *scratch* > which defeats the purpose of disabling company-ispell in every buffer > having `emacs-lisp-mode' as major-mode. > > > But as I've posted here, considering that I've also had a definite > > company-backends setting, so I want to remove the company-ispell from > > it programmatically. > > > > I hope this time I've clearly stated my intention. > > I guess so. In certain modes, you would like to have `company-ispell' > removed from the company-tabnine entry of company-backends. Right? > > In that respect, I think a function like > > --8<---------------cut here---------------start------------->8--- > (defun hz/company-tabnine-remove-company-ispell () > (make-local-variable 'company-backends) > (setf (alist-get 'company-tabnine company-backends) > (remove 'company-ispell > (alist-get 'company-tabnine company-backends)))) > --8<---------------cut here---------------end--------------->8--- > > should do the trick. However, I can imagine that you might not be able > to use it in major-mode hooks such as `emacs-lisp-mode' due to ordering > issues, i.e., I can easily imagine that `company-mode' (and this > company-tabnine thingy) is initialized *after* the major-mode hook has > run because usually, you activate minor-modes in major-mode hooks. In > that case you would try to remove before the company-tabnine entry has > been added to company-backends. > > That's all just guesswork since I don't use company. I have changed the original function to the following form: ```emacs-lisp (defun hz/company-tabnine-remove-company-ispell () (setq-local company-backends '((company-tabnine :separate company-capf company-dabbrev company-keywords company-files)))) ``` Based on my tries, your above suggest code will set and append the following value to the current buffer's company-backends: (company-tabnine :separate company-capf company-dabbrev company-keywords company-files) HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-27 1:39 ` Hongyi Zhao @ 2021-10-27 4:54 ` Hongyi Zhao 2021-10-27 5:13 ` Hongyi Zhao 2021-10-27 18:43 ` Tassilo Horn 0 siblings, 2 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-27 4:54 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs, Stefan Monnier On Wed, Oct 27, 2021 at 9:39 AM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Wed, Oct 27, 2021 at 3:19 AM Tassilo Horn <tsdh@gnu.org> wrote: > > > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > > >> You mean, the above function changes the value not only in *scratch* > > >> but all buffers? > > > > > > After using the above function, it disables me to check the value of > > > `company-backends' when I switch from scratch to other buffers. > > > > What? > > > > > The following message will be triggered when I call `C-h v > > > company-backends RET': > > > > > > Type "q" to restore previous buffer, SPC to scroll help. > > > > Yes, but how does that message hinder you from checking the value of > > `company-backends'? > > I can't reproduce this now. > > > > I'm using company-tabnine package and the following company-backends > > > setting: > > > > > > (setq company-backends '((company-tabnine :separate company-dabbrev > > > company-keywords company-files company-ispell company-capf))) > > > > > > I want to disable the company-ispell backend when I'm in > > > emacs-lisp-mode. The following function will do the trick: > > > > > > (defun hz/scratch-init () > > > (with-current-buffer "*scratch*" > > > (setq-local company-backends > > > '((company-tabnine :separate company-capf > > > company-dabbrev company-keywords company-files))) > > > )) > > > > > > (add-hook 'emacs-lisp-mode-hook #'hz/scratch-init) > > > > Well, your function will always run when `emacs-lisp-mode' or a mode > > derived from it, like `lisp-interaction-mode', the major-mode of > > *scratch*, is activated. But it evaluates that code always in *scratch* > > which defeats the purpose of disabling company-ispell in every buffer > > having `emacs-lisp-mode' as major-mode. > > > > > But as I've posted here, considering that I've also had a definite > > > company-backends setting, so I want to remove the company-ispell from > > > it programmatically. > > > > > > I hope this time I've clearly stated my intention. > > > > I guess so. In certain modes, you would like to have `company-ispell' > > removed from the company-tabnine entry of company-backends. Right? > > > > In that respect, I think a function like > > > > --8<---------------cut here---------------start------------->8--- > > (defun hz/company-tabnine-remove-company-ispell () > > (make-local-variable 'company-backends) > > (setf (alist-get 'company-tabnine company-backends) > > (remove 'company-ispell > > (alist-get 'company-tabnine company-backends)))) > > --8<---------------cut here---------------end--------------->8--- > > > > should do the trick. However, I can imagine that you might not be able > > to use it in major-mode hooks such as `emacs-lisp-mode' due to ordering > > issues, i.e., I can easily imagine that `company-mode' (and this > > company-tabnine thingy) is initialized *after* the major-mode hook has > > run because usually, you activate minor-modes in major-mode hooks. In > > that case you would try to remove before the company-tabnine entry has > > been added to company-backends. > > > > That's all just guesswork since I don't use company. > > I have changed the original function to the following form: > > ```emacs-lisp > (defun hz/company-tabnine-remove-company-ispell () > (setq-local company-backends > '((company-tabnine :separate company-capf company-dabbrev > company-keywords company-files)))) > ``` > > Based on my tries, your above suggest code will set and append the > following value to the current buffer's company-backends: > > (company-tabnine :separate company-capf company-dabbrev > company-keywords company-files) I also tried the following snippet, but still failed: (defun hz/company-tabnine-remove-company-ispell () (make-local-variable 'company-backends) (cond ( (derived-mode-p 'emacs-lisp-mode) (setf (alist-get 'company-tabnine company-backends) (remove 'company-ispell (alist-get 'company-tabnine company-backends)))) ( t (setf (alist-get 'company-tabnine company-backends) (append (alist-get 'company-tabnine company-backends) '(company-ispell)))))) (add-hook 'emacs-startup-hook #'hz/company-tabnine-remove-company-ispell) HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-27 4:54 ` Hongyi Zhao @ 2021-10-27 5:13 ` Hongyi Zhao 2021-10-27 18:43 ` Tassilo Horn 1 sibling, 0 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-27 5:13 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs, Stefan Monnier On Wed, Oct 27, 2021 at 12:54 PM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Wed, Oct 27, 2021 at 9:39 AM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > > On Wed, Oct 27, 2021 at 3:19 AM Tassilo Horn <tsdh@gnu.org> wrote: > > > > > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > > > > >> You mean, the above function changes the value not only in *scratch* > > > >> but all buffers? > > > > > > > > After using the above function, it disables me to check the value of > > > > `company-backends' when I switch from scratch to other buffers. > > > > > > What? > > > > > > > The following message will be triggered when I call `C-h v > > > > company-backends RET': > > > > > > > > Type "q" to restore previous buffer, SPC to scroll help. > > > > > > Yes, but how does that message hinder you from checking the value of > > > `company-backends'? > > > > I can't reproduce this now. > > > > > > I'm using company-tabnine package and the following company-backends > > > > setting: > > > > > > > > (setq company-backends '((company-tabnine :separate company-dabbrev > > > > company-keywords company-files company-ispell company-capf))) > > > > > > > > I want to disable the company-ispell backend when I'm in > > > > emacs-lisp-mode. The following function will do the trick: > > > > > > > > (defun hz/scratch-init () > > > > (with-current-buffer "*scratch*" > > > > (setq-local company-backends > > > > '((company-tabnine :separate company-capf > > > > company-dabbrev company-keywords company-files))) > > > > )) > > > > > > > > (add-hook 'emacs-lisp-mode-hook #'hz/scratch-init) > > > > > > Well, your function will always run when `emacs-lisp-mode' or a mode > > > derived from it, like `lisp-interaction-mode', the major-mode of > > > *scratch*, is activated. But it evaluates that code always in *scratch* > > > which defeats the purpose of disabling company-ispell in every buffer > > > having `emacs-lisp-mode' as major-mode. > > > > > > > But as I've posted here, considering that I've also had a definite > > > > company-backends setting, so I want to remove the company-ispell from > > > > it programmatically. > > > > > > > > I hope this time I've clearly stated my intention. > > > > > > I guess so. In certain modes, you would like to have `company-ispell' > > > removed from the company-tabnine entry of company-backends. Right? > > > > > > In that respect, I think a function like > > > > > > --8<---------------cut here---------------start------------->8--- > > > (defun hz/company-tabnine-remove-company-ispell () > > > (make-local-variable 'company-backends) > > > (setf (alist-get 'company-tabnine company-backends) > > > (remove 'company-ispell > > > (alist-get 'company-tabnine company-backends)))) > > > --8<---------------cut here---------------end--------------->8--- > > > > > > should do the trick. However, I can imagine that you might not be able > > > to use it in major-mode hooks such as `emacs-lisp-mode' due to ordering > > > issues, i.e., I can easily imagine that `company-mode' (and this > > > company-tabnine thingy) is initialized *after* the major-mode hook has > > > run because usually, you activate minor-modes in major-mode hooks. In > > > that case you would try to remove before the company-tabnine entry has > > > been added to company-backends. > > > > > > That's all just guesswork since I don't use company. > > > > I have changed the original function to the following form: > > > > ```emacs-lisp > > (defun hz/company-tabnine-remove-company-ispell () > > (setq-local company-backends > > '((company-tabnine :separate company-capf company-dabbrev > > company-keywords company-files)))) > > ``` > > > > Based on my tries, your above suggest code will set and append the > > following value to the current buffer's company-backends: > > > > (company-tabnine :separate company-capf company-dabbrev > > company-keywords company-files) > > I also tried the following snippet, but still failed: > > (defun hz/company-tabnine-remove-company-ispell () > (make-local-variable 'company-backends) > (cond > ( > (derived-mode-p 'emacs-lisp-mode) > (setf (alist-get 'company-tabnine company-backends) > (remove 'company-ispell (alist-get 'company-tabnine > company-backends)))) > ( > t > (setf (alist-get 'company-tabnine company-backends) > (append (alist-get 'company-tabnine company-backends) > '(company-ispell)))))) > > (add-hook 'emacs-startup-hook #'hz/company-tabnine-remove-company-ispell) The function currently used by me to achieve the goal is as follows: (defun hz/company-tabnine-remove-company-ispell () (when (derived-mode-p 'emacs-lisp-mode) (setq-local company-backends '((company-tabnine :separate company-capf company-dabbrev company-keywords company-files))))) (add-hook 'emacs-startup-hook #'hz/company-tabnine-remove-company-ispell) HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-27 4:54 ` Hongyi Zhao 2021-10-27 5:13 ` Hongyi Zhao @ 2021-10-27 18:43 ` Tassilo Horn 2021-10-28 4:14 ` Hongyi Zhao 1 sibling, 1 reply; 26+ messages in thread From: Tassilo Horn @ 2021-10-27 18:43 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs, Stefan Monnier Hongyi Zhao <hongyi.zhao@gmail.com> writes: >> > However, I can imagine that you might not be able to use it in >> > major-mode hooks such as `emacs-lisp-mode' due to ordering issues, >> > i.e., I can easily imagine that `company-mode' (and this >> > company-tabnine thingy) is initialized *after* the major-mode hook >> > has run because usually, you activate minor-modes in major-mode >> > hooks. In that case you would try to remove before the >> > company-tabnine entry has been added to company-backends. >> > >> > That's all just guesswork since I don't use company. >> >> [...] > > I also tried the following snippet, but still failed: > > (defun hz/company-tabnine-remove-company-ispell () > (make-local-variable 'company-backends) > (cond > ( > (derived-mode-p 'emacs-lisp-mode) > (setf (alist-get 'company-tabnine company-backends) > (remove 'company-ispell (alist-get 'company-tabnine > company-backends)))) > ( > t > (setf (alist-get 'company-tabnine company-backends) > (append (alist-get 'company-tabnine company-backends) > '(company-ispell)))))) > > (add-hook 'emacs-startup-hook #'hz/company-tabnine-remove-company-ispell) The first cond clause looks good but I don't see why you need the t-clause? Isn't the thing that company-ispell is part of the default value of the company-tabnine entry of company-backends? If that's the case, you want to make company-backends buffer-local and remove it in emacs-lisp-mode and derived modes but there is no need to add it again otherwise because the default value won't be altered. So that'd be: --8<---------------cut here---------------start------------->8--- (defun hz/company-tabnine-remove-company-ispell () (when (derived-mode-p 'emacs-lisp-mode) (make-local-variable 'company-backends)) (setf (alist-get 'company-tabnine company-backends) (remove 'company-ispell (alist-get 'company-tabnine company-backends)))) --8<---------------cut here---------------end--------------->8--- But most importantly, `emacs-startup-hook' is not the one you want. That runs once after emacs has loaded the init file. I'm even not sure what buffer is current then. I guess the most logical hook is `company-mode-hook'. (add-hook 'company-mode-hook #'hz/company-tabnine-remove-company-ispell) Or maybe there is also some `company-tabnine-*-hook' that runs after that package has done its setup in a buffer? Bye, Tassilo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-27 18:43 ` Tassilo Horn @ 2021-10-28 4:14 ` Hongyi Zhao 2021-10-28 4:36 ` Hongyi Zhao 2021-10-28 5:40 ` Hongyi Zhao 0 siblings, 2 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-28 4:14 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs, Stefan Monnier On Thu, Oct 28, 2021 at 2:52 AM Tassilo Horn <tsdh@gnu.org> wrote: > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > >> > However, I can imagine that you might not be able to use it in > >> > major-mode hooks such as `emacs-lisp-mode' due to ordering issues, > >> > i.e., I can easily imagine that `company-mode' (and this > >> > company-tabnine thingy) is initialized *after* the major-mode hook > >> > has run because usually, you activate minor-modes in major-mode > >> > hooks. In that case you would try to remove before the > >> > company-tabnine entry has been added to company-backends. > >> > > >> > That's all just guesswork since I don't use company. > >> > >> [...] > > > > I also tried the following snippet, but still failed: > > > > (defun hz/company-tabnine-remove-company-ispell () > > (make-local-variable 'company-backends) > > (cond > > ( > > (derived-mode-p 'emacs-lisp-mode) > > (setf (alist-get 'company-tabnine company-backends) > > (remove 'company-ispell (alist-get 'company-tabnine > > company-backends)))) > > ( > > t > > (setf (alist-get 'company-tabnine company-backends) > > (append (alist-get 'company-tabnine company-backends) > > '(company-ispell)))))) > > > > (add-hook 'emacs-startup-hook #'hz/company-tabnine-remove-company-ispell) > > The first cond clause looks good but I don't see why you need the > t-clause? Isn't the thing that company-ispell is part of the default > value of the company-tabnine entry of company-backends? If that's the > case, you want to make company-backends buffer-local and remove it in > emacs-lisp-mode and derived modes but there is no need to add it again > otherwise because the default value won't be altered. So that'd be: > > --8<---------------cut here---------------start------------->8--- > (defun hz/company-tabnine-remove-company-ispell () > (when (derived-mode-p 'emacs-lisp-mode) > (make-local-variable 'company-backends)) > (setf (alist-get 'company-tabnine company-backends) > (remove 'company-ispell > (alist-get 'company-tabnine company-backends)))) > --8<---------------cut here---------------end--------------->8--- A very strange result based on the above code is that it will remove company-ispell in all modes, say, LaTeX mode. But the following code works as expected: (defun hz/company-tabnine-remove-company-ispell () (when (derived-mode-p 'emacs-lisp-mode) (setq-local company-backends '((company-tabnine :separate company-capf company-dabbrev company-keywords company-files)) ))) > But most importantly, `emacs-startup-hook' is not the one you want. > That runs once after emacs has loaded the init file. I'm even not sure > what buffer is current then. I guess the most logical hook is > `company-mode-hook'. > > (add-hook 'company-mode-hook > #'hz/company-tabnine-remove-company-ispell) This works. Thank you for pointing this out. > Or maybe there is also some `company-tabnine-*-hook' that runs after > that package has done its setup in a buffer? Unfortunately, it doesn't supply these type hooks. HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-28 4:14 ` Hongyi Zhao @ 2021-10-28 4:36 ` Hongyi Zhao 2021-10-28 5:40 ` Hongyi Zhao 1 sibling, 0 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-28 4:36 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs, Stefan Monnier On Thu, Oct 28, 2021 at 12:14 PM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Thu, Oct 28, 2021 at 2:52 AM Tassilo Horn <tsdh@gnu.org> wrote: > > > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > > >> > However, I can imagine that you might not be able to use it in > > >> > major-mode hooks such as `emacs-lisp-mode' due to ordering issues, > > >> > i.e., I can easily imagine that `company-mode' (and this > > >> > company-tabnine thingy) is initialized *after* the major-mode hook > > >> > has run because usually, you activate minor-modes in major-mode > > >> > hooks. In that case you would try to remove before the > > >> > company-tabnine entry has been added to company-backends. > > >> > > > >> > That's all just guesswork since I don't use company. > > >> > > >> [...] > > > > > > I also tried the following snippet, but still failed: > > > > > > (defun hz/company-tabnine-remove-company-ispell () > > > (make-local-variable 'company-backends) > > > (cond > > > ( > > > (derived-mode-p 'emacs-lisp-mode) > > > (setf (alist-get 'company-tabnine company-backends) > > > (remove 'company-ispell (alist-get 'company-tabnine > > > company-backends)))) > > > ( > > > t > > > (setf (alist-get 'company-tabnine company-backends) > > > (append (alist-get 'company-tabnine company-backends) > > > '(company-ispell)))))) > > > > > > (add-hook 'emacs-startup-hook #'hz/company-tabnine-remove-company-ispell) > > > > The first cond clause looks good but I don't see why you need the > > t-clause? Isn't the thing that company-ispell is part of the default > > value of the company-tabnine entry of company-backends? If that's the > > case, you want to make company-backends buffer-local and remove it in > > emacs-lisp-mode and derived modes but there is no need to add it again > > otherwise because the default value won't be altered. So that'd be: > > > > --8<---------------cut here---------------start------------->8--- > > (defun hz/company-tabnine-remove-company-ispell () > > (when (derived-mode-p 'emacs-lisp-mode) > > (make-local-variable 'company-backends)) > > (setf (alist-get 'company-tabnine company-backends) > > (remove 'company-ispell > > (alist-get 'company-tabnine company-backends)))) > > --8<---------------cut here---------------end--------------->8--- > > A very strange result based on the above code is that it will remove > company-ispell in all modes, say, LaTeX mode. But the following code > works as expected: > > (defun hz/company-tabnine-remove-company-ispell () > (when (derived-mode-p 'emacs-lisp-mode) > (setq-local company-backends > '((company-tabnine :separate company-capf company-dabbrev > company-keywords company-files)) > ))) > > > > But most importantly, `emacs-startup-hook' is not the one you want. > > That runs once after emacs has loaded the init file. I'm even not sure > > what buffer is current then. I guess the most logical hook is > > `company-mode-hook'. > > > > (add-hook 'company-mode-hook > > #'hz/company-tabnine-remove-company-ispell) > > This works. Thank you for pointing this out. The following one, which is based on the idea here [1], also works: (add-hook 'after-change-major-mode-hook #'hz/company-tabnine-remove-company-ispell) [1] https://github.com/hlissner/doom-emacs/blob/0869d28483b5d81b818b110af351fd5c4dc04dd9/modules/completion/company/config.el#L66 > > Or maybe there is also some `company-tabnine-*-hook' that runs after > > that package has done its setup in a buffer? > > Unfortunately, it doesn't supply these type hooks. > > HZ -- Assoc. Prof. Hongyi Zhao <hongyi.zhao@gmail.com> Theory and Simulation of Materials Hebei Vocational University of Technology and Engineering No. 473, Quannan West Street, Xindu District, Xingtai, Hebei province ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-28 4:14 ` Hongyi Zhao 2021-10-28 4:36 ` Hongyi Zhao @ 2021-10-28 5:40 ` Hongyi Zhao 1 sibling, 0 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-28 5:40 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs, Stefan Monnier On Thu, Oct 28, 2021 at 12:14 PM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Thu, Oct 28, 2021 at 2:52 AM Tassilo Horn <tsdh@gnu.org> wrote: > > > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > > >> > However, I can imagine that you might not be able to use it in > > >> > major-mode hooks such as `emacs-lisp-mode' due to ordering issues, > > >> > i.e., I can easily imagine that `company-mode' (and this > > >> > company-tabnine thingy) is initialized *after* the major-mode hook > > >> > has run because usually, you activate minor-modes in major-mode > > >> > hooks. In that case you would try to remove before the > > >> > company-tabnine entry has been added to company-backends. > > >> > > > >> > That's all just guesswork since I don't use company. > > >> > > >> [...] > > > > > > I also tried the following snippet, but still failed: > > > > > > (defun hz/company-tabnine-remove-company-ispell () > > > (make-local-variable 'company-backends) > > > (cond > > > ( > > > (derived-mode-p 'emacs-lisp-mode) > > > (setf (alist-get 'company-tabnine company-backends) > > > (remove 'company-ispell (alist-get 'company-tabnine > > > company-backends)))) > > > ( > > > t > > > (setf (alist-get 'company-tabnine company-backends) > > > (append (alist-get 'company-tabnine company-backends) > > > '(company-ispell)))))) > > > > > > (add-hook 'emacs-startup-hook #'hz/company-tabnine-remove-company-ispell) > > > > The first cond clause looks good but I don't see why you need the > > t-clause? Isn't the thing that company-ispell is part of the default > > value of the company-tabnine entry of company-backends? If that's the > > case, you want to make company-backends buffer-local and remove it in > > emacs-lisp-mode and derived modes but there is no need to add it again > > otherwise because the default value won't be altered. So that'd be: > > > > --8<---------------cut here---------------start------------->8--- > > (defun hz/company-tabnine-remove-company-ispell () > > (when (derived-mode-p 'emacs-lisp-mode) > > (make-local-variable 'company-backends)) > > (setf (alist-get 'company-tabnine company-backends) > > (remove 'company-ispell > > (alist-get 'company-tabnine company-backends)))) > > --8<---------------cut here---------------end--------------->8--- > > A very strange result based on the above code is that it will remove > company-ispell in all modes, say, LaTeX mode. But the following code > works as expected: > > (defun hz/company-tabnine-remove-company-ispell () > (when (derived-mode-p 'emacs-lisp-mode) > (setq-local company-backends > '((company-tabnine :separate company-capf company-dabbrev > company-keywords company-files)) > ))) I also obtained the following code snippet, which is extracted from doom-emacs [1] with slightly adjusting: ```emacs-lisp ;;;;; Some Emacs lisp code extracted from doom-emacs ;;;###autoload (defvar company-backend-alist '((text-mode (company-tabnine :separate company-ispell company-dabbrev company-yasnippet)) (prog-mode company-capf company-yasnippet) (conf-mode company-capf company-dabbrev-code company-yasnippet)) "An alist matching modes to company backends. The backends for any mode is built from this.") (defun doom-enlist (exp) "Return EXP wrapped in a list, or as-is if already a list." (declare (pure t) (side-effect-free t)) (if (proper-list-p exp) exp (list exp))) ;;;###autodef (defun set-company-backend (modes &rest backends) "Prepends BACKENDS (in order) to `company-backends' in MODES. MODES should be one symbol or a list of them, representing major or minor modes. This will overwrite backends for MODES on consecutive uses. If the car of BACKENDS is nil, unset the backends for MODES. Examples: (set-company-backend 'js2-mode 'company-tide 'company-yasnippet) (set-company-backend 'sh-mode '(company-shell :with company-yasnippet)) (set-company-backend '(c-mode c++-mode) '(:separate company-irony-c-headers company-irony)) (set-company-backend 'sh-mode nil) ; unsets backends for sh-mode" (declare (indent defun)) (dolist (mode (doom-enlist modes)) (if (null (car backends)) (setq company-backend-alist (delq (assq mode company-backend-alist) company-backend-alist)) (setf (alist-get mode company-backend-alist) backends)))) ;; ;;; Library (defun company--backends () (let (backends) (let ((mode major-mode) (modes (list major-mode))) (while (setq mode (get mode 'derived-mode-parent)) (push mode modes)) (dolist (mode modes) (dolist (backend (append (cdr (assq mode company-backend-alist)) (default-value 'company-backends))) (push backend backends))) (delete-dups (append (cl-loop for (mode . backends) in company-backend-alist if (or (eq major-mode mode) ; major modes (and (boundp mode) (symbol-value mode))) ; minor modes append backends) (nreverse backends)))))) ``` With the help of the above lisp code, the following configuration is enough for the question discussed here: ```emacs-lisp (use-package company-math) (use-package company-tabnine :hook (LaTeX-mode . (lambda () (setq-local company-backends (company--backends)) (add-to-list 'company-backends '(company-math-symbols-latex company-latex-commands)) )) (text-mode . (lambda () (add-to-list 'company-backends 'company-math-symbols-unicode)))) ``` But I've two problems with the above method: 1. When the `company--backends' command is used separately, as follows: (add-hook 'company-mode-hook (lambda () (setq-local company-backends (company--backends)) )) The `(setq-local company-backends (company--backends))` always put the default backends set in the `company-backend-alist' at the very beginning of the ultimate compand-backends result, which makes it difficult for me to set a higher priority for the company-backends added in other hooks. 2. The `set-company-backend' command can't prepend BACKENDS (in order) to `company-backends' in MODES, say, by the followng one: (set-company-backend 'LaTeX-mode 'company-math-symbols-latex 'company-latex-commands) [1] https://github.com/hlissner/doom-emacs/blob/develop/modules/completion/company/autoload.el > > > But most importantly, `emacs-startup-hook' is not the one you want. > > That runs once after emacs has loaded the init file. I'm even not sure > > what buffer is current then. I guess the most logical hook is > > `company-mode-hook'. > > > > (add-hook 'company-mode-hook > > #'hz/company-tabnine-remove-company-ispell) > > This works. Thank you for pointing this out. > > > Or maybe there is also some `company-tabnine-*-hook' that runs after > > that package has done its setup in a buffer? > > Unfortunately, it doesn't supply these type hooks. > > HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 8:15 ` Tassilo Horn 2021-10-26 9:26 ` Hongyi Zhao @ 2021-10-26 12:36 ` Stefan Monnier 2021-10-26 13:41 ` Hongyi Zhao 1 sibling, 1 reply; 26+ messages in thread From: Stefan Monnier @ 2021-10-26 12:36 UTC (permalink / raw) To: Tassilo Horn; +Cc: Hongyi Zhao, help-gnu-emacs Tassilo Horn [2021-10-26 10:15:29] wrote: > Hongyi Zhao <hongyi.zhao@gmail.com> writes: >> I tried with the following function: >> >> ```emacs-lisp >> (defun hz/scratch-init () >> (with-current-buffer "*scratch*" >> (make-local-variable 'company-backends) >> (setf (alist-get 'company-tabnine company-backends) >> (remove 'company-ispell (alist-get 'company-tabnine >> company-backends))) >> )) >> ``` >> >> The above method will set the correct company-backends when I'm on >> scratch buffer. But I also find that when I switch to other buffers, >> says, AUCTeX based LaTeX-mode, the company-backends settings still >> remains the same, > > You mean, the above function changes the value not only in *scratch* but > all buffers? That shouldn't happen, I'd say, as the function explicitly > makes `company-backends' buffer-local in *scratch* before modifying it. The `setf` above changes the data structure by side-effect. It does not change the variable itself. Stefan ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 12:36 ` Stefan Monnier @ 2021-10-26 13:41 ` Hongyi Zhao 0 siblings, 0 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 13:41 UTC (permalink / raw) To: Stefan Monnier; +Cc: help-gnu-emacs, Tassilo Horn On Tue, Oct 26, 2021 at 8:36 PM Stefan Monnier <monnier@iro.umontreal.ca> wrote: > > Tassilo Horn [2021-10-26 10:15:29] wrote: > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > >> I tried with the following function: > >> > >> ```emacs-lisp > >> (defun hz/scratch-init () > >> (with-current-buffer "*scratch*" > >> (make-local-variable 'company-backends) > >> (setf (alist-get 'company-tabnine company-backends) > >> (remove 'company-ispell (alist-get 'company-tabnine > >> company-backends))) > >> )) > >> ``` > >> > >> The above method will set the correct company-backends when I'm on > >> scratch buffer. But I also find that when I switch to other buffers, > >> says, AUCTeX based LaTeX-mode, the company-backends settings still > >> remains the same, > > > > You mean, the above function changes the value not only in *scratch* but > > all buffers? That shouldn't happen, I'd say, as the function explicitly > > makes `company-backends' buffer-local in *scratch* before modifying it. > > The `setf` above changes the data structure by side-effect. > It does not change the variable itself. How can I solve this problem to achieve the same effect as my original function? HZ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Add/remove an element into/from a cons. 2021-10-26 6:17 ` Hongyi Zhao 2021-10-26 6:22 ` Tassilo Horn @ 2021-10-26 6:22 ` Hongyi Zhao 1 sibling, 0 replies; 26+ messages in thread From: Hongyi Zhao @ 2021-10-26 6:22 UTC (permalink / raw) To: Tassilo Horn; +Cc: help-gnu-emacs On Tue, Oct 26, 2021 at 2:17 PM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Tue, Oct 26, 2021 at 2:09 PM Tassilo Horn <tsdh@gnu.org> wrote: > > > > Hongyi Zhao <hongyi.zhao@gmail.com> writes: > > > > >> > > How can I add/remove an element into/from a cons, taking the > > >> > > following one as an example: > > >> > > > > >> > > ```emacs-lisp > > >> > > (setq company-backends '((company-tabnine :separate company-capf > > >> > > company-dabbrev company-keywords company-files company-ispell))) > > >> > > ``` > > >> > > > > >> > > How can I remove `company-ispell` from and re-add it into the > > >> > > company-backends defined above? > > >> > > > >> > You can use `setf' with the place being the alist entry like this > > >> > (company-backends replaced with th/test in my example): > > >> > > > >> > --8<---------------cut here---------------start------------->8--- > > >> > (setq th/test '(( company-tabnine :separate company-capf company-dabbrev > > >> > company-keywords company-files company-ispell))) > > >> > > > >> > (let ((place (assoc 'company-tabnine th/test))) > > >> > (setf place (remove 'company-ispell place))) > > >> > --8<---------------cut here---------------end--------------->8--- > > >> > > >> Yes. It does the trick: > > >> > > >> `C-j' (setq th/test '((company-tabnine :separate company-capf company-dabbrev > > >> company-keywords company-ispell company-files))) > > >> > > >> ;; ((company-tabnine :separate company-capf company-dabbrev > > >> company-keywords company-ispell company-files)) > > >> > > >> > > >> `C-j' (setq th/test (let ((place (assoc 'company-tabnine th/test))) > > >> (setf place (remove 'company-ispell place)))) > > >> > > >> ;; (company-tabnine :separate company-capf company-dabbrev > > >> company-keywords company-files) > > >> > > >> But how to add it back to the alist? > > > > > > I mean: But how to add it back to its original position in the list? > > > > This would add it again as the last element: > > > > --8<---------------cut here---------------start------------->8--- > > (let ((place (assoc 'company-tabnine th/test))) > > (setf place (append place '(company-ispell)))) > > --8<---------------cut here---------------end--------------->8--- > > Thanks. But the push doesn't work: > > (let ((place (assoc 'company-tabnine th/test))) > (setf place (push place '(company-ispell)))) I also tried out the following method: `C-j' (let ((place (assoc 'company-tabnine th/test))) (setf place (push 'company-ispell place))) => ;; (company-ispell company-tabnine :separate company-capf company-dabbrev company-keywords company-files company-ispell) > Debugger entered--Lisp error: (wrong-number-of-arguments (lambda > (command &optional arg &rest ignored) "`company-mode' completion > backend using Ispell." (interactive (list 'interactive)) (cond ((eql > command 'interactive) (company-begin-backend 'company-ispell)) ((eql > command 'prefix) (if (company-ispell-available) (progn > (company-grab-word)))) ((eql command 'candidates) (let ((words > (company-ispell--lookup-words arg ...)) (completion-ignore-case t)) > (if (string= arg "") words (all-completions arg words)))) ((eql > command 'kind) 'text) ((eql command 'sorted) t) ((eql command > 'ignore-case) 'keep-prefix))) 0) > company-ispell() > (let* ((v (company-ispell))) (\(setf\ quote\) (cons place 'v) v)) > (setq place (let* ((v (company-ispell))) (\(setf\ quote\) (cons place 'v) v))) > (let ((place (assoc 'company-tabnine th/test))) (setq place (let* > ((v (company-ispell))) (\(setf\ quote\) (cons place 'v) v)))) > (progn (let ((place (assoc 'company-tabnine th/test))) (setq place > (let* ((v (company-ispell))) (\(setf\ quote\) (cons place 'v) v))))) > elisp--eval-last-sexp(nil) > eval-last-sexp(nil) > funcall-interactively(eval-last-sexp nil) > command-execute(eval-last-sexp) > > HZ -- Assoc. Prof. Hongyi Zhao <hongyi.zhao@gmail.com> Theory and Simulation of Materials Hebei Vocational University of Technology and Engineering No. 473, Quannan West Street, Xindu District, Xingtai, Hebei province ^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2021-10-28 5:40 UTC | newest] Thread overview: 26+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-10-26 2:05 Add/remove an element into/from a cons Hongyi Zhao 2021-10-26 4:57 ` Tassilo Horn 2021-10-26 5:40 ` Hongyi Zhao 2021-10-26 5:42 ` Hongyi Zhao 2021-10-26 6:07 ` Hongyi Zhao 2021-10-26 6:18 ` Tassilo Horn 2021-10-26 6:30 ` Hongyi Zhao 2021-10-26 6:39 ` Hongyi Zhao 2021-10-26 6:08 ` Tassilo Horn 2021-10-26 6:17 ` Hongyi Zhao 2021-10-26 6:22 ` Tassilo Horn 2021-10-26 8:12 ` Hongyi Zhao 2021-10-26 8:15 ` Tassilo Horn 2021-10-26 9:26 ` Hongyi Zhao 2021-10-26 9:31 ` Hongyi Zhao 2021-10-26 18:56 ` Tassilo Horn 2021-10-27 1:39 ` Hongyi Zhao 2021-10-27 4:54 ` Hongyi Zhao 2021-10-27 5:13 ` Hongyi Zhao 2021-10-27 18:43 ` Tassilo Horn 2021-10-28 4:14 ` Hongyi Zhao 2021-10-28 4:36 ` Hongyi Zhao 2021-10-28 5:40 ` Hongyi Zhao 2021-10-26 12:36 ` Stefan Monnier 2021-10-26 13:41 ` Hongyi Zhao 2021-10-26 6:22 ` Hongyi Zhao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).