comparison lisp/custom/widget-edit.el @ 20:859a2309aef8 r19-15b93

Import from CVS: tag r19-15b93
author cvs
date Mon, 13 Aug 2007 08:50:05 +0200
parents d95e72db5c07
children 8fc7fe29b841
comparison
equal deleted inserted replaced
19:ac1f612d5250 20:859a2309aef8
2 ;; 2 ;;
3 ;; Copyright (C) 1996 Free Software Foundation, Inc. 3 ;; Copyright (C) 1996 Free Software Foundation, Inc.
4 ;; 4 ;;
5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> 5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
6 ;; Keywords: extensions 6 ;; Keywords: extensions
7 ;; Version: 1.24 7 ;; Version: 1.30
8 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ 8 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
9 9
10 ;;; Commentary: 10 ;;; Commentary:
11 ;; 11 ;;
12 ;; See `widget.el'. 12 ;; See `widget.el'.
188 (t 188 (t
189 (cdr (assoc (completing-read (concat title ": ") 189 (cdr (assoc (completing-read (concat title ": ")
190 items nil t) 190 items nil t)
191 items))))) 191 items)))))
192 192
193 (defun widget-get-sibling (widget)
194 "Get the item WIDGET is assumed to toggle.
195 This is only meaningful for radio buttons or checkboxes in a list."
196 (let* ((parent (widget-get widget :parent))
197 (children (widget-get parent :children))
198 child)
199 (catch 'child
200 (while children
201 (setq child (car children)
202 children (cdr children))
203 (when (eq (widget-get child :button) widget)
204 (throw 'child child)))
205 nil)))
206
193 ;;; Widget text specifications. 207 ;;; Widget text specifications.
194 ;; 208 ;;
195 ;; These functions are for specifying text properties. 209 ;; These functions are for specifying text properties.
196 210
197 (defun widget-specify-none (from to) 211 (defun widget-specify-none (from to)
286 (put-text-property (point) (1+ (point)) 'secret old)) 300 (put-text-property (point) (1+ (point)) 'secret old))
287 (forward-char)))) 301 (forward-char))))
288 302
289 (unless (widget-get widget :size) 303 (unless (widget-get widget :size)
290 (add-text-properties to (1+ to) (list 'field widget 304 (add-text-properties to (1+ to) (list 'field widget
291 'face face 305 'face face)))
292 'local-map map 306 (add-text-properties to (1+ to) (list 'local-map map
293 'keymap map))))) 307 'keymap map))))
294 308
295 (defun widget-specify-button (widget from to) 309 (defun widget-specify-button (widget from to)
296 ;; Specify button for WIDGET between FROM and TO. 310 ;; Specify button for WIDGET between FROM and TO.
297 (let ((face (widget-apply widget :button-face-get))) 311 (let ((face (widget-apply widget :button-face-get)))
298 (add-text-properties from to (list 'button widget 312 (add-text-properties from to (list 'button widget
329 (delete-region (1- (point-max)) (point-max)) 343 (delete-region (1- (point-max)) (point-max))
330 (goto-char (point-max)) 344 (goto-char (point-max))
331 result))) 345 result)))
332 346
333 ;;; Widget Properties. 347 ;;; Widget Properties.
348
349 (defsubst widget-name (widget)
350 "Return the name of WIDGET, asymbol."
351 (car widget))
334 352
335 (defun widget-put (widget property value) 353 (defun widget-put (widget property value)
336 "In WIDGET set PROPERTY to VALUE. 354 "In WIDGET set PROPERTY to VALUE.
337 The value can later be retrived with `widget-get'." 355 The value can later be retrived with `widget-get'."
338 (setcdr widget (plist-put (cdr widget) property value))) 356 (setcdr widget (plist-put (cdr widget) property value)))
489 "Keymap containing useful binding for buffers containing widgets. 507 "Keymap containing useful binding for buffers containing widgets.
490 Recommended as a parent keymap for modes using widgets.") 508 Recommended as a parent keymap for modes using widgets.")
491 509
492 (unless widget-keymap 510 (unless widget-keymap
493 (setq widget-keymap (make-sparse-keymap)) 511 (setq widget-keymap (make-sparse-keymap))
512 (define-key widget-keymap "\C-k" 'widget-kill-line)
494 (define-key widget-keymap "\t" 'widget-forward) 513 (define-key widget-keymap "\t" 'widget-forward)
495 (define-key widget-keymap "\M-\t" 'widget-backward) 514 (define-key widget-keymap "\M-\t" 'widget-backward)
496 (define-key widget-keymap [(shift tab)] 'widget-backward) 515 (define-key widget-keymap [(shift tab)] 'widget-backward)
497 (define-key widget-keymap [(shift tab)] 'widget-backward) 516 (define-key widget-keymap [(shift tab)] 'widget-backward)
498 (define-key widget-keymap [backtab] 'widget-backward) 517 (define-key widget-keymap [backtab] 'widget-backward)
510 "Keymap used inside an editable field.") 529 "Keymap used inside an editable field.")
511 530
512 (unless widget-field-keymap 531 (unless widget-field-keymap
513 (setq widget-field-keymap (copy-keymap widget-keymap)) 532 (setq widget-field-keymap (copy-keymap widget-keymap))
514 (define-key widget-field-keymap "\C-m" 'widget-field-activate) 533 (define-key widget-field-keymap "\C-m" 'widget-field-activate)
534 (define-key widget-field-keymap "\C-a" 'widget-beginning-of-line)
535 (define-key widget-field-keymap "\C-e" 'widget-end-of-line)
515 (set-keymap-parent widget-field-keymap global-map)) 536 (set-keymap-parent widget-field-keymap global-map))
516 537
517 (defvar widget-text-keymap nil 538 (defvar widget-text-keymap nil
518 "Keymap used inside a text field.") 539 "Keymap used inside a text field.")
519 540
520 (unless widget-text-keymap 541 (unless widget-text-keymap
521 (setq widget-text-keymap (copy-keymap widget-keymap)) 542 (setq widget-text-keymap (copy-keymap widget-keymap))
543 (define-key widget-text-keymap "\C-a" 'widget-beginning-of-line)
544 (define-key widget-text-keymap "\C-e" 'widget-end-of-line)
522 (set-keymap-parent widget-text-keymap global-map)) 545 (set-keymap-parent widget-text-keymap global-map))
523 546
524 (defun widget-field-activate (pos &optional event) 547 (defun widget-field-activate (pos &optional event)
525 "Activate the ediable field at point." 548 "Activate the ediable field at point."
526 (interactive "@d") 549 (interactive "@d")
623 With optional ARG, move across that many fields." 646 With optional ARG, move across that many fields."
624 (interactive "p") 647 (interactive "p")
625 (run-hooks 'widget-backward-hook) 648 (run-hooks 'widget-backward-hook)
626 (widget-move (- arg))) 649 (widget-move (- arg)))
627 650
651 (defun widget-beginning-of-line ()
652 "Go to beginning of field or beginning of line, whichever is first."
653 (interactive)
654 (let ((bol (save-excursion (beginning-of-line) (point)))
655 (prev (previous-single-property-change (point) 'field)))
656 (goto-char (max bol (or prev bol)))))
657
658 (defun widget-end-of-line ()
659 "Go to end of field or end of line, whichever is first."
660 (interactive)
661 (let ((bol (save-excursion (end-of-line) (point)))
662 (prev (next-single-property-change (point) 'field)))
663 (goto-char (min bol (or prev bol)))))
664
665 (defun widget-kill-line ()
666 "Kill to end of field or end of line, whichever is first."
667 (interactive)
668 (let ((field (get-text-property (point) 'field))
669 (newline (save-excursion (search-forward "\n")))
670 (next (next-single-property-change (point) 'field)))
671 (if (and field (> newline next))
672 (kill-region (point) next)
673 (call-interactively 'kill-line))))
674
675 (defun widget-identify (pos)
676 "Identify the widget under point."
677 (interactive "d")
678 (let* ((field (get-text-property pos 'field))
679 (button (get-text-property pos 'button))
680 (doc (get-text-property pos 'widget-doc))
681 (widget (or field button doc)))
682 (with-output-to-temp-buffer "*Widget Identity*"
683 (princ (cond (field "This is an editable text area.\n")
684 (button "This is an active area.\n")
685 (doc "This is documentation text.\n")
686 (t "This is unidentified text.\n")))
687 (while widget
688 (princ "It is part of a `")
689 (princ (car widget))
690 (princ "' widget (value: ")
691 (prin1 (condition-case nil
692 (widget-value widget)
693 (error 'error)))
694 (princ ").\n")
695 (when (eq (car widget) 'radio-button)
696 (let ((sibling (widget-get-sibling widget)))
697 (if (not sibling)
698 (princ "It doesn't seem to control anything.\n")
699 (princ "The value of its sibling is: ")
700 (prin1 (condition-case nil
701 (widget-value sibling)
702 (error 'error)))
703 (princ ".\n"))))
704 (setq widget (widget-get widget :parent))))))
705
628 ;;; Setting up the buffer. 706 ;;; Setting up the buffer.
629 707
630 (defvar widget-field-new nil) 708 (defvar widget-field-new nil)
631 ;; List of all newly created editable fields in the buffer. 709 ;; List of all newly created editable fields in the buffer.
632 (make-variable-buffer-local 'widget-field-new) 710 (make-variable-buffer-local 'widget-field-new)
1229 found (widget-match-inline current values))) 1307 found (widget-match-inline current values)))
1230 found)) 1308 found))
1231 1309
1232 ;;; The `toggle' Widget. 1310 ;;; The `toggle' Widget.
1233 1311
1234 (define-widget 'toggle 'menu-choice 1312 (define-widget 'toggle 'item
1235 "Toggle between two states." 1313 "Toggle between two states."
1236 :convert-widget 'widget-toggle-convert-widget 1314 :format "%[%v%]\n"
1237 :format "%v" 1315 :value-create 'widget-toggle-value-create
1316 :action 'widget-toggle-action
1317 :match (lambda (widget value) t)
1238 :on "on" 1318 :on "on"
1239 :off "off") 1319 :off "off")
1240 1320
1241 (defun widget-toggle-convert-widget (widget) 1321 (defun widget-toggle-value-create (widget)
1242 ;; Create the types representing the `on' and `off' states. 1322 ;; Insert text representing the `on' and `off' states.
1243 (let ((on-type (widget-get widget :on-type)) 1323 (if (widget-value widget)
1244 (off-type (widget-get widget :off-type))) 1324 (insert (widget-get widget :on))
1245 (unless on-type 1325 (insert (widget-get widget :off))))
1246 (setq on-type 1326
1247 (list 'choice-item 1327 (defun widget-toggle-action (widget &optional event)
1248 :value t 1328 ;; Toggle value.
1249 :match (lambda (widget value) value) 1329 (widget-value-set widget (not (widget-value widget)))
1250 :tag (widget-get widget :on)))) 1330 (widget-apply widget :notify widget event))
1251 (unless off-type 1331
1252 (setq off-type
1253 (list 'choice-item :value nil :tag (widget-get widget :off))))
1254 (widget-put widget :args (list on-type off-type)))
1255 widget)
1256
1257 ;;; The `checkbox' Widget. 1332 ;;; The `checkbox' Widget.
1258 1333
1259 (define-widget 'checkbox 'toggle 1334 (define-widget 'checkbox 'toggle
1260 "A checkbox toggle." 1335 "A checkbox toggle."
1261 :convert-widget 'widget-item-convert-widget 1336 :format "%[%v%]"
1262 :on-type '(choice-item :format "%[[X]%]" t) 1337 :on "[X]"
1263 :off-type '(choice-item :format "%[[ ]%]" nil)) 1338 :off "[ ]")
1264 1339
1265 ;;; The `checklist' Widget. 1340 ;;; The `checklist' Widget.
1266 1341
1267 (define-widget 'checklist 'default 1342 (define-widget 'checklist 'default
1268 "A multiple choice widget." 1343 "A multiple choice widget."
1425 ;;; The `radio-button' Widget. 1500 ;;; The `radio-button' Widget.
1426 1501
1427 (define-widget 'radio-button 'toggle 1502 (define-widget 'radio-button 'toggle
1428 "A radio button for use in the `radio' widget." 1503 "A radio button for use in the `radio' widget."
1429 :notify 'widget-radio-button-notify 1504 :notify 'widget-radio-button-notify
1430 :on-type '(choice-item :format "%[(*)%]" t) 1505 :format "%[%v%]"
1431 :off-type '(choice-item :format "%[( )%]" nil)) 1506 :on "(*)"
1507 :off "( )")
1432 1508
1433 (defun widget-radio-button-notify (widget child &optional event) 1509 (defun widget-radio-button-notify (widget child &optional event)
1434 ;; Notify the parent. 1510 ;; Tell daddy.
1435 (widget-apply (widget-get widget :parent) :action widget event)) 1511 (widget-apply (widget-get widget :parent) :action widget event))
1436 1512
1437 ;;; The `radio-button-choice' Widget. 1513 ;;; The `radio-button-choice' Widget.
1438 1514
1439 (define-widget 'radio-button-choice 'default 1515 (define-widget 'radio-button-choice 'default
2072 :format "%{%t%}:\n%v") 2148 :format "%{%t%}:\n%v")
2073 2149
2074 (define-widget 'boolean 'toggle 2150 (define-widget 'boolean 'toggle
2075 "To be nil or non-nil, that is the question." 2151 "To be nil or non-nil, that is the question."
2076 :tag "Boolean" 2152 :tag "Boolean"
2077 :format "%{%t%}: %v") 2153 :format "%{%t%}: %[%v%]")
2078 2154
2079 ;;; The `color' Widget. 2155 ;;; The `color' Widget.
2080 2156
2081 (define-widget 'color-item 'choice-item 2157 (define-widget 'color-item 'choice-item
2082 "A color name (with sample)." 2158 "A color name (with sample)."