diff options
| author | Richard M. Stallman | 2002-06-17 16:12:47 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2002-06-17 16:12:47 +0000 |
| commit | 4adb7c0968a15e528a36f720484a2c4d9e90c536 (patch) | |
| tree | a6cec94690db3c322003985c3235556f13599a65 | |
| parent | 1ecfdc6940dfccd423a6c3d2bd828e58208c3870 (diff) | |
| download | emacs-4adb7c0968a15e528a36f720484a2c4d9e90c536.tar.gz emacs-4adb7c0968a15e528a36f720484a2c4d9e90c536.zip | |
(describe-char): Moved from mule-diag.el, renamed
from describe-char-after. Now calls describe-text-properties.
(describe-property-list): Renamed from describe-text-properties.
(describe-text-properties): Renamed from describe-text-at.
New arg OUTPUT-BUFFER.
(describe-text-properties-1):
New subroutine, broken out from describe-text-properties.
Output a newline before each section of the output.
| -rw-r--r-- | lisp/descr-text.el | 235 |
1 files changed, 194 insertions, 41 deletions
diff --git a/lisp/descr-text.el b/lisp/descr-text.el index f1037e15db2..e75769078b0 100644 --- a/lisp/descr-text.el +++ b/lisp/descr-text.el | |||
| @@ -46,7 +46,7 @@ | |||
| 46 | :type 'hook) | 46 | :type 'hook) |
| 47 | 47 | ||
| 48 | (defun describe-text-mode () | 48 | (defun describe-text-mode () |
| 49 | "Major mode for buffers created by `describe-text-at'. | 49 | "Major mode for buffers created by `describe-char'. |
| 50 | 50 | ||
| 51 | \\{describe-text-mode-map} | 51 | \\{describe-text-mode-map} |
| 52 | Entry to this mode calls the value of `describe-text-mode-hook' | 52 | Entry to this mode calls the value of `describe-text-mode-hook' |
| @@ -92,7 +92,7 @@ if that value is non-nil." | |||
| 92 | (princ (widget-get widget :value)))) | 92 | (princ (widget-get widget :value)))) |
| 93 | pp)))) | 93 | pp)))) |
| 94 | 94 | ||
| 95 | (defun describe-text-properties (properties) | 95 | (defun describe-property-list (properties) |
| 96 | "Insert a description of PROPERTIES in the current buffer. | 96 | "Insert a description of PROPERTIES in the current buffer. |
| 97 | PROPERTIES should be a list of overlay or text properties. | 97 | PROPERTIES should be a list of overlay or text properties. |
| 98 | The `category' property is made into a widget button that call | 98 | The `category' property is made into a widget button that call |
| @@ -141,16 +141,40 @@ The `category' property is made into a widget button that call | |||
| 141 | (with-output-to-temp-buffer "*Text Category*" | 141 | (with-output-to-temp-buffer "*Text Category*" |
| 142 | (set-buffer "*Text Category*") | 142 | (set-buffer "*Text Category*") |
| 143 | (widget-insert "Category " (format "%S" category) ":\n\n") | 143 | (widget-insert "Category " (format "%S" category) ":\n\n") |
| 144 | (describe-text-properties (symbol-plist category)) | 144 | (describe-property-list (symbol-plist category)) |
| 145 | (describe-text-mode) | 145 | (describe-text-mode) |
| 146 | (goto-char (point-min))))) | 146 | (goto-char (point-min))))) |
| 147 | 147 | ||
| 148 | ;;;###autoload | 148 | ;;;###autoload |
| 149 | (defun describe-text-at (pos) | 149 | (defun describe-text-properties (pos &optional output-buffer) |
| 150 | "Describe widgets, buttons, overlays and text properties at POS." | 150 | "Describe widgets, buttons, overlays and text properties at POS. |
| 151 | Interactively, describe them for the character after point. | ||
| 152 | If optional second argument OUTPUT-BUFFER is non-nil, | ||
| 153 | insert the output into that buffer, and don't initialize or clear it | ||
| 154 | otherwise." | ||
| 151 | (interactive "d") | 155 | (interactive "d") |
| 152 | (when (eq (current-buffer) (get-buffer "*Text Description*")) | 156 | (when (eq (current-buffer) (get-buffer "*Text Description*")) |
| 153 | (error "Can't do self inspection")) | 157 | (error "Can't do self inspection")) |
| 158 | (if (>= pos (point-max)) | ||
| 159 | (error "No character follows specified position")) | ||
| 160 | (if output-buffer | ||
| 161 | (describe-text-properties-1 pos output-buffer) | ||
| 162 | (if (not (or (text-properties-at pos) (overlays-at pos))) | ||
| 163 | (message "This is plain text.") | ||
| 164 | (when (get-buffer "*Text Description*") | ||
| 165 | (kill-buffer "*Text Description*")) | ||
| 166 | (let ((buffer (current-buffer))) | ||
| 167 | (save-excursion | ||
| 168 | (with-output-to-temp-buffer "*Text Description*" | ||
| 169 | (set-buffer "*Text Description*") | ||
| 170 | (setq output-buffer (current-buffer)) | ||
| 171 | (widget-insert "Text content at position " (format "%d" pos) ":\n\n") | ||
| 172 | (with-current-buffer buffer | ||
| 173 | (describe-text-properties-1 pos output-buffer)) | ||
| 174 | (describe-text-mode) | ||
| 175 | (goto-char (point-min)))))))) | ||
| 176 | |||
| 177 | (defun describe-text-properties-1 (pos output-buffer) | ||
| 154 | (let* ((properties (text-properties-at pos)) | 178 | (let* ((properties (text-properties-at pos)) |
| 155 | (overlays (overlays-at pos)) | 179 | (overlays (overlays-at pos)) |
| 156 | overlay | 180 | overlay |
| @@ -162,43 +186,172 @@ The `category' property is made into a widget button that call | |||
| 162 | (button-type (and button (button-type button))) | 186 | (button-type (and button (button-type button))) |
| 163 | (button-label (and button (button-label button))) | 187 | (button-label (and button (button-label button))) |
| 164 | (widget (or wid-field wid-button wid-doc))) | 188 | (widget (or wid-field wid-button wid-doc))) |
| 165 | (if (not (or properties overlays)) | 189 | (with-current-buffer output-buffer |
| 166 | (message "This is plain text.") | 190 | ;; Widgets |
| 167 | (when (get-buffer "*Text Description*") | 191 | (when (widgetp widget) |
| 168 | (kill-buffer "*Text Description*")) | 192 | (newline) |
| 193 | (widget-insert (cond (wid-field "This is an editable text area") | ||
| 194 | (wid-button "This is an active area") | ||
| 195 | (wid-doc "This is documentation text"))) | ||
| 196 | (widget-insert " of a ") | ||
| 197 | (describe-text-widget widget) | ||
| 198 | (widget-insert ".\n\n")) | ||
| 199 | ;; Buttons | ||
| 200 | (when (and button (not (widgetp wid-button))) | ||
| 201 | (newline) | ||
| 202 | (widget-insert "Here is a " (format "%S" button-type) | ||
| 203 | " button labeled `" button-label "'.\n\n")) | ||
| 204 | ;; Overlays | ||
| 205 | (when overlays | ||
| 206 | (newline) | ||
| 207 | (if (eq (length overlays) 1) | ||
| 208 | (widget-insert "There is an overlay here:\n") | ||
| 209 | (widget-insert "There are " (format "%d" (length overlays)) | ||
| 210 | " overlays here:\n")) | ||
| 211 | (dolist (overlay overlays) | ||
| 212 | (widget-insert " From " (format "%d" (overlay-start overlay)) | ||
| 213 | " to " (format "%d" (overlay-end overlay)) "\n") | ||
| 214 | (describe-property-list (overlay-properties overlay))) | ||
| 215 | (widget-insert "\n")) | ||
| 216 | ;; Text properties | ||
| 217 | (when properties | ||
| 218 | (newline) | ||
| 219 | (widget-insert "There are text properties here:\n") | ||
| 220 | (describe-property-list properties))))) | ||
| 221 | |||
| 222 | ;;;###autoload | ||
| 223 | (defun describe-char (pos) | ||
| 224 | "Describe the character after POS (interactively, the character after point). | ||
| 225 | The information includes character code, charset and code points in it, | ||
| 226 | syntax, category, how the character is encoded in a file, | ||
| 227 | character composition information (if relevant), | ||
| 228 | as well as widgets, buttons, overlays, and text properties." | ||
| 229 | (interactive "d") | ||
| 230 | (when (eq (current-buffer) (get-buffer "*Text Description*")) | ||
| 231 | (error "Can't do self inspection")) | ||
| 232 | (if (>= pos (point-max)) | ||
| 233 | (error "No character follows specified position")) | ||
| 234 | (let* ((char (char-after pos)) | ||
| 235 | (charset (char-charset char)) | ||
| 236 | (buffer (current-buffer)) | ||
| 237 | (composition (find-composition (point) nil nil t)) | ||
| 238 | (composed (if composition (buffer-substring (car composition) | ||
| 239 | (nth 1 composition)))) | ||
| 240 | (multibyte-p enable-multibyte-characters) | ||
| 241 | item-list max-width) | ||
| 242 | (if (eq charset 'unknown) | ||
| 243 | (setq item-list | ||
| 244 | `(("character" | ||
| 245 | ,(format "%s (0%o, %d, 0x%x) -- invalid character code" | ||
| 246 | (if (< char 256) | ||
| 247 | (single-key-description char) | ||
| 248 | (char-to-string char)) | ||
| 249 | char char char)))) | ||
| 250 | (setq item-list | ||
| 251 | `(("character" | ||
| 252 | ,(format "%s (0%o, %d, 0x%x)" (if (< char 256) | ||
| 253 | (single-key-description char) | ||
| 254 | (char-to-string char)) | ||
| 255 | char char char)) | ||
| 256 | ("charset" | ||
| 257 | ,(symbol-name charset) | ||
| 258 | ,(format "(%s)" (charset-description charset))) | ||
| 259 | ("code point" | ||
| 260 | ,(let ((split (split-char char))) | ||
| 261 | (if (= (charset-dimension charset) 1) | ||
| 262 | (format "%d" (nth 1 split)) | ||
| 263 | (format "%d %d" (nth 1 split) (nth 2 split))))) | ||
| 264 | ("syntax" | ||
| 265 | ,(let ((syntax (get-char-property (point) 'syntax-table))) | ||
| 266 | (with-temp-buffer | ||
| 267 | (internal-describe-syntax-value | ||
| 268 | (if (consp syntax) syntax | ||
| 269 | (aref (or syntax (syntax-table)) char))) | ||
| 270 | (buffer-string)))) | ||
| 271 | ("category" | ||
| 272 | ,@(let ((category-set (char-category-set char))) | ||
| 273 | (if (not category-set) | ||
| 274 | '("-- none --") | ||
| 275 | (mapcar #'(lambda (x) (format "%c:%s " | ||
| 276 | x (category-docstring x))) | ||
| 277 | (category-set-mnemonics category-set))))) | ||
| 278 | ,@(let ((props (aref char-code-property-table char)) | ||
| 279 | ps) | ||
| 280 | (when props | ||
| 281 | (while props | ||
| 282 | (push (format "%s:" (pop props)) ps) | ||
| 283 | (push (format "%s;" (pop props)) ps)) | ||
| 284 | (list (cons "Properties" (nreverse ps))))) | ||
| 285 | ("buffer code" | ||
| 286 | ,(encoded-string-description | ||
| 287 | (string-as-unibyte (char-to-string char)) nil)) | ||
| 288 | ("file code" | ||
| 289 | ,@(let* ((coding buffer-file-coding-system) | ||
| 290 | (encoded (encode-coding-char char coding))) | ||
| 291 | (if encoded | ||
| 292 | (list (encoded-string-description encoded coding) | ||
| 293 | (format "(encoded by coding system %S)" coding)) | ||
| 294 | (list "not encodable by coding system" | ||
| 295 | (symbol-name coding))))) | ||
| 296 | ,@(if (or (memq 'mule-utf-8 | ||
| 297 | (find-coding-systems-region (point) (1+ (point)))) | ||
| 298 | (get-char-property (point) 'untranslated-utf-8)) | ||
| 299 | (let ((uc (or (get-char-property (point) | ||
| 300 | 'untranslated-utf-8) | ||
| 301 | (encode-char (char-after) 'ucs)))) | ||
| 302 | (if uc | ||
| 303 | (list (list "Unicode" | ||
| 304 | (format "%04X" uc)))))) | ||
| 305 | ,(if (display-graphic-p (selected-frame)) | ||
| 306 | (list "font" (or (internal-char-font (point)) | ||
| 307 | "-- none --")) | ||
| 308 | (list "terminal code" | ||
| 309 | (let* ((coding (terminal-coding-system)) | ||
| 310 | (encoded (encode-coding-char char coding))) | ||
| 311 | (if encoded | ||
| 312 | (encoded-string-description encoded coding) | ||
| 313 | "not encodable"))))))) | ||
| 314 | (setq max-width (apply #'max (mapcar #'(lambda (x) (length (car x))) | ||
| 315 | item-list))) | ||
| 316 | (when (get-buffer "*Help*") | ||
| 317 | (kill-buffer "*Help*")) | ||
| 318 | (with-output-to-temp-buffer "*Help*" | ||
| 169 | (save-excursion | 319 | (save-excursion |
| 170 | (with-output-to-temp-buffer "*Text Description*" | 320 | (set-buffer standard-output) |
| 171 | (set-buffer "*Text Description*") | 321 | (set-buffer-multibyte multibyte-p) |
| 172 | (widget-insert "Text content at position " (format "%d" pos) ":\n\n") | 322 | (let ((formatter (format "%%%ds:" max-width))) |
| 173 | ;; Widgets | 323 | (dolist (elt item-list) |
| 174 | (when (widgetp widget) | 324 | (insert (format formatter (car elt))) |
| 175 | (widget-insert (cond (wid-field "This is an editable text area") | 325 | (dolist (clm (cdr elt)) |
| 176 | (wid-button "This is an active area") | 326 | (when (>= (+ (current-column) |
| 177 | (wid-doc "This is documentation text"))) | 327 | (or (string-match "\n" clm) |
| 178 | (widget-insert " of a ") | 328 | (string-width clm)) 1) |
| 179 | (describe-text-widget widget) | 329 | (frame-width)) |
| 180 | (widget-insert ".\n\n")) | 330 | (insert "\n") |
| 181 | ;; Buttons | 331 | (indent-to (1+ max-width))) |
| 182 | (when (and button (not (widgetp wid-button))) | 332 | (insert " " clm)) |
| 183 | (widget-insert "Here is a " (format "%S" button-type) | 333 | (insert "\n"))) |
| 184 | " button labeled `" button-label "'.\n\n")) | 334 | (when composition |
| 185 | ;; Overlays | 335 | (insert "\nComposed with the following character(s) " |
| 186 | (when overlays | 336 | (mapconcat (lambda (x) (format "`%c'" x)) |
| 187 | (if (eq (length overlays) 1) | 337 | (substring composed 1) |
| 188 | (widget-insert "There is an overlay here:\n") | 338 | ", ") |
| 189 | (widget-insert "There are " (format "%d" (length overlays)) | 339 | " to form `" composed "'") |
| 190 | " overlays here:\n")) | 340 | (if (nth 3 composition) |
| 191 | (dolist (overlay overlays) | 341 | (insert ".\n") |
| 192 | (widget-insert " From " (format "%d" (overlay-start overlay)) | 342 | (insert "\nby the rule (" |
| 193 | " to " (format "%d" (overlay-end overlay)) "\n") | 343 | (mapconcat (lambda (x) |
| 194 | (describe-text-properties (overlay-properties overlay))) | 344 | (format (if (consp x) "%S" "?%c") x)) |
| 195 | (widget-insert "\n")) | 345 | (nth 2 composition) |
| 196 | ;; Text properties | 346 | " ") |
| 197 | (when properties | 347 | ").\n" |
| 198 | (widget-insert "There are text properties here:\n") | 348 | "See the variable `reference-point-alist' for " |
| 199 | (describe-text-properties properties)) | 349 | "the meaning of the rule.\n"))) |
| 200 | (describe-text-mode) | 350 | |
| 201 | (goto-char (point-min))))))) | 351 | (let ((output (current-buffer))) |
| 352 | (with-current-buffer buffer | ||
| 353 | (describe-text-properties pos output)) | ||
| 354 | (describe-text-mode)))))) | ||
| 202 | 355 | ||
| 203 | (provide 'descr-text) | 356 | (provide 'descr-text) |
| 204 | 357 | ||