sekka 1.6.4 → 1.6.5

Sign up to get free protection for your applications and to get access to all the features.
data/emacs/popup.el DELETED
@@ -1,1410 +0,0 @@
1
- ;;; popup.el --- Visual Popup User Interface
2
-
3
- ;; Copyright (C) 2009-2015 Tomohiro Matsuyama
4
-
5
- ;; Author: Tomohiro Matsuyama <m2ym.pub@gmail.com>
6
- ;; Keywords: lisp
7
- ;; Package-Version: 20150315.612
8
- ;; Version: 0.5.2
9
- ;; Package-Requires: ((cl-lib "0.3"))
10
-
11
- ;; This program is free software; you can redistribute it and/or modify
12
- ;; it under the terms of the GNU General Public License as published by
13
- ;; the Free Software Foundation, either version 3 of the License, or
14
- ;; (at your option) any later version.
15
-
16
- ;; This program is distributed in the hope that it will be useful,
17
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- ;; GNU General Public License for more details.
20
-
21
- ;; You should have received a copy of the GNU General Public License
22
- ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
23
-
24
- ;;; Commentary:
25
-
26
- ;; popup.el is a visual popup user interface library for Emacs. This
27
- ;; provides a basic API and common UI widgets such as popup tooltips
28
- ;; and popup menus.
29
- ;; See README.markdown for more information.
30
-
31
- ;;; Code:
32
-
33
- (require 'cl-lib)
34
-
35
- (defconst popup-version "0.5.2")
36
-
37
-
38
-
39
- ;;; Utilities
40
-
41
- (defun popup-calculate-max-width (max-width)
42
- "Determines whether the width desired is
43
- character or window proportion based, And returns the result."
44
- (cl-typecase max-width
45
- (integer max-width)
46
- (float (* (ceiling (/ (round (* max-width (window-width))) 10.0)) 10))))
47
-
48
- (defvar popup-use-optimized-column-computation t
49
- "Use the optimized column computation routine.
50
- If there is a problem, please set it nil.")
51
-
52
- (defmacro popup-aif (test then &rest else)
53
- "Anaphoric if."
54
- (declare (indent 2))
55
- `(let ((it ,test))
56
- (if it ,then ,@else)))
57
-
58
- (defmacro popup-awhen (test &rest body)
59
- "Anaphoric when."
60
- (declare (indent 1))
61
- `(let ((it ,test))
62
- (when it ,@body)))
63
-
64
- (defun popup-x-to-string (x)
65
- "Convert any object to string effeciently.
66
- This is faster than `prin1-to-string' in many cases."
67
- (cl-typecase x
68
- (string x)
69
- (symbol (symbol-name x))
70
- (integer (number-to-string x))
71
- (float (number-to-string x))
72
- (t (format "%s" x))))
73
-
74
- (defun popup-substring-by-width (string width)
75
- "Return a cons cell of substring and remaining string by
76
- splitting with WIDTH."
77
- ;; Expand tabs into 4 spaces
78
- (setq string (replace-regexp-in-string "\t" " " string))
79
- (cl-loop with len = (length string)
80
- with w = 0
81
- for l from 0
82
- for c in (append string nil)
83
- while (<= (cl-incf w (char-width c)) width)
84
- finally return
85
- (if (< l len)
86
- (cons (substring string 0 l) (substring string l))
87
- (list string))))
88
-
89
- (defun popup-fill-string (string &optional width max-width justify squeeze)
90
- "Split STRING into fixed width strings and return a cons cell
91
- like \(WIDTH . ROWS). Here, the car WIDTH indicates the actual
92
- maxim width of ROWS.
93
-
94
- The argument WIDTH specifies the width of filling each
95
- paragraph. WIDTH nil means don't perform any justification and
96
- word wrap. Note that this function doesn't add any padding
97
- characters at the end of each row.
98
-
99
- MAX-WIDTH, if WIDTH is nil, specifies the maximum number of
100
- columns.
101
-
102
- The optional fourth argument JUSTIFY specifies which kind of
103
- justification to do: `full', `left', `right', `center', or
104
- `none' (equivalent to nil). A value of t means handle each
105
- paragraph as specified by its text properties.
106
-
107
- SQUEEZE nil means leave whitespaces other than line breaks
108
- untouched."
109
- (if (eq width 0)
110
- (error "Can't fill string with 0 width"))
111
- (if width
112
- (setq max-width width))
113
- (with-temp-buffer
114
- (let ((tab-width 4)
115
- (fill-column width)
116
- (left-margin 0)
117
- (kinsoku-limit 1)
118
- indent-tabs-mode
119
- row rows)
120
- (insert string)
121
- (untabify (point-min) (point-max))
122
- (if width
123
- (fill-region (point-min) (point-max) justify (not squeeze)))
124
- (goto-char (point-min))
125
- (setq width 0)
126
- (while (prog2
127
- (let ((line (buffer-substring
128
- (point) (progn (end-of-line) (point)))))
129
- (if max-width
130
- (while (progn
131
- (setq row (truncate-string-to-width line max-width)
132
- width (max width (string-width row)))
133
- (push row rows)
134
- (if (not (= (length row) (length line)))
135
- (setq line (substring line (length row))))))
136
- (setq width (max width (string-width line)))
137
- (push line rows)))
138
- (< (point) (point-max))
139
- (beginning-of-line 2)))
140
- (cons width (nreverse rows)))))
141
-
142
- (defmacro popup-save-buffer-state (&rest body)
143
- (declare (indent 0))
144
- `(save-excursion
145
- (let ((buffer-undo-list t)
146
- (inhibit-read-only t)
147
- (modified (buffer-modified-p)))
148
- (unwind-protect
149
- (progn ,@body)
150
- (set-buffer-modified-p modified)))))
151
-
152
- (defun popup-vertical-motion (column direction)
153
- "A portable version of `vertical-motion'."
154
- (if (>= emacs-major-version 23)
155
- (vertical-motion (cons column direction))
156
- (vertical-motion direction)
157
- (move-to-column (+ (current-column) column))))
158
-
159
- (defun popup-last-line-of-buffer-p ()
160
- "Return non-nil if the cursor is at the last line of the
161
- buffer."
162
- (save-excursion (end-of-line) (/= (forward-line) 0)))
163
-
164
- (defun popup-lookup-key-by-event (function event)
165
- (or (funcall function (vector event))
166
- (if (symbolp event)
167
- (popup-aif (get event 'event-symbol-element-mask)
168
- (funcall function
169
- (vector (logior (or (get (car it) 'ascii-character)
170
- 0)
171
- (cadr it))))))))
172
-
173
-
174
-
175
- ;;; Core
176
-
177
- (defgroup popup nil
178
- "Visual Popup User Interface"
179
- :group 'lisp
180
- :prefix "popup-")
181
-
182
- (defface popup-face
183
- '((t (:background "lightgray" :foreground "black")))
184
- "Face for popup."
185
- :group 'popup)
186
-
187
- (defface popup-summary-face
188
- '((t (:inherit popup-face :foreground "dimgray")))
189
- "Face for popup summary."
190
- :group 'popup)
191
-
192
- (defface popup-scroll-bar-foreground-face
193
- '((t (:background "black")))
194
- "Foreground face for scroll-bar."
195
- :group 'popup)
196
-
197
- (defface popup-scroll-bar-background-face
198
- '((t (:background "gray")))
199
- "Background face for scroll-bar."
200
- :group 'popup)
201
-
202
- (defvar popup-instances nil
203
- "Popup instances.")
204
-
205
- (defvar popup-scroll-bar-foreground-char
206
- (propertize " " 'face 'popup-scroll-bar-foreground-face)
207
- "Foreground character for scroll-bar.")
208
-
209
- (defvar popup-scroll-bar-background-char
210
- (propertize " " 'face 'popup-scroll-bar-background-face)
211
- "Background character for scroll-bar.")
212
-
213
- (cl-defstruct popup
214
- point row column width height min-height direction overlays keymap
215
- parent depth
216
- face mouse-face selection-face summary-face
217
- margin-left margin-right margin-left-cancel scroll-bar symbol
218
- cursor offset scroll-top current-height list newlines
219
- pattern original-list invis-overlays)
220
-
221
- (defun popup-item-propertize (item &rest properties)
222
- "Same as `propertize' except that this avoids overriding
223
- existed value with `nil' property."
224
- (cl-loop for (k v) on properties by 'cddr
225
- if v append (list k v) into props
226
- finally return
227
- (apply 'propertize
228
- (popup-x-to-string item)
229
- props)))
230
-
231
- (defun popup-item-property (item property)
232
- "Same as `get-text-property' except that this returns nil if
233
- ITEM is not string."
234
- (if (stringp item)
235
- (get-text-property 0 property item)))
236
-
237
- (cl-defun popup-make-item (name
238
- &key
239
- value
240
- face
241
- mouse-face
242
- selection-face
243
- sublist
244
- document
245
- symbol
246
- summary)
247
- "Utility function to make popup item. See also
248
- `popup-item-propertize'."
249
- (popup-item-propertize name
250
- 'value value
251
- 'popup-face face
252
- 'popup-mouse-face mouse-face
253
- 'selection-face selection-face
254
- 'document document
255
- 'symbol symbol
256
- 'summary summary
257
- 'sublist sublist))
258
-
259
- (defsubst popup-item-value (item) (popup-item-property item 'value))
260
- (defsubst popup-item-value-or-self (item) (or (popup-item-value item) item))
261
- (defsubst popup-item-face (item) (popup-item-property item 'popup-face))
262
- (defsubst popup-item-mouse-face (item) (popup-item-property item 'popup-mouse-face))
263
- (defsubst popup-item-selection-face (item) (popup-item-property item 'selection-face))
264
- (defsubst popup-item-document (item) (popup-item-property item 'document))
265
- (defsubst popup-item-summary (item) (popup-item-property item 'summary))
266
- (defsubst popup-item-symbol (item) (popup-item-property item 'symbol))
267
- (defsubst popup-item-sublist (item) (popup-item-property item 'sublist))
268
-
269
- (defun popup-item-documentation (item)
270
- (let ((doc (popup-item-document item)))
271
- (if (functionp doc)
272
- (setq doc (funcall doc (popup-item-value-or-self item))))
273
- doc))
274
-
275
- (defun popup-item-show-help-1 (item)
276
- (let ((doc (popup-item-documentation item)))
277
- (when doc
278
- (with-current-buffer (get-buffer-create " *Popup Help*")
279
- (erase-buffer)
280
- (insert doc)
281
- (goto-char (point-min))
282
- (display-buffer (current-buffer)))
283
- t)))
284
-
285
- (defun popup-item-show-help-with-event-loop (item)
286
- (save-window-excursion
287
- (when (popup-item-show-help-1 item)
288
- (cl-loop do (clear-this-command-keys)
289
- for key = (read-key-sequence-vector nil)
290
- do
291
- (cl-case (key-binding key)
292
- (scroll-other-window
293
- (scroll-other-window))
294
- (scroll-other-window-down
295
- (scroll-other-window-down nil))
296
- (otherwise
297
- (setq unread-command-events (append key unread-command-events))
298
- (cl-return)))))))
299
-
300
- (defun popup-item-show-help (item &optional persist)
301
- "Display the documentation of ITEM with `display-buffer'. If
302
- PERSIST is nil, the documentation buffer will be closed
303
- automatically, meaning interal event loop ensures the buffer to
304
- be closed. Otherwise, the buffer will be just displayed as
305
- usual."
306
- (when item
307
- (if (not persist)
308
- (popup-item-show-help-with-event-loop item)
309
- (popup-item-show-help-1 item))))
310
-
311
- (defun popup-set-list (popup list)
312
- (popup-set-filtered-list popup list)
313
- (setf (popup-pattern popup) nil)
314
- (setf (popup-original-list popup) list))
315
-
316
- (defun popup-set-filtered-list (popup list)
317
- (let ((offset
318
- (if (> (popup-direction popup) 0)
319
- 0
320
- (max (- (popup-height popup) (length list)) 0))))
321
- (setf (popup-list popup) list
322
- (popup-offset popup) offset)))
323
-
324
- (defun popup-selected-item (popup)
325
- (nth (popup-cursor popup) (popup-list popup)))
326
-
327
- (defun popup-selected-line (popup)
328
- (- (popup-cursor popup) (popup-scroll-top popup)))
329
-
330
- (defun popup-line-overlay (popup line)
331
- (aref (popup-overlays popup) line))
332
-
333
- (defun popup-selected-line-overlay (popup)
334
- (popup-line-overlay popup (popup-selected-line popup)))
335
-
336
- (defun popup-hide-line (popup line)
337
- (let ((overlay (popup-line-overlay popup line)))
338
- (overlay-put overlay 'display nil)
339
- (overlay-put overlay 'after-string nil)))
340
-
341
- (defun popup-line-hidden-p (popup line)
342
- (let ((overlay (popup-line-overlay popup line)))
343
- (and (eq (overlay-get overlay 'display) nil)
344
- (eq (overlay-get overlay 'after-string) nil))))
345
-
346
- (cl-defun popup-set-line-item (popup
347
- line
348
- &key
349
- item
350
- face
351
- mouse-face
352
- margin-left
353
- margin-right
354
- scroll-bar-char
355
- symbol
356
- summary
357
- summary-face
358
- keymap)
359
- (let* ((overlay (popup-line-overlay popup line))
360
- (content (popup-create-line-string popup (popup-x-to-string item)
361
- :margin-left margin-left
362
- :margin-right margin-right
363
- :symbol symbol
364
- :summary summary
365
- :summary-face summary-face))
366
- (start 0)
367
- (prefix (overlay-get overlay 'prefix))
368
- (postfix (overlay-get overlay 'postfix))
369
- end)
370
- (put-text-property 0 (length content) 'popup-item item content)
371
- (put-text-property 0 (length content) 'keymap keymap content)
372
- ;; Overlap face properties
373
- (when (get-text-property start 'face content)
374
- (setq start (next-single-property-change start 'face content)))
375
- (while (and start (setq end (next-single-property-change start 'face content)))
376
- (put-text-property start end 'face face content)
377
- (setq start (next-single-property-change end 'face content)))
378
- (when start
379
- (put-text-property start (length content) 'face face content))
380
- (when mouse-face
381
- (put-text-property 0 (length content) 'mouse-face mouse-face content))
382
- (unless (overlay-get overlay 'dangle)
383
- (overlay-put overlay 'display (concat prefix (substring content 0 1)))
384
- (setq prefix nil
385
- content (concat (substring content 1))))
386
- (overlay-put overlay
387
- 'after-string
388
- (concat prefix
389
- content
390
- scroll-bar-char
391
- postfix))))
392
-
393
- (cl-defun popup-create-line-string (popup
394
- string
395
- &key
396
- margin-left
397
- margin-right
398
- symbol
399
- summary
400
- summary-face)
401
- (let* ((popup-width (popup-width popup))
402
- (summary-width (string-width summary))
403
- (content-width (max
404
- (min popup-width (string-width string))
405
- (- popup-width
406
- (if (> summary-width 0)
407
- (+ summary-width 2)
408
- 0))))
409
- (string (car (popup-substring-by-width string content-width)))
410
- (string-width (string-width string))
411
- (spacing (max (- popup-width string-width summary-width)
412
- (if (> popup-width string-width) 1 0)))
413
- (truncated-summary
414
- (car (popup-substring-by-width
415
- summary (max (- popup-width string-width spacing) 0)))))
416
- (when summary-face
417
- (put-text-property 0 (length truncated-summary)
418
- 'face summary-face truncated-summary))
419
- (concat margin-left
420
- string
421
- (make-string spacing ? )
422
- truncated-summary
423
- symbol
424
- margin-right)))
425
-
426
- (defun popup-live-p (popup)
427
- "Return non-nil if POPUP is alive."
428
- (and popup (popup-overlays popup) t))
429
-
430
- (defun popup-child-point (popup &optional offset)
431
- (overlay-end
432
- (popup-line-overlay
433
- popup
434
- (or offset
435
- (popup-selected-line popup)))))
436
-
437
- (defun popup-calculate-direction (height row)
438
- "Return a proper direction when displaying a popup on this
439
- window. HEIGHT is the a height of the popup, and ROW is a line
440
- number at the point."
441
- (let* ((remaining-rows (- (max 1 (- (window-height)
442
- (if mode-line-format 1 0)
443
- (if header-line-format 1 0)))
444
- (count-lines (window-start) (point))))
445
- (enough-space-above (> row height))
446
- (enough-space-below (<= height remaining-rows)))
447
- (if (and enough-space-above
448
- (not enough-space-below))
449
- -1
450
- 1)))
451
-
452
- (cl-defun popup-create (point
453
- width
454
- height
455
- &key
456
- min-height
457
- max-width
458
- around
459
- (face 'popup-face)
460
- mouse-face
461
- (selection-face face)
462
- (summary-face 'popup-summary-face)
463
- scroll-bar
464
- margin-left
465
- margin-right
466
- symbol
467
- parent
468
- parent-offset
469
- keymap)
470
- "Create a popup instance at POINT with WIDTH and HEIGHT.
471
-
472
- MIN-HEIGHT is a minimal height of the popup. The default value is
473
- 0.
474
-
475
- MAX-WIDTH is the maximum width of the popup. The default value is
476
- nil (no limit). If a floating point, the value refers to the ratio of
477
- the window. If an integer, limit is in characters.
478
-
479
- If AROUND is non-nil, the popup will be displayed around the
480
- point but not at the point.
481
-
482
- FACE is a background face of the popup. The default value is POPUP-FACE.
483
-
484
- SELECTION-FACE is a foreground (selection) face of the popup The
485
- default value is POPUP-FACE.
486
-
487
- If SCROLL-BAR is non-nil, the popup will have a scroll bar at the
488
- right.
489
-
490
- If MARGIN-LEFT is non-nil, the popup will have a margin at the
491
- left.
492
-
493
- If MARGIN-RIGHT is non-nil, the popup will have a margin at the
494
- right.
495
-
496
- SYMBOL is a single character which indicates a kind of the item.
497
-
498
- PARENT is a parent popup instance. If PARENT is omitted, the
499
- popup will be a root instance.
500
-
501
- PARENT-OFFSET is a row offset from the parent popup.
502
-
503
- KEYMAP is a keymap that will be put on the popup contents."
504
- (or margin-left (setq margin-left 0))
505
- (or margin-right (setq margin-right 0))
506
- (unless point
507
- (setq point
508
- (if parent (popup-child-point parent parent-offset) (point))))
509
- (when max-width
510
- (setq width (min width (popup-calculate-max-width max-width))))
511
- (save-excursion
512
- (goto-char point)
513
- (let* ((col-row (posn-col-row (posn-at-point)))
514
- (row (cdr col-row))
515
- (column (car col-row))
516
- (overlays (make-vector height nil))
517
- (popup-width (+ width
518
- (if scroll-bar 1 0)
519
- margin-left
520
- margin-right
521
- (if symbol 2 0)))
522
- margin-left-cancel
523
- (window (selected-window))
524
- (window-start (window-start))
525
- (window-hscroll (window-hscroll))
526
- (window-width (window-width))
527
- (right (+ column popup-width))
528
- (overflow (and (> right window-width)
529
- (>= right popup-width)))
530
- (foldable (and (null parent)
531
- (>= column popup-width)))
532
- (direction (or
533
- ;; Currently the direction of cascade popup won't be changed
534
- (and parent (popup-direction parent))
535
-
536
- ;; Calculate direction
537
- (popup-calculate-direction height row)))
538
- (depth (if parent (1+ (popup-depth parent)) 0))
539
- (newlines (max 0 (+ (- height (count-lines point (point-max))) (if around 1 0))))
540
- invis-overlays
541
- current-column)
542
- ;; Case: no newlines at the end of the buffer
543
- (when (> newlines 0)
544
- (popup-save-buffer-state
545
- (goto-char (point-max))
546
- (insert (make-string newlines ?\n))))
547
-
548
- ;; Case: the popup overflows
549
- (if overflow
550
- (if foldable
551
- (progn
552
- (cl-decf column (- popup-width margin-left margin-right))
553
- (unless around (move-to-column column)))
554
- (when (not truncate-lines)
555
- ;; Truncate.
556
- (let ((d (1+ (- popup-width (- window-width column)))))
557
- (cl-decf popup-width d)
558
- (cl-decf width d)))
559
- (cl-decf column margin-left))
560
- (cl-decf column margin-left))
561
-
562
- ;; Case: no space at the left
563
- (when (and (null parent)
564
- (< column 0))
565
- ;; Cancel margin left
566
- (setq column 0)
567
- (cl-decf popup-width margin-left)
568
- (setq margin-left-cancel t))
569
-
570
- (dotimes (i height)
571
- (let (overlay begin w (dangle t) (prefix "") (postfix ""))
572
- (when around
573
- (popup-vertical-motion column direction))
574
- (cl-loop for ov in (overlays-in (save-excursion
575
- (beginning-of-visual-line)
576
- (point))
577
- (save-excursion
578
- (end-of-visual-line)
579
- (point)))
580
- when (and (not (overlay-get ov 'popup))
581
- (not (overlay-get ov 'popup-item))
582
- (or (overlay-get ov 'invisible)
583
- (overlay-get ov 'display)))
584
- do (progn
585
- (push (list ov (overlay-get ov 'display)) invis-overlays)
586
- (overlay-put ov 'display "")))
587
- (setq around t)
588
- (setq current-column (car (posn-col-row (posn-at-point))))
589
-
590
- (when (< current-column column)
591
- ;; Extend short buffer lines by popup prefix (line of spaces)
592
- (setq prefix (make-string
593
- (+ (if (= current-column 0)
594
- (- window-hscroll current-column)
595
- 0)
596
- (- column current-column))
597
- ? )))
598
-
599
- (setq begin (point))
600
- (setq w (+ popup-width (length prefix)))
601
- (while (and (not (eolp)) (> w 0))
602
- (setq dangle nil)
603
- (cl-decf w (char-width (char-after)))
604
- (forward-char))
605
- (if (< w 0)
606
- (setq postfix (make-string (- w) ? )))
607
-
608
- (setq overlay (make-overlay begin (point)))
609
- (overlay-put overlay 'popup t)
610
- (overlay-put overlay 'window window)
611
- (overlay-put overlay 'dangle dangle)
612
- (overlay-put overlay 'prefix prefix)
613
- (overlay-put overlay 'postfix postfix)
614
- (overlay-put overlay 'width width)
615
- (aset overlays
616
- (if (> direction 0) i (- height i 1))
617
- overlay)))
618
- (cl-loop for p from (- 10000 (* depth 1000))
619
- for overlay in (nreverse (append overlays nil))
620
- do (overlay-put overlay 'priority p))
621
- (let ((it (make-popup :point point
622
- :row row
623
- :column column
624
- :width width
625
- :height height
626
- :min-height min-height
627
- :direction direction
628
- :parent parent
629
- :depth depth
630
- :face face
631
- :mouse-face mouse-face
632
- :selection-face selection-face
633
- :summary-face summary-face
634
- :margin-left margin-left
635
- :margin-right margin-right
636
- :margin-left-cancel margin-left-cancel
637
- :scroll-bar scroll-bar
638
- :symbol symbol
639
- :cursor 0
640
- :offset 0
641
- :scroll-top 0
642
- :current-height 0
643
- :list nil
644
- :newlines newlines
645
- :overlays overlays
646
- :invis-overlays invis-overlays
647
- :keymap keymap)))
648
- (push it popup-instances)
649
- it))))
650
-
651
- (defun popup-delete (popup)
652
- "Delete POPUP instance."
653
- (when (popup-live-p popup)
654
- (popup-hide popup)
655
- (mapc 'delete-overlay (popup-overlays popup))
656
- (setf (popup-overlays popup) nil)
657
- (setq popup-instances (delq popup popup-instances))
658
- ;; Restore newlines state
659
- (let ((newlines (popup-newlines popup)))
660
- (when (> newlines 0)
661
- (popup-save-buffer-state
662
- (goto-char (point-max))
663
- (dotimes (i newlines)
664
- (if (and (char-before)
665
- (= (char-before) ?\n))
666
- (delete-char -1)))))))
667
- nil)
668
-
669
- (defun popup-draw (popup)
670
- "Draw POPUP."
671
- (cl-loop for (ov olddisplay) in (popup-invis-overlays popup)
672
- do (overlay-put ov 'display ""))
673
-
674
- (cl-loop with height = (popup-height popup)
675
- with min-height = (popup-min-height popup)
676
- with popup-face = (popup-face popup)
677
- with mouse-face = (popup-mouse-face popup)
678
- with selection-face = (popup-selection-face popup)
679
- with summary-face-0 = (popup-summary-face popup)
680
- with list = (popup-list popup)
681
- with length = (length list)
682
- with thum-size = (max (/ (* height height) (max length 1)) 1)
683
- with page-size = (/ (+ 0.0 (max length 1)) height)
684
- with scroll-bar = (popup-scroll-bar popup)
685
- with margin-left = (make-string (if (popup-margin-left-cancel popup) 0 (popup-margin-left popup)) ? )
686
- with margin-right = (make-string (popup-margin-right popup) ? )
687
- with symbol = (popup-symbol popup)
688
- with cursor = (popup-cursor popup)
689
- with scroll-top = (popup-scroll-top popup)
690
- with offset = (popup-offset popup)
691
- with keymap = (popup-keymap popup)
692
- for o from offset
693
- for i from scroll-top
694
- while (< o height)
695
- for item in (nthcdr scroll-top list)
696
- for page-index = (* thum-size (/ o thum-size))
697
- for face = (if (= i cursor)
698
- (or (popup-item-selection-face item) selection-face)
699
- (or (popup-item-face item) popup-face))
700
- for summary-face = (unless (= i cursor) summary-face-0)
701
- for empty-char = (propertize " " 'face face)
702
- for scroll-bar-char = (if scroll-bar
703
- (cond
704
- ((and (not (eq scroll-bar :always))
705
- (<= page-size 1))
706
- empty-char)
707
- ((and (> page-size 1)
708
- (>= cursor (* page-index page-size))
709
- (< cursor (* (+ page-index thum-size) page-size)))
710
- popup-scroll-bar-foreground-char)
711
- (t
712
- popup-scroll-bar-background-char))
713
- "")
714
- for sym = (if symbol
715
- (concat " " (or (popup-item-symbol item) " "))
716
- "")
717
- for summary = (or (popup-item-summary item) "")
718
-
719
- do
720
- ;; Show line and set item to the line
721
- (popup-set-line-item popup o
722
- :item item
723
- :face face
724
- :mouse-face mouse-face
725
- :margin-left margin-left
726
- :margin-right margin-right
727
- :scroll-bar-char scroll-bar-char
728
- :symbol sym
729
- :summary summary
730
- :summary-face summary-face
731
- :keymap keymap)
732
-
733
- finally
734
- ;; Remember current height
735
- (setf (popup-current-height popup) (- o offset))
736
-
737
- ;; Hide remaining lines
738
- (let ((scroll-bar-char (if scroll-bar (propertize " " 'face popup-face) ""))
739
- (symbol (if symbol " " "")))
740
- (if (> (popup-direction popup) 0)
741
- (progn
742
- (when min-height
743
- (while (< o min-height)
744
- (popup-set-line-item popup o
745
- :item ""
746
- :face popup-face
747
- :margin-left margin-left
748
- :margin-right margin-right
749
- :scroll-bar-char scroll-bar-char
750
- :symbol symbol
751
- :summary "")
752
- (cl-incf o)))
753
- (while (< o height)
754
- (popup-hide-line popup o)
755
- (cl-incf o)))
756
- (cl-loop with h = (if min-height (- height min-height) offset)
757
- for o from 0 below offset
758
- if (< o h)
759
- do (popup-hide-line popup o)
760
- if (>= o h)
761
- do (popup-set-line-item popup o
762
- :item ""
763
- :face popup-face
764
- :margin-left margin-left
765
- :margin-right margin-right
766
- :scroll-bar-char scroll-bar-char
767
- :symbol symbol
768
- :summary ""))))))
769
-
770
- (defun popup-hide (popup)
771
- "Hide POPUP."
772
- (cl-loop for (ov olddisplay) in (popup-invis-overlays popup)
773
- do (overlay-put ov 'display olddisplay))
774
- (dotimes (i (popup-height popup))
775
- (popup-hide-line popup i)))
776
-
777
- (defun popup-hidden-p (popup)
778
- "Return non-nil if POPUP is hidden."
779
- (let ((hidden t))
780
- (when (popup-live-p popup)
781
- (dotimes (i (popup-height popup))
782
- (unless (popup-line-hidden-p popup i)
783
- (setq hidden nil))))
784
- hidden))
785
-
786
- (defun popup-jump (popup cursor)
787
- "Jump to a position specified by CURSOR of POPUP and draw."
788
- (let ((scroll-top (popup-scroll-top popup)))
789
- ;; Do not change page as much as possible.
790
- (unless (and (<= scroll-top cursor)
791
- (< cursor (+ scroll-top (popup-height popup))))
792
- (setf (popup-scroll-top popup) cursor))
793
- (setf (popup-cursor popup) cursor)
794
- (popup-draw popup)))
795
-
796
- (defun popup-select (popup i)
797
- "Select the item at I of POPUP and draw."
798
- (setq i (+ i (popup-offset popup)))
799
- (when (and (<= 0 i) (< i (popup-height popup)))
800
- (setf (popup-cursor popup) i)
801
- (popup-draw popup)
802
- t))
803
-
804
- (defun popup-next (popup)
805
- "Select the next item of POPUP and draw."
806
- (let ((height (popup-height popup))
807
- (cursor (1+ (popup-cursor popup)))
808
- (scroll-top (popup-scroll-top popup))
809
- (length (length (popup-list popup))))
810
- (cond
811
- ((>= cursor length)
812
- ;; Back to first page
813
- (setq cursor 0
814
- scroll-top 0))
815
- ((= cursor (+ scroll-top height))
816
- ;; Go to next page
817
- (setq scroll-top (min (1+ scroll-top) (max (- length height) 0)))))
818
- (setf (popup-cursor popup) cursor
819
- (popup-scroll-top popup) scroll-top)
820
- (popup-draw popup)))
821
-
822
- (defun popup-previous (popup)
823
- "Select the previous item of POPUP and draw."
824
- (let ((height (popup-height popup))
825
- (cursor (1- (popup-cursor popup)))
826
- (scroll-top (popup-scroll-top popup))
827
- (length (length (popup-list popup))))
828
- (cond
829
- ((< cursor 0)
830
- ;; Go to last page
831
- (setq cursor (1- length)
832
- scroll-top (max (- length height) 0)))
833
- ((= cursor (1- scroll-top))
834
- ;; Go to previous page
835
- (cl-decf scroll-top)))
836
- (setf (popup-cursor popup) cursor
837
- (popup-scroll-top popup) scroll-top)
838
- (popup-draw popup)))
839
-
840
- (defun popup-page-next (popup)
841
- "Select next item of POPUP per `popup-height' range.
842
- Pages down through POPUP."
843
- (dotimes (counter (1- (popup-height popup)))
844
- (popup-next popup)))
845
-
846
- (defun popup-page-previous (popup)
847
- "Select previous item of POPUP per `popup-height' range.
848
- Pages up through POPUP."
849
- (dotimes (counter (1- (popup-height popup)))
850
- (popup-previous popup)))
851
-
852
- (defun popup-scroll-down (popup &optional n)
853
- "Scroll down N of POPUP and draw."
854
- (let ((scroll-top (min (+ (popup-scroll-top popup) (or n 1))
855
- (- (length (popup-list popup)) (popup-height popup)))))
856
- (setf (popup-cursor popup) scroll-top
857
- (popup-scroll-top popup) scroll-top)
858
- (popup-draw popup)))
859
-
860
- (defun popup-scroll-up (popup &optional n)
861
- "Scroll up N of POPUP and draw."
862
- (let ((scroll-top (max (- (popup-scroll-top popup) (or n 1))
863
- 0)))
864
- (setf (popup-cursor popup) scroll-top
865
- (popup-scroll-top popup) scroll-top)
866
- (popup-draw popup)))
867
-
868
-
869
-
870
- ;;; Popup Incremental Search
871
-
872
- (defface popup-isearch-match
873
- '((t (:background "sky blue")))
874
- "Popup isearch match face."
875
- :group 'popup)
876
-
877
- (defvar popup-isearch-cursor-color "blue")
878
-
879
- (defvar popup-isearch-keymap
880
- (let ((map (make-sparse-keymap)))
881
- ;(define-key map "\r" 'popup-isearch-done)
882
- (define-key map "\C-g" 'popup-isearch-cancel)
883
- (define-key map "\C-b" 'popup-isearch-close)
884
- (define-key map [left] 'popup-isearch-close)
885
- (define-key map "\C-h" 'popup-isearch-delete)
886
- (define-key map (kbd "DEL") 'popup-isearch-delete)
887
- map))
888
-
889
- (defvar popup-menu-show-quick-help-function 'popup-menu-show-quick-help
890
- "Function used for showing quick help by `popup-menu*'.")
891
-
892
- (defsubst popup-isearch-char-p (char)
893
- (and (integerp char)
894
- (<= 32 char)
895
- (<= char 126)))
896
-
897
- (defun popup-isearch-filter-list (pattern list)
898
- (cl-loop with regexp = (regexp-quote pattern)
899
- for item in list
900
- do
901
- (unless (stringp item)
902
- (setq item (popup-item-propertize (popup-x-to-string item)
903
- 'value item)))
904
- if (string-match regexp item)
905
- collect
906
- (let ((beg (match-beginning 0))
907
- (end (match-end 0)))
908
- (alter-text-property 0 (length item) 'face
909
- (lambda (prop)
910
- (unless (eq prop 'popup-isearch-match)
911
- prop))
912
- item)
913
- (put-text-property beg end
914
- 'face 'popup-isearch-match
915
- item)
916
- item)))
917
-
918
- (defun popup-isearch-prompt (popup pattern)
919
- (format "Pattern: %s" (if (= (length (popup-list popup)) 0)
920
- (propertize pattern 'face 'isearch-fail)
921
- pattern)))
922
-
923
- (defun popup-isearch-update (popup pattern &optional callback)
924
- (setf (popup-cursor popup) 0
925
- (popup-scroll-top popup) 0
926
- (popup-pattern popup) pattern)
927
- (let ((list (popup-isearch-filter-list pattern (popup-original-list popup))))
928
- (popup-set-filtered-list popup list)
929
- (if callback
930
- (funcall callback list)))
931
- (popup-draw popup))
932
-
933
- (cl-defun popup-isearch (popup
934
- &key
935
- (cursor-color popup-isearch-cursor-color)
936
- (keymap popup-isearch-keymap)
937
- callback
938
- help-delay)
939
- "Start isearch on POPUP. This function is synchronized, meaning
940
- event loop waits for quiting of isearch.
941
-
942
- CURSOR-COLOR is a cursor color during isearch. The default value
943
- is `popup-isearch-cursor-color'.
944
-
945
- KEYMAP is a keymap which is used when processing events during
946
- event loop. The default value is `popup-isearch-keymap'.
947
-
948
- CALLBACK is a function taking one argument. `popup-isearch' calls
949
- CALLBACK, if specified, after isearch finished or isearch
950
- canceled. The arguments is whole filtered list of items.
951
-
952
- HELP-DELAY is a delay of displaying helps."
953
- (let ((list (popup-original-list popup))
954
- (pattern (or (popup-pattern popup) ""))
955
- (old-cursor-color (frame-parameter (selected-frame) 'cursor-color))
956
- prompt key binding)
957
- (unwind-protect
958
- (cl-block nil
959
- (if cursor-color
960
- (set-cursor-color cursor-color))
961
- (while t
962
- (setq prompt (popup-isearch-prompt popup pattern))
963
- (setq key (popup-menu-read-key-sequence keymap prompt help-delay))
964
- (if (null key)
965
- (unless (funcall popup-menu-show-quick-help-function popup nil :prompt prompt)
966
- (clear-this-command-keys)
967
- (push (read-event prompt) unread-command-events))
968
- (setq binding (lookup-key keymap key))
969
- (cond
970
- ((and (stringp key)
971
- (popup-isearch-char-p (aref key 0)))
972
- (setq pattern (concat pattern key)))
973
- ((eq binding 'popup-isearch-done)
974
- (cl-return nil))
975
- ((eq binding 'popup-isearch-cancel)
976
- (popup-isearch-update popup "" callback)
977
- (cl-return t))
978
- ((eq binding 'popup-isearch-close)
979
- (popup-isearch-update popup "" callback)
980
- (setq unread-command-events
981
- (append (listify-key-sequence key) unread-command-events))
982
- (cl-return nil))
983
- ((eq binding 'popup-isearch-delete)
984
- (if (> (length pattern) 0)
985
- (setq pattern (substring pattern 0 (1- (length pattern))))))
986
- (t
987
- (setq unread-command-events
988
- (append (listify-key-sequence key) unread-command-events))
989
- (cl-return nil)))
990
- (popup-isearch-update popup pattern callback))))
991
- (if old-cursor-color
992
- (set-cursor-color old-cursor-color)))))
993
-
994
-
995
-
996
- ;;; Popup Tip
997
-
998
- (defface popup-tip-face
999
- '((t (:background "khaki1" :foreground "black")))
1000
- "Face for popup tip."
1001
- :group 'popup)
1002
-
1003
- (defvar popup-tip-max-width 80)
1004
-
1005
- (cl-defun popup-tip (string
1006
- &key
1007
- point
1008
- (around t)
1009
- width
1010
- (height 15)
1011
- min-height
1012
- max-width
1013
- truncate
1014
- margin
1015
- margin-left
1016
- margin-right
1017
- scroll-bar
1018
- parent
1019
- parent-offset
1020
- nowait
1021
- nostrip
1022
- prompt
1023
- &aux tip lines)
1024
- "Show a tooltip of STRING at POINT. This function is
1025
- synchronized unless NOWAIT specified. Almost arguments are same
1026
- as `popup-create' except for TRUNCATE, NOWAIT, and PROMPT.
1027
-
1028
- If TRUNCATE is non-nil, the tooltip can be truncated.
1029
-
1030
- If NOWAIT is non-nil, this function immediately returns the
1031
- tooltip instance without entering event loop.
1032
-
1033
- If `NOSTRIP` is non-nil, `STRING` properties are not stripped.
1034
-
1035
- PROMPT is a prompt string when reading events during event loop."
1036
- (if (bufferp string)
1037
- (setq string (with-current-buffer string (buffer-string))))
1038
-
1039
- (unless nostrip
1040
- ;; TODO strip text (mainly face) properties
1041
- (setq string (substring-no-properties string)))
1042
-
1043
- (and (eq margin t) (setq margin 1))
1044
- (or margin-left (setq margin-left margin))
1045
- (or margin-right (setq margin-right margin))
1046
-
1047
- (let ((it (popup-fill-string string width popup-tip-max-width)))
1048
- (setq width (car it)
1049
- lines (cdr it)))
1050
-
1051
- (setq tip (popup-create point width height
1052
- :min-height min-height
1053
- :max-width max-width
1054
- :around around
1055
- :margin-left margin-left
1056
- :margin-right margin-right
1057
- :scroll-bar scroll-bar
1058
- :face 'popup-tip-face
1059
- :parent parent
1060
- :parent-offset parent-offset))
1061
-
1062
- (unwind-protect
1063
- (when (> (popup-width tip) 0) ; not to be corrupted
1064
- (when (and (not (eq width (popup-width tip))) ; truncated
1065
- (not truncate))
1066
- ;; Refill once again to lines be fitted to popup width
1067
- (setq width (popup-width tip))
1068
- (setq lines (cdr (popup-fill-string string width width))))
1069
-
1070
- (popup-set-list tip lines)
1071
- (popup-draw tip)
1072
- (if nowait
1073
- tip
1074
- (clear-this-command-keys)
1075
- (push (read-event prompt) unread-command-events)
1076
- t))
1077
- (unless nowait
1078
- (popup-delete tip))))
1079
-
1080
-
1081
-
1082
- ;;; Popup Menu
1083
-
1084
- (defface popup-menu-face
1085
- '((t (:inherit popup-face)))
1086
- "Face for popup menu."
1087
- :group 'popup)
1088
-
1089
- (defface popup-menu-mouse-face
1090
- '((t (:background "blue" :foreground "white")))
1091
- "Face for popup menu."
1092
- :group 'popup)
1093
-
1094
- (defface popup-menu-selection-face
1095
- '((t (:background "steelblue" :foreground "white")))
1096
- "Face for popup menu selection."
1097
- :group 'popup)
1098
-
1099
- (defface popup-menu-summary-face
1100
- '((t (:inherit popup-summary-face)))
1101
- "Face for popup summary."
1102
- :group 'popup)
1103
-
1104
- (defvar popup-menu-show-tip-function 'popup-tip
1105
- "Function used for showing tooltip by `popup-menu-show-quick-help'.")
1106
-
1107
- (defun popup-menu-show-help (menu &optional persist item)
1108
- (popup-item-show-help (or item (popup-selected-item menu)) persist))
1109
-
1110
- (defun popup-menu-documentation (menu &optional item)
1111
- (popup-item-documentation (or item (popup-selected-item menu))))
1112
-
1113
- (defun popup-menu-show-quick-help (menu &optional item &rest args)
1114
- (let* ((point (plist-get args :point))
1115
- (height (or (plist-get args :height) (popup-height menu)))
1116
- (min-height (min height (popup-current-height menu)))
1117
- (around nil)
1118
- (parent-offset (popup-offset menu))
1119
- (doc (popup-menu-documentation menu item)))
1120
- (when (stringp doc)
1121
- (if (popup-hidden-p menu)
1122
- (setq around t
1123
- menu nil
1124
- parent-offset nil)
1125
- (setq point nil))
1126
- (let ((popup-use-optimized-column-computation nil)) ; To avoid wrong positioning
1127
- (apply popup-menu-show-tip-function
1128
- doc
1129
- :point point
1130
- :height height
1131
- :min-height min-height
1132
- :around around
1133
- :parent menu
1134
- :parent-offset parent-offset
1135
- args)))))
1136
-
1137
- (defun popup-menu-item-of-mouse-event (event)
1138
- (when (and (consp event)
1139
- (memq (cl-first event) '(mouse-1 mouse-2 mouse-3 mouse-4 mouse-5)))
1140
- (let* ((position (cl-second event))
1141
- (object (elt position 4)))
1142
- (when (consp object)
1143
- (get-text-property (cdr object) 'popup-item (car object))))))
1144
-
1145
- (defun popup-menu-read-key-sequence (keymap &optional prompt timeout)
1146
- (catch 'timeout
1147
- (let ((timer (and timeout
1148
- (run-with-timer timeout nil
1149
- (lambda ()
1150
- (if (zerop (length (this-command-keys)))
1151
- (throw 'timeout nil))))))
1152
- (old-global-map (current-global-map))
1153
- (temp-global-map (make-sparse-keymap))
1154
- (overriding-terminal-local-map (make-sparse-keymap)))
1155
- (substitute-key-definition 'keyboard-quit 'keyboard-quit
1156
- temp-global-map old-global-map)
1157
- (define-key temp-global-map [menu-bar] (lookup-key old-global-map [menu-bar]))
1158
- (define-key temp-global-map [tool-bar] (lookup-key old-global-map [tool-bar]))
1159
- (set-keymap-parent overriding-terminal-local-map keymap)
1160
- (if (current-local-map)
1161
- (define-key overriding-terminal-local-map [menu-bar]
1162
- (lookup-key (current-local-map) [menu-bar])))
1163
- (unwind-protect
1164
- (progn
1165
- (use-global-map temp-global-map)
1166
- (clear-this-command-keys)
1167
- (with-temp-message prompt
1168
- (read-key-sequence nil)))
1169
- (use-global-map old-global-map)
1170
- (if timer (cancel-timer timer))))))
1171
-
1172
- (defun popup-menu-fallback (event default))
1173
-
1174
- (cl-defun popup-menu-event-loop (menu
1175
- keymap
1176
- fallback
1177
- &key
1178
- prompt
1179
- help-delay
1180
- isearch
1181
- isearch-cursor-color
1182
- isearch-keymap
1183
- isearch-callback
1184
- &aux key binding)
1185
- (cl-block nil
1186
- (while (popup-live-p menu)
1187
- (and isearch
1188
- (popup-isearch menu
1189
- :cursor-color isearch-cursor-color
1190
- :keymap isearch-keymap
1191
- :callback isearch-callback
1192
- :help-delay help-delay)
1193
- (keyboard-quit))
1194
- (setq key (popup-menu-read-key-sequence keymap prompt help-delay))
1195
- (setq binding (and key (lookup-key keymap key)))
1196
- (cond
1197
- ((or (null key) (zerop (length key)))
1198
- (unless (funcall popup-menu-show-quick-help-function menu nil :prompt prompt)
1199
- (clear-this-command-keys)
1200
- (push (read-event prompt) unread-command-events)))
1201
- ((eq (lookup-key (current-global-map) key) 'keyboard-quit)
1202
- (keyboard-quit)
1203
- (cl-return))
1204
- ((eq binding 'popup-close)
1205
- (if (popup-parent menu)
1206
- (cl-return)))
1207
- ((memq binding '(popup-select popup-open))
1208
- (let* ((item (or (popup-menu-item-of-mouse-event (elt key 0))
1209
- (popup-selected-item menu)))
1210
- (index (cl-position item (popup-list menu)))
1211
- (sublist (popup-item-sublist item)))
1212
- (unless index (cl-return))
1213
- (if sublist
1214
- (popup-aif (let (popup-use-optimized-column-computation)
1215
- (popup-cascade-menu sublist
1216
- :around nil
1217
- :margin-left (popup-margin-left menu)
1218
- :margin-right (popup-margin-right menu)
1219
- :scroll-bar (popup-scroll-bar menu)
1220
- :parent menu
1221
- :parent-offset index
1222
- :help-delay help-delay
1223
- :isearch isearch
1224
- :isearch-cursor-color isearch-cursor-color
1225
- :isearch-keymap isearch-keymap
1226
- :isearch-callback isearch-callback))
1227
- (and it (cl-return it)))
1228
- (if (eq binding 'popup-select)
1229
- (cl-return (popup-item-value-or-self item))))))
1230
- ((eq binding 'popup-next)
1231
- (popup-next menu))
1232
- ((eq binding 'popup-previous)
1233
- (popup-previous menu))
1234
- ((eq binding 'popup-page-next)
1235
- (popup-page-next menu))
1236
- ((eq binding 'popup-page-previous)
1237
- (popup-page-previous menu))
1238
- ((eq binding 'popup-help)
1239
- (popup-menu-show-help menu))
1240
- ((eq binding 'popup-isearch)
1241
- (popup-isearch menu
1242
- :cursor-color isearch-cursor-color
1243
- :keymap isearch-keymap
1244
- :callback isearch-callback
1245
- :help-delay help-delay))
1246
- ((commandp binding)
1247
- (call-interactively binding))
1248
- (t
1249
- (funcall fallback key (key-binding key)))))))
1250
-
1251
- (defun popup-preferred-width (list)
1252
- "Return the preferred width to show LIST beautifully."
1253
- (cl-loop with tab-width = 4
1254
- for item in list
1255
- for summary = (popup-item-summary item)
1256
- maximize (string-width (popup-x-to-string item)) into width
1257
- if (stringp summary)
1258
- maximize (+ (string-width summary) 2) into summary-width
1259
- finally return
1260
- (let ((total (+ (or width 0) (or summary-width 0))))
1261
- (* (ceiling (/ total 10.0)) 10))))
1262
-
1263
- (defvar popup-menu-keymap
1264
- (let ((map (make-sparse-keymap)))
1265
- (define-key map "\r" 'popup-select)
1266
- (define-key map "\C-f" 'popup-open)
1267
- (define-key map [right] 'popup-open)
1268
- (define-key map "\C-b" 'popup-close)
1269
- (define-key map [left] 'popup-close)
1270
-
1271
- (define-key map "\C-n" 'popup-next)
1272
- (define-key map [down] 'popup-next)
1273
- (define-key map "\C-p" 'popup-previous)
1274
- (define-key map [up] 'popup-previous)
1275
-
1276
- (define-key map [next] 'popup-page-next)
1277
- (define-key map [prior] 'popup-page-previous)
1278
-
1279
- (define-key map [f1] 'popup-help)
1280
- (define-key map (kbd "\C-?") 'popup-help)
1281
-
1282
- (define-key map "\C-s" 'popup-isearch)
1283
-
1284
- (define-key map [mouse-1] 'popup-select)
1285
- (define-key map [mouse-4] 'popup-previous)
1286
- (define-key map [mouse-5] 'popup-next)
1287
- map))
1288
-
1289
- (cl-defun popup-menu* (list
1290
- &key
1291
- point
1292
- (around t)
1293
- (width (popup-preferred-width list))
1294
- (height 15)
1295
- max-width
1296
- margin
1297
- margin-left
1298
- margin-right
1299
- scroll-bar
1300
- symbol
1301
- parent
1302
- parent-offset
1303
- cursor
1304
- (keymap popup-menu-keymap)
1305
- (fallback 'popup-menu-fallback)
1306
- help-delay
1307
- nowait
1308
- prompt
1309
- isearch
1310
- (isearch-cursor-color popup-isearch-cursor-color)
1311
- (isearch-keymap popup-isearch-keymap)
1312
- isearch-callback
1313
- initial-index
1314
- &aux menu event)
1315
- "Show a popup menu of LIST at POINT. This function returns a
1316
- value of the selected item. Almost arguments are same as
1317
- `popup-create' except for KEYMAP, FALLBACK, HELP-DELAY, PROMPT,
1318
- ISEARCH, ISEARCH-CURSOR-COLOR, ISEARCH-KEYMAP, and
1319
- ISEARCH-CALLBACK.
1320
-
1321
- If KEYMAP is a keymap which is used when processing events during
1322
- event loop.
1323
-
1324
- If FALLBACK is a function taking two arguments; a key and a
1325
- command. FALLBACK is called when no special operation is found on
1326
- the key. The default value is `popup-menu-fallback', which does
1327
- nothing.
1328
-
1329
- HELP-DELAY is a delay of displaying helps.
1330
-
1331
- If NOWAIT is non-nil, this function immediately returns the menu
1332
- instance without entering event loop.
1333
-
1334
- PROMPT is a prompt string when reading events during event loop.
1335
-
1336
- If ISEARCH is non-nil, do isearch as soon as displaying the popup
1337
- menu.
1338
-
1339
- ISEARCH-CURSOR-COLOR is a cursor color during isearch. The
1340
- default value is `popup-isearch-cursor-color'.
1341
-
1342
- ISEARCH-KEYMAP is a keymap which is used when processing events
1343
- during event loop. The default value is `popup-isearch-keymap'.
1344
-
1345
- ISEARCH-CALLBACK is a function taking one argument. `popup-menu'
1346
- calls ISEARCH-CALLBACK, if specified, after isearch finished or
1347
- isearch canceled. The arguments is whole filtered list of items.
1348
-
1349
- If `INITIAL-INDEX' is non-nil, this is an initial index value for
1350
- `popup-select'. Only positive integer is valid."
1351
- (and (eq margin t) (setq margin 1))
1352
- (or margin-left (setq margin-left margin))
1353
- (or margin-right (setq margin-right margin))
1354
- (if (and scroll-bar
1355
- (integerp margin-right)
1356
- (> margin-right 0))
1357
- ;; Make scroll-bar space as margin-right
1358
- (cl-decf margin-right))
1359
- (setq menu (popup-create point width height
1360
- :max-width max-width
1361
- :around around
1362
- :face 'popup-menu-face
1363
- :mouse-face 'popup-menu-mouse-face
1364
- :selection-face 'popup-menu-selection-face
1365
- :summary-face 'popup-menu-summary-face
1366
- :margin-left margin-left
1367
- :margin-right margin-right
1368
- :scroll-bar scroll-bar
1369
- :symbol symbol
1370
- :parent parent
1371
- :parent-offset parent-offset))
1372
- (unwind-protect
1373
- (progn
1374
- (popup-set-list menu list)
1375
- (if cursor
1376
- (popup-jump menu cursor)
1377
- (popup-draw menu))
1378
- (when initial-index
1379
- (dotimes (_i (min (- (length list) 1) initial-index))
1380
- (popup-next menu)))
1381
- (if nowait
1382
- menu
1383
- (popup-menu-event-loop menu keymap fallback
1384
- :prompt prompt
1385
- :help-delay help-delay
1386
- :isearch isearch
1387
- :isearch-cursor-color isearch-cursor-color
1388
- :isearch-keymap isearch-keymap
1389
- :isearch-callback isearch-callback)))
1390
- (unless nowait
1391
- (popup-delete menu))))
1392
-
1393
- (defun popup-cascade-menu (list &rest args)
1394
- "Same as `popup-menu' except that an element of LIST can be
1395
- also a sub-menu if the element is a cons cell formed (ITEM
1396
- . SUBLIST) where ITEM is an usual item and SUBLIST is a list of
1397
- the sub menu."
1398
- (apply 'popup-menu*
1399
- (mapcar (lambda (item)
1400
- (if (consp item)
1401
- (popup-make-item (car item)
1402
- :sublist (cdr item)
1403
- :symbol ">")
1404
- item))
1405
- list)
1406
- :symbol t
1407
- args))
1408
-
1409
- (provide 'popup)
1410
- ;;; popup.el ends here