;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; File: unix.el ;; ;; Author: Wolfgang S. Rupprecht ;; ;; Created: Wed Jan 20 12:24:16 EST 1988 ;; ;; Contents: some useful unix interface routines for gnu emacs ;; ;; ;; ;; Copyright (c) 1988 Wolfgang S. Rupprecht. ;; ;; ;; ;; $Log$ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; hacked for fsf v.19 ;; Copyright (c) 1988 Wolfgang S. Rupprecht ;; GNU Emacs and this file unix.el, are distributed in the hope ;; that they will be useful, but WITHOUT ANY WARRANTY. No author or ;; distributor accepts responsibility to anyone for the consequences of ;; using them or for whether they serve any particular purpose or work at ;; all, unless he says so in writing. Refer to the GNU Emacs General ;; Public License for full details. ;; Everyone is granted permission to copy, modify and redistribute GNU ;; Emacs and unix.el, but only under the conditions described in the ;; GNU Emacs General Public License. A copy of this license is supposed ;; to have been given to you along with GNU Emacs so you can know your ;; rights and responsibilities. It should be in a file named COPYING. ;; Among other things, the copyright notice and this notice must be ;; preserved on all copies. (autoload 'compile-internal "compile") (defvar lint-flags "-abhx" "*Flags to pass to lint(1).") (defun lint (buffer) "Run lint(1) on specified buffer and collect output in a buffer. While lint runs asynchronously, you can use the \\[next-error] command to find the text that lint gripes refer to." (interactive "bbuffer to lint ") (save-excursion (switch-to-buffer buffer t) (save-buffer buffer) (compile-internal (concat "lint " lint-flags " " buffer-file-name) "No more lint gripes" "lint"))) (defvar k&r-indent-flags "-nbad -bap -nbbb -nbc -br -c33 -cd33 -ncdb -ce -ci4 -cli0 -d0 -di1 -nfc1 -i4 -ip0 -l75 -lp -npcs -npsl -nsc -nsob -nfca -cp33 -nss") (defvar bsd-indent-flags "-nbap -nbad -nbbb -bc -br -c33 -cd33 -cdb -ce -ci4 -cli0 -d4 -di16 -fc1 -i4 -ip4 -l75 -lp -npcs -psl -sc -nsob -fca -cp33 -nss") (defvar gnu-indent-flags "-nbad -bap -nbbb -nbc -bl -c33 -cd33 -ncdb -nce -di0 -nfc1 -i2 -ip5 -lp -pcs -psl -nsc -nsob -bli2 -ss -cp1 -nfca -cli0") (defvar gm-indent-flags "-nbad -bap -nbbb -bc -br -c33 -cd33 -cdb -ce -ci4 -cli0 -d0 -di16 -nfc1 -i4 -ip0 -l75 -lp -npcs -psl -sc -nsob") (defvar cindent-flags nil ;; "-nbad -bap -nbbb -bc -bl -c33 -cd33 -ncdb -nce -di16 -nfc1 -i4 -ip5 -lp -pcs -psl -nsc -nsob -bli2 -cp1 -cli0" "*Flags to pass to indent(1).") (defun gm-indent (buffer) "GM style: Reformat the specified BUFFER using the Unix indent(1) program. Selects the specified buffer, and saves it to disk, displays new version. M-x revert-buffer and M-x undo work as expected. User may opt not to save the newly indented buffer." (interactive "bbuffer to gm-indent ") (let ((cindent-flags gm-indent-flags)) (cindent buffer) ;; now fix up the things that indent can't do (gm-fix-func-decl) (gm-fix-multi-line-if) (gm-fix-labels) )) (defun gm-fix-func-decl () "Force 4 spaces in front of func variable defines and re-adjust intersymbol spacing." (save-excursion (goto-char (point-min)) (while (re-search-forward "^\\(\\s_\\|\\sw\\)+[ \t]*(" nil t) (if (not (looking-at "[ \t]*)?[ \t]*\n")) (insert "\n") (forward-line 1)) (while (not (looking-at "^{")) (delete-horizontal-space) (insert " ") ;; must watch out for multi-adjective decls, ;; eg "long int foo" or "struct bar foo" (re-search-forward "\n*[,)]") (backward-char 1) (backward-sexp) ;; fix up "function(int * foo)" to be ;; "function( ;; int *foo)" (while (= (preceding-char) ? ) (delete-char -1)) (if (= (preceding-char) ?*) nil (insert " ")) (let ((stars 0)) (while (= (preceding-char) ?*) (setq stars (1+ stars)) (backward-char 1)) (delete-horizontal-space) (indent-to (- 20 stars) 1) ; 20: 4 initial spaces ;; plus 16 spaces for variable names ;; a minimun of one space gets added ) (forward-line 1))))) (defun gm-fix-multi-line-if () "Back up the indentation of multiline if's." ;; write this ) (defun gm-fix-labels () "Back up the indentation of labels one notch." ;; write this ) (defun cindent (buffer) "Reformat the specified BUFFER using the Unix indent(1) program. Selects the specified buffer, and saves it to disk, displays new version. M-x revert-buffer and M-x undo work as expected. User may opt not to save the newly indented buffer." (interactive "bbuffer to indent ") (switch-to-buffer buffer) (let ((auto-save-file-name (make-auto-save-file-name)) (opoint (point)) ;; /bin/csh doesn't work for the following line due to '#' being a ;; comment-start char. 'indent /tmp/foo.c /tmp/#foo.c#' ;; best just to use the /bin/sh as the shell. (shell-file-name "/bin/sh")) ; shell-command uses shell-file-name (save-buffer) (shell-command (concat "indent " cindent-flags " " buffer-file-name " " auto-save-file-name) nil) (if (file-exists-p auto-save-file-name) (progn (erase-buffer) (insert-file auto-save-file-name) (goto-char (min opoint (point-max)))) (error "indent failed to produce the output file")))) (defun unifdef (buffer args) "Remove ifdefs in the specified BUFFER using the Unix unifdef(1) program. Selects the specified buffer, and saves it to disk, displays new version. M-x revert-buffer and M-x undo work as expected. User may opt not to save the newly unifdeffed buffer." (interactive "bbuffer to unifdef: \nsArgs to unifdef: ") (switch-to-buffer buffer) (let ((auto-save-file-name (make-auto-save-file-name)) (opoint (point)) ;; /bin/csh doesn't work for the following line due to '#' beeing a ;; comment-start char. 'indent /tmp/foo.c /tmp/#foo.c#' ;; best just to use the /bin/sh as the shell. (shell-file-name "/bin/sh")) ; shell-command uses shell-file-name (save-buffer) (shell-command (concat "unifdef " args " " buffer-file-name " > " auto-save-file-name) nil) (if (and (file-exists-p auto-save-file-name) (< 0 (nth 7 (file-attributes auto-save-file-name)))) ; filesize > 0 (progn (erase-buffer) (insert-file auto-save-file-name) (goto-char (min opoint (point-max)))) (error "unifdef failed to produce the output file")))) (defun diff (buf &optional nocontext) "Take the diff(1) of a BUFFER and its oldest backup file. With prefix arg, (or optional flag if noninteractive) does an normal non-context diff. This option is required for \\[show-diff]." (interactive "bBuffer: \nP") (switch-to-buffer buf) (let* ((file-base-name (file-name-nondirectory buffer-file-name)) (back-list (file-name-all-completions file-base-name default-directory)) (back-name (oldest-file back-list))) (if (string-equal back-name file-base-name) (message "No older backup of %s found." file-base-name) (compile-internal (format "diff %s %s %s" (if nocontext "-r" "-c") back-name file-base-name) "Use show-diff to move to diffs" "diff")))) (defun oldest-file (list) "Return the oldest file, from the LIST of files." (let ((oldest (car list))) (if list (setq list (cdr list))) (while list (if (file-newer-than-file-p oldest (car list)) (setq oldest (car list))) (setq list (cdr list))) oldest)) (defvar grep-command "grep -n" "The command to run for M-x grep") (defun grep (command) "Run grep, with user-specified args, and collect output in a buffer. While grep runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to." (interactive (list (read-from-minibuffer "Run grep (like this): " (concat grep-command " " (symbol-around-point) " " (other-possibly-interesting-files)) nil nil 'grep-history))) (let (highlight) (if (string-match "[ \t]*\\(-[-A-Za-z][ \t]+\\)*\\([^ \t]+\\)" command) (setq highlight (substring command (match-beginning 2) (match-end 2))) (setq highlight "error: Grep Rexexp Not Set") ; ignorable error ) ;; (error highlight); debug (compile-internal (concat command " /dev/null") "No more grep hits" "grep" ;; nil ;switch to buffer ;; highlight ))) ;; A package of Greg's id tools are available in the comp.sources.unix ;; archives volume 11 under the name 'id'. ;; id/part[01-03] C cross-reference database system (defun gid (command) "Run gid, with user-specified args, and collect output in a buffer. While gid runs asynchronously, you can use the \\[next-error] command to find the text that gid hits refer to. Gid is Greg McGary's pre-digested-grep program, like ctags, but for grep." (interactive (list (read-input "Run gid (with args): " (symbol-around-point)))) (compile-internal (concat "gid " command) "No more gid hits" "gid" ;; nil ;switch to buffer ;; command )) (defun aid (command) "Run aid, with user-specified args, and collect output in a buffer. While aid runs asynchronously, you can use the \\[next-error] command to find the text that aid hits refer to. Aid is Greg McGary's pre-digested-grep program, like ctags, but for grep." (interactive (list (read-input "Run aid (with args): " (symbol-around-point)))) (compile-internal (concat "aid " command) "No more aid hits" "aid" ;; nil ;switch to buffer ;; command )) (defun gidh (command) "Run gid, of system header files, with user-specified args, and collect output in a buffer. While gid runs asynchronously, you can use the \\[next-error] command to find the text that gid hits refer to. Gid is Greg McGary's pre-digested-grep program, like ctags, but for grep." (interactive (list (read-input "Run gid (with args): " (symbol-around-point)))) (compile-internal (concat "gid -f/usr/local/lib/ID " command) "No more gid hits" "gid" ;; nil ;switch to buffer ;; command )) (defun other-possibly-interesting-files () "Return a sh-regexp for other files that may be of intrest for the purpose of grep-ing" (if (equal major-mode 'c-mode) "*.h *.c" ;for .h and .c files (concat "*" (and buffer-file-name (string-match "\\.[^.]+$" buffer-file-name) (substring buffer-file-name (match-beginning 0) (match-end 0)))))) (defun word-around-point () "Return the word around the point as a string." (save-excursion (let (beg) (if (not (looking-at "\\<")) (forward-word -1)) (setq beg (point)) (forward-word 1) (buffer-substring beg (point))))) (defun symbol-around-point () "Return the symbol around the point as a string." (save-excursion (if (not (looking-at "\\s_\\|\\sw")) ; if not in a symbol (re-search-backward "\\s_\\|\\sw" nil t)) ; go into prev. one (buffer-substring (progn (forward-sexp 1) (point)) (progn (backward-sexp 1) (point))))) (defun find-ifdef (command) "Run grep for ifdef, with user-specified args, and collect output in a buffer. While grep runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to." (interactive (list (read-input "Run egrep (with args): " (concat "'^#[\\ \\t]*if.*" (word-around-point) "' *.h *.c")))) (compile-internal (concat "egrep -n " command " /dev/null") "No more egrep hits" "egrep-ifdefs" ;; nil ;switch to buffer ;; command ))