Merged in changes from CVS HEAD

Patches applied:

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-1
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-2
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-3
   Update from CVS


git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-17
This commit is contained in:
Karoly Lorentey 2003-12-28 16:05:28 +00:00
commit 8ed48c277a
46 changed files with 8288 additions and 370 deletions

View file

@ -1740,6 +1740,40 @@ return value of `get-char-property' called with those arguments and
whose cdr is the overlay in which the property was found, or nil if
it was found as a text property or not found at all.
** The mouse pointer shape in void text areas (i.e. after the end of a
line or below the last line in the buffer) of the text window is now
controlled by the new variable `void-text-area-pointer'. The default
is to use the `arrow' (non-text) pointer. Other choices are `text'
(or nil), `hand', `vdrag', `hdrag', `modeline', and `hourglass'.
** The mouse pointer shape over an image can now be controlled by the
:pointer image property.
** The mouse pointer shape over ordinary text or images may now be
controlled/overriden via the `pointer' text property.
** Images may now have an associated image map via the :map property.
An image map is an alist where each element has the format (AREA ID PLIST).
An AREA is specified as either a rectangle, a circle, or a polygon:
A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
pixel coordinates of the upper left and bottom right corners.
A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
and the radius of the circle; r may be a float or integer.
A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
vector describes one corner in the polygon.
When the mouse pointer is above a hot-spot area of an image, the
PLIST of that hot-spot is consulted; if it contains a `help-echo'
property it defines a tool-tip for the hot-spot, and if it contains
a `pointer' property, it defines the shape of the mouse cursor when
it is over the hot-spot. See the variable 'void-area-text-pointer'
for possible pointer shapes.
When you click the mouse when the mouse pointer is over a hot-spot,
an event is composed by combining the ID of the hot-spot with the
mouse event, e.g. [area4 mouse-1] if the hot-spot's ID is `area4'.
** Mouse event enhancements:
*** Mouse clicks on fringes now generates left-fringe or right-fringes

View file

@ -1,3 +1,11 @@
2003-12-27 Paul Eggert <eggert@twinsun.com>
* rcs2log (rlog_options): Append -rbranchtag if CVS/Tag indicates
a tag, and if the user has not specified an rlog option.
Adapted from a suggestion by Martin Stjernholm in
<http://mail.gnu.org/archive/html/bug-gnu-emacs/2003-07/msg00066.html>.
(Copyright): Update to 2003.
2003-12-24 Thien-Thi Nguyen <ttn@gnu.org>
* make-docfile.c (main): For return code, no longer special-case VMS.
@ -5461,7 +5469,7 @@ Tue Jul 1 01:09:07 1997 Geoff Voelker <voelker@cs.washington.edu>
;; coding: iso-2022-7bit
;; End:
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003
Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted provided the copyright notice and this notice are preserved.

View file

@ -29,9 +29,9 @@ Options:
Report bugs to <bug-gnu-emacs@gnu.org>.'
Id='$Id: rcs2log,v 1.51 2003/09/01 15:45:03 miles Exp $'
Id='$Id: rcs2log,v 1.52 2003/12/27 08:18:08 uid65632 Exp $'
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
@ -49,7 +49,7 @@ Id='$Id: rcs2log,v 1.51 2003/09/01 15:45:03 miles Exp $'
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
Copyright='Copyright (C) 2002 Free Software Foundation, Inc.
Copyright='Copyright (C) 2003 Free Software Foundation, Inc.
This program comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of this program
under the terms of the GNU General Public License.
@ -195,8 +195,9 @@ case $rlogfile in
# If no rlog options are given,
# log the revisions checked in since the first ChangeLog entry.
# Since ChangeLog is only by date, some of these revisions may be duplicates of
# what's already in ChangeLog; it's the user's responsibility to remove them.
# Since ChangeLog is only by date, some of these revisions may be
# duplicates of what's already in ChangeLog; it's the user's
# responsibility to remove them.
case $rlog_options in
'')
if test -s "$changelog"
@ -281,6 +282,21 @@ case $rlogfile in
esac
done
# If no rlog options are given, and if we are in a tagged CVS branch,
# log only the changes in that branch.
case $rlog_options in
'')
if test -f CVS/Tag
then
CVSTAG=`cat <CVS/Tag` || exit
case $CVSTAG in
T?*)
rlog_options=-r`expr "$CVSTAG" : 'T\(.*\)'`;;
*)
echo >&2 "$0: invalid CVS/Tag"; exit 1;;
esac
fi;;
esac
fi
# Use $rlog's -zLT option, if $rlog supports it.

View file

@ -1,3 +1,34 @@
2003-12-27 Kim F. Storm <storm@cua.dk>
* ido.el: Handle non-readable directories.
(ido-decorations): Add 9th element for non-readable directory.
(ido-directory-nonreadable): New dynamic var.
(ido-set-current-directory): Set it.
(ido-read-buffer, ido-file-internal):
(ido-read-file-name, ido-read-directory-name): Let-bind it.
(ido-file-name-all-completions1): Return empty list for
non-readable directory.
(ido-exhibit): Print [Not readable] if directory is not readable.
(ido-expand-directory): New defun (based on tiny fix from Karl Chen).
(ido-read-file-name, ido-file-internal, ido-read-directory-name):
Use it.
2003-12-27 Lars Hansen <larsh@math.ku.dk>
* ls-lisp.el (ls-lisp-insert-directory): Add parameter 'string in
calls to directory-files-and-attributes and file-attributes.
(ls-lisp-format): Remove system dependent handling of user and
group id's.
2003-12-25 Luc Teirlinck <teirllm@auburn.edu>
* ffap.el (ffap-read-file-or-url): Revert previous change.
2003-12-25 Andreas Schwab <schwab@suse.de>
* jka-compr.el (jka-compr-insert-file-contents): Avoid error when
file not found.
2003-12-08 Miles Bader <miles@gnu.org>
* dired.el (dired-between-files): Always use dired-move-to-filename,
@ -67,6 +98,23 @@
* info.el (Info-unescape-quotes, Info-split-parameter-string)
(Info-goto-emacs-command-node): Doc fixes.
2003-12-12 Jesper Harder <harder@ifa.au.dk>
* cus-edit.el (custom-add-parent-links): Define "many".
2003-12-08 Per Abrahamsen <abraham@dina.kvl.dk>
* wid-edit.el (widget-child-value-get, widget-child-value-inline)
(widget-child-validate, widget-type-value-create)
(widget-type-default-get, widget-type-match): New functions.
(lazy): New widget.
(menu-choice, checklist, radio-button-choice, editable-list)
(group, documentation-string): Removed redundant (per 2003-10-25
change) calls to `widget-children-value-delete'.
(widget-choice-value-get, widget-choice-value-inline): Removed
functions.
(menu-choice): Updated widget.
2003-12-03 Kenichi Handa <handa@m17n.org>
* language/cyrillic.el: Register "microsoft-cp1251" in

View file

@ -1970,7 +1970,8 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"."
(setq parents (cons symbol parents))))))
(and (null (get symbol 'custom-links)) ;No links of its own.
(= (length parents) 1) ;A single parent.
(let ((links (get (car parents) 'custom-links)))
(let* ((links (get (car parents) 'custom-links))
(many (> (length links) 2)))
(when links
(insert "\nParent documentation: ")
(while links

View file

@ -1216,7 +1216,7 @@ which may actually result in an url rather than a filename."
'ffap-read-file-or-url-internal
dir
nil
(if dir (cons guess (1+ (length dir))) guess)
(if dir (cons guess (length dir)) guess)
(list 'file-name-history))))
;; Do file substitution like (interactive "F"), suggested by MCOOK.
(or (ffap-url-p guess) (setq guess (substitute-in-file-name guess)))

View file

@ -685,16 +685,17 @@ Obsolete. Set 3rd element of `ido-decorations' instead."
:type '(choice string (const nil))
:group 'ido)
(defcustom ido-decorations '( "{" "}" " | " " | ..." "[" "]" " [No match]" " [Matched]")
(defcustom ido-decorations '( "{" "}" " | " " | ..." "[" "]" " [No match]" " [Matched]" " [Not readable]")
"*List of strings used by ido to display the alternatives in the minibuffer.
There are 8 elements in this list, each is a pair of strings:
There are 9 elements in this list:
1st and 2nd elements are used as brackets around the prospect list,
3rd element is the separator between prospects (ignored if ido-separator is set),
4th element is the string inserted at the end of a truncated list of prospects,
5th and 6th elements are used as brackets around the common match string which
can be completed using TAB,
7th element is the string displayed when there are a no matches, and
8th element displayed if there is a single match (and faces are not used)."
8th element is displayed if there is a single match (and faces are not used).
9th element is displayed when the current directory is non-readable."
:type '(repeat string)
:group 'ido)
@ -931,6 +932,9 @@ it doesn't interfere with other minibuffer usage.")
;; `ido-cur-list'. It is in no specific order.
(defvar ido-ignored-list)
;; Remember if current directory is non-readable (so we cannot do completion).
(defvar ido-directory-nonreadable)
;; Keep current item list if non-nil.
(defvar ido-keep-item-list)
@ -1406,6 +1410,7 @@ This function also adds a hook to the minibuffer."
(setq ido-current-directory dir)
(if (get-buffer ido-completion-buffer)
(kill-buffer ido-completion-buffer))
(setq ido-directory-nonreadable (not (file-readable-p dir)))
t))
(defun ido-set-current-home (&optional dir)
@ -1812,7 +1817,8 @@ PROMPT is the prompt to give to the user. DEFAULT if given is the default
buffer to be selected, which will go to the front of the list.
If REQUIRE-MATCH is non-nil, an existing-buffer must be selected.
If INITIAL is non-nil, it specifies the initial input string."
(let ((ido-current-directory nil))
(let ((ido-current-directory nil)
(ido-directory-nonreadable nil))
(ido-read-internal 'buffer prompt 'ido-buffer-history default require-match initial)))
(defun ido-record-work-directory (&optional dir)
@ -1851,12 +1857,18 @@ If INITIAL is non-nil, it specifies the initial input string."
(if (> (length ido-work-file-list) ido-max-work-file-list)
(setcdr (nthcdr (1- ido-max-work-file-list) ido-work-file-list) nil))))
(defun ido-expand-directory (dir)
;; Expand DIR or use DEFAULT-DIRECTORY if nil.
;; Add final slash to result in case it was missing from DEFAULT-DIRECTORY.
(ido-final-slash (expand-file-name (or dir default-directory)) t))
(defun ido-file-internal (method &optional fallback default prompt item initial)
;; Internal function for ido-find-file and friends
(unless item
(setq item 'file))
(let ((ido-current-directory (expand-file-name (or default default-directory)))
filename)
(let* ((ido-current-directory (ido-expand-directory default))
(ido-directory-nonreadable (not (file-readable-p ido-current-directory)))
filename)
(cond
((or (not ido-mode) (ido-is-slow-ftp-host))
@ -2693,30 +2705,33 @@ for first matching file."
(setq ido-temp-list items)))
(defun ido-file-name-all-completions1 (dir)
(if (and ido-enable-tramp-completion
(string-match "\\`/\\([^/:]+:\\([^/:@]+@\\)?\\)\\'" dir))
(cond
((not (file-readable-p dir)) '())
((and ido-enable-tramp-completion
(string-match "\\`/\\([^/:]+:\\([^/:@]+@\\)?\\)\\'" dir))
;; Trick tramp's file-name-all-completions handler to DTRT, as it
;; has some pretty obscure requirements. This seems to work...
;; /ftp: => (f-n-a-c "/ftp:" "")
;; /ftp:kfs: => (f-n-a-c "" "/ftp:kfs:")
;; /ftp:kfs@ => (f-n-a-c "ftp:kfs@" "/")
;; /ftp:kfs@kfs: => (f-n-a-c "" "/ftp:kfs@kfs:")
;; Currently no attempt is made to handle multi: stuff.
;; Trick tramp's file-name-all-completions handler to DTRT, as it
;; has some pretty obscure requirements. This seems to work...
;; /ftp: => (f-n-a-c "/ftp:" "")
;; /ftp:kfs: => (f-n-a-c "" "/ftp:kfs:")
;; /ftp:kfs@ => (f-n-a-c "ftp:kfs@" "/")
;; /ftp:kfs@kfs: => (f-n-a-c "" "/ftp:kfs@kfs:")
;; Currently no attempt is made to handle multi: stuff.
(let* ((prefix (match-string 1 dir))
(user-flag (match-beginning 2))
(len (and prefix (length prefix)))
compl)
(if user-flag
(setq dir (substring dir 1)))
(require 'tramp nil t)
(ido-trace "tramp complete" dir)
(setq compl (file-name-all-completions dir (if user-flag "/" "")))
(if (> len 0)
(mapcar (lambda (c) (substring c len)) compl)
compl))
(file-name-all-completions "" dir)))
(let* ((prefix (match-string 1 dir))
(user-flag (match-beginning 2))
(len (and prefix (length prefix)))
compl)
(if user-flag
(setq dir (substring dir 1)))
(require 'tramp nil t)
(ido-trace "tramp complete" dir)
(setq compl (file-name-all-completions dir (if user-flag "/" "")))
(if (> len 0)
(mapcar (lambda (c) (substring c len)) compl)
compl)))
(t
(file-name-all-completions "" dir))))
(defun ido-file-name-all-completions (dir)
;; Return name of all files in DIR
@ -3518,6 +3533,11 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
(expand-file-name "/" ido-current-directory)
"/"))
(setq refresh t))
((and ido-directory-nonreadable
(file-directory-p (concat ido-current-directory (file-name-directory contents))))
(ido-set-current-directory
(concat ido-current-directory (file-name-directory contents)))
(setq refresh t))
(t
(ido-trace "try single dir")
(setq try-single-dir-match t))))
@ -3574,6 +3594,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
(exit-minibuffer))
(when (and (not ido-matches)
(not ido-directory-nonreadable)
;; ido-rescan ?
ido-process-ignore-lists
ido-ignored-list)
@ -3596,7 +3617,8 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
(memq ido-cur-item '(file dir))
(not (ido-is-root-directory))
(> (length contents) 1)
(not (string-match "[$]" contents)))
(not (string-match "[$]" contents))
(not ido-directory-nonreadable))
(ido-trace "merge?")
(if ido-use-merged-list
(ido-undo-merge-work-directory contents nil)
@ -3658,9 +3680,12 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
(setq comps (cons first (cdr comps)))))
(cond ((null comps)
(if ido-report-no-match
(nth 6 ido-decorations) ;; [No Match]
""))
(cond
(ido-directory-nonreadable
(or (nth 8 ido-decorations) " [Not readable]"))
(ido-report-no-match
(nth 6 ido-decorations)) ;; [No match]
(t "")))
((null (cdr comps)) ;one match
(concat (if (> (length (ido-name (car comps))) (length name))
@ -3771,13 +3796,14 @@ See `read-file-name' for additional parameters."
(ido-read-directory-name prompt dir default-filename mustmatch initial))
((and (not (memq this-command ido-read-file-name-non-ido))
(or (null predicate) (eq predicate 'file-exists-p)))
(let (filename
ido-saved-vc-hb
(vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends))
(ido-current-directory (expand-file-name (or dir default-directory)))
(ido-work-directory-index -1)
(ido-work-file-index -1)
(ido-find-literal nil))
(let* (filename
ido-saved-vc-hb
(vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends))
(ido-current-directory (ido-expand-directory dir))
(ido-directory-nonreadable (not (file-readable-p ido-current-directory)))
(ido-work-directory-index -1)
(ido-work-file-index -1)
(ido-find-literal nil))
(setq filename
(ido-read-internal 'file prompt 'ido-file-history default-filename mustmatch initial))
(if filename
@ -3790,11 +3816,12 @@ See `read-file-name' for additional parameters."
(defun ido-read-directory-name (prompt &optional dir default-dirname mustmatch initial)
"Read directory name, prompting with PROMPT and completing in directory DIR.
See `read-file-name' for additional parameters."
(let (filename
ido-saved-vc-hb
(ido-current-directory (expand-file-name (or dir default-directory)))
(ido-work-directory-index -1)
(ido-work-file-index -1))
(let* (filename
ido-saved-vc-hb
(ido-current-directory (ido-expand-directory dir))
(ido-directory-nonreadable (not (file-readable-p ido-current-directory)))
(ido-work-directory-index -1)
(ido-work-file-index -1))
(setq filename
(ido-read-internal 'dir prompt 'ido-file-history default-dirname mustmatch initial))
(if filename

View file

@ -590,10 +590,11 @@ There should be no more than seven characters after the final `/'."
(file-exists-p local-copy)
(delete-file local-copy)))
(decode-coding-inserted-region
(point) (+ (point) size)
(jka-compr-byte-compiler-base-file-name file)
visit beg end replace)
(unless notfound
(decode-coding-inserted-region
(point) (+ (point) size)
(jka-compr-byte-compiler-base-file-name file)
visit beg end replace))
(and
visit

View file

@ -267,7 +267,7 @@ not contain `d', so that a full listing is expected."
(let* ((dir (file-name-as-directory file))
(default-directory dir) ; so that file-attributes works
(file-alist
(directory-files-and-attributes dir nil wildcard-regexp t))
(directory-files-and-attributes dir nil wildcard-regexp t 'string))
(now (current-time))
(sum 0)
;; do all bindings here for speed
@ -329,7 +329,7 @@ not contain `d', so that a full listing is expected."
;; so must make it a relative filename as ls does:
(if (eq (aref file (1- (length file))) ?/)
(setq file (substring file 0 -1)))
(let ((fattr (file-attributes file)))
(let ((fattr (file-attributes file 'string)))
(if fattr
(insert (ls-lisp-format file fattr (nth 7 fattr)
switches time-index (current-time)))
@ -522,23 +522,14 @@ SWITCHES, TIME-INDEX and NOW give the full switch list and time data."
;; They tend to be bogus on non-UNIX platforms anyway so
;; optionally hide them.
(if (memq 'uid ls-lisp-verbosity)
;; (user-login-name uid) works on Windows NT but not
;; on 9x and maybe not on some other platforms, so...
;; uid can be a sting or an integer
(let ((uid (nth 2 file-attr)))
(if (= uid (user-uid))
(format " %-8s" (user-login-name))
(format " %-8d" uid))))
(format (if (stringp uid) " %-8s" " %-8d") uid)))
(if (not (memq ?G switches)) ; GNU ls -- shows group by default
(if (or (memq ?g switches) ; UNIX ls -- no group by default
(memq 'gid ls-lisp-verbosity))
(if (memq system-type '(macos windows-nt ms-dos))
;; No useful concept of group...
" root"
(let* ((gid (nth 3 file-attr))
(group (user-login-name gid)))
(if group
(format " %-8s" group)
(format " %-8d" gid))))))
(let ((gid (nth 3 file-attr)))
(format (if (stringp gid) " %-8s" " %-8d") gid))))
(ls-lisp-format-file-size file-size (memq ?h switches))
" "
(ls-lisp-format-time file-attr time-index now)

View file

@ -1,6 +1,6 @@
;;; texnfo-upd.el --- utilities for updating nodes and menus in Texinfo files
;; Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002 Free Software Foundation, Inc.
;; Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2003 Free Software Foundation, Inc.
;; Author: Robert J. Chassell
;; Maintainer: bug-texinfo@gnu.org
@ -1795,25 +1795,34 @@ Thus, normally, each included file contains one, and only one, chapter."
;; description slot of a menu as a description.
(let ((case-fold-search t)
menu-list next-node-name previous-node-name)
menu-list next-node-name previous-node-name files-with-node-lines)
;; Find the name of the first node of the first included file.
(set-buffer (find-file-noselect (car (cdr files))))
;; Create a new list of included files that only have node lines
(while files
(set-buffer (find-file-noselect (car files)))
(widen)
(goto-char (point-min))
(when (re-search-forward "^@node" nil t)
(setq files-with-node-lines (cons (car files) files-with-node-lines)))
(setq files (cdr files)))
(setq files-with-node-lines (nreverse files-with-node-lines))
;; Find the name of the first node in a subsequent file
;; and copy it into the variable next-node-name
(set-buffer (find-file-noselect (car (cdr files-with-node-lines))))
(widen)
(goto-char (point-min))
(if (not (re-search-forward "^@node" nil t))
(error "No `@node' line found in %s" (buffer-name)))
(beginning-of-line)
(texinfo-check-for-node-name)
(setq next-node-name (texinfo-copy-node-name))
(push (cons next-node-name (prog1 "" (forward-line 1)))
;; Use following to insert section titles automatically.
;; (texinfo-copy-next-section-title)
menu-list)
;; Go to outer file
(set-buffer (find-file-noselect (pop files)))
;; `pop' is analogous to (prog1 (car PLACE) (setf PLACE (cdr PLACE)))
(set-buffer (find-file-noselect (pop files-with-node-lines)))
(goto-char (point-min))
(if (not (re-search-forward "^@node [ \t]*top[ \t]*\\(,\\|$\\)" nil t))
(error "This buffer needs a Top node"))
@ -1824,18 +1833,16 @@ Thus, normally, each included file contains one, and only one, chapter."
(beginning-of-line)
(setq previous-node-name "Top")
(while files
(while files-with-node-lines
(if (not (cdr files))
(if (not (cdr files-with-node-lines))
;; No next file
(setq next-node-name "")
;; Else,
;; find the name of the first node in the next file.
(set-buffer (find-file-noselect (car (cdr files))))
(set-buffer (find-file-noselect (car (cdr files-with-node-lines))))
(widen)
(goto-char (point-min))
(if (not (re-search-forward "^@node" nil t))
(error "No `@node' line found in %s" (buffer-name)))
(beginning-of-line)
(texinfo-check-for-node-name)
(setq next-node-name (texinfo-copy-node-name))
@ -1845,10 +1852,8 @@ Thus, normally, each included file contains one, and only one, chapter."
menu-list))
;; Go to node to be updated.
(set-buffer (find-file-noselect (car files)))
(set-buffer (find-file-noselect (car files-with-node-lines)))
(goto-char (point-min))
(if (not (re-search-forward "^@node" nil t))
(error "No `@node' line found in %s" (buffer-name)))
(beginning-of-line)
;; Update other menus and nodes if requested.
@ -1862,7 +1867,7 @@ Thus, normally, each included file contains one, and only one, chapter."
(beginning-of-line)
(setq previous-node-name (texinfo-copy-node-name))
(setq files (cdr files)))
(setq files-with-node-lines (cdr files-with-node-lines)))
(nreverse menu-list)))
(defun texinfo-multi-files-insert-main-menu (menu-list)

View file

@ -1267,6 +1267,42 @@ Optional EVENT is the event that triggered the action."
found (widget-apply child :validate)))
found))
(defun widget-child-value-get (widget)
"Get the value of the first member of :children in WIDGET."
(widget-value (car (widget-get widget :children))))
(defun widget-child-value-inline (widget)
"Get the inline value of the first member of :children in WIDGET."
(widget-apply (car (widget-get widget :children)) :value-inline))
(defun widget-child-validate (widget)
"The result of validating the first member of :children in WIDGET."
(widget-apply (car (widget-get widget :children)) :validate))
(defun widget-type-value-create (widget)
"Convert and instantiate the value of the :type attribute of WIDGET.
Store the newly created widget in the :children attribute.
The value of the :type attribute should be an unconverted widget type."
(let ((value (widget-get widget :value))
(type (widget-get widget :type)))
(widget-put widget :children
(list (widget-create-child-value widget
(widget-convert type)
value)))))
(defun widget-type-default-get (widget)
"Get default value from the :type attribute of WIDGET.
The value of the :type attribute should be an unconverted widget type."
(widget-default-get (widget-convert (widget-get widget :type))))
(defun widget-type-match (widget value)
"Non-nil if the :type value of WIDGET matches VALUE.
The value of the :type attribute should be an unconverted widget type."
(widget-apply (widget-convert (widget-get widget :type)) :match value))
(defun widget-types-copy (widget)
"Copy :args as widget types in WIDGET."
(widget-put widget :args (mapcar 'widget-copy (widget-get widget :args)))
@ -1862,9 +1898,8 @@ the earlier input."
:tag "choice"
:void '(item :format "invalid (%t)\n")
:value-create 'widget-choice-value-create
:value-delete 'widget-children-value-delete
:value-get 'widget-choice-value-get
:value-inline 'widget-choice-value-inline
:value-get 'widget-child-value-get
:value-inline 'widget-child-value-inline
:default-get 'widget-choice-default-get
:mouse-down-action 'widget-choice-mouse-down-action
:action 'widget-choice-action
@ -1901,14 +1936,6 @@ the earlier input."
widget void :value value)))
(widget-put widget :choice void))))))
(defun widget-choice-value-get (widget)
;; Get value of the child widget.
(widget-value (car (widget-get widget :children))))
(defun widget-choice-value-inline (widget)
;; Get value of the child widget.
(widget-apply (car (widget-get widget :children)) :value-inline))
(defun widget-choice-default-get (widget)
;; Get default for the first choice.
(widget-default-get (car (widget-get widget :args))))
@ -2099,7 +2126,6 @@ when he invoked the menu."
:entry-format "%b %v"
:greedy nil
:value-create 'widget-checklist-value-create
:value-delete 'widget-children-value-delete
:value-get 'widget-checklist-value-get
:validate 'widget-checklist-validate
:match 'widget-checklist-match
@ -2276,7 +2302,6 @@ Return an alist of (TYPE MATCH)."
:format "%v"
:entry-format "%b %v"
:value-create 'widget-radio-value-create
:value-delete 'widget-children-value-delete
:value-get 'widget-radio-value-get
:value-inline 'widget-radio-value-inline
:value-set 'widget-radio-value-set
@ -2466,7 +2491,6 @@ Return an alist of (TYPE MATCH)."
:format-handler 'widget-editable-list-format-handler
:entry-format "%i %d %v"
:value-create 'widget-editable-list-value-create
:value-delete 'widget-children-value-delete
:value-get 'widget-editable-list-value-get
:validate 'widget-children-validate
:match 'widget-editable-list-match
@ -2637,7 +2661,6 @@ Return an alist of (TYPE MATCH)."
:copy 'widget-types-copy
:format "%v"
:value-create 'widget-group-value-create
:value-delete 'widget-children-value-delete
:value-get 'widget-editable-list-value-get
:default-get 'widget-group-default-get
:validate 'widget-children-validate
@ -2803,7 +2826,6 @@ link for that string."
"A documentation string."
:format "%v"
:action 'widget-documentation-string-action
:value-delete 'widget-children-value-delete
:value-create 'widget-documentation-string-value-create)
(defun widget-documentation-string-value-create (widget)
@ -3250,6 +3272,62 @@ To use this type, you must define :match or :match-alternatives."
(widget-group-match widget
(widget-apply widget :value-to-internal value))))
;;; The `lazy' Widget.
;;
;; Recursive datatypes.
(define-widget 'lazy 'default
"Base widget for recursive datastructures.
The `lazy' widget will, when instantiated, contain a single inferior
widget, of the widget type specified by the :type parameter. The
value of the `lazy' widget is the same as the value of the inferior
widget. When deriving a new widget from the 'lazy' widget, the :type
parameter is allowed to refer to the widget currently being defined,
thus allowing recursive datastructures to be described.
The :type parameter takes the same arguments as the defcustom
parameter with the same name.
Most composite widgets, i.e. widgets containing other widgets, does
not allow recursion. That is, when you define a new widget type, none
of the inferior widgets may be of the same type you are currently
defining.
In Lisp, however, it is custom to define datastructures in terms of
themselves. A list, for example, is defined as either nil, or a cons
cell whose cdr itself is a list. The obvious way to translate this
into a widget type would be
(define-widget 'my-list 'choice
\"A list of sexps.\"
:tag \"Sexp list\"
:args '((const nil) (cons :value (nil) sexp my-list)))
Here we attempt to define my-list as a choice of either the constant
nil, or a cons-cell containing a sexp and my-lisp. This will not work
because the `choice' widget does not allow recursion.
Using the `lazy' widget you can overcome this problem, as in this
example:
(define-widget 'sexp-list 'lazy
\"A list of sexps.\"
:tag \"Sexp list\"
:type '(choice (const nil) (cons :value (nil) sexp sexp-list)))"
:format "%{%t%}: %v"
;; We don't convert :type because we want to allow recursive
;; datastructures. This is slow, so we should not create speed
;; critical widgets by deriving from this.
:convert-widget 'widget-value-convert-widget
:value-create 'widget-type-value-create
:value-get 'widget-child-value-get
:value-inline 'widget-child-value-inline
:default-get 'widget-type-default-get
:match 'widget-type-match
:validate 'widget-child-validate)
;;; The `plist' Widget.
;;
;; Property lists.

View file

@ -1,3 +1,51 @@
2003-12-25 Markus Rost <rost@mathematik.uni-bielefeld.de>
* display.texi (Fringes): Fix typo "set-buffer-window".
2003-12-24 Luc Teirlinck <teirllm@auburn.edu>
* display.texi, eval.texi, help.texi, internals.texi, loading.texi:
* nonascii.texi, processes.texi, tips.texi, variables.texi:
Add or change various xrefs and anchors.
* commands.texi: Replace all occurrences of @acronym{CAR} with
@sc{car}, for consistency with the rest of the Elisp manual.
`car' and `cdr' are historically acronyms, but are no longer
widely thought of as such.
* internals.texi (Pure Storage): Mention that `purecopy' does not
copy text properties.
(Object Internals): Now 29 bits are used (in most implementations)
to address Lisp objects.
* variables.texi (Variables with Restricted Values): New node.
* objects.texi (Lisp Data Types): Mention that certain variables
can only take on a restricted set of values and add an xref to
the new node "Variables with Restricted Values".
* eval.texi (Function Indirection): Describe the errors that
`indirect-function' can signal.
(Eval): Clarify the descriptions of `eval-region' and `values'.
Describe `eval-buffer' instead of `eval-current-buffer' and
mention `eval-current-buffer' as an alias for `current-buffer'.
Correct the description and mention all optional arguments.
* nonascii.texi : Various small changes in addition to the
following.
(Converting Representations): Clarify behavior of
`string-make-multibyte' and `string-to-multibyte' for unibyte all
ASCII arguments.
(Character Sets): Document the variable `charset-list' and adapt
the definition of the function `charset-list' accordingly.
(Translation of Characters): Clarify use of generic characters in
`make-translation-table'. Clarify and correct the description of
the use of translation tables in encoding and decoding.
(User-Chosen Coding Systems): Correct and clarify the description
of `select-safe-coding-system'.
(Default Coding Systems): Clarify description of
`file-coding-system-alist'.
2003-11-30 Luc Teirlinck <teirllm@auburn.edu>
* strings.texi (Text Comparison): Correctly describe when two
@ -42,7 +90,7 @@
2003-11-20 Luc Teirlinck <teirllm@auburn.edu>
* positions.texi (Positions): Mention that, if a marker is used a
* positions.texi (Positions): Mention that, if a marker is used as
a position, its buffer is ignored.
* markers.texi (Overview of Markers): Mention it here too.

View file

@ -1096,7 +1096,7 @@ arguments to the key-binding lookup and modification functions.
Emacs supports four kinds of mouse events: click events, drag events,
button-down events, and motion events. All mouse events are represented
as lists. The @acronym{CAR} of the list is the event type; this says which
as lists. The @sc{car} of the list is the event type; this says which
mouse button was involved, and which modifier keys were used with it.
The event type can also distinguish double or triple button presses
(@pxref{Repeat Events}). The rest of the list elements give position
@ -1172,7 +1172,7 @@ which the click occurred. It is one of the symbols @code{mode-line},
@item @var{x}, @var{y}
These are the pixel-denominated coordinates of the click, relative to
the top left corner of @var{window}, which is @code{(0 . 0)}.
the top left corner of @var{window}, which is @code{(0 . 0)}.
For the mode or header line, @var{y} does not have meaningful data.
For the vertical line, @var{x} does not have meaningful data.
@ -1188,7 +1188,7 @@ an image object as returned by @code{find-image} if click was in an image.
@item @var{string}
This is the string on which the click occurred, including any
properties.
properties.
@item @var{string-pos}
This is the position in the string on which the click occurred,
@ -1560,7 +1560,7 @@ into another window. That produces a pair of events like these:
key binding purposes. For a keyboard event, the event type equals the
event value; thus, the event type for a character is the character, and
the event type for a function key symbol is the symbol itself. For
events that are lists, the event type is the symbol in the @acronym{CAR} of
events that are lists, the event type is the symbol in the @sc{car} of
the list. Thus, the event type is always a symbol or a character.
Two events of the same type are equivalent where key bindings are
@ -2583,7 +2583,7 @@ This function returns the numeric meaning of a valid raw prefix argument
value, @var{arg}. The argument may be a symbol, a number, or a list.
If it is @code{nil}, the value 1 is returned; if it is @code{-}, the
value @minus{}1 is returned; if it is a number, that number is returned;
if it is a list, the @acronym{CAR} of that list (which should be a number) is
if it is a list, the @sc{car} of that list (which should be a number) is
returned.
@end defun

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@c This is part of the GNU Emacs Lisp Reference Manual.
@c Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
@c Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
@c See the file elisp.texi for copying conditions.
@setfilename ../info/customize
@node Customization, Loading, Macros, Top
@ -373,6 +373,7 @@ equivalent to @code{(string)}.
* Composite Types::
* Splicing into Lists::
* Type Keywords::
* Defining New Types::
@end menu
All customization types are implemented as widgets; see @ref{Top, ,
@ -1056,6 +1057,76 @@ arguments, which will be used when creating the @code{radio-button} or
@end ignore
@end table
@node Defining New Types
@subsection Defining New Types
In the previous sections we have described how to construct elaborate
type specifications for @code{defcustom}. In some cases you may want to
give such a type specification a name. The obvious case is when you are
using the same type for many user options, rather than repeat the
specification for each option, you can give the type specification a
name once, and use that name each @code{defcustom}. The other case is
when a user option accept a recursive datastructure. To make it
possible for a datatype to refer to itself, it needs to have a name.
Since custom types are implemented as widgets, the way to define a new
customize type is to define a new widget. We are not going to describe
the widget interface here in details, see @ref{Top, , Introduction,
widget, The Emacs Widget Library}, for that. Instead we are going to
demonstrate the minimal functionality needed for defining new customize
types by a simple example.
@example
(define-widget 'binary-tree-of-string 'lazy
"A binary tree made of cons-cells and strings."
:offset 4
:tag "Node"
:type '(choice (string :tag "Leaf" :value "")
(cons :tag "Interior"
:value ("" . "")
binary-tree-of-string
binary-tree-of-string)))
(defcustom foo-bar ""
"Sample variable holding a binary tree of strings."
:type 'binary-tree-of-string)
@end example
The function to define a new widget is name @code{define-widget}. The
first argument is the symbol we want to make a new widget type. The
second argument is a symbol representing an existing widget, the new
widget is going to be defined in terms of difference from the existing
widget. For the purpose of defining new customization types, the
@code{lazy} widget is perfect, because it accept a @code{:type} keyword
argument with the same syntax as the keyword argument to
@code{defcustom} with the same name. The third argument is a
documentation string for the new widget. You will be able to see that
string with the @kbd{M-x widget-browse @key{ret} binary-tree-of-string
@key{ret}} command.
After these mandatory arguments follows the keyword arguments. The most
important is @code{:type}, which describes the datatype we want to match
with this widget. Here a @code{binary-tree-of-string} is described as
being either a string, or a cons-cell whose car and cdr are themselves
both @code{binary-tree-of-string}. Note the reference to the widget
type we are currently in the process of defining. The @code{:tag}
attribute is a string to name the widget in the user interface, and the
@code{:offset} argument are there to ensure that child nodes are
indented four spaces relatively to the parent node, making the tree
structure apparent in the customization buffer.
The @code{defcustom} shows how the new widget can be used as an ordinary
customization type.
If you wonder about the name @code{lazy}, know that the other composite
widgets convert their inferior widgets to internal form when the widget
is instantiated in a buffer. This conversion is recursive, so the
inferior widgets will convert @emph{their} inferior widgets. If the
datastructure is itself recursive, this conversion will go on forever,
or at least until Emacs run out of stack space. The @code{lazy} widget
stop this recursion, it will only convert its @code{:type} argument when
needed.
@ignore
arch-tag: d1b8fad3-f48c-4ce4-a402-f73b5ef19bd2
@end ignore

View file

@ -805,8 +805,9 @@ If the @var{forms} do not change the major mode in the output buffer,
so that it is still Help mode at the end of their execution, then
@code{with-output-to-temp-buffer} makes this buffer read-only at the
end, and also scans it for function and variable names to make them
into clickable cross-references. @xref{Documentation Tips, , Tips for
Documentation Strings}.
into clickable cross-references. @xref{Docstring hyperlinks, , Tips
for Documentation Strings}, in particular the item on hyperlinks in
documentation strings, for more details.
The string @var{buffer-name} specifies the temporary buffer, which
need not already exist. The argument must be a string, not a buffer.
@ -2527,7 +2528,7 @@ fringe in pixels.
The values of these variables take effect when you display the
buffer in a window. If you change them while the buffer is visible,
you can call @code{set-buffer-window} to display it in a window again.
you can call @code{set-window-buffer} to display it in a window again.
@defun set-window-fringes window left &optional right outside-margins
This function sets the fringe widthes of window @var{window}.

View file

@ -319,6 +319,10 @@ This function returns the meaning of @var{function} as a function. If
definition and starts over with that value. If @var{function} is not a
symbol, then it returns @var{function} itself.
This function signals a @code{void-function} error if the final
symbol is unbound and a @code{cyclic-function-indirection} error if
there is a loop in the chain of symbols.
Here is how you could define @code{indirect-function} in Lisp:
@smallexample
@ -625,32 +629,51 @@ The number of currently active calls to @code{eval} is limited to
@code{max-lisp-eval-depth} (see below).
@end defun
@anchor{Definition of eval-region}
@deffn Command eval-region start end &optional stream read-function
This function evaluates the forms in the current buffer in the region
defined by the positions @var{start} and @var{end}. It reads forms from
the region and calls @code{eval} on them until the end of the region is
reached, or until an error is signaled and not handled.
If @var{stream} is non-@code{nil}, the values that result from
evaluating the expressions in the region are printed using @var{stream}.
@xref{Output Streams}.
By default, @code{eval-region} does not produce any output. However,
if @var{stream} is non-@code{nil}, any output produced by output
functions (@pxref{Output Functions}), as well as the values that
result from evaluating the expressions in the region are printed using
@var{stream}. @xref{Output Streams}.
If @var{read-function} is non-@code{nil}, it should be a function, which
is used instead of @code{read} to read expressions one by one. This
function is called with one argument, the stream for reading input. You
can also use the variable @code{load-read-function} (@pxref{How Programs
Do Loading}) to specify this function, but it is more robust to use the
If @var{read-function} is non-@code{nil}, it should be a function,
which is used instead of @code{read} to read expressions one by one.
This function is called with one argument, the stream for reading
input. You can also use the variable @code{load-read-function}
(@pxref{Definition of load-read-function,, How Programs Do Loading})
to specify this function, but it is more robust to use the
@var{read-function} argument.
@code{eval-region} always returns @code{nil}.
@code{eval-region} does not move point. It always returns @code{nil}.
@end deffn
@cindex evaluation of buffer contents
@deffn Command eval-current-buffer &optional stream
This is like @code{eval-region} except that it operates on the whole
buffer.
@deffn Command eval-buffer &optional buffer-or-name stream filename unibyte print
This is similar to @code{eval-region}, but the arguments provide
different optional features. @code{eval-buffer} operates on the
entire accessible portion of buffer @var{buffer-or-name}.
@var{buffer-or-name} can be a buffer, a buffer name (a string), or
@code{nil} (or omitted), which means to use the current buffer.
@var{stream} is used as in @code{eval-region}, unless @var{stream} is
@code{nil} and @var{print} non-@code{nil}. In that case, values that
result from evaluating the expressions are still discarded, but the
output of the output functions is printed in the echo area.
@var{filename} is the file name to use for @code{load-history}
(@pxref{Unloading}), and defaults to @code{buffer-file-name}
(@pxref{Buffer File Name}). If @var{unibyte} is non-@code{nil},
@code{read} converts strings to unibyte whenever possible.
@findex eval-current-buffer
@code{eval-current-buffer} is an alias for this command.
@end deffn
@anchor{Definition of max-lisp-eval-depth}
@defvar max-lisp-eval-depth
This variable defines the maximum depth allowed in calls to @code{eval},
@code{apply}, and @code{funcall} before an error is signaled (with error
@ -670,14 +693,17 @@ Entry to the Lisp debugger increases the value, if there is little room
left, to make sure the debugger itself has room to execute.
@code{max-specpdl-size} provides another limit on nesting.
@xref{Local Variables}.
@xref{Definition of max-specpdl-size,, Local Variables}.
@end defvar
@defvar values
The value of this variable is a list of the values returned by all the
expressions that were read, evaluated, and printed from buffers
(including the minibuffer) by the standard Emacs commands which do this.
The elements are ordered most recent first.
(including the minibuffer) by the standard Emacs commands which do
this. (Note that this does @emph{not} include evaluation in
@samp{*ielm*} buffers, nor evaluation using @kbd{C-j} in
@code{lisp-interaction-mode}.) The elements are ordered most recent
first.
@example
@group

View file

@ -259,6 +259,7 @@ as shown above for the @code{goal-column} variable, means that it is a
user option; see the description of @code{defvar} in @ref{Defining
Variables}.
@anchor{Definition of Snarf-documentation}
@defun Snarf-documentation filename
This function is used only during Emacs initialization, just before
the runnable Emacs is dumped. It finds the file offsets of the

View file

@ -81,8 +81,9 @@ faster. On modern machines, it is usually not advisable.
After @file{loadup.el} reads @file{site-load.el}, it finds the
documentation strings for primitive and preloaded functions (and
variables) in the file @file{etc/DOC} where they are stored, by calling
@code{Snarf-documentation} (@pxref{Accessing Documentation}).
variables) in the file @file{etc/DOC} where they are stored, by
calling @code{Snarf-documentation} (@pxref{Definition of
Snarf-documentation,, Accessing Documentation}).
@cindex @file{site-init.el}
You can specify other Lisp expressions to execute just before dumping
@ -151,10 +152,10 @@ preload additional libraries or add features to the standard ones.
@defun purecopy object
This function makes a copy in pure storage of @var{object}, and returns
it. It copies a string by simply making a new string with the same
characters in pure storage. It recursively copies the contents of
vectors and cons cells. It does not make copies of other objects such
as symbols, but just returns them unchanged. It signals an error if
asked to copy markers.
characters, but without text properties, in pure storage. It
recursively copies the contents of vectors and cons cells. It does
not make copies of other objects such as symbols, but just returns
them unchanged. It signals an error if asked to copy markers.
This function is a no-op except while Emacs is being built and dumped;
it is usually called only in the file @file{emacs/lisp/loaddefs.el}, but
@ -367,7 +368,7 @@ until the subsequent garbage collection, at which time
@code{garbage-collect} will set the threshold back to 10,000.
@end defopt
The value return by @code{garbage-collect} describes the amount of
The value returned by @code{garbage-collect} describes the amount of
memory used by Lisp data, broken down by data type. By contrast, the
function @code{memory-limit} provides information on the total amount of
memory Emacs is currently using.
@ -595,9 +596,9 @@ protected in the current function. It is necessary to do this explicitly.
GC-protected; as long as the object is not recycled, all pointers to
it remain valid. So if you are sure that a local variable points to
an object that will be preserved by some other pointer, that local
variable does not need a GCPRO. (Formerly, strings were an exception
to this rule; in older Emacs versions, every pointer to a string
needed to be marked by GC.)
variable does not need a @code{GCPRO}. (Formerly, strings were an
exception to this rule; in older Emacs versions, every pointer to a
string needed to be marked by GC.)
The macro @code{GCPRO1} protects just one local variable. If you
want to protect two, use @code{GCPRO2} instead; repeating
@ -612,7 +613,7 @@ Alas, we can't explain all the tricky details here.
accept two arguments at the C level: the number of Lisp arguments, and
a @code{Lisp_Object *} pointer to a C vector containing those Lisp
arguments. This C vector may be part of a Lisp vector, but it need
not be. The responsibility for using GCPRO to protecting the Lisp
not be. The responsibility for using @code{GCPRO} to protect the Lisp
arguments from GC if necessary rests with the caller in this case,
since the caller allocated or found the storage for them.
@ -651,6 +652,7 @@ file, add to it a @code{syms_of_@var{filename}} (e.g.,
of these functions are called, and add a call to
@code{syms_of_@var{filename}} there.
@anchor{Defining Lisp variables in C}
@vindex byte-boolean-vars
The function @code{syms_of_@var{filename}} is also the place to define
any C variables that are to be visible as Lisp variables.
@ -761,9 +763,9 @@ knows about it.
data are stored in a heap and the only access that programs have to it
is through pointers. Pointers are thirty-two bits wide in most
implementations. Depending on the operating system and type of machine
for which you compile Emacs, twenty-eight bits are used to address the
object, and the remaining four bits are used for a GC mark bit and the
tag that identifies the object's type.
for which you compile Emacs, twenty-nine bits are used to address the
object, and the remaining three bits are used for the tag that
identifies the object's type.
Because Lisp objects are represented as tagged pointers, it is always
possible to determine the Lisp data type of any object. The C data type

View file

@ -140,6 +140,7 @@ This variable is non-@code{nil} if Emacs is in the process of loading a
file, and it is @code{nil} otherwise.
@end defvar
@anchor{Definition of load-read-function}
@defvar load-read-function
This variable specifies an alternate expression-reading function for
@code{load} and @code{eval-region} to use instead of @code{read}.
@ -150,7 +151,7 @@ functions should use @code{read}.
Instead of using this variable, it is cleaner to use another, newer
feature: to pass the function as the @var{read-function} argument to
@code{eval-region}. @xref{Eval}.
@code{eval-region}. @xref{Definition of eval-region,, Eval}.
@end defvar
For information about how @code{load} is used in building Emacs, see

View file

@ -96,13 +96,15 @@ default value to @code{nil} early in startup.
@defun position-bytes position
@tindex position-bytes
Return the byte-position corresponding to buffer position @var{position}
in the current buffer.
in the current buffer. If @var{position} is out of range, the value
is @code{nil}.
@end defun
@defun byte-to-position byte-position
@tindex byte-to-position
Return the buffer position corresponding to byte-position
@var{byte-position} in the current buffer.
@var{byte-position} in the current buffer. If @var{byte-position} is
out of range, the value is @code{nil}.
@end defun
@defun multibyte-string-p string
@ -173,6 +175,9 @@ multibyte character. The value should be a char-table, or @code{nil}.
If this is non-@code{nil}, it overrides @code{nonascii-insert-offset}.
@end defvar
The next three functions either return the argument @var{string}, or a
newly created string with no text properties.
@defun string-make-unibyte string
This function converts the text of @var{string} to unibyte
representation, if it isn't already, and returns the result. If
@ -186,15 +191,23 @@ fails, this function takes just the low 8 bits of each character.
@defun string-make-multibyte string
This function converts the text of @var{string} to multibyte
representation, if it isn't already, and returns the result. If
@var{string} is a multibyte string, it is returned unchanged.
The function @code{unibyte-char-to-multibyte} is used to convert
each unibyte character to a multibyte character.
@var{string} is a multibyte string or consists entirely of
@acronym{ASCII} characters, it is returned unchanged. In particular,
if @var{string} is unibyte and entirely @acronym{ASCII}, the returned
string is unibyte. (When the characters are all @acronym{ASCII},
Emacs primitives will treat the string the same way whether it is
unibyte or multibyte.) If @var{string} is unibyte and contains
non-@acronym{ASCII} characters, the function
@code{unibyte-char-to-multibyte} is used to convert each unibyte
character to a multibyte character.
@end defun
@defun string-to-multibyte string
This function returns a multibyte string containing the same sequence
of character codes as @var{string}. If @var{string} is a multibyte
string, the value is the equal to @var{string}.
of character codes as @var{string}. Unlike
@code{string-make-multibyte}, this function unconditionally returns a
multibyte string. If @var{string} is a multibyte string, it is
returned unchanged.
@end defun
@node Selecting a Representation
@ -280,8 +293,8 @@ text representations.
@end example
If the optional argument @var{genericp} is non-@code{nil}, this
function returns @code{t} if @var{charcode} is a generic character
(@pxref{Splitting Characters}).
function also returns @code{t} if @var{charcode} is a generic
character (@pxref{Splitting Characters}).
@end defun
@node Character Sets
@ -311,13 +324,19 @@ Returns @code{t} if @var{object} is a symbol that names a character set,
@code{nil} otherwise.
@end defun
@defvar charset-list
The value is a list of all defined character set names.
@end defvar
@defun charset-list
This function returns a list of all defined character set names.
This function returns the value of @code{charset-list}. It is only
provided for backward compatibility.
@end defun
@defun char-charset character
This function returns the name of the character set that @var{character}
belongs to.
belongs to, or the symbol @code{unknown} if @var{character} is not a
valid character.
@end defun
@defun charset-plist charset
@ -378,6 +397,9 @@ Return a list containing the name of the character set of
identify @var{character} within that character set. The number of byte
values is the character set's dimension.
If @var{character} is invalid as a character code, @code{split-char}
returns a list consisting of the symbol @code{unknown} and @var{character}.
@example
(split-char 2248)
@result{} (latin-iso8859-1 72)
@ -463,11 +485,11 @@ current buffer.
@cindex character translation tables
@cindex translation tables
A @dfn{translation table} specifies a mapping of characters
into characters. These tables are used in encoding and decoding, and
for other purposes. Some coding systems specify their own particular
translation tables; there are also default translation tables which
apply to all other coding systems.
A @dfn{translation table} is a char-table that specifies a mapping
of characters into characters. These tables are used in encoding and
decoding, and for other purposes. Some coding systems specify their
own particular translation tables; there are also default translation
tables which apply to all other coding systems.
@defun make-translation-table &rest translations
This function returns a translation table based on the argument
@ -483,24 +505,30 @@ character, say @var{to-alt}, @var{from} is also translated to
You can also map one whole character set into another character set with
the same dimension. To do this, you specify a generic character (which
designates a character set) for @var{from} (@pxref{Splitting Characters}).
In this case, @var{to} should also be a generic character, for another
character set of the same dimension. Then the translation table
translates each character of @var{from}'s character set into the
corresponding character of @var{to}'s character set.
In this case, if @var{to} is also a generic character, its character
set should have the same dimension as @var{from}'s. Then the
translation table translates each character of @var{from}'s character
set into the corresponding character of @var{to}'s character set. If
@var{from} is a generic character and @var{to} is an ordinary
character, then the translation table translates every character of
@var{from}'s character set into @var{to}.
@end defun
In decoding, the translation table's translations are applied to the
characters that result from ordinary decoding. If a coding system has
property @code{character-translation-table-for-decode}, that specifies
the translation table to use. Otherwise, if
@code{standard-translation-table-for-decode} is non-@code{nil}, decoding
uses that table.
property @code{translation-table-for-decode}, that specifies the
translation table to use. (This is a property of the coding system,
as returned by @code{coding-system-get}, not a property of the symbol
that is the coding system's name. @xref{Coding System Basics,, Basic
Concepts of Coding Systems}.) Otherwise, if
@code{standard-translation-table-for-decode} is non-@code{nil},
decoding uses that table.
In encoding, the translation table's translations are applied to the
characters in the buffer, and the result of translation is actually
encoded. If a coding system has property
@code{character-translation-table-for-encode}, that specifies the
translation table to use. Otherwise the variable
@code{translation-table-for-encode}, that specifies the translation
table to use. Otherwise the variable
@code{standard-translation-table-for-encode} specifies the translation
table.
@ -516,7 +544,8 @@ coding systems that don't specify any other translation table.
@defvar translation-table-for-input
Self-inserting characters are translated through this translation
table before they are inserted.
table before they are inserted. This variable automatically becomes
buffer-local when set.
@end defvar
@node Coding Systems
@ -686,7 +715,7 @@ systems as well.
@defun coding-system-p object
This function returns @code{t} if @var{object} is a coding system
name.
name or @code{nil}.
@end defun
@defun check-coding-system coding-system
@ -701,6 +730,9 @@ except for its eol conversion, which is specified by @code{eol-type}.
@var{eol-type} should be @code{unix}, @code{dos}, @code{mac}, or
@code{nil}. If it is @code{nil}, the returned coding system determines
the end-of-line conversion from the data.
@var{eol-type} may also be 0, 1 or 2, standing for @code{unix},
@code{dos} and @code{mac}, respectively.
@end defun
@defun coding-system-change-text-conversion eol-coding text-coding
@ -745,55 +777,79 @@ return value is just one coding system, the one that is highest in
priority.
If the region contains only @acronym{ASCII} characters, the value
is @code{undecided} or @code{(undecided)}.
is @code{undecided} or @code{(undecided)}, or a variant specifying
end-of-line conversion, if that can be deduced from the text.
@end defun
@defun detect-coding-string string highest
@defun detect-coding-string string &optional highest
This function is like @code{detect-coding-region} except that it
operates on the contents of @var{string} instead of bytes in the buffer.
@end defun
@xref{Process Information}, for how to examine or set the coding
systems used for I/O to a subprocess.
@xref{Coding systems for a subprocess,, Process Information}, in
particular the description of the functions
@code{process-coding-system} and @code{set-process-coding-system}, for
how to examine or set the coding systems used for I/O to a subprocess.
@node User-Chosen Coding Systems
@subsection User-Chosen Coding Systems
@cindex select safe coding system
@defun select-safe-coding-system from to &optional default-coding-system accept-default-p
@defun select-safe-coding-system from to &optional default-coding-system accept-default-p file
This function selects a coding system for encoding specified text,
asking the user to choose if necessary. Normally the specified text
is the text in the current buffer between @var{from} and @var{to},
defaulting to the whole buffer if they are @code{nil}. If @var{from}
is a string, the string specifies the text to encode, and @var{to} is
ignored.
is the text in the current buffer between @var{from} and @var{to}. If
@var{from} is a string, the string specifies the text to encode, and
@var{to} is ignored.
If @var{default-coding-system} is non-@code{nil}, that is the first
coding system to try; if that can handle the text,
@code{select-safe-coding-system} returns that coding system. It can
also be a list of coding systems; then the function tries each of them
one by one. After trying all of them, it next tries the user's most
preferred coding system (@pxref{Recognize Coding,
prefer-coding-system, the description of @code{prefer-coding-system},
emacs, GNU Emacs Manual}), and after that the current buffer's value
of @code{buffer-file-coding-system} (if it is not @code{undecided}).
one by one. After trying all of them, it next tries the current
buffer's value of @code{buffer-file-coding-system} (if it is not
@code{undecided}), then the value of
@code{default-buffer-file-coding-system} and finally the user's most
preferred coding system, which the user can set using the command
@code{prefer-coding-system} (@pxref{Recognize Coding,, Recognizing
Coding Systems, emacs, The GNU Emacs Manual}).
If one of those coding systems can safely encode all the specified
text, @code{select-safe-coding-system} chooses it and returns it.
Otherwise, it asks the user to choose from a list of coding systems
which can encode all the text, and returns the user's choice.
@var{default-coding-system} can also be a list whose first element is
t and whose other elements are coding systems. Then, if no coding
system in the list can handle the text, @code{select-safe-coding-system}
queries the user immediately, without trying any of the three
alternatives described above.
The optional argument @var{accept-default-p}, if non-@code{nil},
should be a function to determine whether the coding system selected
without user interaction is acceptable. If this function returns
@code{nil}, the silently selected coding system is rejected, and the
user is asked to select a coding system from a list of possible
candidates.
should be a function to determine whether a coding system selected
without user interaction is acceptable. @code{select-safe-coding-system}
calls this function with one argument, the base coding system of the
selected coding system. If @var{accept-default-p} returns @code{nil},
@code{select-safe-coding-system} rejects the silently selected coding
system, and asks the user to select a coding system from a list of
possible candidates.
@vindex select-safe-coding-system-accept-default-p
If the variable @code{select-safe-coding-system-accept-default-p} is
non-@code{nil}, its value overrides the value of
@var{accept-default-p}.
As a final step, before returning the chosen coding system,
@code{select-safe-coding-system} checks whether that coding system is
consistent with what would be selected if the contents of the region
were read from a file. (If not, this could lead to data corruption in
a file subsequently re-visited and edited.) Normally,
@code{select-safe-coding-system} uses @code{buffer-file-name} as the
file for this purpose, but if @var{file} is non-@code{nil}, it uses
that file instead (this can be relevant for @code{write-region} and
similar functions). If it detects an apparent inconsistency,
@code{select-safe-coding-system} queries the user before selecting the
coding system.
@end defun
Here are two functions you can use to let the user specify a coding
@ -846,17 +902,19 @@ reading and writing particular files. Each element has the form
expression that matches certain file names. The element applies to file
names that match @var{pattern}.
The @acronym{CDR} of the element, @var{coding}, should be either a coding
The @sc{cdr} of the element, @var{coding}, should be either a coding
system, a cons cell containing two coding systems, or a function name (a
symbol with a function definition). If @var{coding} is a coding system,
that coding system is used for both reading the file and writing it. If
@var{coding} is a cons cell containing two coding systems, its @acronym{CAR}
specifies the coding system for decoding, and its @acronym{cdr} specifies the
@var{coding} is a cons cell containing two coding systems, its @sc{car}
specifies the coding system for decoding, and its @sc{cdr} specifies the
coding system for encoding.
If @var{coding} is a function name, the function must return a coding
system or a cons cell containing two coding systems. This value is used
as described above.
If @var{coding} is a function name, the function should take one
argument, a list of all arguments passed to
@code{find-operation-coding-system}. It must return a coding system
or a cons cell containing two coding systems. This value has the same
meaning as described above.
@end defvar
@defvar process-coding-system-alist
@ -923,7 +981,7 @@ performing @var{operation} with @var{arguments}. The value has this
form:
@example
(@var{decoding-system} @var{encoding-system})
(@var{decoding-system} . @var{encoding-system})
@end example
The first element, @var{decoding-system}, is the coding system to use
@ -948,7 +1006,6 @@ or port number.
This function looks up the target in @code{file-coding-system-alist},
@code{process-coding-system-alist}, or
@code{network-coding-system-alist}, depending on @var{operation}.
@xref{Default Coding Systems}.
@end defun
@node Specifying Coding Systems
@ -1040,33 +1097,41 @@ decoding functions produce sequences of bytes; the encoding functions
are meant to operate on sequences of bytes. All of these functions
discard text properties.
@defun encode-coding-region start end coding-system
This function encodes the text from @var{start} to @var{end} according
@deffn Command encode-coding-region start end coding-system
This command encodes the text from @var{start} to @var{end} according
to coding system @var{coding-system}. The encoded text replaces the
original text in the buffer. The result of encoding is logically a
sequence of bytes, but the buffer remains multibyte if it was multibyte
before.
@end defun
@defun encode-coding-string string coding-system
This command returns the length of the encoded text.
@end deffn
@defun encode-coding-string string coding-system &optional nocopy
This function encodes the text in @var{string} according to coding
system @var{coding-system}. It returns a new string containing the
encoded text. The result of encoding is a unibyte string.
encoded text, except when @var{nocopy} is non-@code{nil}, in which
case the function may return @var{string} itself if the encoding
operation is trivial. The result of encoding is a unibyte string.
@end defun
@defun decode-coding-region start end coding-system
This function decodes the text from @var{start} to @var{end} according
@deffn Command decode-coding-region start end coding-system
This command decodes the text from @var{start} to @var{end} according
to coding system @var{coding-system}. The decoded text replaces the
original text in the buffer. To make explicit decoding useful, the text
before decoding ought to be a sequence of byte values, but both
multibyte and unibyte buffers are acceptable.
@end defun
@defun decode-coding-string string coding-system
This command returns the length of the decoded text.
@end deffn
@defun decode-coding-string string coding-system &optional nocopy
This function decodes the text in @var{string} according to coding
system @var{coding-system}. It returns a new string containing the
decoded text. To make explicit decoding useful, the contents of
@var{string} ought to be a sequence of byte values, but a multibyte
decoded text, except when @var{nocopy} is non-@code{nil}, in which
case the function may return @var{string} itself if the decoding
operation is trivial. To make explicit decoding useful, the contents
of @var{string} ought to be a sequence of byte values, but a multibyte
string is acceptable.
@end defun
@ -1095,22 +1160,22 @@ This function returns the coding system that is in use for decoding
keyboard input---or @code{nil} if no coding system is to be used.
@end defun
@defun set-keyboard-coding-system coding-system
This function specifies @var{coding-system} as the coding system to
@deffn Command set-keyboard-coding-system coding-system
This command specifies @var{coding-system} as the coding system to
use for decoding keyboard input. If @var{coding-system} is @code{nil},
that means do not decode keyboard input.
@end defun
@end deffn
@defun terminal-coding-system
This function returns the coding system that is in use for encoding
terminal output---or @code{nil} for no encoding.
@end defun
@defun set-terminal-coding-system coding-system
This function specifies @var{coding-system} as the coding system to use
@deffn Command set-terminal-coding-system coding-system
This command specifies @var{coding-system} as the coding system to use
for encoding terminal output. If @var{coding-system} is @code{nil},
that means do not encode terminal output.
@end defun
@end deffn
@node MS-DOS File Types
@subsection MS-DOS File Types
@ -1193,18 +1258,18 @@ in any fashion.) It is @code{nil} if no input method is active in the
buffer now.
@end defvar
@defvar default-input-method
@defopt default-input-method
This variable holds the default input method for commands that choose an
input method. Unlike @code{current-input-method}, this variable is
normally global.
@end defvar
@end defopt
@defun set-input-method input-method
This function activates input method @var{input-method} for the current
@deffn Command set-input-method input-method
This command activates input method @var{input-method} for the current
buffer. It also sets @code{default-input-method} to @var{input-method}.
If @var{input-method} is @code{nil}, this function deactivates any input
If @var{input-method} is @code{nil}, this command deactivates any input
method for the current buffer.
@end defun
@end deffn
@defun read-input-method-name prompt &optional default inhibit-null
This function reads an input method name with the minibuffer, prompting
@ -1240,7 +1305,8 @@ it is good for.
@end defvar
The fundamental interface to input methods is through the
variable @code{input-method-function}. @xref{Reading One Event}.
variable @code{input-method-function}. @xref{Reading One Event},
and @ref{Invoking the Input Method}.
@node Locales
@section Locales
@ -1294,14 +1360,14 @@ through @code{MON_12}).
@item paper
Return a list @code{(@var{width} @var{height})} for the default paper
size measured in milimeters (locale items @code{PAPER_WIDTH} and
size measured in millimeters (locale items @code{PAPER_WIDTH} and
@code{PAPER_HEIGHT}).
@end table
If the system can't provide the requested information, or if
@var{item} is not one of those symbols, the value is @code{nil}. All
strings in the return value are decoded using
@code{locale-coding-system}. @xref{Locales,,, libc, GNU Libc Manual},
@code{locale-coding-system}. @xref{Locales,,, libc, The GNU Libc Manual},
for more information about locales and locale items.
@end defun

View file

@ -42,7 +42,9 @@ it as a number; Lisp knows it is a vector, not a number.
variable, and the type is known by the compiler but not represented in
the data. Such type declarations do not exist in Emacs Lisp. A Lisp
variable can have any type of value, and it remembers whatever value
you store in it, type and all.
you store in it, type and all. (Actually, a small number of Emacs
Lisp variables can only take on values of a certain type.
@xref{Variables with Restricted Values}.)
This chapter describes the purpose, printed representation, and read
syntax of each of the standard types in GNU Emacs Lisp. Details on how

View file

@ -676,6 +676,7 @@ instead of a terminal (see @code{process-connection-type} in
@ref{Asynchronous Processes}).
@end defun
@anchor{Coding systems for a subprocess}
@defun process-coding-system process
This function returns a cons cell describing the coding systems in use
for decoding output from @var{process} and for encoding input to

View file

@ -647,6 +647,7 @@ The argument FOO can be either a number
This prevents the open-parenthesis from being treated as the start of a
defun (@pxref{Defuns,, Defuns, emacs, The GNU Emacs Manual}).
@anchor{Docstring hyperlinks}
@item
@iftex
When a documentation string refers to a Lisp symbol, write it as it

View file

@ -43,6 +43,8 @@ variable.
* Future Local Variables:: New kinds of local values we might add some day.
* Variable Aliases:: Variables that are aliases for other variables.
* File Local Variables:: Handling local variable lists in files.
* Variables with Restricted Values:: Non-constant variables whose value can
@emph{not} be an arbitrary Lisp object.
@end menu
@node Global Variables
@ -258,19 +260,21 @@ These kinds of bindings work somewhat like ordinary local bindings, but
they are localized depending on ``where'' you are in Emacs, rather than
localized in time.
@anchor{Definition of max-specpdl-size}
@defvar max-specpdl-size
@cindex variable limit error
@cindex evaluation error
@cindex infinite recursion
This variable defines the limit on the total number of local variable
bindings and @code{unwind-protect} cleanups (@pxref{Nonlocal Exits})
that are allowed before signaling an error (with data @code{"Variable
binding depth exceeds max-specpdl-size"}).
bindings and @code{unwind-protect} cleanups (@pxref{Cleanups,,
Cleaning Up from Nonlocal Exits}) that are allowed before signaling an
error (with data @code{"Variable binding depth exceeds
max-specpdl-size"}).
This limit, with the associated error when it is exceeded, is one way
that Lisp avoids infinite recursion on an ill-defined function.
@code{max-lisp-eval-depth} provides another limit on depth of nesting.
@xref{Eval}.
@xref{Definition of max-lisp-eval-depth,, Eval}.
The default value is 600. Entry to the Lisp debugger increases the
value, if there is little room left, to make sure the debugger itself
@ -1813,6 +1817,41 @@ could include functions to call. So Emacs discards all text
properties from string values specified in a file's local variables
list.
@node Variables with Restricted Values
@section Variables with Restricted Values
Ordinary Lisp variables can be assigned any value that is a valid
Lisp object. However, certain Lisp variables are not defined in Lisp,
but in C. Most of these variables are defined in the C code using
@code{DEFVAR_LISP}. Like variables defined in Lisp, these can take on
any value. However, some variables are defined using
@code{DEFVAR_INT} or @code{DEFVAR_BOOL}. @xref{Defining Lisp
variables in C,, Writing Emacs Primitives}, in particular the
description of functions of the type @code{syms_of_@var{filename}},
for a brief discussion of the C implementation.
Variables of type @code{DEFVAR_BOOL} can only take on the values
@code{nil} or @code{t}. Attempting to assign them any other value
will set them to @code{t}:
@example
(let ((display-hourglass 5))
display-hourglass)
@result{} t
@end example
@defvar byte-boolean-vars
This variable holds a list of all variables of type @code{DEFVAR_BOOL}.
@end defvar
Variables of type @code{DEFVAR_INT} can only take on integer values.
Attempting to assign them any other value will result in an error:
@example
(setq window-min-height 5.0)
@error{} Wrong type argument: integerp, 5.0
@end example
@ignore
arch-tag: 5ff62c44-2b51-47bb-99d4-fea5aeec5d3e
@end ignore

View file

@ -1,3 +1,94 @@
2003-12-28 Kim F. Storm <storm@cua.dk>
* Makefile.in (eval.o): Depend on dispextern.h.
* dispnew.c (buffer_posn_from_coords): Fix calculation of dy for
image glyph using image's ascent.
(mode_line_string): Return image glyph as object clicked on.
Adjust y0 for image glyph using image's ascent.
* dispextern.h (FACE_ID_BITS, MAX_FACE_ID): New defines.
(struct glyph): New members, ascent and descent. Used to save
this glyph's ascent and descent, instead of having.
(struct glyph): Declare member face_id using FACE_ID_BITS.
(find_hot_spot): Add prototype.
* keyboard.c (Qimage): Remove extern (now in lisp.h).
(QCmap): Declare extern.
(make_lispy_position): When position is inside image hot-spot,
use hot-spot element's id as posn element.
* lisp.h (IMAGEP): New macro to test for image object type.
(Qimage): Declare extern.
* macfns.c (Qimage): Remove extern (now in lisp.h).
(valid_image_p, parse_image_spec): Use IMAGEP macro.
* macterm.c (Qface, Qmouse_face): Remove unused externs.
* w32fns.c (Qimage): Remove extern (now in lisp.h).
(valid_image_p, parse_image_spec): Use IMAGEP macro.
* w32menu.c (Qmouse_click, Qevent_kind): Remove unused externs.
* w32term.c (Qface, Qmouse_face): Remove unused externs.
* xdisp.c (Qarrow, Qhand, Qtext, Qpointer): New variables for
pointer types.
(Qrelative_width, Qalign_to): Remove unused variables.
(Vvoid_text_area_pointer): Replace Vshow_text_cursor_in_void.
(QCmap, QCpointer, Qrect, Qcircle, Qpoly): New variables for
image maps.
(x_y_to_hpos_vpos): Return glyph relative coordinates through
new dx and dy args.
Remove buffer_only_p arg (always 0). Simplify code accordingly.
(get_glyph_string_clip_rect): Draw cursor using glyph's rather
than row's ascent and height, to get sensible height on tall rows.
(build_desired_tool_bar_string): Remove Qimage extern.
(get_tool_bar_item): Fix call to x_y_to_hpos_vpos.
(produce_image_glyph): Adjust it.ascent to minimum row ascent if
image glyph is alone on the last line.
(append_glyph, append_composite_glyph, produce_image_glyph)
(append_stretch_glyph): Set glyph's ascent and descent.
(on_hot_spot_p): New function to check if position is inside an
rectangular, circular, or polygon-shaped image hot-spot,
(find_hot_spot): New function to search for image hot-spot.
(Flookup_image_map): New defun to search for image hot-spot.
(define_frame_cursor1): New aux function to determine frame pointer.
(note_mode_line_or_margin_highlight, note_mouse_highlight):
Handle `pointer' text property and :pointer image property to
control frame pointer shape. Detect image hot-spots for pointer
and help_echo properties. Use define_frame_cursor1.
(note_mouse_highlight): Use Vvoid_text_area_pointer.
(syms_of_xdisp): Defsubr new defun. Intern and staticpro new variables.
DEFVAR_LISP Vvoid_text_area_pointer instead of Vshow_text_cursor_in_void.
* xfaces.c (cache_face): Abort if c->size exceeds MAX_FACE_ID.
* xfns.c (x_set_mouse_color): Remove bogus x_check_errors call.
(Qimage): Remove extern (now in lisp.h).
(valid_image_p, parse_image_spec): Use IMAGEP macro.
* xmenu.c (show_help_event): Remove unused code.
* xterm.c (Qface, Qmouse_face): Remove unused externs.
(x_draw_hollow_cursor): Draw cursor using glyph's rather than
row's ascent and descent, to get a sensible height on tall rows.
2003-12-25 Luc Teirlinck <teirllm@auburn.edu>
* minibuf.c (Fcompleting_read): Undo previous change.
2003-12-25 Lars Hansen <larsh@math.ku.dk>
* dired.c (Fdirectory_files, Fdirectory_files_and_attributes):
Arguments GCPRO'ed in call to file name handler.
2003-12-25 Thien-Thi Nguyen <ttn@gnu.org>
* termcap.c (tgetst1): Scan for "%pN"; if all
N are continuous in [1,9], remove all "%pN".
2003-12-24 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
* gtkutil.c (xg_frame_set_char_size): Call x_wm_set_size_hint.

View file

@ -1172,7 +1172,7 @@ alloc.o: alloc.c process.h frame.h window.h buffer.h puresize.h syssignal.h key
bytecode.o: bytecode.c buffer.h syntax.h charset.h window.h $(config_h)
data.o: data.c buffer.h puresize.h charset.h syssignal.h keyboard.h $(config_h)
eval.o: eval.c commands.h keyboard.h blockinput.h atimer.h systime.h \
$(config_h)
dispextern.h $(config_h)
floatfns.o: floatfns.c $(config_h)
fns.o: fns.c commands.h $(config_h) frame.h buffer.h charset.h keyboard.h \
frame.h window.h dispextern.h $(INTERVAL_SRC) coding.h md5.h

View file

@ -842,9 +842,12 @@ syms_of_composite ()
args[0] = QCtest;
args[1] = Qequal;
/* We used to make the hash table weak so that unreferenced
compostions can be garbage-collected. But, usually once
created compositions are repeatedly used in an Emacs session,
and thus it's not worth to save memory in such a way. So, we
make the table not weak. */
args[2] = QCweakness;
/* Fixme: It seems that a weak hash table leads to segfault in GC,
but I have not yet found why. -- handa@m17n.org */
args[3] = Qnil;
args[4] = QCsize;
args[5] = make_number (311);

View file

@ -359,17 +359,8 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
call the corresponding file handler. */
handler = Ffind_file_name_handler (directory, Qdirectory_files);
if (!NILP (handler))
{
Lisp_Object args[6];
args[0] = handler;
args[1] = Qdirectory_files;
args[2] = directory;
args[3] = full;
args[4] = match;
args[5] = nosort;
return Ffuncall (6, args);
}
return call5 (handler, Qdirectory_files, directory,
full, match, nosort);
return directory_files_internal (directory, full, match, nosort, 0, Qnil);
}
@ -395,18 +386,8 @@ ID-FORMAT specifies the preferred format of attributes uid and gid, see
call the corresponding file handler. */
handler = Ffind_file_name_handler (directory, Qdirectory_files_and_attributes);
if (!NILP (handler))
{
Lisp_Object args[7];
args[0] = handler;
args[1] = Qdirectory_files_and_attributes;
args[2] = directory;
args[3] = full;
args[4] = match;
args[5] = nosort;
args[6] = id_format;
return Ffuncall (7, args);
}
return call6 (handler, Qdirectory_files_and_attributes,
directory, full, match, nosort, id_format);
return directory_files_internal (directory, full, match, nosort, 1, id_format);
}

View file

@ -321,6 +321,9 @@ struct glyph
/* Width in pixels. */
short pixel_width;
/* Ascent and descent in pixels. */
short ascent, descent;
/* Vertical offset. If < 0, the glyph is displayed raised, if > 0
the glyph is displayed lowered. */
short voffset;
@ -359,8 +362,10 @@ struct glyph
doesn't have a glyph in a font. */
unsigned glyph_not_available_p : 1;
#define FACE_ID_BITS 21
/* Face of the glyph. */
unsigned face_id : 21;
unsigned face_id : FACE_ID_BITS;
/* Type of font used to display the character glyph. May be used to
determine which set of functions to use to obtain font metrics
@ -1493,6 +1498,7 @@ enum face_id
BASIC_FACE_ID_SENTINEL
};
#define MAX_FACE_ID ((1 << FACE_ID_BITS) - 1)
/* A cache of realized faces. Each frame has its own cache because
Emacs allows different frame-local face definitions. */
@ -2536,6 +2542,7 @@ extern void x_draw_vertical_border P_ ((struct window *w));
extern void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
extern void get_glyph_string_clip_rect P_ ((struct glyph_string *,
NativeRectangle *nr));
extern Lisp_Object find_hot_spot P_ ((Lisp_Object, int, int));
extern void note_mouse_highlight P_ ((struct frame *, int, int));
extern void x_clear_window_mouse_face P_ ((struct window *));
extern void cancel_mouse_face P_ ((struct frame *));

View file

@ -5700,8 +5700,6 @@ buffer_posn_from_coords (w, x, y, dx, dy, object, pos)
struct it it;
struct buffer *old_current_buffer = current_buffer;
struct text_pos startp;
struct glyph_row *row;
struct image *img;
int x0, x1;
current_buffer = XBUFFER (w->buffer);
@ -5714,25 +5712,44 @@ buffer_posn_from_coords (w, x, y, dx, dy, object, pos)
move_it_to (&it, -1, x0 + it.first_visible_x, *y, -1,
MOVE_TO_X | MOVE_TO_Y);
/* Add extra (default width) columns if clicked after EOL. */
x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x);
if (x0 > x1)
it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
current_buffer = old_current_buffer;
*dx = x0 + it.first_visible_x - it.current_x;
*dy = *y - it.current_y;
*object = w->buffer;
#ifdef HAVE_WINDOW_SYSTEM
if (it.what == IT_IMAGE
&& (img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL
&& !NILP (img->spec))
*object = img->spec;
if (it.what == IT_IMAGE)
{
struct image *img;
if ((img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL
&& !NILP (img->spec))
{
struct glyph_row *row = MATRIX_ROW (w->current_matrix, it.vpos);
struct glyph *glyph;
if (it.hpos < row->used[TEXT_AREA]
&& (glyph = row->glyphs[TEXT_AREA] + it.hpos,
glyph->type == IMAGE_GLYPH))
{
*dy -= row->ascent - glyph->ascent;
*object = img->spec;
}
}
}
else
#endif
*object = STRINGP (it.string) ? it.string : w->buffer;
if (STRINGP (it.string))
*object = it.string;
*pos = it.current;
/* Add extra (default width) columns if clicked after EOL. */
x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x);
if (x0 > x1)
it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
*x = it.hpos;
*y = it.vpos;
}
@ -5852,6 +5869,16 @@ marginal_area_string (w, x, y, dx, dy, part, charpos)
{
string = glyph->object;
*charpos = glyph->charpos;
#ifdef HAVE_WINDOW_SYSTEM
if (glyph->type == IMAGE_GLYPH)
{
struct image *img;
img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
if (img != NULL)
string = img->spec;
y0 -= row->ascent - glyph->ascent;
}
#endif
}
else
/* Add extra (default width) columns if clicked after EOL. */

View file

@ -579,7 +579,7 @@ Lisp_Object Qvertical_scroll_bar;
Lisp_Object Qmenu_bar;
extern Lisp_Object Qleft_margin, Qright_margin;
extern Lisp_Object Qleft_fringe, Qright_fringe;
extern Lisp_Object Qimage;
extern Lisp_Object QCmap;
Lisp_Object recursive_edit_unwind (), command_loop ();
Lisp_Object Fthis_command_keys ();
@ -5016,6 +5016,19 @@ make_lispy_position (f, x, y, time)
string = marginal_area_string (w, &rx, &ry, &dx, &dy, part, &charpos);
if (STRINGP (string))
object = Fcons (string, make_number (charpos));
#ifdef HAVE_WINDOW_SYSTEM
else if (IMAGEP (string))
{
Lisp_Object image_map, hotspot;
object = string;
if ((image_map = Fplist_get (XCDR (object), QCmap),
!NILP (image_map))
&& (hotspot = find_hot_spot (image_map, dx, dy),
CONSP (hotspot))
&& (hotspot = XCDR (hotspot), CONSP (hotspot)))
posn = XCAR (hotspot);
}
#endif
}
else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
{
@ -5051,8 +5064,19 @@ make_lispy_position (f, x, y, time)
if (STRINGP (string))
object = Fcons (string,
make_number (CHARPOS (p.string_pos)));
else if (CONSP (string) && EQ (XCAR (string), Qimage))
object = string;
#ifdef HAVE_WINDOW_SYSTEM
else if (IMAGEP (string))
{
Lisp_Object image_map, hotspot;
object = string;
if ((image_map = Fplist_get (XCDR (object), QCmap),
!NILP (image_map))
&& (hotspot = find_hot_spot (image_map, dx, dy),
CONSP (hotspot))
&& (hotspot = XCDR (hotspot), CONSP (hotspot)))
posn = XCAR (hotspot);
}
#endif
}
}

View file

@ -1381,6 +1381,10 @@ typedef unsigned char UCHAR;
#define GC_FRAMEP(x) GC_PSEUDOVECTORP (x, PVEC_FRAME)
#define SUB_CHAR_TABLE_P(x) (CHAR_TABLE_P (x) && NILP (XCHAR_TABLE (x)->top))
/* Test for image (image . spec) */
#define IMAGEP(x) (CONSP (x) && EQ (XCAR (x), Qimage))
#define GC_EQ(x, y) EQ (x, y)
@ -2283,6 +2287,7 @@ extern Lisp_Object Qinhibit_point_motion_hooks;
extern Lisp_Object Qinhibit_redisplay, Qdisplay;
extern Lisp_Object Qinhibit_eval_during_redisplay;
extern Lisp_Object Qmessage_truncate_lines;
extern Lisp_Object Qimage;
extern Lisp_Object Vmessage_log_max;
extern int message_enable_multibyte;
extern Lisp_Object echo_area_buffer[2];

View file

@ -3460,11 +3460,6 @@ If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
static struct image_type *image_types;
/* The symbol `image' which is the car of the lists used to represent
images in Lisp. */
extern Lisp_Object Qimage;
/* The symbol `xbm' which is used as the type symbol for XBM images. */
Lisp_Object Qxbm;
@ -3543,7 +3538,7 @@ valid_image_p (object)
{
int valid_p = 0;
if (CONSP (object) && EQ (XCAR (object), Qimage))
if (IMAGEP (object))
{
Lisp_Object symbol = Fplist_get (XCDR (object), QCtype);
struct image_type *type = lookup_image_type (symbol);
@ -3633,7 +3628,7 @@ parse_image_spec (spec, keywords, nkeywords, type)
int i;
Lisp_Object plist;
if (!CONSP (spec) || !EQ (XCAR (spec), Qimage))
if (!IMAGEP (spec))
return 0;
plist = XCDR (spec);

View file

@ -253,8 +253,6 @@ extern Lisp_Object Vcommand_line_args, Vsystem_name;
extern Lisp_Object Vx_no_window_manager;
extern Lisp_Object Qface, Qmouse_face;
extern int errno;
/* A mask of extra modifier bits to put into every keyboard char. */

View file

@ -1578,10 +1578,13 @@ Completion ignores case if the ambient value of
Lisp_Object prompt, table, predicate, require_match, initial_input;
Lisp_Object hist, def, inherit_input_method;
{
Lisp_Object val, histvar, histpos;
Lisp_Object val, histvar, histpos, position;
Lisp_Object init;
int pos = 0;
int count = SPECPDL_INDEX ();
struct gcpro gcpro1;
init = initial_input;
GCPRO1 (def);
specbind (Qminibuffer_completion_table, table);
@ -1590,6 +1593,23 @@ Completion ignores case if the ambient value of
EQ (require_match, Qt) ? Qnil : require_match);
last_exact_completion = Qnil;
position = Qnil;
if (!NILP (init))
{
if (CONSP (init))
{
position = Fcdr (init);
init = Fcar (init);
}
CHECK_STRING (init);
if (!NILP (position))
{
CHECK_NUMBER (position);
/* Convert to distance from end of input. */
pos = XINT (position) - SCHARS (init);
}
}
if (SYMBOLP (hist))
{
histvar = hist;
@ -1608,7 +1628,7 @@ Completion ignores case if the ambient value of
val = read_minibuf (NILP (require_match)
? Vminibuffer_local_completion_map
: Vminibuffer_local_must_match_map,
initial_input, prompt, Qnil, 0,
init, prompt, make_number (pos), 0,
histvar, histpos, def, 0,
!NILP (inherit_input_method));

6335
src/regex.c Normal file

File diff suppressed because it is too large Load diff

576
src/regex.h Normal file
View file

@ -0,0 +1,576 @@
/* Definitions for data structures and routines for the regular
expression library, version 0.12.
Copyright (C) 1985,89,90,91,92,93,95,2000 Free Software Foundation, Inc.
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
#ifndef _REGEX_H
#define _REGEX_H 1
/* Allow the use in C++ code. */
#ifdef __cplusplus
extern "C" {
#endif
/* POSIX says that <sys/types.h> must be included (by the caller) before
<regex.h>. */
#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS
/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
should be there. */
# include <stddef.h>
#endif
/* The following bits are used to determine the regexp syntax we
recognize. The set/not-set meanings where historically chosen so
that Emacs syntax had the value 0.
The bits are given in alphabetical order, and
the definitions shifted by one from the previous bit; thus, when we
add or remove a bit, only one other definition need change. */
typedef unsigned long int reg_syntax_t;
/* If this bit is not set, then \ inside a bracket expression is literal.
If set, then such a \ quotes the following character. */
#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
/* If this bit is not set, then + and ? are operators, and \+ and \? are
literals.
If set, then \+ and \? are operators and + and ? are literals. */
#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
/* If this bit is set, then character classes are supported. They are:
[:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
[:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
If not set, then character classes are not supported. */
#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
/* If this bit is set, then ^ and $ are always anchors (outside bracket
expressions, of course).
If this bit is not set, then it depends:
^ is an anchor if it is at the beginning of a regular
expression or after an open-group or an alternation operator;
$ is an anchor if it is at the end of a regular expression, or
before a close-group or an alternation operator.
This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
POSIX draft 11.2 says that * etc. in leading positions is undefined.
We already implemented a previous draft which made those constructs
invalid, though, so we haven't changed the code back. */
#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
/* If this bit is set, then special characters are always special
regardless of where they are in the pattern.
If this bit is not set, then special characters are special only in
some contexts; otherwise they are ordinary. Specifically,
* + ? and intervals are only special when not after the beginning,
open-group, or alternation operator. */
#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
/* If this bit is set, then *, +, ?, and { cannot be first in an re or
immediately after an alternation or begin-group operator. */
#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
/* If this bit is set, then . matches newline.
If not set, then it doesn't. */
#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
/* If this bit is set, then . doesn't match NUL.
If not set, then it does. */
#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
/* If this bit is set, nonmatching lists [^...] do not match newline.
If not set, they do. */
#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
/* If this bit is set, either \{...\} or {...} defines an
interval, depending on RE_NO_BK_BRACES.
If not set, \{, \}, {, and } are literals. */
#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
/* If this bit is set, +, ? and | aren't recognized as operators.
If not set, they are. */
#define RE_LIMITED_OPS (RE_INTERVALS << 1)
/* If this bit is set, newline is an alternation operator.
If not set, newline is literal. */
#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
/* If this bit is set, then `{...}' defines an interval, and \{ and \}
are literals.
If not set, then `\{...\}' defines an interval. */
#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
/* If this bit is set, (...) defines a group, and \( and \) are literals.
If not set, \(...\) defines a group, and ( and ) are literals. */
#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
/* If this bit is set, then \<digit> matches <digit>.
If not set, then \<digit> is a back-reference. */
#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
/* If this bit is set, then | is an alternation operator, and \| is literal.
If not set, then \| is an alternation operator, and | is literal. */
#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
/* If this bit is set, then an ending range point collating higher
than the starting range point, as in [z-a], is invalid.
If not set, then when ending range point collates higher than the
starting range point, the range is ignored. */
#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
/* If this bit is set, then an unmatched ) is ordinary.
If not set, then an unmatched ) is invalid. */
#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
/* If this bit is set, succeed as soon as we match the whole pattern,
without further backtracking. */
#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
/* If this bit is set, do not process the GNU regex operators.
If not set, then the GNU regex operators are recognized. */
#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
/* If this bit is set, then *?, +? and ?? match non greedily. */
#define RE_FRUGAL (RE_NO_GNU_OPS << 1)
/* If this bit is set, then (?:...) is treated as a shy group. */
#define RE_SHY_GROUPS (RE_FRUGAL << 1)
/* If this bit is set, ^ and $ only match at beg/end of buffer. */
#define RE_NO_NEWLINE_ANCHOR (RE_SHY_GROUPS << 1)
/* If this bit is set, turn on internal regex debugging.
If not set, and debugging was on, turn it off.
This only works if regex.c is compiled -DDEBUG.
We define this bit always, so that all that's needed to turn on
debugging is to recompile regex.c; the calling code can always have
this bit set, and it won't affect anything in the normal case. */
#define RE_DEBUG (RE_NO_NEWLINE_ANCHOR << 1)
/* This global variable defines the particular regexp syntax to use (for
some interfaces). When a regexp is compiled, the syntax used is
stored in the pattern buffer, so changing this does not affect
already-compiled regexps. */
extern reg_syntax_t re_syntax_options;
#ifdef emacs
/* In Emacs, this is the string or buffer in which we
are matching. It is used for looking up syntax properties. */
extern Lisp_Object re_match_object;
#endif
/* Define combinations of the above bits for the standard possibilities.
(The [[[ comments delimit what gets put into the Texinfo file, so
don't delete them!) */
/* [[[begin syntaxes]]] */
#define RE_SYNTAX_EMACS \
(RE_CHAR_CLASSES | RE_INTERVALS | RE_SHY_GROUPS | RE_FRUGAL)
#define RE_SYNTAX_AWK \
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
| RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \
| RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
#define RE_SYNTAX_GNU_AWK \
((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \
& ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS))
#define RE_SYNTAX_POSIX_AWK \
(RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \
| RE_INTERVALS | RE_NO_GNU_OPS)
#define RE_SYNTAX_GREP \
(RE_BK_PLUS_QM | RE_CHAR_CLASSES \
| RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
| RE_NEWLINE_ALT)
#define RE_SYNTAX_EGREP \
(RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
| RE_NEWLINE_ALT | RE_NO_BK_PARENS \
| RE_NO_BK_VBAR)
#define RE_SYNTAX_POSIX_EGREP \
(RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
/* Syntax bits common to both basic and extended POSIX regex syntax. */
#define _RE_SYNTAX_POSIX_COMMON \
(RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
| RE_INTERVALS | RE_NO_EMPTY_RANGES)
#define RE_SYNTAX_POSIX_BASIC \
(_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
isn't minimal, since other operators, such as \`, aren't disabled. */
#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
(_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
#define RE_SYNTAX_POSIX_EXTENDED \
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
| RE_NO_BK_PARENS | RE_NO_BK_VBAR \
| RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
removed and RE_NO_BK_REFS is added. */
#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
/* [[[end syntaxes]]] */
/* Maximum number of duplicates an interval can allow. Some systems
(erroneously) define this in other header files, but we want our
value, so remove any previous define. */
#ifdef RE_DUP_MAX
# undef RE_DUP_MAX
#endif
/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */
#define RE_DUP_MAX (0x7fff)
/* POSIX `cflags' bits (i.e., information for `regcomp'). */
/* If this bit is set, then use extended regular expression syntax.
If not set, then use basic regular expression syntax. */
#define REG_EXTENDED 1
/* If this bit is set, then ignore case when matching.
If not set, then case is significant. */
#define REG_ICASE (REG_EXTENDED << 1)
/* If this bit is set, then anchors do not match at newline
characters in the string.
If not set, then anchors do match at newlines. */
#define REG_NEWLINE (REG_ICASE << 1)
/* If this bit is set, then report only success or fail in regexec.
If not set, then returns differ between not matching and errors. */
#define REG_NOSUB (REG_NEWLINE << 1)
/* POSIX `eflags' bits (i.e., information for regexec). */
/* If this bit is set, then the beginning-of-line operator doesn't match
the beginning of the string (presumably because it's not the
beginning of a line).
If not set, then the beginning-of-line operator does match the
beginning of the string. */
#define REG_NOTBOL 1
/* Like REG_NOTBOL, except for the end-of-line. */
#define REG_NOTEOL (1 << 1)
/* If any error codes are removed, changed, or added, update the
`re_error_msg' table in regex.c. */
typedef enum
{
#ifdef _XOPEN_SOURCE
REG_ENOSYS = -1, /* This will never happen for this implementation. */
#endif
REG_NOERROR = 0, /* Success. */
REG_NOMATCH, /* Didn't find a match (for regexec). */
/* POSIX regcomp return error codes. (In the order listed in the
standard.) */
REG_BADPAT, /* Invalid pattern. */
REG_ECOLLATE, /* Not implemented. */
REG_ECTYPE, /* Invalid character class name. */
REG_EESCAPE, /* Trailing backslash. */
REG_ESUBREG, /* Invalid back reference. */
REG_EBRACK, /* Unmatched left bracket. */
REG_EPAREN, /* Parenthesis imbalance. */
REG_EBRACE, /* Unmatched \{. */
REG_BADBR, /* Invalid contents of \{\}. */
REG_ERANGE, /* Invalid range end. */
REG_ESPACE, /* Ran out of memory. */
REG_BADRPT, /* No preceding re for repetition op. */
/* Error codes we've added. */
REG_EEND, /* Premature end. */
REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
} reg_errcode_t;
/* This data structure represents a compiled pattern. Before calling
the pattern compiler, the fields `buffer', `allocated', `fastmap',
`translate', and `no_sub' can be set. After the pattern has been
compiled, the `re_nsub' field is available. All other fields are
private to the regex routines. */
#ifndef RE_TRANSLATE_TYPE
# define RE_TRANSLATE_TYPE char *
#endif
struct re_pattern_buffer
{
/* [[[begin pattern_buffer]]] */
/* Space that holds the compiled pattern. It is declared as
`unsigned char *' because its elements are
sometimes used as array indexes. */
unsigned char *buffer;
/* Number of bytes to which `buffer' points. */
size_t allocated;
/* Number of bytes actually used in `buffer'. */
size_t used;
/* Syntax setting with which the pattern was compiled. */
reg_syntax_t syntax;
/* Pointer to a fastmap, if any, otherwise zero. re_search uses
the fastmap, if there is one, to skip over impossible
starting points for matches. */
char *fastmap;
/* Either a translate table to apply to all characters before
comparing them, or zero for no translation. The translation
is applied to a pattern when it is compiled and to a string
when it is matched. */
RE_TRANSLATE_TYPE translate;
/* Number of subexpressions found by the compiler. */
size_t re_nsub;
/* Zero if this pattern cannot match the empty string, one else.
Well, in truth it's used only in `re_search_2', to see
whether or not we should use the fastmap, so we don't set
this absolutely perfectly; see `re_compile_fastmap'. */
unsigned can_be_null : 1;
/* If REGS_UNALLOCATED, allocate space in the `regs' structure
for `max (RE_NREGS, re_nsub + 1)' groups.
If REGS_REALLOCATE, reallocate space if necessary.
If REGS_FIXED, use what's there. */
#define REGS_UNALLOCATED 0
#define REGS_REALLOCATE 1
#define REGS_FIXED 2
unsigned regs_allocated : 2;
/* Set to zero when `regex_compile' compiles a pattern; set to one
by `re_compile_fastmap' if it updates the fastmap. */
unsigned fastmap_accurate : 1;
/* If set, `re_match_2' does not return information about
subexpressions. */
unsigned no_sub : 1;
/* If set, a beginning-of-line anchor doesn't match at the
beginning of the string. */
unsigned not_bol : 1;
/* Similarly for an end-of-line anchor. */
unsigned not_eol : 1;
#ifdef emacs
/* If true, multi-byte form in the `buffer' should be recognized as a
multibyte character. */
unsigned multibyte : 1;
#endif
/* [[[end pattern_buffer]]] */
};
typedef struct re_pattern_buffer regex_t;
/* Type for byte offsets within the string. POSIX mandates this. */
typedef int regoff_t;
/* This is the structure we store register match data in. See
regex.texinfo for a full description of what registers match. */
struct re_registers
{
unsigned num_regs;
regoff_t *start;
regoff_t *end;
};
/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
`re_match_2' returns information about at least this many registers
the first time a `regs' structure is passed. */
#ifndef RE_NREGS
# define RE_NREGS 30
#endif
/* POSIX specification for registers. Aside from the different names than
`re_registers', POSIX uses an array of structures, instead of a
structure of arrays. */
typedef struct
{
regoff_t rm_so; /* Byte offset from string's start to substring's start. */
regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
} regmatch_t;
/* Declarations for routines. */
/* To avoid duplicating every routine declaration -- once with a
prototype (if we are ANSI), and once without (if we aren't) -- we
use the following macro to declare argument types. This
unfortunately clutters up the declarations a bit, but I think it's
worth it. */
#if defined __STDC__ || defined PROTOTYPES
# define _RE_ARGS(args) args
#else /* not __STDC__ || PROTOTYPES */
# define _RE_ARGS(args) ()
#endif /* not __STDC__ || PROTOTYPES */
/* Sets the current default syntax to SYNTAX, and return the old syntax.
You can also simply assign to the `re_syntax_options' variable. */
extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
/* Compile the regular expression PATTERN, with length LENGTH
and syntax given by the global `re_syntax_options', into the buffer
BUFFER. Return NULL if successful, and an error string if not. */
extern const char *re_compile_pattern
_RE_ARGS ((const char *pattern, size_t length,
struct re_pattern_buffer *buffer));
/* Compile a fastmap for the compiled pattern in BUFFER; used to
accelerate searches. Return 0 if successful and -2 if was an
internal error. */
extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
/* Search in the string STRING (with length LENGTH) for the pattern
compiled into BUFFER. Start searching at position START, for RANGE
characters. Return the starting position of the match, -1 for no
match, or -2 for an internal error. Also return register
information in REGS (if REGS and BUFFER->no_sub are nonzero). */
extern int re_search
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
int length, int start, int range, struct re_registers *regs));
/* Like `re_search', but search in the concatenation of STRING1 and
STRING2. Also, stop searching at index START + STOP. */
extern int re_search_2
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
int length1, const char *string2, int length2,
int start, int range, struct re_registers *regs, int stop));
/* Like `re_search', but return how many characters in STRING the regexp
in BUFFER matched, starting at position START. */
extern int re_match
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
int length, int start, struct re_registers *regs));
/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
extern int re_match_2
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
int length1, const char *string2, int length2,
int start, struct re_registers *regs, int stop));
/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
ENDS. Subsequent matches using BUFFER and REGS will use this memory
for recording register information. STARTS and ENDS must be
allocated with malloc, and must each be at least `NUM_REGS * sizeof
(regoff_t)' bytes long.
If NUM_REGS == 0, then subsequent matches should allocate their own
register data.
Unless this function is called, the first search or match using
PATTERN_BUFFER will allocate its own register data, without
freeing the old data. */
extern void re_set_registers
_RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
unsigned num_regs, regoff_t *starts, regoff_t *ends));
#if defined _REGEX_RE_COMP || defined _LIBC
# ifndef _CRAY
/* 4.2 bsd compatibility. */
extern char *re_comp _RE_ARGS ((const char *));
extern int re_exec _RE_ARGS ((const char *));
# endif
#endif
/* GCC 2.95 and later have "__restrict"; C99 compilers have
"restrict", and "configure" may have defined "restrict". */
#ifndef __restrict
# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
# if defined restrict || 199901L <= __STDC_VERSION__
# define __restrict restrict
# else
# define __restrict
# endif
# endif
#endif
/* For now conditionally define __restrict_arr to expand to nothing.
Ideally we would have a test for the compiler which allows defining
it to restrict. */
#ifndef __restrict_arr
# define __restrict_arr
#endif
/* POSIX compatibility. */
extern int regcomp _RE_ARGS ((regex_t *__restrict __preg,
const char *__restrict __pattern,
int __cflags));
extern int regexec _RE_ARGS ((const regex_t *__restrict __preg,
const char *__restrict __string, size_t __nmatch,
regmatch_t __pmatch[__restrict_arr],
int __eflags));
extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg,
char *__errbuf, size_t __errbuf_size));
extern void regfree _RE_ARGS ((regex_t *__preg));
#ifdef __cplusplus
}
#endif /* C++ */
#endif /* regex.h */
/*
Local variables:
make-backup-files: t
version-control: t
trim-versions-without-asking: nil
End:
*/
/* arch-tag: bda6e3ec-3c02-4237-a55a-01ad2e120083
(do not change this comment) */

View file

@ -284,6 +284,52 @@ tgetst1 (ptr, area)
}
*r++ = c;
}
/* Sometimes entries have "%pN" which means use parameter N in the
next %-substitution. If all such N are continuous in the range
[1,9] we can remove each "%pN" because they are redundant, thus
reducing bandwidth requirements. True, Emacs is well beyond the
days of 150baud teletypes, but some of its users aren't much so.
This pass could probably be integrated into the one above but
abbreviation expansion makes that effort a little more hairy than
its worth; this is cleaner. */
{
register int last_p_param = 0;
int remove_p_params = 1;
struct { char *beg; int len; } cut[11];
for (cut[0].beg = p = ret; p < r - 3; p++)
{
if (!remove_p_params)
break;
if (*p == '%' && *(p + 1) == 'p')
{
if (*(p + 2) - '0' == 1 + last_p_param)
{
cut[last_p_param].len = p - cut[last_p_param].beg;
last_p_param++;
p += 3;
cut[last_p_param].beg = p;
}
else /* not continuous: bail */
remove_p_params = 0;
if (last_p_param > 10) /* too many: bail */
remove_p_params = 0;
}
}
if (remove_p_params && last_p_param)
{
register int i;
char *wp;
cut[last_p_param].len = r - cut[last_p_param].beg;
for (i = 0, wp = ret; i <= last_p_param; wp += cut[i++].len)
bcopy (cut[i].beg, wp, cut[i].len);
r = wp;
}
}
*r = '\0';
/* Update *AREA. */
if (area)

View file

@ -6937,11 +6937,6 @@ DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
static struct image_type *image_types;
/* The symbol `image' which is the car of the lists used to represent
images in Lisp. */
extern Lisp_Object Qimage;
/* The symbol `xbm' which is used as the type symbol for XBM images. */
Lisp_Object Qxbm;
@ -7021,7 +7016,7 @@ valid_image_p (object)
{
int valid_p = 0;
if (CONSP (object) && EQ (XCAR (object), Qimage))
if (IMAGEP (object))
{
Lisp_Object tem;
@ -7123,7 +7118,7 @@ parse_image_spec (spec, keywords, nkeywords, type)
int i;
Lisp_Object plist;
if (!CONSP (spec) || !EQ (XCAR (spec), Qimage))
if (!IMAGEP (spec))
return 0;
plist = XCDR (spec);

View file

@ -153,7 +153,6 @@ Lisp_Object Vmenu_updating_frame;
Lisp_Object Qdebug_on_next_call;
extern Lisp_Object Qmenu_bar;
extern Lisp_Object Qmouse_click, Qevent_kind;
extern Lisp_Object QCtoggle, QCradio;

View file

@ -221,8 +221,6 @@ static int input_signal_count;
extern Lisp_Object Vcommand_line_args, Vsystem_name;
extern Lisp_Object Qface, Qmouse_face;
#ifndef USE_CRT_DLL
extern int errno;
#endif

View file

@ -243,6 +243,9 @@ Lisp_Object Qbuffer_position, Qposition, Qobject;
/* Cursor shapes */
Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
/* Pointer shapes */
Lisp_Object Qarrow, Qhand, Qtext;
Lisp_Object Qrisky_local_variable;
/* Holds the list (error). */
@ -291,7 +294,7 @@ int inhibit_eval_during_redisplay;
/* Names of text properties relevant for redisplay. */
Lisp_Object Qdisplay, Qrelative_width, Qalign_to;
Lisp_Object Qdisplay;
extern Lisp_Object Qface, Qinvisible, Qwidth;
/* Symbols used in text property values. */
@ -299,7 +302,7 @@ extern Lisp_Object Qface, Qinvisible, Qwidth;
Lisp_Object Vdisplay_pixels_per_inch;
Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
Lisp_Object Qmargin;
Lisp_Object Qmargin, Qpointer;
extern Lisp_Object Qheight;
extern Lisp_Object QCwidth, QCheight, QCascent;
extern Lisp_Object Qscroll_bar;
@ -312,7 +315,7 @@ Lisp_Object Vshow_trailing_whitespace;
i.e. in blank areas after eol and eob. This used to be
the default in 21.3. */
Lisp_Object Vshow_text_cursor_in_void;
Lisp_Object Vvoid_text_area_pointer;
/* Name of the face used to highlight trailing whitespace. */
@ -323,6 +326,10 @@ Lisp_Object Qtrailing_whitespace;
Lisp_Object Qimage;
/* The image map types. */
Lisp_Object QCmap, QCpointer;
Lisp_Object Qrect, Qcircle, Qpoly;
/* Non-zero means print newline to stdout before next mini-buffer
message. */
@ -1579,11 +1586,10 @@ glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
date. */
static struct glyph *
x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
struct window *w;
int x, y;
int *hpos, *vpos, *area;
int buffer_only_p;
int *hpos, *vpos, *dx, *dy, *area;
{
struct glyph *glyph, *end;
struct glyph_row *row = NULL;
@ -1634,23 +1640,22 @@ x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
/* Find glyph containing X. */
glyph = row->glyphs[*area];
end = glyph + row->used[*area];
while (glyph < end)
x -= x0;
while (glyph < end && x >= glyph->pixel_width)
{
if (x < x0 + glyph->pixel_width)
{
if (w->pseudo_window_p)
break;
else if (!buffer_only_p || BUFFERP (glyph->object))
break;
}
x0 += glyph->pixel_width;
x -= glyph->pixel_width;
++glyph;
}
if (glyph == end)
return NULL;
if (dx)
{
*dx = x;
*dy = y - (row->y + row->ascent - glyph->ascent);
}
*hpos = glyph - row->glyphs[*area];
return glyph;
}
@ -1738,20 +1743,28 @@ get_glyph_string_clip_rect (s, nr)
r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
#ifdef HAVE_NTGUI
/* ++KFS: From W32 port, but it looks ok for all platforms to me. */
/* If drawing the cursor, don't let glyph draw outside its
advertised boundaries. Cleartype does this under some circumstances. */
if (s->hl == DRAW_CURSOR)
{
struct glyph *glyph = s->first_glyph;
int height;
if (s->x > r.x)
{
r.width -= s->x - r.x;
r.x = s->x;
}
r.width = min (r.width, s->first_glyph->pixel_width);
r.width = min (r.width, glyph->pixel_width);
/* Don't draw cursor glyph taller than our actual glyph. */
height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
if (height < r.height)
{
r.y = s->ybase + glyph->descent - height;
r.height = height;
}
}
#endif
#ifdef CONVERT_FROM_XRECT
CONVERT_FROM_XRECT (r, *nr);
@ -8276,7 +8289,7 @@ build_desired_tool_bar_string (f)
int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
int hmargin, vmargin, relief, idx, end;
extern Lisp_Object QCrelief, QCmargin, QCconversion, Qimage;
extern Lisp_Object QCrelief, QCmargin, QCconversion;
/* If image is a vector, choose the image according to the
button state. */
@ -8693,7 +8706,7 @@ get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
int area;
/* Find the glyph under X/Y. */
*glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
*glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
if (*glyph == NULL)
return -1;
@ -17682,6 +17695,8 @@ append_glyph (it)
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 = CHAR_GLYPH;
glyph->multibyte_p = it->multibyte_p;
@ -17716,6 +17731,8 @@ append_composite_glyph (it)
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 = COMPOSITE_GLYPH;
glyph->multibyte_p = it->multibyte_p;
@ -17764,6 +17781,7 @@ produce_image_glyph (it)
{
struct image *img;
struct face *face;
int face_ascent, glyph_ascent;
xassert (it->what == IT_IMAGE);
@ -17775,10 +17793,15 @@ produce_image_glyph (it)
PREPARE_FACE_FOR_DISPLAY (it->f, face);
prepare_image_for_display (it->f, img);
it->ascent = it->phys_ascent = image_ascent (img, face);
it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face);
it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
it->pixel_width = img->width + 2 * img->hmargin;
/* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
if (face_ascent > it->ascent)
it->ascent = it->phys_ascent = face_ascent;
it->nglyphs = 1;
if (face->box != FACE_NO_BOX)
@ -17808,6 +17831,8 @@ produce_image_glyph (it)
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
glyph->pixel_width = it->pixel_width;
glyph->ascent = glyph_ascent;
glyph->descent = it->descent;
glyph->voffset = it->voffset;
glyph->type = IMAGE_GLYPH;
glyph->multibyte_p = it->multibyte_p;
@ -17847,6 +17872,8 @@ append_stretch_glyph (it, object, width, height, ascent)
glyph->charpos = CHARPOS (it->position);
glyph->object = object;
glyph->pixel_width = width;
glyph->ascent = ascent;
glyph->descent = height - ascent;
glyph->voffset = it->voffset;
glyph->type = STRETCH_GLYPH;
glyph->multibyte_p = it->multibyte_p;
@ -19942,6 +19969,189 @@ fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
}
/* See if position X, Y is within a hot-spot of an image. */
static int
on_hot_spot_p (hot_spot, x, y)
Lisp_Object hot_spot;
int x, y;
{
if (!CONSP (hot_spot))
return 0;
if (EQ (XCAR (hot_spot), Qrect))
{
/* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
Lisp_Object rect = XCDR (hot_spot);
Lisp_Object tem;
if (!CONSP (rect))
return 0;
if (!CONSP (XCAR (rect)))
return 0;
if (!CONSP (XCDR (rect)))
return 0;
if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
return 0;
if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
return 0;
if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
return 0;
if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
return 0;
return 1;
}
else if (EQ (XCAR (hot_spot), Qcircle))
{
/* CDR is (Center . Radius) = ((x0 . y0) . r) */
Lisp_Object circ = XCDR (hot_spot);
Lisp_Object lr, lx0, ly0;
if (CONSP (circ)
&& CONSP (XCAR (circ))
&& (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
&& (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
&& (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
{
double r = XFLOATINT (lr);
double dx = XINT (lx0) - x;
double dy = XINT (ly0) - y;
return (dx * dx + dy * dy <= r * r);
}
}
else if (EQ (XCAR (hot_spot), Qpoly))
{
/* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
if (VECTORP (XCDR (hot_spot)))
{
struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
Lisp_Object *poly = v->contents;
int n = v->size;
int i;
int inside = 0;
Lisp_Object lx, ly;
int x0, y0;
/* Need an even number of coordinates, and at least 3 edges. */
if (n < 6 || n & 1)
return 0;
/* Count edge segments intersecting line from (X,Y) to (X,infinity).
If count is odd, we are inside polygon. Pixels on edges
may or may not be included depending on actual geometry of the
polygon. */
if ((lx = poly[n-2], !INTEGERP (lx))
|| (ly = poly[n-1], !INTEGERP (lx)))
return 0;
x0 = XINT (lx), y0 = XINT (ly);
for (i = 0; i < n; i += 2)
{
int x1 = x0, y1 = y0;
if ((lx = poly[i], !INTEGERP (lx))
|| (ly = poly[i+1], !INTEGERP (ly)))
return 0;
x0 = XINT (lx), y0 = XINT (ly);
/* Does this segment cross the X line? */
if (x0 >= x)
{
if (x1 >= x)
continue;
}
else if (x1 < x)
continue;
if (y > y0 && y > y1)
continue;
if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
inside = !inside;
}
return inside;
}
}
else
return 0;
}
Lisp_Object
find_hot_spot (map, x, y)
Lisp_Object map;
int x, y;
{
while (CONSP (map))
{
if (CONSP (XCAR (map))
&& on_hot_spot_p (XCAR (XCAR (map)), x, y))
return XCAR (map);
map = XCDR (map);
}
return Qnil;
}
DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
3, 3, 0,
doc: /* Lookup in image map MAP coordinates X and Y.
An image map is an alist where each element has the format (AREA ID PLIST).
An AREA is specified as either a rectangle, a circle, or a polygon:
A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
pixel coordinates of the upper left and bottom right corners.
A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
and the radius of the circle; r may be a float or integer.
A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
vector describes one corner in the polygon.
Returns the alist element for the first matching AREA in MAP. */)
(map, x, y)
Lisp_Object map;
Lisp_Object x, y;
{
int ix, iy;
if (NILP (map))
return Qnil;
if (!INTEGERP (x))
wrong_type_argument (Qintegerp, x);
if (!INTEGERP (y))
wrong_type_argument (Qintegerp, y);
return find_hot_spot (map, XINT (x), XINT (y));
}
/* Display frame CURSOR, optionally using shape defined by POINTER. */
static void
define_frame_cursor1 (f, cursor, pointer)
struct frame *f;
Cursor cursor;
Lisp_Object pointer;
{
if (!NILP (pointer))
{
if (EQ (pointer, Qarrow))
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
else if (EQ (pointer, Qhand))
cursor = FRAME_X_OUTPUT (f)->hand_cursor;
else if (EQ (pointer, Qtext))
cursor = FRAME_X_OUTPUT (f)->text_cursor;
else if (EQ (pointer, intern ("hdrag")))
cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
#ifdef HAVE_X_WINDOWS
else if (EQ (pointer, intern ("vdrag")))
cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
#endif
else if (EQ (pointer, intern ("hourglass")))
cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
else if (EQ (pointer, Qmodeline))
cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
else
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
}
#ifndef HAVE_CARBON
if (cursor != No_Cursor)
#else
if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
#endif
rif->define_frame_cursor (f, cursor);
}
/* Take proper action when mouse has moved to the mode or header line
or marginal area AREA of window W, x-position X and y-position Y.
X is relative to the start of the text display area of W, so the
@ -19957,18 +20167,24 @@ note_mode_line_or_margin_highlight (w, x, y, area)
struct frame *f = XFRAME (w->frame);
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
int charpos;
Lisp_Object string, help, map, pos;
Lisp_Object pointer = Qnil;
int charpos, dx, dy;
Lisp_Object string;
Lisp_Object pos, help, image;
if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
string = mode_line_string (w, &x, &y, 0, 0, area, &charpos);
else
string = marginal_area_string (w, &x, &y, 0, 0, area, &charpos);
{
x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
string = marginal_area_string (w, &x, &y, &dx, &dy, area, &charpos);
}
help = Qnil;
if (STRINGP (string))
{
pos = make_number (charpos);
/* If we're on a string with `help-echo' text property, arrange
for the help to be displayed. This is done by setting the
global variable help_echo_string to the help string. */
@ -19981,9 +20197,13 @@ note_mode_line_or_margin_highlight (w, x, y, area)
help_echo_pos = charpos;
}
if (NILP (pointer))
pointer = Fget_text_property (pos, Qpointer, string);
/* Change the mouse pointer according to what is under X/Y. */
if (area == ON_MODE_LINE)
if (NILP (pointer) && area == ON_MODE_LINE)
{
Lisp_Object map;
map = Fget_text_property (pos, Qlocal_map, string);
if (!KEYMAPP (map))
map = Fget_text_property (pos, Qkeymap, string);
@ -19991,8 +20211,42 @@ note_mode_line_or_margin_highlight (w, x, y, area)
cursor = dpyinfo->vertical_scroll_bar_cursor;
}
}
else if (IMAGEP (string))
{
Lisp_Object image_map, hotspot;
if ((image_map = Fplist_get (XCDR (string), QCmap),
!NILP (image_map))
&& (hotspot = find_hot_spot (image_map, dx, dy),
CONSP (hotspot))
&& (hotspot = XCDR (hotspot), CONSP (hotspot)))
{
Lisp_Object area_id, plist;
rif->define_frame_cursor (f, cursor);
area_id = XCAR (hotspot);
/* Could check AREA_ID to see if we enter/leave this hot-spot.
If so, we could look for mouse-enter, mouse-leave
properties in PLIST (and do something...). */
if ((plist = XCDR (hotspot), CONSP (plist)))
{
pointer = Fplist_get (plist, Qpointer);
if (NILP (pointer))
pointer = Qhand;
help = Fplist_get (plist, Qhelp_echo);
if (!NILP (help))
{
help_echo_string = help;
/* Is this correct? ++kfs */
XSETWINDOW (help_echo_window, w);
help_echo_object = w->buffer;
help_echo_pos = charpos;
}
}
if (NILP (pointer))
pointer = Fplist_get (XCDR (string), QCpointer);
}
}
define_frame_cursor1 (f, cursor, pointer);
}
@ -20012,6 +20266,7 @@ note_mouse_highlight (f, x, y)
Lisp_Object window;
struct window *w;
Cursor cursor = No_Cursor;
Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
struct buffer *b;
/* When a menu is active, don't highlight because this looks odd. */
@ -20049,7 +20304,6 @@ note_mouse_highlight (f, x, y)
return;
/* Reset help_echo_string. It will get recomputed below. */
/* ++KFS: X version didn't do this, but it looks harmless. */
help_echo_string = Qnil;
/* Convert to window-relative pixel coordinates. */
@ -20087,7 +20341,7 @@ note_mouse_highlight (f, x, y)
&& XFASTINT (w->last_modified) == BUF_MODIFF (b)
&& XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
{
int hpos, vpos, pos, i, area;
int hpos, vpos, pos, i, dx, dy, area;
struct glyph *glyph;
Lisp_Object object;
Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
@ -20097,7 +20351,45 @@ note_mouse_highlight (f, x, y)
int obegv, ozv, same_region;
/* Find the glyph under X/Y. */
glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
/* Look for :pointer property on image. */
if (glyph != NULL && glyph->type == IMAGE_GLYPH)
{
struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
if (img != NULL && IMAGEP (img->spec))
{
Lisp_Object image_map, hotspot;
if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
!NILP (image_map))
&& (hotspot = find_hot_spot (image_map, dx, dy),
CONSP (hotspot))
&& (hotspot = XCDR (hotspot), CONSP (hotspot)))
{
Lisp_Object area_id, plist;
area_id = XCAR (hotspot);
/* Could check AREA_ID to see if we enter/leave this hot-spot.
If so, we could look for mouse-enter, mouse-leave
properties in PLIST (and do something...). */
if ((plist = XCDR (hotspot), CONSP (plist)))
{
pointer = Fplist_get (plist, Qpointer);
if (NILP (pointer))
pointer = Qhand;
help_echo_string = Fplist_get (plist, Qhelp_echo);
if (!NILP (help_echo_string))
{
help_echo_window = window;
help_echo_object = glyph->object;
help_echo_pos = glyph->charpos;
}
}
}
if (NILP (pointer))
pointer = Fplist_get (XCDR (img->spec), QCpointer);
}
}
/* Clear mouse face if X/Y not over text. */
if (glyph == NULL
@ -20106,8 +20398,13 @@ note_mouse_highlight (f, x, y)
{
if (clear_mouse_face (dpyinfo))
cursor = No_Cursor;
if (NILP (Vshow_text_cursor_in_void))
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
if (NILP (pointer))
{
if (area != TEXT_AREA)
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
else
pointer = Vvoid_text_area_pointer;
}
goto set_cursor;
}
@ -20120,9 +20417,6 @@ note_mouse_highlight (f, x, y)
if (BUFFERP (object) && pos > BUF_Z (b))
goto set_cursor;
if (glyph->type == IMAGE_GLYPH)
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
/* Make the window's buffer temporarily current for
overlays_at and compute_char_face. */
obuf = current_buffer;
@ -20366,7 +20660,7 @@ note_mouse_highlight (f, x, y)
check_help_echo:
/* Look for a `help-echo' property. */
{
if (NILP (help_echo_string)) {
Lisp_Object help, overlay;
/* Check overlays first. */
@ -20432,6 +20726,46 @@ note_mouse_highlight (f, x, y)
}
}
/* Look for a `pointer' property. */
if (NILP (pointer))
{
/* Check overlays first. */
for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
pointer = Foverlay_get (overlay_vec[i], Qpointer);
if (NILP (pointer))
{
Lisp_Object object = glyph->object;
int charpos = glyph->charpos;
/* Try text properties. */
if (STRINGP (object)
&& charpos >= 0
&& charpos < SCHARS (object))
{
pointer = Fget_text_property (make_number (charpos),
Qpointer, object);
if (NILP (pointer))
{
/* If the string itself doesn't specify a pointer,
see if the buffer text ``under'' it does. */
struct glyph_row *r
= MATRIX_ROW (w->current_matrix, vpos);
int start = MATRIX_ROW_START_CHARPOS (r);
int pos = string_buffer_position (w, object, start);
if (pos > 0)
pointer = Fget_char_property (make_number (pos),
Qpointer, w->buffer);
}
}
else if (BUFFERP (object)
&& charpos >= BEGV
&& charpos < ZV)
pointer = Fget_text_property (make_number (charpos),
Qpointer, object);
}
}
BEGV = obegv;
ZV = ozv;
current_buffer = obuf;
@ -20439,12 +20773,7 @@ note_mouse_highlight (f, x, y)
set_cursor:
#ifndef HAVE_CARBON
if (cursor != No_Cursor)
#else
if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
#endif
rif->define_frame_cursor (f, cursor);
define_frame_cursor1 (f, cursor, pointer);
}
@ -21040,6 +21369,7 @@ syms_of_xdisp ()
#endif
#ifdef HAVE_WINDOW_SYSTEM
defsubr (&Stool_bar_lines_needed);
defsubr (&Slookup_image_map);
#endif
defsubr (&Sformat_mode_line);
@ -21073,16 +21403,14 @@ syms_of_xdisp ()
staticpro (&Qspace);
Qmargin = intern ("margin");
staticpro (&Qmargin);
Qpointer = intern ("pointer");
staticpro (&Qpointer);
Qleft_margin = intern ("left-margin");
staticpro (&Qleft_margin);
Qright_margin = intern ("right-margin");
staticpro (&Qright_margin);
Qalign_to = intern ("align-to");
staticpro (&Qalign_to);
QCalign_to = intern (":align-to");
staticpro (&QCalign_to);
Qrelative_width = intern ("relative-width");
staticpro (&Qrelative_width);
QCrelative_width = intern (":relative-width");
staticpro (&QCrelative_width);
QCrelative_height = intern (":relative-height");
@ -21101,6 +21429,16 @@ syms_of_xdisp ()
staticpro (&Qtrailing_whitespace);
Qimage = intern ("image");
staticpro (&Qimage);
QCmap = intern (":map");
staticpro (&QCmap);
QCpointer = intern (":pointer");
staticpro (&QCpointer);
Qrect = intern ("rect");
staticpro (&Qrect);
Qcircle = intern ("circle");
staticpro (&Qcircle);
Qpoly = intern ("poly");
staticpro (&Qpoly);
Qmessage_truncate_lines = intern ("message-truncate-lines");
staticpro (&Qmessage_truncate_lines);
Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
@ -21125,6 +21463,12 @@ syms_of_xdisp ()
staticpro (&Qbox);
Qhollow = intern ("hollow");
staticpro (&Qhollow);
Qhand = intern ("hand");
staticpro (&Qhand);
Qarrow = intern ("arrow");
staticpro (&Qarrow);
Qtext = intern ("text");
staticpro (&Qtext);
Qrisky_local_variable = intern ("risky-local-variable");
staticpro (&Qrisky_local_variable);
Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
@ -21178,10 +21522,11 @@ wide as that tab on the display. */);
The face used for trailing whitespace is `trailing-whitespace'. */);
Vshow_trailing_whitespace = Qnil;
DEFVAR_LISP ("show-text-cursor-in-void", &Vshow_text_cursor_in_void,
doc: /* Non-nil means show the text cursor in void text areas.
The default is to show the non-text (typically arrow) cursor. */);
Vshow_text_cursor_in_void = Qnil;
DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
doc: /* The pointer shape to show in void text areas.
Nil means to show the text pointer. Other options are `arrow', `text',
`hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
Vvoid_text_area_pointer = Qarrow;
DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
doc: /* Non-nil means don't actually do any redisplay.

View file

@ -5579,12 +5579,19 @@ cache_face (c, face, hash)
face->id = i;
/* Maybe enlarge C->faces_by_id. */
if (i == c->used && c->used == c->size)
if (i == c->used)
{
int new_size = 2 * c->size;
int sz = new_size * sizeof *c->faces_by_id;
c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
c->size = new_size;
if (c->used == c->size)
{
int new_size, sz;
new_size = min (2 * c->size, MAX_FACE_ID);
if (new_size == c->size)
abort (); /* Alternatives? ++kfs */
sz = new_size * sizeof *c->faces_by_id;
c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
c->size = new_size;
}
c->used++;
}
#if GLYPH_DEBUG
@ -5603,8 +5610,6 @@ cache_face (c, face, hash)
#endif /* GLYPH_DEBUG */
c->faces_by_id[i] = face;
if (i == c->used)
++c->used;
}

View file

@ -1302,7 +1302,6 @@ x_set_mouse_color (f, arg, oldval)
hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
x_check_errors (dpy, "bad hourglass pointer cursor: %s");
x_check_errors (dpy, "bad nontext pointer cursor: %s");
if (!NILP (Vx_mode_pointer_shape))
{
CHECK_NUMBER (Vx_mode_pointer_shape);
@ -4418,11 +4417,6 @@ the excessive values are ignored. */)
static struct image_type *image_types;
/* The symbol `image' which is the car of the lists used to represent
images in Lisp. */
extern Lisp_Object Qimage;
/* The symbol `xbm' which is used as the type symbol for XBM images. */
Lisp_Object Qxbm;
@ -4502,7 +4496,7 @@ valid_image_p (object)
{
int valid_p = 0;
if (CONSP (object) && EQ (XCAR (object), Qimage))
if (IMAGEP (object))
{
Lisp_Object tem;
@ -4604,7 +4598,7 @@ parse_image_spec (spec, keywords, nkeywords, type)
int i;
Lisp_Object plist;
if (!CONSP (spec) || !EQ (XCAR (spec), Qimage))
if (!IMAGEP (spec))
return 0;
plist = XCDR (spec);

View file

@ -99,7 +99,6 @@ Lisp_Object Vmenu_updating_frame;
Lisp_Object Qdebug_on_next_call;
extern Lisp_Object Qmenu_bar;
extern Lisp_Object Qmouse_click, Qevent_kind;
extern Lisp_Object QCtoggle, QCradio;
@ -1304,6 +1303,7 @@ show_help_event (f, widget, help)
}
else
{
#if 0 /* This code doesn't do anything useful. ++kfs */
/* WIDGET is the popup menu. It's parent is the frame's
widget. See which frame that is. */
xt_or_gtk_widget frame_widget = XtParent (widget);
@ -1317,7 +1317,7 @@ show_help_event (f, widget, help)
FRAME_X_P (f) && f->output_data.x->widget == frame_widget))
break;
}
#endif
show_help_echo (help, Qnil, Qnil, Qnil, 1);
}
}

View file

@ -287,7 +287,7 @@ extern Lisp_Object Vcommand_line_args, Vsystem_name;
extern Lisp_Object Vx_no_window_manager;
extern Lisp_Object Qface, Qmouse_face, Qeql;
extern Lisp_Object Qeql;
extern int errno;
@ -7270,13 +7270,6 @@ x_draw_hollow_cursor (w, row)
struct glyph *cursor_glyph;
GC gc;
/* Compute frame-relative coordinates from window-relative
coordinates. */
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
y = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
+ row->ascent - w->phys_cursor_ascent);
h = row->height - 1;
/* Get the glyph the cursor is on. If we can't tell because
the current matrix is invalid or such, give up. */
cursor_glyph = get_phys_cursor_glyph (w);
@ -7293,6 +7286,19 @@ x_draw_hollow_cursor (w, row)
wd = min (FRAME_COLUMN_WIDTH (f), wd);
w->phys_cursor_width = wd;
/* Compute frame-relative coordinates from window-relative
coordinates. */
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
/* Compute the proper height and ascent of the rectangle, based
on the actual glyph. Using the full height of the row looks
bad when there are tall images on that row. */
h = max (FRAME_LINE_HEIGHT (f), cursor_glyph->ascent + cursor_glyph->descent);
if (h < row->height)
y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
h--;
/* The foreground of cursor_gc is typically the same as the normal
background color, which can cause the cursor box to be invisible. */
xgcv.foreground = f->output_data.x->cursor_pixel;