1 ;;; tinypair.el --- Self insert character (pa)irs () "" '' <>
3 ;; This file is not part of Emacs
7 ;; Copyright (C) 1995-2007 Jari Aalto
8 ;; Keywords: extensions
10 ;; Maintainer: Jari Aalto
12 ;; To get information on this program, call M-x tinypair-version.
13 ;; Look at the code with folding.el.
17 ;; This program is free software; you can redistribute it and/or modify it
18 ;; under the terms of the GNU General Public License as published by the Free
19 ;; Software Foundation; either version 2 of the License, or (at your option)
22 ;; This program is distributed in the hope that it will be useful, but
23 ;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 ;; You should have received a copy of the GNU General Public License
28 ;; along with program; see the file COPYING. If not, write to the
29 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
30 ;; Boston, MA 02110-1301, USA.
32 ;; Visit <http://www.gnu.org/copyleft/gpl.html> for more information
37 ;; ....................................................... &t-install ...
38 ;; Put this file on your Emacs-Lisp load path, add following into your
39 ;; ~/.emacs startup file.
41 ;; ** MINOR MODE IS GLOBALLY ACTIVED WHEN YOU LOAD THIS FILE **
43 ;; ;; If you don't want global activation, use
44 ;; ;; (defvar tinypair-mode nil)
46 ;; (require 'tinypair)
47 ;; (tinypair-pair-type-select 'us) ;; US `style'
48 ;; (tinypair-pair-type-select 'european) ;; European 'style'
50 ;; Or use autoload and your Emacs starts faster
52 ;; (autoload 'turn-on-tinypair-mode "tinypair")
53 ;; (add-hook <your-favourite-mode-hook> 'turn-on-tinypair-mode)
55 ;; If you want to turn the pairing off, use this:
57 ;; M-x turn-off-tinypair-mode
59 ;; If you have any questions, use this function
61 ;; M-x tinypair-submit-bug-report
63 ;; If you find any incorrect behavior, please immediately
65 ;; o Turn on debug M-x tinypair-debug-toggle
72 ;; ..................................................... &t-commentary ...
77 ;; Pacakge paired-insert.el was posted to gnu.emacs.help group, and
78 ;; the code was not very well documented, The code showed lot of
79 ;; promises, but it lacked smart pairing, so this package was born instead.
81 ;; Overview of features
83 ;; o Minor mode for paired characters.
84 ;; o [] {} <> '' `' ""
88 ;; *Remember* Always ask youself "Does this character the cursor is
89 ;; on, belong to _word_ class?", when you wonder why the pairing does
90 ;; not take in effect around the current character block.
92 ;; The pair control is turned off for lisp mode, because it makes
93 ;; things worse if the pairing is on. The pairing in US style includes
97 ;; But European people almost never use backquote, intead they use:
101 ;; General pairing rules, just some of them
103 ;; The pairing is done according to assoc lists in the following way:
105 ;; o if there is whitespace in front of char, then pair is inserted
106 ;; o if character is over pair-end, no pairing takes effect.
107 ;; Like if you press opening paren when you're sitting on the
111 ;; * <-- cursor here, pressing another ( does not pair.
113 ;; but this behavior can be controlled through variable
115 ;; o if the cursor is at the beginning of the word (see syntax-table):
116 ;; -- if there is no pairs around the word, the whole word is paired.
117 ;; -- if there is pair, no pairing takes effect. The char acts as
118 ;; self-insert-command.
120 ;; o if previous character is word. then the ' doesn't pair. Reason
121 ;; is in english language .........................^
123 ;; o if character is repeated with prefix arg, the pairing isn't done,
124 ;; instead the character is repeated as in self-insert-command.
126 ;; Cursor positioning
128 ;; By default the cursor is positioned in the "middle" of the inserted
129 ;; pair chars. But for words, this is impossible, because there is no
130 ;; middle position. Please see the variables
132 ;; tinypair-:word-positioning
133 ;; tinypair-:word-positioning-function
135 ;; which allow you to customize cursor positioning after word pairing.
137 ;; Word about syntax tables
139 ;; Syntax table play a major part in pairing, especially pairing words
140 ;; correctly. Suppose you're writing in text mode:
142 ;; ...txt txt... (help is the key)
145 ;; If you now press " to have the word HELP paired, you don't get it,
146 ;; because normally text mode's syntax table says that "(" belongs
147 ;; to group "w" (word) too. So the actual word is seen as "(help" and
148 ;; the program determines that you're inside a word, thus not
149 ;; allowing the pairing.
151 ;; In the other hand, if you were in any other mode, say in C++, the
152 ;; "(" is defined as open parenthesis syntax and it that case the
153 ;; seen word seen would have been "help" and the " character would have
154 ;; been added around the HELP string. Like this:
156 ;; ...txt txt... ("help" is the key)
159 ;; You may propably want quickly to see the syntax definition of
160 ;; characters; use function from my lisp libraries
162 ;; (defalias 'syntax-info 'ti::string-syntax-info)
164 ;; To return to this syntax problem in text mode, you could do the
165 ;; following, to make certain characters out of "w" class.
167 ;; (defun my-syntax-default (table )
168 ;; "My syntax table settings."
169 ;; (modify-syntax-entry ?[ "_" table)
170 ;; (modify-syntax-entry ?] "_" table)
171 ;; (modify-syntax-entry ?{ "_" table)
172 ;; (modify-syntax-entry ?} "_" table)
173 ;; (modify-syntax-entry ?( "_" table)
174 ;; (modify-syntax-entry ?) "_" table)
175 ;; (modify-syntax-entry ?/ "." table)
176 ;; (modify-syntax-entry ?\' "\"" table)
177 ;; (modify-syntax-entry ?\" "\"" table)
178 ;; (modify-syntax-entry ?_ "w" table))
180 ;; Then you just change the definitions of syntax table in hook:
182 ;; (setq text-mode-hook 'my-text-mode-hook)
183 ;; (defun my-text-mode-hook ()
184 ;; (my-syntax-default text-mode-syntax-table))
186 ;; Do you wonder why I put {}()[] into "_" class and not in
187 ;; corresponding "(" or ")" classes? Well, my stig-paren just went
188 ;; beserk and started beeping the bell whenever I was nearby
189 ;; ")" class... The "_" shut it down, so I just chose it. You can
190 ;; of course put the chars into any class you like.
203 (eval-when-compile (ti::package-use-dynamic-compilation))
205 (ti::package-defgroup-tiny TinyPair tinypair-: extensions
206 "self insert character pairs () \"\" '' <>
209 o When you hit e.g. \", package will double the character. If you
210 insertion point was on whitespace, the pair is inserted 'as
211 is', but if point was in front of word, the word is surrounded
212 with pair, provided that there we no pair already.
213 o Every pair beginning character may have it's own function
214 to handle the pairing.")
219 (defcustom tinypair-:load-hook nil
220 "*Hook that is run when package is loaded."
227 (defvar tinypair-:us-alist
231 (?\< ?\> tinypair-c-\<)
232 (?\` ?\' tinypair-c-\')
233 (?\" ?\" tinypair-c-\"))
234 "Default US pairing alist.")
236 (defvar tinypair-:european-alist
240 (?\< ?\> tinypair-c-\<)
241 (?\' ?\' tinypair-c-\')
242 (?\` ?\` nil) ;in perl, or shell you need backticks
243 (?\" ?\" tinypair-c-\"))
244 "Default European pairing alist.")
246 (defvar tinypair-:alist tinypair-:us-alist
247 "The pairing alist '((?BEG-CHAR ?END-CHAR FUNC-SYM) ..)
248 The FUNC-SYM element is optional. FUNC definition should have form,
257 t force immediate pairing
258 nil pairing prohibited, main should insert char \"as is\"
259 nbr return control to main program.
260 sym func handled pairing, main program should terminate.
262 If the func element is missing, pairing is done always according to main
263 function's decision.")
265 ;;; ........................................................ &v-public ...
266 ;;; User configurable
268 ;; - Since not all people program with perl-mode when coding perl
269 ;; (I don't use it), the default function here is not always
271 ;; - For detecting buffer contents in more robust way that just
272 ;; relying on the major-mode variable, see this
274 ;; tinylibid.el -- Identifying buffer regardless of mode
276 (defcustom tinypair-:all-pairing-disabled-function
277 'tinypair-check-if-pairing-allowed
278 "*Funtion to determine if any pairing is allowed.
279 Takes no args, and must return nil or non-nil.
280 If return value is non-nil, pairing is allowed."
284 (defcustom tinypair-:disable-mode-list
296 lisp-interaction-mode
298 compilation-minor-mode
306 Electric-buffer-menu-mode ;; std emacs ebuff-menu.el
307 Buffer-menu-mode ;; std Emacs
308 bs-mode) ;; bs.el by <Olaf.Sylvester@kiel.netsurf.de>
309 "*List of `major-mode' symbols, where the pairing is prohibited.
310 This variable is used by function `tinypair-check-if-pairing-allowed' which is
311 the default Manager for pairing. If you
312 change `tinypair-:all-pairing-disabled-function', this variable is not used."
313 :type '(repeat symbol)
316 (defcustom tinypair-:automatic-word-pairing t
317 "*If non-nil, then the word pairing is allowed.
318 Eg when your cursor is at the beginning of word, pressing
319 pair-beg char will pair the whole word.
325 (defcustom tinypair-:word-positioning-function
326 'tinypair-word-position-function
327 "*Function to position the cursor after pairing.
328 The value can also be a function symbol, which takes care of positioning
329 the cursor. Passed parameters are:
331 BEG-POINT ,point+1 where the beg-char were inserted
334 If function returns, non-nil it is assumed that function handled the
335 positioning. If it returns nil, then the control is returned to calling
336 program and the positioning is done according to variable
337 `tinypair-:word-positioning'"
341 (defcustom tinypair-:word-positioning 'end
342 "*How the cursor should be positioned after word pairing.
343 'beg ,leave point after beg pair char
344 'end ,leave point after end pair char"
350 (defcustom tinypair-:word-syntax-classes '(?w ?$ ?. )
351 "*List of syntax classes that are treated like WORD while pairing.
352 Eg if you have following text in LaTeX mode:
355 * <-- cursor here, now you want to pair it with (
357 You would normally get
362 Because the character $ is in class $. (You can check the class with
363 function `tinypair-syntax-info'). But when the is defined into this variable's
364 list, it is seen as \"word\", and the pairing is done like for word,
365 so that you get this:
369 :type '(repeat character :tag "syntax class")
375 ;;;###autoload (autoload 'tinypair-version "tinypair" "Display commentary." t)
378 (ti::macrof-version-bug-report
382 "$Id: tinypair.el,v 2.47 2007/05/01 17:20:51 jaalto Exp $"
383 '(tinypair-:version-id
387 tinypair-:european-alist
389 tinypair-:all-pairing-disabled-function
390 tinypair-:disable-mode-list
391 tinypair-:automatic-word-pairing
392 tinypair-:word-positioning-function
393 tinypair-:word-positioning
394 tinypair-:word-syntax-classes)
395 '(tinypair-:debug-buffer)))
400 ;;; ............................................................ &mode ...
402 ;;;###autoload (autoload 'tinypair-mode "tinypair" "" t)
403 ;;;###autoload (autoload 'turn-on-tinypair-mode "tinypair" "" t)
404 ;;;###autoload (autoload 'turn-off-tinypair-mode "tinypair" "" t)
405 ;;;###autoload (autoload 'tinypair-commentary "tinypair" "" t)
407 (defvar tinypair-mode t
408 "*Minor mode on/off flag.")
410 (make-variable-buffer-local 'tinypair-mode)
412 (ti::macrof-minor-mode-wizard
413 "tinypair-" " p" nil "Pair" 'TinyUrl "tinypair-:"
414 "Paired insert of characters.
418 \\{tinypair-:mode-map}"
422 ;; The Menubar item takes space and is not useful at least not
423 ;; now, because there is no other functionality in this mode.
427 (define-key root-map "<" 'tinypair-self-insert-command)
428 (define-key root-map "(" 'tinypair-self-insert-command)
429 (define-key root-map "{" 'tinypair-self-insert-command)
430 (define-key root-map "[" 'tinypair-self-insert-command)
431 (define-key root-map "\"" 'tinypair-self-insert-command)
432 (define-key root-map "'" 'tinypair-self-insert-command)
433 (define-key root-map "`" 'tinypair-self-insert-command)
434 (define-key root-map "\C-c\"" 'tinypair-pair-type-select)))
436 ;;;### (autoload 'tinypair-debug-toggle "tinypair" t t)
438 (eval-and-compile (ti::macrof-debug-standard "tinypair" "-:"))
440 (defalias 'tinypair-syntax-info 'ti::string-syntax-info)
442 ;;; ----------------------------------------------------------------------
444 (defsubst tinypair-word-class-p (class)
445 "Check if CLASS of part of logical word classes."
446 (memq class tinypair-:word-syntax-classes))
448 ;;; ----------------------------------------------------------------------
450 (defun tinypair-whitespace-p ()
451 "Check that current point is sitting alone. No word next to it."
452 (let ((prev (char-to-string (or (preceding-char) ?\n )))
453 (next (char-to-string (or (following-char) ?\n ))))
454 (and (string-match "[ \000\t\n\f\r]" prev)
455 (string-match "[ \000\t\n\f\r]" next))))
457 ;;; ----------------------------------------------------------------------
459 (defun tinypair-word-class-skip (&optional back)
460 "Skip forward all `tinypair-:word-syntax-class' characters. Optionally BACK."
461 (let* ((ptr tinypair-:word-syntax-classes)
463 'skip-syntax-backward
464 'skip-syntax-forward))
467 (funcall func (char-to-string (car ptr)))
468 (if (eq (point) point)
470 ;; moved, start over.
472 (setq ptr tinypair-:word-syntax-classes)))))
474 ;;; ----------------------------------------------------------------------
476 (defun tinypair-word-beginning-paired-on-line (char-string)
477 "Search backward CHAR-STRING and check if it's next to word in current line.
478 The point is not preserved.
479 See `tinypair-:word-syntax-classes' for word definition."
481 (when (search-backward char-string (line-beginning-position) t)
482 (if (tinypair-word-class-p (char-syntax (ti::buffer-read-char nil 1)))
485 ;;; ----------------------------------------------------------------------
487 (defun tinypair-elt-beg (elt)
488 "Return begin pair from ELT."
491 (defun tinypair-elt-end (elt)
492 "Return end pair from ELT."
495 (defun tinypair-elt-func (elt)
496 "Return func from ELT."
497 (if (= (length elt) 3)
504 ;;; ----------------------------------------------------------------------
505 ;;; "c" refers to "checking func"
507 (defun tinypair-c-\' (ch1 ch2)
508 "Check if tick ' character can be paired."
509 (setq ch1 ch2) ;; Byte compiler silencer
510 ;; - Check previous character. If it is a word, assume that user is
511 ;; writing regular text, like "I'm, it's, he's"
512 ;; - In fact this test is useful in old perl code too, where
513 ;; one writes "$package'variable".
515 ((tinypair-word-class-p (char-syntax (preceding-char)))
520 ;;; ----------------------------------------------------------------------
522 (defun tinypair-c-\< (ch1 ch2)
523 "Check if < character can be paired. In HTML mode when there
524 is tag end,\"slash\", it's not desirable to have <>. Several other HTML
525 cases are checked too."
526 (setq ch1 ch2) ;; Byte compiler silencer
529 ((memq (following-char) '(?/ ))
531 ((eq major-mode 'shell-mode)
533 ((and nil ;; currently disabled
534 (not (tinypair-whitespace-p))
535 (tinypair-word-beginning-paired-on-line "<"))
537 ((or (looking-at "a[ \t]+href")
538 (looking-at "hr[ \t]\\(size\\|wid\\)") ;1.1N <hr size=..>
539 (looking-at "\\(th\\|tr\\)[ \t]align") ;1.1N tables
540 (looking-at "p[ \t]+align") ;1.1N <p align=..>
541 (looking-at "\\(link\\|img\\|form\\) "))
542 ;; The word pairing isn't good in sgml/html mode.
545 ;; <A HREF="http://www.interplay.com">Interplay</a>
546 ;; <LINK REV="company" HREF="http://www.interplay.com">
551 ;;; ----------------------------------------------------------------------
553 ;;; It's like you have opened ne quote
555 ;;; * ,point here, and you want to end the quote..
557 ;;; In this case the pairing isn't desiredable
559 (defun tinypair-c-\" (ch1 ch2)
560 "Check if \" character can be paired. Looks backward if previous word
563 (let* ((ret 1) ;default is main handling
566 ;; The prev is nil if point is in BOB
567 (setq prev (char-syntax (or (ti::buffer-read-char nil -1) ?\ )))
569 (tinypair-word-class-p prev))
572 ;; "This statement has been paired"
575 ;; If we find QUOTE next to WORD, then we assume that this
576 ;; is just closing QUOTE and we won't pair it
577 (if (tinypair-word-beginning-paired-on-line "\"")
580 (skip-syntax-backward "w")
581 ;; point must move, because the skip-syntax will skip
583 ;; 2 1 1= before 2, after
584 ;; and reading that first " require backward char
585 (when (and (not (= point (point))) ;require movement
587 (prog1 t (forward-char -1)) ;now we can move
588 ;;; (ti::d! (following-char) ch1)
589 (eq (following-char) ch1))
597 ;;; ----------------------------------------------------------------------
599 (defun tinypair-check-if-pairing-allowed ()
600 "Function to determine if pairing is allowed.
601 Returns t, when pairing is allowed for buffer."
602 (not (memq major-mode tinypair-:disable-mode-list)))
604 ;;; ----------------------------------------------------------------------
606 (defun tinypair-move (count)
608 ((or (not (integerp count))
612 (backward-char (/ count 2)))))
614 ;;; ----------------------------------------------------------------------
615 ;;; - I used this before, may use it again...
617 (defun tinypair-move-logical-word (&optional count)
618 "Move forward, skipping `tinypair-:word-syntax-classes' COUNT times."
621 (back (if (< count 0)
624 (func (if back 'skip-chars-backward
625 'skip-chars-forward)))
627 (funcall func " \f\t\r\n") ;ignore whitespace
628 (tinypair-word-class-skip back)
631 ;;; ----------------------------------------------------------------------
633 (defun tinypair-word-position-function (beg char)
634 "Special cursor positioning function.
635 BEG is start point and CHAR is starting pair character."
638 ;; Mostly in minibuffer and for lisp'ish things, put cursor
639 ;; after starting paren.
641 ((or (char= char ?\' ) ;Move to next word.
645 (skip-chars-forward " \t\f")
646 (unless (tinypair-whitespace-p)
647 (setq point (point))))
652 ;;; ----------------------------------------------------------------------
654 (defun tinypair-word-pair (arg ch-beg ch-end)
655 "Insert pair around word(s) ARG times using CH-BEG and CH-END."
656 (let* ((fid "tinypair-word-pair: ")
657 (pos-flag tinypair-:word-positioning)
658 (pos-func tinypair-:word-positioning-function)
663 syntax-now syntax-prev
666 (setq syntax-prev (char-syntax
667 (setq ch1 (or (preceding-char) ?\ ))))
668 (setq syntax-now (char-syntax
669 (setq ch2 (or (following-char) ?\ ))))
670 ;; No-ops. XEmacs byte ocmpiler silencers
679 (char-to-string syntax-now)
681 (char-to-string syntax-prev)
683 (tinypair-word-class-p syntax-now)
685 (tinypair-word-class-p syntax-prev)
689 (char-to-string ch2))
693 (tinypair-word-class-p syntax-now)
694 ;; the $ character is consudered word in programming
695 ;; modes, so treat it specially. So is Perl's %
699 ;; The wanted behavior is
701 ;; ${PATH} not ${}PATH
703 (or (null (tinypair-word-class-p syntax-prev))
704 (ti::char-in-list-case ch1 '(?$ ?%))))
705 (setq count (if (null arg)
708 (if (< count 0) ;switch the values
709 (setq tmp ch-beg ch-beg ch-end ch-end tmp))
712 (tinypair-move-logical-word count)
713 (setq read-ch (or (ti::buffer-read-char nil 0) ?\ ))
714 (tinypair-debug fid "count" count
717 (char-to-string read-ch)
718 (char-to-string ch-end))
719 (unless (char= read-ch ch-end)
722 (insert (ti::string-repeat arg ch-beg)))
724 (tinypair-debug fid "default")
725 (insert ch-beg ch-end)
727 (setq pos-flag nil)))
728 ;; ............................................ cursor positioning ...
729 (setq tmp nil) ;"status" of call
730 (and (fboundp pos-func)
732 (setq tmp (funcall pos-func beg ch-beg)))
733 (tinypair-debug fid "cursor>>" beg (fboundp pos-func) tmp)
735 ((not (null tmp)) ;function handled this.
746 ;;; ----------------------------------------------------------------------
748 (defun tinypair-pair-type-select (&optional arg)
749 "Pairing control center.
751 nil 'us 'usa Use US pairing.
752 other value Use European pairing style."
755 (message "TinyPair: Selected %s pairing style "
756 (if arg "European" "US" )))
758 ((memq arg '(nil us usa))
759 (setq tinypair-:alist tinypair-:us-alist))
761 (setq tinypair-:alist tinypair-:european-alist))))
763 ;;; ----------------------------------------------------------------------
764 ;;; - Original idea in 19.29+ package paired-insert.el. Unfortunately the
765 ;;; package didn't satisfy my needs, so here is better pairing func.
767 ;;; - the 'pair' variable in this function is purposively set
768 ;;; many times, although it is not always necessary. It is just eases
769 ;;; following the program flow.
771 (defun tinypair-self-insert-command (arg)
772 "Smart pairing. ARG is repeat count of character."
774 (let* ((fid "tinypair-self-insert-command: ")
775 (nbr (prefix-numeric-value arg))
776 (word-pair tinypair-:automatic-word-pairing)
777 (ch last-command-char)
778 (elt (assoc ch tinypair-:alist))
779 ;; If TinyEf is active in minibuffer prompt, turn ourself off.
781 (if (and (boundp 'tief-mode)
782 (symbol-value 'tief-mode))
784 (if (fboundp tinypair-:all-pairing-disabled-function)
785 (funcall tinypair-:all-pairing-disabled-function)
787 (pair nil) ;pair control
788 (status 1) ;see user configuration CHAR-FUNC
789 direction ;character looking at cmd
790 ch-func ;character function
797 'CHAR (char-to-string ch)
800 'PAIR-ALLOW-FLAG pair-allow
805 (turn-off-tinypair-mode)
806 ;; This isn't exactly right, e.g. in some modes the "'" or any pairing
807 ;; character is not a self-insert-command, but a keymap prefix.
808 ;; We run `self-insert-command' only if buffer is NOT read-only.
809 (unless buffer-read-only
810 (self-insert-command nbr)))
811 ((null elt) ;Not defined for pairing
812 (self-insert-command nbr))
814 ;; ... ... ... ... ... ... ... ... ... ... ... ... .. do pairing . .
815 (setq ch-beg (tinypair-elt-beg elt))
816 (setq ch-end (tinypair-elt-end elt))
817 (setq ch-func (tinypair-elt-func elt))
818 (setq syntax-now (char-syntax (setq ch-now (following-char))))
819 (tinypair-debug fid 'POINT (point) ch-func)
820 (if (fboundp ch-func)
821 (setq status (funcall ch-func ch-beg ch-end)))
823 "CH-NOW" (char-to-string ch-now)
825 "CH-END" (char-to-string ch-end)
828 "SYNTAX-NOW" (char-to-string syntax-now))
834 (if (> arg -1) nil 'back))
837 ;; No-ops. XEmacs byte compiler silencers
839 (setq direction nil))
842 (tinypair-debug fid "direction" (or direction 'forward)
843 "WORD-PAIR" word-pair)
845 ;; ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
846 ((char= ch-now ch-end) ;already pair visible
847 (tinypair-debug fid "now = End"))
848 ;; ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
849 ((char= syntax-now ?\ ) ;whitespace at point
850 (setq pair t) ;ok, do pairing
851 (tinypair-debug fid "Whitespace 1 1 t"))
853 ;; ... ... ... ... ... ... ... ... ... ... ... ... ... words ..
855 ;; handle smart pairing.
858 (tinypair-debug fid "default word")
859 (setq arg 1 pair t))) ;main COND
860 ;; ... ... ... ... ... ... ... ... ... ... ... insert chars ? ...
861 (tinypair-debug fid "Doing... ARG; PAIR-flag" arg pair )
864 (tinypair-word-pair arg ch-beg ch-end))
866 (tinypair-word-pair nil ch-beg ch-end))
868 (insert (ti::string-repeat nbr ch-beg)))))
869 ;; ... ... ... ... ... ... ... ... ... ... ... ... other status ..
873 (insert ch-beg ch-end)
880 (add-hook 'tinypair-:mode-define-keys-hook 'tinypair-mode-define-keys)
882 (ti::add-hooks '(minibuffer-setup-hook
885 gnus-summary-mode-hook
888 rmail-summary-mode-hook
890 vm-summary-mode-hook)
891 'turn-off-tinypair-mode)
894 (turn-on-tinypair-mode))
897 (run-hooks 'tinypair-:load-hook)
899 ;;; tinypair.el ends here