diff options
| -rw-r--r-- | lisp/ChangeLog | 8 | ||||
| -rw-r--r-- | lisp/descr-text.el | 785 |
2 files changed, 407 insertions, 386 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index b0cc109162b..f44529c9bc0 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,13 @@ | |||
| 1 | 2009-11-24 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2009-11-24 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | Handle the [back] button properly (bug#4979). | ||
| 4 | * descr-text.el (describe-text-properties): Add a `buffer' argument. | ||
| 5 | Use help-setup-xref, help-buffer, and with-help-window. | ||
| 6 | (describe-char): Add `buffer' argument. | ||
| 7 | Pass proper command to help-setup-xref. Don't meddle with | ||
| 8 | help-xref-stack-item directly. | ||
| 9 | (describe-text-category): Use with-help-window and help-buffer. | ||
| 10 | |||
| 3 | * emacs-lisp/shadow.el (list-load-path-shadows): Setup a major mode | 11 | * emacs-lisp/shadow.el (list-load-path-shadows): Setup a major mode |
| 4 | for the displayed buffer (bug#4887). | 12 | for the displayed buffer (bug#4887). |
| 5 | 13 | ||
diff --git a/lisp/descr-text.el b/lisp/descr-text.el index c952ef1d796..d289f7d6d47 100644 --- a/lisp/descr-text.el +++ b/lisp/descr-text.el | |||
| @@ -103,39 +103,41 @@ into help buttons that call `describe-text-category' or | |||
| 103 | (interactive "SCategory: ") | 103 | (interactive "SCategory: ") |
| 104 | (help-setup-xref (list #'describe-text-category category) | 104 | (help-setup-xref (list #'describe-text-category category) |
| 105 | (called-interactively-p 'interactive)) | 105 | (called-interactively-p 'interactive)) |
| 106 | (save-excursion | 106 | (with-help-window (help-buffer) |
| 107 | (with-output-to-temp-buffer "*Help*" | 107 | (with-current-buffer standard-output |
| 108 | (set-buffer standard-output) | ||
| 109 | (insert "Category " (format "%S" category) ":\n\n") | 108 | (insert "Category " (format "%S" category) ":\n\n") |
| 110 | (describe-property-list (symbol-plist category)) | 109 | (describe-property-list (symbol-plist category)) |
| 111 | (goto-char (point-min))))) | 110 | (goto-char (point-min))))) |
| 112 | 111 | ||
| 113 | ;;;###autoload | 112 | ;;;###autoload |
| 114 | (defun describe-text-properties (pos &optional output-buffer) | 113 | (defun describe-text-properties (pos &optional output-buffer buffer) |
| 115 | "Describe widgets, buttons, overlays and text properties at POS. | 114 | "Describe widgets, buttons, overlays, and text properties at POS. |
| 115 | POS is taken to be in BUFFER or in current buffer if nil. | ||
| 116 | Interactively, describe them for the character after point. | 116 | Interactively, describe them for the character after point. |
| 117 | If optional second argument OUTPUT-BUFFER is non-nil, | 117 | If optional second argument OUTPUT-BUFFER is non-nil, |
| 118 | insert the output into that buffer, and don't initialize or clear it | 118 | insert the output into that buffer, and don't initialize or clear it |
| 119 | otherwise." | 119 | otherwise." |
| 120 | (interactive "d") | 120 | (interactive "d") |
| 121 | (let ((src-buf (current-buffer))) | ||
| 122 | (if buffer (set-buffer buffer) (setq buffer (current-buffer))) | ||
| 121 | (if (>= pos (point-max)) | 123 | (if (>= pos (point-max)) |
| 122 | (error "No character follows specified position")) | 124 | (error "No character follows specified position")) |
| 123 | (if output-buffer | 125 | (if output-buffer |
| 124 | (describe-text-properties-1 pos output-buffer) | 126 | (describe-text-properties-1 pos output-buffer) |
| 125 | (if (not (or (text-properties-at pos) (overlays-at pos))) | 127 | (if (not (or (text-properties-at pos) (overlays-at pos))) |
| 126 | (message "This is plain text.") | 128 | (message "This is plain text.") |
| 127 | (let ((buffer (current-buffer)) | 129 | (with-temp-buffer |
| 128 | (target-buffer "*Help*")) | ||
| 129 | (when (eq buffer (get-buffer target-buffer)) | ||
| 130 | (setq target-buffer "*Help*<2>")) | ||
| 131 | (save-excursion | ||
| 132 | (with-output-to-temp-buffer target-buffer | ||
| 133 | (set-buffer standard-output) | ||
| 134 | (setq output-buffer (current-buffer)) | 130 | (setq output-buffer (current-buffer)) |
| 135 | (insert "Text content at position " (format "%d" pos) ":\n\n") | 131 | (insert "Text content at position " (format "%d" pos) ":\n\n") |
| 136 | (with-current-buffer buffer | 132 | (set-buffer buffer) |
| 137 | (describe-text-properties-1 pos output-buffer)) | 133 | (describe-text-properties-1 pos output-buffer) |
| 138 | (goto-char (point-min)))))))) | 134 | (set-buffer src-buf) |
| 135 | (help-setup-xref (list 'describe-text-properties pos nil buffer) | ||
| 136 | (called-interactively-p 'interactive)) | ||
| 137 | (with-help-window (help-buffer) | ||
| 138 | (with-current-buffer standard-output | ||
| 139 | (buffer-swap-text output-buffer) | ||
| 140 | (goto-char (point-min))))))))) | ||
| 139 | 141 | ||
| 140 | (defun describe-text-properties-1 (pos output-buffer) | 142 | (defun describe-text-properties-1 (pos output-buffer) |
| 141 | (let* ((properties (text-properties-at pos)) | 143 | (let* ((properties (text-properties-at pos)) |
| @@ -373,383 +375,394 @@ This function is semi-obsolete. Use `get-char-code-property'." | |||
| 373 | mnemonics ", "))))) | 375 | mnemonics ", "))))) |
| 374 | 376 | ||
| 375 | ;;;###autoload | 377 | ;;;###autoload |
| 376 | (defun describe-char (pos) | 378 | (defun describe-char (pos &optional buffer) |
| 377 | "Describe the character after POS (interactively, the character after point). | 379 | "Describe the character after POS (interactively, the character after point). |
| 380 | Is POS is taken to be in buffer BUFFER or current buffer if nil. | ||
| 378 | The information includes character code, charset and code points in it, | 381 | The information includes character code, charset and code points in it, |
| 379 | syntax, category, how the character is encoded in a file, | 382 | syntax, category, how the character is encoded in a file, |
| 380 | character composition information (if relevant), | 383 | character composition information (if relevant), |
| 381 | as well as widgets, buttons, overlays, and text properties." | 384 | as well as widgets, buttons, overlays, and text properties." |
| 382 | (interactive "d") | 385 | (interactive "d") |
| 383 | (if (>= pos (point-max)) | 386 | (unless (buffer-live-p buffer) (setq buffer (current-buffer))) |
| 384 | (error "No character follows specified position")) | 387 | (let ((src-buf (current-buffer))) |
| 385 | (let* ((char (char-after pos)) | 388 | (set-buffer buffer) |
| 386 | (eight-bit-p (and (not enable-multibyte-characters) (>= char 128))) | 389 | (if (>= pos (point-max)) |
| 387 | (charset (if eight-bit-p 'eight-bit | 390 | (error "No character follows specified position")) |
| 388 | (or (get-text-property pos 'charset) (char-charset char)))) | 391 | (let* ((char (char-after pos)) |
| 389 | (composition (find-composition pos nil nil t)) | 392 | (eight-bit-p (and (not enable-multibyte-characters) (>= char 128))) |
| 390 | (component-chars nil) | 393 | (charset (if eight-bit-p 'eight-bit |
| 391 | (display-table (or (window-display-table) | 394 | (or (get-text-property pos 'charset) |
| 392 | buffer-display-table | 395 | (char-charset char)))) |
| 393 | standard-display-table)) | 396 | (composition (find-composition pos nil nil t)) |
| 394 | (disp-vector (and display-table (aref display-table char))) | 397 | (component-chars nil) |
| 395 | (multibyte-p enable-multibyte-characters) | 398 | (display-table (or (window-display-table) |
| 396 | (overlays (mapcar #'(lambda (o) (overlay-properties o)) | 399 | buffer-display-table |
| 397 | (overlays-at pos))) | 400 | standard-display-table)) |
| 398 | (char-description (if (not multibyte-p) | 401 | (disp-vector (and display-table (aref display-table char))) |
| 399 | (single-key-description char) | 402 | (multibyte-p enable-multibyte-characters) |
| 400 | (if (< char 128) | 403 | (overlays (mapcar #'(lambda (o) (overlay-properties o)) |
| 401 | (single-key-description char) | 404 | (overlays-at pos))) |
| 402 | (string-to-multibyte | 405 | (char-description (if (not multibyte-p) |
| 403 | (char-to-string char))))) | 406 | (single-key-description char) |
| 404 | (text-props-desc | 407 | (if (< char 128) |
| 405 | (let ((tmp-buf (generate-new-buffer " *text-props*"))) | 408 | (single-key-description char) |
| 406 | (unwind-protect | 409 | (string-to-multibyte |
| 407 | (progn | 410 | (char-to-string char))))) |
| 408 | (describe-text-properties pos tmp-buf) | 411 | (text-props-desc |
| 409 | (with-current-buffer tmp-buf (buffer-string))) | 412 | (let ((tmp-buf (generate-new-buffer " *text-props*"))) |
| 410 | (kill-buffer tmp-buf)))) | 413 | (unwind-protect |
| 411 | item-list max-width code) | 414 | (progn |
| 412 | 415 | (describe-text-properties pos tmp-buf) | |
| 413 | (if multibyte-p | 416 | (with-current-buffer tmp-buf (buffer-string))) |
| 414 | (or (setq code (encode-char char charset)) | 417 | (kill-buffer tmp-buf)))) |
| 415 | (setq charset (char-charset char) | 418 | item-list max-width code) |
| 416 | code (encode-char char charset))) | 419 | |
| 417 | (setq code char)) | 420 | (if multibyte-p |
| 418 | (when composition | 421 | (or (setq code (encode-char char charset)) |
| 419 | ;; When the composition is trivial (i.e. composed only with the | 422 | (setq charset (char-charset char) |
| 420 | ;; current character itself without any alternate characters), | 423 | code (encode-char char charset))) |
| 421 | ;; we don't show the composition information. Otherwise, store | 424 | (setq code char)) |
| 422 | ;; two descriptive strings in the first two elments of | 425 | (when composition |
| 423 | ;; COMPOSITION. | 426 | ;; When the composition is trivial (i.e. composed only with the |
| 424 | (or (catch 'tag | 427 | ;; current character itself without any alternate characters), |
| 425 | (let ((from (car composition)) | 428 | ;; we don't show the composition information. Otherwise, store |
| 426 | (to (nth 1 composition)) | 429 | ;; two descriptive strings in the first two elments of |
| 427 | (next (1+ pos)) | 430 | ;; COMPOSITION. |
| 428 | (components (nth 2 composition)) | 431 | (or (catch 'tag |
| 429 | ch) | 432 | (let ((from (car composition)) |
| 430 | (if (and (vectorp components) (vectorp (aref components 0))) | 433 | (to (nth 1 composition)) |
| 431 | (let ((idx (- pos from)) | 434 | (components (nth 2 composition)) |
| 432 | (nglyphs (lgstring-glyph-len components)) | 435 | ch) |
| 433 | (i 0) j glyph glyph-from) | 436 | (if (and (vectorp components) (vectorp (aref components 0))) |
| 434 | ;; COMPONENTS is a gstring. Find a grapheme | 437 | (let ((idx (- pos from)) |
| 435 | ;; cluster containing the current character. | 438 | (nglyphs (lgstring-glyph-len components)) |
| 436 | (while (and (< i nglyphs) | 439 | (i 0) j glyph glyph-from) |
| 437 | (setq glyph (lgstring-glyph components i)) | 440 | ;; COMPONENTS is a gstring. Find a grapheme |
| 438 | (< (lglyph-to glyph) idx)) | 441 | ;; cluster containing the current character. |
| 439 | (setq i (1+ i))) | 442 | (while (and (< i nglyphs) |
| 440 | (if (or (not glyph) (= i nglyphs)) | 443 | (setq glyph (lgstring-glyph components i)) |
| 441 | ;; The composition is broken. | 444 | (< (lglyph-to glyph) idx)) |
| 442 | (throw 'tag nil)) | 445 | (setq i (1+ i))) |
| 443 | (setq glyph-from (lglyph-from glyph) | 446 | (if (or (not glyph) (= i nglyphs)) |
| 444 | to (+ from (lglyph-to glyph) 1) | 447 | ;; The composition is broken. |
| 445 | from (+ from glyph-from) | 448 | (throw 'tag nil)) |
| 446 | j i) | 449 | (setq glyph-from (lglyph-from glyph) |
| 447 | (while (and (< j nglyphs) | 450 | to (+ from (lglyph-to glyph) 1) |
| 448 | (setq glyph (lgstring-glyph components j)) | 451 | from (+ from glyph-from) |
| 449 | (= (lglyph-from glyph) glyph-from)) | 452 | j i) |
| 450 | (setq j (1+ j))) | 453 | (while (and (< j nglyphs) |
| 451 | (if (and (= to (1+ from)) | 454 | (setq glyph (lgstring-glyph components j)) |
| 452 | (= i (1- j)) | 455 | (= (lglyph-from glyph) glyph-from)) |
| 453 | (setq glyph (lgstring-glyph components i)) | 456 | (setq j (1+ j))) |
| 454 | (= char (lglyph-char glyph))) | 457 | (if (and (= to (1+ from)) |
| 455 | ;; The composition is trivial. | 458 | (= i (1- j)) |
| 456 | (throw 'tag nil)) | 459 | (setq glyph (lgstring-glyph components i)) |
| 457 | (nconc composition (list i (1- j)))) | 460 | (= char (lglyph-char glyph))) |
| 458 | (dotimes (i (length components)) | 461 | ;; The composition is trivial. |
| 459 | (if (integerp (setq ch (aref components i))) | 462 | (throw 'tag nil)) |
| 460 | (push (cons ch (describe-char-display pos ch)) | 463 | (nconc composition (list i (1- j)))) |
| 461 | component-chars))) | 464 | (dotimes (i (length components)) |
| 462 | (setq component-chars (nreverse component-chars))) | 465 | (if (integerp (setq ch (aref components i))) |
| 463 | (if (< from pos) | 466 | (push (cons ch (describe-char-display pos ch)) |
| 464 | (if (< (1+ pos) to) | 467 | component-chars))) |
| 465 | (setcar composition | 468 | (setq component-chars (nreverse component-chars))) |
| 466 | (concat | 469 | (if (< from pos) |
| 467 | " with the surrounding characters \"" | 470 | (if (< (1+ pos) to) |
| 468 | (mapconcat 'describe-char-padded-string | 471 | (setcar composition |
| 469 | (buffer-substring from pos) "") | 472 | (concat |
| 470 | "\" and \"" | 473 | " with the surrounding characters \"" |
| 471 | (mapconcat 'describe-char-padded-string | 474 | (mapconcat 'describe-char-padded-string |
| 472 | (buffer-substring (1+ pos) to) "") | 475 | (buffer-substring from pos) "") |
| 473 | "\"")) | 476 | "\" and \"" |
| 474 | (setcar composition | 477 | (mapconcat 'describe-char-padded-string |
| 475 | (concat | 478 | (buffer-substring (1+ pos) to) "") |
| 476 | " with the preceding character(s) \"" | 479 | "\"")) |
| 477 | (mapconcat 'describe-char-padded-string | 480 | (setcar composition |
| 478 | (buffer-substring from pos) "") | 481 | (concat |
| 479 | "\""))) | 482 | " with the preceding character(s) \"" |
| 480 | (if (< (1+ pos) to) | 483 | (mapconcat 'describe-char-padded-string |
| 481 | (setcar composition | 484 | (buffer-substring from pos) "") |
| 482 | (concat | 485 | "\""))) |
| 483 | " with the following character(s) \"" | 486 | (if (< (1+ pos) to) |
| 484 | (mapconcat 'describe-char-padded-string | 487 | (setcar composition |
| 485 | (buffer-substring (1+ pos) to) "") | 488 | (concat |
| 486 | "\"")) | 489 | " with the following character(s) \"" |
| 487 | (setcar composition nil))) | 490 | (mapconcat 'describe-char-padded-string |
| 488 | (setcar (cdr composition) | 491 | (buffer-substring (1+ pos) to) "") |
| 489 | (format "composed to form \"%s\" (see below)" | 492 | "\"")) |
| 490 | (buffer-substring from to))))) | 493 | (setcar composition nil))) |
| 491 | (setq composition nil))) | 494 | (setcar (cdr composition) |
| 492 | 495 | (format "composed to form \"%s\" (see below)" | |
| 493 | (setq item-list | 496 | (buffer-substring from to))))) |
| 494 | `(("character" | 497 | (setq composition nil))) |
| 495 | ,(format "%s (%d, #o%o, #x%x)" | 498 | |
| 496 | (apply 'propertize char-description | 499 | (setq item-list |
| 497 | (text-properties-at pos)) | 500 | `(("character" |
| 498 | char char char)) | 501 | ,(format "%s (%d, #o%o, #x%x)" |
| 499 | ("preferred charset" | 502 | (apply 'propertize char-description |
| 500 | ,`(insert-text-button | 503 | (text-properties-at pos)) |
| 501 | ,(symbol-name charset) | 504 | char char char)) |
| 502 | 'type 'help-character-set 'help-args '(,charset)) | 505 | ("preferred charset" |
| 503 | ,(format "(%s)" (charset-description charset))) | 506 | ,`(insert-text-button |
| 504 | ("code point" | 507 | ,(symbol-name charset) |
| 505 | ,(let ((str (if (integerp code) | 508 | 'type 'help-character-set 'help-args '(,charset)) |
| 506 | (format (if (< code 256) "0x%02X" "0x%04X") code) | 509 | ,(format "(%s)" (charset-description charset))) |
| 507 | (format "0x%04X%04X" (car code) (cdr code))))) | 510 | ("code point" |
| 508 | (if (<= (charset-dimension charset) 2) | 511 | ,(let ((str (if (integerp code) |
| 509 | `(insert-text-button | 512 | (format (if (< code 256) "0x%02X" "0x%04X") |
| 510 | ,str | 513 | code) |
| 511 | 'action (lambda (&rest ignore) | 514 | (format "0x%04X%04X" (car code) (cdr code))))) |
| 512 | (list-charset-chars ',charset) | 515 | (if (<= (charset-dimension charset) 2) |
| 513 | (with-selected-window | 516 | `(insert-text-button |
| 514 | (get-buffer-window "*Character List*" 0) | 517 | ,str |
| 515 | (goto-char (point-min)) | 518 | 'action (lambda (&rest ignore) |
| 516 | (forward-line 2) ;Skip the header. | 519 | (list-charset-chars ',charset) |
| 517 | (let ((case-fold-search nil)) | 520 | (with-selected-window |
| 518 | (if (search-forward ,(char-to-string char) | 521 | (get-buffer-window "*Character List*" 0) |
| 519 | nil t) | 522 | (goto-char (point-min)) |
| 520 | (goto-char (match-beginning 0)))))) | 523 | (forward-line 2) ;Skip the header. |
| 521 | 'follow-link t | 524 | (let ((case-fold-search nil)) |
| 522 | 'help-echo | 525 | (if (search-forward |
| 523 | "mouse-2, RET: show this character in its character set") | 526 | ,(char-to-string char) nil t) |
| 524 | str))) | 527 | (goto-char (match-beginning 0)))))) |
| 525 | ("syntax" | 528 | 'follow-link t |
| 526 | ,(let ((syntax (syntax-after pos))) | 529 | 'help-echo |
| 527 | (with-temp-buffer | 530 | "mouse-2, RET: show this character in its character set") |
| 528 | (internal-describe-syntax-value syntax) | 531 | str))) |
| 529 | (buffer-string)))) | 532 | ("syntax" |
| 530 | ("category" | 533 | ,(let ((syntax (syntax-after pos))) |
| 531 | ,@(if (not eight-bit-p) | 534 | (with-temp-buffer |
| 532 | (let ((category-set (char-category-set char))) | 535 | (internal-describe-syntax-value syntax) |
| 533 | (if category-set | 536 | (buffer-string)))) |
| 534 | (describe-char-categories category-set) | 537 | ("category" |
| 535 | '("-- none --"))))) | 538 | ,@(if (not eight-bit-p) |
| 536 | ("to input" | 539 | (let ((category-set (char-category-set char))) |
| 537 | ,@(if (not eight-bit-p) | 540 | (if category-set |
| 538 | (let ((key-list (and (eq input-method-function | 541 | (describe-char-categories category-set) |
| 539 | 'quail-input-method) | 542 | '("-- none --"))))) |
| 540 | (quail-find-key char)))) | 543 | ("to input" |
| 541 | (if (consp key-list) | 544 | ,@(if (not eight-bit-p) |
| 542 | (list "type" | 545 | (let ((key-list (and (eq input-method-function |
| 543 | (mapconcat #'(lambda (x) (concat "\"" x "\"")) | 546 | 'quail-input-method) |
| 544 | key-list " or ") | 547 | (quail-find-key char)))) |
| 545 | "with" | 548 | (if (consp key-list) |
| 546 | `(insert-text-button | 549 | (list "type" |
| 547 | ,current-input-method | 550 | (concat "\"" |
| 548 | 'type 'help-input-method | 551 | (mapconcat 'identity |
| 549 | 'help-args '(,current-input-method))))))) | 552 | key-list "\" or \"") |
| 550 | ("buffer code" | 553 | "\"") |
| 551 | ,(if multibyte-p | 554 | "with" |
| 552 | (encoded-string-description | 555 | `(insert-text-button |
| 553 | (string-as-unibyte (char-to-string char)) nil) | 556 | ,current-input-method |
| 554 | (format "#x%02X" char))) | 557 | 'type 'help-input-method |
| 555 | ("file code" | 558 | 'help-args '(,current-input-method))))))) |
| 556 | ,@(if multibyte-p | 559 | ("buffer code" |
| 557 | (let* ((coding buffer-file-coding-system) | 560 | ,(if multibyte-p |
| 558 | (encoded (encode-coding-char char coding charset))) | 561 | (encoded-string-description |
| 559 | (if encoded | 562 | (string-as-unibyte (char-to-string char)) nil) |
| 560 | (list (encoded-string-description encoded coding) | 563 | (format "#x%02X" char))) |
| 561 | (format "(encoded by coding system %S)" coding)) | 564 | ("file code" |
| 562 | (list "not encodable by coding system" | 565 | ,@(if multibyte-p |
| 563 | (symbol-name coding)))) | 566 | (let* ((coding buffer-file-coding-system) |
| 564 | (list (format "#x%02X" char)))) | 567 | (encoded (encode-coding-char char coding charset))) |
| 565 | ("display" | 568 | (if encoded |
| 566 | ,(cond | 569 | (list (encoded-string-description encoded coding) |
| 567 | (disp-vector | 570 | (format "(encoded by coding system %S)" |
| 568 | (setq disp-vector (copy-sequence disp-vector)) | 571 | coding)) |
| 569 | (dotimes (i (length disp-vector)) | 572 | (list "not encodable by coding system" |
| 570 | (aset disp-vector i | 573 | (symbol-name coding)))) |
| 571 | (cons (aref disp-vector i) | 574 | (list (format "#x%02X" char)))) |
| 572 | (describe-char-display | 575 | ("display" |
| 573 | pos (glyph-char (aref disp-vector i)))))) | 576 | ,(cond |
| 574 | (format "by display table entry [%s] (see below)" | 577 | (disp-vector |
| 575 | (mapconcat | 578 | (setq disp-vector (copy-sequence disp-vector)) |
| 576 | #'(lambda (x) | 579 | (dotimes (i (length disp-vector)) |
| 577 | (format "?%c" (glyph-char (car x)))) | 580 | (aset disp-vector i |
| 578 | disp-vector " "))) | 581 | (cons (aref disp-vector i) |
| 579 | (composition | 582 | (describe-char-display |
| 580 | (cadr composition)) | 583 | pos (glyph-char (aref disp-vector i)))))) |
| 581 | (t | 584 | (format "by display table entry [%s] (see below)" |
| 582 | (let ((display (describe-char-display pos char))) | 585 | (mapconcat |
| 583 | (if (display-graphic-p (selected-frame)) | 586 | #'(lambda (x) |
| 584 | (if display | 587 | (format "?%c" (glyph-char (car x)))) |
| 585 | (concat "by this font (glyph code)\n " display) | 588 | disp-vector " "))) |
| 586 | "no font available") | 589 | (composition |
| 587 | (if display | 590 | (cadr composition)) |
| 588 | (format "terminal code %s" display) | 591 | (t |
| 589 | "not encodable for terminal")))))) | 592 | (let ((display (describe-char-display pos char))) |
| 590 | ,@(let ((face | 593 | (if (display-graphic-p (selected-frame)) |
| 591 | (if (not (or disp-vector composition)) | 594 | (if display |
| 592 | (cond | 595 | (concat "by this font (glyph code)\n " display) |
| 593 | ((and show-trailing-whitespace | 596 | "no font available") |
| 594 | (save-excursion (goto-char pos) | 597 | (if display |
| 595 | (looking-at-p "[ \t]+$"))) | 598 | (format "terminal code %s" display) |
| 596 | 'trailing-whitespace) | 599 | "not encodable for terminal")))))) |
| 597 | ((and nobreak-char-display char (eq char '#xa0)) | 600 | ,@(let ((face |
| 598 | 'nobreak-space) | 601 | (if (not (or disp-vector composition)) |
| 599 | ((and nobreak-char-display char (eq char '#xad)) | 602 | (cond |
| 600 | 'escape-glyph) | 603 | ((and show-trailing-whitespace |
| 601 | ((and (< char 32) (not (memq char '(9 10)))) | 604 | (save-excursion (goto-char pos) |
| 602 | 'escape-glyph))))) | 605 | (looking-at-p "[ \t]+$"))) |
| 603 | (if face (list (list "hardcoded face" | 606 | 'trailing-whitespace) |
| 604 | `(insert-text-button | 607 | ((and nobreak-char-display char (eq char '#xa0)) |
| 605 | ,(symbol-name face) | 608 | 'nobreak-space) |
| 606 | 'type 'help-face 'help-args '(,face)))))) | 609 | ((and nobreak-char-display char (eq char '#xad)) |
| 607 | ,@(if (not eight-bit-p) | 610 | 'escape-glyph) |
| 608 | (let ((unicodedata (describe-char-unicode-data char))) | 611 | ((and (< char 32) (not (memq char '(9 10)))) |
| 609 | (if unicodedata | 612 | 'escape-glyph))))) |
| 610 | (cons (list "Unicode data" " ") unicodedata)))))) | 613 | (if face (list (list "hardcoded face" |
| 611 | (setq max-width (apply #'max (mapcar #'(lambda (x) | 614 | `(insert-text-button |
| 612 | (if (cadr x) (length (car x)) 0)) | 615 | ,(symbol-name face) |
| 613 | item-list))) | 616 | 'type 'help-face |
| 614 | (help-setup-xref nil (called-interactively-p 'interactive)) | 617 | 'help-args '(,face)))))) |
| 615 | (with-help-window (help-buffer) | 618 | ,@(if (not eight-bit-p) |
| 616 | (with-current-buffer standard-output | 619 | (let ((unicodedata (describe-char-unicode-data char))) |
| 617 | (set-buffer-multibyte multibyte-p) | 620 | (if unicodedata |
| 618 | (let ((formatter (format "%%%ds:" max-width))) | 621 | (cons (list "Unicode data" " ") unicodedata)))))) |
| 619 | (dolist (elt item-list) | 622 | (setq max-width (apply 'max (mapcar (lambda (x) |
| 620 | (when (cadr elt) | 623 | (if (cadr x) (length (car x)) 0)) |
| 621 | (insert (format formatter (car elt))) | 624 | item-list))) |
| 622 | (dolist (clm (cdr elt)) | 625 | (set-buffer src-buf) |
| 623 | (if (eq (car-safe clm) 'insert-text-button) | 626 | (help-setup-xref (list 'describe-char pos buffer) |
| 624 | (progn (insert " ") (eval clm)) | 627 | (called-interactively-p 'interactive)) |
| 625 | (when (>= (+ (current-column) | 628 | (with-help-window (help-buffer) |
| 626 | (or (string-match-p "\n" clm) | 629 | (with-current-buffer standard-output |
| 627 | (string-width clm)) | 630 | (set-buffer-multibyte multibyte-p) |
| 628 | 1) | 631 | (let ((formatter (format "%%%ds:" max-width))) |
| 629 | (window-width)) | 632 | (dolist (elt item-list) |
| 630 | (insert "\n") | 633 | (when (cadr elt) |
| 631 | (indent-to (1+ max-width))) | 634 | (insert (format formatter (car elt))) |
| 632 | (insert " " clm))) | 635 | (dolist (clm (cdr elt)) |
| 633 | (insert "\n")))) | 636 | (if (eq (car-safe clm) 'insert-text-button) |
| 634 | 637 | (progn (insert " ") (eval clm)) | |
| 635 | (when overlays | 638 | (when (>= (+ (current-column) |
| 636 | (save-excursion | 639 | (or (string-match-p "\n" clm) |
| 637 | (goto-char (point-min)) | 640 | (string-width clm)) |
| 638 | (re-search-forward "character:[ \t\n]+") | 641 | 1) |
| 639 | (let ((end (+ (point) (length char-description)))) | 642 | (window-width)) |
| 640 | (mapc #'(lambda (props) | 643 | (insert "\n") |
| 641 | (let ((o (make-overlay (point) end))) | 644 | (indent-to (1+ max-width))) |
| 642 | (while props | 645 | (insert " " clm))) |
| 643 | (overlay-put o (car props) (nth 1 props)) | 646 | (insert "\n")))) |
| 644 | (setq props (cddr props))))) | 647 | |
| 645 | overlays)))) | 648 | (when overlays |
| 646 | 649 | (save-excursion | |
| 647 | (when disp-vector | 650 | (goto-char (point-min)) |
| 648 | (insert | 651 | (re-search-forward "character:[ \t\n]+") |
| 649 | "\nThe display table entry is displayed by ") | 652 | (let ((end (+ (point) (length char-description)))) |
| 650 | (if (display-graphic-p (selected-frame)) | 653 | (mapc #'(lambda (props) |
| 651 | (progn | 654 | (let ((o (make-overlay (point) end))) |
| 652 | (insert "these fonts (glyph codes):\n") | 655 | (while props |
| 653 | (dotimes (i (length disp-vector)) | 656 | (overlay-put o (car props) (nth 1 props)) |
| 654 | (insert (glyph-char (car (aref disp-vector i))) ?: | 657 | (setq props (cddr props))))) |
| 655 | (propertize " " 'display '(space :align-to 5)) | 658 | overlays)))) |
| 656 | (or (cdr (aref disp-vector i)) "-- no font --") | 659 | |
| 657 | "\n") | 660 | (when disp-vector |
| 658 | (let ((face (glyph-face (car (aref disp-vector i))))) | 661 | (insert |
| 659 | (when face | 662 | "\nThe display table entry is displayed by ") |
| 660 | (insert (propertize " " 'display '(space :align-to 5)) | 663 | (if (display-graphic-p (selected-frame)) |
| 661 | "face: ") | 664 | (progn |
| 662 | (insert (concat "`" (symbol-name face) "'")) | 665 | (insert "these fonts (glyph codes):\n") |
| 663 | (insert "\n"))))) | 666 | (dotimes (i (length disp-vector)) |
| 664 | (insert "these terminal codes:\n") | 667 | (insert (glyph-char (car (aref disp-vector i))) ?: |
| 665 | (dotimes (i (length disp-vector)) | 668 | (propertize " " 'display '(space :align-to 5)) |
| 666 | (insert (car (aref disp-vector i)) | 669 | (or (cdr (aref disp-vector i)) "-- no font --") |
| 667 | (propertize " " 'display '(space :align-to 5)) | 670 | "\n") |
| 668 | (or (cdr (aref disp-vector i)) "-- not encodable --") | 671 | (let ((face (glyph-face (car (aref disp-vector i))))) |
| 669 | "\n")))) | 672 | (when face |
| 670 | 673 | (insert (propertize " " 'display '(space :align-to 5)) | |
| 671 | (when composition | 674 | "face: ") |
| 672 | (insert "\nComposed") | 675 | (insert (concat "`" (symbol-name face) "'")) |
| 673 | (if (car composition) | 676 | (insert "\n"))))) |
| 674 | (insert (car composition))) | 677 | (insert "these terminal codes:\n") |
| 675 | (if (and (vectorp (nth 2 composition)) | 678 | (dotimes (i (length disp-vector)) |
| 676 | (vectorp (aref (nth 2 composition) 0))) | 679 | (insert (car (aref disp-vector i)) |
| 677 | (let* ((gstring (nth 2 composition)) | 680 | (propertize " " 'display '(space :align-to 5)) |
| 678 | (font (lgstring-font gstring)) | 681 | (or (cdr (aref disp-vector i)) "-- not encodable --") |
| 679 | (from (nth 3 composition)) | 682 | "\n")))) |
| 680 | (to (nth 4 composition)) | 683 | |
| 681 | glyph) | 684 | (when composition |
| 682 | (if (fontp font) | 685 | (insert "\nComposed") |
| 683 | (progn | 686 | (if (car composition) |
| 684 | (insert " using this font:\n " | 687 | (insert (car composition))) |
| 685 | (symbol-name (font-get font :type)) | 688 | (if (and (vectorp (nth 2 composition)) |
| 686 | ?: | 689 | (vectorp (aref (nth 2 composition) 0))) |
| 687 | (aref (query-font font) 0) | 690 | (let* ((gstring (nth 2 composition)) |
| 688 | "\nby these glyphs:\n") | 691 | (font (lgstring-font gstring)) |
| 689 | (while (and (<= from to) | 692 | (from (nth 3 composition)) |
| 690 | (setq glyph (lgstring-glyph gstring from))) | 693 | (to (nth 4 composition)) |
| 691 | (insert (format " %S\n" glyph)) | 694 | glyph) |
| 692 | (setq from (1+ from)))) | 695 | (if (fontp font) |
| 693 | (insert " by these characters:\n") | 696 | (progn |
| 694 | (while (and (<= from to) | 697 | (insert " using this font:\n " |
| 695 | (setq glyph (lgstring-glyph gstring from))) | 698 | (symbol-name (font-get font :type)) |
| 696 | (insert (format " %c (#x%d)\n" | 699 | ?: |
| 697 | (lglyph-char glyph) (lglyph-char glyph))) | 700 | (aref (query-font font) 0) |
| 698 | (setq from (1+ from))))) | 701 | "\nby these glyphs:\n") |
| 699 | (insert " by the rule:\n\t(") | 702 | (while (and (<= from to) |
| 700 | (let ((first t)) | 703 | (setq glyph (lgstring-glyph gstring from))) |
| 701 | (mapc (lambda (x) | 704 | (insert (format " %S\n" glyph)) |
| 702 | (if first (setq first nil) | 705 | (setq from (1+ from)))) |
| 703 | (insert " ")) | 706 | (insert " by these characters:\n") |
| 704 | (if (consp x) (insert (format "%S" x)) | 707 | (while (and (<= from to) |
| 705 | (if (= x ?\t) (insert (single-key-description x)) | 708 | (setq glyph (lgstring-glyph gstring from))) |
| 706 | (insert ??) | 709 | (insert (format " %c (#x%d)\n" |
| 707 | (insert (describe-char-padded-string x))))) | 710 | (lglyph-char glyph) (lglyph-char glyph))) |
| 708 | (nth 2 composition))) | 711 | (setq from (1+ from))))) |
| 709 | (insert ")\nThe component character(s) are displayed by ") | 712 | (insert " by the rule:\n\t(") |
| 710 | (if (display-graphic-p (selected-frame)) | 713 | (let ((first t)) |
| 711 | (progn | 714 | (mapc (lambda (x) |
| 712 | (insert "these fonts (glyph codes):") | 715 | (if first (setq first nil) |
| 713 | (dolist (elt component-chars) | 716 | (insert " ")) |
| 714 | (if (/= (car elt) ?\t) | 717 | (if (consp x) (insert (format "%S" x)) |
| 715 | (insert "\n " | 718 | (if (= x ?\t) (insert (single-key-description x)) |
| 716 | (describe-char-padded-string (car elt)) | 719 | (insert ??) |
| 717 | ?: | 720 | (insert (describe-char-padded-string x))))) |
| 718 | (propertize " " 'display '(space :align-to 5)) | 721 | (nth 2 composition))) |
| 719 | (or (cdr elt) "-- no font --"))))) | 722 | (insert ")\nThe component character(s) are displayed by ") |
| 720 | (insert "these terminal codes:") | 723 | (if (display-graphic-p (selected-frame)) |
| 721 | (dolist (elt component-chars) | 724 | (progn |
| 722 | (insert "\n " (car elt) ":" | 725 | (insert "these fonts (glyph codes):") |
| 723 | (propertize " " 'display '(space :align-to 4)) | 726 | (dolist (elt component-chars) |
| 724 | (or (cdr elt) "-- not encodable --")))) | 727 | (if (/= (car elt) ?\t) |
| 725 | (insert "\nSee the variable `reference-point-alist' for " | 728 | (insert "\n " |
| 726 | "the meaning of the rule.\n"))) | 729 | (describe-char-padded-string (car elt)) |
| 727 | 730 | ?: | |
| 728 | (unless eight-bit-p | 731 | (propertize " " |
| 729 | (insert (if (not describe-char-unidata-list) | 732 | 'display '(space :align-to 5)) |
| 730 | "\nCharacter code properties are not shown: " | 733 | (or (cdr elt) "-- no font --"))))) |
| 731 | "\nCharacter code properties: ")) | 734 | (insert "these terminal codes:") |
| 732 | (insert-text-button | 735 | (dolist (elt component-chars) |
| 733 | "customize what to show" | 736 | (insert "\n " (car elt) ":" |
| 734 | 'action (lambda (&rest ignore) | 737 | (propertize " " 'display '(space :align-to 4)) |
| 735 | (customize-variable | 738 | (or (cdr elt) "-- not encodable --")))) |
| 736 | 'describe-char-unidata-list)) | 739 | (insert "\nSee the variable `reference-point-alist' for " |
| 737 | 'follow-link t) | 740 | "the meaning of the rule.\n"))) |
| 738 | (insert "\n") | 741 | |
| 739 | (dolist (elt (if (eq describe-char-unidata-list t) | 742 | (unless eight-bit-p |
| 740 | (nreverse (mapcar 'car char-code-property-alist)) | 743 | (insert (if (not describe-char-unidata-list) |
| 741 | describe-char-unidata-list)) | 744 | "\nCharacter code properties are not shown: " |
| 742 | (let ((val (get-char-code-property char elt)) | 745 | "\nCharacter code properties: ")) |
| 743 | description) | 746 | (insert-text-button |
| 744 | (when val | 747 | "customize what to show" |
| 745 | (setq description (char-code-property-description elt val)) | 748 | 'action (lambda (&rest ignore) |
| 746 | (insert (if description | 749 | (customize-variable |
| 747 | (format " %s: %s (%s)\n" elt val description) | 750 | 'describe-char-unidata-list)) |
| 748 | (format " %s: %s\n" elt val))))))) | 751 | 'follow-link t) |
| 749 | 752 | (insert "\n") | |
| 750 | (if text-props-desc (insert text-props-desc)) | 753 | (dolist (elt (if (eq describe-char-unidata-list t) |
| 751 | (setq help-xref-stack-item (list 'help-insert-string (buffer-string))) | 754 | (nreverse (mapcar 'car char-code-property-alist)) |
| 752 | (toggle-read-only 1))))) | 755 | describe-char-unidata-list)) |
| 756 | (let ((val (get-char-code-property char elt)) | ||
| 757 | description) | ||
| 758 | (when val | ||
| 759 | (setq description (char-code-property-description elt val)) | ||
| 760 | (insert (if description | ||
| 761 | (format " %s: %s (%s)\n" elt val description) | ||
| 762 | (format " %s: %s\n" elt val))))))) | ||
| 763 | |||
| 764 | (if text-props-desc (insert text-props-desc)) | ||
| 765 | (toggle-read-only 1)))))) | ||
| 753 | 766 | ||
| 754 | (define-obsolete-function-alias 'describe-char-after 'describe-char "22.1") | 767 | (define-obsolete-function-alias 'describe-char-after 'describe-char "22.1") |
| 755 | 768 | ||