15

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?

davidscolgan
  • 7,508
  • 9
  • 59
  • 78

6 Answers6

17

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.

Alan W. Smith
  • 24,647
  • 4
  • 70
  • 96
Sean
  • 29,130
  • 4
  • 80
  • 105
3

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.

Joakim Hårsman
  • 1,824
  • 13
  • 14
2

M-x eval-buffer should do it.

Greg
  • 1,053
  • 7
  • 8
  • Eval-buffer reevaluates the code, but the minor mode's behavior does not seem to be updated, even if I turn it off and on again. Is there a command I can use in combination with this one to reload the minor mode? – davidscolgan Oct 26 '10 at 02:38
  • Well, I assumed that minor modes worked similar to .emacs file modifications, but I'm clearly wrong. My next guess was that the .emacs would also have to be refreshed- no dice. Guess we'll both need to wait for someone who knows what they're talking about to swing by. Sorry for the wrong attempt. – Greg Oct 26 '10 at 03:05
2

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".

johntellsall
  • 14,394
  • 4
  • 46
  • 40
1

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&
Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
0

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"

reikred
  • 151
  • 7