;; Scott's .emacs file ;; Last modified: 21 Jun 2006 ;; Intended for GNU Emacs, but might work on other Emacs variants too. ;; Feel free to copy, distribute, and make modifications to this file. ;; KDE users: If you use this .emacs file and find that the background ;; color is black except where there is text (then the background ;; color is white), then you need to go to Control Center | Look & ;; Feel | Style. Then, uncheck the box labeled "Apply fonts and ;; colors to non-KDE apps." Then, restart KDE. Depending on your ;; version of KDE, the steps described here might be different. ;; Start quietly (setq inhibit-startup-message t) ;; Remove menubar (menu-bar-mode 0) ;; if using a graphical window (ie. not using -nw) (if window-system (progn ;; Put scroll bar on the right side (if (> emacs-major-version 19) (set-scroll-bar-mode 'right)) ;; Remove graphical toolbar (if version 21 or higher) (if (> emacs-major-version 20) (tool-bar-mode 0)) ;; If Emacs "hangs" for a few seconds while starting, you might have ;; to comment out or change the following line that tries to set the ;; font to a fixed width font: (set-default-font "fixed") ;; (set-default-font "9x15") ;; high resolution monitor, bigger fonts ;; (set-default-font "-xos4-terminus-bold-r-normal--14-140-72-72-c-80-iso8859-1") ;; don't show tooltips (if (or (and (> emacs-major-version 20) (> emacs-minor-version 0)) (> emacs-major-version 21)) (tooltip-mode 0)) ;; show entire file path in frame title (setq frame-title-format "Emacs - %f") ;; use mouse wheel to scroll (if (> emacs-major-version 20) (mouse-wheel-mode t)) ;; Default: scroll with middle, page-up with left click, page down with right ;; Scroll with left mouse button ;; This only works with the plain scroll bar, not the Xaw3d variety (global-set-key [vertical-scroll-bar down-mouse-1] 'scroll-bar-drag) ;; Page down with middle button (global-set-key [vertical-scroll-bar mouse-2] 'scroll-bar-scroll-up) (global-set-key [vertical-scroll-bar drag-mouse-2] 'scroll-bar-scroll-up) (global-unset-key [vertical-scroll-bar down-mouse-2]) ;; Page up with right button (global-set-key [vertical-scroll-bar mouse-3] 'scroll-bar-scroll-down) (global-set-key [vertical-scroll-bar drag-mouse-3] 'scroll-bar-scroll-down) ;; basic colors (setq default-frame-alist '((cursor-color . "red") (cursor-type . box) (foreground-color . "white") (background-color . "black"))) ;; modeline colors (set-face-background 'modeline "gray") (set-face-foreground 'modeline "black") ;; (mouse-avoidance-mode 'animate) ;; Cool...but annoying )) ;; end if window-system ;; ----File associations---- (setq auto-mode-alist (append '(("\\.C$" . c++-mode) ("\\.cc$" . c++-mode) ("\\.cpp$" . c++-mode) ("\\.cxx$" . c++-mode) ("\\.hxx$" . c++-mode) ("\\.h$" . c++-mode) ("\\.hh$" . c++-mode) ("\\.idl$" . c++-mode) ("\\.c$" . c-mode) ("\\.cg$" . c-mode) ; nvidia cg ("\\.pl$" . perl-mode) ("\\.pm$" . perl-mode) ("\\.java$" . java-mode) ("\\.m$" . octave-mode) ("\\.html$" . html-mode) ("\\.htm$" . html-mode) ("\\.xml$" . sgml-mode) ;; ("\\.php$" . php-mode) ("\\.log$" . text-mode) ("\\.sty$" . latex-mode) ("\\.tex$" . latex-mode) ("\\.latex$" . latex-mode) ("\\.diff$" . diff-mode) ("\\.patch$" . diff-mode) ("/tmp/mutt.*" . email-mode) ("/home/skuhl/tmp/mutt.*" . email-mode) ("\\.txt$" . doc-mode)) auto-mode-alist)) (prefer-coding-system 'utf-8) ;; To use manually: M-x doc-mode ;; a mode designed for editing text file documents that contain a lot ;; of text to spell check, etc. (defun doc-mode () (interactive) (text-mode) ;; use regular text mode (auto-fill-mode) ;; wrap lines ;; (refill-mode) ;; wrap lines (more aggressive) (flyspell-mode)) ;; underline misspelled words ;; run M-x flyspell-buffer for it to underline all ;; words in the file instead of the words your ;; cursor moves over. (defun email-mode () (interactive) (load "/home/skuhl/.emacs.d/post") (post-mode) (flyspell-mode)) ;; ----Programming mode settings---- ;; If you want to change indention of your code, go to the place in code ;; where indention is wrong and press C-C C-o to see the symbol you need ;; to change. ;; I prefer that curly braces are put on the line after the loop statement ;; and that it is lined up with the statement. The following reflects ;; this preference. ;; change this variable to be how much you want to indent ;; when in a programming mode below (setq my-indent-width 2) ;; turn on fly spell in latex mode by default. ;; run M-x flyspell-buffer for it to underline all ;; words in the file instead of the words your ;; cursor moves over. (add-hook 'latex-mode-hook '(lambda()(flyspell-mode))) ;; Set up java mode (add-hook 'java-mode-hook '(lambda () ;; automatically indent when return is pressed while coding (define-key java-mode-map "\C-m" 'newline-and-indent) (c-set-style "BSD") (setq c-basic-offset my-indent-width) (c-set-offset 'inline-open 0) (c-set-offset 'case-label 'my-indent-width) (c-set-offset 'substatement 'my-indent-width) (set (make-local-variable 'compile-command) (concat "javac " buffer-file-name)))) ;; NOTE: To call gmake in a different directory other than ;; the current one, try ;; "gmake -C /home/user/my-c-stuff" ;; in place of ;; (concat "gmake " buffer-file-name) ;; Set up C mode (add-hook 'c-mode-hook '(lambda () ;; automatically indent when return is pressed while coding (define-key c-mode-map "\C-m" 'newline-and-indent) (c-set-style "BSD") (setq c-basic-offset my-indent-width) (c-set-offset 'inline-open 0) (c-set-offset 'case-label 'my-indent-width) (set (make-local-variable 'compile-command) (concat "gmake " buffer-file-name)))) ;; Set up c++ mode (add-hook 'c++-mode-hook '(lambda () ;; automatically indent when return is pressed while coding (define-key c-mode-map "\C-m" 'newline-and-indent) (c-set-style "BSD") (setq c-basic-offset my-indent-width) (c-set-offset 'inline-open 0) (c-set-offset 'access-label -2) (c-set-offset 'case-label 'my-indent-width) (c-set-offset 'topmost-intro 0) (set (make-local-variable 'compile-command) (concat "gmake " buffer-file-name)))) ;; Set up perl mode (add-hook 'perl-mode-hook '(lambda () (setq perl-indent-level my-indent-width))) ;; Set up php mode (add-hook 'php-mode-hook '(lambda () ;; automatically indent when return is pressed while coding (define-key c-mode-map "\C-m" 'newline-and-indent) (c-set-style "BSD") (setq c-basic-offset my-indent-width) (c-set-offset 'inline-open 0))) (add-hook 'latex-mode-hook '(lambda () (set (make-local-variable 'compile-command) (concat "latex " buffer-file-name)))) ;; always prompt for compile command (setq compilation-read-command t) ;; Press M-1 to compile (global-set-key "\M-1" 'compile) ;;----Color set up---- ;; Turn on pretty font colors (global-font-lock-mode t) (setq font-lock-maximum-decoration t) (lazy-lock-mode) ;; Scroll faster, colors won't appear correctly right away (setq lazy-lock-defer-on-scrolling t) (setq search-highlight t) ; incremental search highlights (setq query-replace-highlight t) ; highlight during query ;; set highlight color (set-face-background 'region "MidnightBlue") ;; Isearch highlight colors (copy-face 'default 'isearch) (set-face-background 'isearch "DarkGreen") (set-face-foreground 'isearch "white") ;; Isearch lazy highlight colors (if (> emacs-major-version 20) (progn (set-face-background 'isearch-lazy-highlight-face "DimGray") (set-face-foreground 'isearch-lazy-highlight-face "white"))) ;; Some new colors for font-lock ;; For list of colors, use M-x list-colors-display ;; The "nil 1" after the make-face-italic and make-face-bold ;; prevents errors from being reported (I saw this problem ;; with Emacs 20.7.2 in -nw mode). The errors don't appear ;; on 21.2.1 (copy-face 'default 'font-lock-string-face) (make-face-italic 'font-lock-string-face nil 1) (set-face-foreground 'font-lock-string-face "azure3") (copy-face 'default 'font-lock-variable-name-face) (set-face-foreground 'font-lock-variable-name-face "sky blue") (copy-face 'default 'font-lock-preprocessor-face) (set-face-foreground 'font-lock-preprocessor-face "Red") (copy-face 'default 'font-lock-comment-face) (set-face-foreground 'font-lock-comment-face "Tan") (copy-face 'default 'font-lock-function-name-face) (make-face-bold 'font-lock-function-name-face nil 1) (set-face-foreground 'font-lock-function-name-face "Coral") (copy-face 'default 'font-lock-keyword-face) (set-face-foreground 'font-lock-keyword-face "deep sky blue") (copy-face 'default 'font-lock-type-face) (make-face-bold 'font-lock-type-face nil 1) (set-face-foreground 'font-lock-type-face "LimeGreen") (copy-face 'default 'font-lock-reference-face) (set-face-foreground 'font-lock-reference-face "LightSkyBlue1") (copy-face 'default 'font-lock-doc-string-face) (make-face-italic 'font-lock-doc-string-face nil 1) (set-face-foreground 'font-lock-doc-string-face "wheat") (copy-face 'default 'font-lock-constant-face) (set-face-foreground 'font-lock-constant-face "cornflower blue") (copy-face 'default 'font-lock-type-name-face) (make-face-italic 'font-lock-type-name-face nil 1) (set-face-foreground 'font-lock-type-name-face "Red") (copy-face 'default 'font-lock-builtin-face) (make-face-bold 'font-lock-builtin-face nil 1) (set-face-foreground 'font-lock-builtin-face "OrangeRed3") (copy-face 'default 'show-paren-match-face) (set-face-background 'show-paren-match-face "dim gray") (copy-face 'default 'show-paren-mismatch-face) (set-face-background 'show-paren-mismatch-face "magenta") (copy-face 'default 'minibuffer-prompt) (make-face-bold 'minibuffer-prompt nil 1) (set-face-foreground 'minibuffer-prompt "red") (copy-face 'default 'ediff-even-diff-face-A) (set-face-foreground 'ediff-even-diff-face-A "white") (set-face-background 'ediff-even-diff-face-A "SlateGray4") (copy-face 'default 'ediff-odd-diff-face-A) (set-face-foreground 'ediff-odd-diff-face-A "white") (set-face-background 'ediff-odd-diff-face-A "SteelBlue4") (copy-face 'ediff-even-diff-face-A 'ediff-even-diff-face-B) (copy-face 'ediff-odd-diff-face-A 'ediff-odd-diff-face-B) (copy-face 'ediff-even-diff-face-A 'ediff-odd-diff-face-C) (copy-face 'ediff-odd-diff-face-A 'ediff-odd-diff-face-C) (copy-face 'default 'ediff-current-diff-face-A) (set-face-foreground 'ediff-current-diff-face-A "white") (set-face-background 'ediff-current-diff-face-A "IndianRed4") (copy-face 'default 'ediff-current-diff-face-B) (set-face-foreground 'ediff-current-diff-face-B "white") (set-face-background 'ediff-current-diff-face-B "sienna4") (copy-face 'default 'ediff-current-diff-face-C) (set-face-foreground 'ediff-current-diff-face-C "white") (set-face-background 'ediff-current-diff-face-C "firebrick4") (copy-face 'default 'ediff-fine-diff-face-A) (set-face-foreground 'ediff-fine-diff-face-A "white") (set-face-background 'ediff-fine-diff-face-A "SpringGreen4") (copy-face 'ediff-fine-diff-face-A 'ediff-fine-diff-face-B) (copy-face 'ediff-fine-diff-face-A 'ediff-fine-diff-face-C) ;; Turn on selection (setq transient-mark-mode 't highlight-nonselected-windows 't) ;; Emacs is silly ;; (when (fboundp 'zone) ;; (require 'zone) ;; (setq zone-idle 10) ;; seconds to wait till zoning ;; (zone-when-idle 10) ;; ) ;;----Delete/Backspace settings---- ;; Delete deleted char right of cursor (global-set-key [delete] 'delete-char) (global-set-key [(shift backspace)] 'delete-char) ;; Backspace deletes previous char (global-set-key [backspace] 'delete-backward-char) (global-set-key [(shift delete)] 'delete-backward-char) ;; helpful when using emacs with "-nw" over ssh. (global-set-key "\C-h" 'delete-backward-char) ;; Change help command to [F1] (it is usually C-h) (global-set-key [f1] 'help-command) ;; Pressing backspace during an Isearch will delete the previous ;; character typed (or do a reverse isearch if something matches the ;; current word). Without this, it will delete the highlighted text. (define-key isearch-mode-map [backspace] 'isearch-delete-char) ;;----Modeline settings---- ;; Show 24-hour time and date on status bar ;; (setq display-time-24hr-format t) ;; (setq display-time-day-and-date t) ;; (display-time) ;; Show line and column number (line-number-mode 1) (column-number-mode 1) ;;----Misc stuff---- (when (= emacs-major-version 20) ;; resize the miniwindow if required (resize-minibuffer-mode 1)) ;; Enable completions (load-library "completion") (initialize-completions) ;; Don't beep at me (setq visible-bell t) ;; Replace highlighted/marked areas (delete-selection-mode t) ;; show paren matches (setq blink-matching-paren t) (setq show-paren-delay 0) (show-paren-mode t) ;; Typing "yes" or "no" takes too long---use "y" or "n" (fset 'yes-or-no-p 'y-or-n-p) ;;----Moving around--- ;; Scroll one line at a time (setq scroll-step 1) ;; Don't insert new lines when scrolling (setq next-line-add-newlines nil) ;; Set C-c, g to goto-line (global-set-key "\C-cg" 'goto-line) ;; Set up home/end keys (global-set-key [end] 'end-of-buffer) (global-set-key [home] 'beginning-of-buffer) ;; Moving around more easily (global-set-key [C-right] 'forward-word) (global-set-key [C-left] 'backward-word) ;;----Ediff stuff---- ;; Use M-x ediff-buffers or M-x ediff-files to compare two files ;; don't open up new window (setq ediff-window-setup-function 'ediff-setup-windows-plain) ;; show files side by side (setq ediff-split-window-function 'split-window-horizontally) ;; use a wide window (add-hook 'ediff-startup-hook 'ediff-toggle-wide-display) ;; ignore differences in whitespace (setq ediff-diff-options "-w") ;;----Shell stuff---- ;; hide passwords (add-hook 'comint-output-filter-functions 'comint-watch-for-password-prompt) ;; Don't show ^M when on windows machines in plain shell mode (add-hook 'comint-output-filter-functions 'comint-strip-ctrl-m) ;; truncate shell buffer to comint-buffer-maximum-size (add-hook 'comint-output-filter-functions 'comint-truncate-buffer) ;; set maximum-buffer size for shell-mode (setq comint-buffer-maximum-size 10240) ;; don't allow shell prompt to be erased (setq comint-prompt-read-only "y") (copy-face 'default 'comint-highlight-prompt) (set-face-foreground 'comint-highlight-prompt "firebrick1") (set-face-background 'comint-highlight-prompt "black") ;; Shell mode: M-x shell ;; If you don't like this try: M-x eshell ;; ;; In order to supress the color codes from being displayed as "junk" ;; on the screen, you'll probably want like this at the bottom of one ;; of your dot files for your shell (if you use bash, ;; /home/user/.bashrc): ;; ;; # If you want to check to see if you are running a shell inside of ;; Emacs in bash shell scripts, use the following if statement: ;; ;; if [ $EMACS ]; then ;; TERM=dumb; ;; PS1="[\u@\h \W]\$ " # normal prompt ;; alias ls='ls -F' # no colors for ls ;; else ;; alias ls='ls -F --color=tty' ;; fi ;; ;; Actually display colors when programs output colored text. Without ;; this command, emacs prints the actual control characters. (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on) (add-hook 'shell-mode-hook (function (lambda () (setq comint-scroll-to-bottom-on-input t) (setq comint-scroll-to-bottom-on-output t) (setq comint-scroll-show-maximum-output t) (compilation-shell-minor-mode) (rename-buffer "shell" t)))) (add-hook 'gdb-mode-hook (function (lambda () (setq comint-scroll-to-bottom-on-input t) (setq comint-scroll-to-bottom-on-output t) (setq comint-scroll-show-maximum-output t)))) ;; If a shell is already open, it will pop up. ;; If a shell isn't open yet, open one and make it pop up (defun to-shell () (interactive) (setq shell-is-open 0) ;; check for buffer named shell (mapcar (lambda (buffer) (if (string-equal (buffer-name buffer) "shell") (setq shell-is-open 1))) (buffer-list)) ;; if shell isn't open, open one up, bury it (if (= shell-is-open 0) (progn (shell) (bury-buffer))) ;; pop the shell so it takes up part of screen (pop-to-buffer "shell")) ;; Press M-2 to get shell (global-set-key "\M-2" 'to-shell) ;;----Saving Files---- ;; Put a newline at end of file if it isn't there. ;; (setq require-final-newline t) (defun strip-eol-whitespace () (interactive) (save-excursion ;; don't move cursor (beginning-of-buffer) ;; start at top of buffer (replace-regexp "[ \t]+$" ""))) ;; strip spaces & tabs ;; Strip whitespace at end of lines when saving. ;; WARNING: Might be a BAD idea with some files! ;(add-hook 'write-file-hooks ; (function ; (lambda () ; (strip-eol-whitespace)))) ;;(save-excursion ;; don't move cursor ;; (beginning-of-buffer) ;; start at top of buffer ;; (replace-regexp "[ \t]+$" ""))))) ;; strip spaces & tabs ;; Replace all tabs with spaces when saving. ;; WARNING: Can cause problems with makefiles ;; (add-hook 'write-file-hooks ;; (function (lambda () (untabify (point-min) (point-max))))) ;; Don't make backup files (setq make-backup-files nil backup-inhibited t) ;; auto-save stuff ;; (setq auto-save-interval 100) ;; (setq auto-save-timeout nil) ;; (setq auto-save-list-file-prefix ".saves/") ;; backup version stuff ;; (setq version-control t) ;; (setq kept-old-versions 3) ;; (setq kept-new-versions 5) ;; (setq delete-old-versions t) ;;----Custom functions---- ;; Remove tabs from entire buffer (defun untabify-buffer () (interactive) (untabify (point-min) (point-max))) ;; converts <, >, and & to <, > & (defun html-tag-escape (point mark) (interactive "*r") (if (< (mark) (point)) (exchange-point-and-mark)) (save-restriction (narrow-to-region point mark) (save-excursion (while (search-forward "\&" nil t) (replace-match "&" nil t))) (save-excursion (while (search-forward "<" nil t) (replace-match "<" nil t))) (save-excursion (while (search-forward ">" nil t) (replace-match ">" nil t))))) ;; reverse of html-tag-escape (defun html-tag-unescape (point mark) (interactive "*r") (if (< (mark) (point)) (exchange-point-and-mark)) (save-restriction (narrow-to-region point mark) (save-excursion (while (search-forward "<" nil t) (replace-match "<" nil t))) (save-excursion (while (search-forward "%gt;" nil t) (replace-match "<" nil t))) (save-excursion (while (search-forward "&" nil t) (replace-match "&" nil t))))) ;; Prints the string "string" "n" times. (defun repeat-insert (n string) (while (> n 0) (insert string) (setq n (- n 1)))) ;; Uncomment region (undos comment-region command) (define-key global-map "\C-c\C-v" 'uncomment-region) (defun uncomment-region (beg end) "...Uncomment selected region" (interactive "*r") (comment-region beg end -1)) ;; makes nice C comments in the form: ;; /* * * * * * * * * * * * * * ;; * ;; * ;; * ;; * * * * * * * * * * * * * */ ;; ;; If called with no selection, a comment 'template' ;; will be printed to the buffer. Otherwise, the selection ;; will be put inside of the comment (define-key global-map "\C-cb" 'block-comment-region) (defun block-comment-region (mark point) (interactive "*r") (if (and mark-active (not (char-equal (mark) (point)))) (progn ;; if there is a selection (if (< (mark) (point)) (exchange-point-and-mark)) (fill-individual-paragraphs (point) (mark)) (prefix-region (point) (mark) " * ") ;; put this at the beginning of lines (goto-char (point)) (insert "/") (repeat-insert 39 "* " ) (insert "\n") (goto-char (mark)) (end-of-line) (insert "\n") (repeat-insert 39 " *" ) (insert "/")(forward-line) (deactivate-mark) (message "")) ;; don't show how many things were replaced (progn ;; if there isn't a selection, just do a template (goto-char (point)) (insert "/") (repeat-insert 39 "* ") (insert "\n") (repeat-insert 3 " * \n") (repeat-insert 39 " *") (insert "/\n") (forward-line -4) (end-of-line)))) ;; makes nice C comments in the form: ;; /* ;; * ;; */ ;; ;; If called with no selection, a comment 'template' ;; will be printed to the buffer. Otherwise, the selection ;; will be put inside of the comment (define-key global-map "\C-cl" 'long-comment-region) (defun long-comment-region (mark point) (interactive "*r") (if (and mark-active (not (char-equal (mark) (point)))) (progn ;; if there is a selection (if (< (mark) (point)) (exchange-point-and-mark)) (fill-individual-paragraphs (point) (mark)) (prefix-region (point) (mark) " * ") ;; put this at the beginning of lines (goto-char (point)) (insert "/*\n") ;; beginning of comment (goto-char (mark)) (end-of-line) (insert "\n */") ;; end of comment (forward-line) (deactivate-mark) (message "")) ;; don't show how many things were replaced (progn ;; if there isn't a selection, just do a template (goto-char (point)) (insert "/*\n * \n */") (forward-line -1) (end-of-line)))) (defun prefix-region (point mark string) "Prefix the region between [point] and [mark] with [string]" (interactive "*r\nsPrefix: ") (save-excursion (save-restriction (narrow-to-region point mark) (replace-regexp "^" string)))) ;; don't wrap long lines, M-x no-wrap (defun no-wrap() (interactive) (progn ;; truncate lines if they are too long (setq truncate-lines t) ;; trucate even even when screen is split into multiple windows (setq truncate-partial-width-windows nil) ;; load auto-show (shows lines when cursor moves to right of long line) (require 'auto-show) (auto-show-mode 1) ;; position cursor to end of output in shell mode (auto-show-make-point-visible) )) ;; wrap long lines, M-x wrap (defun wrap() (interactive) (setq truncate-lines nil)) ;; To convert file types: C-x RET f type RET ;; Or, use one of the following functions (defun unix () ;; M-x unix "Use UNIX line endings" (interactive) (set-buffer-file-coding-system 'undecided-unix)) (defun dos () ;; M-x dos "Use DOS line endings" (interactive) (set-buffer-file-coding-system 'undecided-dos)) (defun mac () ;; M-x mac "Use MAC line endings" (interactive) (set-buffer-file-coding-system 'undecided-mac)) (defun swap-values (symbol1 symbol2) "Swap the values of SYMBOL1 and SYMBOL2. Return the former value of SYMBOL1, the final value of SYMBOL2." (let ((x (symbol-value symbol1))) (set symbol1 (symbol-value symbol2)) (set symbol2 x))) (defun transpose-regions-allow-empty (startr1 endr1 startr2 endr2 &optional leave-markers) "Like `transpose-regions', but allow empty regions." (if (> startr1 endr1) (swap-values 'startr1 'endr1)) (if (> startr2 endr2) (swap-values 'startr2 'endr2)) (if (> startr1 startr2) (progn (swap-values 'startr1 'startr2) (swap-values 'endr1 'endr2))) (if (= startr1 endr1) (setq endr1 startr2)) (if (= startr2 endr2) (setq startr2 endr1)) (if (and (/= startr1 endr1) (/= startr2 endr2)) (transpose-regions startr1 endr1 startr2 endr2 leave-markers))) (defun shuffle-regions (regions &optional leave-markers) "Randomly permute REGIONS given as a list of (BEG . END) cells. The caller must ensure (i) the regions don't overlap, (ii) BEG is never greater than END, (iii) the regions are listed in the reverse order they appear in the buffer. See `transpose-regions' for LEAVE-MARKERS." (let ((n (length regions))) (while (> n 1) (let ((r (random n))) (if (zerop r) (setq regions (cdr regions)) (let* ((a (car regions)) (b (elt regions r)) (x (- (- (cdr a) (car a)) (- (cdr b) (car b))))) (transpose-regions-allow-empty (car a) (cdr a) (car b) (cdr b) leave-markers) (setq regions (cdr regions)) (let ((iter regions)) (while iter (let ((i (car iter))) (if (eq i b) (progn (setcdr i (+ x (cdr i))) (setq iter nil)) (setcar i (+ x (car i))) (setcdr i (+ x (cdr i))))) (setq iter (cdr iter))))))) (setq n (1- n))))) (defun shuffle-lines (beg end) "Randomly permute lines in region." (interactive "r") (save-excursion (save-restriction (narrow-to-region beg end) (goto-char (point-min)) (let (lines) (while (not (eobp)) (let ((beg (point))) (end-of-line) (let ((end (point))) (setq lines (cons (cons beg end) lines)))) (forward-line)) (shuffle-regions lines t)))))