Reputation: 20342
Here's the use case: I read an articles on tech blogs about C++ (fails of multiple inheritance this and multi-threading that etc.:). Usually they come with some code. It's almost always one file and I almost always want to run it and play around with it.
I want to do it with Emacs and I want to do it FAST, as in with the least (or reasonably few) keystrokes.
So suppose I've already created a multiple_inheritance.cc
file in its own folder
and pasted the code. How do I get to an executable really fast?
Here's what I'm doing now (hopefully someone will improve it.)
(defun cpp-generate-makefile ()
(interactive)
(let* ((n-buffer (buffer-file-name))
(n-file (file-name-nondirectory n-buffer))
(n-target (file-name-sans-extension n-file))
(n-makefile (concat (file-name-directory n-buffer) "Makefile")))
(if (file-exists-p n-makefile)
(when (called-interactively-p 'any)
(message "Makefile already exists"))
(with-current-buffer (find-file-noselect n-makefile)
(insert
(concat n-target ": " n-file
"\n\tg++ -g -O2 -std=c++0x -o $@ $^\n\n"
"clean: \n\trm -f " n-target "\n"))
(save-buffer)))))
(defun cpp-run ()
(interactive)
(save-buffer)
(cpp-generate-makefile)
(compile "make"))
(add-hook 'c++-mode-hook
(lambda()
;; ...
(define-key c++-mode-map [f5] 'cpp-run)))
Here's a few things that SLOW me down currently:
compile
asks if I want to save any open files that are totally unrelated to C++.*compilation*
buffer in case there was an error.
I've looked into compile.el
, which has compilation-num-errors-found
defined,
but that variable isn't used anywhere in that file.term
and run the program?Upvotes: 4
Views: 1276
Reputation: 20342
I've updated the code I had to add a run
target to Makefile
.
I've also added an extension to C:
(defvar cpp-generate-compiler "g++ -g -O2 -std=c++0x")
(defun cpp-generate-makefile ()
(interactive)
(let* ((n-buffer (buffer-file-name))
(n-file (file-name-nondirectory n-buffer))
(n-target (file-name-sans-extension n-file))
(n-makefile (concat
(file-name-directory n-buffer)
"Makefile")))
(if (file-exists-p n-makefile)
(when (called-interactively-p 'any)
(message "Makefile already exists"))
(with-current-buffer (find-file-noselect n-makefile)
(insert
(concat n-target ": " n-file
(format "\n\t%s -o $@ $^"
cpp-generate-compiler)
"\n\nclean: \n\trm -f " n-target
"\n\nrun: " n-target "\n\t ./" n-target
"\n\n.PHONY: clean run\n"))
(save-buffer)))))
(defun cpp-run ()
(interactive)
(save-buffer)
(cpp-generate-makefile)
(compile "make run"))
(defun c-run ()
(interactive)
(let ((cpp-generate-compiler "gcc -g -O2 -std=c99"))
(cpp-run)))
(add-hook 'c++-mode-hook
(lambda()
;; ...
(define-key c++-mode-map [f5] 'cpp-run)))
(add-hook 'c-mode-hook
(lambda()
;; ...
(define-key c-mode-map [f5] 'c-run)))
(setq compilation-ask-about-save nil)
(setq compilation-finish-functions
(list (lambda(buffer str)
(unless (string= str "finished\n")
(push-mark)
(next-error)))))
With (setq compilation-ask-about-save nil)
there's no more
warnings about saving (cpp-run
saves automatically).
And I just have to remember that M-g n and M-g p navigate the errors.
Now my process is neary optimal: one key from source to result in case there are no errors.
In case there are errors, it's an extra M-g n.
Now, if only there was a way for compile
to call (push-mark)(next-error)
...
Thanks to suggestion of @juanleon, this is solved with:
(setq compilation-finish-functions
(list (lambda(buffer str)
(unless (string= str "finished\n")
(push-mark)
(next-error)))))
But for some reason, push-mark
doesn't work properly in this case.
Upvotes: 0
Reputation: 4553
To sum up the answers in the comments.
compilation-ask-about-save
. If you don't want to change this globally (with setq) you can change it just inside your function by wrapping it in a (let ((compilation-ask-about-save nil)) ...function contents...)
statement. (define-key c++-mode-map "\M-j" 'next-error)
. I personally use global-set-key for this, just because it's useful in a whole bunch of modes. (compile "make && ./a.out")
(using the name of your executable of course). Hope this helps.
Upvotes: 2