Tag Archives: elisp

Emacs (and Vi) automatically make scripts executable

http://www.debian-administration.org/articles/571 shows the how to. I have installed shebang.el. This entry here is to help me find it easier when I’m actually looking for it.

Interestingly, the same post explains how to achieve this with Vi as well. So, I’d better keep a reference to that post here.

Advertisements

Emacs for managing processes

Vkill.el is an Emacs front-end for running the ps command and selecting processes for operations. Somewhat similar to dired. Vkill.el is my discovery of today on Emacs from #emacs channel on freenode.


In case the link goes down, I have put a copy of the code here.

;;; vkill.el --- view and kill Unix processes from within Emacs

;; Copyright (C) 1987, 1989 Kyle E. Jones
;; Copyright (C) 1991, 93, 96, 2000 Noah S. Friedman

;; Author: Kyle E. Jones
;; Noah Friedman
;; Maintainer: friedman@splode.com

;; $Id: vkill.el,v 1.7 2002/03/20 18:48:18 friedman Exp $

;; Verbatim copies of this file may be freely redistributed.
;;
;; Modified versions of this file may be redistributed provided that this
;; notice remains unchanged, the file contains prominent notice of
;; author and time of modifications, and redistribution of the file
;; is not further restricted in any way.
;;
;; This file is distributed `as is', without warranties of any kind.

;;; Commentary:

;; M-x vkill creates a buffer containing ps(1) output and allows you to
;; mvoe around in it marking processes to be sent a signal. Type a `?'
;; in the Process Info buffer for more help.
;;
;; The commands vkill and list-unix-processes are the package entry points.
;;
;; To autoload, use
;; (autoload 'vkill "vkill" nil t)
;; (autoload 'list-unix-processes "vkill" nil t)
;; in your .emacs file.

;;; ChangeLog:

;; 2002-03-20 Noah Friedman
;;
;; * vkill.el (vkill-ps-command): Convert user-uid to string for concat.
;;
;; 2001-09-09 Noah Friedman
;;
;; * vkill.el (vkill-update-process-info): Nuke trailing whitespace
;; from ps output.
;;
;; 2000-03-10 Noah Friedman
;;
;; * vkill.el (vkill-goal-column): Variable deleted.
;; (vkill): Don't set goal column.
;; (vkill-command-column-regexp): New variable.
;; (vkill-update-process-info): Use it to set goal column here.
;; (vkill-send-signal): Handle variable amount of whitespace after
;; signal markers.
;; Use syntax table regexps instead of literal whitespace.
;; (vkill-after-send-signal-hook): New variable.
;; (vkill-send-signal): Run it.
;;
;; 1996-07-15 Noah Friedman
;;
;; * vkill.el (vkill-goal-column, vkill-ps-command,
;; vkill-all-ps-command): Add gnu/linux as recognized system type.
;; (vkill-ps-command, vkill-all-ps-command): For linux systems, do not
;; pass `-g' option to `ps'.
;;
;; 1996-04-20 Noah Friedman
;;
;; * vkill.el: Comment fixes. Recognize Linux systems.
;; (process-list-vkill, process-list-all-vkill): New commands.
;; (vkill-toggle-truncate-lines): Use recenter to update display.
;;
;; 1996-02-14 Noah Friedman
;;
;; * vkill.el (vkill-goal-column, vkill-ps-command,
;; vkill-all-ps-command): Updated for linux.
;;
;; 1993-03-29 Noah Friedman
;;
;; * vkill.el: Set goal column to start of command.
;;
;; 1991-06-27 Noah Friedman
;;
;; * vkill.el: Changed bsd ps arguments to get the complete command
;; line, added "w" command to toggle between truncated lines and line
;; wrapping in the process list buffer.
;;
;; 1991-04-28 Noah Friedman
;;
;; * vkill.el: Handle differences in `ps' under various
;; operating systems.

;;; Code:

(provide 'vkill)

(defvar vkill-show-all-processes nil
"*Non-nil means always show all processes on the system.
Normally if you are not the superuser, only your own processes are
displayed.")

(defvar vkill-command-column-regexp "\\b\\(CMD\\|COMMAND\\)\\b")

;(setq vkill-ps-command (concat "ps -wwwfu " (number-to-string (user-uid))))
(defvar vkill-ps-command
(cond ((memq system-type '(berkeley-unix netbsd))
"ps -uxgww")
((memq system-type '(linux lignux gnu/linux))
;; Alternate SYSV style
;;(concat "ps -wwwfu " (number-to-string (user-uid)))
"ps uxwww")
(t
(concat "ps -fu " (number-to-string (user-uid)))))
"*Command used to get list of processes owned by the current user.
Arguments to the \"ps\" command differ under various operating
systems.")

(defvar vkill-all-ps-command
(cond ((memq system-type '(berkeley-unix netbsd))
"ps -auxgww")
((memq system-type '(linux lignux gnu/linux))
;;"ps -wwwef"
"ps auxwww")
(t
"ps -ef"))
"*Command used to get list of all processes currently running on the
system. Arguments to the \"ps\" command differ under various
operating systems.")

(defvar vkill-after-send-signal-hook nil
"*Hook to run after all else in `vkill-send-signal'")

(defvar vkill-keymap nil
"Keymap for vkill commands")
(cond ((null vkill-keymap)
(setq vkill-keymap (make-sparse-keymap))
(define-key vkill-keymap " " 'next-line)
(define-key vkill-keymap "n" 'next-line)
(define-key vkill-keymap "p" 'previous-line)
(define-key vkill-keymap "\C-?" 'previous-line)
(define-key vkill-keymap "?" 'vkill-help)
(define-key vkill-keymap "d" 'vkill-mark-process) ; Dired compatibility
(define-key vkill-keymap "m" 'vkill-mark-process)
(define-key vkill-keymap "M" 'vkill-mark-all-processes)
(define-key vkill-keymap "P" 'vkill-update-process-info)
(define-key vkill-keymap "g" 'revert-buffer) ; Dired compatibility
(define-key vkill-keymap "q" 'vkill-quit)
(define-key vkill-keymap "u" 'vkill-unmark-process)
(define-key vkill-keymap "U" 'vkill-unmark-all-processes)
(define-key vkill-keymap "x" 'vkill-send-signal) ; Dired compatibility
(define-key vkill-keymap "k" 'vkill-send-signal)
(define-key vkill-keymap "w" 'vkill-toggle-truncate-lines)))

(defconst vkill-quick-help-string
"(n)ext, (p)revious, (m)ark, (u)nmark, (k)ill, (q)uit (type ? for more help)"
"Quick help string for vkill.")

(defmacro vkill-signum (n)
(list 'if (list '> n 0) 1
(list 'if (list 'zerop n) 0 -1)))

(defmacro vkill-decrement (variable)
(list 'setq variable (list '1- variable)))

(defun vkill-abs (n) (if (< n 0) (- n) n))

(defun vkill (&optional list)
"Mode for displaying all UNIX processes owned by the current user
\(all the processes on the system if invoked by the superuser) and allowing
the user to mark processes to be sent a certain signal. Processes are
marked by moving the cursor to the line displaying information
about the victim process and typing `m' to mark the process.

If invoked with a prefix arg (optional first arg non-nil from a program)
the window displaying the process information will be displayed but not
selected.

Commands:
SPC, n - next line
DEL, p - previous line

m, d - mark process
u - unmark process
M - mark all processes
U - unmark all processes

P, g - update process information
k, x - send signal to marked processes (signal read from minibuffer)

w - toggle truncation of lines
? - help"
(interactive "P")
(let ((vkill-buffer (get-buffer-create "*Process Info*")) new)
(set-buffer vkill-buffer)
(setq new (zerop (buffer-size)))
(cond (new
(make-local-variable 'goal-column)
(make-local-variable 'revert-buffer-function)
(abbrev-mode 0)
(auto-fill-mode 0)
(setq buffer-read-only t
truncate-lines t
revert-buffer-function 'vkill-revert
major-mode 'vkill-mode
mode-name "Vkill")
(use-local-map vkill-keymap)))

(if (or new list)
(progn
(vkill-update-process-info list)
(goto-line 2)))

(if list
(display-buffer vkill-buffer)
(pop-to-buffer vkill-buffer)
(message "type q to quit, ? for help"))))

(fset 'vkill-mode 'vkill)
(put 'vkill-mode 'mode-class 'special)

(defun list-unix-processes (&optional activate)
"List UNIX processes owned by the current user using the ps(1) command.
If run by the superuser, all processes are listed. The buffer used to
display the listing is put into a special major mode similar to Dired
and Buffer Menu; you can mark processes to be sent a signal using this buffer.
See the documentation for `vkill-mode' for more information."
(interactive "P")
(vkill t))

(defun vkill-mark-process (&optional count)
"Mark the process listed on the current line and move forward a line.
With prefix arg COUNT, move forward that many lines, while marking the
corrseponding processes. A negative COUNT means move backwards."
(interactive "p")
(or count (setq count 1))
(let (buffer-read-only
(direction (vkill-signum count)))
(setq count (vkill-abs count))
(while (and (not (zerop count)) (not (eobp)) (not (bobp)))
(beginning-of-line)
(if (not (bobp))
(progn
(insert "*")
(delete-char 1)))
(forward-line direction)
(next-line 0) ; move to goal column.
(vkill-decrement count))))

(defun vkill-mark-all-processes ()
"Mark all listed processes."
(interactive)
(save-excursion
(let (buffer-read-only)
(goto-line 2)
(while (not (eobp))
(insert "*")
(delete-char 1)
(forward-line)))))

(defun vkill-unmark-all-processes ()
"Remove marks from all listed processes."
(interactive)
(save-excursion
(let (buffer-read-only)
(goto-line 2)
(while (not (eobp))
(insert " ")
(delete-char 1)
(forward-line)))))

(defun vkill-unmark-process (&optional count)
"Un-mark from the process listed on the current line and move forward a line.
With prefix arg COUNT, move forward that many lines, unmarking the
corresponding processes. A negative COUNT means move backwards."
(interactive "p")
(or count (setq count 1))
(let (buffer-read-only
(direction (vkill-signum count)))
(setq count (vkill-abs count))
(while (and (not (zerop count)) (not (eobp)) (not (bobp)))
(beginning-of-line)
(if (not (bobp))
(progn
(insert " ")
(delete-char 1)))
(forward-line direction)
(vkill-decrement count))))

(defun vkill-quit ()
"End current vkill session without sending a signal to any of the marked
processes."
(interactive)
(if (one-window-p)
(progn
(switch-to-buffer (other-buffer))
(bury-buffer (other-buffer)))
(bury-buffer (current-buffer))
(delete-window)))

(defun vkill-update-process-info (&optional quietly)
"Update the vkill process information. This throws away all process marks."
(interactive)
(or quietly (message "Updating process information..."))
(let ((buffer-read-only nil))
(erase-buffer)
(shell-command-on-region (point-min) (point-max)
(if (or vkill-show-all-processes
(zerop (user-real-uid)))
vkill-all-ps-command vkill-ps-command) t)
(goto-char (point-min))
(while (not (eobp))
(insert " ")
(forward-line))
(save-match-data
(goto-char (point-min))
(while (re-search-forward "[ \t\r]+$" nil t)
(delete-region (match-beginning 0) (match-end 0)))
(goto-char (point-min))

(and (boundp 'vkill-command-column-regexp)
(re-search-forward vkill-command-column-regexp nil t)
(setq goal-column (1- (match-beginning 0)))))
(goto-line 2)
(sort-numeric-fields 2 (point) (point-max)))
(or quietly (input-pending-p)
(message "Updating process information... done.")))

(defun vkill-revert (&rest args)
(vkill-update-process-info))

(defun vkill-send-signal (signal)
"Send a SIGNAL to the marked processes. SIGNAL may be a string (HUP, INT,
etc.) or a number. When called interactively, SIGNAL is always read from the
minibuffer."
(interactive "sSignal (default TERM): ")
(if (equal signal "")
(setq signal "TERM"))
(let ((workbuf (get-buffer-create " *vkill*")))
(save-excursion
(copy-to-buffer workbuf (point-min) (point-max))
(set-buffer workbuf)
(goto-char (point-min))
(delete-matching-lines "^\\s-")
(goto-char (point-min))
(if (not (looking-at "^\\* "))
(error "No processes marked"))
(while (re-search-forward "^\\*\\s-+\\S-+\\s-+\\([0-9]+\\).*\n" nil t)
(replace-match " \\1" t nil))
(goto-char (point-min))
(insert "kill -" (if (numberp signal) (int-to-string signal) signal))
(call-process shell-file-name nil 0 nil "-c" (buffer-string)))
(kill-buffer workbuf))
(run-hooks 'vkill-after-send-signal-hook))

(defun vkill-help ()
"Provide help for the vkill user."
(interactive)
(if (eq last-command 'vkill-help)
(describe-mode)
(message vkill-quick-help-string)))

(defun vkill-toggle-truncate-lines ()
"Toggle truncation of long lines in the buffer"
(interactive)
(setq truncate-lines (not truncate-lines))
(save-window-excursion
(recenter 0)))

(defun process-list-vkill ()
(interactive)
(setq vkill-show-all-processes nil)
(vkill)
(vkill-update-process-info))

(defun process-list-all-vkill ()
(interactive)
(setq vkill-show-all-processes t)
(vkill)
(vkill-update-process-info))

(provide 'vkill)

;;; vkill.el ends here.

An emacs function that works on Windows..

Linux or any other Unix has spoiled its user with too many desktop environments and window managers. So maximising the Emacs frame through an Emacs command is not done for those systems.

But since Windows is not so, w32-send-sys-command seems to do the ‘maximise’ window of the Emacs frame properly.

I don’t use Windows at all, leave alone Emacs on it. But who knows? I keep this tip for the future 😉