;;; moy-compilation-schedule-execute.el --- Schedule a command to execute at the end of compilation ;; Copyright (C) 2004 Matthieu MOY ;; Author: Matthieu Moy ;; Keywords: convenience, processes, terminals ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; Adds the notion of `compilation-end-hook-once' : A list of functions ;; that will be executed once (and then removed from the hook) at the ;; end of the running compilation. ;; ;; The main commands are ;; `moy-compilation-schedule-execute-in-{shell,eshell,ansi-term,gud}', ;; that are equivalent to pressing RET in the corresponding mode if no ;; compilation is running, or that simulate a RET just after the end ;; of compilation. ;; ;; Typical use : ;; You are developping a programm named "program_name". Edit the ;; source, then, compile with ;; M-x compile ;; Now, go to the shell buffer (I suggest you use shell-toggle for ;; that). Now, type in the shell ;; ./program_name ;; And ;; M-x moy-compilation-schedule-execute-in-shell RET (Or the key you ;; decided to bind it to ...) ;; Go to dring a coffee ;-) ;; When you come back, the compilation is over in the compilation ;; buffer, and the program has been ran. ;; ;; I personnally bind it to C-M-RET, and I have "M-x recompile" bound ;; to f9, and shell-toggle bound to f11, so I just type ;; f9 f11 C-M-RET ;; To compile and execute my programs. ;; I would add that I have a patched version of shell toggle ;; http://www-verimag.imag.fr/~moy/emacs/shell-toggle-patched.el ;; That allows to toggle to a *gud* buffer too. ;; So, after ;; C-x b *gud* RET M-x shell-toggle-this-is-the-shell-buffer RET ;; Once, I can type ;; f9 f11 r C-M-RET ;; to compile and debug my programs. ;;; Changelog ;; ;; Version 1.0 : January 10, 2004 ;; - Support for ansi-term, shell, eshell and gud simulation of RET at ;; the end of compilation. ;; ;; Version 1.1 : January 17, 2004 ;; - compilation-end-hook-once : Hook run once only, ;; compilation-end-hook : hook ran at the end of each compilation. ;; ;; Version 1.2 : February 10, 2004 ;; - added the function add-hook-once. Compilation-end-hook-once is ;; now deprecated. ;; - Use of compilation-finish-functions instead of a defadvice. The ;; advice is now disabled by default. ;;; Code: (require 'compile) ;;; Shell (defun moy-execute-in-ansi-term (buffer) (switch-to-buffer buffer) (term-send-raw-string "\n") ) ;;;###autoload (defun moy-compilation-schedule-execute-in-ansi-term () "Command designed to be mapped to a key in term mode (more precisely in char mode). If no compilation is running, this is equivalent to pressing RET. If a compilation is running, then at the end of the compilation, a RET will be simulated. This is very usefull when you want to execute in a shell the program you are compiling." (interactive) (moy-compilation-schedule-execute 'moy-execute-in-ansi-term)) ;;; EShell (defun moy-execute-in-eshell (buffer) (switch-to-buffer buffer) (eshell-send-input) ) ;;;###autoload (defun moy-compilation-schedule-execute-in-eshell () "Command designed to be mapped to a key in eshell mode. If no compilation is running, this is equivalent to pressing RET. If a compilation is running, then at the end of the compilation, a RET will be simulated. This is very usefull when you want to execute in a eshell the program you are compiling." (interactive) (moy-compilation-schedule-execute 'moy-execute-in-eshell)) ;;; Traditional "shell" mode (defun moy-execute-in-shell (buffer) (switch-to-buffer buffer) (comint-send-input) ) ;;;###autoload (defun moy-compilation-schedule-execute-in-shell () "Command designed to be mapped to a key in shell mode. If no compilation is running, this is equivalent to pressing RET. If a compilation is running, then at the end of the compilation, a RET will be simulated. This is very usefull when you want to execute in a shell the program you are compiling." (interactive) (moy-compilation-schedule-execute 'moy-execute-in-shell)) ;;; gud (defun moy-execute-in-gud (buffer) (switch-to-buffer buffer) (end-of-buffer) (comint-send-input) ) ;;;###autoload (defun moy-compilation-schedule-execute-in-gud () "Command designed to be mapped to a key in gud mode. If no compilation is running, this is equivalent to pressing RET. If a compilation is running, then at the end of the compilation, a RET will be simulated. This is very usefull when you want to debug the program you are compiling." (interactive) (moy-compilation-schedule-execute 'moy-execute-in-gud)) (defun moy-compilation-add-finish-functions-once (hook function) "Same as `add-hook', but FUN is only run once. Also contrary to `add-hook', this is not idempotent." ;; FIXME: need to check if `function' was already added to the hook. (let ((code (list 'lambda))) (setcdr code `((buffer string) ; arguments (,function) ; body (remove-hook ',hook ',code))) (add-hook hook code))) ;;;###autoload (defun moy-compilation-schedule-execute (function) "Schedules the execution of the function given as an argument for the end of the current compilation process. If no compilation is runnging, execute the command right now. `function' should take one argument, which is the buffer from which this function is called." (if compilation-in-progress (let ((func `(lambda () (,function ,(current-buffer))))) (moy-compilation-add-finish-functions-once 'compilation-finish-functions func)) (funcall function (current-buffer)))) (defvar compilation-end-hook-once nil "Deprecated. use add-hook-once instead.") ;;;###autoload (defvar compilation-end-hook nil) ; Disabled by default. (defadvice compilation-handle-exit (after compilation-end-advice) (run-hooks 'compilation-end-hook) (mapcar '(lambda (x) (funcall x) (remove-hook 'compilation-end-hook-once x)) compilation-end-hook-once)) (provide 'moy-compilation-schedule-execute) ;;; moy-compilation-schedule-execute.el ends here