~ubuntu-branches/ubuntu/precise/emacs-goodies-el/precise-proposed

« back to all changes in this revision

Viewing changes to elisp/emacs-goodies-el/miniedit.el

  • Committer: Bazaar Package Importer
  • Author(s): Bhavani Shankar
  • Date: 2010-06-22 19:03:03 UTC
  • mfrom: (4.1.20 sid)
  • Revision ID: james.westby@ubuntu.com-20100622190303-ygrbht6kae9ukl8m
Tags: 33.6ubuntu1
* Merge from debian unstable.  Remaining changes: LP: #597284
  - Add {hardy,jaunty,karmic,lucid}-proposed distribution targets
    to dpkg-dev-el.
  - Add maverick{,-proposed} distribution targets; drop out the lucid
    non-proposed target, since uploads to the release pocket are not
    permitted for stable releases.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;;; miniedit.el --- Enhanced editing for minibuffer fields.
 
2
;; Time-stamp: <2010-04-06 19:05:08 deego>
 
3
;; Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 
4
;; Emacs Lisp Archive entry
 
5
;; Filename: miniedit.el
 
6
;; Package: miniedit
 
7
;; Author(s): Deepak Goel <deego3@gmail.com>,
 
8
;;            Christoph Conrad <christoph.conrad@gmx.de>
 
9
;; Version: 2.0
 
10
;; Author's homepage: http://www.gnufans.net/~deego/DeegoWiki/DeepakGoel.html
 
11
;; For latest version:
 
12
 
 
13
(defconst miniedit-home-page
 
14
  "http://gnufans.net/~deego/emacspub/lisp-mine/miniedit/")
 
15
;; This file is NOT (yet) part of GNU Emacs.
 
16
 
 
17
;; This is free software; you can redistribute it and/or modify
 
18
;; it under the terms of the GNU General Public License as published by
 
19
;; the Free Software Foundation; either version 2, or (at your option)
 
20
;; any later version.
 
21
 
 
22
;; This is distributed in the hope that it will be useful,
 
23
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 
24
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
25
;; GNU General Public License for more details.
 
26
 
 
27
;; You should have received a copy of the GNU General Public License
 
28
;; along with GNU Emacs; see the file COPYING.  If not, write to the
 
29
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
30
;; Boston, MA 02111-1307, USA.
 
31
 
 
32
 
 
33
;; See also:
 
34
 
 
35
 
 
36
;; Quick start:
 
37
(defconst miniedit-quick-start
 
38
  "Drop this file somewhere in your load-path, and add somewhere in your  .emacs.
 
39
 \(require 'miniedit\)
 
40
 \(miniedit-install\)
 
41
Xemacsers use \(miniedit-install-for-xemacs\) instead of
 
42
\(miniedit-install\).
 
43
 
 
44
Installation can also be done by customizing the variable `miniedit-install'.
 
45
 
 
46
Then, type M-C-e in any minibuffer to do nicer edits, and type M-C-c
 
47
or C-c C-c when done.
 
48
 
 
49
Please type M-x miniedit-introduction, M-x miniedit-quick-start and
 
50
M-x miniedit-commentary for more details. "
 
51
)
 
52
 
 
53
;;;###autoload
 
54
(defun miniedit-quick-start ()
 
55
  "Provides electric help for function `miniedit-quick-start'."
 
56
  (interactive)
 
57
  (with-electric-help
 
58
   '(lambda () (insert miniedit-quick-start) nil) "*doc*"))
 
59
 
 
60
;;; Introduction:
 
61
;; Stuff that gets posted to gnu.emacs.sources
 
62
;; as introduction
 
63
(defconst miniedit-introduction
 
64
  "Helps easily edit minibuffers.
 
65
Adds a key \"C-M-e\" \(e for edit\) to the minibuffer-local-map, and
 
66
other similar maps, and bind it to the function `miniedit'. This
 
67
means that when you are in a minibuffer, trying to input text,
 
68
you can type C-M-e to go enter those fields in a nice, full buffer
 
69
\(with text mode\) instead.  In particular, inserting new lines and
 
70
indenting is easy.  Helpful, for instance, when editing bbdb notes
 
71
fields, which tend to be multiline, \(right?\)
 
72
 
 
73
P.S.: Lots of code borrowed from checkdoc.
 
74
 
 
75
Tested mainly on emacs21.  It may now work even on Xemacs, `
 
76
atleast for some of the minibuffer-maps.
 
77
 
 
78
Please type M-x miniedit-introduction, M-x miniedit-quick-start and
 
79
M-x miniedit-commentary for more details. ")
 
80
 
 
81
;;;###autoload
 
82
(defun miniedit-introduction ()
 
83
  "Provides electric help for function `miniedit-introduction'."
 
84
  (interactive)
 
85
  (with-electric-help
 
86
   '(lambda () (insert miniedit-introduction) nil) "*doc*"))
 
87
 
 
88
(defvar miniedit-version "2.0")
 
89
 
 
90
;;; BUGS:
 
91
;;   Commit problem:  Once you are in the miniedit buffer, if you move
 
92
;;   buffers around, switch back and forth etc., the commit *sometimes*
 
93
;;   fails.. the author is working on this.... :)
 
94
;;   that is why we kill-new and have variables like
 
95
;;   miniedit-before-edit-kill-p and miniedit-after-edit-kill-p. -- to
 
96
;;   save any lost data.
 
97
;;==========================================
 
98
;;; code:
 
99
(eval-when-compile (require 'custom))
 
100
(eval-when-compile
 
101
  (require 'cl))
 
102
 
 
103
(defgroup miniedit nil
 
104
  "Miniedit"
 
105
  :group 'applications)
 
106
 
 
107
(defcustom miniedit-install-p nil
 
108
  "Whether to setup miniedit for use."
 
109
  :type 'boolean
 
110
  :set (lambda (symbol value)
 
111
         (set-default symbol value)
 
112
         (when value
 
113
           (if (string-match "XEmacs" emacs-version)
 
114
               (miniedit-install-for-xemacs)
 
115
             (miniedit-install))))
 
116
  :require 'miniedit
 
117
  :group 'miniedit)
 
118
 
 
119
(defcustom miniedit-before-edit-kill-p nil
 
120
  "Add to kill ring before starting edit?"
 
121
  :group 'miniedit)
 
122
 
 
123
(defcustom miniedit-before-commit-kill-p nil
 
124
  "Add the string to `kill-ring' before committing?"
 
125
  :group 'miniedit
 
126
)
 
127
 
 
128
(defcustom miniedit-before-edit-function nil
 
129
 "Function to run on minibuffer-string before editing.
 
130
 
 
131
If this variable points to a function-name, that function is run on
 
132
the string that is gotten from the minibuffer..  The function should
 
133
do whatever it wants, and then it should return a (possibly) modified
 
134
string.  That modified string is what becomes the string to be
 
135
edited."
 
136
 
 
137
 :group 'miniedit
 
138
)
 
139
 
 
140
(defcustom miniedit-before-commit-function nil
 
141
 "If non-nil, function to run on minibuffer-string after editing.
 
142
 
 
143
If this variable points to a function-name, that function is run on
 
144
the string that is read from the miniedit-buffer..  The function should
 
145
do whatever it wants, and then it should return a (possibly) modified
 
146
string.  That modified string is what gets committed to the
 
147
minibuffer."
 
148
 :group 'miniedit
 
149
 
 
150
)
 
151
 
 
152
 
 
153
(defcustom miniedit-before-edit-hook nil
 
154
  "A hook thatis run before editing begins.."
 
155
  :group 'miniedit
 
156
)
 
157
 
 
158
(defcustom miniedit-before-commit-hook nil
 
159
  "A hook that is run before commitment to the minibuffer."
 
160
  :group 'miniedit
 
161
)
 
162
 
 
163
(defvar miniedit-string "miniedit-default-string"
 
164
  "This varible is what shall store the miniedit string temporarily...
 
165
This variable is introduced so that various miniedit-hooks can be used to
 
166
modify this string..")
 
167
 
 
168
 
 
169
 
 
170
(defmacro miniedit-withit (expr &rest rest)
 
171
  "Bind it to EXPR and do `REST'.
 
172
 
 
173
Caution: var-capture by its very nature.."
 
174
  `(let ((it ,expr))
 
175
     ,@rest))
 
176
 
 
177
;;;  Tom Fawcett <tfawcett@hpl.hp.com>
 
178
;; For us xemacs users who don't have princ-list
 
179
;(eval-when-compile
 
180
;  (unless (fboundp 'princ-list)
 
181
;    (defmacro princ-list (&rest things)
 
182
;      (cons 'progn (mapcar #'(lambda (x) `(princ ,x)) things)))))
 
183
 
 
184
;; special handling because princ-list is not defined for xemacs..
 
185
 
 
186
;;copied from mule-cmds.. and renamed...
 
187
(defun miniedit-princ-list (&rest args)
 
188
  "Same as `princ-list', but provided for Xemacs.  Print ARGS."
 
189
  (while args (princ (car args)) (setq args (cdr args)))
 
190
  (princ "\n"))
 
191
 
 
192
(defcustom miniedit-show-help-p t
 
193
  "Whether to pop up the help-buffer.."
 
194
  :type 'boolean
 
195
  :group 'miniedit)
 
196
 
 
197
(defcustom miniedit-fill-column-deduction 14
 
198
  "The `fill-column' will be reduced from its default by this amount.
 
199
 
 
200
One would like this because part of the minibuffer is occupied by the
 
201
prompt string.  And, for instance, because in bbdb's notes, a large
 
202
left margin is taken up by the entry \"notes:\".
 
203
 
 
204
This variable can be assigned *anything* which results in an integer
 
205
when eval'ed."
 
206
  :group 'miniedit :type 'integer
 
207
 
 
208
)
 
209
 
 
210
 
 
211
;;;###autoload
 
212
(defun miniedit ()
 
213
  "The main miniedit function."
 
214
  (interactive)
 
215
  (let ((miniedit-string miniedit-string)
 
216
        (minibufname (buffer-name))
 
217
        )
 
218
    (save-excursion
 
219
      ;; so that it can be redefined below..
 
220
      (makunbound 'miniedit-mode-map)
 
221
      (easy-mmode-define-minor-mode
 
222
       miniedit-mode
 
223
       "The mode to inherit minibuffer keybindings"
 
224
       nil
 
225
       " MINI"
 
226
       ;; 3 means C-c
 
227
       ;; 16 means C-p
 
228
       (list 'keymap (cons 16 (current-local-map))))
 
229
      (define-key miniedit-mode-map (kbd "C-c C-c") 'exit-recursive-edit)
 
230
      (let ((contents
 
231
             (miniedit-recursive-edit
 
232
              ""
 
233
              (progn
 
234
                (setq miniedit-string
 
235
                      (minibuffer-contents-no-properties))
 
236
                 (when (and
 
237
                        (stringp miniedit-string)
 
238
                        miniedit-before-edit-kill-p)
 
239
                   (kill-new miniedit-string))
 
240
                 (when
 
241
                     miniedit-before-edit-function
 
242
                   (miniedit-withit
 
243
                    (funcall miniedit-before-edit-function
 
244
                             miniedit-string)
 
245
                    (when it (setq miniedit-string it))))
 
246
                 (run-hooks 'miniedit-before-editing-hook)
 
247
                 miniedit-string)
 
248
              
 
249
              )))
 
250
        (delete-other-windows)
 
251
        (other-window 1)
 
252
        (miniedit-set-minibuffer-contents contents minibufname)
 
253
        ))))
 
254
 
 
255
(defun miniedit-set-minibuffer-contents (contents minibuffer-name)
 
256
  "Set `minibuffer-contents' to CONTENTS.
 
257
The name of the minibuffer is MINIBUFFER-NAME.
 
258
 
 
259
version 21 or higher only.."
 
260
  (set-buffer minibuffer-name)
 
261
  (delete-minibuffer-contents)
 
262
  (insert contents))
 
263
 
 
264
 
 
265
;;;###autoload
 
266
(defun miniedit-install ()
 
267
  "Install miniedit by frobbing your miniedit-local maps."
 
268
  (interactive)
 
269
  (define-key minibuffer-local-map "\M-\C-e" 'miniedit)
 
270
  (define-key minibuffer-local-ns-map "\M-\C-e" 'miniedit)
 
271
  (define-key minibuffer-local-completion-map "\M-\C-e" 'miniedit)
 
272
  (define-key minibuffer-local-must-match-map "\M-\C-e" 'miniedit)
 
273
  (when (interactive-p)
 
274
    (message "Miniedit installed.."))
 
275
  )
 
276
 
 
277
;;; 2002-05-03 T20:51:31-0400 (Friday)    D. Goel
 
278
;;;###autoload
 
279
(defun miniedit-install-for-xemacs ()
 
280
  "Try to Install miniedit for Xemacs."
 
281
  (interactive)
 
282
  (ignore-errors (define-key minibuffer-local-map "\M-\C-e" 'miniedit))
 
283
  ;;(define-key minibuffer-local-ns-map "\M-\C-e" 'miniedit)
 
284
  (ignore-errors (define-key minibuffer-local-completion-map "\M-\C-e" 'miniedit))
 
285
  (ignore-errors (define-key minibuffer-local-must-match-map "\M-\C-e" 'miniedit))
 
286
  )
 
287
 
 
288
;; silence the compiler:
 
289
(defun miniedit-mode (&rest arg)
 
290
  "Miniedit mode.
 
291
Optional argument ARG is ignored."
 
292
nil)
 
293
 
 
294
(defun miniedit-recursive-edit (msg &optional content)
 
295
  "Enter recursive edit to permit a user to edit long contents..
 
296
Useful when the original contents are in a minibuffer.  Transfer those
 
297
contents to a new buffer and edit them there.
 
298
 
 
299
MSG is a message, which is displayed in a Edit buffer.
 
300
Mostly copied from `checkdoc-recursive-edit'.
 
301
CONTENT is the content to be edited..
 
302
Then, returns a string...
 
303
 
 
304
Optimized for being called when the current buffer is a minibuffer.."
 
305
  (let ((this-buffer (buffer-name))
 
306
        (new-content content)
 
307
        save-content
 
308
        (errorp nil)
 
309
        )
 
310
    (save-excursion
 
311
      (other-window 1)
 
312
      (switch-to-buffer "*Miniedit*")
 
313
      (set-buffer "*Miniedit*")
 
314
      (setq save-content (buffer-substring (point-min) (point-max)))
 
315
      (delete-region (point-min) (point-max))
 
316
      (text-mode)
 
317
      (miniedit-mode t)
 
318
      (let ((fill-column (- fill-column
 
319
                            (eval miniedit-fill-column-deduction))))
 
320
        (if (stringp content) (insert content)
 
321
          (setq errorp t))
 
322
        (unless errorp
 
323
          (miniedit-show-help
 
324
           "Read THIS MESSAGE --->\n  " msg
 
325
           "\n\nEdit field, and press C-c C-c or C-M-c to continue.")
 
326
 
 
327
 
 
328
          (message "When you're done editing press C-M-c to continue.")
 
329
 
 
330
          (unwind-protect
 
331
              (recursive-edit)
 
332
            (if (get-buffer-window "*Miniedit*")
 
333
                (progn
 
334
                  (progn
 
335
                    (setq new-content (buffer-substring
 
336
                                       (point-min) (point-max)))
 
337
                    ;;(delete-window (get-buffer-window "*Miniedit*"))
 
338
                    (kill-buffer "*Miniedit*")
 
339
                    )))
 
340
            (when
 
341
                (get-buffer "*Miniedit Help*")
 
342
              (kill-buffer "*Miniedit Help*")))))
 
343
      (unless (stringp new-content)
 
344
        (setq errorp t))
 
345
 
 
346
      
 
347
      ;;user-customization of new content begins..
 
348
      (setq miniedit-string
 
349
            new-content)
 
350
      (when (and
 
351
             (stringp miniedit-string)
 
352
             miniedit-before-commit-kill-p)
 
353
        (kill-new miniedit-string))
 
354
      (when
 
355
          miniedit-before-commit-function
 
356
        (miniedit-withit
 
357
         (funcall miniedit-before-commit-function
 
358
                  miniedit-string)
 
359
         (when it (setq miniedit-string it))))
 
360
      (run-hooks 'miniedit-before-committing-hook)
 
361
        ;;user-customization of new content ends..
 
362
        
 
363
 
 
364
      (if (not errorp)
 
365
          new-content
 
366
        save-content))))
 
367
 
 
368
 
 
369
 
 
370
 
 
371
(defun miniedit-recursive-edit-no-mini (msg &optional content)
 
372
  "No use of this function is currently known.
 
373
Enter recursive edit to permit a user to edit long bbdb contents..
 
374
MSG is a message, which is displayed in a Edit buffer.
 
375
Mostly copied from `checkdoc-recursive-edit'.
 
376
CONTENT is the content to be edited..
 
377
Then, returns a string...
 
378
 
 
379
Optimized for being called when the current buffer is not a minibuffer.."
 
380
  (let ((this-buffer (buffer-name))
 
381
        (new-content content)
 
382
        )
 
383
    (save-excursion
 
384
      ;(other-window 1)
 
385
      (switch-to-buffer "*Miniedit*")
 
386
      (set-buffer "*Miniedit*")
 
387
      (kill-region (point-min) (point-max))
 
388
      (text-mode)
 
389
      (let ((fill-column (- fill-column 16)))
 
390
        (if (stringp content) (insert content))
 
391
        (with-output-to-temp-buffer "*Miniedit Help*"
 
392
          (miniedit-princ-list
 
393
           "IMPORTANT: Read THIS MESSAGE --->\n  " msg
 
394
           "\n\nEdit field, and press C-M-c to continue."))
 
395
        (shrink-window-if-larger-than-buffer
 
396
         (get-buffer-window "*Miniedit Help*"))
 
397
        (message "When you're done editing press C-M-c to continue.")
 
398
        (unwind-protect
 
399
            (recursive-edit)
 
400
          (if (get-buffer-window "*Miniedit*")
 
401
              (progn
 
402
                (progn
 
403
                  (setq new-content (buffer-substring
 
404
                                     (point-min) (point-max)))
 
405
                  (delete-window (get-buffer-window "*Miniedit*"))
 
406
                  (kill-buffer "*Miniedit*")
 
407
                  )))
 
408
          (kill-buffer "*Miniedit Help*")))
 
409
      (switch-to-buffer this-buffer)
 
410
      new-content)))
 
411
  
 
412
 
 
413
(defun miniedit-show-help (&rest args)
 
414
  "Show help.
 
415
Optional argument ARGS will be ignored."
 
416
  (when miniedit-show-help-p
 
417
    (with-output-to-temp-buffer "*Miniedit Help*"
 
418
      (apply 'miniedit-princ-list
 
419
             args))
 
420
    (shrink-window-if-larger-than-buffer
 
421
     (get-buffer-window "*Miniedit Help*"))))
 
422
 
 
423
 
 
424
 
 
425
(provide 'miniedit)
 
426
 
 
427
;;; miniedit.el ends here