| 1 | ;; shutter.el --- anything shutter. |
|---|
| 2 | |
|---|
| 3 | ;; Copyright (C) 2008 Narihiro Nakamura |
|---|
| 4 | |
|---|
| 5 | ;; Author: Narihiro Nakamura <authorNari@gmail.com> |
|---|
| 6 | ;; Keywords: convenience |
|---|
| 7 | ;; Version: 0.1.0 |
|---|
| 8 | |
|---|
| 9 | ;; This file is free software; you can redistribute it and/or modify |
|---|
| 10 | ;; it under the terms of the GNU General Public License as published by |
|---|
| 11 | ;; the Free Software Foundation; either version 3, or (at your option) |
|---|
| 12 | ;; any later version. |
|---|
| 13 | |
|---|
| 14 | ;; This file is distributed in the hope that it will be useful, |
|---|
| 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 17 | ;; GNU General Public License for more details. |
|---|
| 18 | |
|---|
| 19 | ;; You should have received a copy of the GNU General Public License |
|---|
| 20 | ;; along with GNU Emacs; see the file COPYING. If not, write to |
|---|
| 21 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
|---|
| 22 | ;; Boston, MA 02110-1301, USA. |
|---|
| 23 | |
|---|
| 24 | ;;; Commentary: |
|---|
| 25 | |
|---|
| 26 | ;; In order to use this function, put this file into |
|---|
| 27 | ;; a directory included in load-path, |
|---|
| 28 | ;; and add following code to your .emacs. |
|---|
| 29 | ;; +------------------------+ |
|---|
| 30 | ;; (require 'shutter) |
|---|
| 31 | ;; (define-key global-map "\C-ct" 'shut_up) |
|---|
| 32 | ;; +------------------------+ |
|---|
| 33 | |
|---|
| 34 | ;;; Example: |
|---|
| 35 | |
|---|
| 36 | ;; "FooBar.. |"| insert when You use shutter.el |
|---|
| 37 | ;; [FooBar.. |]| insert when You use shutter.el |
|---|
| 38 | ;; 'FooBar.. |'| insert when You use shutter.el |
|---|
| 39 | ;; `FooBar.. |`| insert when You use shutter.el |
|---|
| 40 | ;; (FooBar.. |)| insert when You use shutter.el |
|---|
| 41 | |
|---|
| 42 | ;;; Code: |
|---|
| 43 | (defvar shut-matching-delimeter-alist |
|---|
| 44 | '(("[" . "]") |
|---|
| 45 | ("{" . "}") |
|---|
| 46 | ("(" . ")") |
|---|
| 47 | ("'" . "'") |
|---|
| 48 | ("`" . "`") |
|---|
| 49 | ("\"" . "\""))) |
|---|
| 50 | |
|---|
| 51 | (defvar user-shut-matching-delimeter-alist nil) |
|---|
| 52 | |
|---|
| 53 | (defun shut-matching-char (arg) |
|---|
| 54 | (interactive "P") |
|---|
| 55 | (insert (cdr (assoc arg |
|---|
| 56 | shut-matching-delimeter-alist)))) |
|---|
| 57 | |
|---|
| 58 | (defun set-shut-matching-delimeter-alist (alist) |
|---|
| 59 | (interactive "P") |
|---|
| 60 | (setq user-shut-matching-delimeter-alist alist)) |
|---|
| 61 | |
|---|
| 62 | (defun shut-up () |
|---|
| 63 | (interactive) |
|---|
| 64 | (let ((delimeters (if user-shut-matching-delimeter-alist |
|---|
| 65 | user-shut-matching-delimeter-alist |
|---|
| 66 | shut-matching-delimeter-alist)) |
|---|
| 67 | (searched) |
|---|
| 68 | (cursor)) |
|---|
| 69 | (progn |
|---|
| 70 | (setq cursor (point)) |
|---|
| 71 | (while delimeters |
|---|
| 72 | (progn |
|---|
| 73 | (if (and (not-pair (car delimeters)) |
|---|
| 74 | (search-backward (car (car delimeters)) nil t)) |
|---|
| 75 | (if (or (eq searched nil) |
|---|
| 76 | (< (car searched) (match-beginning 0))) |
|---|
| 77 | (setq searched (cons (match-beginning 0) (car (car delimeters)))))) |
|---|
| 78 | (setq delimeters (cdr delimeters)) |
|---|
| 79 | (goto-char cursor))) |
|---|
| 80 | (if searched |
|---|
| 81 | (shut-matching-char (cdr searched)))) |
|---|
| 82 | )) |
|---|
| 83 | |
|---|
| 84 | (defun not-pair (delimeters) |
|---|
| 85 | (let ((cursor)) |
|---|
| 86 | (progn |
|---|
| 87 | (setq cursor (point)) |
|---|
| 88 | (if (string-equal (car delimeters) (cdr delimeters)) |
|---|
| 89 | (let ((count 2)) |
|---|
| 90 | (progn |
|---|
| 91 | (while (search-backward (car delimeters) nil t) |
|---|
| 92 | (setq count (+ count 1))) |
|---|
| 93 | ;; (message "delimeters = %s : count = %s : return %s : same delimeters = %s" |
|---|
| 94 | ;; (car delimeters) count (eq (% count 2) 1) (string-equal (car delimeters) (cdr delimeters))) |
|---|
| 95 | ;; (sit-for 1) |
|---|
| 96 | (goto-char cursor) |
|---|
| 97 | (eq (% count 2) 1))) |
|---|
| 98 | (let ((open 0) (close 0)) |
|---|
| 99 | (progn |
|---|
| 100 | (while (search-backward (car delimeters) nil t) |
|---|
| 101 | (setq open (+ open 1))) |
|---|
| 102 | (goto-char cursor) |
|---|
| 103 | (while (search-backward (cdr delimeters) nil t) |
|---|
| 104 | (setq close (+ close 1))) |
|---|
| 105 | ;; (message "delimeters = %s : open %s : close %s : return %s : same delimeters = %s" |
|---|
| 106 | ;; cursor open close (eq open close) (string-equal (car delimeters) (cdr delimeters))) |
|---|
| 107 | ;; (sit-for 1) |
|---|
| 108 | (goto-char cursor) |
|---|
| 109 | (not (eq open close)))))))) |
|---|
| 110 | |
|---|
| 111 | (provide 'shutter) |
|---|