Using saved parent location: http://bzr.savannah.gnu.org/r/emacs/trunk/ Now on revision 102221. ------------------------------------------------------------ revno: 102221 committer: Glenn Morris branch nick: trunk timestamp: Mon 2010-11-01 21:08:43 -0700 message: * lisp/gnus/gnus-html.el: Reorder requirements to quieten compiler. diff: === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2010-11-02 02:19:52 +0000 +++ lisp/gnus/ChangeLog 2010-11-02 04:08:43 +0000 @@ -1,3 +1,7 @@ +2010-11-02 Glenn Morris + + * gnus-html.el: Reorder requirements to quieten compiler. + 2010-11-02 Katsumi Yamaoka * gnus-cite.el (gnus-article-fill-cited-article): Make fill work @@ -8,10 +12,10 @@ 2010-11-01 Andrew Cohen - * nnir.el (nnir-run-gmane): inhibit demon. return nil if no messages. - (nnir-read-parms): don't modify query. - (nnir-run-query): add ability to search topic on current line. - (nnir-get-active): clean up. + * nnir.el (nnir-run-gmane): Inhibit demon. Return nil if no messages. + (nnir-read-parms): Don't modify query. + (nnir-run-query): Add ability to search topic on current line. + (nnir-get-active): Clean up. 2010-11-01 Lars Magne Ingebrigtsen === modified file 'lisp/gnus/gnus-html.el' --- lisp/gnus/gnus-html.el 2010-10-24 09:55:56 +0000 +++ lisp/gnus/gnus-html.el 2010-11-02 04:08:43 +0000 @@ -29,9 +29,10 @@ ;;; Code: (eval-when-compile (require 'cl)) + +(require 'gnus-art) (eval-when-compile (require 'mm-decode)) -(require 'gnus-art) (require 'mm-url) (require 'url) (require 'url-cache) ------------------------------------------------------------ revno: 102220 committer: Glenn Morris branch nick: trunk timestamp: Mon 2010-11-01 21:06:44 -0700 message: * lisp/gnus/gnus-util.el: Comment. diff: === modified file 'lisp/gnus/gnus-util.el' --- lisp/gnus/gnus-util.el 2010-11-01 03:58:53 +0000 +++ lisp/gnus/gnus-util.el 2010-11-02 04:06:44 +0000 @@ -1658,6 +1658,8 @@ (defun gnus-iswitchb-completing-read (prompt collection &optional require-match initial-input history def) "`iswitchb' based completing-read function." + ;; Make sure iswitchb is loaded before we let-bind its variables. + ;; If it is loaded inside the let, variables can become unbound afterwards. (require 'iswitchb) (let ((iswitchb-make-buflist-hook (lambda () ------------------------------------------------------------ revno: 102219 committer: Chong Yidong branch nick: trunk timestamp: Mon 2010-11-01 22:30:50 -0400 message: Fix last change to package.el. diff: === modified file 'lisp/emacs-lisp/package.el' --- lisp/emacs-lisp/package.el 2010-11-02 01:50:26 +0000 +++ lisp/emacs-lisp/package.el 2010-11-02 02:30:50 +0000 @@ -1027,7 +1027,8 @@ (package-read-all-archive-contents) ;; "Deactivate" obsoleted built-in packages (dolist (elt package-obsolete-alist) - (delq (car elt) package-activated-list)) + (setq package-activated-list + (delq (car elt) package-activated-list))) ;; Try to activate all our packages. (dolist (elt package-alist) (package-activate (car elt) (package-desc-vers (cdr elt))))) ------------------------------------------------------------ revno: 102218 committer: Katsumi Yamaoka branch nick: trunk timestamp: Tue 2010-11-02 02:19:52 +0000 message: gnus-cite.el (gnus-article-fill-cited-article): Make fill work properly for XEmacs as well. gnus-cite.el (gnus-article-fill-cited-article, gnus-article-foldable-buffer, gnus-article-natural-long-line-p): Use window-width rather than frame-width. diff: === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2010-11-01 23:47:38 +0000 +++ lisp/gnus/ChangeLog 2010-11-02 02:19:52 +0000 @@ -1,3 +1,11 @@ +2010-11-02 Katsumi Yamaoka + + * gnus-cite.el (gnus-article-fill-cited-article): Make fill work + properly for XEmacs as well. + (gnus-article-fill-cited-article, gnus-article-foldable-buffer) + (gnus-article-natural-long-line-p): Use window-width rather than + frame-width. + 2010-11-01 Andrew Cohen * nnir.el (nnir-run-gmane): inhibit demon. return nil if no messages. === modified file 'lisp/gnus/gnus-cite.el' --- lisp/gnus/gnus-cite.el 2010-11-01 23:11:37 +0000 +++ lisp/gnus/gnus-cite.el 2010-11-02 02:19:52 +0000 @@ -544,17 +544,20 @@ use-hard-newlines) (unless do-fill (setq do-fill (gnus-article-foldable-buffer (cdar marks)))) + ;; Note: the XEmacs version of `fill-region' inserts a newline + ;; unless the region ends with a newline. (when do-fill (if (not long-lines) (fill-region (point-min) (point-max)) (goto-char (point-min)) (while (not (eobp)) (end-of-line) - (when (> (current-column) (frame-width)) + (when (prog1 + (> (current-column) (window-width)) + (forward-line 1)) (save-restriction - (narrow-to-region (line-beginning-position) (point)) - (fill-region (point-min) (point-max)))) - (forward-line 1))))) + (narrow-to-region (line-beginning-position 0) (point)) + (fill-region (point-min) (point-max)))))))) (set-marker (caar marks) nil) (setq marks (cdr marks))) (when marks @@ -581,7 +584,7 @@ (push elem columns)) (setcdr elem (1+ (cdr elem))))) (end-of-line) - (when (> (current-column) (frame-width)) + (when (> (current-column) (window-width)) (setq do-fill t)) (forward-line 1)) (and do-fill @@ -596,7 +599,7 @@ (and ;; The line is long. (> (- (line-end-position) (line-beginning-position)) - (frame-width)) + (window-width)) ;; It doesn't start with spaces. (not (looking-at " ")) ;; Not cited text. ------------------------------------------------------------ revno: 102217 committer: Chong Yidong branch nick: trunk timestamp: Mon 2010-11-01 21:50:26 -0400 message: Two fixes for elpa packages overriding built-in ones. * emacs-lisp/package.el (package-initialize): Ensure that obsoleted built-in packages are not in package-activated-list during activation. (describe-package-1): Make the "installed" status override "built-in". diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2010-11-02 01:50:22 +0000 +++ lisp/ChangeLog 2010-11-02 01:50:26 +0000 @@ -1,3 +1,11 @@ +2010-11-02 Chong Yidong + + * emacs-lisp/package.el (package-initialize): Ensure that + obsoleted built-in packages are not in package-activated-list + during activation. + (describe-package-1): Make the "installed" status override + "built-in". + 2010-11-01 Vinicius Jose Latorre * subr.el (version-separator, version-regexp-alist): Remove '*' === modified file 'lisp/emacs-lisp/package.el' --- lisp/emacs-lisp/package.el 2010-10-31 00:06:18 +0000 +++ lisp/emacs-lisp/package.el 2010-11-02 01:50:26 +0000 @@ -1020,15 +1020,17 @@ The variable `package-load-list' controls which packages to load." (interactive) (require 'finder-inf nil t) - (setq package-alist package--builtins) - (setq package-activated-list (mapcar #'car package-alist)) - (setq package-obsolete-alist nil) + (setq package-alist package--builtins + package-activated-list (mapcar #'car package-alist) + package-obsolete-alist nil) (package-load-all-descriptors) (package-read-all-archive-contents) + ;; "Deactivate" obsoleted built-in packages + (dolist (elt package-obsolete-alist) + (delq (car elt) package-activated-list)) ;; Try to activate all our packages. - (mapc (lambda (elt) - (package-activate (car elt) (package-desc-vers (cdr elt)))) - package-alist)) + (dolist (elt package-alist) + (package-activate (car elt) (package-desc-vers (cdr elt))))) ;;;; Package description buffer. @@ -1073,10 +1075,10 @@ ;; This package is loaded (i.e. in `package-alist'). (progn (setq version (package-version-join (package-desc-vers desc))) - (cond (built-in + (cond ((setq pkg-dir (package--dir package-name version)) + (insert "an installed package.\n\n")) + (built-in (princ "a built-in package.\n\n")) - ((setq pkg-dir (package--dir package-name version)) - (insert "an installed package.\n\n")) (t ;; This normally does not happen. (insert "a deleted package.\n\n") (setq version nil)))) ------------------------------------------------------------ revno: 102216 committer: Vinicius Jose Latorre + + * subr.el (version-separator, version-regexp-alist): Remove '*' + from docstring. + (version-list-<=, version<=, version=): Doc fix. + 2010-11-01 Kenichi Handa * faces.el (glyphless-char): Inherit underline for tty. === modified file 'lisp/subr.el' --- lisp/subr.el 2010-10-13 23:43:39 +0000 +++ lisp/subr.el 2010-11-02 01:50:22 +0000 @@ -3593,18 +3593,18 @@ ;;;; Comparing version strings. (defconst version-separator "." - "*Specify the string used to separate the version elements. + "Specify the string used to separate the version elements. Usually the separator is \".\", but it can be any other string.") (defconst version-regexp-alist - '(("^[-_+ ]?alpha$" . -3) - ("^[-_+]$" . -3) ; treat "1.2.3-20050920" and "1.2-3" as alpha releases - ("^[-_+ ]cvs$" . -3) ; treat "1.2.3-CVS" as alpha release - ("^[-_+ ]?beta$" . -2) + '(("^[-_+ ]?alpha$" . -3) + ("^[-_+]$" . -3) ; treat "1.2.3-20050920" and "1.2-3" as alpha releases + ("^[-_+ ]cvs$" . -3) ; treat "1.2.3-CVS" as alpha release + ("^[-_+ ]?beta$" . -2) ("^[-_+ ]?\\(pre\\|rcc\\)$" . -1)) - "*Specify association between non-numeric version and its priority. + "Specify association between non-numeric version and its priority. This association is used to handle version string like \"1.0pre2\", \"0.9alpha1\", etc. It's used by `version-to-list' (which see) to convert the @@ -3698,7 +3698,7 @@ (setq al (cdr al))) (cond (al (push (cdar al) lst)) - ;; Convert 22.3a to 22.3.1. + ;; Convert 22.3a to 22.3.1, 22.3b to 22.3.2, etc. ((string-match "^[-_+ ]?\\([a-zA-Z]\\)$" s) (push (- (aref (downcase (match-string 1 s)) 0) ?a -1) lst)) @@ -3754,7 +3754,7 @@ "Return t if L1, a list specification of a version, is lower or equal to L2. Note that integer list (1) is equal to (1 0), (1 0 0), (1 0 0 0), -etc. That is, the trailing zeroes are irrelevant. Also, integer +etc. That is, the trailing zeroes are insignificant. Also, integer list (1) is greater than (1 -1) which is greater than (1 -2) which is greater than (1 -3)." (while (and l1 l2 (= (car l1) (car l2))) @@ -3796,7 +3796,7 @@ "Return t if version V1 is lower (older) than or equal to V2. Note that version string \"1\" is equal to \"1.0\", \"1.0.0\", \"1.0.0.0\", -etc. That is, the trailing \".0\"s are insignificant.. Also, version +etc. That is, the trailing \".0\"s are insignificant. Also, version string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\", which is higher than \"1alpha\"." (version-list-<= (version-to-list v1) (version-to-list v2))) @@ -3805,7 +3805,7 @@ "Return t if version V1 is equal to V2. Note that version string \"1\" is equal to \"1.0\", \"1.0.0\", \"1.0.0.0\", -etc. That is, the trailing \".0\"s are insignificant.. Also, version +etc. That is, the trailing \".0\"s are insignificant. Also, version string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\", which is higher than \"1alpha\"." (version-list-= (version-to-list v1) (version-to-list v2))) ------------------------------------------------------------ revno: 102215 author: Andrew Cohen committer: Katsumi Yamaoka branch nick: trunk timestamp: Mon 2010-11-01 23:47:38 +0000 message: nnir.el: Fix various bugs. diff: === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2010-11-01 23:11:37 +0000 +++ lisp/gnus/ChangeLog 2010-11-01 23:47:38 +0000 @@ -1,3 +1,10 @@ +2010-11-01 Andrew Cohen + + * nnir.el (nnir-run-gmane): inhibit demon. return nil if no messages. + (nnir-read-parms): don't modify query. + (nnir-run-query): add ability to search topic on current line. + (nnir-get-active): clean up. + 2010-11-01 Lars Magne Ingebrigtsen * gnus-cite.el (gnus-article-foldable-buffer): Protect against === modified file 'lisp/gnus/nnir.el' --- lisp/gnus/nnir.el 2010-11-01 03:58:53 +0000 +++ lisp/gnus/nnir.el 2010-11-01 23:47:38 +0000 @@ -1407,6 +1407,7 @@ (format "author:%s" (cdr (assq 'author query))) "")) (search (format "%s %s %s" qstring groupspec authorspec)) + (gnus-inhibit-demon t) artlist) (require 'mm-url) (with-current-buffer nntp-server-buffer @@ -1441,14 +1442,15 @@ (function (lambda (x y) (> (nnir-artitem-rsv x) (nnir-artitem-rsv y))))))) - (message "Can't search non-gmane nntp groups"))) + (message "Can't search non-gmane nntp groups") + nil)) ;;; Util Code: (defun nnir-read-parms (query nnir-search-engine) "Reads additional search parameters according to `nnir-engines'." (let ((parmspec (caddr (assoc nnir-search-engine nnir-engines)))) - (nconc query + (append query (mapcar 'nnir-read-parm parmspec)))) (defun nnir-read-parm (parmspec) @@ -1472,7 +1474,11 @@ (with-current-buffer gnus-server-buffer (list (list (gnus-server-server-name)))) (nnir-sort-groups-by-server - (or gnus-group-marked (list (gnus-group-group-name))))))) + (or gnus-group-marked + (if (gnus-group-group-name) + (list (gnus-group-group-name)) + (cdr (assoc (gnus-group-topic-name) + gnus-topic-alist)))))))) (apply 'vconcat (mapcar (lambda (x) (let* ((server (car x)) @@ -1582,32 +1588,15 @@ (goto-char (point-min)) (unless (string= gnus-ignored-newsgroups "") (delete-matching-lines gnus-ignored-newsgroups)) - ;; We treat NNTP as a special case to avoid problems with - ;; garbage group names like `"foo' that appear in some badly - ;; managed active files. -jh. - (if (eq (car method) 'nntp) - (while (not (eobp)) - (ignore-errors - (push (cons - (mm-string-as-unibyte - (buffer-substring - (point) - (progn - (skip-chars-forward "^ \t") - (point)))) - (let ((last (read cur))) - (cons (read cur) last))) - groups)) - (forward-line)) - (while (not (eobp)) - (ignore-errors - (push (mm-string-as-unibyte - (let ((p (point))) - (skip-chars-forward "^ \t\\\\") - (setq name (buffer-substring (+ p 1) (- (point) 1))) - (gnus-group-full-name name method))) - groups)) - (forward-line))))) + (while (not (eobp)) + (ignore-errors + (push (mm-string-as-unibyte + (let ((p (point))) + (skip-chars-forward "^ \t\\\\") + (setq name (buffer-substring (+ p 1) (- (point) 1))) + (gnus-group-full-name name method))) + groups)) + (forward-line)))) groups)) ;; The end. ------------------------------------------------------------ revno: 102214 author: Lars Magne Ingebrigtsen committer: Katsumi Yamaoka branch nick: trunk timestamp: Mon 2010-11-01 23:11:37 +0000 message: gnus-sum.el (gnus-print-buffer): Rewrite to use with-temp-buffer. gnus-sum.el (gnus-print-buffer): Just print the buffer as is. gnus-cite.el (gnus-article-foldable-buffer): Protect against degenerate articles. diff: === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2010-11-01 22:21:10 +0000 +++ lisp/gnus/ChangeLog 2010-11-01 23:11:37 +0000 @@ -1,5 +1,12 @@ 2010-11-01 Lars Magne Ingebrigtsen + * gnus-cite.el (gnus-article-foldable-buffer): Protect against + degenerate articles. + + * gnus-sum.el (gnus-print-buffer): Rewrite to use with-temp-buffer. + (gnus-print-buffer): Just print the buffer as is, without any copying + to a buffer and then re-highlighting. + * nnimap.el (nnimap-request-group): Store the new updated info. (nnimap-request-group): Select the group when we don't know whether it exists or not. === modified file 'lisp/gnus/gnus-cite.el' --- lisp/gnus/gnus-cite.el 2010-11-01 22:21:10 +0000 +++ lisp/gnus/gnus-cite.el 2010-11-01 23:11:37 +0000 @@ -571,7 +571,8 @@ columns) (goto-char (point-min)) (while (not (eobp)) - (forward-char (length prefix)) + (unless (> (length prefix) (- (point-max) (point))) + (forward-char (length prefix))) (skip-chars-forward " \t") (unless (eolp) (let ((elem (assq (current-column) columns))) === modified file 'lisp/gnus/gnus-sum.el' --- lisp/gnus/gnus-sum.el 2010-10-31 22:31:24 +0000 +++ lisp/gnus/gnus-sum.el 2010-11-01 23:11:37 +0000 @@ -9330,41 +9330,26 @@ (ps-despool filename)) (defun gnus-print-buffer () - (let ((buffer (generate-new-buffer " *print*"))) - (unwind-protect - (progn - (copy-to-buffer buffer (point-min) (point-max)) - (set-buffer buffer) - (gnus-remove-text-with-property 'gnus-decoration) - (when (gnus-visual-p 'article-highlight 'highlight) - ;; Copy-to-buffer doesn't copy overlay. So redo - ;; highlight. - (let ((gnus-article-buffer buffer)) - (gnus-article-highlight-citation t) - (gnus-article-highlight-signature) - (gnus-article-emphasize) - (gnus-article-delete-invisible-text))) - (let ((ps-left-header - (list - (concat "(" - (gnus-summary-print-truncate-and-quote - (mail-header-subject gnus-current-headers) - 66) ")") - (concat "(" - (gnus-summary-print-truncate-and-quote - (mail-header-from gnus-current-headers) - 45) ")"))) - (ps-right-header - (list - "/pagenumberstring load" - (concat "(" - (mail-header-date gnus-current-headers) ")")))) - (gnus-run-hooks 'gnus-ps-print-hook) - (save-excursion - (if ps-print-color-p - (ps-spool-buffer-with-faces) - (ps-spool-buffer))))) - (kill-buffer buffer)))) + (let ((ps-left-header + (list + (concat "(" + (gnus-summary-print-truncate-and-quote + (mail-header-subject gnus-current-headers) + 66) ")") + (concat "(" + (gnus-summary-print-truncate-and-quote + (mail-header-from gnus-current-headers) + 45) ")"))) + (ps-right-header + (list + "/pagenumberstring load" + (concat "(" + (mail-header-date gnus-current-headers) ")")))) + (gnus-run-hooks 'gnus-ps-print-hook) + (save-excursion + (if ps-print-color-p + (ps-spool-buffer-with-faces) + (ps-spool-buffer))))) (defun gnus-summary-show-complete-article () "Show a complete version of the current article. ------------------------------------------------------------ revno: 102213 author: Lars Magne Ingebrigtsen committer: Katsumi Yamaoka branch nick: trunk timestamp: Mon 2010-11-01 22:21:10 +0000 message: Merge changes made in Gnus trunk. nnimap.el (nnimap-parse-line): Don't bug out oddly formed replies (bug #7311). gnus-cite.el (gnus-article-fill-cited-article): Minimize the long-lines case by only filling the long lines. gnus-start.el (gnus-ask-server-for-new-groups): Return the new groups. gnus-group.el (gnus-group-find-new-groups): Display all the new groups. gnus-start.el (gnus-find-new-newsgroups): Return the list of new groups. nnimap.el (nnimap-request-group): Store the new updated info. nnimap.el (nnimap-request-group): Select the group when we don't know whether it exists or not. diff: === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2010-11-01 06:39:01 +0000 +++ lisp/gnus/ChangeLog 2010-11-01 22:21:10 +0000 @@ -1,3 +1,24 @@ +2010-11-01 Lars Magne Ingebrigtsen + + * nnimap.el (nnimap-request-group): Store the new updated info. + (nnimap-request-group): Select the group when we don't know whether it + exists or not. + + * gnus-start.el (gnus-ask-server-for-new-groups): Return the new + groups. + + * gnus-group.el (gnus-group-find-new-groups): Display all the new + groups. + + * gnus-start.el (gnus-find-new-newsgroups): Return the list of new + groups. + + * gnus-cite.el (gnus-article-fill-cited-article): Minimize the + long-lines case by only filling the long lines. + + * nnimap.el (nnimap-parse-line): Don't bug out oddly formed replies + (bug #7311). + 2010-11-01 Katsumi Yamaoka * shr.el: No need to declare `declare-function' since shr.el is for === modified file 'lisp/gnus/gnus-cite.el' --- lisp/gnus/gnus-cite.el 2010-10-31 22:31:24 +0000 +++ lisp/gnus/gnus-cite.el 2010-11-01 22:21:10 +0000 @@ -545,7 +545,16 @@ (unless do-fill (setq do-fill (gnus-article-foldable-buffer (cdar marks)))) (when do-fill - (fill-region (point-min) (point-max)))) + (if (not long-lines) + (fill-region (point-min) (point-max)) + (goto-char (point-min)) + (while (not (eobp)) + (end-of-line) + (when (> (current-column) (frame-width)) + (save-restriction + (narrow-to-region (line-beginning-position) (point)) + (fill-region (point-min) (point-max)))) + (forward-line 1))))) (set-marker (caar marks) nil) (setq marks (cdr marks))) (when marks === modified file 'lisp/gnus/gnus-group.el' --- lisp/gnus/gnus-group.el 2010-10-30 15:01:14 +0000 +++ lisp/gnus/gnus-group.el 2010-11-01 22:21:10 +0000 @@ -4186,8 +4186,14 @@ With 2 C-u's, use most complete method possible to query the server for new groups, and subscribe the new groups as zombies." (interactive "p") - (gnus-find-new-newsgroups (or arg 1)) - (gnus-group-list-groups)) + (let ((new-groups (gnus-find-new-newsgroups (or arg 1))) + current-group) + (gnus-group-list-groups) + (setq current-group (gnus-group-group-name)) + (dolist (group new-groups) + (gnus-group-jump-to-group group)) + (when current-group + (gnus-group-jump-to-group current-group)))) (defun gnus-group-edit-global-kill (&optional article group) "Edit the global kill file. === modified file 'lisp/gnus/gnus-start.el' --- lisp/gnus/gnus-start.el 2010-10-30 15:01:14 +0000 +++ lisp/gnus/gnus-start.el 2010-11-01 22:21:10 +0000 @@ -1145,7 +1145,8 @@ (if (> groups 0) (gnus-message 5 "%d new newsgroup%s arrived." groups (if (> groups 1) "s have" " has")) - (gnus-message 5 "No new newsgroups.")))))) + (gnus-message 5 "No new newsgroups.")) + groups)))) (defun gnus-matches-options-n (group) ;; Returns `subscribe' if the group is to be unconditionally @@ -1243,7 +1244,7 @@ (gnus-message 5 "No new newsgroups")) (when got-new (setq gnus-newsrc-last-checked-date new-date)) - got-new)) + new-newsgroups)) (defun gnus-subscribe-group (group &optional previous method) "Subscribe GROUP and put it after PREVIOUS." === modified file 'lisp/gnus/nnimap.el' --- lisp/gnus/nnimap.el 2010-11-01 06:13:43 +0000 +++ lisp/gnus/nnimap.el 2010-11-01 22:21:10 +0000 @@ -669,7 +669,8 @@ (let ((result (nnimap-possibly-change-group ;; Don't SELECT the group if we're going to select it ;; later, anyway. - (if dont-check + (if (and dont-check + (assoc group nnimap-current-infos)) nil group) server)) @@ -698,7 +699,8 @@ 1 group "SELECT"))))) (when (and info marks) - (nnimap-update-infos marks (list info))) + (nnimap-update-infos marks (list info)) + (nnimap-store-info info (gnus-active (gnus-info-group info)))) (goto-char (point-max)) (let ((uidnext (nth 5 (car marks)))) (setq high (or (if uidnext @@ -1555,12 +1557,16 @@ (split-string (buffer-substring (1+ (point)) - (1- (search-forward "]" (line-end-position) 'move))))) + (if (search-forward "]" (line-end-position) 'move) + (1- (point)) + (point))))) ((eql char ?\() (split-string (buffer-substring (1+ (point)) - (1- (search-forward ")" (line-end-position) 'move))))) + (if (search-forward ")" (line-end-position) 'move) + (1- (point)) + (point))))) ((eql char ?\") (forward-char 1) (buffer-substring ------------------------------------------------------------ revno: 102212 committer: Chong Yidong branch nick: trunk timestamp: Mon 2010-11-01 11:18:42 -0400 message: Fix error in last merge from branch. Remove 2010-10-25 commit by Michael Albinus to dbusbind.c, which is not intended for trunk. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2010-11-01 14:59:31 +0000 +++ src/ChangeLog 2010-11-01 15:18:42 +0000 @@ -78,12 +78,6 @@ when aborting on GTK. This requires using shut_down_emacs directly instead of Fkill_emacs. -2010-10-31 Michael Albinus - - * dbusbind.c (Fdbus_call_method_asynchronously) - (Fdbus_register_signal, Fdbus_register_method): Check, whether - `dbus-registered-objects-table' is initialized. - 2010-10-29 Eli Zaretskii * emacs.c (main): Call syms_of_filelock unconditionally. === modified file 'src/dbusbind.c' --- src/dbusbind.c 2010-10-31 14:40:01 +0000 +++ src/dbusbind.c 2010-11-01 15:18:42 +0000 @@ -1232,10 +1232,6 @@ SDATA (interface), SDATA (method)); - /* Check dbus-registered-objects-table. */ - if (!HASH_TABLE_P (Vdbus_registered_objects_table)) - XD_SIGNAL1 (build_string ("dbus.el is not loaded")); - /* Open a connection to the bus. */ connection = xd_initialize (bus, TRUE); @@ -1873,10 +1869,6 @@ wrong_type_argument (intern ("functionp"), handler); GCPRO6 (bus, service, path, interface, signal, handler); - /* Check dbus-registered-objects-table. */ - if (!HASH_TABLE_P (Vdbus_registered_objects_table)) - XD_SIGNAL1 (build_string ("dbus.el is not loaded")); - /* Retrieve unique name of service. If service is a known name, we will register for the corresponding unique name, if any. Signals are sent always with the unique name as sender. Note: the unique @@ -1989,10 +1981,6 @@ /* TODO: We must check for a valid service name, otherwise there is a segmentation fault. */ - /* Check dbus-registered-objects-table. */ - if (!HASH_TABLE_P (Vdbus_registered_objects_table)) - XD_SIGNAL1 (build_string ("dbus.el is not loaded")); - /* Open a connection to the bus. */ connection = xd_initialize (bus, TRUE); ------------------------------------------------------------ revno: 102211 committer: Juanma Barranquero branch nick: trunk timestamp: Mon 2010-11-01 15:59:31 +0100 message: Fix dates in ChangeLog entries. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2010-11-01 07:55:44 +0000 +++ lisp/ChangeLog 2010-11-01 14:59:31 +0000 @@ -2,7 +2,7 @@ * faces.el (glyphless-char): Inherit underline for tty. -2010-10-28 Kenichi Handa +2010-11-01 Kenichi Handa Implement various display methods for glyphless characters. === modified file 'src/ChangeLog' --- src/ChangeLog 2010-11-01 07:53:08 +0000 +++ src/ChangeLog 2010-11-01 14:59:31 +0000 @@ -7,8 +7,7 @@ * coding.c (Fset_terminal_coding_system_internal): Set the `charset_list' member of struct terminal. - * term.c (produce_glyphs): Handle the case it->what == - IT_GLYPHLESS. + * term.c (produce_glyphs): Handle the case it->what == IT_GLYPHLESS. (append_glyphless_glyph, produce_glyphless_glyph): New functions. * xdisp.c (lookup_glyphless_char_display): Make it non-static. @@ -16,15 +15,15 @@ (last_glyphless_glyph_frame, last_glyphless_glyph_face_id) (last_glyphless_glyph_merged_face_id): Make them non-static. - * w32term.c (x_draw_glyphless_glyph_string_foreground): Fix - the arg with_background for font->driver->draw. - -2010-10-29 Kenichi Handa - - * w32gui.h (STORE_XCHAR2B, XCHAR2B_BYTE1, XCHAR2B_BYTE2): Surround - chp by parentheses. - -2010-10-28 Kenichi Handa + * w32term.c (x_draw_glyphless_glyph_string_foreground): + Fix the arg with_background for font->driver->draw. + +2010-11-01 Kenichi Handa + + * w32gui.h (STORE_XCHAR2B, XCHAR2B_BYTE1, XCHAR2B_BYTE2): + Surround chp by parentheses. + +2010-11-01 Kenichi Handa Implement various display methods for glyphless characters. @@ -50,8 +49,8 @@ (Vglyphless_char_display): Declare it as a Lisp variable. * dispextern.h (enum glyph_type): Add GLYPHLESS_GLYPH. - (struct glyph): Change the size of the member "type" to 3. Add - glyphless to the union slice and u. + (struct glyph): Change the size of the member "type" to 3. + Add glyphless to the union slice and u. (enum display_element_type): Add IT_GLYPHLESS. (enum glyphless_display_method): New enum. (struct it): New member glyphless_method. @@ -60,8 +59,7 @@ * xterm.c (x_draw_glyphless_glyph_string_foreground): New function. (x_draw_glyph_string): Handle the case GLYPHLESS_GLYPH. - * w32term.c (x_draw_glyphless_glyph_string_foreground): New - function. + * w32term.c (x_draw_glyphless_glyph_string_foreground): New function. (x_draw_glyph_string): Handle the case GLYPHLESS_GLYPH. * nsterm.m (ns_draw_glyph_string): Handle the case ------------------------------------------------------------ revno: 102210 [merge] committer: Kenichi Handa branch nick: trunk timestamp: Mon 2010-11-01 16:56:16 +0900 message: Implement various display methods for glyphless characters. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2010-11-01 07:40:11 +0000 +++ lisp/ChangeLog 2010-11-01 07:55:44 +0000 @@ -1,3 +1,17 @@ +2010-11-01 Kenichi Handa + + * faces.el (glyphless-char): Inherit underline for tty. + +2010-10-28 Kenichi Handa + + Implement various display methods for glyphless characters. + + * international/characters.el (char-acronym-table): New variable. + (glyphless-char-control): New variable. + (update-glyphless-char-display): New funciton. + + * faces.el (glyphless-char): New face. + 2010-11-01 Glenn Morris * calendar/holidays.el (general-holidays, oriental-holidays) === modified file 'lisp/faces.el' --- lisp/faces.el 2010-11-01 06:13:43 +0000 +++ lisp/faces.el 2010-11-01 07:53:08 +0000 @@ -2482,6 +2482,14 @@ (defface help-argument-name '((((supports :slant italic)) :inherit italic)) "Face to highlight argument names in *Help* buffers." :group 'help) + +(defface glyphless-char + '((((type tty)) :inherit underline) + (t :height 0.6)) + "Face for displaying non-graphic characters (e.g. U+202A (LRE)). +It is used for characters of no fonts too." + :version "24.1" + :group 'basic-faces) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Manipulating font names. === modified file 'lisp/international/characters.el' --- lisp/international/characters.el 2010-10-15 00:41:53 +0000 +++ lisp/international/characters.el 2010-10-29 00:50:13 +0000 @@ -1234,6 +1234,131 @@ (optimize-char-table (standard-category-table)) +;; Display of glyphless characters. + +(defvar char-acronym-table + (make-char-table 'char-acronym-table nil) + "Char table of acronyms for non-graphic characters.") + +(let ((c0-acronyms '("NUL" "SOH" "STX" "ETX" "EOT" "ENQ" "ACK" "BEL" + "BS" nil nil "VT" "FF" "CR" "SO" "SI" + "DLE" "DC1" "DC2" "DC3" "DC4" "NAK" "SYN" "ETB" + "CAN" "EM" "SUB" "ESC" "FC" "GS" "RS" "US"))) + (dotimes (i 32) + (aset char-acronym-table i (car c0-acronyms)) + (setq c0-acronyms (cdr c0-acronyms)))) + +(let ((c1-acronyms '("XXX" "XXX" "BPH" "NBH" "IND" "NEL" "SSA" "ESA" + "HTS" "HTJ" "VTS" "PLD" "PLU" "R1" "SS2" "SS1" + "DCS" "PU1" "PU2" "STS" "CCH" "MW" "SPA" "EPA" + "SOS" "XXX" "SC1" "CSI" "ST" "OSC" "PM" "APC"))) + (dotimes (i 32) + (aset char-acronym-table (+ #x0080 i) (car c1-acronyms)) + (setq c1-acronyms (cdr c1-acronyms)))) + +(aset char-acronym-table #x17B4 "KIVAQ") ; KHMER VOWEL INHERENT AQ +(aset char-acronym-table #x17B5 "KIVAA") ; KHMER VOWEL INHERENT AA +(aset char-acronym-table #x200B "ZWSP") ; ZERO WIDTH SPACE +(aset char-acronym-table #x200C "ZWNJ") ; ZERO WIDTH NON-JOINER +(aset char-acronym-table #x200D "ZWJ") ; ZERO WIDTH JOINER +(aset char-acronym-table #x200E "LRM") ; LEFT-TO-RIGHT MARK +(aset char-acronym-table #x200F "RLM") ; RIGHT-TO-LEFT MARK +(aset char-acronym-table #x202A "LRE") ; LEFT-TO-RIGHT EMBEDDING +(aset char-acronym-table #x202B "RLE") ; RIGHT-TO-LEFT EMBEDDING +(aset char-acronym-table #x202C "PDF") ; POP DIRECTIONAL FORMATTING +(aset char-acronym-table #x202D "LRO") ; LEFT-TO-RIGHT OVERRIDE +(aset char-acronym-table #x202E "RLO") ; RIGHT-TO-LEFT OVERRIDE +(aset char-acronym-table #x2060 "WJ") ; WORD JOINER +(aset char-acronym-table #x206A "ISS") ; INHIBIT SYMMETRIC SWAPPING +(aset char-acronym-table #x206B "ASS") ; ACTIVATE SYMMETRIC SWAPPING +(aset char-acronym-table #x206C "IAFS") ; INHIBIT ARABIC FORM SHAPING +(aset char-acronym-table #x206D "AAFS") ; ACTIVATE ARABIC FORM SHAPING +(aset char-acronym-table #x206E "NADS") ; NATIONAL DIGIT SHAPES +(aset char-acronym-table #x206F "NODS") ; NOMINAL DIGIT SHAPES +(aset char-acronym-table #xFEFF "ZWNBSP") ; ZERO WIDTH NO-BREAK SPACE +(aset char-acronym-table #xFFF9 "IAA") ; INTERLINEAR ANNOTATION ANCHOR +(aset char-acronym-table #xFFFA "IAS") ; INTERLINEAR ANNOTATION SEPARATOR +(aset char-acronym-table #xFFFB "IAT") ; INTERLINEAR ANNOTATION TERMINATOR +(aset char-acronym-table #x1D173 "BEGBM") ; MUSICAL SYMBOL BEGIN BEAM +(aset char-acronym-table #x1D174 "ENDBM") ; MUSICAL SYMBOL END BEAM +(aset char-acronym-table #x1D175 "BEGTIE") ; MUSICAL SYMBOL BEGIN TIE +(aset char-acronym-table #x1D176 "END") ; MUSICAL SYMBOL END TIE +(aset char-acronym-table #x1D177 "BEGSLR") ; MUSICAL SYMBOL BEGIN SLUR +(aset char-acronym-table #x1D178 "ENDSLR") ; MUSICAL SYMBOL END SLUR +(aset char-acronym-table #x1D179 "BEGPHR") ; MUSICAL SYMBOL BEGIN PHRASE +(aset char-acronym-table #x1D17A "ENDPHR") ; MUSICAL SYMBOL END PHRASE +(aset char-acronym-table #xE0001 "|->TAG") ; LANGUAGE TAG +(aset char-acronym-table #xE0020 "SP TAG") ; TAG SPACE +(dotimes (i 94) + (aset char-acronym-table (+ #xE0021 i) (format " %c TAG" (+ 33 i)))) +(aset char-acronym-table #xE007F "->|TAG") ; CANCEL TAG + +;;; Control of displaying glyphless characters. +(defvar glyphless-char-control + '((format-control . thin-space) + (no-font . hexa-code)) + "List of directives to control displaying of glyphless characters. + +Each element has the form (TARGET . METHOD), where TARGET is a +symbol specifying the target character group to control, and +METHOD is a symbol specifying the method of displaying them. + +TARGET must be one of these symbols: + `c0-control': U+0000..U+001F. + `c1-control': U+0080..U+009F. + `format-control': Characters of Unicode General Category `Cf'. + Ex: U+200C (ZWNJ), U+200E (LRM)), but don't include characters + that have graphic image such as U+00AD (SHY). + `no-font': characters for which no suitable font is found. + +METHOD must be one of these symbols: + `zero-width': don't display. + `thin-space': display a thin space (1-pixel width). + `empty-box': display an empty box. + `acronym': display an acronum string in a box. + `hexa-code': display a hexadecimal character code in a box. + +Just setting this variable does not take effect. Call the +function `update-glyphless-char-display' (which see) after +setting this variable.") + +(defun update-glyphless-char-display () + "Make the setting of `glyphless-char-control' take effect. +This function updates the char-table `glyphless-char-display'." + (dolist (elt glyphless-char-control) + (let ((target (car elt)) + (method (cdr elt))) + (cond ((eq target 'c0-control) + (set-char-table-range glyphless-char-display '(#x00 . #x1F) + method)) + ((eq target 'c1-control) + (set-char-table-range glyphless-char-display '(#x80 . #x9F) + method)) + ((eq target 'format-control) + (map-char-table + #'(lambda (char category) + (if (eq category 'Cf) + (let ((this-method method) + from to) + (if (consp char) + (setq from (car char) to (cdr char)) + (setq from char to char)) + (while (<= from to) + (when (/= from #xAD) + (if (eq method 'acronym) + (setq this-method + (aref char-acronym-table from))) + (set-char-table-range glyphless-char-display + from this-method)) + (setq from (1+ from)))))) + unicode-category-table)) + ((eq target 'no-font) + (set-char-table-extra-slot glyphless-char-display 0 method)) + (t + (error "Invalid target character group: %s" target)))))) + +(update-glyphless-char-display) + ;;; Setting word boundary. (setq word-combining-categories === modified file 'src/ChangeLog' --- src/ChangeLog 2010-10-31 22:35:44 +0000 +++ src/ChangeLog 2010-11-01 07:53:08 +0000 @@ -1,3 +1,72 @@ +2010-11-01 Kenichi Handa + + * dispextern.h (lookup_glyphless_char_display): Extern it. + + * termhooks.h (struct terminal): New member charset_list. + + * coding.c (Fset_terminal_coding_system_internal): Set the + `charset_list' member of struct terminal. + + * term.c (produce_glyphs): Handle the case it->what == + IT_GLYPHLESS. + (append_glyphless_glyph, produce_glyphless_glyph): New functions. + + * xdisp.c (lookup_glyphless_char_display): Make it non-static. + (lookup_glyphless_char_display): Set it->what at the end. + (last_glyphless_glyph_frame, last_glyphless_glyph_face_id) + (last_glyphless_glyph_merged_face_id): Make them non-static. + + * w32term.c (x_draw_glyphless_glyph_string_foreground): Fix + the arg with_background for font->driver->draw. + +2010-10-29 Kenichi Handa + + * w32gui.h (STORE_XCHAR2B, XCHAR2B_BYTE1, XCHAR2B_BYTE2): Surround + chp by parentheses. + +2010-10-28 Kenichi Handa + + Implement various display methods for glyphless characters. + + * xdisp.c (Qglyphless_char, Vglyphless_char_display) + (Qglyphless_char_display, Qhexa_code, Qempty_box, Qthin_space) + (Qzero_width): New variables. + (THIN_SPACE_WIDTH): New macro. + (lookup_glyphless_char_display): New funciton. + (last_glyphless_glyph_frame, last_glyphless_glyph_face_id) + (last_glyphless_glyph_merged_face_id): New variables. + (get_next_display_element): Check glyphless characters. + (redisplay_internal): Initialize last_glyphless_glyph_frame and + last_glyphless_glyph_face_id. + (fill_glyphless_glyph_string): New function. + (BUILD_GLYPHLESS_GLYPH_STRING): New macro. + (BUILD_GLYPH_STRINGS): Handle the case GLYPHLESS_GLYPH. + (append_glyphless_glyph, produce_glyphless_glyph): New functions. + (x_produce_glyphs): If a suitable font is not found, produce a + glyphless glyph. Handle the case it->what == IT_GLYPHLESS. + (syms_of_xdisp): Intern and staticpro Qglyphless_char, + Qglyphless_char_display, Qhexa_code, Qempty_box, Qthin_space, and + Qzero_width. + (Vglyphless_char_display): Declare it as a Lisp variable. + + * dispextern.h (enum glyph_type): Add GLYPHLESS_GLYPH. + (struct glyph): Change the size of the member "type" to 3. Add + glyphless to the union slice and u. + (enum display_element_type): Add IT_GLYPHLESS. + (enum glyphless_display_method): New enum. + (struct it): New member glyphless_method. + (Vglyphless_char_display): Extern it. + + * xterm.c (x_draw_glyphless_glyph_string_foreground): New function. + (x_draw_glyph_string): Handle the case GLYPHLESS_GLYPH. + + * w32term.c (x_draw_glyphless_glyph_string_foreground): New + function. + (x_draw_glyph_string): Handle the case GLYPHLESS_GLYPH. + + * nsterm.m (ns_draw_glyph_string): Handle the case + GLYPHLESS_GLYPH (the detail is not yet implemented). + 2010-10-31 Glenn Morris * xterm.c (x_connection_closed) [USE_X_TOOLKIT]: Fix merge, maybe. === modified file 'src/coding.c' --- src/coding.c 2010-10-14 14:32:27 +0000 +++ src/coding.c 2010-11-01 04:09:26 +0000 @@ -9297,7 +9297,8 @@ doc: /* Internal use only. */) (Lisp_Object coding_system, Lisp_Object terminal) { - struct coding_system *terminal_coding = TERMINAL_TERMINAL_CODING (get_terminal (terminal, 1)); + struct terminal *term = get_terminal (terminal, 1); + struct coding_system *terminal_coding = TERMINAL_TERMINAL_CODING (term); CHECK_SYMBOL (coding_system); setup_coding_system (Fcheck_coding_system (coding_system), terminal_coding); /* We had better not send unsafe characters to terminal. */ @@ -9306,6 +9307,10 @@ terminal_coding->common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK; terminal_coding->src_multibyte = 1; terminal_coding->dst_multibyte = 0; + if (terminal_coding->common_flags & CODING_REQUIRE_ENCODING_MASK) + term->charset_list = coding_charset_list (terminal_coding); + else + term->charset_list = Fcons (Qascii, Qnil); return Qnil; } === modified file 'src/dispextern.h' --- src/dispextern.h 2010-10-14 14:32:27 +0000 +++ src/dispextern.h 2010-11-01 04:09:26 +0000 @@ -279,6 +279,9 @@ /* Glyph describes a static composition. */ COMPOSITE_GLYPH, + /* Glyph describes a glyphless character. */ + GLYPHLESS_GLYPH, + /* Glyph describes an image. */ IMAGE_GLYPH, @@ -333,7 +336,7 @@ /* Which kind of glyph this is---character, image etc. Value should be an enumerator of type enum glyph_type. */ - unsigned type : 2; + unsigned type : 3; /* 1 means this glyph was produced from multibyte text. Zero means it was produced from unibyte text, i.e. charsets aren't @@ -402,6 +405,11 @@ /* Start and end indices of glyphs of a graphme cluster of a composition (type == COMPOSITE_GLYPH). */ struct { int from, to; } cmp; + /* Pixel offsets for upper and lower part of the acronym. */ + struct { + short upper_xoff, upper_yoff; + short lower_xoff, lower_yoff; + } glyphless; } slice; /* A union of sub-structures for different glyph types. */ @@ -433,6 +441,19 @@ } stretch; + /* Sub-stretch for type == GLYPHLESS_GLYPH. */ + struct + { + /* Value is an enum of the type glyphless_display_method. */ + unsigned method : 2; + /* 1 iff this glyph is for a character of no font. */ + unsigned for_no_font : 1; + /* Length of acronym or hexadecimal code string (at most 8). */ + unsigned len : 4; + /* Character to display. Actually we need only 22 bits. */ + unsigned ch : 26; + } glyphless; + /* Used to compare all bit-fields above in one step. */ unsigned val; } u; @@ -1918,6 +1939,9 @@ /* A composition (static and automatic). */ IT_COMPOSITION, + /* A glyphless character (e.g. ZWNJ, LRE). */ + IT_GLYPHLESS, + /* An image. */ IT_IMAGE, @@ -1964,6 +1988,20 @@ WINDOW_WRAP }; +/* An enumerator for the method of displaying glyphless characters. */ + +enum glyphless_display_method + { + /* Display a thin (1-pixel width) space. */ + GLYPHLESS_DISPLAY_THIN_SPACE, + /* Display an empty box of proper width. */ + GLYPHLESS_DISPLAY_EMPTY_BOX, + /* Display an acronym string in a box. */ + GLYPHLESS_DISPLAY_ACRONYM, + /* Display a hexadecimal character code in a box. */ + GLYPHLESS_DISPLAY_HEXA_CODE + }; + struct it_slice { Lisp_Object x; @@ -2295,6 +2333,10 @@ PRODUCE_GLYPHS, this should be set beforehand too. */ int char_to_display; + /* If what == IT_GLYPHLESS, the method to display such a + character. */ + enum glyphless_display_method glyphless_method; + /* If what == IT_IMAGE, the id of the image to display. */ int image_id; @@ -2976,9 +3018,10 @@ extern Lisp_Object Vmouse_autoselect_window; extern int unibyte_display_via_language_environment; extern EMACS_INT underline_minimum_offset; +extern Lisp_Object Vglyphless_char_display; extern void reseat_at_previous_visible_line_start (struct it *); - +extern Lisp_Object lookup_glyphless_char_display (int, struct it *); extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, struct font *, int, int *); === modified file 'src/nsterm.m' --- src/nsterm.m 2010-10-14 14:32:27 +0000 +++ src/nsterm.m 2010-10-29 00:50:13 +0000 @@ -2983,6 +2983,22 @@ ns_unfocus (s->f); break; + case GLYPHLESS_GLYPH: + n = ns_get_glyph_string_clip_rect (s, r); + ns_focus (s->f, r, n); + + if (s->for_overlaps || (s->cmp_from > 0 + && ! s->first_glyph->u.cmp.automatic)) + s->background_filled_p = 1; + else + ns_maybe_dumpglyphs_background + (s, s->first_glyph->type == COMPOSITE_GLYPH); + /* ... */ + /* Not yet implemented. */ + /* ... */ + ns_unfocus (s->f); + break; + default: abort (); } === modified file 'src/term.c' --- src/term.c 2010-10-01 20:18:24 +0000 +++ src/term.c 2010-11-01 04:09:26 +0000 @@ -1501,6 +1501,8 @@ static void produce_stretch_glyph (struct it *); static void append_composite_glyph (struct it *); static void produce_composite_glyph (struct it *); +static void append_glyphless_glyph (struct it *, int, char *); +static void produce_glyphless_glyph (struct it *, int, Lisp_Object); /* Append glyphs to IT's glyph_row. Called from produce_glyphs for terminal frames if IT->glyph_row != NULL. IT->char_to_display is @@ -1609,6 +1611,12 @@ goto done; } + if (it->what == IT_GLYPHLESS) + { + produce_glyphless_glyph (it, 0, Qnil); + goto done; + } + if (it->char_to_display >= 040 && it->char_to_display < 0177) { it->pixel_width = it->nglyphs = 1; @@ -1660,11 +1668,22 @@ } else { - it->pixel_width = CHAR_WIDTH (it->char_to_display); - it->nglyphs = it->pixel_width; - - if (it->glyph_row) - append_glyph (it); + Lisp_Object charset_list = FRAME_TERMINAL (it->f)->charset_list; + + if (char_charset (it->char_to_display, charset_list, NULL)) + { + it->pixel_width = CHAR_WIDTH (it->char_to_display); + it->nglyphs = it->pixel_width; + if (it->glyph_row) + append_glyph (it); + } + else + { + Lisp_Object acronym = lookup_glyphless_char_display (-1, it); + + xassert (it->what == IT_GLYPHLESS); + produce_glyphless_glyph (it, 1, acronym); + } } done: @@ -1844,6 +1863,161 @@ } +/* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID + is a face ID to be used for the glyph. What actually appended are + glyphs of type CHAR_GLYPH of which characters are in STR + (it->nglyphs bytes). */ + +static void +append_glyphless_glyph (struct it *it, int face_id, char *str) +{ + struct glyph *glyph, *end; + bidi_type_t bidi_type; + int resolved_level; + int i; + + xassert (it->glyph_row); + glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area]; + end = it->glyph_row->glyphs[1 + it->area]; + + /* If the glyph row is reversed, we need to prepend the glyph rather + than append it. */ + if (it->glyph_row->reversed_p && it->area == TEXT_AREA) + { + struct glyph *g; + int move_by = it->pixel_width; + + /* Make room for the new glyphs. */ + if (move_by > end - glyph) /* don't overstep end of this area */ + move_by = end - glyph; + for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--) + g[move_by] = *g; + glyph = it->glyph_row->glyphs[it->area]; + end = glyph + move_by; + } + + if (glyph >= end) + return; + glyph->type = CHAR_GLYPH; + glyph->pixel_width = 1; + glyph->face_id = face_id; + glyph->padding_p = 0; + glyph->charpos = CHARPOS (it->position); + glyph->object = it->object; + if (it->bidi_p) + { + glyph->resolved_level = it->bidi_it.resolved_level; + if ((it->bidi_it.type & 7) != it->bidi_it.type) + abort (); + glyph->bidi_type = it->bidi_it.type; + } + else + { + glyph->resolved_level = 0; + glyph->bidi_type = UNKNOWN_BT; + } + + /* BIDI Note: we put the glyphs of characters left to right, even in + the REVERSED_P case because we write to the terminal + left-to-right. */ + for (i = 0; i < it->nglyphs && glyph < end; ++i) + { + if (i > 0) + glyph[0] = glyph[-1]; + glyph->u.ch = str[i]; + ++it->glyph_row->used[it->area]; + ++glyph; + } +} + +/* Declared in xdisp.c */ +extern struct frame *last_glyphless_glyph_frame; +extern unsigned last_glyphless_glyph_face_id; +extern int last_glyphless_glyph_merged_face_id; +extern Lisp_Object Qglyphless_char; + +/* Produce glyphs for a glyphless character for iterator IT. + IT->glyphless_method specifies which method to use for displaying + the character. See the description of enum + glyphless_display_method in dispextern.h for the detail. + + FOR_NO_FONT is nonzero if and only if this is for a character that + is not supproted by the coding system of the terminal. ACRONYM, if + non-nil, is an acronym string for the character. + + The glyphs actually produced are of type CHAR_GLYPH. */ + +static void +produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym) +{ + int face_id; + struct face *face; + int width, len; + char buf[9], *str = " "; + + /* Get a face ID for the glyph by utilizing a cache (the same way as + doen for `escape-glyph' in get_next_display_element). */ + if (it->f == last_glyphless_glyph_frame + && it->face_id == last_glyphless_glyph_face_id) + { + face_id = last_glyphless_glyph_merged_face_id; + } + else + { + /* Merge the `glyphless-char' face into the current face. */ + face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id); + last_glyphless_glyph_frame = it->f; + last_glyphless_glyph_face_id = it->face_id; + last_glyphless_glyph_merged_face_id = face_id; + } + + if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE) + { + /* As there's no way to produce a thin space, we produce + a space of canonical width.. */ + len = 1; + } + else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX) + { + len = CHAR_WIDTH (it->c); + if (len == 0) + len = 1; + else if (width > 4) + len = 4; + } + else + { + if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM) + { + int i; + + if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display)) + acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c); + buf[0] = '['; + str = STRINGP (acronym) ? (char *) SDATA (acronym) : ""; + for (len = 0; len < 6 && str[len] && ASCII_BYTE_P (str[len]); len++) + buf[1 + len] = str[len]; + buf[1 + len] = ']'; + len += 2; + } + else + { + xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEXA_CODE); + len = (it->c < 0x100 ? sprintf (buf, "U+%02X", it->c) + : it->c < 0x10000 ? sprintf (buf, "U+%04X", it->c) + : it->c <= MAX_UNICODE_CHAR ? sprintf (buf, "U+%06X", it->c) + : sprintf (buf, "E+%06X", it->c)); + } + str = buf; + } + + it->pixel_width = len; + it->nglyphs = len; + if (len > 0 && it->glyph_row) + append_glyphless_glyph (it, face_id, str); +} + + /* Get information about special display element WHAT in an environment described by IT. WHAT is one of IT_TRUNCATION or IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a === modified file 'src/termhooks.h' --- src/termhooks.h 2010-10-03 16:21:55 +0000 +++ src/termhooks.h 2010-11-01 04:09:26 +0000 @@ -328,6 +328,11 @@ /* Parameter alist of this terminal. */ Lisp_Object param_alist; + /* List of charsets supported by the terminal. It is set by + Fset_terminal_coding_system_internal along with + the member terminal_coding. */ + Lisp_Object charset_list; + /* All fields before `next_terminal' should be Lisp_Object and are traced by the GC. All fields afterwards are ignored by the GC. */ === modified file 'src/w32gui.h' --- src/w32gui.h 2010-07-25 00:20:51 +0000 +++ src/w32gui.h 2010-10-29 02:01:41 +0000 @@ -59,13 +59,13 @@ /* Dealing with bits of wchar_t as if they were an XChar2b. */ #define STORE_XCHAR2B(chp, byte1, byte2) \ - ((*chp) = ((XChar2b)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))) + ((*(chp)) = ((XChar2b)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))) #define XCHAR2B_BYTE1(chp) \ - (((*chp) & 0xff00) >> 8) + (((*(chp)) & 0xff00) >> 8) #define XCHAR2B_BYTE2(chp) \ - ((*chp) & 0x00ff) + ((*(chp)) & 0x00ff) /* Windows equivalent of XImage. */ === modified file 'src/w32term.c' --- src/w32term.c 2010-10-24 01:22:37 +0000 +++ src/w32term.c 2010-11-01 07:35:04 +0000 @@ -1394,6 +1394,94 @@ } +/* Draw the foreground of glyph string S for glyphless characters. */ + +static void +x_draw_glyphless_glyph_string_foreground (struct glyph_string *s) +{ + struct glyph *glyph = s->first_glyph; + XChar2b char2b[8]; + int x, i, j; + int with_background; + + /* If first glyph of S has a left box line, start drawing the text + of S to the right of that box line. */ + if (s->face->box != FACE_NO_BOX + && s->first_glyph->left_box_line_p) + x = s->x + eabs (s->face->box_line_width); + else + x = s->x; + + SetTextColor (s->hdc, s->gc->foreground); + SetBkColor (s->hdc, s->gc->background); + SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT); + + s->char2b = char2b; + with_background = ! (s->for_overlaps + || (s->background_filled_p && s->hl != DRAW_CURSOR)); + for (i = 0; i < s->nchars; i++, glyph++) + { + char buf[7], *str = NULL; + int len = glyph->u.glyphless.len; + + if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM) + { + if (len > 1 + && CHAR_TABLE_P (Vglyphless_char_display) + && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) + >= 1)) + { + Lisp_Object acronym + = (! glyph->u.glyphless.for_no_font + ? CHAR_TABLE_REF (Vglyphless_char_display, + glyph->u.glyphless.ch) + : XCHAR_TABLE (Vglyphless_char_display)->extras[0]); + if (STRINGP (acronym)) + str = (char *) SDATA (acronym); + } + } + else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEXA_CODE) + { + sprintf ((char *) buf, "%0*X", + glyph->u.glyphless.ch < 0x10000 ? 4 : 6, + glyph->u.glyphless.ch); + str = buf; + } + + if (str) + { + struct font *font = s->font; + int upper_len = (len + 1) / 2; + unsigned code; + HFONT old_font; + + old_font = SelectObject (s->hdc, FONT_HANDLE (font)); + /* It is assured that all LEN characters in STR is ASCII. */ + for (j = 0; j < len; j++) + { + code = font->driver->encode_char (font, str[j]); + STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF); + } + font->driver->draw (s, 0, upper_len, + x + glyph->slice.glyphless.upper_xoff, + s->ybase + glyph->slice.glyphless.upper_yoff, + with_background); + font->driver->draw (s, upper_len, len, + x + glyph->slice.glyphless.lower_xoff, + s->ybase + glyph->slice.glyphless.lower_yoff, + with_background); + SelectObject (s->hdc, old_font); + } + if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE) + w32_draw_rectangle (s->hdc, s->gc, + x, s->ybase - glyph->ascent, + glyph->pixel_width - 1, + glyph->ascent + glyph->descent - 1); + x += glyph->pixel_width; + } +} + + /* Brightness beyond which a color won't have its highlight brightness boosted. @@ -2282,6 +2370,14 @@ x_draw_composite_glyph_string_foreground (s); break; + case GLYPHLESS_GLYPH: + if (s->for_overlaps) + s->background_filled_p = 1; + else + x_draw_glyph_string_background (s, 0); + x_draw_glyphless_glyph_string_foreground (s); + break; + default: abort (); } === modified file 'src/xdisp.c' --- src/xdisp.c 2010-10-23 21:19:02 +0000 +++ src/xdisp.c 2010-11-01 04:09:26 +0000 @@ -932,6 +932,21 @@ /* Number of seconds to wait before displaying an hourglass cursor. */ Lisp_Object Vhourglass_delay; +/* Name of the face used to display glyphless characters. */ +Lisp_Object Qglyphless_char; + +/* Char-table to control the display of glyphless characters. */ +Lisp_Object Vglyphless_char_display; + +/* Symbol for the purpose of Vglyphless_char_display. */ +Lisp_Object Qglyphless_char_display; + +/* Method symbols for Vglyphless_char_display. */ +static Lisp_Object Qhexa_code, Qempty_box, Qthin_space, Qzero_width; + +/* Default pixel width of `thin-space' display method. */ +#define THIN_SPACE_WIDTH 1 + /* Default number of seconds to wait before displaying an hourglass cursor. */ #define DEFAULT_HOURGLASS_DELAY 1 @@ -5732,6 +5747,57 @@ (IT)->string))) +/* Lookup the char-table Vglyphless_char_display for character C (-1 + if we want information for no-font case), and return the display + method symbol. By side-effect, update it->what and + it->glyphless_method. This function is called from + get_next_display_element for each character element, and from + x_produce_glyphs when no suitable font was found. */ + +Lisp_Object +lookup_glyphless_char_display (int c, struct it *it) +{ + Lisp_Object glyphless_method = Qnil; + + if (CHAR_TABLE_P (Vglyphless_char_display) + && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1) + glyphless_method = (c >= 0 + ? CHAR_TABLE_REF (Vglyphless_char_display, c) + : XCHAR_TABLE (Vglyphless_char_display)->extras[0]); + retry: + if (NILP (glyphless_method)) + { + if (c >= 0) + /* The default is to display the character by a proper font. */ + return Qnil; + /* The default for the no-font case is to display an empty box. */ + glyphless_method = Qempty_box; + } + if (EQ (glyphless_method, Qzero_width)) + { + if (c >= 0) + return glyphless_method; + /* This method can't be used for the no-font case. */ + glyphless_method = Qempty_box; + } + if (EQ (glyphless_method, Qthin_space)) + it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE; + else if (EQ (glyphless_method, Qempty_box)) + it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX; + else if (EQ (glyphless_method, Qhexa_code)) + it->glyphless_method = GLYPHLESS_DISPLAY_HEXA_CODE; + else if (STRINGP (glyphless_method)) + it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM; + else + { + /* Invalid value. We use the default method. */ + glyphless_method = Qnil; + goto retry; + } + it->what = IT_GLYPHLESS; + return glyphless_method; +} + /* Load IT's display element fields with information about the next display element from the current position of IT. Value is zero if end of buffer (or C string) is reached. */ @@ -5740,6 +5806,10 @@ static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS); static int last_escape_glyph_merged_face_id = 0; +struct frame *last_glyphless_glyph_frame = NULL; +unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS); +int last_glyphless_glyph_merged_face_id = 0; + int get_next_display_element (struct it *it) { @@ -5818,6 +5888,15 @@ goto get_next; } + if (! NILP (lookup_glyphless_char_display (c, it))) + { + if (it->what == IT_GLYPHLESS) + goto done; + /* Don't display this character. */ + set_iterator_to_next (it, 0); + goto get_next; + } + if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display)) nbsp_or_shy = (c == 0xA0 ? char_is_nbsp : c == 0xAD ? char_is_soft_hyphen @@ -6032,6 +6111,7 @@ } #endif + done: /* Is this character the last one of a run of characters with box? If yes, set IT->end_of_box_run_p to 1. */ if (it->face_box_p @@ -11579,6 +11659,8 @@ reconsider_clip_changes (w, current_buffer); last_escape_glyph_frame = NULL; last_escape_glyph_face_id = (1 << FACE_ID_BITS); + last_glyphless_glyph_frame = NULL; + last_glyphless_glyph_face_id = (1 << FACE_ID_BITS); /* If new fonts have been loaded that make a glyph matrix adjustment necessary, do it. */ @@ -20657,6 +20739,42 @@ } +/* Fill glyph string S from a sequence glyphs for glyphless characters. + See the comment of fill_glyph_string for arguments. + Value is the index of the first glyph not in S. */ + + +static int +fill_glyphless_glyph_string (struct glyph_string *s, int face_id, + int start, int end, int overlaps) +{ + struct glyph *glyph, *last; + int voffset; + + xassert (s->first_glyph->type == GLYPHLESS_GLYPH); + s->for_overlaps = overlaps; + glyph = s->row->glyphs[s->area] + start; + last = s->row->glyphs[s->area] + end; + voffset = glyph->voffset; + s->face = FACE_FROM_ID (s->f, face_id); + s->font = s->face->font; + s->nchars = 1; + s->width = glyph->pixel_width; + glyph++; + while (glyph < last + && glyph->type == GLYPHLESS_GLYPH + && glyph->voffset == voffset + && glyph->face_id == face_id) + { + s->nchars++; + s->width += glyph->pixel_width; + glyph++; + } + s->ybase += voffset; + return glyph - s->row->glyphs[s->area]; +} + + /* Fill glyph string S from a sequence of character glyphs. FACE_ID is the face id of the string. START is the index of the @@ -21167,6 +21285,28 @@ } while (0) +/* Add a glyph string for a sequence of glyphless character's glyphs + to the list of strings between HEAD and TAIL. The meanings of + arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */ + +#define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ + do \ + { \ + int face_id; \ + XChar2b *char2b; \ + \ + face_id = (row)->glyphs[area][START].face_id; \ + \ + s = (struct glyph_string *) alloca (sizeof *s); \ + INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \ + append_glyph_string (&HEAD, &TAIL, s); \ + s->x = (X); \ + START = fill_glyphless_glyph_string (s, face_id, START, END, \ + overlaps); \ + } \ + while (0) + + /* Build a list of glyph strings between HEAD and TAIL for the glyphs of AREA of glyph row ROW on window W between indices START and END. HL overrides the face for drawing glyph strings, e.g. it is @@ -21190,7 +21330,7 @@ BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \ HL, X, LAST_X); \ break; \ - \ + \ case COMPOSITE_GLYPH: \ if (first_glyph->u.cmp.automatic) \ BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \ @@ -21199,21 +21339,26 @@ BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \ HL, X, LAST_X); \ break; \ - \ + \ case STRETCH_GLYPH: \ BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \ HL, X, LAST_X); \ break; \ - \ + \ case IMAGE_GLYPH: \ BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \ HL, X, LAST_X); \ break; \ - \ + \ + case GLYPHLESS_GLYPH: \ + BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \ + HL, X, LAST_X); \ + break; \ + \ default: \ abort (); \ } \ - \ + \ if (s) \ { \ set_glyph_string_background_width (s, START, LAST_X); \ @@ -22109,6 +22254,229 @@ } +/* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID + is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if + and only if this is for a character for which no font was found. + + If the display method (it->glyphless_method) is + GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEXA_CODE, LEN is a + length of the acronym or the hexadecimal string, UPPER_XOFF and + UPPER_YOFF are pixel offsets for the upper part of the string, + LOWER_XOFF and LOWER_YOFF are for the lower part. + + For the other display methods, LEN through LOWER_YOFF are zero. */ + +static void +append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len, + short upper_xoff, short upper_yoff, + short lower_xoff, short lower_yoff) +{ + struct glyph *glyph; + enum glyph_row_area area = it->area; + + glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; + if (glyph < it->glyph_row->glyphs[area + 1]) + { + /* If the glyph row is reversed, we need to prepend the glyph + rather than append it. */ + if (it->glyph_row->reversed_p && area == TEXT_AREA) + { + struct glyph *g; + + /* Make room for the additional glyph. */ + for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--) + g[1] = *g; + glyph = it->glyph_row->glyphs[area]; + } + glyph->charpos = CHARPOS (it->position); + glyph->object = it->object; + glyph->pixel_width = it->pixel_width; + glyph->ascent = it->ascent; + glyph->descent = it->descent; + glyph->voffset = it->voffset; + glyph->type = GLYPHLESS_GLYPH; + glyph->u.glyphless.method = it->glyphless_method; + glyph->u.glyphless.for_no_font = for_no_font; + glyph->u.glyphless.len = len; + glyph->u.glyphless.ch = it->c; + glyph->slice.glyphless.upper_xoff = upper_xoff; + glyph->slice.glyphless.upper_yoff = upper_yoff; + glyph->slice.glyphless.lower_xoff = lower_xoff; + glyph->slice.glyphless.lower_yoff = lower_yoff; + glyph->avoid_cursor_p = it->avoid_cursor_p; + glyph->multibyte_p = it->multibyte_p; + glyph->left_box_line_p = it->start_of_box_run_p; + glyph->right_box_line_p = it->end_of_box_run_p; + glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent + || it->phys_descent > it->descent); + glyph->padding_p = 0; + glyph->glyph_not_available_p = 0; + glyph->face_id = face_id; + glyph->font_type = FONT_TYPE_UNKNOWN; + if (it->bidi_p) + { + glyph->resolved_level = it->bidi_it.resolved_level; + if ((it->bidi_it.type & 7) != it->bidi_it.type) + abort (); + glyph->bidi_type = it->bidi_it.type; + } + ++it->glyph_row->used[area]; + } + else + IT_EXPAND_MATRIX_WIDTH (it, area); +} + + +/* Produce a glyph for a glyphless character for iterator IT. + IT->glyphless_method specifies which method to use for displaying + the character. See the description of enum + glyphless_display_method in dispextern.h for the detail. + + FOR_NO_FONT is nonzero if and only if this is for a character for + which no font was found. ACRONYM, if non-nil, is an acronym string + for the character. */ + +static void +produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym) +{ + int face_id; + struct face *face; + struct font *font; + int base_width, base_height, width, height; + short upper_xoff, upper_yoff, lower_xoff, lower_yoff; + int len; + + /* Get the metrics of the base font. We always refer to the current + ASCII face. */ + face = FACE_FROM_ID (it->f, it->face_id)->ascii_face; + font = face->font ? face->font : FRAME_FONT (it->f); + it->ascent = FONT_BASE (font) + font->baseline_offset; + it->descent = FONT_DESCENT (font) - font->baseline_offset; + base_height = it->ascent + it->descent; + base_width = font->average_width; + + /* Get a face ID for the glyph by utilizing a cache (the same way as + doen for `escape-glyph' in get_next_display_element). */ + if (it->f == last_glyphless_glyph_frame + && it->face_id == last_glyphless_glyph_face_id) + { + face_id = last_glyphless_glyph_merged_face_id; + } + else + { + /* Merge the `glyphless-char' face into the current face. */ + face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id); + last_glyphless_glyph_frame = it->f; + last_glyphless_glyph_face_id = it->face_id; + last_glyphless_glyph_merged_face_id = face_id; + } + + if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE) + { + it->pixel_width = THIN_SPACE_WIDTH; + len = 0; + upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0; + } + else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX) + { + width = CHAR_WIDTH (it->c); + if (width == 0) + width = 1; + else if (width > 4) + width = 4; + it->pixel_width = base_width * width; + len = 0; + upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0; + } + else + { + char buf[7], *str; + unsigned int code[6]; + int upper_len; + int ascent, descent; + struct font_metrics metrics_upper, metrics_lower; + + face = FACE_FROM_ID (it->f, face_id); + font = face->font ? face->font : FRAME_FONT (it->f); + PREPARE_FACE_FOR_DISPLAY (it->f, face); + + if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM) + { + if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display)) + acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c); + str = STRINGP (acronym) ? (char *) SDATA (acronym) : ""; + } + else + { + xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEXA_CODE); + sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c); + str = buf; + } + for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++) + code[len] = font->driver->encode_char (font, str[len]); + upper_len = (len + 1) / 2; + font->driver->text_extents (font, code, upper_len, + &metrics_upper); + font->driver->text_extents (font, code + upper_len, len - upper_len, + &metrics_lower); + + + + /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */ + width = max (metrics_upper.width, metrics_lower.width) + 4; + upper_xoff = upper_yoff = 2; /* the typical case */ + if (base_width >= width) + { + /* Align the upper to the left, the lower to the right. */ + it->pixel_width = base_width; + lower_xoff = base_width - 2 - metrics_lower.width; + } + else + { + /* Center the shorter one. */ + it->pixel_width = width; + if (metrics_upper.width >= metrics_lower.width) + lower_xoff = (width - metrics_lower.width) / 2; + else + upper_xoff = (width - metrics_upper.width) / 2; + } + + /* +5 is for horizontal bars of a box plus 1-pixel spaces at + top, bottom, and between upper and lower strings. */ + height = (metrics_upper.ascent + metrics_upper.descent + + metrics_lower.ascent + metrics_lower.descent) + 5; + /* Center vertically. + H:base_height, D:base_descent + h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent + + ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up + descent = D - H/2 + h/2; + lower_yoff = descent - 2 - ld; + upper_yoff = lower_yoff - la - 1 - ud; */ + ascent = - (it->descent - (base_height + height + 1) / 2); + descent = it->descent - (base_height - height) / 2; + lower_yoff = descent - 2 - metrics_lower.descent; + upper_yoff = (lower_yoff - metrics_lower.ascent - 1 + - metrics_upper.descent); + /* Don't make the height shorter than the base height. */ + if (height > base_height) + { + it->ascent = ascent; + it->descent = descent; + } + } + + it->phys_ascent = it->ascent; + it->phys_descent = it->descent; + if (it->glyph_row) + append_glyphless_glyph (it, face_id, for_no_font, len, + upper_xoff, upper_yoff, + lower_xoff, lower_yoff); + it->nglyphs = 1; + take_vertical_position_into_account (it); +} + + /* RIF: Produce glyphs/get display metrics for the display element IT is loaded with. See the description of struct it in dispextern.h @@ -22126,28 +22494,24 @@ XChar2b char2b; struct face *face = FACE_FROM_ID (it->f, it->face_id); struct font *font = face->font; - int font_not_found_p = font == NULL; struct font_metrics *pcm = NULL; int boff; /* baseline offset */ - if (font_not_found_p) - { - /* When no suitable font found, display an empty box based - on the metrics of the font of the default face (or what - remapped). */ - struct face *no_font_face - = FACE_FROM_ID (it->f, - NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID - : lookup_basic_face (it->f, DEFAULT_FACE_ID)); - font = no_font_face->font; - boff = font->baseline_offset; - } - else - { - boff = font->baseline_offset; - if (font->vertical_centering) - boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; - } + if (font == NULL) + { + /* When no suitable font is found, display this character by + the method specified in the first extra slot of + Vglyphless_char_display. */ + Lisp_Object acronym = lookup_glyphless_char_display (-1, it); + + xassert (it->what == IT_GLYPHLESS); + produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil); + goto done; + } + + boff = font->baseline_offset; + if (font->vertical_centering) + boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; if (it->char_to_display != '\n' && it->char_to_display != '\t') { @@ -22167,8 +22531,7 @@ it->descent = FONT_DESCENT (font) - boff; } - if (! font_not_found_p - && get_char_glyph_code (it->char_to_display, font, &char2b)) + if (get_char_glyph_code (it->char_to_display, font, &char2b)) { pcm = get_per_char_metric (it->f, font, &char2b); if (pcm->width == 0 @@ -22758,11 +23121,14 @@ if (it->glyph_row) append_composite_glyph (it); } + else if (it->what == IT_GLYPHLESS) + produce_glyphless_glyph (it, 0, Qnil); else if (it->what == IT_IMAGE) produce_image_glyph (it); else if (it->what == IT_STRETCH) produce_stretch_glyph (it); + done: /* Accumulate dimensions. Note: can't assume that it->descent > 0 because this isn't true for images with `:ascent 100'. */ xassert (it->ascent >= 0 && it->descent >= 0); @@ -26592,6 +26958,35 @@ hourglass_atimer = NULL; hourglass_shown_p = 0; + + DEFSYM (Qglyphless_char, "glyphless-char"); + DEFSYM (Qhexa_code, "hexa-code"); + DEFSYM (Qempty_box, "empty-box"); + DEFSYM (Qthin_space, "thin-space"); + DEFSYM (Qzero_width, "zero-width"); + + DEFSYM (Qglyphless_char_display, "glyphless-char-display"); + /* Intern this now in case it isn't already done. + Setting this variable twice is harmless. + But don't staticpro it here--that is done in alloc.c. */ + Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); + Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1)); + + DEFVAR_LISP ("glyphless-char-display", &Vglyphless_char_display, + doc: /* Char-table to control displaying of glyphless characters. +Each element, if non-nil, is an ASCII acronym string (displayed in a box) +or one of these symbols: + hexa-code: display with hexadecimal character code in a box + empty-box: display with an empty box + thin-space: display with 1-pixel width space + zero-width: don't display + +It has one extra slot to control the display of a character for which +no font is found. The value of the slot is `hexa-code' or `empty-box'. +The default is `empty-box'. */); + Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil); + Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0), + Qempty_box); } === modified file 'src/xterm.c' --- src/xterm.c 2010-10-31 22:35:44 +0000 +++ src/xterm.c 2010-11-01 07:53:08 +0000 @@ -1330,6 +1330,83 @@ } +/* Draw the foreground of glyph string S for glyphless characters. */ + +static void +x_draw_glyphless_glyph_string_foreground (struct glyph_string *s) +{ + struct glyph *glyph = s->first_glyph; + XChar2b char2b[8]; + int x, i, j; + + /* If first glyph of S has a left box line, start drawing the text + of S to the right of that box line. */ + if (s->face && s->face->box != FACE_NO_BOX + && s->first_glyph->left_box_line_p) + x = s->x + eabs (s->face->box_line_width); + else + x = s->x; + + s->char2b = char2b; + + for (i = 0; i < s->nchars; i++, glyph++) + { + char buf[7], *str = NULL; + int len = glyph->u.glyphless.len; + + if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM) + { + if (len > 0 + && CHAR_TABLE_P (Vglyphless_char_display) + && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) + >= 1)) + { + Lisp_Object acronym + = (! glyph->u.glyphless.for_no_font + ? CHAR_TABLE_REF (Vglyphless_char_display, + glyph->u.glyphless.ch) + : XCHAR_TABLE (Vglyphless_char_display)->extras[0]); + if (STRINGP (acronym)) + str = (char *) SDATA (acronym); + } + } + else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEXA_CODE) + { + sprintf ((char *) buf, "%0*X", + glyph->u.glyphless.ch < 0x10000 ? 4 : 6, + glyph->u.glyphless.ch); + str = buf; + } + + if (str) + { + int upper_len = (len + 1) / 2; + unsigned code; + + /* It is assured that all LEN characters in STR is ASCII. */ + for (j = 0; j < len; j++) + { + code = s->font->driver->encode_char (s->font, str[j]); + STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF); + } + s->font->driver->draw (s, 0, upper_len, + x + glyph->slice.glyphless.upper_xoff, + s->ybase + glyph->slice.glyphless.upper_yoff, + 0); + s->font->driver->draw (s, upper_len, len, + x + glyph->slice.glyphless.lower_xoff, + s->ybase + glyph->slice.glyphless.lower_yoff, + 0); + } + if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE) + XDrawRectangle (s->display, s->window, s->gc, + x, s->ybase - glyph->ascent, + glyph->pixel_width - 1, + glyph->ascent + glyph->descent - 1); + x += glyph->pixel_width; + } +} + #ifdef USE_X_TOOLKIT static struct frame *x_frame_of_widget (Widget); @@ -2656,6 +2733,14 @@ x_draw_composite_glyph_string_foreground (s); break; + case GLYPHLESS_GLYPH: + if (s->for_overlaps) + s->background_filled_p = 1; + else + x_draw_glyph_string_background (s, 1); + x_draw_glyphless_glyph_string_foreground (s); + break; + default: abort (); } ------------------------------------------------------------ revno: 102209 committer: Glenn Morris branch nick: trunk timestamp: Mon 2010-11-01 00:40:11 -0700 message: Reposition some aliases in holidays.el. * lisp/calendar/holidays.el (general-holidays, oriental-holidays) (local-holidays, other-holidays, hebrew-holidays, christian-holidays) (islamic-holidays, bahai-holidays, solar-holidays): Move aliases before the definitions of their targets. (The position doesn't actually matter so long as the aliases are autoloaded). diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2010-11-01 06:44:54 +0000 +++ lisp/ChangeLog 2010-11-01 07:40:11 +0000 @@ -1,5 +1,10 @@ 2010-11-01 Glenn Morris + * calendar/holidays.el (general-holidays, oriental-holidays) + (local-holidays, other-holidays, hebrew-holidays, christian-holidays) + (islamic-holidays, bahai-holidays, solar-holidays): Move aliases before + the definitions of their targets. + * emacs-lisp/smie.el (smie): New custom group. (smie-blink-matching-inners, smie-indent-basic): Add :group. === modified file 'lisp/calendar/holidays.el' --- lisp/calendar/holidays.el 2010-08-29 16:17:13 +0000 +++ lisp/calendar/holidays.el 2010-11-01 07:40:11 +0000 @@ -1,7 +1,8 @@ ;;; holidays.el --- holiday functions for the calendar package ;; Copyright (C) 1989, 1990, 1992, 1993, 1994, 1997, 2001, 2002, 2003, -;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. ;; Author: Edward M. Reingold ;; Maintainer: Glenn Morris @@ -43,6 +44,9 @@ ;; explicitly load this file. ;;;###autoload +(define-obsolete-variable-alias 'general-holidays + 'holiday-general-holidays "23.1") +;;;###autoload (defcustom holiday-general-holidays (mapcar 'purecopy '((holiday-fixed 1 1 "New Year's Day") @@ -68,11 +72,11 @@ :group 'holidays) ;;;###autoload (put 'holiday-general-holidays 'risky-local-variable t) -;;;###autoload -(define-obsolete-variable-alias 'general-holidays - 'holiday-general-holidays "23.1") ;;;###autoload +(define-obsolete-variable-alias 'oriental-holidays + 'holiday-oriental-holidays "23.1") +;;;###autoload (defcustom holiday-oriental-holidays (mapcar 'purecopy '((holiday-chinese-new-year) @@ -93,11 +97,10 @@ :group 'holidays) ;;;###autoload (put 'holiday-oriental-holidays 'risky-local-variable t) -;;;###autoload -(define-obsolete-variable-alias 'oriental-holidays - 'holiday-oriental-holidays "23.1") ;;;###autoload +(define-obsolete-variable-alias 'local-holidays 'holiday-local-holidays "23.1") +;;;###autoload (defcustom holiday-local-holidays nil "Local holidays. See the documentation for `calendar-holidays' for details." @@ -105,10 +108,10 @@ :group 'holidays) ;;;###autoload (put 'holiday-local-holidays 'risky-local-variable t) -;;;###autoload -(define-obsolete-variable-alias 'local-holidays 'holiday-local-holidays "23.1") ;;;###autoload +(define-obsolete-variable-alias 'other-holidays 'holiday-other-holidays "23.1") +;;;###autoload (defcustom holiday-other-holidays nil "User defined holidays. See the documentation for `calendar-holidays' for details." @@ -116,8 +119,6 @@ :group 'holidays) ;;;###autoload (put 'holiday-other-holidays 'risky-local-variable t) -;;;###autoload -(define-obsolete-variable-alias 'other-holidays 'holiday-other-holidays "23.1") ;;;###autoload (defvar hebrew-holidays-1 @@ -219,6 +220,9 @@ (make-obsolete-variable 'hebrew-holidays-4 'hebrew-holidays "23.1") ;;;###autoload +(define-obsolete-variable-alias 'hebrew-holidays + 'holiday-hebrew-holidays "23.1") +;;;###autoload (defcustom holiday-hebrew-holidays (mapcar 'purecopy '((holiday-hebrew-passover) @@ -235,11 +239,11 @@ :group 'holidays) ;;;###autoload (put 'holiday-hebrew-holidays 'risky-local-variable t) -;;;###autoload -(define-obsolete-variable-alias 'hebrew-holidays - 'holiday-hebrew-holidays "23.1") ;;;###autoload +(define-obsolete-variable-alias 'christian-holidays + 'holiday-christian-holidays "23.1") +;;;###autoload (defcustom holiday-christian-holidays (mapcar 'purecopy '((holiday-easter-etc) ; respects calendar-christian-all-holidays-flag @@ -257,11 +261,11 @@ :group 'holidays) ;;;###autoload (put 'holiday-christian-holidays 'risky-local-variable t) -;;;###autoload -(define-obsolete-variable-alias 'christian-holidays - 'holiday-christian-holidays "23.1") ;;;###autoload +(define-obsolete-variable-alias 'islamic-holidays + 'holiday-islamic-holidays "23.1") +;;;###autoload (defcustom holiday-islamic-holidays (mapcar 'purecopy '((holiday-islamic-new-year) @@ -281,11 +285,10 @@ :group 'holidays) ;;;###autoload (put 'holiday-islamic-holidays 'risky-local-variable t) -;;;###autoload -(define-obsolete-variable-alias 'islamic-holidays - 'holiday-islamic-holidays "23.1") ;;;###autoload +(define-obsolete-variable-alias 'bahai-holidays 'holiday-bahai-holidays "23.1") +;;;###autoload (defcustom holiday-bahai-holidays (mapcar 'purecopy '((holiday-bahai-new-year) @@ -305,10 +308,10 @@ :group 'holidays) ;;;###autoload (put 'holiday-bahai-holidays 'risky-local-variable t) -;;;###autoload -(define-obsolete-variable-alias 'bahai-holidays 'holiday-bahai-holidays "23.1") ;;;###autoload +(define-obsolete-variable-alias 'solar-holidays 'holiday-solar-holidays "23.1") +;;;###autoload (defcustom holiday-solar-holidays (mapcar 'purecopy '((solar-equinoxes-solstices) @@ -328,8 +331,6 @@ :group 'holidays) ;;;###autoload (put 'holiday-solar-holidays 'risky-local-variable t) -;;;###autoload -(define-obsolete-variable-alias 'solar-holidays 'holiday-solar-holidays "23.1") ;; This one should not be autoloaded, else .emacs changes of ;; holiday-general-holidays etc have no effect. @@ -919,5 +920,4 @@ (provide 'holidays) -;; arch-tag: 48eb3117-75a7-4dbe-8fd9-873c3cbb0d37 ;;; holidays.el ends here ------------------------------------------------------------ revno: 102208 committer: Glenn Morris branch nick: trunk timestamp: Mon 2010-11-01 00:34:04 -0700 message: * cedet/semantic/bovine/c.el (semantic-analyze-split-name): Move before use. diff: === modified file 'lisp/cedet/ChangeLog' --- lisp/cedet/ChangeLog 2010-11-01 06:19:31 +0000 +++ lisp/cedet/ChangeLog 2010-11-01 07:34:04 +0000 @@ -1,5 +1,7 @@ 2010-11-01 Glenn Morris + * semantic/bovine/c.el (semantic-analyze-split-name): Move before use. + * semantic/symref/cscope.el (ede-toplevel): * semantic/symref.el (ede-toplevel): * semantic/tag-file.el (ede-toplevel): === modified file 'lisp/cedet/semantic/bovine/c.el' --- lisp/cedet/semantic/bovine/c.el 2010-09-23 19:00:31 +0000 +++ lisp/cedet/semantic/bovine/c.el 2010-11-01 07:34:04 +0000 @@ -1002,6 +1002,13 @@ where typename is the name of the type, and typeoftype is \"class\" or \"struct\".") +(define-mode-local-override semantic-analyze-split-name c-mode (name) + "Split up tag names on colon (:) boundaries." + (let ((ans (split-string name ":"))) + (if (= (length ans) 1) + name + (delete "" ans)))) + (defun semantic-c-reconstitute-token (tokenpart declmods typedecl) "Reconstitute a token TOKENPART with DECLMODS and TYPEDECL. This is so we don't have to match the same starting text several times. @@ -1559,13 +1566,6 @@ (string= (semantic-tag-type type) "enum")) (semantic-tag-type-members type))) -(define-mode-local-override semantic-analyze-split-name c-mode (name) - "Split up tag names on colon (:) boundaries." - (let ((ans (split-string name ":"))) - (if (= (length ans) 1) - name - (delete "" ans)))) - (define-mode-local-override semantic-analyze-unsplit-name c-mode (namelist) "Assemble the list of names NAMELIST into a namespace name." (mapconcat 'identity namelist "::")) @@ -1871,5 +1871,4 @@ ;; generated-autoload-load-name: "semantic/bovine/c" ;; End: -;; arch-tag: 263951a8-0f18-445d-8e73-eb8f9ac8e2a3 ;;; semantic/bovine/c.el ends here ------------------------------------------------------------ revno: 102207 committer: Glenn Morris branch nick: trunk timestamp: Sun 2010-10-31 23:44:54 -0700 message: * lisp/emacs-lisp/smie.el (smie): New custom group. (smie-blink-matching-inners, smie-indent-basic): Add :group. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2010-11-01 06:13:43 +0000 +++ lisp/ChangeLog 2010-11-01 06:44:54 +0000 @@ -1,5 +1,8 @@ 2010-11-01 Glenn Morris + * emacs-lisp/smie.el (smie): New custom group. + (smie-blink-matching-inners, smie-indent-basic): Add :group. + * faces.el (xw-defined-colors, x-setup-function-keys): * mouse-sel.el (x-select-text): * term/w32console.el (x-setup-function-keys): Update declarations. === modified file 'lisp/emacs-lisp/smie.el' --- lisp/emacs-lisp/smie.el 2010-10-29 19:20:28 +0000 +++ lisp/emacs-lisp/smie.el 2010-11-01 06:44:54 +0000 @@ -70,6 +70,10 @@ (eval-when-compile (require 'cl)) +(defgroup smie nil + "Simple Minded Indentation Engine." + :group 'languages) + (defvar comment-continue) (declare-function comment-string-strip "newcomment" (str beforep afterp)) @@ -790,7 +794,8 @@ (defcustom smie-blink-matching-inners t "Whether SMIE should blink to matching opener for inner keywords. If non-nil, it will blink not only for \"begin..end\" but also for \"if...else\"." - :type 'boolean) + :type 'boolean + :group 'smie) (defun smie-blink-matching-check (start end) (save-excursion @@ -866,7 +871,8 @@ (defcustom smie-indent-basic 4 "Basic amount of indentation." - :type 'integer) + :type 'integer + :group 'smie) (defvar smie-rules-function 'ignore "Function providing the indentation rules. ------------------------------------------------------------ Use --include-merges or -n0 to see merged revisions.