use-package’s :config vs. :init

I read this Reddit thread about favorite themes, and got intrigued by the spacemacs theme1.

I added that theme to my init file, and tried making it the default theme. I use use-package, and configured the theme as follows:

(use-package spacemacs-theme
:ensure t
:config
(load-theme 'spacemacs-light t)
)

When re-evaluating my init file, the theme didn’t load. I tried to run only the (load-theme 'spacemacs-light t) line, and the theme loaded. I changed the :config to :init in the package configuration, and it loaded when I re-loaded emacs.

What, then, is the difference between :init and :config in use-package?

The answer to that question, which I found it in this stack-overflow answer, is that in use-package, whatever defined inside the :init keyword, will load whenever emacs is loading. What’s in the :config, though, will be executed only when the package is actually loaded (i.e lazy loading)2.

Here’s how my configuration for that theme looks like now:

(use-package spacemacs-theme
:ensure t
:init
(load-theme 'spacemacs-light t)
)

Footnotes:

1

I tried spacemacs before, and liked its look and feel, but didn’t know I can take it back with me to gnu emacs

2

Needless to say that, going back to the use-package documentation, the difference between :init and :config is clearly described…

Elisp Video Tutorial – Notes

I’ve just finished watching Daniel Gopar’s elisp video tutorial. So far there are 4 parts to the tutorial, and based on this thread on Reddit, there are more to come.

After watching the guide I don’t feel more proficient in elisp, yet less timid running evals and more courageous tinkering with my config file.

Following is a short summary of the code exercises and shortcuts I logged while watching.

Part 1 – Intro

Link to episode 1

REPL – read-eval-print-loop

Define functions:

(defun add-num (a b) (+ a b))

Define a test:

(require 'ert)
(ert-deftest add-num-pos ()
         (should
         (equal (add-num 10 10) 20)))

To run the test that I’ve just created: M-x ert-run-tests-interactively

Choose the test I would like to run (in this case “pos-add-num”)

Part 2 – Create A Simple Function And A Test Of That Function

Link to episode 2

setq to set variables and lists (setq my-list '(1 2 3))

add-to-list to add element (add-to-list 'my-list 4)

Another way to add to list, but this time to a copy of the list: (cons 5 my-list) – this will return (5 1 2 3 4) But when inquiring my-list, we will get (1 2 3 4)

car returns the first element in every list (car my-list) -> 1

cdr returns everything from a list, after the first element (crd my-list) -> (2 3 4)

nth return a certain element in the list (nth 4 my-list) -> 3

member check for a certain value in a list, and return the elements in that list from that value on (member 3 my-list) -> (3 4) (member 7 my-list) -> nil

Part 3 – Looping And Local Variables

Link to episode 3

Use the scratch buffer, so I can write in multiple lines

C-x C-e to evaluate code. Point needs to be at the end of the code in order to get evaluated.

Looping through variables:

let to create a local variable

when and if – what they suppose to do…

If there is more than one statement in the if statement, need to use to wrap those lines with progn. There is no such limitation in the else statement.

Part 4 – Interactive Functions

Link to episode 4

Created a function to count words, plus the test for it.

(defun cheap-count-words()
  (interactive)
  (let ((words 0))
    (save-excursion
      (goto-char (point-min))
    (while (forward-word)
      (setq words (1+ words)) ))
    (message (format "Words in Buffer: %s" words))words))



;; Tests
(require 'ert)

(ert-deftest count-words-test ()
  (get-buffer-create "*test*")
  (with-current-buffer "*test*"
    (erase-buffer)
    (insert "Hello world")
    (should (=(cheap-count-words) 2)))
  (kill-buffer "*test*"))