; miscellaneous emacs-lisp hacks ; created by J. Stolfi on 91-12-06 (defun point-is-in-leading-blanks () "True if characters between beginning-of-line and point are all blanks." (<= (current-column) (current-indentation)) ) (defun is-lower-case-letter (char) "t iff /char/ is a lower-case letter" (and (>= char ?a) (<= char ?z))) (defun expand-abbrev-from-table (table) "Like expand-abbrev, but uses the given abbrev table in lieu of the local one" (let ( (old-global global-abbrev-table) (old-local local-abbrev-table) ) (setq local-abbrev-table table) (setq global-abbrev-table empty-abbrev-table) (let ((res (expand-abbrev))) (setq local-abbrev-table old-local) (setq global-abbrev-table old-global) res ) ) ) (defun delete-forward-space () "Deletes horizontal space ahead of point" (while (is-horizontal-space (following-char)) (delete-char 1)) ) (defun delete-backward-space () "Deletes horizontal space behind of point" (while (is-horizontal-space (preceding-char)) (delete-char -1)) ) (defun is-horizontal-space (char) "t iff char is a horizontal space" (or (= char ?\ ) (= char ?\t)) ) ; Smart beginning-of-line (defun stolfi-beginning-of-line () "Move back to left margin, or to beginning of line if already at left margin" (interactive) (let ((p-start (point))) (back-to-indentation) (if (>= (point) p-start) (beginning-of-line)) ) ) ; Smart delete-char (defun stolfi-delete-next-char () "Deletes character after point; if newline, also deletes following whitespace, leaving exactly one space before or after point, as appropriate." (interactive) (let ((c (following-char))) (delete-char 1) (cond ( (= c ?\n) (progn (delete-forward-space) (if (not (is-horizontal-space (preceding-char))) (progn (insert-char ?\ 1) (backward-char 1) ) ) ) ) ( (is-horizontal-space c) (delete-forward-space) ) ) ) ) (defun stolfi-delete-prev-char () "Deletes character before point; if newline, also deletes all whitespace, leaving exactly one space before or after point, as appropriate." (interactive) (let ((c (preceding-char))) (backward-delete-char-untabify 1) (cond ( (= c ?\n) (progn (delete-forward-space) (if (not (is-horizontal-space (preceding-char))) (progn (insert-char ?\ 1) (backward-char 1) ) ) ) ) ) ) ) ; Smart newline-and-indent (defun stolfi-newline-and-indent () "Inserts newline and indents like previous line" (interactive) (let ((hpos (current-indentation))) (insert-char ?\n 1) (indent-to hpos) (delete-forward-space) ) ) (defun stolfi-open-line () "Insert a newline after point, attempts to indent it properly" (interactive) (let ((p-here (point))) (stolfi-newline-and-indent) (goto-char p-here) ) ) ; Indent-region, indent-line (defvar stolfi-indent-step 2 "This buffer's standard indentation step" ) (make-variable-buffer-local 'stolfi-indent-step) (defun stolfi-sync-region-to-lines () "Expands region if needed so that it begins at beginning-of-line" (let ((gtr (> (point) (mark)))) (if gtr (exchange-point-and-mark)) ; now point <= mark ; adjust to previous b-o-l, if not at b-o-l (beginning-of-line) ; restore original order of point and mark (if gtr (exchange-point-and-mark)) ) ) (defun stolfi-indent-region (&optional arg) "Indent region by stolfi-indent-step, or by arg if non-nil" (interactive "P") (let ((gtr (> (point) (mark)))) (if gtr (exchange-point-and-mark)) (let ( (col (current-column)) (count (if arg arg stolfi-indent-step)) ) (beginning-of-line) (indent-rigidly (point) (mark) count) (move-to-column (max 0 (+ col count))) ) (if gtr (exchange-point-and-mark)) ) ) (defun stolfi-exdent-region (&optional arg) "Exdent region by stolfi-indent-step, or by arg if non-nil" (interactive "P") (let ( (gtr (> (point) (mark))) ) (if gtr (exchange-point-and-mark)) (let ( (col (current-column)) (count (if arg arg stolfi-indent-step)) ) (beginning-of-line) (indent-rigidly (point) (mark) (- count)) (move-to-column (max 0 (- col count))) ) (if gtr (exchange-point-and-mark)) ) ) (defun stolfi-indent-line (arg) "Indent this line by stolfi-indent-step, or by arg if non-nil" (interactive "P") (let ( (p-here (copy-marker (point))) (count (if arg arg stolfi-indent-step)) ) (back-to-indentation) (insert-before-markers (make-string count ?\ )) (goto-char p-here) ) ) (defun stolfi-exdent-line (arg) "Exdent this line by stolfi-indent-step, or by arg if non-nil" (interactive "P") (let ( (p-here (copy-marker (point))) (count (min (current-indentation) (if arg arg stolfi-indent-step))) ) (end-of-line) (back-to-indentation) (delete-char (- count)) (goto-char p-here) ) ) (defun stolfi-next-slot (slot-mark search-limit) "Skips to the next slot; deletes it and returns t iff found" (if (search-forward slot-mark search-limit t) (progn (delete-char (- (length slot-mark))) t) nil ) ) (defun stolfi-prev-slot (slot-mark search-limit) "Skips to the previous slot; deletes it and returns t iff found" (if (search-backward slot-mark search-limit t) (progn (delete-char (length slot-mark)) t) nil ) ) (defun stolfi-scroll-to-top () "Scroll the current window so that the line containing point becomes line 3" (interactive) (recenter 2) ) (defun stolfi-scroll-to-bottom () "Scroll the current window so that the line containing point becomes next-to-last" (interactive) (recenter -2) ) (defun stolfi-file-name-if-readable (fname &optional dir) "If the file `fname' exists and is readable, returns the expanded form `fname', oherwise Otherwise returns nil.\n\nIf `fname' is not an absolute pathname, it is interpreted and expanded relative to the directory named `dir' (or to the current buffer's `default directory' if `dir'is nil)." (if (not fname) nil (let* ( (pname (expand-file-name fname dir)) ) (cond ( (not pname) nil ) ( (file-readable-p pname) pname ) (t nil) ) ) ) )