2

I asked How can I script emacs to install packages from list? and got this answer.

(setq package-selected-packages
      '(async
        epl
        evil
        goto-chg
        helm
        helm-ag
        helm-core
        helm-descbinds
        helm-projectile
        pkg-info
        popup
        projectile
        undo-tree))
(package-install-selected-packages)

When I inspect the value of the variable package-activated-list in my installation the output is (evil goto-chg undo-tree goto-chg helm-ag helm helm-core async popup async helm-descbinds helm helm-core async popup async helm-projectile projectile pkg-info epl helm helm-core async popup async popup projectile pkg-info epl undo-tree)

How could I insert the literal output of package-activated-list into the buffer, after the quote. ie generate the script

(setq package-selected-packages
      '
      ;;<<list of  `package-activated-list` goes here >>
      )
(package-install-selected-packages)

It would be better with duplicates removed and sorted, but those are secondary issues.

vfclists
  • 1,347
  • 1
  • 11
  • 28
  • I don't understand the question. You want to generate `(setq package-selected-packages '(async … undo-tree))`, right? Do you want to generate just this snippet or a function? If a function, what arguments should it take? And most importantly, what input does the generator take? – Gilles 'SO- stop being evil' Jul 16 '17 at 08:48
  • You seem to be dead-set on using quote. Is there a reason why just not quoting the variable won't work for you? – wasamasa Jul 16 '17 at 09:01
  • @Gilles I am now learning both emacs and elisp so generating it as function and generating it as snippet are both of interest to me, but my original aim is to generate it as a function, meaning it would involve a call to a function which takes the text template of `setq(...` with a placeholder for whatever variable is involved, which is `package-activated-list` and a function to deduplicate and sort its output. – vfclists Jul 16 '17 at 10:31
  • @wasamasa As an emacs and elisp newbie both methods and when and where they are appropriate are of interest to me. – vfclists Jul 16 '17 at 10:33
  • @wasamasa `(setq package-selected-packages package-activated-list)` won't work for duplicating `package-activated-list` from one instance of emacs to the init file for setting up emacs on a different machine (as explained in the linked-to question). – Peder Klingenberg Jul 16 '17 at 19:26
  • @vfclists `setq` with an unquoted value sets your variable to the result of evaluating the value. `(setq foo `(a b c)) (setq bar foo)` sets both `foo` and `bar` to the list `(a b c)`, because `foo` in the second form evaluates to the list you set it to in the first form. In your usecase (if I understand it correctly), `package-activated-list` on the second machine presumably has the wrong value initially, that would be why you want to set `package-selected-packages`. Then you need the quoted variant. – Peder Klingenberg Jul 16 '17 at 19:36
  • The question I am asking is answered by Peder's first answer, at 9:09. I am still not familiar with emacs and elisp to express myself properly. I hope that clarifies it. His second answer covers the task I was trying to accomplish that needed the subject of the question. I hope this clears it up. – vfclists Jul 26 '17 at 07:49
  • I have updated the title to reflect my original intent and it has also been answered satisfactory, so I think the hold can be removed now. – vfclists Jul 27 '17 at 06:30
  • @Dan: Closing this question as unclear is silly, I didn't think it was unclear when I answered it, and my answer was accepted. Please reopen. (Seems I can only notify one user, I wanted to notify Stefan and Drew as well.) – Peder Klingenberg Jul 28 '17 at 21:39
  • @PederKlingenberg: feel free to vote to reopen the question: it needs 5 votes. I still don't understand the question, but that can be overruled if enough users want to reopen it. – Dan Jul 28 '17 at 21:44
  • @Dan I don't have enough rep on the this site to vote on close/reopen. :( – Peder Klingenberg Jul 28 '17 at 21:53
  • @Dan I have changed the title of the question to explain precisely what I meant. The question may have been long winded because I did not know the right lingo to express what I wanted, and had to use an example to clarify it, but it is quite clear as it stands now. Peder's additional answer may be causing some confusion as it has a higher score, but perhaps more upvotes on the answer will clarify the intent of the question. – vfclists Jul 29 '17 at 03:55
  • Now that you have clarified the question, in particular by giving it a good title, it seems to be a [duplicate of this question](https://emacs.stackexchange.com/q/7481/105), so it should be closed for that reason. It's a good question, and it has been posed several times (several duplicates have therefore been closed). – Drew Jul 29 '17 at 05:19

3 Answers3

4

If you're writing a script interactively, and want to insert the current value of package-activated-list into that script, you can do that with C-0 M-: package-activated-list RET. Alternatively, if you have the text package-activated-list in your buffer, you can put the point just after it and press C-0 C-x C-e to have the contents of the variable inserted at point. In that case, the original variable name remains, so you may want to remove that afterwards.

If you want transform the value of the variable, you can use any Lisp expression at the M-: prompt, e.g.

M-0 M-: (sort package-activated-list #'string<) RET
  • Second issue: `sort` takes two arguments. Using `(sort package-activated-list #'string<)` works. – Omar Jul 30 '17 at 18:13
  • True, thanks. Fixed, though I didn't introduce the error. @Gilles - if you're going to add information to other people's answers, at least do it right, please. – Peder Klingenberg Jul 31 '17 at 08:02
2

I don't see the big practical use in this, but you could make a function returning the setq form:

(defun generate-setq-form-function (variable value)
  `(setq ,variable 
         ',(sort (delete-dups (copy-tree value))
                 #'(lambda (x y)
                     (string< (symbol-name x) (symbol-name y))))))

This would be called like so:

(generate-setq-form-function 'package-selected-packages package-activated-list) 

If the quote bothers you, you could even wrap it in a macro:

(defmacro generate-setq-form-macro (variable value)
  `(generate-setq-form-function ',variable ,value))

To be called like so:

(generate-setq-form-macro package-selected-packages package-activated-list)

The trouble is that you would still need to evaluate this on the computer with the correct package-activated-list and insert the result in a file if you want it to replicate the list on another computer. So you need to use C-0 M-: and evaluate the call, like in my other answer.

Alternatively, you could mess around with (interactive) declarations and prompts, but this already seems like overkill to me.

  • When I try to enter `C-0 M-:` the character `0` is inserted into the buffer, ie the scratch buffer. Could there be some fault in my keyboard setup, or is the key not configured by `define-key` or one of the other keyboard settings? – vfclists Jul 18 '17 at 00:33
  • `C-0` is supposed to give you a zero prefix argument to a command. It's just a shortcut for `C-u 0`, so you can try that instead. Numeric prefix arguments are common enough that they have lots of alternative standard bindings. `ESC 0` is another one. – Peder Klingenberg Jul 18 '17 at 16:20
  • @vfclists Further to [Peder's comment](https://emacs.stackexchange.com/questions/34205/how-do-you-insert-the-value-of-a-variable-at-the-cursor-position-point-when-edit#comment53012_34215), note that `M-0` is the same as `C-0`, but there is no need for a zero prefix argument - any non-negative one will do, so you can also try `C-u M-:`. See the Emacs Manual node on [Numeric Arguments](https://www.gnu.org/software/emacs/manual/html_node/emacs/Arguments.html) for more information. – Basil Jul 28 '17 at 05:39
  • @Basil The difference between a `C-0` and `C-u` is that with a non-zero argument to either `M-:` or `C-x C-e`, the inserted value is possibly truncated, subject to `eval-expression-print-length` and `eval-expression-print-level`. So in this case there is in fact a need for the zero argument. – Peder Klingenberg Jul 28 '17 at 20:20
  • @PederKlingenberg Right you are; I misread the docstring. Sorry about the confusion. – Basil Jul 28 '17 at 23:29
2

You can use M-: (insert (format "%s" package-activated-list)).

Omar
  • 4,732
  • 1
  • 17
  • 32