15
votes

As an Emacs beginner, I am working on writing a minor mode. My current (naive) method of programming elisp consists of making a change, closing out Emacs, restarting Emacs, and observing the change. How can I streamline this process? Is there a command to refresh everything?

6

6 Answers

17
votes

You might try using M-C-x (eval-defun), which will re-evaluate the top-level form around point. Unlike M-x eval-buffer or C-x C-e (exal-last-sexp), this will reset variables declared with defvar and defcustom to their initial values, which might be what's tripping you up.

3
votes

Also try out C-u C-M-x which evaluates the definition at point and sets a breakpoint there, so you get dropped into the debugger when you hit that function.

M-x ielm is also very useful as a more feature-rich Lisp REPL when developing Emacs code.

2
votes

M-x eval-buffer should do it.

2
votes

What Sean said. In addition, I have (eval-defun) bound to a key, along with a test. The development loop then becomes: 1) edit function, 2) press eval-and-test key, 3) observe results, 4) repeat. This is extremely fast.

During development I write a test, bind it to jmc-test, then use the above key to run it on my just-edited function. I edit more, then press key again, testing it again. When the function works, I zap jmc-test, edit another function, and write another jmc-test function. They're nearly always one line of code, so easy to just bang out.

(defun jmc-eval-and-test ()
  (interactive)
  (eval-defun nil)
  (jmc-test))
(define-key emacs-lisp-mode-map (kbd "<kp-enter>")  'jmc-eval-and-test)

(when t
  (defun myfunc (beer yum)
    (+ beer yum))
  (defun jmc-test () (message "out: %s" (myfunc 1 2))))

When editing "myfunc", if I hit keypad enter, it prints "out: 3".

1
votes

It all depends on what you're writing and how you've written it. Toggling the mode should get you the new behavior. If you're using [define-minor-mode][1], you can add code in the body of the macro that keys off the mode variable:

(define-minor-mode my-minor-mode 
  "doc string"
  nil
  ""
  nil
  (if my-minor-mode
      (progn
         ;; do something when minor mode is on
      )
    ;; do something when minor mode is off
    )

But, another way to check it quickly would be to spawn a new Emacs from your existing one:

M-x shell-command emacs&
0
votes

I just define a function called ldf (short for load-file) in my .emacs file, like this:

(defun ldf (arg) (interactive "P") (load-file (buffer-file-name)))

As you can see, this little function looks up the filename of the current buffer and then loads the file. Whenever I need to reload the current buffer elisp file, just type "M-x ldf"