]> git.donarmstrong.com Git - lib.git/blob - emacs_el/tiny-tools/tiny/tiny-setup.el
add tiny-tools
[lib.git] / emacs_el / tiny-tools / tiny / tiny-setup.el
1 ;;; tiny-setup.el --- Tiny Tools configure center.
2
3 ;; This file is not part of Emacs
4
5 ;;{{{ Id
6
7 ;; Copyright (C)    2001-2007 Jari Aalto
8 ;; Keywords:        extensions
9 ;; Author:          Jari Aalto
10 ;; Maintainer:      Jari Aalto
11
12 ;; Look at the code with folding.el
13
14 ;; COPYRIGHT NOTICE
15 ;;
16 ;; This program is free software; you can redistribute it and/or modify it
17 ;; under the terms of the GNU General Public License as published by the Free
18 ;; Software Foundation; either version 2 of the License, or (at your option)
19 ;; any later version.
20 ;;
21 ;; This program is distributed in the hope that it will be useful, but
22 ;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24 ;; for more details.
25 ;;
26 ;; You should have received a copy of the GNU General Public License
27 ;; along with program; see the file COPYING. If not, write to the
28 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29 ;; Boston, MA 02110-1301, USA.
30 ;;
31 ;; Visit <http://www.gnu.org/copyleft/gpl.html> for more information
32
33 ;;}}}
34 ;;{{{ Install
35
36 ;; Nothing to install. Load this file.
37
38 ;;}}}
39
40 ;;{{{ Documentation
41
42 ;;; Commentary:
43
44 ;;  Preface, overview of options
45 ;;
46 ;;      This file will configure all Tiny Tool files. The alternative method
47 ;;      is to look into each package individually and to follow instructions
48 ;;      there to set up the files.
49 ;;
50 ;;      To use this file, see control function `tinypath-setup' for
51 ;;      full description. Try this:
52 ;;
53 ;;          M-x RET load-library RET tiny-setup RET
54 ;;          C-h f tinypath-setup
55 ;;          M-x tinypath-setup-display
56 ;;
57 ;;          M-x tiny-setup RET                       Default 'all setup
58 ;;
59 ;;       To setup all tools from $HOME/.emacs, use:
60 ;;
61 ;;          (load "~/path/to/tinypath.el")   ;; Emacs autosetup, SEE THIS!
62 ;;          (require 'tiny-setup)            ;; control center
63 ;;          (tiny-setup 'all)                ;; configure all at once.
64 ;;
65 ;;       To activate individual features:
66 ;;
67 ;;          (tiny-setup nil '(tinymy--defadvice))  ;; Add smart M-x compile
68 ;;
69 ;;      After you have loaded this file, have a look at the *Messages*
70 ;,      (Emacs) or *Message-Log* (XEmcs) buffers, where you can find
71 ;;      messgaes from the setup procedure.
72 ;;
73 ;;      Emacs 21.x news: Windowed Emacs modeline contains new feature,
74 ;;      where you can activate and deactivate minor modes. Shoot
75 ;;      modeline with your mouse and follow message: "Mouse-3: minor
76 ;;      mode menu". Minor modes available here are installed to that menu.
77 ;;
78 ;;  Administration
79 ;;
80 ;;      This part should concern the maintainer only.
81 ;;
82 ;;     Autoload files
83 ;;
84 ;;      If *loaddef* files were not included in the package or if they were
85 ;;      mistakenly deleted. The tiny-setup.el startup is not possible
86 ;;      without the autoload files.
87 ;;
88 ;;      To generate autoloads recursively, call function
89 ;;      `tiny-setup-autoload-batch-update' with the ROOT
90 ;;      directory of your lisp files. The only requirement is that each
91 ;;      directory name is unique, because the generated autoload file name
92 ;;      contains directory name: *tiny-autoload-loaddefs-DIRNAME.el*
93 ;;
94 ;;     Compilation check
95 ;;
96 ;;      To check for possible leaks in code, ran the byte compilation
97 ;;      function from shell by using XEmacs compiler. The Emacs byte
98 ;;      compiler is not that good in findings all errors.
99 ;;      See function `tiny-setup-compile-kit-all'.
100 ;;
101 ;;     Profiling
102 ;;
103 ;;      To check how much time each file load would take, see function
104 ;;      `tiny-setup-test-load-time-libraries'. Here are results as of
105 ;;      2001-03-18 running Win9x/512Meg/400Mhz, Emacs 20.7, non-compiled
106 ;;      files:
107 ;;
108 ;;          Timing tinyliba,  took     2.025000 secs (autoloads)
109 ;;          Timing tinylibb,  took     0.011000 secs
110 ;;          Timing tinylibm,  took     0.977000 secs
111 ;;          Timing tinylib,   took     0.982000 secs
112 ;;          Timing tinylibxe, took     0.000000 secs
113 ;;          Timing tinylibid, took     0.006000 secs
114 ;;          Timing tinylibo,  took     0.005000 secs
115 ;;          Timing tinylibt,  took     0.011000 secs
116 ;;          total time is 4.027999997138977 seconds
117
118 ;;}}}
119
120 ;;; Change Log:
121
122 ;;; Code:
123
124 (eval-when-compile
125   (require 'cl))
126
127 (require 'tinyliba)
128
129 (eval-and-compile
130   (defvar font-lock-mode)
131   (defvar mode-line-mode-menu) ;; Emacs only
132   (autoload 'tinydebian-install                 "tinydebian"   "" t)
133   (autoload 'tinydesk-edit-state-file           "tinydesk"     "" t)
134   (autoload 'tinydesk-unload                    "tinydesk"     "" t)
135   (autoload 'tinydesk-save-state                "tinydesk"     "" t)
136   (autoload 'tinydesk-recover-state             "tinydesk"     "" t)
137   (autoload 'byte-compile-file                  "bytecomp")
138   (autoload 'tinylisp-install                   "tinylisp"      "" t)
139   (autoload 'turn-on-tinylisp-mode              "tinylisp"      "" t)
140   (autoload 'ti::mail-mailbox-p                 "tinylibmail")
141   (autoload 'turn-on-tinymailbox-mode           "tinymailbox"   "" t)
142   (autoload 'turn-on-tinymailbox-mode-maybe     "tinymailbox"   "" t)
143   (autoload 'folding-uninstall                  "folding"       "" t)
144   (autoload 'folding-install-hooks              "folding")
145   (autoload 'turn-on-folding-mode               "folding"       "" t)
146   (autoload 'dired-sort-default-keys            "dired-sort")
147   (autoload 'tinymy-define-keys-extra           "tinymy")
148   (autoload 'tinymy-compile-run-command-advice  "tinymy"        "" t)
149   (autoload 'tinymy-define-keys                 "tinymy")
150   (autoload 'tinyef-minibuffer-define-key-extras "tinyef"      "" t)
151   (autoload 'turn-on-tinyef-mode                "tinyef"        "" t)
152   (autoload 'turn-on-tinypair-mode              "tinypair"      "" t)
153   (autoload 'turn-off-tinypair-mode             "tinypair"      "" t)
154   (autoload 'turn-on-tinyperl-mode-all-buffers  "tinyperl"      "" t)
155   (autoload 'tinyrmail-install                  "tinyrmail"     "" t)
156   (autoload 'turn-on-tinycompile-mode           "tinycompile"   "" t)
157   (autoload 'tinytag-install-sample-databases   "tinytag"       "" t)
158   (autoload 'turn-on-tinytf-mode                "tinytf"        "" t)
159   (autoload 'turn-on-tinyurl-mode               "tinyurl"       "" t))
160
161 ;;  Copy from tinylib.el
162 (defmacro tiny-setup-ti::macrov-mode-line-mode-menu (mode-symbol text)
163   "Add MODE-SYMBOL to minor mode list in Emacs mode line menu."
164   (let ((sym  (vector (intern (symbol-name (` (, mode-symbol)))))))
165     (` (when (boundp 'mode-line-mode-menu) ;; Emacs 21.1
166          (define-key mode-line-mode-menu (, sym)
167            '(menu-item (, text)
168                        (, mode-symbol)
169                        :button (:toggle . (, mode-symbol))))))))
170
171 (defvar tiny-setup-load-hook nil
172   "*Hook run when package is loaded.")
173
174 (defconst tiny-setup-:library-compile-order
175   '("tinylibenv.el"
176     "tinyliba.el"
177     "tinylibm.el"
178     "tinylibb.el")
179   "Order of compilation of the libraries.
180 This variable is list of REGEXPS.")
181
182 (defconst tiny-setup-:library-compile-exclude
183   '("tinylib-ad.el") ;; adviced functions
184   "Libraries not to compile.")
185
186 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
187 ;;
188 ;;
189 ;;      SETUP CHOICES
190 ;;
191 ;;
192 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
193
194 ;;  See list of file descriptions with this bash script:
195 ;;
196 ;;      head -1 $(ls *el | sort) | grep ';;'
197
198 (defconst tiny-setup-:option-table
199   '(("dired-sort"
200      ("Dired sort package. Defines `s' key prefix to dired.")
201      ("autoload"))
202
203     ("folding"
204      ("Folding content management package. Detect {{{ and }}}.")
205      ("autoload"))
206
207     ("tinyadvice"
208      "Collection of advised functions."
209      ("load"))
210
211     ("tinyappend"
212      "A simple text gathering to buffer utility."
213      ("bind" "bindforce"))
214
215     ("tinybookmark"
216      "Keep file in organized sections."
217      ("bind"))
218
219     ("tinybuffer"
220      "Change buffers in current window."
221      ("bind" "bindforce"))
222
223     ("tinycache"
224      "Maintain a cache of visited files [compile, dired]."
225      ())
226
227     ("tinychist"
228      "Command history save/restore utility."
229      ())
230
231     ("tinycygwin"
232      "Cygwin bug reporting interface and other Cygwin utilities."
233      ()) ;;#todo:
234
235     ("tinycomment"
236      "Smart comment setting utility."
237      ("autoload" "bind"))
238
239     ("tinycompile"
240      "Compile buffer additions. Minor mode."
241      ("autoload"))
242
243     ("tinydesk"
244      "Save and restore files between Emacs sessions."
245      ("activate" "bind" "bindforce"))
246
247     ("tinydiff"
248      "Diff and patch minor mode. Browsing, patching."
249      ("autoload" "bind" "bindforce"))
250
251     ("tinydebian"
252      "Debian Linux utilities for system administrator. Bug reports etc."
253      ("autoload" "load"))
254
255     ("tinydired"
256      "Dired enhancements. Background Ange ftp support."
257      ("autoload"))
258
259     ("tinyeat"
260      "Eat blocks of text at point, forward and backward."
261      ("bind" "bindforce"))
262
263     ("tinyef"
264      "(E)lectric (f)ile minor mode. Easy C-x C-f filename composing."
265      ("autoload" "bindextra"))
266
267     ("tinygnus"
268      "Gnus Plug-in. Additional functions. Spam complain and more."
269      ("autoload"))
270
271     ("tinyhotlist"
272      "Hot-list of important buffers and  files. Entry can be ange-ftp or dired too."
273      ("autoload" "bind" "bindforce" "bindmouse"  "bindmouseforce"))
274
275     ("tinyigrep"
276      "Top level interface to igrep.el."
277      ("autoload" "bind" "bindforce"))
278
279     ;;  there is nothing to setup in libraries. These are already
280     ;;  autoloaded in tinyliba.el
281
282     ("tinylib-ad"
283      "Library of advised functions. Backward compatibility."
284      ())
285     ("tinylib"
286      "Library of general functions."
287      ())
288     ("tinyliba"
289      "Library for (a)utoload definitions."
290      ())
291     ("tinylibb"
292      "Library of (b)ackward compatible functions."
293      ())
294     ("tinylibck"
295      "Library to (c)onvert (k)eybindings for XEmacs or Emacs."
296      ())
297     ("tinylibenv"
298      "Library for environment check functions."
299      ())
300     ("tinylibid"
301      "Library for (Id)entifying buffer, regardless of mode."
302      ())
303     ("tinylibm"
304      "Library of s(m)all macros or functions."
305      ())
306     ("tinylibmenu"
307      "Library for echo-area menu."
308      ())
309     ("tinylibmail"
310      "Library of (m)ail and news (t)ool functions."
311      ())
312     ("tinylibo"
313      "Library for handling (o)verlays."
314      ())
315     ("tinylibt"
316      "Library for handling text properties."
317      ())
318     ("tinylibxe"
319      "Library for Emacs and XEmacs emulation."
320      ())
321     ("tinyliby"
322      "Library of functions related to Emacs s(y)stem."
323      ("defalias"))
324
325     ("tinylisp"
326      "Emacs lisp programming help grab-bag."
327      ("autoload" "activate"))
328
329     ("tinyload"
330      "Load set of packages when Emacs is idle (lazy load)."
331      ())
332
333     ;;  This asks lock password at startup, can't define "load" option
334     ;;  for this for unattended load.
335
336     ("tinylock"
337      "Simple Emacs locking utility."
338      ()) ;;#todo:
339
340     ("tinylpr"
341      "Easy Emacs lpr command handling, pop-up, completions."
342      ("bind"))
343
344     ("tinymacro"
345      "Fast way to assign newly created macro to a key. Redefines C-x )"
346      ("bind" "bindforce"))
347
348     ("tinymail"
349      "Mail add-ons. Report incoming mail, passwd, BBDB complete."
350      ("autoload"))
351
352     ("tinymailbox"
353      "Berkeley style mailbox browsing minor mode."
354      ("autoload"))
355
356     ("tinymy"
357      "Collection of user (`my') functions. Simple solutions."
358      ("load" "bind" "bindforce" "defalias" "defadvice"))
359
360     ("tinynbr"
361      "Number conversion minor mode oct/bin/hex."
362      ("autoload")) ;; Already autoloaded. M-x turn-on-tinynbr-mode
363
364     ("tinypad"
365      "Emulate Windows notepad with extra menu."
366      ("autoload"))
367
368     ("tinypage"
369      "Handling ^L pages. Select, cut, copy, renumber headings etc."
370      ("autoload" "bind"))
371
372     ("tinypair"
373      "Self insert character (pa)irs () \"\" '' <>."
374      ("autoload" "activate"))
375
376     ;; Please see the documentation in this file
377     ;; LOAD tinypath.el AS VERY FIRST PACKAGE. Before even tiny-setup.pl
378
379     ("tinypath"
380      "Manage Emacs startup dynamically."
381      ())
382
383     ("tinyperl"
384      "Grab-bag of Perl language utilities. Pod documentation browser."
385      ("autoload"))
386
387     ("tinypgp"
388      "PGP minor mode, remailing, keyring management."
389      ())
390
391     ("tinyprocmail"
392      "Procmail minor mode and coding checker. See http://www.procmail.org/"
393      ("autoload"))
394
395     ("tinyreplace"
396      "Handy query-replace, area, case preserve, words."
397      ("bind"))
398
399     ("tinyrmail"
400      "RMAIL add-ons, pgp, mime labels, Spam complaint."
401      ("autoload"))
402
403     ("tinyscroll"
404      "Enable or Disable auto-scroll for any buffer."
405      ("autoload"))
406
407     ("tinysearch"
408      "Grab and search word under cursor."
409      ("bind" "bindforce" "bindmousealt" "bindmousemeta"))
410
411     ("tinytab"
412      "Programmed TAB minor mode."
413      ("autoload" "bind" "bindforce" "bindextra" "bindextraforce"))
414
415     ("tinytag"
416      "Coding help. E.g. show Java/Perl/C++ function call syntax while coding."
417      ("autoload"))
418
419     ("tinytf"
420      "Document layout tool for '(T)echnical text (F)ormat."
421      ("autoload"))
422
423     ("tinyurl"
424      "Mark and jump to any URL on current line. Support also C, C++, Perl, Elisp."
425      ("autoload" "bind"))
426
427     ("tinyvc"
428      "CVS and RCS log minor mode. Check-out, Check-in."
429      ("autoload"))
430
431     ("tinyxreg"
432      "Restore points and window configurations stored in register via X-popup."
433      ("bind")))
434   "Packages and options. This variable is not user configurable.
435 Format is:
436  '((PACKAGE ((OPTION-STR ..) ..))).")
437
438 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
439 ;;
440 ;;
441 ;;      USER SPACE: CONFIGURE SETUP FOR ALL FILES
442 ;;
443 ;;
444 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
445
446 ;;; ----------------------------------------------------------------------
447 ;;;
448 ;;;###autoload
449 (defun tiny-setup (&optional type option-list)
450   "Tiny Tools setup controller. See Message buffer for results.
451
452 Please make sure you have run the makefile.pl with build option
453 \"all\" or \"autoload\". You can verify this by finding files which
454 contain word \"loaddefs\".
455
456 Autoload statements are always defined when this function is called,
457 so even if you do not define any options to be installed, they will be
458 available in callable functions that trigger loading packages. This
459 means, that you an call e.g function \\[tinytab-mode] and the call
460 will trigger loading package tinytab.el
461
462 Please notice, that this central setup function configures only the
463 essential packages, even with TYPE and FEATURE-LIST. The listing
464 \\[tiny-setup-display] lists many packages that are not loaded
465 or set up in any default way because a) package's scope is very narrow
466 and it may not interest the majority b) there is no sensible autoload
467 and it requires manual settings: tinyload.el and tinypath.el are
468 good example of this. c) package is a library and it has been
469 taken cared of by other means.
470
471 Remember that all functions are autoloaded and accessible, although
472 packages marked <no options> may not have default configurations. Here is
473 sample listing that you may expect from \\[tiny-setup-display] which
474 displays then content of `tiny-setup-:option-table' when no tiny-setup
475 configure options are not defined and you should load the package as
476 instructed in the file itself:
477
478     ..
479     tinychist            <no options defined to install>
480     ...
481                          Command history save/restore utility.
482     tinyload             <no options defined to install>
483                          Load set of packages when Emacs is idle (lazy load).
484     tinylock             <no options defined to install>
485                          Simple emacs locking utility.
486     ...
487     tinynbr              <no options defined to install>
488                          Number conversion minor mode oct/bin/hex.
489     ...
490     tinypath             <no options defined to install>
491                          Manage Emacs startup dynamically.
492
493 Here is one way to install packages: a) configure paths automatically b)
494 load default setup and enable some extra features c) define
495 delayed loading for some packages that you use most of the time.
496
497    (load \"/ABSOLUTE-PATH/tinypath.el\")
498
499    ;;  Define \"ready to use packages\"
500
501    (require 'tiny-setup)
502
503    (tinypath-setup
504      'all                       ;; Activate default features safely
505      ;; plus features that you want
506     '(tinyeat--bind
507       tinydesk--bindforce
508       tinymy--defadvice         ;;  Make M-x compile smarter
509       tinydiff--bind
510       tinydired--autoload
511       tinyef--bindextra
512       tinyeat--bindforce
513       tinymacro--bindforce
514       tinydesk--bindforce
515       tinypair--activate
516       tinylisp--activate        ;; turn on on in all .el buffers
517       ..))
518
519    ;; Delayed loading of these packages, when Emacs goes idle.
520
521    (setq tinyload-:load-list
522      '(\"tinyadvice\"           ;; NOTE: for Emacs only.
523        \"tinymy\"
524        \"tinymail\"
525        \"tinygnus\"
526        \"tinyigrep\"
527       ..))
528
529   (require 'tinyload)
530
531 Here is yet another example. The `tiny-setup' function can configure only
532 the very basic features. You can manually set default values before
533 packages are loaded (look into each file for interesting things).
534
535     ;; First, configure few packages MANUALLY
536
537     (require 'tinylibm)
538
539     (ti::add-hooks 'tinytf-:mode-define-keys-hook
540                    '(tinytf-mode-define-keys tinytf-mode-define-f-keys))
541
542     (setq tinymy-:define-key-force t)
543     (setq tinyef-:mode-key \"\\C-cmr\")
544
545     (setq tinylock-:auto-lock-interval1 45)     ;in minutes
546
547     (setq tinyef-:mode-key-table
548           '((?\[   . step-delete-back)          ;KEY -- action symbol
549             (?\]   . step-delete-fwd)
550             (?\*   . chunk-delete)
551             (?\;   . move-back)
552             (?\'   . move-fwd)
553             (?\~   . e-tilde)
554             (?\/   . e-slash)
555             (?\$   . e-dollar)))
556
557     ;; After that, let the central configure tool do the rest
558
559     (require 'tiny-setup)
560
561     (tiny-setup
562      'all
563      '(tinymy--bind-bindemacs
564        tinytab--bindforce-bindextra
565        tinyreplace--bindemacs
566        tinyeat--bindforce))
567
568 The major TYPE of installation can be one of the following:
569
570     'autoload
571
572     Setup packages so that they are loaded when the options are needed,
573     but do not define any key-bindings that already exist. This will
574     bind free keys to trigger loading packages.
575
576     'all
577
578     Configure with all options on. This will affect free key-bindings.
579
580     nil
581
582     Autoload files (functions are ready for calling), but
583     no defaults are configured unless OPTION-LIST is set.
584
585 Alternatively, you can select from OPTION-LIST what packages and what
586 options inside it will be installed. See list of packages and their
587 options with command \\[tiny-setup-display]
588
589     The syntax for each package is the same and the symbol passed is
590     composed from keywords:
591
592         <package>--   Name of package affected, like `tinyeat--'.
593
594         activate    Activate feature in all related buffers.
595                     Like turning on `tinylisp-mode' in all Emacs lisp
596                     buffers or `tinyperl-mode' in all perl files.
597
598         bind        Bind default keys. This will arrange package
599                     to an autoload state. When a certain key is pressed,
600                     package is loaded.
601
602         bindforce   Overwrite any existing Emacs binding. This is like
603                     bind, but without a safe check.
604
605         bindemacs   Bind keys that are known to be occupied in Emacs.
606
607         load        Load package. If you're tempted to use this,
608                     consider investing to more efficient method described
609                     in tinyload.el. Packages that have complex setup or
610                     which can't be autoloaded easily are categorized as
611                     \"load\".
612
613         autoload    Configure package so that it will get loaded if function
614                     related to a package is needed.
615
616     For example, to enable options in tinyadvice.el and tinyurl.el, you could
617     send option list below. Notice that multiple options for a package
618     are separated by single dashes.
619
620         (require 'tiny-setup)
621         (tinypath-setup 'all '(tinyadvice--load tinyurl--autoload-bind ...))
622                                                 |        |        |
623                                                 |        |        Option 2.
624                                                 |        Option 1.
625                                                 Package."
626   (interactive)
627   (when (and (interactive-p)
628              (eq type nil)
629              (eq option-list nil))
630     (setq type 'all))
631   (tiny-setup-autoload-read)
632   (cond
633    ((eq type 'all)
634     (tiny-setup-all nil))
635    ((eq type 'autoload)
636     (tiny-setup-all 'autoload-bind)))
637   (when option-list
638     (tiny-setup-option-process option-list))
639   (message "TinySetup: Done.%s"
640            (if (ti::xemacs-p)
641                " See buffer \" *Message-Log*\""
642              " See buffer *Messages*")))
643
644 ;;; ----------------------------------------------------------------------
645 ;;;
646 (defun tiny-setup-option-process (option-list)
647   "Process OPTION-LIST described in `tiny-setup'.
648 OPTION-LIST items items are in form:
649
650    PACKAGE--OPTION-OPTION-OPTION-..
651
652 Like
653
654    '(tinymy--bind-bindextra)
655              |    |
656              |    option 2
657              option 1
658
659 See also `tiny-setup-:option-table'."
660   (dolist (elt option-list)
661     (let* ((name (symbol-name elt))
662            (package (if (string-match "\\(^[^ \t-]+\\)--" name)
663                         (match-string 1 name))))
664       (if package
665           (tiny-setup-package package elt)
666         (message "TinySetup: Invalid setup option format %s" name)))))
667
668 ;;; ----------------------------------------------------------------------
669 ;;;
670 (defun tiny-setup-all (&optional type)
671   "Setup all tools with TYPE."
672   (dolist (elt tiny-setup-:option-table)
673     (tiny-setup-package (car elt) type)))
674
675 ;;; ----------------------------------------------------------------------
676 ;;;
677 ;;;###autoload
678 (defun tiny-setup-display (&optional no-descriptions)
679   "List all packages and available setup options.
680 With Argument, like, \\[universal-argument], list NO-DESCRIPTIONS."
681   (interactive "P")
682   (let* ((buffer (get-buffer-create "*tiny-setup*")))
683     (with-current-buffer buffer
684       (erase-buffer)
685       (insert "package              Supported install options\n"
686               "-----------          "
687               (make-string 30 ?-)
688               "\n")
689       (dolist (elt tiny-setup-:option-table)
690         (insert (format "%-20s %s\n%-20s %s\n"
691                         (car elt)
692                         (if (null (tiny-setup-nth-options elt))
693                             "<no options defined to install>"
694                           (mapconcat
695                            'identity
696                            (sort (tiny-setup-nth-options elt) 'string<)
697                            " "))
698                         ""
699                         (tiny-setup-nth-description elt))))
700       (insert "
701 The options can be installed by adding code like this to .emacs:
702
703     (require 'tiny-setup)
704     (tinypath-setup nil '(tinyadvice--load tinyurl--autoload-bind ...))
705 ")
706       (goto-char (point-min))
707       (display-buffer (current-buffer)))))
708
709 ;;; ----------------------------------------------------------------------
710 ;;;
711 (put 'tiny-setup-error-macro 'lisp-indent-function 0)
712 (put 'tiny-setup-error-macro 'edebug-form-spec '(body))
713 (defmacro tiny-setup-error-macro (&rest body)
714   "Show error."
715   (` (progn
716        (pop-to-buffer (get-buffer-create "*TinySetup Error*"))
717        (,@ body))))
718
719 ;;; ----------------------------------------------------------------------
720 ;;;
721 (put 'tiny-setup-dolist-buffer-list 'lisp-indent-function 0)
722 (put 'tiny-setup-dolist-buffer-list 'edebug-form-spec '(body))
723 (defmacro tiny-setup-dolist-buffer-list (&rest body)
724   "Run BODY in each buffer."
725   (`
726    (dolist (buffer (buffer-list))
727      (with-current-buffer buffer
728        (,@ body)))))
729
730 ;;; ----------------------------------------------------------------------
731 ;;;
732 ;;;###autoload
733 (defun tiny-setup-autoload-read ()
734   "Read all autoloads. Makefile must have been run for this to work.
735 Syntax in Tiny Tools kit bin/ directory: perl makefile.pl autoload."
736   (condition-case err
737       (progn
738         ;;  It's better to use `load' and not `require' because user may run
739         ;;  makefile again.
740         (load "tiny-autoload-loaddefs-tiny")
741         (load "tiny-autoload-loaddefs-other"))
742     (error
743      (let* ((str
744              (format
745               (concat
746                "\
747 TinySetup: Error in reading autoload loaddefs. %s
748
749 Symptoms: load-path:
750
751     Please check that your `load-path' contains directories
752     tiny/lisp/tiny and tiny/lisp/other.
753
754     To check your load path, run \\[tinypath-load-path-display]
755     or run this lisp code:
756
757        (insert (prin1-to-string load-path))
758                                            |
759                                            Put cursor here and press
760                                            C-u C-x C-e
761
762 Symptoms: autoload files:
763
764     Check that the tiny-autoload*el files are present in these directories.
765     If there is no autoload files, create them by running makefile:
766
767     cd bin/
768     perl makefile.pl --verbose 2 autoload.
769
770 Symptoms: compiled files
771
772     There may be problem with compiled  tiny-autoload*.elc files.
773     Please remove all *.elc files and try again.")
774               (prin1-to-string err))))
775        ;;  Write to *Message* buffer
776        (message str)
777        (tiny-setup-error-macro
778         (insert str
779                 "
780
781 Symptoms for tinypath.el usage:
782
783     If you use tinypath.el, it may be possible that it didn't find the
784     default ~/elisp or ~/lisp directories. Please move all your Emacs setup
785     files under one of these directories. Alternatively set the location
786     of your private lisp with:
787
788     (require 'cl)
789
790     (setq tinypath-:load-path-root '(\"~/your-lisp-dir-location\"))
791     (pushnew \"/ABSOLUTE/INSTALLATION-PATH/HERE\"
792              load-path
793              :test 'string=)
794     (load \"tinypath\")
795
796     (require 'tiny-setup)
797     (tiny-setup 'all)
798
799     Refer to doc/txt/README.txt in tiny-tools kit and
800     \\[tinypath-version] documentation for more instructions how to let
801     tinypath.el set the `load-path' automatically."))
802        (error str)))))
803
804 ;;; ----------------------------------------------------------------------
805 ;;;
806 (defun tiny-setup-option-strings (type)
807   "Return list of options from symbol TYPE."
808   (setq type (symbol-name type))
809   (if (not (string-match "--\\(.*\\)" type))
810       type
811     (split-string (match-string 1 type) "[-]")))
812
813 ;;; ----------------------------------------------------------------------
814 ;;;
815 (defun tiny-setup-package-require (package)
816   (message "TinySetup: %s loaded." package)
817   (unless (featurep (intern package))
818     (message "TinySetup: %s LOADED." package)
819     (require (intern package))))
820
821 ;;; ----------------------------------------------------------------------
822 ;;;
823 (defun tiny-setup-package-option-p (package opt option-list)
824   "Check if PACKAGE and OPT is part of user requested OPTION-LIST."
825   (let (ret)
826     (dolist (elt option-list)
827       (when (string= elt opt)
828         (setq ret t)
829         (return)))
830     (unless ret
831       (message "TinySetup: [%s] No option [] found for `%s'"
832                package
833                (if (eq 1 (length option-list))
834                    (car option-list)
835                  (prin1-to-string option-list))))
836     ret))
837
838 ;;; ----------------------------------------------------------------------
839 ;;;
840 (defun tiny-setup-package (package &optional type)
841   "Activate PACKAGE with TYPE.
842 If TYPE is nil, activate all options that do not contain word
843 `force' or `load'."
844   (let* ((req-options (and type
845                            (tiny-setup-option-strings type)))
846          (list     (tiny-setup-package-options package)))
847     (cond
848      ((null list)
849       (message "TinySetup: %-15s No options to configure."
850                package))
851      (t
852       (unless req-options ;; nil, activate almost all
853         (dolist (option list)
854           (unless (string-match "^load\\|force" option)
855             (push option req-options))))
856       (let* (function
857              sym)
858         (dolist (option req-options)
859           (cond
860            ((not (member option list))
861             (message "TinySetup: Unknown option %s. Choose from %s"
862                      option
863                      (prin1-to-string list)))
864            (t
865             (setq function (format "tiny-setup-%s-%s" package option))
866             (setq sym (intern-soft function))
867             (cond
868              ((and (null sym)
869                    (string= option "load"))
870               (tiny-setup-package-require package))
871              ((null sym)
872               (message "TinySetup: ERROR Unknown function %s"
873                        function))
874              (t
875               (setq function sym)
876               (message "TinySetup: %-15s configured with `%s'" package option)
877               (funcall function)))))))))))
878
879 ;;; ----------------------------------------------------------------------
880 ;;;
881 (defun tiny-setup-nth-options (elt)
882   "Return option list from ELT."
883   (nth 2 elt))
884
885 ;;; ----------------------------------------------------------------------
886 ;;;
887 (defun tiny-setup-nth-description (elt)
888   "Return option list from ELT."
889   (nth 1 elt))
890
891 ;;; ----------------------------------------------------------------------
892 ;;;
893 (defun tiny-setup-package-options (package)
894   "Return list of options for PACKAGE."
895   (let ((elt   (assoc package tiny-setup-:option-table)))
896     (when elt
897       (tiny-setup-nth-options elt))))
898
899 ;;; ----------------------------------------------------------------------
900 ;;;
901 (defun tiny-setup-define-key-1
902   (key keymap function &optional prefix str force)
903   "Define KEY to KEYMAP using FUNCTION if not yet occupied.
904
905 Input:
906
907   KEY       Key definitions
908   KEYMAP    The map.
909   FUNCTION  function to bind
910   PREFIX    Message prefix. Like \"Package:\" who requested change.
911   STR       Human readable key definition. Shown to user.
912   FORCE     Override key definition without a check."
913   (setq str (if (stringp str)
914                 (format "\"%s\"" str)
915               ""))
916   (let ((def (lookup-key keymap key)))
917     (cond
918      (force
919       (message "%sKey %-10s%s set to `%s' (FORCED, was `%s')."
920                (or prefix "")
921                (prin1-to-string key)
922                str
923                (symbol-name function)
924                def)
925       (define-key keymap key function))
926      (t
927       (cond
928        ((or (eq def function)
929             (memq def '(nil ignore))
930             ;; Lookup key returns NBR if the sequence of keys exceed
931             ;; the last keymap prefix
932             ;; C-cck  --> C-cc  is undefined, so there is no C-c c map yet
933             (integerp def))
934         (message "%sKey %-10s%s set to `%s'."
935                  (or prefix "")
936                  (prin1-to-string key)
937                  str
938                  (symbol-name function))
939         (define-key keymap key function))
940        (t
941         (message
942          "%sKey %-10s%s already has a definition `%s'. Not set to `%s'"
943          (or prefix "")
944          (prin1-to-string key)
945          str
946          (prin1-to-string def)
947          (symbol-name function))))))))
948
949 ;;; ----------------------------------------------------------------------
950 ;;;
951 (defun tiny-setup-define-key (key keymap function &optional str force)
952   "Define KEY to KEYMAP using FUNCTION. Display STR and FORCE binding."
953   (tiny-setup-define-key-1
954    key keymap function "TinySetup: " str force))
955
956 ;;; ----------------------------------------------------------------------
957 ;;;
958 (defun tiny-setup-alist-search (alist regexp)
959   "Search ALIST for REGEXP."
960   (dolist (elt alist)
961     (if (string-match regexp (car elt))
962         (return elt))))
963
964 ;;; ----------------------------------------------------------------------
965 ;;;
966 (defun tiny-setup-aput (sym regexp key value &optional force)
967   "Search SYM's for REGEXP and set KEY to VALUE if not found.
968 This function effectively compares each key in SYM to REGEXP and
969 if there is no matches, it adds new (KEY . VALUE) pair.
970
971 Useful, if something needs to be added to the `auto-mode-alist', but
972 previous definitions must be preserved."
973   (let* ((found (tiny-setup-alist-search (symbol-value sym) regexp)))
974     (cond
975      ((and found
976            (eq (cdr found) value))
977       (message "TinySetup: `%s' now contains (%s . %s)"
978                (symbol-name sym)
979                key
980                value))
981      (found
982       (message "TinySetup: `%s' already contains %s. Not set to (%s . %s)"
983                (symbol-name sym)
984                (prin1-to-string found)
985                key
986                value))
987      (t
988       (message "TinySetup: `%s' now contains (%s . %s)"
989                (symbol-name sym)
990                key
991                value))
992      (push (cons key value) (symbol-value sym)))))
993
994 ;;; ----------------------------------------------------------------------
995 ;;;
996 (defun tiny-setup-defalias (symbol definition)
997   "Like `defalias' but with verbose messages."
998   (message "TinySetup: defalias `%s' =>  `%s'"
999            (symbol-name symbol)
1000            (symbol-name definition))
1001   (defalias symbol definition))
1002
1003 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1004 ;;
1005 ;;
1006 ;;      TIMING UTILITIES
1007 ;;      These are admistrative utilies for package maintainer(s)
1008 ;;
1009 ;;
1010 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1011
1012 ;;; ----------------------------------------------------------------------
1013 ;;;
1014 (defun tiny-setup-time-difference (a b)
1015   "Calculate difference between times A and B.
1016 The input must be in form of '(current-time)'
1017 The returned value is difference in seconds.
1018 E.g. if you want to calculate days; you'd do
1019 \(/ (ti::date-time-difference a b) 86400)  ;; 60sec * 60min * 24h"
1020   (multiple-value-bind (s0 s1 s2) a
1021     (setq a (+ (* (float (ash 1 16)) s0)
1022                (float s1) (* 0.0000001 s2))))
1023   (multiple-value-bind (s0 s1 s2) b
1024     (setq b (+ (* (float (ash 1 16)) s0)
1025                (float s1) (* 0.0000001 s2))))
1026   (- a b))
1027
1028 ;;; ----------------------------------------------------------------------
1029 ;;;
1030 (defvar tiny-setup-:time nil)
1031 (put 'tiny-setup-time-this 'lisp-indent-function 0)
1032 (put 'tiny-setup-time-this 'edebug-form-spec '(body))
1033 (defmacro tiny-setup-time-this (&rest body)
1034   "Run BODY with and time execution. Time is in `my-:tmp-time-diff'."
1035   (`
1036    (let* ((tmp-time-A (current-time))
1037           tmp-time-B)
1038      (,@ body)
1039      (setq tmp-time-B (current-time))
1040      (setq tiny-setup-:time
1041            (tiny-setup-time-difference tmp-time-B tmp-time-A)))))
1042
1043 ;;; ----------------------------------------------------------------------
1044 ;;;
1045 (defun tiny-setup-time-load-file (file)
1046   "Time lisp FILE loading."
1047   (interactive "fload file and time it: ")
1048   (tiny-setup-time-this
1049    (load file))
1050   (message "Tiny: Timing %-15s took %12f secs" file tiny-setup-:time))
1051
1052 ;;; ----------------------------------------------------------------------
1053 ;;;
1054 (defun tiny-setup-test-load-time-libraries ()
1055   "Time package load times."
1056   (interactive)
1057   (message "\n\n** Tiny setup: timing test start\n")
1058   (message "load-path: %s"
1059            (prin1-to-string load-path))
1060   (let* ((path (locate-library "tinylib.el"))
1061          (time-a (current-time))
1062          time-b)
1063     (if (not path)
1064         (message "Tiny: [timing] Can't find tinylib.el along `load-path'")
1065       (setq path (file-name-directory path))
1066       (dolist (pkg (directory-files path 'full "^tinylib.*el"))
1067         (tiny-setup-time-load-file pkg))
1068       (setq time-b (current-time))
1069       (message "Tiny: total time is %s seconds"
1070                (tiny-setup-time-difference time-b time-a))
1071       (display-buffer "*Messages*"))))
1072
1073 ;;; ----------------------------------------------------------------------
1074 ;;;
1075 (defun tiny-setup-test-load-all ()
1076   "Load each package to check against errors."
1077   (interactive)
1078   (message "\n\n** Tiny setup: load test start\n")
1079   (let* ((path (locate-library "tinylib.el")))
1080     (if (not path)
1081         (message "Tiny: [load test] Can't find tinylib.el along `load-path'")
1082       (setq path (file-name-directory path))
1083       (dolist (pkg (directory-files path 'full "^tiny.*el"))
1084         (load pkg))
1085       (display-buffer "*Messages*"))))
1086
1087 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1088 ;;
1089 ;;
1090 ;;      AUTOLOAD UTILITIES
1091 ;;      These are admistrative utilies for package maintainer(s)
1092 ;;
1093 ;;
1094 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1095
1096 ;;; ----------------------------------------------------------------------
1097 ;;;
1098 (defun tiny-setup-directory-last (dir)
1099   "Return last directory name in DIR. /dir1/dir2/ -> dir2."
1100   (if (string-match "[/\\]\\([^/\\]+\\)[/\\]?$" dir)
1101       (match-string 1 dir)
1102     ""))
1103
1104 ;;; ----------------------------------------------------------------------
1105 ;;;
1106 (defun tiny-setup-directory-to-file-name (dir template)
1107   "Make file name from NAME and TEMPLATE. <template>-<last-dir>.el."
1108   (concat
1109    (file-name-as-directory dir)
1110    template
1111    (tiny-setup-directory-last dir)
1112    ".el"))
1113
1114 ;;; ----------------------------------------------------------------------
1115 ;;;
1116 (defun tinypath-tmp-autoload-file-footer (file &optional end)
1117   "Return 'provide and optional END of the file marker."
1118   (concat
1119    (format
1120     "\n(provide '%s)\n\n"
1121     (file-name-sans-extension (file-name-nondirectory file)))
1122    (if end
1123        (format ";; End of file %s\n"
1124                (file-name-nondirectory (file-name-nondirectory file)))
1125      "")))
1126
1127 ;;; ----------------------------------------------------------------------
1128 ;;;
1129 (defun tiny-setup-directories (list)
1130   "Return only directories from LIST."
1131   (let* (ret)
1132     (dolist (elt list)
1133       (when (and (file-directory-p elt)
1134                  ;;  Drop . ..
1135                  (not (string-match
1136                        "[/\\]\\.+$\\|CVS\\|RCS"
1137                        elt)))
1138         (push elt ret)))
1139     ret))
1140
1141 ;;; ----------------------------------------------------------------------
1142 ;;;
1143 ;;; (tiny-setup-autoload-build-functions "~/elisp/tiny/lisp/tiny")
1144 ;;; (tiny-setup-autoload-build-functions "~/elisp/tiny/lisp/other")
1145 ;;;
1146 (defun tiny-setup-autoload-build-functions (dir &optional regexp)
1147   "Build all autoloads in DIR-LIST, except for files matching REGEXP.
1148 Store the autoloads to tiny-DIR-autoload.el"
1149   (let* (make-backup-files                 ;; Do not make backups
1150          (backup-enable-predicate 'ignore) ;; Really, no backups
1151          (files   (directory-files
1152                    dir
1153                    'full
1154                    "\\.el$"))
1155          ;; There is no mistake in name here: it is "tiny-autoload-DIRNAME".
1156          ;; the other autoload generater will generate
1157          ;; "tiny-autoload-loaddefs-DIRNAME"
1158          (to-file (tiny-setup-directory-to-file-name dir "tiny-autoload-"))
1159          (name    (file-name-nondirectory to-file)))
1160     (when files
1161       (with-temp-buffer
1162         (insert
1163          (format ";;; %s -- " name)
1164          "Autoload definitions of program files in Tiny Tools Kit\n"
1165          ";;  Generate date: " (format-time-string "%Y-%m-%d" (current-time))
1166          "\n\
1167 ;;  This file is automatically generated. Do not Change.
1168 ;;  Read README.txt in the Tiny Tools doc/ directory for instructions."
1169          "\n\n")
1170         (dolist (file files)
1171           (if (and (stringp regexp)
1172                    (string-match regexp file))
1173               (message "Tiny: Ignoring autoload creation for %s" file)
1174             (ti::package-autoload-create-on-file
1175              file (current-buffer) 'no-show)))
1176         (insert (tinypath-tmp-autoload-file-footer to-file 'eof))
1177         (let ((backup-inhibited t))
1178           (write-region (point-min) (point-max) to-file))
1179         to-file))
1180     (message "TinySetup: Updated ALL autoloads in dir %s" dir)))
1181
1182 ;;; ----------------------------------------------------------------------
1183 ;;;     This is autoload generator will generate ALL, that means ALL,
1184 ;;;     autoloads from EVERY function and macro.
1185 ;;;     The implementation is in tinylib.el
1186 ;;;
1187 ;;; (tiny-setup-autoload-build-functions-all "~/elisp/tiny/lisp/")
1188 ;;;
1189 (defun tiny-setup-autoload-build-functions-all (dir)
1190   "Build all autoloads recursively below DIR."
1191   (interactive "Dautoload build root dir: ")
1192   (let* ((dirs (tiny-setup-directories
1193                 (directory-files
1194                  (expand-file-name dir)
1195                  'abs)))
1196          (regexp "tinylib\\|autoload"))
1197     (cond
1198      (dirs
1199       (tiny-setup-autoload-build-functions dir regexp)
1200       (dolist (dir dirs)
1201         (tiny-setup-autoload-build-functions-all dir)))
1202      (t
1203       (tiny-setup-autoload-build-functions dir regexp)))))
1204
1205 ;;; ----------------------------------------------------------------------
1206 ;;; (tiny-setup-autoload-build-loaddefs-tiny-tools "~/elisp/tiny/lisp/" t)
1207 ;;; (tiny-setup-autoload-build-loaddefs-tiny-tools "~/elisp/tiny/lisp/other" t)
1208 ;;;
1209 (defun tiny-setup-autoload-build-loaddefs-tiny-tools (dir &optional force)
1210   "Build Tiny Tools autoloads below DIR. FORCE recreates everything."
1211   (interactive "DAutoload root: \nP")
1212   (ti::package-autoload-loaddefs-build-recursive
1213    dir
1214    "autoload\\|loaddefs" ;; Exclude these files
1215    force
1216    (function
1217     (lambda (dir)
1218       (tiny-setup-directory-to-file-name
1219        (or dir
1220            (error "TinySetup: No DIR"))
1221        "tiny-autoload-loaddefs-")))))
1222
1223 ;;; ----------------------------------------------------------------------
1224 ;;;     This is autoload generator will generate ONLY functions marked
1225 ;;;     with special ### autoload tag. The implementation used is in
1226 ;;;     core Emacs package autoload.el
1227 ;;;
1228 ;;; (tiny-setup-autoload-batch-update "~/elisp/tiny/lisp/" 'force)
1229 ;;;
1230 ;;; This function is invoked from the perl makefile.pl with the
1231 ;;; ROOT directory as sole argument in Emacs command line.
1232 ;;;
1233 ;;; The build command from prompt is
1234 ;;;
1235 ;;;    $ perl makefile.pl --verbose 2 --binary emacs  autoload
1236 ;;;
1237 (defun tiny-setup-autoload-batch-update (&optional dir force)
1238   "Update autoloads in batch mode. Argument in command line is DIR. FORCE."
1239   (interactive "DAutoload dir to update: ")
1240   (unless dir
1241     (setq dir (pop command-line-args-left))
1242     (setq force t))
1243   (if dir                               ;Require slash
1244       (setq dir (file-name-as-directory dir)))
1245   (unless dir
1246     (message "Tiny: From what directory to make recursively autoloads?")
1247     ;; Self generate error for command line ...
1248     (error 'tiny-setup-autoload-batch-update))
1249   (message "TinySetup: Generating all autoloads under %s" dir)
1250   (let* ((default-directory (expand-file-name dir)))
1251     (message "Tiny: tiny-setup-autoload-batch-update %s"  default-directory)
1252     (when (not (string-match "^[/~]\\|^[a-zA-Z]:[/\\]"
1253                              default-directory))
1254       (message "Tiny: Autoload directory must be absolute path name.")
1255       (error 'tiny-setup-autoload-batch-update))
1256     (tiny-setup-autoload-build-loaddefs-tiny-tools
1257      default-directory force)))
1258     ;;  This would generate second set of autoloads. Don't do that any more,
1259     ;;  rely on Emacs autoload.el instead.
1260     ;; (tiny-setup-autoload-build-functions-all default-directory)
1261
1262 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1263 ;;
1264 ;;
1265 ;;      PACKAGE BYTE COMPILATION
1266 ;;      These are admistrative utilies for package maintainer(s)
1267 ;;
1268 ;;
1269 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1270
1271 ;;; ----------------------------------------------------------------------
1272 ;;;
1273 (defsubst tiny-setup-file-list-lisp (dir)
1274   "Return all lisp files under DIR."
1275   (directory-files dir 'full "\\.el$"))
1276
1277 ;;; ----------------------------------------------------------------------
1278 ;;;
1279 (defsubst tiny-setup-file-list-lisp-compiled (dir)
1280   "Return all compiled lisp files under DIR."
1281   (directory-files dir 'full "\\.elc$"))
1282
1283 ;;; ----------------------------------------------------------------------
1284 ;;;
1285 (put 'tiny-setup-directory-recursive-macro 'lisp-indent-function 1)
1286 (put 'tiny-setup-directory-recursive-macro 'edebug-form-spec '(body))
1287 (defmacro tiny-setup-directory-recursive-macro (directory &rest body)
1288   "Start from DIRECTORY and run BODY recursively in each directories.
1289
1290 Following variables are set during BODY:
1291
1292 `dir'      Directrory name
1293 `dir-list' All directories under `dir'."
1294   (`
1295    (flet ((recurse
1296            (dir)
1297            (let* ((dir-list (tiny-setup-directory-list dir)))
1298              (,@ body)
1299              (when dir-list
1300                (dolist (elt dir-list)
1301                  (recurse elt))))))
1302      (recurse (, directory)))))
1303
1304 ;;; ----------------------------------------------------------------------
1305 ;;;
1306 (defun tiny-setup-directory-list (dir)
1307   "Return all directories under DIR."
1308   (let (list)
1309     (dolist (elt (directory-files dir 'full))
1310       (when (and (file-directory-p elt)
1311                  (not (string-match "[\\/]\\.\\.?$" elt)))
1312         (push elt list)))
1313     list))
1314
1315 ;;; ----------------------------------------------------------------------
1316 ;;;
1317 (defun tiny-setup-compile-directory (dir &optional function)
1318   "Compile all isp files in DIRECTORY.
1319 Optional FUNCTION is passed one argument FILE, and it should return
1320 t or nil if file is to be compiled."
1321   (dolist (file (tiny-setup-file-list-lisp dir))
1322     (when (or (null function)
1323               (funcall function file))
1324       (byte-compile-file file))))
1325
1326 ;;; ----------------------------------------------------------------------
1327 ;;;
1328 (defun tiny-setup-compile-directory-recursive (root &optional function)
1329   "Compile all files under ROOT directory.
1330 Optional FUNCTION is passed one argument FILE, and it should return
1331 t or nil if file is to be compiled."
1332   (tiny-setup-directory-recursive-macro root
1333                                         (message "TinySetup: compiling directory %s" dir)
1334                                         (tiny-setup-compile-directory
1335                                          dir function)))
1336
1337 ;;; ----------------------------------------------------------------------
1338 ;;;
1339 (defun tiny-setup-compile-directory-delete-recursive (root)
1340   "Delete all compiled files under ROOT directory recursively."
1341   (tiny-setup-directory-recursive-macro root
1342                                         (dolist (file (tiny-setup-file-list-lisp-compiled dir))
1343                                           (message "TinySetup: deleting compiled file %s" file)
1344                                           (delete-file file))))
1345
1346 ;;; ----------------------------------------------------------------------
1347 ;;;
1348 (defun tiny-setup-compile-kit-libraries (dir)
1349   "Compile tiny tools libraries"
1350   (tiny-setup-directory-recursive-macro dir
1351                                         (let ((libs (directory-files dir 'abs-path "tinylib.*\\.el$")))
1352                                           (when libs ;;  Found correct directory
1353                                             (message "TinySetup: compiling libraries in right order.")
1354                                             (let ((default-directory dir)
1355                                                   compile-file)
1356                                               ;; There is certain order of compilation. Low level libraries first.
1357                                               (dolist (regexp tiny-setup-:library-compile-order)
1358                                                 (when (setq compile-file ;; compile these first
1359                                                             (find-if (function
1360                                                                       (lambda (elt)
1361                                                                         (string-match regexp elt)))
1362                                                                      libs))
1363                                                   (setq libs (delete compile-file libs))
1364                                                   (byte-compile-file compile-file)))
1365                                               (message "TinySetup: compiling rest of the libraries.")
1366                                               (dolist (file libs) ;; Rest of the libraries
1367                                                 (cond
1368                                                  ((find-if (function
1369                                                             (lambda (regexp)
1370                                                               (string-match regexp file)))
1371                                                            tiny-setup-:library-compile-exclude)
1372                                                   (message "TinySetup: ignoring library %s" file))
1373                                                  (t
1374                                                   (byte-compile-file file)))))))))
1375
1376 ;;; ----------------------------------------------------------------------
1377 ;;;
1378 (defun tiny-setup-compile-kit-all (&optional dir)
1379   "Compile tiny tools kit under DIR.
1380 This function can be called from shell command line, where the
1381 last argument is the DIR from where to start compiling.
1382
1383 Notice that there is `.' at the end of call to `tiny-setup-compile-kit-all':
1384
1385 $ cd root-dir
1386 $ find . -name \"*elc\" -exec rm {} \\;
1387 $ emacs -batch -l load-path.el -l tiny-setup.el -f tiny-setup-compile-kit-all .
1388
1389 If only the libraries need compilation, use this command:
1390
1391 $ emacs -batch -l load-path.el -l tiny-setup.el -f -eval '(tiny-setup-compile-kit-libraries \".\")
1392
1393 If only one file needs to be compiled:
1394
1395 $ emacs -batch -l load-path.el -l tiny-setup.el -f -eval batch-byte-compile <file>"
1396   (interactive "D[compile] installation root dir: ")
1397   (unless dir
1398     (setq dir (car-safe command-line-args-left)))
1399   (if dir                               ;Require slash
1400       (setq dir (file-name-as-directory dir))
1401     (error "Compile under which DIR? Give parameter"))
1402   (message "tinySetup: byte compiling root %s" dir)
1403   ;;  Remove compiled files first
1404   (tiny-setup-compile-directory-delete-recursive dir)
1405   ;;  Libraries first
1406   (tiny-setup-compile-kit-libraries dir)
1407   ;;  The rest follows, it doesn't matter if libs are are compiled twice.
1408   (tiny-setup-compile-directory-recursive
1409    dir
1410    (function
1411     (lambda (x)
1412       (not (string-match "tinylib" x))))))
1413
1414 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1415 ;;
1416 ;;
1417 ;;      USER SPACE: KIT AND PACKAGE CONFIGURATION
1418 ;;
1419 ;;
1420 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1421
1422 (defun tiny-setup-folding-autoload-find-file-hook ()
1423   "Install folding if file includes {{{ and }}}.
1424 Do nothing if folding is already installed."
1425   (if (or (fboundp 'folding-install)
1426           (featurep 'folding))
1427       ;;  Remove ourself from the `find-file-hooks'.
1428       (remove-hook  'find-file-hooks
1429                     'tiny-setup-folding-autoload-find-file-hook)
1430     (let* ((start  (concat "\\("
1431                            (regexp-quote (or comment-start "dummy"))
1432                            "\\)+"))
1433            (regexp (concat "^" start "{{{ \\|^" start "}}}")))
1434       (when (ti::re-search-check regexp)
1435         (folding-install-hooks)
1436         (turn-on-folding-mode)))))
1437
1438 (defun tiny-setup-folding-autoload ()
1439   "Autoload."
1440   (defvar folding-mode nil)
1441   (tiny-setup-ti::macrov-mode-line-mode-menu
1442    folding-mode "Outline (Folding)")
1443   (add-hook  'find-file-hooks
1444              'tiny-setup-folding-autoload-find-file-hook))
1445
1446 (defun tiny-setup-dired-sort-autoload ()
1447   "Autoload."
1448   (add-hook  'dired-mode-hook 'dired-sort-default-keys 'end))
1449
1450 (defun tiny-setup-tinyadvice-load ()
1451   "Load for Emacs only."
1452   (if (ti::emacs-p)
1453       (require 'tinyadvice)
1454     (message "TinySetup: tinyadvice.el is not for XEmacs. Didn't load.")))
1455
1456 (defun tiny-setup-tinyappend-bind (&optional force)
1457   "Bind."
1458   ;; non-shift key
1459   (tiny-setup-define-key  "\C-c+" global-map 'tinyappend-end
1460                           "C-c+" force)
1461   ;; non-shift key
1462   (tiny-setup-define-key  "\C-c_" global-map 'tinyappend-beg
1463                           "C-c_" force)
1464   (tiny-setup-define-key  "\C-c-" global-map 'tinyappend-kill
1465                           "C-c-" force)
1466   (tiny-setup-define-key  "\C-c|" global-map 'tinyappend-yank
1467                           "C-c|" force))
1468
1469 (defun tiny-setup-tinyappend-bindforce ()
1470   "Bind."
1471   (tiny-setup-tinyappend-bind 'force))
1472
1473 (defun tiny-setup-tinybookmark-defalias ()
1474   "Defalias."
1475   ;; (tiny-setup-defalias 'tinybookmark-insert 'bm)
1476   nil)
1477
1478 (defun tiny-setup-tinybookmark-bind ()
1479   "Bind."
1480   (if (ti::emacs-p)
1481       (tiny-setup-define-key [(?\e) (control mouse-1)]
1482                              global-map 'tinybookmark-mouse)
1483     (tiny-setup-define-key [(control meta button1)]
1484                            global-map 'tinybookmark-mouse))
1485
1486   ;; (tiny-setup-define-key [(?\e) (control shift mouse-1)]
1487   ;;                     global-map 'tinybookmark-mouse-parse)
1488
1489   (tiny-setup-define-key [(shift left)]
1490                          global-map 'tinybookmark-backward)
1491   (tiny-setup-define-key [(shift right)]
1492                          global-map 'tinybookmark-forward))
1493
1494 (defun tiny-setup-tinycache-activate ()
1495   "Autoload activate package."
1496   (add-hook 'compilation-mode-hook
1497             '(lambda () (require 'tinycache)))
1498   (when (ti::emacs-p)
1499     (add-hook 'dired-mode-hook
1500               '(lambda () (require 'tinycache))))
1501   (eval-after-load "compile"
1502     '(progn (require 'tinycache)))
1503   (eval-after-load "dired"
1504     '(progn (require 'tinycache))))
1505
1506 (defun tiny-setup-tinybuffer-bind (&optional force)
1507   "Bind."
1508   (tiny-setup-define-key [(control <)]
1509                          global-map 'tinybuffer-previous-buffer
1510                          nil force)
1511   (tiny-setup-define-key [(control >)]
1512                          global-map 'tinybuffer-next-buffer
1513                          nil force)
1514   (tiny-setup-define-key [(control meta <)]
1515                          global-map 'tinybuffer-iswitch-to-buffer
1516                          nil force)
1517   (tiny-setup-define-key [(control meta >)]
1518                          global-map 'tinybuffer-sort-mode-toggle
1519                          nil force))
1520
1521 (defun tiny-setup-tinybuffer-bindforce ()
1522   "Bind."
1523   (tiny-setup-tinybuffer-bind 'force))
1524
1525 (defun tiny-setup-tinycomment-autoload ()
1526   "Autoload."
1527   (autoload 'tinycomment-indent-for-comment "tinycomment" "" t))
1528
1529 (defun tiny-setup-tinycomment-bind (&optional force)
1530   "Bind."
1531   (tiny-setup-define-key
1532    [(meta ?\;)]
1533    global-map
1534    'tinycomment-indent-for-comment "M-;"
1535    (or force
1536        ;;  Override default. In Emacs 21.2 this is more intelligent
1537        ;;  function comment-dwim
1538        (eq (lookup-key global-map [(meta ?\;)])
1539            'indent-for-comment))))
1540
1541 (defun tiny-setup-tinycompile-autoload ()
1542   "Autoload."
1543   (add-hook 'compilation-mode-hook 'turn-on-tinycompile-mode 'append)
1544   (dolist (buffer (buffer-list))
1545     (with-current-buffer buffer
1546       (when (memq major-mode '(compilation-mode))
1547         (turn-on-tinycompile-mode)))))
1548
1549 (defun tiny-setup-tinydesk-bind (&optional force)
1550   "Bind with optional FORCE."
1551   (message "TinySetup: [tinydesk] binding keys in `ctl-x-4-map'")
1552   (tiny-setup-define-key
1553    "S" ctl-x-4-map
1554    'tinydesk-save-state nil force) ;; free in 19.28
1555   (tiny-setup-define-key
1556    "R" ctl-x-4-map
1557    'tinydesk-recover-state nil force) ;; Free in 21.2
1558   (tiny-setup-define-key
1559    "E" ctl-x-4-map
1560    'tinydesk-edit-state-file nil force) ;; free in 19.28
1561   (tiny-setup-define-key
1562    "U" ctl-x-4-map
1563    'tinydesk-unload nil force)) ;; free in 19.28
1564
1565 (defun tiny-setup-tinydesk-bindforce ()
1566   "Bind."
1567   (tiny-setup-tinydesk-bind 'force))
1568
1569 (defun tiny-setup-tinydesk-activate ()
1570   "Activate.")
1571
1572 (defun tiny-setup-tinydiff-autoload ()
1573   "Autoload."
1574   (tiny-setup-aput 'auto-mode-alist
1575                    "diff" "\\.diff\\'" 'turn-on-tinydiff-mode)
1576   (tiny-setup-aput 'auto-mode-alist
1577                    "patch" "\\.patch\\'"  'turn-on-tinydiff-mode))
1578
1579 (defun tiny-setup-tinydiff-bind (&optional force)
1580   "Bind keys."
1581   (tiny-setup-define-key
1582    "\C-cD"
1583    global-map 'tinydiff-diff-show "C-cD" force)
1584   (tiny-setup-define-key
1585    "\C-cP"
1586    global-map 'tinydiff-patch  "C-cP" force))
1587
1588 (defun tiny-setup-tinydiff-bindforce ()
1589   "Bind keys."
1590   (tiny-setup-tinydiff-bind 'force))
1591
1592 (defun tiny-setup-tinydebian-autoload ()
1593   "Autoload."
1594   (autoload 'tinydebian-bug-report-mail "tinydebian" "" t))
1595
1596 (defun tiny-setup-tinydebian-load ()
1597   "Load."
1598   (require 'tinydebian)
1599   (tinydebian-install))
1600
1601 (defun tiny-setup-tinydired-autoload ()
1602   "Autoload. This is for Emacs only.
1603 You may want to set
1604
1605   (setq tinydired-:force-add-keys 'override)."
1606   (if (ti::xemacs-p)
1607       (message "\
1608 TinySetup: tinydired.el works only with Emacs. Package not loaded.")
1609     (add-hook 'tinydired-:load-hook    'tinydired-hook-control)
1610     (add-hook 'dired-mode-hook '(lambda () (require 'tinydired) nil))
1611     ;;  If dired is already loaded, install immediately
1612     (dolist (buffer (buffer-list))
1613       (with-current-buffer buffer
1614         (when (memq major-mode '(dired-mode))
1615           (require 'tinydired)
1616           (return))))))
1617
1618 (defun tiny-setup-tinyeat-bind (&optional force)
1619   "Bind."
1620
1621   (message "\
1622 TinySetup: [NOTE] The automatic setup will not make much much good,
1623            because no default Emacs keys are redefined. tinyeat.el
1624            package delete keys are installed only if you call function
1625            `tinyeat-install-default-bindings' directly.")
1626
1627   ;;  These are REAL difficult choices, because almost every keyboard
1628   ;;  interprets backspace differently.
1629
1630   (tiny-setup-define-key [(control backspace)]
1631                          global-map 'tinyeat-forward-preserve
1632                          nil force)
1633   (tiny-setup-define-key [(control delete)]
1634                          global-map 'tinyeat-forward-preserve
1635                          nil force)
1636
1637   (tiny-setup-define-key [(control shift delete)]
1638                          global-map 'tinyeat-delete-paragraph
1639                          nil force)
1640
1641   (tiny-setup-define-key [(control shift backspace)]
1642                          global-map 'tinyeat-delete-paragraph
1643                          nil force)
1644
1645   (tiny-setup-define-key [(shift backspace)]
1646                          global-map 'tinyeat-delete-whole-word
1647                          nil force)
1648
1649   (tiny-setup-define-key [(meta delete)]
1650                          global-map 'tinyeat-erase-buffer
1651                          nil force)
1652
1653   (tiny-setup-define-key [(alt control k)]
1654                          global-map 'tinyeat-zap-line
1655                          nil force)
1656
1657   (unless (ti::compat-window-system)
1658     (tiny-setup-define-key
1659      [(control meta ?h)]
1660      global-map 'tinyeat-erase-buffer nil force))
1661
1662   (when (fboundp 'read-kbd-macro)
1663     (tiny-setup-define-key
1664      (read-kbd-macro "ESC DEL")
1665      global-map 'tinyeat-erase-buffer "ESC DEL" force)))
1666
1667 (defun tiny-setup-tinyeat-bindforce ()
1668   "Bind with override."
1669   (tiny-setup-tinyeat-bind 'force))
1670
1671 (defun tiny-setup-tinyef-bindextra ()
1672   "Bind extra keys."
1673   (if (not (fboundp 'tinyef-minibuffer-define-key-extras))
1674       (add-hook 'tinyef-load-hook 'tinyef-minibuffer-define-key-extras)
1675     (tinyef-minibuffer-define-key-extras)))
1676
1677 (defun tiny-setup-tinyef-autoload ()
1678   "Autoload."
1679   (add-hook 'minibuffer-setup-hook 'turn-on-tinyef-mode))
1680
1681 (defun tiny-setup-tinygnus-autoload ()
1682   "Autoload."
1683   (defvar tinygnus-group-mode nil)
1684   (tiny-setup-ti::macrov-mode-line-mode-menu
1685    tinygnus-group-mode "Gnus Group mode extras")
1686   (defvar tinygnus-summary-mode nil)
1687   (tiny-setup-ti::macrov-mode-line-mode-menu
1688    tinygnus-summary-mode "Gnus Summary mode extras")
1689   (add-hook 'gnus-startup-hook '(lambda () (require 'tinygnus)))
1690   (when (featurep 'gnus)
1691     ;;  Gnus already present
1692     (require 'tinygnus)))
1693
1694 (defun tiny-setup-tinyhotlist-autoload ()
1695   "Autoload."
1696   (add-hook 'tinyhotlist-:load-hook 'tinyhotlist-load-hotlist))
1697
1698 (defun tiny-setup-tinyhotlist-bindmouse (&optional force)
1699   "Bind."
1700   (if (not (ti::compat-window-system))
1701       (message
1702        (concat
1703         "TinySetup: tinyhotlist.el Mouse binding skipped."
1704         "No window system available."))
1705     (if (ti::emacs-p)
1706         (tiny-setup-define-key
1707          [(control shift mouse-3)]
1708          global-map
1709          'tinyhotlist-control
1710          force)
1711       (tiny-setup-define-key
1712        [(control shift button3)]
1713        global-map
1714        'tinyhotlist-control
1715        force))))
1716
1717 (defun tiny-setup-tinyhotlist-bindmouseforce ()
1718   "Bind."
1719   (tiny-setup-tinyhotlist-bindmouse 'force))
1720
1721 (defun tiny-setup-tinyhotlist-bind (&optional force)
1722   "Bind."
1723   (tiny-setup-define-key
1724    (read-kbd-macro "\C-cH")
1725    global-map 'tinyhotlist-control "C-cH" force))
1726
1727 (defun tiny-setup-tinyhotlist-bindforce ()
1728   "Bind."
1729   (tiny-setup-tinyhotlist-bind))
1730
1731 (defun tiny-setup-tinyigrep-autoload ()
1732   "Autoload."
1733   (if (featurep 'igrep)
1734       (require 'tinyigrep)
1735     (eval-after-load "igrep" '(progn (require 'tinyigrep)))))
1736
1737 (defun tiny-setup-tinyigrep-bind (&optional force)
1738   "Bind."
1739   (tiny-setup-define-key
1740    (read-kbd-macro "\C-cG")
1741    global-map 'tinyigrep-menu "C-cG" force))
1742
1743 (defun tiny-setup-tinyigrep-bindforce ()
1744   "Bind."
1745   (tiny-setup-tinyigrep-bind 'force))
1746
1747 (defun tiny-setup-tinyliby-defalias ()
1748   "Defalias."
1749   ;;  Shorter name.
1750   (tiny-setup-defalias 'describe-symbols 'ti::system-describe-symbols))
1751
1752 (defun tiny-setup-tinylibt-bind ()
1753   "Bind."
1754   ;;#todo:
1755   ;;   (tiny-setup-define-key "\C-ztm" global-map 'ti::text-mark-region)   ;; e.g. permanent 'mark'
1756   ;;   (tiny-setup-define-key "\C-ztu" global-map 'ti::text-unmark-region) ;; remove 'mark'
1757   ;;   (tiny-setup-define-key "\C-ztc" global-map 'ti::text-clear-buffer-properties)
1758   ;;   (tiny-setup-define-key "\C-ztb" global-map 'ti::text-buffer)
1759   ;;   (tiny-setup-define-key "\C-ztU" global-map 'ti::text-undo)
1760   nil)
1761
1762 (defun tiny-setup-tinylisp-autoload ()
1763   "Autoload."
1764   (defvar tinylisp-mode nil)
1765   (tiny-setup-ti::macrov-mode-line-mode-menu
1766    tinylisp-mode "Emacs Lisp extras")
1767   (add-hook 'lisp-mode-hook               'turn-on-tinylisp-mode)
1768   (add-hook 'emacs-lisp-mode-hook         'turn-on-tinylisp-mode)
1769   (add-hook 'lisp-interaction-mode-hook   'turn-on-tinylisp-mode))
1770
1771 (defun tiny-setup-tinylisp-activate ()
1772   "Activate on every lisp buffer."
1773   (tiny-setup-tinylisp-autoload) ;; Make sure this is called
1774   ;;  If this is vanilla emacs which only has one lisp buffer, *scratch*
1775   ;;  then do not load tinylisp.el. install only hooks.
1776   ;;
1777   ;;  But if there are already any lisp buffers around (count), then
1778   ;;  be sure to treat also *scratch*.
1779   ;;
1780   (let ((count 0))
1781     (tiny-setup-dolist-buffer-list
1782      (when (and (not (string-match "*scratch*" (buffer-name)))
1783                 (or (string-match "\\.el$" (buffer-name))
1784                     (memq major-mode '(emacs-lisp-mode
1785                                        lisp-interaction-mode))))
1786        (message "TinySetup: activating tinylisp-mode in %s" (buffer-name))
1787        (incf count)
1788        (turn-on-tinylisp-mode)))
1789     (when (> count 0)
1790       (with-current-buffer "*scratch*"
1791         (turn-on-tinylisp-mode)))))
1792
1793 (defun tiny-setup-tinylpr-bind ()
1794   "Bind."
1795   ;;#todo:
1796   ;; (ti::use-prefix-key "\C-z")          ;; Free C-z for us.
1797   ;; (tiny-setup-define-key "\C-zp" (ti::definteractive (ti::menu-menu global-map 'tinylpr-:menu)))
1798   nil)
1799
1800 (defun tiny-setup-tinymacro-bind (&optional force)
1801   "Bind."
1802   ;; (tiny-setup-define-key "\C-x(" global-map 'start-kbd-macro)
1803
1804   ;;  We must overwrite this any any case, othewise the packages
1805   ;;  is not much use. Use 'force unconditionally.
1806
1807   (tiny-setup-define-key
1808    "\C-x)"
1809    global-map 'tinymacro-end-kbd-macro-and-assign
1810    "C-x)" 'force))
1811
1812 (defun tiny-setup-tinymacro-bindforce ()
1813   "Bind."
1814   (tiny-setup-tinymacro-bind 'force))
1815
1816 (defun tiny-setup-tinymail-autoload ()
1817   "Autoload."
1818   (add-hook 'mail-setup-hook     'turn-on-tinymail-mode)
1819   (add-hook 'message-mode-hook   'turn-on-tinymail-mode)
1820   (add-hook 'tinymail-:mode-hook 'turn-on-tinytab-mode))
1821
1822 (defun tiny-setup-tinymailbox-find-file-hook (&optional disable)
1823   "Activate `tinymailbox-mode' on mailbox files."
1824   (if (memq 'turn-on-tinymailbox-mode-maybe
1825             find-file-hooks)
1826       ;;  Package has been installed. It handles `find-file-hook'
1827       ;;  detection better, so remove us.
1828       (setq disable t)
1829     (when (ti::mail-mailbox-p)
1830       (turn-on-tinymailbox-mode-maybe)))
1831   (if disable
1832       (remove-hook
1833        'find-file-hooks
1834        'tiny-setup-tinymailbox-find-file-hook)))
1835
1836 (defun tiny-setup-tinymailbox-autoload ()
1837   "Autoload."
1838   (add-hook  'find-file-hooks
1839              'tiny-setup-tinymailbox-find-file-hook)
1840   ;;  Gnus temporary mailbox files have name "Incoming"
1841   (tiny-setup-aput 'auto-mode-alist
1842                    "Incoming" "Incoming"  'turn-on-tinymailbox-mode)
1843   ;;  Other mailbox files
1844   (tiny-setup-aput 'auto-mode-alist
1845                    "mbo?x" "\\.mbo?x\\'"  'turn-on-tinymailbox-mode)
1846   ;;  Typical procmail spool files, like ~/Mail/spool/mail.work.spool
1847   (tiny-setup-aput 'auto-mode-alist
1848                    "spool" "\\.spool\\'"  'turn-on-tinymailbox-mode))
1849
1850 (defun tiny-setup-tinymy-defadvice ()
1851   "Activate smart M-x compile support."
1852   (tinymy-compile-run-command-advice))
1853
1854 (defun tiny-setup-tinymy-bind ()
1855   "Bind."
1856   (message
1857    "TinySetup: [tinymy] You should call function `tinymy-define-keys'."))
1858
1859 (defun tiny-setup-tinymy-bindforce ()
1860   "Bind extra keys that replace Emacs keys."
1861
1862   (tiny-setup-define-key
1863    "\C-xq" global-map 'tinymy-buffer-file-chmod nil 'force)
1864
1865   (tiny-setup-define-key
1866    [(prior)] global-map 'tinymy-scroll-up nil 'force)
1867
1868   (tiny-setup-define-key
1869    [(next)] global-map 'tinymy-scroll-down nil 'force)
1870
1871   (tiny-setup-define-key
1872    [(next)] global-map  'tinymy-scroll-down nil 'force)
1873
1874   (tiny-setup-define-key
1875    [(control right)] global-map 'tinymy-word-forward nil 'force)
1876
1877   (tiny-setup-define-key
1878    [(control left)] global-map 'tinymy-word-backward nil 'force)
1879
1880   (when (and (boundp 'window-system)
1881              (symbol-value 'window-system))
1882     (tiny-setup-define-key
1883      [(meta f)] global-map 'tinymy-word-forward nil 'force)
1884     (tiny-setup-define-key
1885      [(meta b)] global-map 'tinymy-word-backward nil 'force))
1886
1887   (when (boundp 'shared-lisp-mode-map)
1888     (defvar shared-lisp-mode-map nil) ;; Byte compiler silencer
1889     (tiny-setup-define-key
1890      "%" shared-lisp-mode-map 'tinymy-vi-type-paren-match nil 'force))
1891
1892   (when (boundp 'emacs-lisp-mode-map)
1893     (tiny-setup-define-key
1894      "%" emacs-lisp-mode-map 'tinymy-vi-type-paren-match nil 'force))
1895
1896   (when (boundp 'lisp-mode-map)
1897     (tiny-setup-define-key
1898      "%" lisp-mode-map 'tinymy-vi-type-paren-match nil 'force)))
1899
1900 (defun tiny-setup-tinymy-defalias ()
1901   "Bind."
1902   ;;  Faster prompting for experts
1903   (tiny-setup-defalias 'yes-or-no-p 'y-or-n-p))
1904
1905 (defun tiny-setup-tinynbr-autoload ()
1906   "Autoload."
1907   (defvar tinynbr-mode nil)
1908   (tiny-setup-ti::macrov-mode-line-mode-menu
1909    tinynbr-mode "Number manipulation"))
1910
1911 (defun tiny-setup-tinypad-autoload ()
1912   "Autoload."
1913   (defvar tinypad-mode nil)
1914   (tiny-setup-ti::macrov-mode-line-mode-menu
1915    tinypad-mode "Notepad emulation menu"))
1916
1917 (defun tiny-setup-tinypage-bind ()
1918   "Bind."
1919   ;;#todo:
1920   nil)
1921
1922 (defun tiny-setup-turn-off-tinypair-mode ()
1923   "Safeguard to function `turn-off-tinypair-mode'.
1924 If tinypair.el cannot be found, function `turn-off-tinypair-mode'
1925 cannot be called. Attempt to do so will yield serious error,
1926 preventing user to enter minibuffer at all.
1927
1928 To prevent this serious error, package existence is
1929 verified."
1930   (when (locate-library "tinypair")
1931     ;; It's safe to call this. Function is already autoloaded.
1932     (turn-off-tinypair-mode)))
1933
1934 (defun tiny-setup-tinypair-autoload ()
1935   "Autoload."
1936   (defvar tinypair-mode nil)
1937   (add-hook 'minibuffer-setup-hook 'turn-off-tinypair-mode)
1938   (tiny-setup-ti::macrov-mode-line-mode-menu
1939    tinypair-mode "Paired insert"))
1940
1941 (defun tiny-setup-tinypair-activate-buffer (mode &optional uninstall)
1942   "Activate or deactivate tinypair in buffers."
1943   (dolist (buffer (buffer-list))
1944     (with-current-buffer buffer
1945       (when (eq major-mode mode)
1946         (if uninstall
1947             (turn-off-tinypair-mode)
1948           (turn-on-tinypair-mode))
1949         (message "TinySetup: tinypair-mode %s in buffer %s"
1950                  (if uninstall
1951                      "turned off"
1952                    "turned on")
1953                  (buffer-name))))))
1954
1955 (defun tiny-setup-tinypair-activate (&optional uninstall)
1956   "Install to programming modes."
1957   ;;  In Cperl, CC, Java the "{" key is electric, so we don't
1958   ;;  install into those buffers.
1959   (dolist (mode '(awk-mode-hook
1960                   emacs-lisp-mode-hook
1961                   sh-mode-hook))
1962     (ti::add-hooks mode 'turn-on-tinypair-mode uninstall)
1963     (let ((name (symbol-name mode)))
1964       (message "TinySetup: tinypair-mode %s %s"
1965                (if uninstall
1966                    "removed from"
1967                  "added to")
1968                name)
1969       (when (and (string-match "^\\(.*-mode\\)" name)
1970                  (setq mode (intern-soft (match-string 1 name))))
1971         ;;  Activate in current Emacs
1972         (tiny-setup-tinypair-activate-buffer mode uninstall)))))
1973
1974 (defun tiny-setup-tinypage-autoload ()
1975   "Autoload."
1976   (defvar tinypage-mode nil)
1977   (tiny-setup-ti::macrov-mode-line-mode-menu
1978    tinypage-mode "Paged ^L mode"))
1979
1980 (defun tiny-setup-tinyperl-autoload ()
1981   "Autoload."
1982   (defvar tinyperl-mode nil)
1983   (tiny-setup-ti::macrov-mode-line-mode-menu
1984    tinyperl-mode "Perl extras (pod)")
1985   (add-hook 'perl-mode-hook  'turn-on-tinyperl-mode)
1986   (add-hook 'cperl-mode-hook 'turn-on-tinyperl-mode)
1987   (when (or (featurep 'cperl)
1988             (featurep 'perl))
1989     (turn-on-tinyperl-mode-all-buffers)))
1990
1991 (defun tiny-setup-tinyprocmail-autoload ()
1992   "Autoload."
1993   ;;  old procmail files start with rc.*
1994   (defvar tinyprocmail-mode nil)
1995   (tiny-setup-ti::macrov-mode-line-mode-menu
1996    tinyprocmail-mode "Procmail recipe coding")
1997   (tiny-setup-aput 'auto-mode-alist
1998                    "procmailrc"
1999                    "\\.rc\\'\\|^rc\\.\\|procmailrc"
2000                    'turn-on-tinyprocmail-mode))
2001
2002 (defun tiny-setup-tinyreplace-bind ()
2003   "Bind. Replace M-&"
2004   (tiny-setup-define-key [(meta ?&)]
2005                          global-map
2006                          'tinyreplace-menu
2007                          "Meta-&"))
2008
2009 (defun tiny-setup-tinytag-install-sample-databases ()
2010   "Delayd installation of databases."
2011   (unless (get 'tinytag-install-sample-databases 'done)
2012     (tinytag-install-sample-databases)
2013     (tiny-setup-tinytag-hook
2014      '(tiny-setup-tinytag-install-sample-databases)
2015      'uninstall)))
2016
2017 (defun tiny-setup-tinytag-hook (hook-list &optional uninstall)
2018   "Activate database install."
2019   (ti::add-hooks '(java-mode-hook
2020                    jde-mode-hook
2021                    c++-mode-hook)
2022                  hook-list
2023                  uninstall)
2024   (ti::add-hooks '(cc-mode-hook
2025                    c-mode-hook)
2026                  hook-list
2027                  uninstall
2028                  nil
2029                  'check-boundp))
2030
2031 (defun tiny-setup-tinytag-autoload ()
2032   "Autoload."
2033   (tiny-setup-tinytag-hook
2034    '(tinytag-install
2035      tiny-setup-tinytag-install-sample-databases)))
2036
2037 (defun tiny-setup-tinyvc-autoload ()
2038   "Autoload."
2039   ;;  This is bit tricky autoload setup, but it is the only way.
2040   ;;  Otherwise you would have to say (require 'tinyvc),
2041   ;;  which is not nice at all
2042   (defadvice vc-print-log (after tinyvc act)
2043     "Run hook `tinyvc-:vc-print-log-hook'."
2044     (require 'tinyvc)
2045     (run-hooks 'tinyvc-:vc-print-log-hook))
2046   (eval-after-load "vc" '(progn (require 'tinyvc))))
2047
2048 (defun tiny-setup-tinyrmail-autoload ()
2049   "Autoload."
2050   (add-hook 'rmail-mode-hook 'tinyrmail-install)
2051   (if (featurep 'rmail)
2052       (tinyrmail-install)))
2053
2054 (defun tiny-setup-tinysearch-bindforce ()
2055   "Bind search keys.")
2056   ;; (tinysearch-install-default-keybindings)
2057
2058 (defun tiny-setup-tinysearch-bindmousealt ()
2059   "Bind."
2060   (tiny-setup-define-key [(alt control mouse-1)]
2061                          global-map 'tinysearch-search-word-forward)
2062   (tiny-setup-define-key [(alt control shift mouse-1)]
2063                          global-map 'tinysearch-search-word-backward))
2064
2065 (defun tiny-setup-tinysearch-bindmousemeta ()
2066   "Bind."
2067   (tiny-setup-define-key [(meta control mouse-1)]
2068                          global-map 'tinysearch-search-word-forward)
2069   (tiny-setup-define-key [(meta control shift mouse-1)]
2070                          global-map 'tinysearch-search-word-backward))
2071
2072 (defun tiny-setup-tinyscroll-autoload ()
2073   "Autoload."
2074   (unless (boundp 'compilation-scroll-output)
2075     (add-hook 'compilation-mode-hook
2076               '(lambda () (require  'tinyscroll) nil))))
2077
2078 (defun tiny-setup-tinytab-autoload ()
2079   "Autoload."
2080   (defvar tinytab-mode nil)
2081   (tiny-setup-ti::macrov-mode-line-mode-menu
2082    tinytab-mode "Tab indent mode"))
2083
2084 (defun tiny-setup-tinytab-bind (&optional force)
2085   "Bind."
2086   (tiny-setup-define-key "\C-cT"
2087                          global-map 'tinytab-mode "C-cT"
2088                          force)
2089   (tiny-setup-define-key "\C-c\C-m"
2090                          global-map 'tinytab-return-key-mode "C-c <RET>"
2091                          force))
2092
2093 (defun tiny-setup-tinytab-bindforce ()
2094   "Bind."
2095   (tiny-setup-tinytab-bind 'force))
2096
2097 (defun tiny-setup-tinytab-bindextra (&optional force)
2098   "Bind."
2099   ;;  make shift-TAB to toggle mode
2100   (tiny-setup-define-key [(control shift backtab)]
2101                          global-map 'tinytab-mode nil force)
2102   (tiny-setup-define-key [(control shift tab)]
2103                          global-map 'tinytab-mode nil force)
2104   (tiny-setup-define-key [(control shift kp-tab)]
2105                          global-map 'tinytab-mode nil force))
2106
2107 (defun tiny-setup-tinytab-bindextraforce (&optional force)
2108   "Bind with FORCE."
2109   (tiny-setup-tinytab-bindextra 'force))
2110
2111 ;;; .......................................................... &tinytf ...
2112
2113 (defun tiny-setup-tinytf-buffer-type-p ()
2114   "Check if bufferi suitable for tinytf.el."
2115   (let (case-fold-search)
2116     (and (string-match "\\.txt"
2117                        (or (buffer-file-name) ""))
2118          (not (save-excursion
2119                 ;; Exclude mail buffers:
2120                 ;;     From: me@here.com
2121                 (goto-char (point-min))
2122                 (re-search-forward "^[-a-z]+: " nil t)))
2123          (or (re-search-forward
2124               "^Table [Oo]f [Cc]ontents[ \t]*$" nil t)
2125              ;; See if we can find level 1 and 2 headings
2126              ;;
2127              ;; This Heading here
2128              ;;
2129              ;;     And This Heading here
2130              ;;
2131              (re-search-forward
2132               "^[0-9.]*[A-Z][^ \t\n]+.*[\r\n]+    [A-Z][^ \t\n]" nil t)
2133              ;;  Try finding wro headers then
2134              ;;
2135              ;; This is Header
2136              ;;
2137              ;; And this is header
2138              ;;
2139              (and (re-search-forward
2140                    "^[0-9.]*[A-Z][^ \t\n][^ \t\n]+" nil t)
2141                   (re-search-forward
2142                    "^[0-9.]*[A-Z][^ \t\n][^ \t\n]+" nil t))))))
2143
2144 (defun tiny-setup-turn-on-tinytf-mode-maybe ()
2145   "Turn on mode function `tinytf-mode' as needed."
2146   (let (case-fold-search)
2147     (cond
2148      ((memq 'turn-on-tinytf-mode-maybe find-file-hooks)
2149       ;;  tinytf is already loaded, remove ourself.
2150       (remove-hook 'find-file-hooks 'tiny-setup-turn-on-tinytf-mode-maybe))
2151      ((tiny-setup-tinytf-buffer-type-p)
2152       (turn-on-tinytf-mode)
2153       (remove-hook 'find-file-hooks 'tiny-setup-turn-on-tinytf-mode-maybe)))
2154     ;;  Hook must return nil
2155     nil))
2156
2157 (defun tiny-setup-tinytf-autoload ()
2158   "Autoload."
2159   (defvar tinytf-mode nil)
2160   (tiny-setup-ti::macrov-mode-line-mode-menu
2161    tinytf-mode "Technical text")
2162   (add-hook 'find-file-hooks 'tiny-setup-turn-on-tinytf-mode-maybe))
2163
2164 ;;; ......................................................... &tinyurl ...
2165
2166 (defun tiny-setup-tinyurl-mode-maybe ()
2167   "Turn on `tinyurl-mode' as needed."
2168   (if (featurep 'tinyurl)
2169       ;; TinyUrl has already set up the watchdog.
2170       (remove-hook 'find-file-hooks 'tiny-setup-tinyurl-mode-maybe)
2171     ;;  Use simplistic test here. TinyUrl has much better once it's active.
2172     (if (ti::re-search-check "[fh]t?tp://[a-z]+[a-z.]+")
2173         (turn-on-tinyurl-mode)))
2174   ;;  Hook is best to return nil
2175   nil)
2176
2177 (defun tiny-setup-tinyurl-autoload ()
2178   "Autoload."
2179   (defvar tinyurl-mode nil)
2180   (tiny-setup-ti::macrov-mode-line-mode-menu
2181    tinyurl-mode "Url mode")
2182   (add-hook 'find-file-hooks 'tiny-setup-tinyurl-mode-maybe))
2183
2184 (defun tiny-setup-tinyurl-bind ()
2185   "Bind."
2186   (message "TinySetup: [tinyurl] nothing to bind. Call `tinyurl-mode-1'.")
2187   ;;*     (tiny-setup-define-key "\C-cmuu"  global-map 'tinyurl-mode)
2188   ;;*     (tiny-setup-define-key "\C-cmu1"  global-map 'tinyurl-mode-1)
2189   ;;*     (tiny-setup-define-key "\C-cmup"  global-map 'tinyurl-plugged-mode-toggle)
2190   nil)
2191
2192 (defun tiny-setup-tinyxreg-bind ()
2193   "Bind."
2194   (tiny-setup-define-key "\C-x/"
2195                          global-map 'tinyxreg-point-to-register "C-x/" 'force)
2196   (tiny-setup-define-key "\C-x\\"
2197                          global-map 'tinyxreg-remove-register "C-x\\")
2198   (tiny-setup-define-key "\C-cj"
2199                          global-map 'tinyxreg-jump-to-register "C-cj" ))
2200
2201 (provide   'tiny-setup)
2202 (run-hooks 'tiny-setup-load-hook)
2203
2204 ;;; tiny-setup.el ends here