Re: [PATCH] Support opaque display-table objects on XEmacs
16 years, 6 months
Aidan Kehoe
Ar an seachtú lá is fiche de mí Bealtaine, scríobh Reiner Steib:
> On Thu, May 22 2008, Miles Bader wrote:
>
> > Aidan Kehoe <kehoea(a)parhasard.net> writes:
> >> This patch adds support for the non-sequence display tables of XEmacs
> >> 21.5, without any run-time overhead on GNU. A patch that’s equivalent
> >> in functionality for that version has been integrated into the XEmacs
> >> package repository; this conflicts with that, though--sorry Mike!--and
> >> is more compatible with GNU.
>
> I gather that it should be applied to the stable and development
> branch. Right?
That would be ideal from my perspective, yes.
> >> I’ve tested this (somewhat superficially) with XEmacs 21.5, 21.4
> >> and GNU.
>
> (Just call the later "Emacs".)
That’s something I’ve considered, yes. (Also, “latter”.)
> >> Please advise me if this is the wrong list to submit this to.
>
> It's the right list. Thanks.
>
> >> I have papers on file with the FSF for Gnus and for GNU Emacs as a
> >> whole, so that shouldn’t be an issue.
>
> Confirmed.
>
> >> * gnus-util.el (gnus-put-display-table): New.
> >> (gnus-get-display-table): New.
> >> Macros that expand to an #'aset call under GNU, and to a runtime choice
> >> under XEmacs.
>
> Is writing “#'” a new XEmacsy ChangeLog convention?
No, it’s a Common Lisp thing that I picked up from the SXEmacs folk, and
that I find helpful and clear. (In CL it’s a macro that throws an error at
read time if the following symbol doesn’t have a function definition.)
> >> * gnus-sum.el (gnus-summary-set-display-table):
> >> Use #'gnus-{put,get}-display-table, gnus-set-display-table for the
> >> display table, instead of #'aset.
> >> * gnus-xmas.el (gnus-xmas-summary-set-display-table):
> >> Use #'gnus-{put,get}-display-table, gnus-set-display-table for the
> >> display table.
>
> It's better (e.g. for searching) to spell out the macro names (not
> using {put,get}).
This is unclear to me; are you asking me to resubmit the patch for this
reason?
> >> @@ -3431,8 +3431,8 @@
> >> 256)))
> >> (while (>= (setq i (1- i)) 127)
> >> ;; Only modify if the entry is nil.
> >> - (unless (aref table i)
> >> - (aset table i [??]))))
> >> + (unless (get-display-table i table)
> >> + (put-display-table i [??] table))))
> >> (setq buffer-display-table table)))
> >
> > Should those be `gnus-get-display-table' and `gnus-put-display-table'?
>
> Aidan?
Ah, yes, they should. I’ll resubmit the patch on that basis.
> >> +(defmacro gnus-put-display-table (range value display-table)
> >> + "Set the value for char RANGE to VALUE in DISPLAY-TABLE. "
> >> + (if (featurep 'xemacs)
> >> + (progn
>
> Useless `progn'?
Yes.
> >> + `(if (fboundp 'put-display-table)
> >> + (put-display-table ,range ,value ,display-table)
> >> + (if (sequencep ,display-table)
> >> + (aset ,display-table ,range ,value)
> >> + (put-char-table ,range ,value ,display-table))))
>
> `cond' would be more readable than an `if'-cascade, IMHO.
Meh, part of the cascade is at compile time, part at run time, and the
latter is only two deep. One more level and I would agree with you.
--
¿Dónde estará ahora mi sobrino Yoghurtu Nghé, que tuvo que huir
precipitadamente de la aldea por culpa de la escasez de rinocerontes?
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches
[COMMIT] Don't load .flc files from the directory of the corresponding file
16 years, 6 months
Aidan Kehoe
Ville, I’ve tested this, and it works. Norbert, you’re away for the next
couple of weeks; does anyone else have access to build and release a new
package?
APPROVE COMMIT
NOTE: This patch has been committed.
xemacs-packages/edit-utils/ChangeLog addition:
2008-06-09 Aidan Kehoe <kehoea(a)parhasard.net>
* fast-lock.el (fast-lock-cache-directories):
Remove the directory the file is in, to avoid running code from
arbitrary other users. Update the docstring to motivate this.
Also, mark it as a risky local variable to prevent it being
evaluated in file local variable sections.
Thank you Ulrich Müller, thank you Hans de Graaff.
XEmacs Packages source patch:
Diff command: cvs -q diff -Nu
Files affected: xemacs-packages/edit-utils/fast-lock.el
===================================================================
RCS
Index: xemacs-packages/edit-utils/fast-lock.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/edit-utils/fast-lock.el,v
retrieving revision 1.4
diff -u -u -r1.4 fast-lock.el
--- xemacs-packages/edit-utils/fast-lock.el 2006/03/07 07:10:32 1.4
+++ xemacs-packages/edit-utils/fast-lock.el 2008/06/09 18:55:05
@@ -247,7 +247,7 @@
;; User Variables:
-(defcustom fast-lock-cache-directories '("." "~/.emacs-flc")
+(defcustom fast-lock-cache-directories '("~/.emacs-flc")
; - `internal', keep each file's Font Lock cache file in the same file.
; - `external', keep each file's Font Lock cache file in the same directory.
"*Directories in which Font Lock cache files are saved and read.
@@ -265,9 +265,14 @@
((\"^/your/true/home/directory/\" . \".\") \"~/.emacs-flc\")
would cause a file's current directory to be used if the file is under your
-home directory hierarchy, or otherwise the absolute directory `~/.emacs-flc'."
+home directory hierarchy, or otherwise the absolute directory `~/.emacs-flc'.
+For security reasons, it is not advisable to use the file's current directory
+to avoid the possibility of using the cache of another user."
:type '(repeat (choice (cons regexp directory) directory))
:group 'fast-lock)
+
+;;;###autoload
+(put 'fast-lock-cache-directories 'risky-local-variable t)
(defcustom fast-lock-minimum-size (* 25 1024)
"*Minimum size of a buffer for cached fontification.
--
¿Dónde estará ahora mi sobrino Yoghurtu Nghé, que tuvo que huir
precipitadamente de la aldea por culpa de la escasez de rinocerontes?
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches
Re: [Bug: 21.5-b28] lines in occur-engine wasn't correctly computed
16 years, 6 months
FKtPp
On Thu, May 29, 2008 at 12:14:51AM +0800, It's me FKtPp ;) wrote:
> ================================================================
> Dear Bug Team!
>
> When occuring some regexp, which can match across multi-lines, line
> numbers in the occur result list will be incorrectly computed.
>
> (setq origpt (point))
> (when (setq endpt (re-search-forward regexp nil t))
> (setq matches (1+ matches)) ;; increment match count
> (setq matchbeg (match-beginning 0))
> (setq lines (+ lines (1- (count-lines origpt endpt))))
>
> Note that endpt, it was not at the same line of the "diplayed string
> in the occur result list" in case of multi-line match.
>
> ================================================================
>
hi Team,
I've composed a patch against this issue, could you please help
evaluate it. And if possiable install it?
ChangeLog Entry:
===============================================================================
2008-06-09 It's me FKtPp ;) <m_pupil(a)yahoo.com.cn>
* occur.el:
* occur.el (occur-accumulate-lines): Convert to use
#'point-at-b(e)ol built-in functions
* occur.el (occur-engine-update-lines): New. always count lines
from a bol to anther bol
* occur.el (occur-engine): change the lines value calculation
method, so that it can deal with multine matches,
e.g. `^(def[^()]+)'. Mainly because of the following lines in the
(info "(lispref)Syntax of Regexps").
Note that a complement character set can match a newline, unless
newline is mentioned as one of the characters not to match.
Patch Entry:
===============================================================================
core-beta[XEmacs] source patch:
Diff command: hg diff -wbB
Files affected: lisp/occur.el
diff -r 0204391fc17c lisp/occur.el
--- lisp/occur.el Wed Jun 04 21:57:49 2008 +0200
+++ lisp/occur.el Mon Jun 09 02:30:24 2008 +0800
@@ -246,8 +246,9 @@
(eobp)
(bobp))))
(setq count (+ count (if forwardp -1 1)))
- (setq beg (line-beginning-position)
- end (line-end-position))
+ ;; XEmacs specific line-beginning/end-possion to point-at-b(e)ol conversion
+ (setq beg (point-at-bol)
+ end (point-at-eol))
(if (and keep-props (if-boundp 'jit-lock-mode jit-lock-mode)
(text-property-not-all beg end 'fontified t))
(if-fboundp 'jit-lock-fontify-now
@@ -426,6 +427,19 @@
(concat " :" line "\n"))
lines))
+(defsubst occur-engine-update-lines (lines beg end)
+ "count lines between the BEG and END point position, then add to LINES
+
+Returns updated LINES value.
+NOTE: this is a XEmacs specific inline function."
+ (save-excursion
+ (let (beg-bol end-bol)
+ (goto-char beg)
+ (setq beg-bol (point-at-bol))
+ (goto-char end)
+ (setq end-bol (point-at-bol))
+ (+ lines (count-lines beg-bol end-bol)))))
+
(defun occur-engine (regexp buffers out-buf nlines case-fold-search
title-face prefix-face match-face keep-props)
(with-current-buffer out-buf
@@ -456,83 +470,96 @@
(goto-char (point-min)) ;; begin searching in the buffer
(while (not (eobp))
(setq origpt (point))
- (when (setq endpt (re-search-forward regexp nil t))
- (setq matches (1+ matches)) ;; increment match count
- (setq matchbeg (match-beginning 0))
- (setq lines (+ lines (1- (count-lines origpt endpt))))
- (save-excursion
- (goto-char matchbeg)
- (setq begpt (line-beginning-position)
- endpt (line-end-position)))
- (setq marker (make-marker))
- (set-marker marker matchbeg)
- (if (and keep-props
- (if-boundp 'jit-lock-mode jit-lock-mode)
- (text-property-not-all begpt endpt 'fontified t))
- (if-fboundp #'jit-lock-fontify-now
- (jit-lock-fontify-now begpt endpt)))
- (setq curstring (buffer-substring begpt endpt))
- ;; Depropertize the string, and maybe
- ;; highlight the matches
- (let ((len (length curstring))
- (start 0))
- (unless keep-props
- (set-text-properties 0 len nil curstring))
- (while (and (< start len)
- (string-match regexp curstring start))
- (add-text-properties
- (match-beginning 0) (match-end 0)
- (append
- `(occur-match t)
- (when match-face
- ;; Use `face' rather than `font-lock-face' here
- ;; so as to override faces copied from the buffer.
- `(face ,match-face)))
- curstring)
- (setq start (match-end 0))))
- ;; Generate the string to insert for this match
- (let* ((out-line
- (concat
- ;; Using 7 digits aligns tabs properly.
- (apply #'propertize (format "%7d:" lines)
- (append
- (when prefix-face
- `(font-lock-face prefix-face))
- '(occur-prefix t)))
- ;; We don't put `mouse-face' on the newline,
- ;; because that loses. And don't put it
- ;; on context lines to reduce flicker.
- (propertize curstring 'mouse-face 'highlight)
- "\n"))
- (data
- (if (= nlines 0)
- ;; The simple display style
- out-line
- ;; The complex multi-line display
- ;; style. Generate a list of lines,
- ;; concatenate them all together.
- (apply #'concat
- (nconc
- (occur-engine-add-prefix (nreverse (cdr (occur-accumulate-lines (- (1+ (abs nlines))) keep-props))))
- (list out-line)
- (if (> nlines 0)
- (occur-engine-add-prefix
- (cdr (occur-accumulate-lines (1+ nlines) keep-props)))))))))
- ;; Actually insert the match display data
- (with-current-buffer out-buf
- (let ((beg (point))
- (end (progn (insert data) (point))))
- (unless (= nlines 0)
- (insert "-------\n"))
- (add-text-properties
- beg end
- `(occur-target ,marker help-echo "mouse-2: go to this occurrence")))))
- (goto-char endpt))
- (if endpt
- (progn
- (setq lines (1+ lines))
- ;; On to the next match...
- (forward-line 1))
+ (if (setq endpt (re-search-forward regexp nil t))
+ (progn (setq matches (1+ matches) ;; increment match count
+ matchbeg (match-beginning 0)
+ matchend endpt
+ ;; Yes, always count against the
+ ;; matchbeg to keep the lines value
+ ;; correct
+ lines (occur-engine-update-lines lines origpt matchbeg))
+ ;; Later the #'occur-accumulate-lines
+ ;; function will relays current POINT
+ ;; position to extract correct result, so
+ ;; we don't do #'save-excursion here
+ ;; anymore.
+ (goto-char matchbeg)
+ ;; XEmacs specific
+ ;; line-beginning/end-possion to
+ ;; point-at-b(e)ol conversion.
+ (setq begpt (point-at-bol)
+ endpt (point-at-eol))
+ (setq marker (make-marker))
+ (set-marker marker matchbeg)
+ (if (and keep-props
+ (if-boundp 'jit-lock-mode jit-lock-mode)
+ (text-property-not-all begpt endpt 'fontified t))
+ (if-fboundp #'jit-lock-fontify-now
+ (jit-lock-fontify-now begpt endpt)))
+ (setq curstring (buffer-substring begpt endpt))
+ ;; Depropertize the string, and maybe
+ ;; highlight the matches
+ (let ((len (length curstring))
+ (start 0))
+ (unless keep-props
+ (set-text-properties 0 len nil curstring))
+ (while (and (< start len)
+ (string-match regexp curstring start))
+ (add-text-properties
+ (match-beginning 0) (match-end 0)
+ (append
+ `(occur-match t)
+ (when match-face
+ ;; Use `face' rather than `font-lock-face' here
+ ;; so as to override faces copied from the buffer.
+ `(face ,match-face)))
+ curstring)
+ (setq start (match-end 0))))
+ ;; Generate the string to insert for this match
+ (let* ((out-line
+ (concat
+ ;; Using 7 digits aligns tabs properly.
+ (apply #'propertize (format "%7d:" lines)
+ (append
+ (when prefix-face
+ `(font-lock-face prefix-face))
+ '(occur-prefix t)))
+ ;; We don't put `mouse-face' on the newline,
+ ;; because that loses. And don't put it
+ ;; on context lines to reduce flicker.
+ (propertize curstring 'mouse-face 'highlight)
+ "\n"))
+ (data
+ (if (= nlines 0)
+ ;; The simple display style
+ out-line
+ ;; The complex multi-line display
+ ;; style. Generate a list of lines,
+ ;; concatenate them all together.
+ (apply #'concat
+ (nconc
+ (occur-engine-add-prefix (nreverse (cdr (occur-accumulate-lines (- (1+ (abs nlines))) keep-props))))
+ (list out-line)
+ (if (> nlines 0)
+ (occur-engine-add-prefix
+ (cdr (occur-accumulate-lines (1+ nlines) keep-props)))))))))
+ ;; Actually insert the match display data
+ (with-current-buffer out-buf
+ (let ((beg (point))
+ (end (progn (insert data) (point))))
+ (unless (= nlines 0)
+ (insert "-------\n"))
+ (add-text-properties
+ beg end
+ `(occur-target ,marker help-echo "mouse-2: go to this occurrence")))))
+ ;; On to the next match... Here we don't
+ ;; do the ugly #'forward-line and #'1+
+ ;; lines, instead calculate the actual
+ ;; lines between the matchbeg and
+ ;; matchend so that it can deal with
+ ;; multi-line matches.
+ (goto-char matchend)
+ (setq lines (occur-engine-update-lines lines matchbeg matchend)))
(goto-char (point-max))))))
(when (not (zerop matches)) ;; is the count zero?
(setq globalcount (+ globalcount matches))
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches
carbon2-commit: #'require hyper-apropos in #'describe-property-list, for hyper-apropos-face
16 years, 6 months
Aidan Kehoe
changeset: 4502:0204391fc17cfbae2117a6ba5babd84081ac3834
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Wed Jun 04 21:57:49 2008 +0200
files: lisp/ChangeLog lisp/descr-text.el
description:
#'require hyper-apropos in #'describe-property-list, for hyper-apropos-face
2008-06-04 Aidan Kehoe <kehoea(a)parhasard.net>
* descr-text.el (describe-property-list):
#'require hyper-apropos, since we use hyper-apropos-face
diff -r a99eb40f0b5b20b5883afae4908bf425998addbf -r 0204391fc17cfbae2117a6ba5babd84081ac3834 lisp/ChangeLog
--- a/lisp/ChangeLog Thu May 29 18:53:45 2008 +0200
+++ b/lisp/ChangeLog Wed Jun 04 21:57:49 2008 +0200
@@ -1,3 +1,8 @@ 2008-05-25 Aidan Kehoe <kehoea@parhasa
+2008-06-04 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * descr-text.el (describe-property-list):
+ #'require hyper-apropos, since we use hyper-apropos-face
+
2008-05-25 Aidan Kehoe <kehoea(a)parhasard.net>
* descr-text.el: New.
diff -r a99eb40f0b5b20b5883afae4908bf425998addbf -r 0204391fc17cfbae2117a6ba5babd84081ac3834 lisp/descr-text.el
--- a/lisp/descr-text.el Thu May 29 18:53:45 2008 +0200
+++ b/lisp/descr-text.el Wed Jun 04 21:57:49 2008 +0200
@@ -82,6 +82,7 @@ into help buttons that call `describe-te
into help buttons that call `describe-text-category' or
`describe-face' when pushed."
;; Sort the properties by the size of their value.
+ (require 'hyper-apropos)
(dolist (elt (sort (let (ret)
(while properties
(push (list (pop properties) (pop properties)) ret))
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches
carbon2-commit: Correct an omitted word, expand on bignum equality in the lispref.
16 years, 6 months
Aidan Kehoe
changeset: 4501:a99eb40f0b5b20b5883afae4908bf425998addbf
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Thu May 29 18:53:45 2008 +0200
files: man/ChangeLog man/lispref/objects.texi
description:
Correct an omitted word, expand on bignum equality in the lispref.
2008-05-29 Aidan Kehoe <kehoea(a)parhasard.net>
* lispref/objects.texi (Equality Predicates):
Expand on bignum equality; correct an omitted word in the last
commit.
diff -r 2d39535e1f9d3557a3382ef0823ad5a47ace5a6a -r a99eb40f0b5b20b5883afae4908bf425998addbf man/ChangeLog
--- a/man/ChangeLog Tue May 27 11:58:42 2008 +0200
+++ b/man/ChangeLog Thu May 29 18:53:45 2008 +0200
@@ -1,3 +1,9 @@ 2008-05-27 Aidan Kehoe <kehoea@parhasa
+2008-05-29 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * lispref/objects.texi (Equality Predicates):
+ Expand on bignum equality; correct an omitted word in the last
+ commit.
+
2008-05-27 Aidan Kehoe <kehoea(a)parhasard.net>
* lispref/objects.texi (Equality Predicates):
diff -r 2d39535e1f9d3557a3382ef0823ad5a47ace5a6a -r a99eb40f0b5b20b5883afae4908bf425998addbf man/lispref/objects.texi
--- a/man/lispref/objects.texi Tue May 27 11:58:42 2008 +0200
+++ b/man/lispref/objects.texi Thu May 29 18:53:45 2008 +0200
@@ -2247,10 +2247,12 @@ change in one will be reflected by the s
@code{eq} returns @code{t} if @var{object1} and @var{object2} are
integers with the same value. It is preferable to use @code{=} or
-@code{eql} in many contexts for numeric comparison; @pxref{Comparison of
-Numbers}. @code{eq} also returns @code{t} if @var{object1} and
-@var{object2} are identical characters, though in this case you may
-prefer to use @code{char=}.
+@code{eql} in many contexts for numeric comparison, especially since
+bignums (integers with values that would have otherwise overflowed, only
+available on some builds) with the same value are not @code{eq};
+@pxref{Comparison of Numbers}. @code{eq} also returns @code{t} if
+@var{object1} and @var{object2} are identical characters, though in this
+case you may prefer to use @code{char=}.
Also, since symbol names are normally unique, if the arguments are
symbols with the same name, they are @code{eq}. For other types (e.g.,
@@ -2264,7 +2266,7 @@ the same name are not @code{eq}. @xref{
the same name are not @code{eq}. @xref{Creating Symbols}.)
NOTE: Under XEmacs 19, characters are really just integers, and thus
-characters and integers with the same numeric are @code{eq}. Under
+characters and integers with the same numeric code are @code{eq}. Under
XEmacs 20, it was necessary to preserve remnants of this in function
such as @code{old-eq} in order to maintain byte-code compatibility.
Byte code compiled under any Emacs 19 will automatically have calls to
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches
carbon2-commit: Correct a thinko in the #'translate-region docstring
16 years, 6 months
Aidan Kehoe
changeset: 4499:c76b1bc6bd28adf5c762d5575a55b9ac49dddc7b
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Tue May 27 12:01:29 2008 +0200
files: src/ChangeLog src/editfns.c
description:
Correct a thinko in the #'translate-region docstring
2008-05-27 Aidan Kehoe <kehoea(a)parhasard.net>
* editfns.c (Ftranslate_region):
Correct a thinko in the last commit; I meant #'get-char-table, not
#'put-char-table.
diff -r c661944aa2597457798ce30bdaa6ac6ddbc8c3b0 -r c76b1bc6bd28adf5c762d5575a55b9ac49dddc7b src/ChangeLog
--- a/src/ChangeLog Sun May 25 22:54:33 2008 +0200
+++ b/src/ChangeLog Tue May 27 12:01:29 2008 +0200
@@ -1,3 +1,9 @@ 2008-05-25 Aidan Kehoe <kehoea@parhasa
+2008-05-27 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * editfns.c (Ftranslate_region):
+ Correct a thinko in the last commit; I meant #'get-char-table, not
+ #'put-char-table.
+
2008-05-25 Aidan Kehoe <kehoea(a)parhasard.net>
* chartab.c (Fmake_char_table):
diff -r c661944aa2597457798ce30bdaa6ac6ddbc8c3b0 -r c76b1bc6bd28adf5c762d5575a55b9ac49dddc7b src/editfns.c
--- a/src/editfns.c Sun May 25 22:54:33 2008 +0200
+++ b/src/editfns.c Tue May 27 12:01:29 2008 +0200
@@ -1825,11 +1825,11 @@ nil (nil meaning don't replace.)
If TABLE is a char-table, its elements describe the mapping between
characters and their replacements. The char-table should be of type `char'
-or `generic'. If the value given by `put-char-table' for a given character
+or `generic'. If the value given by `get-char-table' for a given character
is nil, that character will not be translated by `translate-region'. Since
-`char' char-tables can never return nil to `put-char-table', and since most
-translation involves a subset of the possible XEmacs characters, not all of
-them, the most generally useful table type here is `generic'.
+`get-char-table' can never return nil with a char table of type `char', and
+since most translation involves a subset of the possible XEmacs characters,
+not all of them, the most generally useful table type here is `generic'.
Returns the number of substitutions performed.
*/
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches
carbon2-commit: Say explicitly that eq is useful for chars; xref number comparison, lispref
16 years, 6 months
Aidan Kehoe
changeset: 4500:2d39535e1f9d3557a3382ef0823ad5a47ace5a6a
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Tue May 27 11:58:42 2008 +0200
files: man/ChangeLog man/lispref/objects.texi
description:
Say explicitly that eq is useful for chars; xref number comparison, lispref
2008-05-27 Aidan Kehoe <kehoea(a)parhasard.net>
* lispref/objects.texi (Equality Predicates):
Cross reference to the section on comparison of numbers when
talking about using #'eq with integers; also mention that
#'eq gives t when passed identical integers, and that #'char= is
also available there.
diff -r c76b1bc6bd28adf5c762d5575a55b9ac49dddc7b -r 2d39535e1f9d3557a3382ef0823ad5a47ace5a6a man/ChangeLog
--- a/man/ChangeLog Tue May 27 12:01:29 2008 +0200
+++ b/man/ChangeLog Tue May 27 11:58:42 2008 +0200
@@ -1,3 +1,11 @@ 2008-05-21 Aidan Kehoe <kehoea@parhasa
+2008-05-27 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * lispref/objects.texi (Equality Predicates):
+ Cross reference to the section on comparison of numbers when
+ talking about using #'eq with integers; also mention that
+ #'eq gives t when passed identical integers, and that #'char= is
+ also available there.
+
2008-05-21 Aidan Kehoe <kehoea(a)parhasard.net>
* internals/internals.texi (Ben's README):
diff -r c76b1bc6bd28adf5c762d5575a55b9ac49dddc7b -r 2d39535e1f9d3557a3382ef0823ad5a47ace5a6a man/lispref/objects.texi
--- a/man/lispref/objects.texi Tue May 27 12:01:29 2008 +0200
+++ b/man/lispref/objects.texi Tue May 27 11:58:42 2008 +0200
@@ -2246,12 +2246,17 @@ change in one will be reflected by the s
change in one will be reflected by the same change in the other.
@code{eq} returns @code{t} if @var{object1} and @var{object2} are
-integers with the same value. Also, since symbol names are normally
-unique, if the arguments are symbols with the same name, they are
-@code{eq}. For other types (e.g., lists, vectors, strings), two
-arguments with the same contents or elements are not necessarily
-@code{eq} to each other: they are @code{eq} only if they are the same
-object.
+integers with the same value. It is preferable to use @code{=} or
+@code{eql} in many contexts for numeric comparison; @pxref{Comparison of
+Numbers}. @code{eq} also returns @code{t} if @var{object1} and
+@var{object2} are identical characters, though in this case you may
+prefer to use @code{char=}.
+
+Also, since symbol names are normally unique, if the arguments are
+symbols with the same name, they are @code{eq}. For other types (e.g.,
+lists, vectors, strings), two arguments with the same contents or
+elements are not necessarily @code{eq} to each other: they are @code{eq}
+only if they are the same object.
(The @code{make-symbol} function returns an uninterned symbol that is
not interned in the standard @code{obarray}. When uninterned symbols
@@ -2259,11 +2264,11 @@ the same name are not @code{eq}. @xref{
the same name are not @code{eq}. @xref{Creating Symbols}.)
NOTE: Under XEmacs 19, characters are really just integers, and thus
-characters and integers are @code{eq}. Under XEmacs 20, it was
-necessary to preserve remnants of this in function such as @code{old-eq}
-in order to maintain byte-code compatibility. Byte code compiled
-under any Emacs 19 will automatically have calls to @code{eq} mapped
-to @code{old-eq} when executed under XEmacs 20.
+characters and integers with the same numeric are @code{eq}. Under
+XEmacs 20, it was necessary to preserve remnants of this in function
+such as @code{old-eq} in order to maintain byte-code compatibility.
+Byte code compiled under any Emacs 19 will automatically have calls to
+@code{eq} mapped to @code{old-eq} when executed under XEmacs 20.
@example
@group
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches
carbon2-commit: Fill out docstrings for #'translate-region, #'make-char-table.
16 years, 6 months
Aidan Kehoe
changeset: 4498:c661944aa2597457798ce30bdaa6ac6ddbc8c3b0
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Sun May 25 22:54:33 2008 +0200
files: src/ChangeLog src/chartab.c src/editfns.c
description:
Fill out docstrings for #'translate-region, #'make-char-table.
2008-05-25 Aidan Kehoe <kehoea(a)parhasard.net>
* chartab.c (Fmake_char_table):
Document the default return values for the various char table
types.
* editfns.c (Ftranslate_region): Document why `generic' char tables
are preferable to `char' char tables for this function.
diff -r a78d697ccd2c832f5770b564e944a88b4f1f2549 -r c661944aa2597457798ce30bdaa6ac6ddbc8c3b0 src/ChangeLog
--- a/src/ChangeLog Sun May 25 21:11:35 2008 +0200
+++ b/src/ChangeLog Sun May 25 22:54:33 2008 +0200
@@ -1,3 +1,11 @@ 2008-05-21 Aidan Kehoe <kehoea@parhasa
+2008-05-25 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * chartab.c (Fmake_char_table):
+ Document the default return values for the various char table
+ types.
+ * editfns.c (Ftranslate_region): Document why `generic' char tables
+ are preferable to `char' char tables for this function.
+
2008-05-21 Aidan Kehoe <kehoea(a)parhasard.net>
* fileio.c (Fmake_symbolic_link):
diff -r a78d697ccd2c832f5770b564e944a88b4f1f2549 -r c661944aa2597457798ce30bdaa6ac6ddbc8c3b0 src/chartab.c
--- a/src/chartab.c Sun May 25 21:11:35 2008 +0200
+++ b/src/chartab.c Sun May 25 22:54:33 2008 +0200
@@ -566,25 +566,32 @@ sorts of values. The different char tab
sorts of values. The different char table types are
`category'
- Used for category tables, which specify the regexp categories
- that a character is in. The valid values are nil or a
- bit vector of 95 elements. Higher-level Lisp functions are
- provided for working with category tables. Currently categories
+ Used for category tables, which specify the regexp categories that a
+ character is in. The valid values are nil or a bit vector of 95
+ elements, and values default to nil. Higher-level Lisp functions
+ are provided for working with category tables. Currently categories
and category tables only exist when Mule support is present.
`char'
- A generalized char table, for mapping from one character to
- another. Used for case tables, syntax matching tables,
- `keyboard-translate-table', etc. The valid values are characters.
+ A generalized char table, for mapping from one character to another.
+ Used for case tables, syntax matching tables,
+ `keyboard-translate-table', etc. The valid values are characters,
+ and the default result given by `get-char-table' if a value hasn't
+ been set for a given character or for a range that includes it, is
+ ?\x00.
`generic'
- An even more generalized char table, for mapping from a
- character to anything.
+ An even more generalized char table, for mapping from a character to
+ anything. The default result given by `get-char-table' is nil.
`display'
- Used for display tables, which specify how a particular character
- is to appear when displayed. #### Not yet implemented.
+ Used for display tables, which specify how a particular character is
+ to appear when displayed. #### Not yet implemented; currently, the
+ display table code uses generic char tables, and it's not clear that
+ implementing this char table type would be useful.
`syntax'
Used for syntax tables, which specify the syntax of a particular
character. Higher-level Lisp functions are provided for
- working with syntax tables. The valid values are integers.
+ working with syntax tables. The valid values are integers, and the
+ default result given by `get-char-table' is the syntax code for
+ `inherit'.
*/
(type))
{
diff -r a78d697ccd2c832f5770b564e944a88b4f1f2549 -r c661944aa2597457798ce30bdaa6ac6ddbc8c3b0 src/editfns.c
--- a/src/editfns.c Sun May 25 21:11:35 2008 +0200
+++ b/src/editfns.c Sun May 25 22:54:33 2008 +0200
@@ -1824,8 +1824,12 @@ nil (nil meaning don't replace.)
nil (nil meaning don't replace.)
If TABLE is a char-table, its elements describe the mapping between
-characters and their replacements. The char-table should be of type
-`char' or `generic'.
+characters and their replacements. The char-table should be of type `char'
+or `generic'. If the value given by `put-char-table' for a given character
+is nil, that character will not be translated by `translate-region'. Since
+`char' char-tables can never return nil to `put-char-table', and since most
+translation involves a subset of the possible XEmacs characters, not all of
+them, the most generally useful table type here is `generic'.
Returns the number of substitutions performed.
*/
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches
carbon2-commit: Import and extend GNU's descr-text.el, supporting prefix argument for C-x =
16 years, 6 months
Aidan Kehoe
changeset: 4497:a78d697ccd2c832f5770b564e944a88b4f1f2549
parent: 4493:23ef20edf6ba892a78e7e257a28f4879e31f4095
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Sun May 25 21:11:35 2008 +0200
files: lisp/ChangeLog lisp/descr-text.el lisp/mule/mule-cmds.el lisp/simple.el lisp/syntax.el lisp/unicode.el
description:
Import and extend GNU's descr-text.el, supporting prefix argument for C-x =
2008-05-25 Aidan Kehoe <kehoea(a)parhasard.net>
* descr-text.el: New.
Taken from GNU's GPLV2 version of 2007-02-14, with modifications
for XEmacs support and extensions for Unihan.txt support and
db/dbm caches.
* simple.el (what-cursor-position):
Support an optional prefix argument, as does GNU, calling
#'describe-char to giving more detail on the character at point,
notably from UnicodeData and (in our case, optionally) Unihan.txt.
* syntax.el (syntax-after):
Make this available for the sake of #'describe-char.
* mule/mule-cmds.el (iso-2022-control-alist):
Make this available, for the sake of #'encoded-string-description
and #'describe-char.
* mule/mule-cmds.el (encoded-string-description):
Make this available, for the sake of #'describe-char.
* unicode.el (unicode-error-default-translation-table):
Make this a char table of type generic, not of type char. Makes it
possible to have the relevant logic in #'describe-char reasonably
clear; also, and this is undocumented, makes it much easier to
implement #'frob-unicode-errors-region. I should document this,
and revise #'frob-unicode-errors-region.
diff -r 23ef20edf6ba892a78e7e257a28f4879e31f4095 -r a78d697ccd2c832f5770b564e944a88b4f1f2549 lisp/ChangeLog
--- a/lisp/ChangeLog Wed May 21 21:09:20 2008 +0200
+++ b/lisp/ChangeLog Sun May 25 21:11:35 2008 +0200
@@ -1,3 +1,27 @@ 2008-05-14 Stephen J. Turnbull <stephe
+2008-05-25 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * descr-text.el: New.
+ Taken from GNU's GPLV2 version of 2007-02-14, with modifications
+ for XEmacs support and extensions for Unihan.txt support and
+ db/dbm caches.
+ * simple.el (what-cursor-position):
+ Support an optional prefix argument, as does GNU, calling
+ #'describe-char to giving more detail on the character at point,
+ notably from UnicodeData and (in our case, optionally) Unihan.txt.
+ * syntax.el (syntax-after):
+ Make this available for the sake of #'describe-char.
+ * mule/mule-cmds.el (iso-2022-control-alist):
+ Make this available, for the sake of #'encoded-string-description
+ and #'describe-char.
+ * mule/mule-cmds.el (encoded-string-description):
+ Make this available, for the sake of #'describe-char.
+ * unicode.el (unicode-error-default-translation-table):
+ Make this a char table of type generic, not of type char. Makes it
+ possible to have the relevant logic in #'describe-char reasonably
+ clear; also, and this is undocumented, makes it much easier to
+ implement #'frob-unicode-errors-region. I should document this,
+ and revise #'frob-unicode-errors-region.
+
2008-05-14 Stephen J. Turnbull <stephen(a)xemacs.org>
* subr.el (add-to-list): Fix Aidan's last commit.
diff -r 23ef20edf6ba892a78e7e257a28f4879e31f4095 -r a78d697ccd2c832f5770b564e944a88b4f1f2549 lisp/mule/mule-cmds.el
--- a/lisp/mule/mule-cmds.el Wed May 21 21:09:20 2008 +0200
+++ b/lisp/mule/mule-cmds.el Sun May 25 21:11:35 2008 +0200
@@ -901,34 +901,24 @@ It can be retrieved with `(get-char-code
;; Pretty description of encoded string
;; Alist of ISO 2022 control code vs the corresponding mnemonic string.
-;; (defvar iso-2022-control-alist
-;; '((?\x1b . "ESC")
-;; (?\x0e . "SO")
-;; (?\x0f . "SI")
-;; (?\x8e . "SS2")
-;; (?\x8f . "SS3")
-;; (?\x9b . "CSI")))
-
-;; (defun encoded-string-description (str coding-system)
-;; "Return a pretty description of STR that is encoded by CODING-SYSTEM."
-;; (setq str (string-as-unibyte str))
-;; (let ((char (aref str 0))
-;; desc)
-;; (when (< char 128)
-;; (setq desc (or (cdr (assq char iso-2022-control-alist))
-;; (char-to-string char)))
-;; (let ((i 1)
-;; (len (length str)))
-;; (while (< i len)
-;; (setq char (aref str i))
-;; (if (>= char 128)
-;; (setq desc nil i len)
-;; (setq desc (concat desc " "
-;; (or (cdr (assq char iso-2022-control-alist))
-;; (char-to-string char)))
-;; i (1+ i))))))
-;; (or desc
-;; (mapconcat (function (lambda (x) (format "0x%02x" x))) str " "))))
+(defvar iso-2022-control-alist
+ '((?\x1b . "ESC")
+ (?\x0e . "SO")
+ (?\x0f . "SI")
+ (?\x8e . "SS2")
+ (?\x8f . "SS3")
+ (?\x9b . "CSI")))
+
+(defun encoded-string-description (str coding-system)
+ "Return a pretty description of STR that is encoded by CODING-SYSTEM."
+; (setq str (string-as-unibyte str))
+ (mapconcat
+ (if (and coding-system (eq (coding-system-type coding-system) 'iso2022))
+ ;; Try to get a pretty description for ISO 2022 escape sequences.
+ (function (lambda (x) (or (cdr (assq x iso-2022-control-alist))
+ (format "#x%02X" x))))
+ (function (lambda (x) (format "#x%02X" x))))
+ str " "))
;; (defun encode-coding-char (char coding-system)
;; "Encode CHAR by CODING-SYSTEM and return the resulting string.
diff -r 23ef20edf6ba892a78e7e257a28f4879e31f4095 -r a78d697ccd2c832f5770b564e944a88b4f1f2549 lisp/simple.el
--- a/lisp/simple.el Wed May 21 21:09:20 2008 +0200
+++ b/lisp/simple.el Sun May 25 21:11:35 2008 +0200
@@ -782,13 +782,16 @@ See also `line-number'."
done)))
(- (buffer-size) (forward-line (buffer-size)))))))
-(defun what-cursor-position ()
+(defun what-cursor-position (&optional detail)
"Print info on cursor position (on screen and within buffer).
Also describe the character after point, giving its UCS code point and Mule
charset and codes; for ASCII characters, give its code in octal, decimal and
-hex."
- ;; XEmacs change
- (interactive "_")
+hex.
+
+With prefix argument, show extended details about the character in a
+separate buffer. See also the command `describe-char'."
+ ;; XEmacs change "_"
+ (interactive "_P")
(let* ((char (char-after (point))) ; XEmacs
(beg (point-min))
(end (point-max))
@@ -813,6 +816,8 @@ hex."
(if (= pos end)
(message "point=%d of %d(%d%%)%s column %d %s"
pos total percent narrowed-details col hscroll)
+ (if detail
+ (describe-char (point)))
;; XEmacs: don't use single-key-description, treat non-ASCII
;; characters differently.
(if (< char ?\x80)
diff -r 23ef20edf6ba892a78e7e257a28f4879e31f4095 -r a78d697ccd2c832f5770b564e944a88b4f1f2549 lisp/syntax.el
--- a/lisp/syntax.el Wed May 21 21:09:20 2008 +0200
+++ b/lisp/syntax.el Sun May 25 21:11:35 2008 +0200
@@ -38,6 +38,14 @@
"Return a new syntax table.
It inherits all characters from the standard syntax table."
(make-char-table 'syntax))
+
+(defun syntax-after (pos)
+ "Return the raw syntax of the char after POS.
+If POS is outside the buffer's accessible portion, return nil."
+ (unless (or (< pos (point-min)) (>= pos (point-max)))
+ (let ((st (if lookup-syntax-properties
+ (get-char-property pos 'syntax-table))))
+ (char-syntax (char-after pos) (or st (syntax-table))))))
(defun simple-set-syntax-entry (char spec table)
(put-char-table char spec table))
diff -r 23ef20edf6ba892a78e7e257a28f4879e31f4095 -r a78d697ccd2c832f5770b564e944a88b4f1f2549 lisp/unicode.el
--- a/lisp/unicode.el Wed May 21 21:09:20 2008 +0200
+++ b/lisp/unicode.el Sun May 25 21:11:35 2008 +0200
@@ -506,7 +506,7 @@ The second argument must be 'ucs, the th
;; point). Make them available to user code.
(defvar unicode-error-default-translation-table
(loop
- with char-table = (make-char-table 'char)
+ with char-table = (make-char-table 'generic)
for i from ?\x00 to ?\xFF
initially (unless (featurep 'mule) (return))
do
diff -r 23ef20edf6ba892a78e7e257a28f4879e31f4095 -r a78d697ccd2c832f5770b564e944a88b4f1f2549 lisp/descr-text.el
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/descr-text.el Sun May 25 21:11:35 2008 +0200
@@ -0,0 +1,1284 @@
+;;; descr-text.el --- describe text mode
+
+;; Copyright (C) 1994, 1995, 1996, 2001, 2002, 2003, 2004,
+;; 2005, 2006, 2007 Free Software Foundation, Inc.
+
+;; Author: Boris Goldowsky <boris(a)gnu.org>
+;; Maintainer: FSF
+;; Keywords: faces, i18n, Unicode, multilingual
+
+;; This file is part of XEmacs.
+
+;; XEmacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; XEmacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with XEmacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Describe-Text Mode.
+
+;;; Code:
+
+(eval-when-compile (require 'wid-edit))
+
+;;; Describe-Text Utilities.
+
+(defun describe-text-widget (widget)
+ "Insert text to describe WIDGET in the current buffer."
+ ;; XEmacs change; use the widget function.
+ (widget-create 'push-button
+:notify `(lambda (&rest ignore)
+ (widget-browse ',widget))
+:help-echo
+ "mouse-2, RET: browse this widget"
+ (symbol-name (if (symbolp widget)
+ widget
+ (car widget))))
+ (widget-insert " ")
+ (widget-create 'info-link
+:tag "Widget help"
+:help-echo
+ "Read widget documentation"
+ "(widget)Top"))
+
+(defun describe-text-sexp (sexp)
+ "Insert a short description of SEXP in the current buffer."
+ ;; XEmacs change; use the widget functions.
+ (let ((pp (condition-case signal
+ (pp-to-string sexp)
+ (error (prin1-to-string signal)))))
+ (when (string-match "\n\\'" pp)
+ (setq pp (substring pp 0 (1- (length pp)))))
+ (if (cond ((string-match "\n" pp)
+ nil)
+ ((> (length pp) (- (window-width) (current-column)))
+ nil)
+ (t t))
+ (widget-insert pp)
+ (widget-create 'push-button
+:notify `(lambda (&rest ignore)
+ (with-output-to-temp-buffer
+ "*Pp Eval Output*"
+ (princ ',pp)))
+:help-echo
+ "mouse-2, RET: pretty print value in another buffer"
+ "[Show]"))))
+
+(defun describe-property-list (properties)
+ "Insert a description of PROPERTIES in the current buffer.
+PROPERTIES should be a list of overlay or text properties.
+The `category', `face' and `font-lock-face' properties are made
+into help buttons that call `describe-text-category' or
+`describe-face' when pushed."
+ ;; Sort the properties by the size of their value.
+ (dolist (elt (sort (let (ret)
+ (while properties
+ (push (list (pop properties) (pop properties)) ret))
+ ret)
+ (lambda (a b) (string< (prin1-to-string (nth 0 a) t)
+ (prin1-to-string (nth 0 b) t)))))
+ (let ((key (nth 0 elt))
+ (value (nth 1 elt)))
+ ;; XEmacs change; use #'widget-insert, #'widget-create
+ (widget-insert (propertize (format " %-20s " key)
+ 'face 'hyper-apropos-heading))
+ (cond ((eq key 'category)
+ (widget-create
+ 'push-button
+ :notify `(lambda (&rest ignore)
+ (describe-text-category ',value))
+ :help-echo "mouse-2, RET: describe this category"
+ (symbol-name value)))
+ ((memq key '(face font-lock-face mouse-face))
+ (widget-create
+ 'push-button
+:notify (lexical-let
+ ((value-name (symbol-name value)))
+ (lambda (&rest ignore)
+ (hyper-describe-face (intern value-name))))
+ :help-echo "mouse-2, RET: describe this face"
+ (format "%S" value)))
+ ((widgetp value)
+ (describe-text-widget value))
+ (t
+ (describe-text-sexp value))))
+ (insert "\n")))
+
+;;; Describe-Text Commands.
+
+(defun describe-text-category (category)
+ "Describe a text property category."
+ (interactive "SCategory: ")
+ ; (help-setup-xref (list #'describe-text-category category) (interactive-p))
+ (save-excursion
+ (with-output-to-temp-buffer "*Help*"
+ (set-buffer standard-output)
+ (insert "Category " (format "%S" category) ":\n\n")
+ (describe-property-list (symbol-plist category))
+ (goto-char (point-min)))))
+
+;;;###autoload
+(defun describe-text-properties (pos &optional output-buffer)
+ "Describe widgets, buttons, overlays and text properties at POS.
+Interactively, describe them for the character after point.
+If optional second argument OUTPUT-BUFFER is non-nil,
+insert the output into that buffer, and don't initialize or clear it
+otherwise."
+ (interactive "d")
+ (if (>= pos (point-max))
+ (error "No character follows specified position"))
+ (if output-buffer
+ (describe-text-properties-1 pos output-buffer)
+ (if (not (or (text-properties-at pos) ; (overlays-at pos)))
+ ;; XEmacs change.
+ (extents-at pos)))
+ (message "This is plain text.")
+ (let ((buffer (current-buffer))
+ (target-buffer "*Help*"))
+ (when (eq buffer (get-buffer target-buffer))
+ (setq target-buffer "*Help*<2>"))
+ (save-excursion
+ (with-output-to-temp-buffer target-buffer
+ (set-buffer standard-output)
+ (setq output-buffer (current-buffer))
+ (insert "Text content at position " (format "%d" pos) ":\n\n")
+ (with-current-buffer buffer
+ (describe-text-properties-1 pos output-buffer))
+ (goto-char (point-min))))))))
+
+(defun describe-text-properties-1 (pos output-buffer)
+ (let* ((properties (text-properties-at pos))
+ ;; XEmacs change; extents, not overlays.
+ (extents (extents-at pos))
+ (wid-field (get-char-property pos 'field))
+ (wid-button (get-char-property pos 'button))
+ (wid-doc (get-char-property pos 'widget-doc))
+ ;; If button.el is not loaded, we have no buttons in the text.
+ ;; XEmacs change; use the #'and-fboundp, #'declare-fboundp macros.
+ (button (and-fboundp 'button-at (button-at pos)))
+ (button-type (and button
+ (declare-fboundp (button-type button))))
+ (button-label (and button
+ (declare-fboundp (button-label button))))
+ (widget (or wid-field wid-button wid-doc)))
+ (with-current-buffer output-buffer
+ ;; Widgets
+ (when (widgetp widget)
+ (newline)
+ (insert (cond (wid-field "This is an editable text area")
+ (wid-button "This is an active area")
+ (wid-doc "This is documentation text")))
+ (insert " of a ")
+ (describe-text-widget widget)
+ (insert ".\n\n"))
+ ;; Buttons
+ (when (and button (not (widgetp wid-button)))
+ (newline)
+ (insert "Here is a `" (format "%S" button-type)
+ "' button labeled `" button-label "'.\n\n"))
+ ;; Overlays
+ (when extents
+ (newline)
+ (if (eq (length extents) 1)
+ (insert "There is an extent here:\n")
+ (insert "There are " (format "%d" (length extents))
+ " overlays here:\n"))
+ (dolist (extent extents)
+ (insert " From " (format "%d" (extent-start-position extent))
+ " to " (format "%d" (extent-end-position extent)) "\n")
+ (describe-property-list (extent-properties extent)))
+ (insert "\n"))
+ ;; Text properties
+ (when properties
+ (newline)
+ (insert "There are text properties here:\n")
+ (describe-property-list properties)))))
+
+(defcustom describe-char-unicodedata-file
+ ;; XEmacs change; initialise this by default, using Perl.
+ (let ((have-perl
+ (member-if
+ #'(lambda (path)
+ (file-exists-p (format "%s%cperl" path directory-sep-char)))
+ exec-path))
+ installprivlib res)
+ (when have-perl
+ (setq installprivlib
+ (with-string-as-buffer-contents ""
+ (shell-command "perl -V:installprivlib" t)
+ ;; 1+ because buffer offsets start at one.
+ (delete-region 1 (1+ (length "installprivlib='")))
+ ;; Delete the final newline, semicolon and quotation mark.
+ (delete-region (- (point-max) 3) (point-max))))
+ (cond
+ ((file-exists-p
+ (setq res
+ (format "%s%cunicore%cUnicodeData.txt"
+ installprivlib directory-sep-char directory-sep-char))))
+ ((file-exists-p
+ (setq res
+ (format "%s%cunicode%cUnicodeData.txt"
+ installprivlib directory-sep-char directory-sep-char)))))
+ res))
+ "Location of Unicode data file.
+This is the UnicodeData.txt file from the Unicode Consortium, used for
+diagnostics. If it is non-nil `describe-char' will print data
+looked up from it. This facility is mostly of use to people doing
+multilingual development.
+
+This is a fairly large file, typically installed with Perl.
+At the time of writing it is at the URL
+`http://www.unicode.org/Public/UNIDATA/UnicodeData.txt'.
+
+It is possible to build a DBM or Berkeley index cache for this file, so that
+it is not necessary to parse the whole file at run time. See
+`unidata-initialize-unicodedata-database'.
+
+See also `describe-char-unihan-file' for the complementary file describing
+East Asian Han characters and their associated information."
+
+:group 'mule
+:type '(choice (const :tag "None" nil)
+ file))
+
+;; XEmacs additions, from here until `describe-char-unicode-data'
+(defcustom describe-char-use-cache t
+ "Whether `describe-char' should use a DBM or Berkeley DB cache.
+This speeds up navigation of `describe-char-unicodedata-file', and makes
+navigation of `describe-char-unihan-file' reasonable."
+:group 'mule
+:type '(choice (const :tag "None" nil)
+ file))
+
+(defcustom describe-char-unihan-file nil
+ "Location of Unihan file.
+This the Unihan.txt file from the Unicode Consortium, used for diagnostics.
+If it is non-nil `describe-char' can print data looked up from it. This
+facility is of use to people doing multilingual development, to those
+learning Chinese or Japanese, and to a lesser extent to those learning
+Korean or Vietnamese.
+
+This is large file, typically not installed with the operating system. At
+the time of writing it is at the URL
+`http://www.unicode.org/Public/UNIDATA/UniHan.txt'.
+
+In contrast with `describe-char-unicodedata-file', `describe-char' will not
+load this entire file and parse it if it is available. It requires a
+pre-initialized cache; see `unidata-initialize-unihan-database'. "
+:group 'mule
+:type '(choice (const :tag "None" nil)
+ file))
+
+;; XEmacs addition
+(defvar unidata-database-format
+ (or (and (featurep 'dbm) 'dbm)
+ (and (featurep 'berkeley-db) 'berkeley-db))
+ "The DB format to use for the `describe-char' cache, or nil if no cache.")
+
+(defvar describe-char-unihan-field-descriptions
+ #s(hash-table test equal data
+ ("kAccountingNumeric"
+ "Value as an an accounting numeral"
+ "kBigFive"
+ "Big Five mapping (excluding ETEN, etc. extensions)"
+ "kCCCII"
+ "Hex CCCII code, for libraries in the Republic of China"
+ "kCNS1986"
+ "Hex CNS 11643-1986 mapping, for the Republic of China"
+ "kCNS1992"
+ "Hex CNS 11643-1986 mapping, for the Republic of China"
+ "kCangjie"
+ "Cangjie input code for the character"
+ "kCantonese"
+ "Cantonese pronunciation, using jyutping"
+ "kCheungBauer"
+ "Radical-stroke index, cangjie input code, \
+and Cantonese readings"
+ "kCheungBauerIndex"
+ "Index of information about this character \
+in Cheung & Bauer, 2002"
+ "kCihaiT"
+ "Lookup information for this character in the \
+Cihai dictionary ISBN 962-231-005-2."
+ "kCompatibilityVariant"
+ "Compatibility decomposition for this character"
+ "kCowles"
+ "Lookup information for this character in the \
+Cowles dictionary ISBN 962-231-005-2."
+ "kDaeJaweon"
+ "Lookup information for this character in the \
+Dae Jaweon (Korean) dictionary, 1988"
+ "kDefinition"
+ "Definition for this character in modern written Chinese"
+ "kEACC"
+ "The EACC (= CCCII, as used by the \
+US library of congress) code for this character"
+ "kFenn"
+ "Frequency information for this character from \
+Fenn's Chinese-English dictionary, 1979"
+ "kFennIndex"
+ "Lookup information for this character in \
+Fenn's Chinese-English dictionary, 1979"
+ "kFourCornerCode"
+ "Four-corner lookup code for this character"
+ "kFrequency"
+ "Frequency information from traditional \
+Chinese USENET postings"
+ "kGB0" "GB 2312-80 mapping, ku/ten"
+ "kGB1" "GB 12345-90 mapping, ku/ten"
+ "kGB3" "GB 7589-87 mapping, ku/ten"
+ "kGB5" "GB 7590-87 mapping, ku/ten"
+ "kGB7" "GB 8565-89 mapping, ku/ten"
+ ;; Identical to the previous information?!
+ "kGB8" "GB 8565-89 mapping, ku/ten"
+ "kGSR"
+ "Lookup information for this character in \
+Karlgern's Grammata Serica Recensa"
+ "kGradeLevel"
+ "The first grade in the HK school system \
+where knowledge of this character is expected"
+ "kHDZRadBreak" "Whether Hanyu Da Zidian has a radical break \
+beginning with this character"
+ "kHKGlyph" "Lookup information for this character in the HK \
+glyph reference, ISBN 962-949-040-4"
+ "kHKSCS" "Mapping to the HK Supplementary Character Set for \
+Big Five."
+ "kHanYu" "Character lookup information for Hanyu Da Zidian, \
+`Great Chinese Character Dictionary'"
+ "kHangul" "Korean pronunciation"
+ "kHanyuPinlu" "Pronunciation and frequency info, from Xiandai\
+ Hanyu Pinlu Cidian"
+ "kIBMJapan" "IBM Japanese mapping"
+ "kIICore" "Is this character in the core East Asian \
+ideograph set from the IRG?"
+ "kIRGDaeJaweon" "Lookup information for this character \
+in the Dae Jaweon (Korean) dictionary"
+ "kIRGDaiKanwaZiten" "Lookup information for this character \
+in the Morohashi (Japanese) dictionary"
+ "kIRGHanyuDaZidian" "Lookup information for this character \
+in the Hanyu Da Zidian (Chinese) dictionary"
+ "kIRGKangXi" "Lookup information for this character \
+in the KangXi dictionary"
+ "kIRG_GSource" "PRC character source information"
+ "kIRG_HSource" "Hong Kong character source information"
+ "kIRG_JSource" "Japanese character source information"
+ "kIRG_KPSource" "Korean character source information"
+ "kIRG_KSource" "Republic of Korean character source\
+ information"
+ "kIRG_TSource" "Republic of China character source \
+information"
+ "kIRG_USource" "Unicode (standards body) source information"
+ "kIRG_VSource" "Vietnamese character source information"
+ "kJIS0213" "JIS X 0213-2000 mapping in min,ku,ten form"
+ "kJapaneseKun" "Native Japanese pronunciation"
+ "kJapaneseOn" "Sino-Japanese pronunciation"
+ "kJis0" "JIS X 0208-1990 mapping in ku/ten form"
+ "kJis1" "JIS X 0212-1990 mapping in ku/ten form"
+ "kKPS0" "KPS 9566-97 mapping in hexadecimal"
+ "kKPS1" "KPS 10721-2000 mapping in hexadecimal"
+ "kKSC0" "KS X 1001:1992 (KS C 5601-1989) mapping \
+in ku/ten form"
+ "kKSC1" "KS X 1002:1991 (KS C 5657-1991) mapping \
+in ku/ten form"
+ "kKangXi" "Lookup information for this character \
+in the KangXi (Chinese) dictionary"
+ "kKarlgren" "Lookup information for this character \
+in Karlgren's dictionary, 1974"
+ "kKorean" "Pronunciation in Korean"
+ "kLau" "Lookup information for this character \
+in Lau's Cantonese-English dictionary"
+ "kMainlandTelegraph" "PRC telegraph code"
+ "kMandarin" "Mandarin pronunciation in Pinyin"
+ "kMatthews" "Lookup information for Robert Mathews' \
+Chinese-English dictionary"
+ "kMeyerWempe" "Lookup information for Bernard Meyer and \
+Theodore Wempe's dictionary"
+ ;; Identical to kIRGDaiKanwaZiten?!?
+ "kMorohashi" "Lookup information for this character \
+in the Morohashi (Japanese) dictionary"
+ "kNelson" "Lookup information for this character in \
+Nelson's Japanese-English dictionary"
+ "kOtherNumeric" "Esoteric numeric value"
+ "kPhonetic" "Phonetic index data"
+ "kPrimaryNumeric" "Standard numeric value"
+ "kPseudoGB1" "Fake GB 12345-90, for the purposes of \
+Unicode inclusion"
+ "kRSAdobe_Japan1_6" "Adobe-Japan1-6 information for \
+the character"
+ "kRSJapanese" "Radical/stroke count for Japanese"
+ "kRSKanWa" "Morohashi radical/stroke count"
+ "kRSKangXi" "KangXi radical/stroke count"
+ "kRSKorean" "Korean radical/stroke count"
+ "kRSUnicode" "Unicode radical/stroke count"
+ "kSBGY" "Lookup information for this character in the Song \
+Ben Guang Yun Chinese dictionary"
+ "kSemanticVariant" "Semantic variant character"
+ "kSimplifiedVariant" "Simplified variant character"
+ "kSpecializedSemanticVariant" "Specialized semantic variant"
+ "kTaiwanTelegraph" "Taiwanese telegraph code"
+ "kTang" "Tang dynasty pronunciation"
+ "kTotalStrokes" "Total number of strokes"
+ "kTraditionalVariant" "Traditional variant character"
+ "kVietnamese" "Vietnamese pronunciation"
+ "kXerox" "Xerox code"
+ "kZVariant" "Z-variant code(s)"))
+ "A map from symbolic Unihan field names to English-language descriptions.")
+
+(defun unidata-generate-database-file-name (unidata-file-name size
+ database-format)
+ "Return a filename suitable for storing the cache for UNIDATA-FILE-NAME."
+ (expand-file-name
+ (format "~%c.xemacs%c%s-%s" directory-sep-char directory-sep-char
+ (md5 (format "%s-%d" unidata-file-name size))
+ database-format)))
+
+(defun unidata-initialize-unicodedata-database (unidata-file-name)
+ "Init the berkeley or gdbm lookup table for UNIDATA-FILE-NAME.
+
+The table is a (non-SQL) database with information on the file offset of
+each Unicode code point described in UNIDATA-FILE-NAME. In the normal
+course of events UNIDATA-FILE-NAME is the value of
+`unidata-default-file-name', which see. "
+ (check-argument-type #'file-readable-p unidata-file-name)
+ (unless unidata-database-format
+ (error 'unimplemented "No (non-SQL) DB support available"))
+ (let* ((database-format unidata-database-format)
+ (size (eighth (file-attributes unidata-file-name)))
+ (database-file-name
+ (unidata-generate-database-file-name unidata-file-name
+ size database-format))
+ (database-handle (open-database database-file-name database-format
+ nil "rw+" #o644 'no-conversion-unix))
+ (coding-system-for-read 'no-conversion-unix)
+ (buffer-size 32768)
+ (offset-start 0)
+ (offset-end buffer-size)
+ (range-information (make-range-table 'start-closed-end-closed))
+ (range-staging (make-hash-table :test 'equal))
+ (message "Initializing UnicodeData database cache: ")
+ (loop-count 1)
+ range-startinfo)
+ (with-temp-buffer
+ (progress-feedback-with-label 'describe-char-unicodedata-file
+ "%s" 0 message)
+ (while (progn
+ (delete-region (point-min) (point-max))
+ (insert-file-contents unidata-file-name nil
+ offset-start offset-end)
+ ;; If we've reached the end of the data, pass nil back to
+ ;; the while loop test.
+ (not (= (point-min) (point-max))))
+
+ (when (= buffer-size (- (point-max) (point-min)))
+ ;; If we're in the body of the file, and there's a trailing
+ ;; incomplete end-line, delete it, and adjust offset-end
+ ;; appropriately.
+ (goto-char (point-max))
+ (search-backward "\n")
+ (forward-char)
+ (delete-region (point) (point-max))
+ (setq offset-end (+ offset-start (- (point) (point-min)))))
+
+ (progress-feedback-with-label 'describe-char-unicodedata-file
+ "%s" (truncate
+ (* (/ offset-start size) 100))
+ (concat message
+ (make-string
+ (mod loop-count 39) ?.)))
+ (incf loop-count)
+ (goto-char (point-min))
+ (while (re-search-forward
+ #r"^\([0-9A-F]\{4,6\}\);\([^;]*\);.*$" nil t)
+ (cond
+ ((and (> (- (match-end 2) (match-beginning 2)) 7)
+ (equal (substring (match-string 2) -7)
+ " First>"))
+ ;; Start of a range. Save the start info in range-staging.
+ (puthash (substring (match-string 2) 0 -7)
+ (list (string-to-int (match-string 1) 16)
+ (+ offset-start (1- (match-beginning 0))))
+ range-staging))
+ ((and (> (- (match-end 2) (match-beginning 2)) 7)
+ (equal (substring (match-string 2) -6)
+ " Last>"))
+ ;; End of a range. Combine with the start info, save it to the
+ ;; range-information range table.
+ (setq range-startinfo
+ (gethash (substring (match-string 2) 0 -6) range-staging))
+ (assert range-startinfo nil
+ "Unexpected order for range information.")
+ (put-range-table
+ (first range-startinfo)
+ (string-to-int (match-string 1) 16)
+ (list (second range-startinfo)
+ (+ offset-start (1- (match-end 0))))
+ range-information)
+ (remhash (substring (match-string 2) 0 -6) range-staging))
+ (t
+ ;; Normal character. Save the associated information in the
+ ;; database directly.
+ (put-database (match-string 1)
+ (format "(%d %d)"
+ (+ offset-start (1- (match-beginning 0)))
+ (+ offset-start (1- (match-end 0))))
+ database-handle))))
+ (goto-char (point-min))
+ (setq offset-start offset-end
+ offset-end (+ buffer-size offset-end))))
+ ;; Save the range information as such in the database.
+ (put-database "range-information"
+ (let ((print-readably t))
+ (prin1-to-string range-information))
+ database-handle)
+ (close-database database-handle)
+ (progress-feedback-with-label 'describe-char-unicodedata-file
+ "%s" 100 message)
+ database-file-name))
+
+(defun unidata-initialize-unihan-database (unihan-file-name)
+ "Init the berkeley or gdbm lookup table for UNIHAN-FILE-NAME.
+
+The table is a (non-SQL) database with information on the file offset of
+each Unicode code point described in Unicode.org's Han character repository.
+Unihan.txt (see `describe-char-unihan-file', the usual argument to this
+function) is very large, and manipulating it directly can be tedious and
+slow, so creating this cache makes it reasonable to display Unihan info in
+the output of \\[universal-argument] \\[what-cursor-position] . "
+ (check-argument-type #'file-readable-p unihan-file-name)
+ (unless unidata-database-format
+ (error 'unimplemented "No (non-SQL) DB support available"))
+ (let* ((database-format unidata-database-format)
+ (size (eighth (file-attributes unihan-file-name)))
+ (database-file-name
+ (unidata-generate-database-file-name unihan-file-name
+ size database-format))
+ (database-handle (open-database database-file-name database-format
+ nil "rw+" #o644 'no-conversion-unix))
+ (coding-system-for-read 'no-conversion-unix)
+ (buffer-size 65536)
+ (offset-start 0)
+ (offset-end buffer-size)
+ (message "Initializing Unihan database cache: ")
+ (loop-count 1)
+ trailing-unicode leading-unicode character-start character-end)
+ (with-temp-buffer
+ (progress-feedback-with-label 'describe-char-unihan-file
+ "%s" 0 message)
+ (while (progn
+ (delete-region (point-min) (point-max))
+ (insert-file-contents unihan-file-name nil
+ offset-start offset-end)
+ ;; If we've reached the end of the data, return nil to the
+ ;; while.
+ (not (= (point-min) (point-max))))
+
+ (incf loop-count)
+ (progress-feedback-with-label 'describe-char-unihan-file
+ "%s" (truncate
+ (* (/ offset-start size) 100))
+ (concat message
+ (make-string
+ (mod loop-count 44) ?.)))
+ (block 'dealing-with-chars
+ (when (= buffer-size (- (point-max) (point-min)))
+ ;; If we're in the body of the file, we need to delete the
+ ;; character info for the last character, and set offset-end
+ ;; appropriately. Otherwise, we may not be able to pick where
+ ;; the actual description of a character ends and
+ ;; begins.
+ ;;
+ ;; This breaks if any single Unihan character description is
+ ;; greater than the buffer size in length.
+ (goto-char (point-max))
+ (beginning-of-line)
+
+ (when (< (- (point-max) (point)) (eval-when-compile
+ (length "U+ABCDEF\t")))
+ ;; If the character ID of the last line may have been cut off,
+ ;; we need to delete all of that line here.
+ (delete-region (point) (point-max))
+ (forward-line -1))
+
+ (when (looking-at "^\\(U\\+[0-9A-F]\\{4,6\\}\\)\t")
+ (setq trailing-unicode (match-string 1)
+ trailing-unicode
+ (format "^%s\t" (regexp-quote trailing-unicode)))
+
+ (end-of-line)
+
+ ;; Go back until we hit a line that doesn't start with this
+ ;; character info.
+ (while (re-search-backward trailing-unicode nil t))
+
+ ;; The re-search-backward failed, so point is still at the end
+ ;; of the last match. Move to its beginning.
+ (beginning-of-line)
+ (delete-region (point) (point-max))
+ (setq offset-end (+ offset-start (- (point) (point-min))))))
+ (goto-char (point-min))
+ (while t
+ (when (= (point) (point-max))
+ ;; We're at the end of this part of the file.
+ (return-from 'dealing-with-chars))
+
+ (unless (re-search-forward "^\\(U\\+[0-9A-F]\\{4,6\\}\\)\t"
+ nil t)
+ ;; We're probably in the comments at the start of the file. No
+ ;; need to look for character info.
+ (return-from 'dealing-with-chars))
+
+ ;; Store where the character started.
+ (beginning-of-line)
+ (setq character-start (point))
+
+ (setq leading-unicode
+ (format "^%s\t" (regexp-quote (match-string 1))))
+
+ ;; Loop until we get past this entry.
+ (while (re-search-forward leading-unicode nil t))
+
+ ;; Now, store the information.
+ (setq leading-unicode
+ (string-to-number (substring leading-unicode 3) 16)
+ leading-unicode (format "%04X" leading-unicode)
+ character-end (prog2 (end-of-line) (point)))
+ (put-database leading-unicode
+ (format "(%d %d)"
+ (+ offset-start (1- character-start))
+ (+ offset-start (1- character-end)))
+ database-handle)
+ (forward-line)))
+ (setq offset-start offset-end
+ offset-end (+ buffer-size offset-end))))
+ (close-database database-handle)
+ (progress-feedback-with-label 'describe-char-unihan-file
+ "%s" 100
+ message)
+ database-file-name))
+;; End XEmacs additions.
+
+(defun describe-char-unicode-data (char)
+ "Return a list of Unicode data for unicode CHAR.
+Each element is a list of a property description and the property value.
+The list is null if CHAR isn't found in `describe-char-unicodedata-file'."
+ (when describe-char-unicodedata-file
+ (unless (file-exists-p describe-char-unicodedata-file)
+ (error 'file-error
+ "`unicodedata-file' %s not found" describe-char-unicodedata-file))
+ ;; XEmacs change; accept a character argument, use the cache if
+ ;; appropriate.
+ (when (characterp char)
+ (setq char (encode-char char 'ucs)))
+ (with-temp-buffer
+ (if describe-char-use-cache
+ ;; Use the database info.
+ (let ((database-handle (open-database
+ (unidata-generate-database-file-name
+ describe-char-unicodedata-file
+ (eighth (file-attributes
+ describe-char-unicodedata-file))
+ unidata-database-format)
+ unidata-database-format
+ nil "r"
+ #o644 'no-conversion-unix))
+ (coding-system-for-read 'no-conversion-unix)
+ key lookup)
+ (unless database-handle
+ (error 'io-error "Could not open %s as a %s database"
+ (unidata-generate-database-file-name
+ describe-char-unicodedata-file
+ (eighth (file-attributes
+ describe-char-unicodedata-file))
+ unidata-database-format)
+ unidata-database-format))
+ (setq key (format "%04X" char)
+ lookup (get-database key database-handle))
+ (if lookup
+ ;; Okay, we have information on that character in particular.
+ (progn (setq lookup (read lookup))
+ (insert-file-contents describe-char-unicodedata-file nil
+ (first lookup) (second lookup)))
+ ;; No information on that character in particular. Do we have
+ ;; range information? If so, load and check for our desired
+ ;; character.
+ (setq lookup (get-database "range-information" database-handle)
+ lookup (if lookup (read lookup))
+ lookup (if lookup (get-range-table char lookup)))
+ (when lookup
+ (insert-file-contents describe-char-unicodedata-file nil
+ (first lookup) (second lookup))))
+ (close-database database-handle))
+
+ ;; Otherwise, insert the whole file (the FSF approach).
+ (set-buffer (get-buffer-create " *Unicode Data*"))
+ (when (zerop (buffer-size))
+ ;; Don't use -literally in case of DOS line endings.
+ (insert-file-contents describe-char-unicodedata-file)))
+
+ (goto-char (point-min))
+ (let ((hex (format "%04X" char))
+ found first last unihan-match unihan-info
+ (unihan-database-handle
+ (and describe-char-unihan-file
+ (open-database (unidata-generate-database-file-name
+ describe-char-unihan-file
+ (eighth (file-attributes
+ describe-char-unihan-file))
+ unidata-database-format)
+ unidata-database-format
+ nil "r" #o644 'no-conversion-unix)))
+ (coding-system-for-read 'no-conversion-unix))
+ (if (re-search-forward (concat "^" hex) nil t)
+ (setq found t)
+ ;; It's not listed explicitly. Look for ranges, e.g. CJK
+ ;; ideographs, and check whether it's in one of them.
+ (while (and (re-search-forward "^\\([^;]+\\);[^;]+First>;" nil t)
+ (>= char (setq first
+ (string-to-number (match-string 1) 16)))
+ (progn
+ (forward-line 1)
+ (looking-at "^\\([^;]+\\);[^;]+Last>;")
+ (> char
+ (setq last
+ (string-to-number (match-string 1) 16))))))
+ (if (and first (>= char first)
+ last (<= char last))
+ (setq found t)))
+ (if found
+ (let ((fields (mapcar (lambda (elt)
+ (if (> (length elt) 0)
+ elt))
+ (cdr (split-string
+ (buffer-substring
+ (line-beginning-position)
+ (line-end-position))
+ ";")))))
+ ;; The length depends on whether the last field was empty.
+ (unless (or (= 13 (length fields))
+ (= 14 (length fields)))
+ (error 'invalid-argument
+ "Invalid contents in %s" describe-char-unicodedata-file))
+ ;; The field names and values lists are slightly
+ ;; modified from Mule-UCS unidata.el.
+ (apply #'list
+ (list "Name" (let ((name (nth 0 fields)))
+ ;; Check for <..., First>, <..., Last>
+ (if (string-match "\\`\\(<[^,]+\\)," name)
+ (concat (match-string 1 name) ">")
+ name)))
+ (list "Category"
+ (cdr (assoc
+ (nth 1 fields)
+ '(("Lu" . "uppercase letter")
+ ("Ll" . "lowercase letter")
+ ("Lt" . "titlecase letter")
+ ("Mn" . "non-spacing mark")
+ ("Mc" . "spacing-combining mark")
+ ("Me" . "enclosing mark")
+ ("Nd" . "decimal digit")
+ ("Nl" . "letter number")
+ ("No" . "other number")
+ ("Zs" . "space separator")
+ ("Zl" . "line separator")
+ ("Zp" . "paragraph separator")
+ ("Cc" . "other control")
+ ("Cf" . "other format")
+ ("Cs" . "surrogate")
+ ("Co" . "private use")
+ ("Cn" . "not assigned")
+ ("Lm" . "modifier letter")
+ ("Lo" . "other letter")
+ ("Pc" . "connector punctuation")
+ ("Pd" . "dash punctuation")
+ ("Ps" . "open punctuation")
+ ("Pe" . "close punctuation")
+ ("Pi" . "initial-quotation punctuation")
+ ("Pf" . "final-quotation punctuation")
+ ("Po" . "other punctuation")
+ ("Sm" . "math symbol")
+ ("Sc" . "currency symbol")
+ ("Sk" . "modifier symbol")
+ ("So" . "other symbol")))))
+ (list "Combining class"
+ (cdr (assoc
+ (string-to-number (nth 2 fields))
+ '((0 . "Spacing")
+ (1 . "Overlays and interior")
+ (7 . "Nuktas")
+ (8 . "Hiragana/Katakana voicing marks")
+ (9 . "Viramas")
+ (10 . "Start of fixed position classes")
+ (199 . "End of fixed position classes")
+ (200 . "Below left attached")
+ (202 . "Below attached")
+ (204 . "Below right attached")
+ (208 . "Left attached (reordrant around \
+single base character)")
+ (210 . "Right attached")
+ (212 . "Above left attached")
+ (214 . "Above attached")
+ (216 . "Above right attached")
+ (218 . "Below left")
+ (220 . "Below")
+ (222 . "Below right")
+ (224 . "Left (reordrant around single base \
+character)")
+ (226 . "Right")
+ (228 . "Above left")
+ (230 . "Above")
+ (232 . "Above right")
+ (233 . "Double below")
+ (234 . "Double above")
+ (240 . "Below (iota subscript)")))))
+ (list "Bidi category"
+ (cdr (assoc
+ (nth 3 fields)
+ '(("L" . "Left-to-Right")
+ ("LRE" . "Left-to-Right Embedding")
+ ("LRO" . "Left-to-Right Override")
+ ("R" . "Right-to-Left")
+ ("AL" . "Right-to-Left Arabic")
+ ("RLE" . "Right-to-Left Embedding")
+ ("RLO" . "Right-to-Left Override")
+ ("PDF" . "Pop Directional Format")
+ ("EN" . "European Number")
+ ("ES" . "European Number Separator")
+ ("ET" . "European Number Terminator")
+ ("AN" . "Arabic Number")
+ ("CS" . "Common Number Separator")
+ ("NSM" . "Non-Spacing Mark")
+ ("BN" . "Boundary Neutral")
+ ("B" . "Paragraph Separator")
+ ("S" . "Segment Separator")
+ ("WS" . "Whitespace")
+ ("ON" . "Other Neutrals")))))
+ (list
+ "Decomposition"
+ (if (nth 4 fields)
+ (let* ((parts (split-string (nth 4 fields)))
+ (info (car parts)))
+ (if (string-match "\\`<\\(.+\\)>\\'" info)
+ (setq info (match-string 1 info))
+ (setq info nil))
+ (if info (setq parts (cdr parts)))
+ ;; Maybe printing ? for unrepresentable unicodes
+ ;; here and below should be changed?
+ (setq parts (mapconcat
+ (lambda (arg)
+ (string (or (decode-char
+ 'ucs
+ (string-to-number arg 16))
+ ??)))
+ parts " "))
+ (concat info parts))))
+ (list "Decimal digit value"
+ (nth 5 fields))
+ (list "Digit value"
+ (nth 6 fields))
+ (list "Numeric value"
+ (nth 7 fields))
+ (list "Mirrored"
+ (if (equal "Y" (nth 8 fields))
+ "yes"))
+ (list "Old name" (nth 9 fields))
+ (list "ISO 10646 comment" (nth 10 fields))
+ (list "Uppercase" (and (nth 11 fields)
+ (string (or (decode-char
+ 'ucs
+ (string-to-number
+ (nth 11 fields) 16))
+ ??))))
+ (list "Lowercase" (and (nth 12 fields)
+ (string (or (decode-char
+ 'ucs
+ (string-to-number
+ (nth 12 fields) 16))
+ ??))))
+ (list "Titlecase" (and (nth 13 fields)
+ (string (or (decode-char
+ 'ucs
+ (string-to-number
+ (nth 13 fields) 16))
+ ??))))
+
+ ;; XEmacs addition.
+ ;; If we're aware the character is a Han character, provide
+ ;; the Unihan information, or tell the user that it's not
+ ;; available.
+ (if (and (> (length (nth 0 fields)) 13)
+ (equal "<CJK Ideograph"
+ (substring (nth 0 fields) 0 14)))
+ (if (and unihan-database-handle
+ (setq unihan-match
+ (get-database (format "%04X" char)
+ unihan-database-handle)
+ unihan-match
+ (and unihan-match (read unihan-match))))
+ (with-temp-buffer
+ (insert-file-contents describe-char-unihan-file
+ nil (first unihan-match)
+ (second unihan-match))
+ (goto-char (point-min))
+ (while (re-search-forward
+ "^U\\+[0-9A-F]+\t\\(k[^\t]+\\)\t\\(.*\\)$"
+ nil t)
+ (push
+ (list
+ (or (gethash
+ (match-string 1)
+ describe-char-unihan-field-descriptions)
+ (match-string 1))
+ (decode-coding-string (match-string 2) 'utf-8))
+ unihan-info))
+ (close-database unihan-database-handle)
+ unihan-info)
+ ;; It's a Han character, but Unihan.txt is not
+ ;; available. Tell the user.
+ (list
+ '("Unihan"
+ "No Unihan information available; is \
+`describe-char-unihan-file' set, and its cache initialized?")))))))))))
+
+;; Return information about how CHAR is displayed at the buffer
+;; position POS. If the selected frame is on a graphic display,
+;; return a cons (FONTNAME . GLYPH-CODE). Otherwise, return a string
+;; describing the terminal codes for the character.
+(defun describe-char-display (pos char)
+ (let* ((frame (selected-frame))
+ (charset (char-charset char))
+ (ccl (or (and (charset-property charset 'encode-as-utf-8)
+ ccl-encode-to-ucs-2)
+ (charset-property charset 'ccl-program)))
+ (ccl-vector (make-vector 8 0)))
+ (if (display-graphic-p (selected-frame))
+ (list
+ (font-instance-name
+ (face-font-instance (or (get-char-property pos 'face)
+ 'default)
+ (selected-window)
+ charset))
+ (cond
+ ((and ccl (eq 'x (frame-type frame)))
+ (setq char (split-char char))
+ (aset ccl-vector 0 (charset-id charset))
+ (aset ccl-vector 1 (second char))
+ (if (= 2 (charset-dimension charset))
+ (aset ccl-vector 2 (third char)))
+ (ccl-execute ccl ccl-vector)
+ (if (= 2 (charset-dimension charset))
+ (logior (lsh (aref ccl-vector 1) 8)
+ (aref ccl-vector 2))
+ (aref ccl-vector 1)))
+ ;; #### We don't handle the X case where redisplay falls back to an
+ ;; ISO 10646-1 font at runtime.
+ ((eq 'x (frame-type frame))
+ (if (= 2 (charset-dimension charset))
+ (prog2
+ (setq char (split-char char))
+ (logior (lsh (second char) 8)
+ (third char)))
+ (second (split-char char))))
+ ;; Otherwise we assume we're using Unicode.
+ (t
+ (encode-char char 'ucs))))
+ (let* ((coding (console-tty-output-coding-system (device-console)))
+ (encoded (encode-coding-string char coding)))
+ (if encoded
+ (format "%s, coding system %s"
+ (encoded-string-description encoded coding)
+ (coding-system-name coding)))))))
+
+
+;;;###autoload
+(defun describe-char (pos)
+ "Describe the character after POS (interactively, the character after point).
+The information includes character code, charset and code points in it,
+syntax, category, how the character is encoded in a file,
+character composition information (if relevant),
+as well as widgets, buttons, overlays, and text properties."
+ (interactive "d")
+ (if (>= pos (point-max))
+ (error "No character follows specified position"))
+ (let* ((char (char-after pos))
+ (charset (char-charset char))
+ (composition (find-composition pos nil nil t))
+ (component-chars nil)
+ (display-table
+ (specifier-instance current-display-table (selected-window)))
+ (disp-table-entry (and display-table
+ (get-display-table char display-table)))
+ (extents (mapcar #'(lambda (o) (extent-properties o))
+ (extents-at pos)))
+ (char-description (single-key-description char))
+ (text-props-desc
+ (let ((tmp-buf (generate-new-buffer " *text-props*")))
+ (unwind-protect
+ (progn
+ (describe-text-properties pos tmp-buf)
+ (with-current-buffer tmp-buf (buffer-string)))
+ (kill-buffer tmp-buf))))
+ item-list max-width unicode unicode-formatted unicode-error)
+
+
+ (setq unicode-error
+ ;; XEmacs change, check does the character represent a Unicode
+ ;; error sequence.
+ (get-char-table char unicode-error-default-translation-table)
+ unicode (and (not unicode-error) (encode-char char 'ucs))
+ unicode-formatted (if unicode-error
+ (format
+ "Invalid Unicode sequence, ?\x%02x on disk"
+ unicode-error)
+ (if (and unicode (natnump unicode))
+ (format (if (> unicode #xFFFF)
+ "U+%06X" "U+%04X")
+ unicode)
+ ""))
+ item-list
+ `(("character"
+ ,(format "%s (%s, %d, #o%o, #x%x)"
+ (apply 'propertize char-description
+ (text-properties-at pos))
+ unicode-formatted
+ char
+ char
+ char))
+ ("charset"
+ ,(lexical-let
+ ((charset-name (symbol-name charset)))
+ `(progn
+ (widget-create 'push-button
+:notify ,(lambda (&rest ignored-arg)
+ (with-displaying-help-buffer
+ (lambda nil
+ (charset-description
+ (intern charset-name)))
+ charset-name))
+ ,charset-name)
+ (widget-insert (format " (%s)" (charset-description
+ ',charset))))))
+ ("code point"
+ ,(let ((split (split-char char)))
+ `(widget-create 'push-button
+;:notify
+; ,(lambda (&rest ignored-arg)
+; (with-selected-wind
+; insert-gui-button
+; (make-gui-button
+ ,(if (= (charset-dimension charset) 1)
+ (format "#x%02X" (nth 1 split))
+ (format "#x%02X #x%02X" (nth 1 split)
+ (nth 2 split))))))
+ ("syntax"
+ ,(let ((syntax
+ (syntax-string-to-code (string (syntax-after pos)))))
+ (with-temp-buffer
+ (describe-syntax-code syntax (current-buffer))
+ ;; Remove the newline.
+ (delete-backward-char)
+ (buffer-string))))
+ ;; XEmacs; #### add category support.
+; ("category"
+; ,@(let ((category-set (char-category-set char)))
+; (if (not category-set)
+; '("-- none --")
+; (mapcar #'(lambda (x) (format "%c:%s"
+; x (category-docstring x)))
+; (category-set-mnemonics category-set)))))
+; ,@(let ((props (get-char-table char char-code-property-table))
+; ps)
+; (when props
+; (while props
+; (push (format "%s:" (pop props)) ps)
+; (push (format "%s;" (pop props)) ps))
+; (list (cons "Properties" (nreverse ps)))))
+ ("to input"
+ ,@(let ((key-list (and-fboundp #'quail-find-key
+ current-input-method
+ (quail-find-key char))))
+ (if (consp key-list)
+ (list "type"
+ (mapconcat #'(lambda (x) (concat "\"" x "\""))
+ key-list " or ")
+ "with"
+ `(insert-text-button
+ ,current-input-method
+ 'type 'help-input-method
+ 'help-args '(,current-input-method))))))
+; ("buffer code"
+; ,(encoded-string-description
+; (string-as-unibyte (char-to-string char) nil))
+ ("file code"
+ ,@(let* ((coding buffer-file-coding-system)
+ ;; ### XEmacs; use encode-coding-char once
+ ;; merged.
+ (encoded (encode-coding-string char coding)))
+ (if encoded
+ (list (encoded-string-description encoded coding)
+ (format "(encoded by coding system %S)"
+ (coding-system-name coding)))
+ (list "not encodable by coding system"
+ (coding-system-name coding)))))
+ ("display"
+ ,(cond
+ (disp-table-entry
+ ;; XEmacs change; just use the print syntax of the display
+ ;; table entry. Might be possible to improve this, but
+ ;; nothing occurs to me right now.
+ (format "by display table entry [%S] " disp-table-entry))
+ (composition
+ (let ((from (car composition))
+ (to (nth 1 composition))
+ (next (1+ pos))
+ (components (nth 2 composition))
+ ch)
+ (setcar composition
+ (and (< from pos) (buffer-substring from pos)))
+ (setcar (cdr composition)
+ (and (< next to) (buffer-substring next to)))
+ (dotimes (i (length components))
+ (if (integerp (setq ch (aref components i)))
+ (push (cons ch (describe-char-display pos ch))
+ component-chars)))
+ (setq component-chars (nreverse component-chars))
+ (format "composed to form \"%s\" (see below)"
+ (buffer-substring from to))))
+ (t
+ (let ((display (describe-char-display pos char)))
+ (if (display-graphic-p (selected-frame))
+ (if display
+ (concat
+ "by this font (glyph code)\n"
+ (format " %s (#x%02X)"
+ (first display) (second display)))
+ "no font available")
+ (if display
+ (format "terminal code %s" display)
+ "not encodable for terminal"))))))
+ ,@(let ((face
+ (if (not (or disp-table-entry composition))
+ (cond
+ ;; XEmacs #### Implement this.
+; ((and show-trailing-whitespace
+; (save-excursion (goto-char pos)
+; (looking-at "[ \t]+$")))
+; 'trailing-whitespace)
+; ((and nobreak-char-display unicode (eq unicode '#xa0))
+; 'nobreak-space)
+; ((and nobreak-char-display unicode (eq unicode '#xad))
+; 'escape-glyph)
+ ((and (< char 32) (not (memq char '(9 10))))
+ 'escape-glyph)))))
+ (if face (list (list "hardcoded face"
+ `(insert-gui-button
+ (make-gui-button
+ ,(symbol-name face)))))))
+ ,@(let ((unicodedata (and unicode
+ (describe-char-unicode-data unicode))))
+ (if unicodedata
+ (cons (list "Unicode data" " ") unicodedata)))))
+ (setq max-width (apply #'max (mapcar #'(lambda (x)
+ (if (cadr x) (length (car x)) 0))
+ item-list)))
+ ; (help-setup-xref nil (interactive-p))
+ (with-displaying-help-buffer
+ (lambda ()
+ (with-current-buffer standard-output
+ ; (set-buffer-multibyte multibyte-p)
+ (let ((formatter (format "%%%ds:" max-width)))
+ (dolist (elt item-list)
+ (when (cadr elt)
+ (insert (format formatter (car elt)))
+ (dolist (clm (cdr elt))
+ (if (consp clm)
+ (progn (insert " ") (eval clm))
+ (when (>= (+ (current-column)
+ (or (string-match "\n" clm)
+ (string-width clm))
+ 1)
+ (window-width))
+ (insert "\n")
+ (indent-to (1+ max-width)))
+ (insert " " clm)))
+ (insert "\n"))))
+
+ (when extents
+ (save-excursion
+ (goto-char (point-min))
+ (re-search-forward "character:[ \t\n]+")
+ (let* ((end (+ (point) (length char-description))))
+ (mapc #'(lambda (props)
+ (let ((o (make-extent (point) end)))
+ (while props
+ (set-extent-property o (car props) (nth 1 props))
+ (setq props (cddr props)))))
+ extents))))
+
+ ;; XEmacs change; don't give GUI- or TTY-specific detail about the
+ ;; display table entry, the #'specifier-instance call above dealt
+ ;; with that.
+ ; (when disp-table-entry ...)
+
+ ;; XEmacs; this doesn't work now.
+ (when composition
+ (insert "\nComposed")
+ (if (car composition)
+ (if (cadr composition)
+ (insert " with the surrounding characters \""
+ (car composition) "\" and \""
+ (cadr composition) "\"")
+ (insert " with the preceding character(s) \""
+ (car composition) "\""))
+ (if (cadr composition)
+ (insert " with the following character(s) \""
+ (cadr composition) "\"")))
+ (insert " by the rule:\n\t("
+ (mapconcat (lambda (x)
+ (format (if (consp x) "%S" "?%c") x))
+ (nth 2 composition)
+ " ")
+ ")")
+ (insert "\nThe component character(s) are displayed by ")
+ ;; XEmacs #### Once composition is in place, this should be
+ ;; a (font-instance-name (face-font-instance [...])) call.
+ (if (display-graphic-p (selected-frame))
+ (progn
+ (insert "these fonts (glyph codes):")
+ (dolist (elt component-chars)
+ (insert "\n " (car elt) ?:
+ (propertize " " 'display '(space :align-to 5))
+ (if (cdr elt)
+ (format "%s (#x%02X)" (cadr elt) (cddr elt))
+ "-- no font --"))))
+ (insert "these terminal codes:")
+ (dolist (elt component-chars)
+ (insert "\n " (car elt) ":"
+ (propertize " " 'display '(space :align-to 5))
+ (or (cdr elt) "-- not encodable --"))))
+ (insert "\nSee the variable `reference-point-alist' for "
+ "the meaning of the rule.\n"))
+
+ (if text-props-desc (insert text-props-desc))
+; (setq help-xref-stack-item (list 'help-insert-string (buffer-string)))
+ (toggle-read-only 1)
+ (print-help-return-message)))
+ (format "Describe %c" (char-after pos)))))
+
+(defalias 'describe-char-after 'describe-char)
+(make-obsolete 'describe-char-after 'describe-char "22.1")
+
+(provide 'descr-text)
+
+;; arch-tag: fc55a498-f3e9-4312-b5bd-98cc02480af1
+;;; descr-text.el ends here
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches