msdos/mainmake.v2 (version): Update due to change in emacs.c.
src/emacs.c <emacs_version>: Add a comment regarding msdos/mainmake.v2's
dependency on the syntax of this declaration.
* Makefile.in (install-arch-indep): Delete any old info .gz files first.
+2010-06-12 Joakim Verona <joakim@verona.se>
+
+ * image.c: Add support for ImageMagick. When HAVE_IMAGEMAGICK is
+ defined:
+ (imagemagick_image_p): New function to test for ImageMagic img.
+ (imagemagick_load): New function to load ImageMagick img.
+ (imagemagick_load_image): New function, helper for imagemagick_load
+ (imagemagick-types): New function.
+ (Qimagemagick): New Lisp_object.
+ (imagemagick-render-type): New var, decides which renderer to use
+ * image.el:
+ (imagemagick-types-inhibit): New var.
+ (imagemagick-register-types): New function.
+ * config.in, Makefile.in, configure.in
+
2010-06-11 Glenn Morris <rgm@gnu.org>
* configure.in (--without-compress-info): New option.
--- /dev/null
+* README for the ImageMagick Emacs branch
+
+This is the imagemagick branch of Emacs. Imagemagick can now be used
+to load many new image formats, and also do useful transforms like
+scaling and rotation.
+
+This file will attempt to contain draft NEWS, Changelog and manual
+entries for the new functionality.
+
+You might need to regenerate the configure scripts:
+aclocal
+automake
+autoheader
+autoconf
+./configure --with-imagemagick
+
+
+* TODO image-type-header-regexps priorities the jpeg loader over the
+imagemagick one. This is not wrong, but how should a user go about
+prefering the imagemagick loader? The user might like zooming etc in
+jpegs.
+
+try (setq image-type-header-regexps nil) for a quick hack to prefer
+imagemagick over the jpg loader.
+
+* TODO For some reason its unbearably slow to look at a page in a large
+ image bundle using the :index feature. The imagemagick "display"
+ command is also a bit slow, but nowhere near as slow as the emacs
+ code. It seems imagemagick tries to unpack every page when loading
+ the bundle. This feature is not the primary usecase for the
+ imagemagick patch though.
+
+ ImageMagick 6.6.2-9 introduced a bugfix for single page djvu load.
+ It is now way faster to use the :index feature, but its still not
+ very fast.
+
+** DONE optimize number of pages calculation for bundles as suggested by
+ imagemagick forum: "set the density to something low like 2 and use
+ MagickPingImage()"
+
+** TODO try to cache the num pages calculation. it can take a while to
+ calculate the number of pages, and if you need to do it for each
+ page view, page-flipping becomes uselessly slow.
+
+* TODO integrate with image-dired
+
+* TODO integrate with docview.
+
+* TODO integrate with image-mode
+Some work has been done, M-x image-transform-fit-to-height will fit
+the image to the height of the Emacs window for instance.
+
+* TODO look for optimizations for handling images with low depth
+Currently the code seems to default to 24 bit RGB which is costly for
+images with lower bit depth.
+
+* TODO complete documentation drafts below
+
+* DONE fix inconsistencys with spelling of imagemagick in the src
+* DONE report number of images in image bundle types somehow
+Works like for "gif" support. Thanks to Juri Linkov.
+* DONE probably add pdf to inhibited types
+* DONE inhibit types is defconst should probably be defcustom
+* TODO decide what to do with some uncommitted imagemagick support
+ functions for image size etc.
+* TODO Test with more systems
+Tested on Fedora 12, Fedora 14 so far, and the libmagick that ships with it.
+Ubuntu 8.04 was also tested, but it seems it ships a broken
+ImageMagick.
+
+I also tried using an imagemagick compiled from their SVN, in
+parallell with the one packaged by Fedora, it worked well.
+
+* DONE Also need some way to handle render methods that only work on newer ImageMagicks
+Is handled by configure now
+
+* Some nits from Stefan Monnier
+I just took a quick look at the code and I see the following nits to fix:
+
+** DONE obviously a merge will have to come with a good ChangeLog.
+** DONE also the merge will need to come with documentation. Maybe not in the
+ Texinfo form yet, but at least in the etc/NEWS with enough info that
+ describes the `scale' and other such arguments that someone can start
+ using them.
+** DONE the README talks about naming inconsistencies, I think these should be
+ fixed before a first commit (should be straightforward).
+
+** DONE the "let" in image.el should not be followed by a line break and the while
+ should be replaced by a dolist.
+
+** DONE the prototype of imagemagick_load_image has some odd indentation in ([[2010.06.14]])
+ its args, not sure what happened.
+** DONE a few lines in the C code break the 80columns limit.
+** DONE please use ANSI style function declarations rather than K&R for new code. ([[2010.06.14]])
+** DONE you can get rid of the prototypes by reordering the code. ([[2010.06.14]])
+** DONE the docstrings in DEFUN should not be indented (they'll display ([[2010.06.14]])
+ weirdly otherwise in C-h f).
+** DONE Some "{" are at the end of a for/if rather than on their own line. ([[2010.06.14]])
+** DONE why use "*( imtypes + i)" rather than "imtypes[i]"? ([[2010.06.14]])
+** DONE some "," lack a space after them. ([[2010.06.14]])
+** DONE several "=" and "==" lack spaces around them. ([[2010.06.14]])
+
+
+* NEWS entry
+** ImageMagick support
+It is now possible to use the Imagemagick library to load many new
+image formats in Emacs.
+
+To enable, use the following configure option:
+--with-imagemagick
+
+The new function (imagemagick-types) returns a list of image file
+extensions that your installation of imagemagick supports.
+
+The function (imagemagick-register-types) will enable the imagemagick
+support for the extensions in imagemagick-types minus the types listed
+in imagemagick-types-inhibit.
+
+imagemagick-types-inhibit has the value '(C HTML HTM TXT PDF) by default.
+This means imagemagick will be used also to load jpeg files, if you
+have both jpeg and imagemagick libraries linked. Add 'JPG to
+imagemagick-types-inhibit if you do not want this.
+
+imagemagick-render-type is a new variable which can be set to choose
+between screen render methods.
+
+- 0 is a conservative metod which works with older ImageMagick
+ versions. It is a bit slow, but robust.
+
+- 1 utilizes a newer ImageMagick method
+
+
+Images loaded with imagemagick will support a couple of new display
+specification behaviours:
+
+- if the :width and :height keywords are specified, these values are
+used for scaling the image. If only one of :width or :height is
+specified, the other one will be calculated so as to preserve the
+aspect ratio.If both :width and :height are specified, aspect ratio
+will not be preserved.
+
+- :rotation specifies a rotation angle in degrees.
+
+- :index specifies which image inside an image bundle file format, such
+as TIFF or DJVM, to view.
+
+The image-metadata function can be used to retrieve the total number
+of images in an image bundle. This is simmilar to how GIF files work.
+
+* Manual entry
+nothing yet, but the NEWS entry could be adapted.
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.66 for emacs 24.0.50.
+# Generated by GNU Autoconf 2.65 for emacs 24.0.50.
#
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
#
#
# This configure script is free software; the Free Software Foundation
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
} # as_fn_mkdir_p
fi # as_fn_arith
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
+# script with status $?, using 1 if that was 0.
as_fn_error ()
{
- as_status=$1; test $as_status -eq 0 && as_status=1
- if test "$4"; then
- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
fi
- $as_echo "$as_me: error: $2" >&2
+ $as_echo "$as_me: error: $1" >&2
as_fn_exit $as_status
} # as_fn_error
exec 6>&1
# Name of the host.
-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
GTK_OBJ
GTK_LIBS
GTK_CFLAGS
+IMAGEMAGICK_LIBS
+IMAGEMAGICK_CFLAGS
RSVG_LIBS
RSVG_CFLAGS
VMLIMIT_OBJ
with_gif
with_png
with_rsvg
+with_imagemagick
with_xft
with_libotf
with_m17n_flt
ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: $ac_useropt"
+ as_fn_error "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: $ac_useropt"
+ as_fn_error "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: $ac_useropt"
+ as_fn_error "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: $ac_useropt"
+ as_fn_error "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries=$ac_optarg ;;
- -*) as_fn_error $? "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information"
+ -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
;;
*=*)
# Reject names that are not valid shell variable names.
case $ac_envvar in #(
'' | [0-9]* | *[!_$as_cr_alnum]* )
- as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ as_fn_error "invalid variable name: \`$ac_envvar'" ;;
esac
eval $ac_envvar=\$ac_optarg
export $ac_envvar ;;
if test -n "$ac_prev"; then
ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- as_fn_error $? "missing argument to $ac_option"
+ as_fn_error "missing argument to $ac_option"
fi
if test -n "$ac_unrecognized_opts"; then
case $enable_option_checking in
no) ;;
- fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
*) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
esac
fi
[\\/$]* | ?:[\\/]* ) continue;;
NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
esac
- as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+ as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
done
# There might be people who depend on the old broken behavior: `$host'
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used" >&2
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
ac_pwd=`pwd` && test -n "$ac_pwd" &&
ac_ls_di=`ls -di .` &&
ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- as_fn_error $? "working directory cannot be determined"
+ as_fn_error "working directory cannot be determined"
test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- as_fn_error $? "pwd does not report name of working directory"
+ as_fn_error "pwd does not report name of working directory"
# Find the source files, if location was not specified.
fi
if test ! -r "$srcdir/$ac_unique_file"; then
test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+ as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
fi
ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking ...' messages
+ -q, --quiet, --silent do not print \`checking...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for \`--cache-file=config.cache'
-n, --no-create do not create output files
--without-gif don't compile with GIF image support
--without-png don't compile with PNG image support
--without-rsvg don't compile with SVG image support
+ --with-imagemagick compile with ImageMagick image support
--without-xft don't use XFT for anti aliased fonts
--without-libotf don't use libotf for OpenType font support
--without-m17n-flt don't use m17n-flt for text shaping
if $ac_init_version; then
cat <<\_ACEOF
emacs configure 24.0.50
-generated by GNU Autoconf 2.66
+generated by GNU Autoconf 2.65
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2009 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
ac_fn_c_check_header_mongrel ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if eval "test \"\${$3+set}\"" = set; then :
+ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
eval "$3=\$ac_header_compiler"
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
} # ac_fn_c_check_header_compile
-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
-# ---------------------------------------------
-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
-# accordingly.
+# ac_fn_c_check_decl LINENO SYMBOL VAR
+# ------------------------------------
+# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
ac_fn_c_check_decl ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- as_decl_name=`echo $2|sed 's/ *(.*//'`
- as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
-$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
+$as_echo_n "checking whether $2 is declared... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
int
main ()
{
-#ifndef $as_decl_name
-#ifdef __cplusplus
- (void) $as_decl_use;
-#else
- (void) $as_decl_name;
-#endif
+#ifndef $2
+ (void) $2;
#endif
;
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
$as_echo_n "checking for $2.$3... " >&6; }
-if eval "test \"\${$4+set}\"" = set; then :
+if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
running configure, to aid debugging if configure makes a mistake.
It was created by emacs $as_me 24.0.50, which was
-generated by GNU Autoconf 2.66. Invocation command line was
+generated by GNU Autoconf 2.65. Invocation command line was
$ $0 $@
{
echo
- $as_echo "## ---------------- ##
+ cat <<\_ASBOX
+## ---------------- ##
## Cache variables. ##
-## ---------------- ##"
+## ---------------- ##
+_ASBOX
echo
# The following way of writing the cache mishandles newlines in values,
(
)
echo
- $as_echo "## ----------------- ##
+ cat <<\_ASBOX
+## ----------------- ##
## Output variables. ##
-## ----------------- ##"
+## ----------------- ##
+_ASBOX
echo
for ac_var in $ac_subst_vars
do
echo
if test -n "$ac_subst_files"; then
- $as_echo "## ------------------- ##
+ cat <<\_ASBOX
+## ------------------- ##
## File substitutions. ##
-## ------------------- ##"
+## ------------------- ##
+_ASBOX
echo
for ac_var in $ac_subst_files
do
fi
if test -s confdefs.h; then
- $as_echo "## ----------- ##
+ cat <<\_ASBOX
+## ----------- ##
## confdefs.h. ##
-## ----------- ##"
+## ----------- ##
+_ASBOX
echo
cat confdefs.h
echo
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
- # We do not want a PATH search for config.site.
- case $CONFIG_SITE in #((
- -*) ac_site_file1=./$CONFIG_SITE;;
- */*) ac_site_file1=$CONFIG_SITE;;
- *) ac_site_file1=./$CONFIG_SITE;;
- esac
+ ac_site_file1=$CONFIG_SITE
elif test "x$prefix" != xNONE; then
ac_site_file1=$prefix/share/config.site
ac_site_file2=$prefix/etc/config.site
{ $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
$as_echo "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file" \
- || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
+ . "$ac_site_file"
fi
done
as_fn_append ac_header_list " stdlib.h"
as_fn_append ac_header_list " unistd.h"
as_fn_append ac_header_list " sys/param.h"
+as_fn_append ac_func_list " MagickExportImagePixels"
as_fn_append ac_header_list " sys/time.h"
as_fn_append ac_func_list " alarm"
# Check that the precious variables saved in the cache have kept the same
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+ as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
fi
## -------------------- ##
## Main body of script. ##
g | gt | gtk ) val=gtk ;;
gtk3 ) val=gtk3 ;;
* )
-as_fn_error $? "\`--with-x-toolkit=$withval' is invalid;
+as_fn_error "\`--with-x-toolkit=$withval' is invalid;
this option's value should be \`yes', \`no', \`lucid', \`athena', \`motif', \`gtk' or
\`gtk3'. \`yes' and \`gtk' are synonyms. \`athena' and \`lucid' are synonyms." "$LINENO" 5
;;
fi
+# Check whether --with-imagemagick was given.
+if test "${with_imagemagick+set}" = set; then :
+ withval=$with_imagemagick;
+else
+ with_imagemagick=no
+fi
+
+
# Check whether --with-xft was given.
if test "${with_xft+set}" = set; then :
stringfreelist) ac_gc_check_string_free_list=1 ;;
xmallocoverrun) ac_xmalloc_overrun=1 ;;
conslist) ac_gc_check_cons_list=1 ;;
- *) as_fn_error $? "unknown check category $check" "$LINENO" 5 ;;
+ *) as_fn_error "unknown check category $check" "$LINENO" 5 ;;
esac
done
IFS="$ac_save_IFS"
ac_aux_dir=
for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- if test -f "$ac_dir/install-sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f "$ac_dir/install.sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- elif test -f "$ac_dir/shtool"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/shtool install -c"
- break
- fi
+ for ac_t in install-sh install.sh shtool; do
+ if test -f "$ac_dir/$ac_t"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/$ac_t -c"
+ break 2
+ fi
+ done
done
if test -z "$ac_aux_dir"; then
- as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+ as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
fi
# These three variables are undocumented and unsupported,
# Make sure we can run config.sub.
$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
- as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+ as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
$as_echo_n "checking build system type... " >&6; }
test "x$ac_build_alias" = x &&
ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
test "x$ac_build_alias" = x &&
- as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
$as_echo "$ac_cv_build" >&6; }
case $ac_cv_build in
*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
esac
build=$ac_cv_build
ac_save_IFS=$IFS; IFS='-'
ac_cv_host=$ac_cv_build
else
ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
fi
fi
$as_echo "$ac_cv_host" >&6; }
case $ac_cv_host in
*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
esac
host=$ac_cv_host
ac_save_IFS=$IFS; IFS='-'
if test $unported = yes; then
- as_fn_error $? "Emacs hasn't been ported to \`${canonical}' systems.
+ as_fn_error "Emacs hasn't been ported to \`${canonical}' systems.
Check \`etc/MACHINES' for recognized configuration names." "$LINENO" 5
fi
test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
+as_fn_error "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details." "$LINENO" 5; }
fi
fi
fi
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
fi
ac_ext=c
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_GREP"; then
- as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_GREP=$GREP
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_EGREP"; then
- as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_EGREP=$EGREP
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
fi
ac_ext=c
if test "x${with_makeinfo}" = "xno"; then
MAKEINFO=off
elif test ! -e $srcdir/info/emacs; then
- as_fn_error $? "You do not seem to have makeinfo >= 4.6, and your
+ as_fn_error "You do not seem to have makeinfo >= 4.6, and your
source tree does not seem to have pre-built manuals in the \`info' directory.
Either install a suitable version of makeinfo, or re-run configure
with the \`--without-makeinfo' option to build without the manuals. " "$LINENO" 5
if test "x$GCC" = "xyes"; then
C_SWITCH_MACHINE="-fno-common"
else
- as_fn_error $? "What gives? Fix me if DEC Unix supports ELF now." "$LINENO" 5
+ as_fn_error "What gives? Fix me if DEC Unix supports ELF now." "$LINENO" 5
fi
else
UNEXEC_OBJ=unexalpha.o
## Some platforms don't use any of these files, so it is not
## appropriate to put this test outside the if block.
test -e $CRT_DIR/crtn.o || test -e $CRT_DIR/crt0.o || \
- as_fn_error $? "crt*.o not found in specified location." "$LINENO" 5
+ as_fn_error "crt*.o not found in specified location." "$LINENO" 5
fi
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
if test "$emacs_alsa_subdir" != yes; then
- as_fn_error $? "pkg-config found alsa, but it does not compile. See config.log for error messages." "$LINENO" 5
+ as_fn_error "pkg-config found alsa, but it does not compile. See config.log for error messages." "$LINENO" 5
fi
ALSA_CFLAGS="$ALSA_CFLAGS -DALSA_SUBDIR_INCLUDE"
fi
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
;; #(
*)
- as_fn_error $? "unknown endianness
+ as_fn_error "unknown endianness
presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
esac
$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
set x ${MAKE-make}
ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then :
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat >conftest.make <<\_ACEOF
all:
@echo '@@@%%%=$(MAKE)=@@@%%%'
_ACEOF
-# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
case `${MAKE-make} -f conftest.make 2>/dev/null` in
*@@@%%%=?*=@@@%%%*)
eval ac_cv_prog_make_${ac_make}_set=yes;;
have_x=disabled
else
case $x_includes,$x_libraries in #(
- *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #(
+ *\'*) as_fn_error "cannot use X directory names containing '" "$LINENO" 5;; #(
*,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then :
$as_echo_n "(cached) " >&6
else
@echo libdir='${LIBDIR}'
_ACEOF
if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then
- # GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+ # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
for ac_var in incroot usrlibdir libdir; do
eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`"
done
if test "x$ac_cv_header_AppKit_AppKit_h" = x""yes; then :
HAVE_NS=yes
else
- as_fn_error $? "\`--with-ns' was specified, but the include
+ as_fn_error "\`--with-ns' was specified, but the include
files are missing or cannot be compiled." "$LINENO" 5
fi
if test "$HAVE_XSERVER" = true ||
test -n "$DISPLAY" ||
test "`echo /usr/lib/libX11.*`" != "/usr/lib/libX11.*"; then
- as_fn_error $? "You seem to be running X, but no X development libraries
+ as_fn_error "You seem to be running X, but no X development libraries
were found. You should install the relevant development files for X
and for the toolkit you want, such as Gtk+, Lesstif or Motif. Also make
sure you have development files for image handling, i.e.
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
LIBS="$RSVG_LIBS $LIBS"
fi
fi
+fi
+
+HAVE_IMAGEMAGICK=no
+if test "${with_imagemagick}" != "no"; then
+ IMAGEMAGICK_MODULE="Wand"
+
+ succeeded=no
+
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
+ ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+ if test "$PKG_CONFIG" = "no" ; then
+ :
+ else
+ PKG_CONFIG_MIN_VERSION=0.9.0
+ if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $IMAGEMAGICK_MODULE" >&5
+$as_echo_n "checking for $IMAGEMAGICK_MODULE... " >&6; }
+
+ if $PKG_CONFIG --exists "$IMAGEMAGICK_MODULE" 2>&5; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ succeeded=yes
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking IMAGEMAGICK_CFLAGS" >&5
+$as_echo_n "checking IMAGEMAGICK_CFLAGS... " >&6; }
+ IMAGEMAGICK_CFLAGS=`$PKG_CONFIG --cflags "$IMAGEMAGICK_MODULE"|sed -e 's,///*,/,g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IMAGEMAGICK_CFLAGS" >&5
+$as_echo "$IMAGEMAGICK_CFLAGS" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking IMAGEMAGICK_LIBS" >&5
+$as_echo_n "checking IMAGEMAGICK_LIBS... " >&6; }
+ IMAGEMAGICK_LIBS=`$PKG_CONFIG --libs "$IMAGEMAGICK_MODULE"|sed -e 's,///*,/,g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IMAGEMAGICK_LIBS" >&5
+$as_echo "$IMAGEMAGICK_LIBS" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ IMAGEMAGICK_CFLAGS=""
+ IMAGEMAGICK_LIBS=""
+ ## If we have a custom action on failure, don't print errors, but
+ ## do set a variable so people can do so.
+ IMAGEMAGICK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$IMAGEMAGICK_MODULE"`
+
+ fi
+
+
+
+ else
+ echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+ echo "*** See http://www.freedesktop.org/software/pkgconfig"
+ fi
+ fi
+
+ if test $succeeded = yes; then
+ :
+ else
+ :
+ fi
+
+
+
+
+ if test ".${IMAGEMAGICK_CFLAGS}" != "."; then
+ HAVE_IMAGEMAGICK=yes
+
+$as_echo "#define HAVE_IMAGEMAGICK 1" >>confdefs.h
+
+ CFLAGS="$CFLAGS $IMAGEMAGICK_CFLAGS"
+ LIBS="$IMAGEMAGICK_LIBS $LIBS"
+ fi
+
+
+$as_echo "#define HAVE_MAGICKEXPORTIMAGEPIXELS 1" >>confdefs.h
+
+
+
+
+ for ac_func in $ac_func_list
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+
fi
fi
if test "$pkg_check_gtk" = "no" && test "$USE_X_TOOLKIT" != "maybe"; then
- as_fn_error $? "$GTK_PKG_ERRORS" "$LINENO" 5
+ as_fn_error "$GTK_PKG_ERRORS" "$LINENO" 5
fi
fi
fi
if test "$pkg_check_gtk" = "no" && test "$USE_X_TOOLKIT" != "maybe"; then
- as_fn_error $? "$GTK_PKG_ERRORS" "$LINENO" 5
+ as_fn_error "$GTK_PKG_ERRORS" "$LINENO" 5
fi
fi
fi
if test "${GTK_COMPILES}" != "yes"; then
if test "$USE_X_TOOLKIT" != "maybe"; then
- as_fn_error $? "Gtk+ wanted, but it does not compile, see config.log. Maybe some x11-devel files missing?" "$LINENO" 5;
+ as_fn_error "Gtk+ wanted, but it does not compile, see config.log. Maybe some x11-devel files missing?" "$LINENO" 5;
fi
else
HAVE_GTK=yes
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
USE_X_TOOLKIT=LUCID
LUCID_LIBW=-lXaw
elif test x"${USE_X_TOOLKIT}" = xLUCID; then
- as_fn_error $? "Lucid toolkit requires X11/Xaw include files" "$LINENO" 5
+ as_fn_error "Lucid toolkit requires X11/Xaw include files" "$LINENO" 5
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no; do not use toolkit by default" >&5
$as_echo "no; do not use toolkit by default" >&6; }
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
MISSING="$MISSING libtiff" && WITH_NO="$WITH_NO --with-tiff=no"
if test "X${MISSING}" != X; then
- as_fn_error $? "The following required libraries were not found:
+ as_fn_error "The following required libraries were not found:
$MISSING
Maybe some development libraries/packages are missing?
If you don't want to link with them give
for ac_func in _getb67 GETB67 getb67; do
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define CRAY_STACKSEG_END $ac_func
if test x"$ac_cv_func_alloca_works" != xyes; then
- as_fn_error $? "a system implementation of alloca is required " "$LINENO" 5
+ as_fn_error "a system implementation of alloca is required " "$LINENO" 5
fi
# fmod, logb, and frexp are found in -lm on most systems.
if test $ac_cv_prog_liblockfile = yes; then
- as_fn_error $? "Shared liblockfile found but can't link against it.
+ as_fn_error "Shared liblockfile found but can't link against it.
This probably means that movemail could lose mail.
There may be a \`development' package to install containing liblockfile." "$LINENO" 5
fi
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
- for ac_func in $ac_func_list
-do :
- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-
-
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mktime" >&5
$as_echo_n "checking for working mktime... " >&6; }
static time_t time_t_min;
/* Values we'll use to set the TZ environment variable. */
-static const char *tz_strings[] = {
- (const char *) 0, "TZ=GMT0", "TZ=JST-9",
+static char *tz_strings[] = {
+ (char *) 0, "TZ=GMT0", "TZ=JST-9",
"TZ=EST+3EDT+2,M10.1.0/00:00:00,M2.3.0/00:00:00"
};
#define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0]))
instead of "TZ=America/Vancouver" in order to detect the bug even
on systems that don't support the Olson extension, or don't have the
full zoneinfo tables installed. */
- putenv ((char*) "TZ=PST8PDT,M4.1.0,M10.5.0");
+ putenv ("TZ=PST8PDT,M4.1.0,M10.5.0");
tm.tm_year = 98;
tm.tm_mon = 3;
}
static int
-mktime_test1 (time_t now)
+mktime_test1 (now)
+ time_t now;
{
struct tm *lt;
return ! (lt = localtime (&now)) || mktime (lt) == now;
}
static int
-mktime_test (time_t now)
+mktime_test (now)
+ time_t now;
{
return (mktime_test1 (now)
&& mktime_test1 ((time_t) (time_t_max - now))
}
static int
-bigtime_test (int j)
+bigtime_test (j)
+ int j;
{
struct tm tm;
time_t now;
instead of "TZ=America/Vancouver" in order to detect the bug even
on systems that don't support the Olson extension, or don't have the
full zoneinfo tables installed. */
- putenv ((char*) "TZ=PST8PDT,M4.1.0,M10.5.0");
+ putenv ("TZ=PST8PDT,M4.1.0,M10.5.0");
t = mktime (&tm);
for (i = 0; i < N_STRINGS; i++)
{
if (tz_strings[i])
- putenv ((char*) tz_strings[i]);
+ putenv (tz_strings[i]);
for (t = 0; t <= time_t_max - delta; t += delta)
if (! mktime_test (t))
# Make sure getloadavg.c is where it belongs, at configure-time.
test -f "$srcdir/$ac_config_libobj_dir/getloadavg.c" ||
- as_fn_error $? "$srcdir/$ac_config_libobj_dir/getloadavg.c is missing" "$LINENO" 5
+ as_fn_error "$srcdir/$ac_config_libobj_dir/getloadavg.c is missing" "$LINENO" 5
ac_save_LIBS=$LIBS
fi
if test "$have_tputs_et_al" != true; then
- as_fn_error $? "I couldn't find termcap functions (tputs and friends).
+ as_fn_error "I couldn't find termcap functions (tputs and friends).
Maybe some development libraries/packages are missing? Try installing
libncurses-dev(el), libterminfo-dev(el) or similar." "$LINENO" 5
fi
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
&& test x"`$CC --version 2> /dev/null | grep 'gcc.* 4.5.0'`" != x \
&& test x"`echo $CFLAGS | grep '\-O[23]'`" != x \
&& test x"`echo $CFLAGS | grep '\-fno-optimize-sibling-calls'`" = x; then
- as_fn_error $? "GCC 4.5.0 has problems compiling Emacs; see etc/PROBLEMS'." "$LINENO" 5
+ as_fn_error "GCC 4.5.0 has problems compiling Emacs; see etc/PROBLEMS'." "$LINENO" 5
fi
#### Find out which version of Emacs this is.
version=`grep 'const char emacs_version' ${srcdir}/src/emacs.c \
| sed -e 's/^[^"]*"\([^"]*\)".*$/\1/'`
if test x"${version}" = x; then
- as_fn_error $? "can't find current emacs version in \`${srcdir}/src/emacs.c'." "$LINENO" 5
+ as_fn_error "can't find current emacs version in \`${srcdir}/src/emacs.c'." "$LINENO" 5
fi
if test x"${version}" != x"$PACKAGE_VERSION"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: version mismatch between \`${srcdir}/configure.in' and \`${srcdir}/src/emacs.c'." >&5
echo " Does Emacs use a gif library? ${HAVE_GIF} $LIBGIF"
echo " Does Emacs use -lpng? ${HAVE_PNG}"
echo " Does Emacs use -lrsvg-2? ${HAVE_RSVG}"
+echo " Does Emacs use imagemagick? ${HAVE_IMAGEMAGICK}"
echo " Does Emacs use -lgpm? ${HAVE_GPM}"
echo " Does Emacs use -ldbus? ${HAVE_DBUS}"
echo " Does Emacs use -lgconf? ${HAVE_GCONF}"
ac_libobjs=
ac_ltlibobjs=
-U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
# 1. Remove the extension, and $U if already installed.
ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
+# script with status $?, using 1 if that was 0.
as_fn_error ()
{
- as_status=$1; test $as_status -eq 0 && as_status=1
- if test "$4"; then
- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
fi
- $as_echo "$as_me: error: $2" >&2
+ $as_echo "$as_me: error: $1" >&2
as_fn_exit $as_status
} # as_fn_error
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
} # as_fn_mkdir_p
# values after options handling.
ac_log="
This file was extended by emacs $as_me 24.0.50, which was
-generated by GNU Autoconf 2.66. Invocation command line was
+generated by GNU Autoconf 2.65. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
emacs config.status 24.0.50
-configured by $0, generated by GNU Autoconf 2.66,
+configured by $0, generated by GNU Autoconf 2.65,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2009 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
ac_need_defaults=false;;
--he | --h)
# Conflict between --help and --header
- as_fn_error $? "ambiguous option: \`$1'
+ as_fn_error "ambiguous option: \`$1'
Try \`$0 --help' for more information.";;
--help | --hel | -h )
$as_echo "$ac_cs_usage"; exit ;;
ac_cs_silent=: ;;
# This is an error.
- -*) as_fn_error $? "unrecognized option: \`$1'
+ -*) as_fn_error "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;
*) as_fn_append ac_config_targets " $1"
"leim/Makefile") CONFIG_FILES="$CONFIG_FILES leim/Makefile" ;;
"default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
{
tmp=./conf$$-$RANDOM
(umask 077 && mkdir "$tmp")
-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
fi
ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
- ac_cs_awk_cr='\\r'
+ ac_cs_awk_cr='\r'
else
ac_cs_awk_cr=$ac_cr
fi
echo "_ACEOF"
} >conf$$files.sh &&
. ./conf$$files.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
rm -f conf$$files.sh
{
echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
echo "_ACEOF"
} >conf$$subs.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
. ./conf$$subs.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
if test $ac_delim_n = $ac_delim_num; then
break
elif $ac_last_try; then
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
else
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
fi
else
cat
fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
- || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+ || as_fn_error "could not setup config files machinery" "$LINENO" 5
_ACEOF
-# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
-# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
-h
-s///
-s/^/:/
-s/[ ]*$/:/
-s/:\$(srcdir):/:/g
-s/:\${srcdir}:/:/g
-s/:@srcdir@:/:/g
-s/^:*//
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
s/:*$//
-x
-s/\(=[ ]*\).*/\1/
-G
-s/\n//
s/^[^=]*=[ ]*$//
}'
fi
if test -z "$ac_t"; then
break
elif $ac_last_try; then
- as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
else
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
fi
_ACAWK
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
- as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+ as_fn_error "could not setup config headers machinery" "$LINENO" 5
fi # test -n "$CONFIG_HEADERS"
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
case $ac_tag in
*:-:* | *:-) cat >"$tmp/stdin" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
else
$AWK -f "$tmp/subs.awk" | $SHELL
fi >$tmp/out \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
{ ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined" >&5
+which seems to be undefined. Please make sure it is defined." >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined" >&2;}
+which seems to be undefined. Please make sure it is defined." >&2;}
rm -f "$tmp/stdin"
case $ac_file in
-) cat "$tmp/out" && rm -f "$tmp/out";;
*) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
esac \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
;;
:H)
#
$as_echo "/* $configure_input */" \
&& eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
} >"$tmp/config.h" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
$as_echo "$as_me: $ac_file is unchanged" >&6;}
else
rm -f "$ac_file"
mv "$tmp/config.h" "$ac_file" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
fi
else
$as_echo "/* $configure_input */" \
&& eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
- || as_fn_error $? "could not create -" "$LINENO" 5
+ || as_fn_error "could not create -" "$LINENO" 5
fi
;;
ac_clean_files=$ac_clean_files_save
test $ac_write_fail = 0 ||
- as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
# configure is writing to config.log, and then calls config.status.
exec 5>>config.log
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
- $ac_cs_success || as_fn_exit 1
+ $ac_cs_success || as_fn_exit $?
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
OPTION_DEFAULT_ON([gif],[don't compile with GIF image support])
OPTION_DEFAULT_ON([png],[don't compile with PNG image support])
OPTION_DEFAULT_ON([rsvg],[don't compile with SVG image support])
+OPTION_DEFAULT_OFF([imagemagick],[compile with ImageMagick image support])
OPTION_DEFAULT_ON([xft],[don't use XFT for anti aliased fonts])
OPTION_DEFAULT_ON([libotf],[don't use libotf for OpenType font support])
fi
fi
+HAVE_IMAGEMAGICK=no
+if test "${with_imagemagick}" != "no"; then
+ IMAGEMAGICK_MODULE="Wand"
+ PKG_CHECK_MODULES(IMAGEMAGICK, $IMAGEMAGICK_MODULE, :, :)
+ AC_SUBST(IMAGEMAGICK_CFLAGS)
+ AC_SUBST(IMAGEMAGICK_LIBS)
+
+ if test ".${IMAGEMAGICK_CFLAGS}" != "."; then
+ HAVE_IMAGEMAGICK=yes
+ AC_DEFINE(HAVE_IMAGEMAGICK, 1, [Define to 1 if using imagemagick.])
+ CFLAGS="$CFLAGS $IMAGEMAGICK_CFLAGS"
+ LIBS="$IMAGEMAGICK_LIBS $LIBS"
+ fi
+
+ AC_DEFINE(HAVE_MAGICKEXPORTIMAGEPIXELS, 1, [Define to 1 if MagickExportImagePixels is defined.])
+ AC_CHECK_FUNCS_ONCE(MagickExportImagePixels)
+
+fi
+
HAVE_GTK=no
if test "${with_gtk3}" = "yes"; then
echo " Does Emacs use a gif library? ${HAVE_GIF} $LIBGIF"
echo " Does Emacs use -lpng? ${HAVE_PNG}"
echo " Does Emacs use -lrsvg-2? ${HAVE_RSVG}"
+echo " Does Emacs use imagemagick? ${HAVE_IMAGEMAGICK}"
echo " Does Emacs use -lgpm? ${HAVE_GPM}"
echo " Does Emacs use -ldbus? ${HAVE_DBUS}"
echo " Does Emacs use -lgconf? ${HAVE_GCONF}"
* GIF Images:: Special features for GIF format.
* TIFF Images:: Special features for TIFF format.
* PostScript Images:: Special features for PostScript format.
+* ImageMagick Images:: Special features available through ImageMagick.
* Other Image Types:: Various other formats are supported.
* Defining Images:: Convenient ways to define an image for later use.
* Showing Images:: Convenient ways to display an image once it is defined.
@end example
@end table
+@node ImageMagick Images
+@subsection ImageMagick Images
+The Imagemagick library can be used to load many image formats in Emacs.
+
+The function (imagemagick-types) returns a list of image file
+extensions that your installation of imagemagick supports.
+
+The function (imagemagick-register-types) will enable the imagemagick
+support for the extensions in imagemagick-types minus the types listed
+in imagemagick-types-inhibit.
+
+imagemagick-types-inhibit has the value '(C HTML HTM TXT PDF) by
+default. There can be overlap between image loaders in your Emacs
+installation. If you never want to use the ImageMagick loader to use
+Jpeg files, for instance, add 'JPG to imagemagick-types-inhibit. Which
+loader that will be used in practice depends on the priority of the
+loaders.
+
+imagemagick-render-type is a new variable which can be set to choose
+between screen render methods for the ImageMagick loader.
+
+- 0 is a conservative metod which works with older ImageMagick
+ versions. It is a bit slow, but robust.
+
+- 1 utilizes a newer ImageMagick method
+
+
+Images loaded with imagemagick will support a couple of new display
+specification behaviours:
+
+- if the :width and :height keywords are specified, these values are
+used for scaling the image. If only one of :width or :height is
+specified, the other one will be calculated so as to preserve the
+aspect ratio.If both :width and :height are specified, aspect ratio
+will not be preserved.
+
+- :rotation specifies a rotation angle in degrees.
+
+- :index specifies which image inside an image bundle file format, such
+as TIFF or DJVM, to view.
+
+The image-metadata function can be used to retrieve the total number
+of images in an image bundle. This is simmilar to how GIF files work.
+
+
@node Other Image Types
@subsection Other Image Types
@cindex PBM
+2010-08-14 Eli Zaretskii <eliz@gnu.org>
+
+ * tutorials/TUTORIAL.he: Use MAQAF instead of hyphen where appropriate.
+ Fix a few typos.
+
2010-08-08 Ken Brown <kbrown@cornell.edu>
* PROBLEMS: Mention problem with Cygwin 1.5.19.
top, left, right or bottom. The Options => Show/Hide menu has entries
for this.
+** ImageMagick support
+It is now possible to use the Imagemagick library to load many new
+image formats in Emacs.
+
+To enable, use the following configure option:
+--with-imagemagick
+
+The new function (imagemagick-types) returns a list of image file
+extensions that your installation of imagemagick supports.
+
+The function (imagemagick-register-types) will enable the imagemagick
+support for the extensions in imagemagick-types minus the types listed
+in imagemagick-types-inhibit.
+
+See the Emacs Manual for more information.
+
** The colors for selected text (the region face) are taken from the GTK
theme when Emacs is built with GTK.
** Selection changes.
-The way Emacs interacts with the clipboard and primary selection, by
-default, is now similar to other X applications. In particular, kill
-and yank use the clipboard, in addition to the primary selection.
+The default handling of clipboard and primary selections has been
+changed to conform with other X applications.
+
+*** `select-active-regions' now defaults to t, so active regions set
+the primary selection.
+
+It also accepts a new value, `lazy', which means to only set the
+primary selection for temporarily active regions (usually made by
+mouse-dragging or shift-selection).
-*** `select-active-regions' now defaults to `lazy'.
-This means that any active region made with shift-selection or mouse
-dragging, or acted on by Emacs (e.g. with M-w or C-w), is
-automatically added to the primary window selection.
+*** `mouse-2' is now bound to `mouse-yank-primary'.
*** `x-select-enable-clipboard' now defaults to t.
+Thus, killing and yanking now use the clipboard (in addition to the
+kill ring).
*** `x-select-enable-primary' now defaults to nil.
*** `mouse-drag-copy-region' now defaults to nil.
-*** `mouse-2' is now bound to `mouse-yank-primary'.
-
\f
* Changes in Specialized Modes and Packages in Emacs 24.1
+** FIXME: xdg-open for browse-url and reportbug, 2010/08. (Close bug#4546?)
+
** Archive Mode has basic support to browse 7z archives.
+** ERC changes
+
+*** New vars `erc-autojoin-timing' and `erc-autojoin-delay'.
+If the value of `erc-autojoin-timing' is 'ident, ERC autojoins after a
+successful NickServ identification, or after `erc-autojoin-delay'
+seconds. The default value, 'ident, means to autojoin immediately
+after connecting.
+
** In ido-mode, C-v is no longer bound to ido-toggle-vc.
The reason is that this interferes with cua-mode.
\f
* Lisp changes in Emacs 24.1
+** New hook post-self-insert-hook run at the end of self-insert-command.
+
** Syntax tables support a new "comment style c" additionally to style b.
** frame-local variables cannot be let-bound any more.
** prog-mode is a new major-mode meant to be the parent of programming mode.
Scenario: undefined step # features/cucumber.feature:3
Given this is undefined # features/cucumber.feature:4
- Scenario: assertion false (Test::Unit) # features/cucumber.feature:6
- Given this will generate 'assert false' # features/step_definitions/default_steps.rb:1
+ Scenario: assertion false (Test::Unit) # foo/bar.feature:6
+ Given this will generate 'assert false' # foo/bar.rb:1
<false> is not true. (Test::Unit::AssertionFailedError)
- /home/gusev/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/test/unit/assertions.rb:48:in `assert_block'
- /home/gusev/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/test/unit/assertions.rb:500:in `_wrap_assertion'
- /home/gusev/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/test/unit/assertions.rb:46:in `assert_block'
- /home/gusev/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/test/unit/assertions.rb:63:in `assert'
- /home/gusev/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/test/unit/assertions.rb:495:in `_wrap_assertion'
- /home/gusev/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/test/unit/assertions.rb:61:in `assert'
- ./features/step_definitions/default_steps.rb:2:in `/^this will generate 'assert false'$/'
+ /home/gusev/.rvm/foo/bar.rb:48:in `assert_block'
+ /home/gusev/.rvm/foo/bar.rb:500:in `_wrap_assertion'
features/cucumber.feature:7:in `Given this will generate 'assert false''
- Scenario: assertion false (RSpec) # features/cucumber.feature:9
- Given this will generate 'should be_true' # features/step_definitions/default_steps.rb:5
+ Scenario: assertion false (RSpec) # foo/bar.feature:9
+ Given this will generate 'should be_true' # foo/bar.rb:5
expected true to be false (Spec::Expectations::ExpectationNotMetError)
- ./features/step_definitions/default_steps.rb:6:in `/^this will generate 'should be_true'$/'
- features/cucumber.feature:10:in `Given this will generate 'should be_true''
+ ./foo/bar/baz.rb:6:in `/^this will generate 'should be_true'$/'
+ foo/bar.feature:10:in `Given this will generate 'should be_true''
- Scenario: backtrace in step definition # features/cucumber.feature:12
- Given this will generate backtrace # features/step_definitions/default_steps.rb:9
+ Scenario: backtrace in step definition # foo/bar.feature:12
+ Given this will generate backtrace # foo/sbar.rb:9
(RuntimeError)
- ./features/step_definitions/default_steps.rb:10:in `/^this will generate backtrace$/'
- features/cucumber.feature:13:in `Given this will generate backtrace'
-
- Scenario: deeep backtrace in step definition # features/cucumber.feature:15
- Given this will generate deep backtrace # features/step_definitions/default_steps.rb:13
- (RuntimeError)
- ./features/step_definitions/default_steps.rb:18:in `deep'
- ./features/step_definitions/default_steps.rb:14:in `/^this will generate deep backtrace$/'
- features/cucumber.feature:16:in `Given this will generate deep backtrace'
+ ./foo/bar.rb:10:in `/^this will generate backtrace$/'
+ foo/bar.feature:13:in `Given this will generate backtrace'
Failing Scenarios:
-cucumber features/cucumber.feature:6 # Scenario: assertion false (Test::Unit)
-cucumber features/cucumber.feature:9 # Scenario: assertion false (RSpec)
-cucumber features/cucumber.feature:12 # Scenario: backtrace in step definition
-cucumber features/cucumber.feature:15 # Scenario: deeep backtrace in step definition
+cucumber foo/cucumber.feature:6 # Scenario: assertion false (Test::Unit)
+cucumber foo/cucumber.feature:9 # Scenario: assertion false (RSpec)
+cucumber foo/cucumber.feature:12 # Scenario: backtrace in step definition
+cucumber foo/cucumber.feature:15 # Scenario: deeep backtrace in step definition
5 scenarios (4 failed, 1 undefined)
5 steps (4 failed, 1 undefined)
-שיעור ראשון בשימוש ב-Emacs. זכויות שימוש ראה בסוף המסמך.
+שיעור ראשון בשימוש ב־Emacs. זכויות שימוש ראה בסוף המסמך.
-פקודות רבות של Emacs משתמשות במקש CONTROL (לפעמים הוא מסומן ב-CTRL או CTL)
+פקודות רבות של Emacs משתמשות במקש CONTROL (לפעמים הוא מסומן ב־CTRL או CTL)
או במקש META (לפעמים מסומן EDIT או ALT). במקום לציין את כל השמות האפשריים
בכל פעם, נשתמש בקיצורים הבאים:
אם במקלדת אין אף אחד ממקשי META או EDIT או ALT, אפשר להקיש
ולשחרר מקש ESC ואז להקיש <תו>. אנו נכתוב <ESC> עבור מקש ESC.
-הערה חשובה: כדי לצאת מ-Emacs יש להקיש C-x C-c (שני תוים, משמאל לימין).
+הערה חשובה: כדי לצאת מ־Emacs יש להקיש C-x C-c (שני תוים, משמאל לימין).
כדי להפסיק פקודה באמצע ההקשה, יש להקיש C-g.
המחרוזת ">>" בקצה הימני מסמנת הוראות עבורכם כדי לנסות להשתמש בפקודה כלשהי.
לדוגמה:
<<שורות ריקות תתווספנה סביב השורה הבאה ע"י help-with-tutorial>>
[אמצע העמוד הושאר ריק למטרות לימודיות. הטקסט ממשיך להלן]
->> הקישו עתה C-v (הצג העמוד הבא) על-מנת להתקדם לעמוד הבא. (קדימה, נסו
+>> הקישו עתה C-v (הצג העמוד הבא) על־מנת להתקדם לעמוד הבא. (קדימה, נסו
זאת ע"י לחיצה והחזקה של מקש CONTROL והקשה על v.)
מעתה והלאה, עליכם לעשות זאת בכל פעם שתסיימו לקרוא את המוצג על המסך.
(החזיקו מקש META והקישו v או הקישו <ESC>v אם אין במקלדת מקש META
או EDIT או ALT).
->> נסו עתה כמה פעמים להקיש M-v ואחר-כך C-v.
+>> נסו עתה כמה פעמים להקיש M-v ואחר־כך C-v.
* סיכום עד כאן
כך שהטקסט ליד הסמן יימצא במרכז התצוגה
(שימו לב: CONTROL-L ולא CONTROL-1.)
->> מצאו את הסמן על-גבי התצוגה וזכרו את הטקסט לידו. לאחר מכן הקישו C-l.
+>> מצאו את הסמן על־גבי התצוגה וזכרו את הטקסט לידו. לאחר מכן הקישו C-l.
מצאו את הסמן שנית ושימו לב שהוא עדיין ליד אותו הטקסט, אבל עכשיו
הוא במרכז התצוגה.
אם תקישו C-l שוב, קטע הטקסט הזה יזוז לקצה העליון של התצוגה. הקישו
C-l שוב והוא יזוז לתחתית התצוגה.
-גם מקשי PageUp ו-PageDn, אם הם קיימים במקלדת שלכם, יכולים לשמש לתנועה
-בעמודים שלמים, אולם השימוש ב-C-v ו-M-v יעיל יותר.
+גם מקשי PageUp ו־PageDn, אם הם קיימים במקלדת שלכם, יכולים לשמש לתנועה
+בעמודים שלמים, אולם השימוש ב־C-v ו־M-v יעיל יותר.
* תנועת סמן בסיסית
------------------
תנועה בעמודים שלמים הינה שימושית, אבל כיצד ניתן להגיע למקום ספציפי
-בתוך הטקסט שעל-גבי התצוגה?
+בתוך הטקסט שעל־גבי התצוגה?
ניתן לעשות זאת בכמה דרכים. אפשר למשל להשתמש במקשי החצים, אולם יהיה
זה יעיל יותר אם תחזיקו את הידיים מעל החלק הסטנדרטי של המקלדת ותשתמשו
-בפקודות C-p, C-b, C-f ו-C-n. פקודות אלו שוות ערך לארבעת מקשי החצים,
+בפקודות C-p, C-b, C-f ו־C-n. פקודות אלו שוות ערך לארבעת מקשי החצים,
כדלקמן:
שורה קודמת, C-p
:
השורה הבאה, C-n
->> השתמשו במקשי C-n ו-C-p על-מנת להגיע לשורה האמצעית של הדיאגרמה.
- הקישו C-l כדי למרכז את הדיאגרמה על-גבי התצוגה.
+>> השתמשו במקשי C-n ו־C-p על־מנת להגיע לשורה האמצעית של הדיאגרמה.
+ הקישו C-l כדי למרכז את הדיאגרמה על־גבי התצוגה.
קל יותר לזכור את המקשים הללו באמצעות המלים שהם מייצגים:
-P מ-previous (קודם), N מ-Next (הבא), B מ-Backward (אחורה)
-ו-F מ-Forward (קדימה). מקשי התנועה הבסיסיים הללו ישמשו אתכם כל הזמן.
+P מ־previous (קודם), N מ־Next (הבא), B מ־Backward (אחורה)
+ו־F מ־Forward (קדימה). מקשי התנועה הבסיסיים הללו ישמשו אתכם כל הזמן.
>> הקישו C-n כמה פעמים כדי למקם את הסמן בשורה זו.
->> הניעו את הסמן בתוך השורה עם C-f ואחר-כך למעלה עם C-p.
+>> הניעו את הסמן בתוך השורה עם C-f ואחר־כך למעלה עם C-p.
שימו לב מה עושה C-p כאשר הסמן נמצא באמצע השורה.
כל שורה של טקטס מסתיימת בתו מיוחד הנקרא Newline. תו זה מפריד בין
השורה לזו שאחריה. (בדרך כלל, השורה האחרונה בקובץ תסתיים אף היא
-ב-Newline, אך Emacs אינו זקוק לכך.)
+ב־Newline, אך Emacs אינו זקוק לכך.)
>> נסו C-b בתחילת שורה. הוא יגרום לסמן לנוע לסוף השורה הקודמת. זאת,
- משום שהוא נע אחורה וחולף על-פני תו ה-Newline.
+ משום שהוא נע אחורה וחולף על־פני תו ה־Newline.
-גם C-f יכול לחלוף על-פני Newline, בדיוק כמו C-b.
+גם C-f יכול לחלוף על־פני Newline, בדיוק כמו C-b.
>> הקישו C-b עוד כמה פעמים כדי לקבל הרגשה היכן נמצא הסמן.
עתה הקישו C-f מספר פעמים הדרוש לשוב לסוף השורה. ואז הקישו
C-f עוד פעם אחת כדי לנוע לתחילת השורה הבאה.
כשהסמן יוצא מגבולות הטקסט המוצג, חלקי הטקסט מעבר לחלק המוצג נכנסים
-לתצוגה. לזה קוראים "גלילה". גלילה מאפשרת ל-Emacs להניע את הסמן למקום
+לתצוגה. לזה קוראים "גלילה". גלילה מאפשרת ל־Emacs להניע את הסמן למקום
כלשהו בטקסט מבלי שהסמן ייעלם מהתצוגה.
>> נסו להניע את הסמן אל מחוץ לתצוגה ע"י הקשת C-n ושימו לב למה שקורה.
-אם תנועה תו-תו איטית מדי, תוכלו לנוע מילים שלמות. M-f (META-f) מזיז
+אם תנועה תו־תו איטית מדי, תוכלו לנוע מילים שלמות. M-f (META-f) מזיז
את הסמן מילה אחת קדימה ואילו M-b זז מילה אחורה.
->> הקישו M-f ו-M-b מספר פעמים.
+>> הקישו M-f ו־M-b מספר פעמים.
אם הסמן נמצא באמצע מילה, M-f זז לסוף המילה. אם הסמן נמצא בין שתי מלים,
M-f עובר את המילה הבאה ונעצר בסופה. M-b פועל באופן דומה בכיוון הפוך.
->> הקישו עתה M-f ו-M-b פעמים אחדות, וגם C-f ו-C-b פה ושם כדי שתוכלו
- להתרשם מהתוצאה של M-f ו-M-b במקומות שונים בתוך ובין המלים.
+>> הקישו עתה M-f ו־M-b פעמים אחדות, וגם C-f ו־C-b פה ושם כדי שתוכלו
+ להתרשם מהתוצאה של M-f ו־M-b במקומות שונים בתוך ובין המלים.
-שימו לב להקבלה שבין C-f ו-C-b מצד אחד ו-M-f ו-M-b מהצד השני. לעתים
+שימו לב להקבלה שבין C-f ו־C-b מצד אחד ו־M-f ו־M-b מהצד השני. לעתים
קרובות מאד מקשים עם META משמשים לפעולות הקשורות ליחידות של שפה (מלים,
משפטים, פסקאות) ואילו מקשים עם CONTROL פועלים על יחידות בסיסיות שאינן
תלויות בסוג הטקסט שהינכך עורכים (תוים, שורות, וכד').
-ההקבלה הזאת קיימת גם לגבי שורות ומשפטים: C-a ו-C-e נעים לתחילת השורה
-וסופה, בהתאמה, ואילו M-a ו-M-e נעים לתחילת המשפט וסופו.
+ההקבלה הזאת קיימת גם לגבי שורות ומשפטים: C-a ו־C-e נעים לתחילת השורה
+וסופה, בהתאמה, ואילו M-a ו־M-e נעים לתחילת המשפט וסופו.
->> נסו עתה שתי הקשות על C-a ואחר-כך שתי הקשות על C-e.
- נסו שני M-a ואחר-כך שני M-e.
+>> נסו עתה שתי הקשות על C-a ואחר־כך שתי הקשות על C-e.
+ נסו שני M-a ואחר־כך שני M-e.
שימו לב שחזרה על C-a אינה עושה דבר, ואילו כל הקשה חוזרת על M-a מניעה
את הסמן במשפט נוסף. אמנם אין כאן אנלוגיה מושלמת, אבל התוצאה נראית
אלו הן הפקודות הנפוצות ביותר.
שתי פקודות תנועה חשובות אחרת הן M-< (META פחות), אשר נעה לתחילת
-הטקסט, ו-M-> (META יותר), אשר נעה לסוף הטקסט.
+הטקסט, ו־M-> (META יותר), אשר נעה לסוף הטקסט.
ברוב המקלדות המקש ">" נמצא מעל הפסיק, לכן כדי להקישו יש צורך ללחוץ
ולהחזיק מקש Shift. באופן דומה יש ללחוץ על Shift כדי להקיש M-<כי
אחרת היה יוצא M-פסיק.
>> נסו עתה M-< כדי להגיע לתחילת השיעור.
- אחר-כך הקישו C-v מספר פעמים, עד שתגיעו לכאן.
+ אחר־כך הקישו C-v מספר פעמים, עד שתגיעו לכאן.
>> עכשיו נסו M-> כדי להגיע לסוף השיעור.
לאחר מכן הקישו M-v כמה פעמים כדי לחזור לכאן.
ניתן להזיז את הסמן גם בעזרת מקשי החצים, אם הם קיימים במקלדת שלכם.
-אבל אנחנו ממליצים ללמוד להשתמש ב-C-b, C-f, C-n ו-C-p משלוש סיבות.
+אבל אנחנו ממליצים ללמוד להשתמש ב־C-b, C-f, C-n ו־C-p משלוש סיבות.
קודם כל, הם יעבדו עם כל מקלדת. שנית, כשתתרגלו לעבוד עם Emacs, תראו
כי השימוש במקשים אלו מהיר יותר מהשימוש בחצים (מכיון שאין צורך להזיז
את היד מהחלק העיקרי של המקלדת). ושלישית, כשהמקשים הללו יהפכו להרגל,
רוב הפקודות של Emacs מקבלות ארגומנט נומרי; עבור רוב הפקודות הארגומנט
משמש כמונה של מספר החזרות על הפקודה. כדי לספק ארגומנט לפקודה, יש להקיש
-C-u ואחר-כך ספרות, וזאת לפני שמקישים את הפקודה עצמה. עם במקלדת קיים
+C-u ואחר־כך ספרות, וזאת לפני שמקישים את הפקודה עצמה. עם במקלדת קיים
מקש META (או EDIT או ALT), יש גם אפשרות אחרת לציין ארגומנט נומרי:
הקישו את הספרות תוך כדי החזקת מקש META. אנו ממליצים על C-u משום שהוא
יעבוד עם כל מקלדת. הארגומנט הנומרי נקרא גם "ארגומנט קידומת" (prefix
משתמשות בו כדגלון -- נוכחותו של הארגומנט, ללא קשר לערכו המספרי, גורמת
לפקודה להתנהג קצת אחרת.
-C-v ו-M-v יוצאים מהכלל הזה באופן אחר. כשפקודות אלו מקבלות ארגומנט,
+C-v ו־M-v יוצאים מהכלל הזה באופן אחר. כשפקודות אלו מקבלות ארגומנט,
הן גוללים את התצוגה כמספר הזה של שורות, ולא בדפים. למשל, C-u 8 C-v
-יגלול את התצוגה ב-8 שורות.
+יגלול את התצוגה ב־8 שורות.
>> נסו עתה להקיש C-u 8 C-v.
-כתוצאה, התצוגה היתה צריכה לזוז ב-8 שורות. אם ברצונכם לגלול בחזרה,
-אפשר להשיג זאת ע"י מתן ארגומנט ל-M-v.
+כתוצאה, התצוגה היתה צריכה לזוז ב־8 שורות. אם ברצונכם לגלול בחזרה,
+אפשר להשיג זאת ע"י מתן ארגומנט ל־M-v.
-אם הפעלתם את Emacs על-גבי מערכת חלונאית כגון X או MS-Windows, אתם
+אם הפעלתם את Emacs על־גבי מערכת חלונאית כגון X או MS-Windows, אתם
צריכים לראות פס צר וגבוה, ששמו פס גלילה (scroll bar) בצידו של החלון
של Emacs. (שימו לב שבשני צידי החלון קיימים פסים נוספים. אלה נקראים
"השוליים" -- "fringes" -- ומשמשים להצגת סימני המשך שורה וסימונים
* פקודות מנוטרלות
-----------------
-מספר פקודות ב-Emacs מנוטרלות בכוונה כדי שמשתמשים מתחילים לא יפעילו
+מספר פקודות ב־Emacs מנוטרלות בכוונה כדי שמשתמשים מתחילים לא יפעילו
אותן בדרך מקרה.
אם תקישו את אחת הפקודות הללו, Emacs יציג הודעה המתארת את הפקודה וישאל
>> הקישו C-x 1 ושימו לב שהחלון עם ההסבר על C-f נעלם.
פקודה זו שונה מכל שאר הפקודות שלמדנו עד כה בכך שהיא מכילה שני תוים.
-היא מתחילה עם התו CONTROL-x. פקודות רבות מאד מתחילות ב-CONTROL-x; חלק
+היא מתחילה עם התו CONTROL-x. פקודות רבות מאד מתחילות ב־CONTROL-x; חלק
גדול מהן עוסקות בחלונות, קבצים, חוצצים ונושאים דומים אחרים. פקודות אלו
מכילות שנים, שלושה ואפילו ארבעה תוים.
* הכנסה ומחיקה
--------------
+--------------
אם ברצונכם להכניס טקסט, פשוט הקישו על המקשים המתאימים. תוים רגילים,
כגון A, א, 7, * וכד' מתפרשים ע"י Emacs כטקסט ומיד מתווספים לטקסט
למחיקת התו האחרון שהקשתם הקישו <DelBack>. המקש שאנו קוראים לו <DelBack>
יכול להתקרא בשמות שונים -- "Delete", "DEL" או "Backspace". בדרך כלל
זהו מקש גדול ובולט שנמצא לא הרחק ממקש <Return>, והוא משמש אתכם למחיקת
-התו אחרון גם בתוכניות אחרות, לא רק ב-Emacs.
+התו אחרון גם בתוכניות אחרות, לא רק ב־Emacs.
אם קיים במקלדת שלכם מקש גדול שעליו רשום <Backspace>, אז זהון המקש אשר
-ישמש כ-<DelBack>. גם אם יהיה מקש אחר המסומן ב-"Delete" במקום אחרת זה
-אינו ה-<DelBack> שלכם.
+ישמש כ־<DelBack>. גם אם יהיה מקש אחר המסומן ב־"Delete" במקום אחרת זה
+אינו ה־<DelBack> שלכם.
באופן כללי יותר, <DelBack> מוחק את התו שקודם למיקום הסמן.
->> הקישו עתה מספר תוים, ואחר-כך מחקו אותם ע"י הקשות אחדות
+>> הקישו עתה מספר תוים, ואחר־כך מחקו אותם ע"י הקשות אחדות
על <DelBack>. אל תחששו לשנות את הקובץ הזה -- העותק המקורי
של השיעור יישאר ללא שינוי. אתם עובדים על העותק האישי שלכם.
>> הקישו טקסט עד שתגיעו לקצה השורה, ואז תמשיכו להקיש עוד טקסט.
כתוצאה, תראו שמופיעה שורת המשך.
->> עתה הקישו <DelBack> על-מנת למחוק טקסט עד שהשורה תיעשה קצרה מספיק
- ותתאים לשורה בודדת על-גבי התצוגה. שורת ההמשך תיעלם.
+>> עתה הקישו <DelBack> על־מנת למחוק טקסט עד שהשורה תיעשה קצרה מספיק
+ ותתאים לשורה בודדת על־גבי התצוגה. שורת ההמשך תיעלם.
-ניתן למחוק את תו ה-Newline כמו כל תו אחר. מחיקת ה-Newline בין שתי
+ניתן למחוק את תו ה־Newline כמו כל תו אחר. מחיקת ה־Newline בין שתי
שורות תמזג את השורות לשורה אחת. אם השורה המשולבת תהיה ארוכה מרוחב
התצוגה, היא תוצג עם שורת המשך.
>> הניעו את הסמן לתחילת השורה והקישו <DelBack>. כתוצאה, השורה תתמזג
אם קודמתה.
->> עתה הקישו <Return> כדי להחזיר את ה-Newline שמחקתם.
+>> עתה הקישו <Return> כדי להחזיר את ה־Newline שמחקתם.
-זכרו כי לרוב הפקודות ב-Emacs אפשר לציין מספר חזרות. גם תוי טקסט
+זכרו כי לרוב הפקודות ב־Emacs אפשר לציין מספר חזרות. גם תוי טקסט
שייכים לקבוצת פקודות זו. חזרה על תו טקסט מכניסה אותו מספר פעמים.
->> נסו זאת עכשיו -- הקישו C-u 8 * על-מנת להכניס ********.
+>> נסו זאת עכשיו -- הקישו C-u 8 * על־מנת להכניס ********.
-ובכן, למדתם את האופן הבסיסי ביותר להדפיס משהו ב-Emacs ולתקן שגיאות.
+ובכן, למדתם את האופן הבסיסי ביותר להדפיס משהו ב־Emacs ולתקן שגיאות.
אפשר למחוק גם מלים ואף שורות שלמות. להלן סיכום פקודות המחיקה:
<Delback> מחק תו שלפני הסמן
C-k גזור טקסט מהסמן ועד סוף השורה
M-k גזור טקסט עד סוף המשפט הנוכחי.
-שימו לב שהיחס בין <Delback> ו-C-d לעומת M-<Delback> ו-M-d ממשיכים את
-ההקבלה שבין C-f ו-M-f (אמנם <Delback> איננו תו בקרה, בוא נזניח את
-הנקודה הזו לעת-עתה). C-k ו-M-k דומים ל-C-e ו-M-e, אם נקביל שורות
+שימו לב שהיחס בין <Delback> ו־C-d לעומת M-<Delback> ו־M-d ממשיכים את
+ההקבלה שבין C-f ו־M-f (אמנם <Delback> איננו תו בקרה, בוא נזניח את
+הנקודה הזו לעת־עתה). C-k ו־M-k דומים ל־C-e ו־M-e, אם נקביל שורות
למשפטים.
בנוסף, קיימת שיטה אחידה שמאפשרת לגזור קטע כלשהו של טקסט. לשם כך, תגיעו
>> הקישו C-<SPC>. Emacs צריך להציג הודעה האומרת "Mark set" בתחתית
התצוגה.
>> הניעו את הסמן אל האות צ בשורה השניה של הפיסקה.
->> הקישו C-w. בכך תגזרו את חלק הטקסט שמתחיל ב-ב ומסתיים לפני ה-צ.
+>> הקישו C-w. בכך תגזרו את חלק הטקסט שמתחיל ב־ב ומסתיים לפני ה־צ.
-ההבדל בין "מחיקה" ("deletion") ו-"גזירה" ("killing") הוא שהטקסט
+ההבדל בין "מחיקה" ("deletion") ו־"גזירה" ("killing") הוא שהטקסט
"הגזור" ניתן לאחזור ולהכנסה (במקום כלשהוא בטקסט), ואילו טקסט "מחוק" לא
ניתן להכניס מחדש בשיטה זו. (אבל ניתן לבטל את מחיקה -- ראה להלן.) אחזור
הטקסט הגזור נקרא "הדבקה" ("yanking"). באופן כללי, פקודות אשר עלולות
להעלים כמויות גדולות של טקסט תמיד גוזרות את הטקסט (כך שניתן יהיה בקלות
לשחזרו) בעוד הפקודות שמורידות תו בודד או שורות ריקות ותוי רווח --
-מוחקות (כך שלא ניתן להדביק את הטקסט שנמחק). כך, <Delback> ו-C-d מוחקים
+מוחקות (כך שלא ניתן להדביק את הטקסט שנמחק). כך, <Delback> ו־C-d מוחקים
כאשר מפעילים אותם ללא ארגומנט, אבל גוזרים כאשר מפעילים אותם עם ארגומנט.
->> הניעו את הסמן לתחילת שורה שאינה ריקה. אחר-כך הקישו C-k כדי לגזור
+>> הניעו את הסמן לתחילת שורה שאינה ריקה. אחר־כך הקישו C-k כדי לגזור
את כל הטקסט של אותה שורה.
->> הקישו C-k פעם נוספת. שימו לב שהוא גוזר את ה-Newline שבסוף השורה.
+>> הקישו C-k פעם נוספת. שימו לב שהוא גוזר את ה־Newline שבסוף השורה.
-שימו לב ש-C-k בודד גוזר את תכולת השורה, ו-C-k נוסף גוזר גם את השורה
+שימו לב ש־C-k בודד גוזר את תכולת השורה, ו־C-k נוסף גוזר גם את השורה
עצמה וגורם לשאר השורות לנוע כלפי מעלה. C-k מפרש את הארגומנט הנומרי
-באופן מיוחד: הוא גוזר כמספר הזה שורות, כולל ה-Newlines שלהן. זה שונה
-מסתם הפעלה חוזרת: C-u 2 C-k גוזר שתי שורות כולל ה-Newlines שלהן,
+באופן מיוחד: הוא גוזר כמספר הזה שורות, כולל ה־Newlines שלהן. זה שונה
+מסתם הפעלה חוזרת: C-u 2 C-k גוזר שתי שורות כולל ה־Newlines שלהן,
ואילו הקשה על C-k פעמיים לא עושה כן.
אחזור הטקסט שגזרנו נקרא "הדבקה" ("yanking"). (תחשבו על זה כעל שליפה
באותו מקום ממנו נגזר או במקום אחר כלשהו בתוך הטקסט שאתם עורכים, או
אפילו בקובץ אחר. ניתן להדביק את אותו הטקסט מספר פעמים ובכך ליצור
עותקים מרובים ממנו. תוכניות עריכה אחרות משתמשות במונחים "cutting"
-ו-"pasting" במקום "killing" ו-"yanking" (ראה את מילון המונחים בפרק
-ה-"Glossary" של מדריך למשתמשי Emacs).
+ו־"pasting" במקום "killing" ו־"yanking" (ראה את מילון המונחים בפרק
+ה־"Glossary" של מדריך למשתמשי Emacs).
הפקודה להדבקה היא C-y. היא מכניסה את הטקסט הגזור במקום הנוכחי של הסמן.
>> נסו זאת: הקישו C-y כדי לאחזר טקסט שגזרתם קודם לכן.
אם תקישו C-k מספר פעמים ברצף, כל הטקסט שגזרתם בדרך זו נשמר ביחד, כך
-ש-C-y בודד ידביק את כולו בבת אחת.
+ש־C-y בודד ידביק את כולו בבת אחת.
>> עשו זאת עתה: הקישו C-k כמה פעמים.
עכשיו לאחזור הטקסט שגזרתם:
->> הקישו C-y. אחר-כך הניעו את הסמן כמה שורות כלפי מטה והקישו C-y שוב.
+>> הקישו C-y. אחר־כך הניעו את הסמן כמה שורות כלפי מטה והקישו C-y שוב.
כפי שראיתם, כך תוכלו להעתיק חלק מהטקסט ממקום למקום.
מה לעשות אם יש לכם טקסט להדבקה, אבל בינתיים גזרתם טקסט אחר? C-y ידביק
אם תקישו M-y מספיק פעמים בזו אחר זו, תגיעו חזרה לנקודת ההתחלה (טקסט
שגזרתם לאחרונה).
->> גזרו שורה, אחר-כך תניעו את הסמן אנה ואנה, ולבסוף גזרו שורה נוספת.
+>> גזרו שורה, אחר־כך תניעו את הסמן אנה ואנה, ולבסוף גזרו שורה נוספת.
הקישו C-y כדי לאחזר את השורה השניה שגזרתם.
עתה הקישו M-y והשורה שאחזרתם תוחלף בשורה הראשונה שגזרתם.
הקישו M-y מספר פעמים נוספות ושימו לב לתוצאות. המשיכו להקיש M-y
ופקודות גלילה) אינן נספרות ותוים שמכניסים את עצמם מקובצים בקבוצות של
עד 20, כדי להקטין את מספר הפעמים שיש להקיש C-x u כדי לבטל הכנסת טקסט.
->> גזרו שורה זו עם C-k, אחר-כך הקישו C-x u והיא תופיע שוב.
+>> גזרו שורה זו עם C-k, אחר־כך הקישו C-x u והיא תופיע שוב.
C-_ הינה דרך חלופית להפעיל את פקודת הביטול. היא פועלת בדיוק כמו C-x u,
אבל קלה יותר להקשה מספר פעמים בזו אחר זו. החסרון של C-_ הוא שבכמה
מקלדות לא ברור מאליו כיצד להקיש זאת. זו הסיבה לקיומו של C-x u. במקלדות
אחדות ניתן להקיש C-_ ע"י החזקת CONTROL והקשת לוכסן /.
-ארגומנט נומרי ל-C-_ או ל-C-x u משמש כמספר החזרות על הפקודה.
+ארגומנט נומרי ל־C-_ או ל־C-x u משמש כמספר החזרות על הפקודה.
ניתן לבטל מחיקה של טקסט בדיוק כמו שניתן לבטל גזירה. ההבדלים בין מחיקה
וגזירה משפיעים על יכולתכם להדביק את הטקסט הגזור עם C-y; הם אינם חשובים
* קבצים
-------
-על-מנת שהטקסט שערכתם יישמר, יש לשים אותו בקובץ. אחרת, הוא ייעלם ברגע
-שתצאו מ-Emacs. כדי לשים את הטקס בקובץ, יש "לפתוח" ("find") את הקובץ
+על־מנת שהטקסט שערכתם יישמר, יש לשים אותו בקובץ. אחרת, הוא ייעלם ברגע
+שתצאו מ־Emacs. כדי לשים את הטקס בקובץ, יש "לפתוח" ("find") את הקובץ
לפני שמתחילים להקיש טקסט. (שם אחר לכך הוא "לפקוד" את הקובץ - "visit".)
פתיחת הקובץ משמעותה שתוכן הקובץ מוצג בתוך Emacs. מבחינות רבות הדבר
אם תביטו בחלק התחתון של התצוגה, תראו שם שורה בולטת שמתחילה ומסתיימת
במקפים וליד הקצה השמאלי שלה כתוב "TUTORIAL.he". חלק זה של התצוגה בדרך
כלל מציג את שם הקובץ אותו אתם פוקדים. כרגע אתם פוקדים קובץ בשם
-"TUTORIAL.he" שהוא עותק הטיוטה האישי שלכם של שיעור השימוש ב-Emacs.
-פתיחת קובץ כלשהו ב-Emacs תציג את שמו של הקובץ במקום זה.
+"TUTORIAL.he" שהוא עותק הטיוטה האישי שלכם של שיעור השימוש ב־Emacs.
+פתיחת קובץ כלשהו ב־Emacs תציג את שמו של הקובץ במקום זה.
היבט אחד מיוחד של פתיחת קובץ הוא שיש לציין את שם הקובץ אשר ברצונכם
לפתוח. אנו אומרים שהפקודה "קוראת ארגומנט מהמסוף" (במקרה זה הארגומנט
C-x C-f פתח קובץ
Emacs מבקש שתקישו את שם הקובץ. שם הקובץ שתקישו מופיע בשורה התחתונה של
-התצוגה. שורה זו נקראת "מיני-חוצץ" ("minibuffer") כשהיא משמשת לסוג זה
+התצוגה. שורה זו נקראת "מיני־חוצץ" ("minibuffer") כשהיא משמשת לסוג זה
של קלט. ניתן להשתמש בכל פקודות העריכה הרגילות של Emacs כשמקישים את
שם הקובץ בחוצץ זה.
-אם טרם סיימתם להקיש את שם הקובץ (או כל סוג אחר של קלט במיני-חוצץ),
+אם טרם סיימתם להקיש את שם הקובץ (או כל סוג אחר של קלט במיני־חוצץ),
ניתן לבטל את הפקודה בעזרת C-g.
->> הקישו C-x C-f ואחר-כך הקישו C-g. זה מבטל את המיני-חוצץ וגם מבטל
- את הפקודה C-x C-f שהשתמשה במיני-חוצץ. התוצאה היא שאף קובץ לא נפתח.
+>> הקישו C-x C-f ואחר־כך הקישו C-g. זה מבטל את המיני־חוצץ וגם מבטל
+ את הפקודה C-x C-f שהשתמשה במיני־חוצץ. התוצאה היא שאף קובץ לא נפתח.
-משסיימתם להקיש את שם הקובץ, הקישו <Return> לסיים את הקלט. או-אז תיגש
-C-x C-f לעבודה ותמצא ותפתח את הקובץ שבחרתם. המיני-חוצץ נעלם כאשר
-פקודת ה-C-x C-f תסיים את עבודתה.
+משסיימתם להקיש את שם הקובץ, הקישו <Return> לסיים את הקלט. או־אז תיגש
+C-x C-f לעבודה ותמצא ותפתח את הקובץ שבחרתם. המיני־חוצץ נעלם כאשר
+פקודת ה־C-x C-f תסיים את עבודתה.
-זמן קצר אחר-כך תוכן הקובץ יופיע על-גבי התצוגה ותוכלו לבצע בו שינויים.
+זמן קצר אחר־כך תוכן הקובץ יופיע על־גבי התצוגה ותוכלו לבצע בו שינויים.
כשתחליטו לשמור את השינויים, הקישו את הפקודה הבאה:
C-x C-s שמור את הקובץ
לאיבוד. השם החדש נוצר ע"י הוספת "~" בסוף השם המקורי של הקובץ.
כשהשמירה מסתיימת, Emacs מציג בשורה התחתונה את שם הקובץ שנשמר. נסו
-לשמור לעתים מזומנות על-מנת להימנע מלאבד יותר מדי מהעבודה שלכם אם המחשב
+לשמור לעתים מזומנות על־מנת להימנע מלאבד יותר מדי מהעבודה שלכם אם המחשב
ייפול (ראה להלן פיסקה על שמירה אוטומטית).
>> הקישו C-x C-s כדי לשמור את העותק שלכם של השיעור.
כתוצאה, תופיע ההודעה "Wrote ... TUTORIAL.he" בתחתית התצוגה.
-ניתן לפתוח קובץ קיים על-מנת לצפות בו או לערוך אותו. ניתן גם לפתוח קובץ
+ניתן לפתוח קובץ קיים על־מנת לצפות בו או לערוך אותו. ניתן גם לפתוח קובץ
שאינו קיים. זו הדרך ליצור קבצים חדשים בעזרת Emacs: פתחו את הקובץ
שיהיה תחילה ריק ואז התחילו להקיש טקסט לתוכו. כשתפעילו את פקודת השמירה,
Emacs ייצור את הקובץ עם הטקסט שהקשתם. מאותו רגע ואילך, תוכלו לחשוב
* חוצצים
--------
-אם תפתחו קובץ נוסף עם C-x C-f, הקובץ הראשון עדיין נשאר פתוח ב-Emacs.
+אם תפתחו קובץ נוסף עם C-x C-f, הקובץ הראשון עדיין נשאר פתוח ב־Emacs.
תוכלו לחזור אליו ע"י C-x C-f. כך תוכלו לפתוח מספר רב של קבצים.
>> ניצור עתה קובץ בשם "foo" ע"י הקשת C-x C-f foo <Return>.
- אחר-כך הכניסו קצת טקסט, ערכו אותו ולבסוף שמרו בקובץ "foo"
+ אחר־כך הכניסו קצת טקסט, ערכו אותו ולבסוף שמרו בקובץ "foo"
ע"י C-x C-s. עתה חזרו לשיעור בעזרת C-x C-f TUTORIAL.he <Return>.
Emacs מחזיק כל קובץ בתוך יישות בשם "חוצץ" ("buffer"). פתיחת קובץ יוצרת
בפקודה C-x b. פקודה זו תחייב אותכם להקיש את שם החוצץ.
>> הקישו C-x b foo <Return> כדי לחזור לחוצץ "foo" אשר מחזיק טקסט של
- הקובץ "foo". אחר-כך הקישו C-x b TUTORIAL.he <Return> כדי לשוב
+ הקובץ "foo". אחר־כך הקישו C-x b TUTORIAL.he <Return> כדי לשוב
לשיעור זה.
ברוב המקרים שם החוצץ זהה לשם הקובץ (ללא שם התיקיה שלו). אבל אין זה
תמיד כך. רשימת החוצצים שנוצרת ע"י C-x C-b תמיד תציג את שמות כל החוצצים
-הקיימים ב-Emacs.
+הקיימים ב־Emacs.
כל טקסט שמוצג בחלון של Emacs הינו תמיד חלק של חוצץ כלשהו. קיימים
חוצצים שאינם קשורים לשום קובץ. לדוגמא, החוצץ בשם "*Buffer List*" אינו
שהופיעו בשורה התחתונה במהלך עבודתכם בתוך Emacs.
>> הקישו C-x b *Messages* <Return> כדי לצפות בחוצץ של הודעות.
- אחר-כך הקישו C-x b TUTORIAL.he <Return> על-מנת לחזור לשיעור זה.
+ אחר־כך הקישו C-x b TUTORIAL.he <Return> על־מנת לחזור לשיעור זה.
-אם עשיתם שינויים בטקסט של קובץ ואחר-כך פתחתם קובץ אחר, אין הדבר שומר
+אם עשיתם שינויים בטקסט של קובץ ואחר־כך פתחתם קובץ אחר, אין הדבר שומר
את השינויים שעשיתם לקובץ הראשון. השינויים הללו נשארים בתוך Emacs, בתוך
החוצץ של אותו קובץ. יצירתו ועריכתו של הקובץ הנוסף אינם משפיעים על
החוצץ של הקובץ הראשון. דבר זה הוא שימושי, אך משמעותו היא שיש צורך
C-x s עובר על כל החוצצים אשר מכילים שינויים שטרם נשמרו. לגבי כל חוצץ
כזה הוא שואל אתכם האם לשמור אותו או לא.
->> הכניסו שורה של טקסט ואחר-כך הקישו C-x s.
+>> הכניסו שורה של טקסט ואחר־כך הקישו C-x s.
הוא צריך לשאול האם לשמור חוצץ בשם TUTORIAL.he.
השיבו בחיוב ע"י הקשה על "y".
* הרחבת אוסף הפקודות
--------------------
-מספר הפקודות ב-Emacs גדול בהרבה ממה שניתן להפעיל ע"י כל תוי ה-control
-וה-meta. כדי להתגבר על בעיה זו, Emacs משתמש בפקודות X המרחיבות (eXtend)
+מספר הפקודות ב־Emacs גדול בהרבה ממה שניתן להפעיל ע"י כל תוי ה־control
+וה־meta. כדי להתגבר על בעיה זו, Emacs משתמש בפקודות X המרחיבות (eXtend)
את אוסף הפקודות הרגיל. פקודות הרחבה אלו הן שתים:
C-x הרחבת תו. תו בודד שבא אחריו משלים את הפקודה.
בעזרת שתי אלו ניתן להפעיל פקודות שימושיות שבהן משתמשים לעתים רחוקות
יותר מאשר פקודות שלמדתם עד עכשיו. כמה מהן כבר ראיתם: C-x C-f לפתיחת
-קובץ, ו-C-x C-s לשמירת קובץ, לדוגמא. דוגמא נוספת היא פקודה לצאת
-מ-Emacs -- C-x C-c. (כשאתם מפעילים C-x C-c, אל תדאגו לשינויים שטרם
+קובץ, ו־C-x C-s לשמירת קובץ, לדוגמא. דוגמא נוספת היא פקודה לצאת
+מ־Emacs -- C-x C-c. (כשאתם מפעילים C-x C-c, אל תדאגו לשינויים שטרם
נשמרו; C-x C-c מציע לשמור כל קובץ ששיניתם לפני שהוא מסיים את Emacs.)
אם אתם משתמשים בצג גרפי אשר תומך במספר תוכניות במקביל, אינכם זקוקים
-לפקודה מיוחדת כדי לעבור מ-Emacs לתוכנית אחרת. אפשר לעשות זאת בעזרת
+לפקודה מיוחדת כדי לעבור מ־Emacs לתוכנית אחרת. אפשר לעשות זאת בעזרת
העכבר או פקודות של מנהל החלונות. אולם, כאשר אתם משתמשים בתצוגה
-טקסטואלית שמסוגלת להציג רק תוכנית אחת בו-זמנית, תצטרכו "להשעות"
-("suspend") את Emacs על-מנת לעבור לתוכנית אחרת.
+טקסטואלית שמסוגלת להציג רק תוכנית אחת בו־זמנית, תצטרכו "להשעות"
+("suspend") את Emacs על־מנת לעבור לתוכנית אחרת.
-הפקודה C-z יוצאת מ-Emacs *באופן זמני* -- כך שתוכלו לשוב אליו מאוחר
+הפקודה C-z יוצאת מ־Emacs *באופן זמני* -- כך שתוכלו לשוב אליו מאוחר
יותר ולהמשיך מאותה נקודה. כאשר Emacs רץ על תצוגת טקסט, C-z "משעה" את
Emacs: הוא מחזיר אתכם לשורת הפקודות הבסיסית של מערכת ההפעלה ("shell"),
-אבל אינו מסיים את Emacs. ברוב המערכות, כדי להמשיך בעבודתכם ב-Emacs,
+אבל אינו מסיים את Emacs. ברוב המערכות, כדי להמשיך בעבודתכם ב־Emacs,
תצטרכו להקיש את הפקודה "fg" או "%emacs".
-הרגע הנכון להשתמש ב-C-x C-c הוא כאשר אתם עומדים להתנתק (log out).
-כמו-כן, תצטרכו להשתמש בו כדי לצאת מ-Emacs שהופעל ע"י תוכניות אחרות
+הרגע הנכון להשתמש ב־C-x C-c הוא כאשר אתם עומדים להתנתק (log out).
+כמו־כן, תצטרכו להשתמש בו כדי לצאת מ־Emacs שהופעל ע"י תוכניות אחרות
כגון קריאת דואר אלקטרוני -- תוכניות אלו לא תמיד יודעות להסתדר עם
השעיית Emacs.
C-x s שמור חוצצים אחדים
C-x C-b הצג רשימת חוצצים
C-x b החלף חוצץ
- C-x C-c צא מ-Emacs
+ C-x C-c צא מ־Emacs
C-x 1 השאר רק חלון אחד ומחק כל השאר
C-x u בטל פקודה אחרונה
ספציפיות רק לאופני פעולה (modes) מיוחדים. דוגמא לכך היא פקודה
replace-string (החלף מחרוזת) אשר מחליפה מחרוזת אחת במשנה בכל החוצץ.
אחרי שתקישו M-x, Emacs מציג M-x בתחתית התצוגה ומחכה שתקישו את שם
-הפקודה, במקרה זה "replace-string". מספיק שתקישו "repl s<TAB>" ו-Emacs
+הפקודה, במקרה זה "replace-string". מספיק שתקישו "repl s<TAB>" ו־Emacs
ישלים את השם המלא. (<TAB> הוא מקש Tab, בדרך כלל תמצאו אותו מעל מקש
-ה-CapsLock או Shift, ליד הקצה השמאלי של המקלדת.) סיימו את שם הפקודה
+ה־CapsLock או Shift, ליד הקצה השמאלי של המקלדת.) סיימו את שם הפקודה
ע"י הקשת <Return>.
הפקודה להחלפת מחרוזת זקוקה לשני ארגומנטים -- המחרוזת שתוחלף וזו שתחליף
----------------
שינויים שערכתם בקובץ אבל טרם שמרתם עלולים ללכת לאיבוד אם המחשב שלכם
-נתקע. על-מנת להגן עליכם מפני סכנה זו, Emacs שומר לעתים מזומנות כל קובץ
+נתקע. על־מנת להגן עליכם מפני סכנה זו, Emacs שומר לעתים מזומנות כל קובץ
שנמצא בעריכה. השמירה האוטומטית הזאת נעשית לקובץ נפרד ששמו מתחיל
ומסתיים בתו #. לדוגמא, אם הינכם עורכים קובץ בשם "hello.c", קובץ השמירה
האוטומטית שיווצר עבורו ייקרא "#hello.c#". שמירה רגילה של הקובץ על ידכם
אם המחשב אכן נתקע, תוכלו לנציל את השינויים שלא הספקתם לשמור. לשם כך,
יש לפתוח את הקובץ כרגיל (את הקובץ בשמו המקורי, לא את קובץ השמירה
-האוטומטית), ואחר-כך להקיש M-x recover-file <Return>. כש-Emacs יבקש
-אישור, הקישו yes<Return> כדי ש-Emacs ישחזר את הקובץ כפי שנשמר
+האוטומטית), ואחר־כך להקיש M-x recover-file <Return>. כש־Emacs יבקש
+אישור, הקישו yes<Return> כדי ש־Emacs ישחזר את הקובץ כפי שנשמר
אוטומטית.
את מיקומכם הנוכחי בתוך הטקסט, לאמור כי NN אחוזים מהטקסט קודמים לטקסט
המוצג כרגע בחלון. אם המוצג בחלון כולל את תחילת הטקסט, תראו שם "Top"
במקום "0% ". אם המוצג בחלון כולל את סוף הטקסט, תראו שם "Bot" (bottom).
-אם הטקסט כל-כך קצר שכולו מוצג בחלון, שורת הסטטוס תציג "All".
+אם הטקסט כל־כך קצר שכולו מוצג בחלון, שורת הסטטוס תציג "All".
האות L והמספר שאחריה מציינים את המיקום הנוכחי בדרך אחרת: הם מראים את
מספר השורה שבה נמצא הסמן.
כעת. ברירת המחדל היא Fundamental, האופן הבסיס, שבו אתם משתמשים כעת.
זוהי דוגמא של "אופן עריכה ראשי" (major mode).
-ל-Emacs אופני עריכה ראשיים רבים ומגוונים. חלק מהם נועדו לעריכה של שפת
+ל־Emacs אופני עריכה ראשיים רבים ומגוונים. חלק מהם נועדו לעריכה של שפת
תכנות מסוימת ו/או סוג מסוים של טקסט, כגון Lisp mode, Text mode וכד'.
בכל רגע נתון רק אופן עיקרי אחד יכול להיות פעיל ושמו תמיד מצויין בשורת
הסטטוס באותו מקום בו כרגע אתם רואים "Fundamental".
למשל הפקודה להפעיל את האופן Fundamental הינה M-x fundamental-mode.
אם בכוונתכם לערוך טקסט בשפה אנושית כלשהי, כמו הקובץ הזה, כדאי לכם
-להשתמש ב-Text mode.
+להשתמש ב־Text mode.
>> הקישו M-x text-mode <Return>.
אל דאגה: אף אחת מפקודות Emacs שלמדתם עד כה משנה את התנהגותה באופן
-מהותי. עם זאת, שימו לב ש-M-f ו-M-b מתייחסים עכשיו ל-'גרש' כחלק מהמילה.
-לפני-כן, ב-Fundamental mode, M-f ו-M-b התנהגו עם הגרש כמפריד בין
+מהותי. עם זאת, שימו לב ש־M-f ו־M-b מתייחסים עכשיו ל־'גרש' כחלק מהמילה.
+לפני־כן, ב־Fundamental mode, M-f ו־M-b התנהגו עם הגרש כמפריד בין
מילים.
-אופנים ראשיים בדרך-כלל משנים קלות את התנהגות הפקודות: רוב הפקודות
+אופנים ראשיים בדרך־כלל משנים קלות את התנהגות הפקודות: רוב הפקודות
עדיין "עושות אותה עבודה" בכל האופנים הראשיים, אבל עושות אותה קצת אחרת.
לצפיה בתיעוד של האופן הראשי הנוכחי יש להקיש C-h m.
->> השתמשו ב-C-u C-v פעם אחת או יותר כדי להביא שורה זו לראשית התצוגה.
->> עתה הקישו C-h m כדי לראות במה Text mode שונה מה-Fundamental mode.
+>> השתמשו ב־C-u C-v פעם אחת או יותר כדי להביא שורה זו לראשית התצוגה.
+>> עתה הקישו C-h m כדי לראות במה Text mode שונה מה־Fundamental mode.
>> לבסוף, הקישו C-x 1 כדי לסלק את התיעוד מהתצוגה.
-אופנים ראשיים נקראים כך משום שקיימים גם אופני-משנה (minor modes).
+אופנים ראשיים נקראים כך משום שקיימים גם אופני־משנה (minor modes).
אופני משנה אינם מהווים חלופה לאופנים הראשיים, הם רק משנים אותם במקצת.
-כל אופן-משנה ניתן להפעלה או ביטול ללא תלות בכל שאר אופני המשנה וללא
-תלות באופן הראשי הנוכחי. לכן תוכלו להפעיל אופן-משנה אחד או יותר, או אף
-אופן-משנה.
+כל אופן־משנה ניתן להפעלה או ביטול ללא תלות בכל שאר אופני המשנה וללא
+תלות באופן הראשי הנוכחי. לכן תוכלו להפעיל אופן־משנה אחד או יותר, או אף
+אופן־משנה.
-אחד מאופני-המשנה השימושיים ביותר, במיוחד לשם עריכת טקס בשפת-אנוש, הוא
+אחד מאופני־המשנה השימושיים ביותר, במיוחד לשם עריכת טקס בשפת־אנוש, הוא
Auto Fill mode. כאשר אופן זה מופעל, Emacs אוטומטית פותח שורה חדשה
בסיום מילה אם הטקסט שהקשתם ארוך מדי בשביל שורה אחת.
זו מפעילה את האופן כשאינו פעיל ומבטלת אותו כשהוא פעיל. לפעולה זו
קוראים "מיתוג" -- הפקודה "ממתגת" את האופן.
->> הקישו עתה M-x auto-fill-mode <Return>. אחר-כך הקישו "שדגכ " (עם
+>> הקישו עתה M-x auto-fill-mode <Return>. אחר־כך הקישו "שדגכ " (עם
הרווח בסוף) שוב ושוב עד שתיפתח שורה חדשה. הרווחים חשובים משום
- ש-Auto Fill mode שובר שורות אך ורק ברווח שבין המלים.
+ ש־Auto Fill mode שובר שורות אך ורק ברווח שבין המלים.
-השוליים (margin) ש-Emacs שומר בדרך-כלל מתחילים אחרי 70 תווים, אבל ניתן
+השוליים (margin) ש־Emacs שומר בדרך־כלל מתחילים אחרי 70 תווים, אבל ניתן
לשנות הגדרה זו בעזרת הפקודה C-x f. פקודה זו מקבלת את ההגדרה החדשה של
השוליים כארגומנט נומרי.
->> הקישו C-x f עם ארגומנט של 20. (C-u 2 0 C-x f). אחר-כך הקישו טקסט
- כלשהו ושימו לב ש-Emacs פותח שורות חדשות אחרי 20 תווים לכל היותר.
- לבסוף, החזירו את הגדרת השוליים ל-70 ע"י שימוש חוזר ב-C-x f.
+>> הקישו C-x f עם ארגומנט של 20. (C-u 2 0 C-x f). אחר־כך הקישו טקסט
+ כלשהו ושימו לב ש־Emacs פותח שורות חדשות אחרי 20 תווים לכל היותר.
+ לבסוף, החזירו את הגדרת השוליים ל־70 ע"י שימוש חוזר ב־C-x f.
אם ערכתם שינויים באמצע פסקה, Auto Fill mode לא ימלא שורות מחדש באופן
אוטומטי.
החיפוש של Emacs הינו "מצטבר" ("incremental"). פירוש הדבר הוא שהחיפוש
מתבצע במקביל להקשתכם את המחרוזת אותה ברצונכם למצוא.
-הפקודה להתחיל בחיפוש היא C-s לחיפוש קדימה ו-C-r לחיפוש אחורה. חכו! אל
+הפקודה להתחיל בחיפוש היא C-s לחיפוש קדימה ו־C-r לחיפוש אחורה. חכו! אל
תפעילו אותן עדיין.
כשתקישו C-s, תראו שבאזור תצוגת ההד יופיע הטקסט "I-search". זה אומר
-ש-Emacs נמצא במצב "חיפוש מצטבר" ("incremental search") והוא ממתין
+ש־Emacs נמצא במצב "חיפוש מצטבר" ("incremental search") והוא ממתין
להקשתכם את המחרוזת אותה ברצונכם למצוא. הקשה על <Return> מסיימת את
החיפוש.
->> הקישו עתה C-s כדי להתחיל בחיפוש. לאט-לאט, אות-אות, הקישו את המילה
+>> הקישו עתה C-s כדי להתחיל בחיפוש. לאט־לאט, אות־אות, הקישו את המילה
"סמן", עם הפסקה אחרי כל אות, ושימו לב להתנהגות הסמן.
זה עתה מצאתם את המילה "סמן" פעם אחת.
>> הקישו C-s שוב, כדי למצוא את "סמן" במקומות נוספים בטקסט.
(הערה: במערכות אחדות הקשה על C-s מקפיעה את תצוגת המסך, כך שלא תראו
יותר שום פלט של Emacs. משמעות הדבר שתכונת מערכת ההפעלה ששמה "flow
-control" מופעלת ע"י C-s ואינה מעבירה את C-s ל-Emacs. לביטול הקפאת
+control" מופעלת ע"י C-s ואינה מעבירה את C-s ל־Emacs. לביטול הקפאת
התצוגה במערכות אלו יש להקיש C-q.)
אם במהלך החיפוש תקישו על <Delback>, תראו שהתו האחרון של המחרוזת
המבוקשת נמחק והחיפוש חוזר למקום הקודם בו נמצאה המחרוזת ללא התו האחרון.
-למשל, נניח שהקשתם "ס" על-מנת למצוא את המקום הבא בו מופיעה האות "ס". אם
+למשל, נניח שהקשתם "ס" על־מנת למצוא את המקום הבא בו מופיעה האות "ס". אם
עכשיו תקישו "מ", הסמן יזוז למקום בו נמצא "סמ". עתה הקישו <Delback>.
-ה-"מ" נמחק מהמחרוזת והסמן חוזר למקום בו הוא מצא את "ס" לראשונה.
+ה־"מ" נמחק מהמחרוזת והסמן חוזר למקום בו הוא מצא את "ס" לראשונה.
אם במהלך החיפוש תפעילו פקודה כלשהי ע"י הקשה על מקש תוך לחיצה על
CONTROL או META, החיפוש יסתיים. (כמה תווים יוצאים מכלל זה -- אלו תווים
-מיוחדים בעת חיפוש, כדוגמת C-s ו-C-r.)
+מיוחדים בעת חיפוש, כדוגמת C-s ו־C-r.)
הקשה על C-s מתחילה חיפוש שמנסה למצוא את המחרוזת _אחרי_ הסמן. אם
ברצונכם למצוא משהו בטקסט הקודם למקום הנוכחי, הקישו C-r במקום C-s. כל
---------------
אחת התכונות הנוחות של Emacs היא כי ניתן להציג יותר מחלון אחד על המסך
-בו-זמנית. (הערה: Emacs משתמש במונח "frame" -- "תבנית" -- בשביל מה
+בו־זמנית. (הערה: Emacs משתמש במונח "frame" -- "תבנית" -- בשביל מה
שתוכניות אחרות מכנות "חלון". תבניות מתוארות בפסקה הבאה. תוכלו למצוא את
רשימת המונחים של Emacs בפרק "Glossary" של מדריך משתמש.)
>> הקישו C-M-v כדי לגלול את החלון התחתון.
(אם במקלדת שלכם אין מקש META אמיתי, הקישו <ESC> C-v כתחליף.)
->> הקישו C-x o ("o" הוא רמז ל-"other", "אחר") על-מנת להעביר את הסמן
+>> הקישו C-x o ("o" הוא רמז ל־"other", "אחר") על־מנת להעביר את הסמן
לחלון התחתון.
->> הקישו C-v ו-M-v בחלון התחתון כדי לגלול אותו.
+>> הקישו C-v ו־M-v בחלון התחתון כדי לגלול אותו.
המשיכו לקרוא הוראות אלו בחלון העליון.
>> הקישו C-x o שוב לחזור לחלון העליון.
- הסמן בחלון העליון יישאר במקום בו הוא היה לפני-כן.
+ הסמן בחלון העליון יישאר במקום בו הוא היה לפני־כן.
-תוכלו להמשיך להשתמש ב-C-x o כדי לדלג בין שני החלונות. לכל חלון מיקום
+תוכלו להמשיך להשתמש ב־C-x o כדי לדלג בין שני החלונות. לכל חלון מיקום
סמן משלו, אבל רק חלון אחד מציג את הסמן בכל רגע. כל פקודות העריכה
הרגילות פועלות על החלון שבו מוצג הסמן. אנו קוראים לחלון זה "החלון
הנבחר".
C-M-v היא דוגמא אחת של פקודת CONTROL-META. אם במקלדת שלכם קיים מקש
META אמיתי, תוכלו להקיש את הפקודה ע"י לחיצה והחזקה של מקשי CONTROL
-ו-META גם יחד ואז להקיש v. הסדר שבו תלחצו על CONTROL ו-META אינו משנה
+ו־META גם יחד ואז להקיש v. הסדר שבו תלחצו על CONTROL ו־META אינו משנה
כי שני המקשים הללו פועלים ע"י שינוי התו המוקש יחד איתם.
-אם אין במקלדת מקש META אמיתי ואתם משתמשים ב-<ESC> כתחליף, הסדר כן
+אם אין במקלדת מקש META אמיתי ואתם משתמשים ב־<ESC> כתחליף, הסדר כן
משנה: חייבים להקיש <ESC> ורק לאחר מכן CONTROL-v, וזאת משום
-ש-CONTROL-<ESC> v לא יעבוד. <ESC> הוא תו בזכות עצמו, שלא כמו CONTROL
+ש־CONTROL-<ESC> v לא יעבוד. <ESC> הוא תו בזכות עצמו, שלא כמו CONTROL
או META.
>> הקישו C-x 1 (בחלון העליון) כדי לסלק את החלון התחתון.
(אילו הקשתם C-x 1 בחלון התחתון, הייתם מסלקים את החלון העליון. תוכלו
-לחשוב על פקודה זו כ-"השאר רק חלון אחד -- החלון בו אני נמצא עתה".)
+לחשוב על פקודה זו כ־"השאר רק חלון אחד -- החלון בו אני נמצא עתה".)
-אין חובה להציג את אותו החוצץ בשני החלונות. תוכלו להשתמש ב-C-x C-f
+אין חובה להציג את אותו החוצץ בשני החלונות. תוכלו להשתמש ב־C-x C-f
לפתיחת קובץ באחד החלונות -- דבר זה אינו משפיע על החלון השני. אפשר גם
-לפתוח קבצים שונים בכל אחד משני החלונות באופן בלתי-תלוי.
+לפתוח קבצים שונים בכל אחד משני החלונות באופן בלתי־תלוי.
הנה עוד שיטה להשתמש בשני חלונות להצגה של שני דברים שונים:
->> הקישו C-x 4 C-f ואחר-כך הקישו שם של אחד הקבצים שלכם.
+>> הקישו C-x 4 C-f ואחר־כך הקישו שם של אחד הקבצים שלכם.
סיימו עם <Return>. שימו לב שהקובץ המבוקש מוצג בחלון התחתון. הסמן
מדלג לשם אף הוא.
->> הקישו C-x o לעבור לחלון העליון ואחר-כך הקישו C-x 1 כדי לסלק את
+>> הקישו C-x o לעבור לחלון העליון ואחר־כך הקישו C-x 1 כדי לסלק את
החלון התחתון.
>> הקישו M-x delete-frame <Return>.
התבנית שבה הקשתם את הפקודה תיסגר ותיעלם מהמסך.
-כמו-כן, ניתן לסגור תבנית בדרך הרגילה הנתמכת ע"י מנהל החלונות של המערכת
-שלכם (בדרך-כלל, ע"י הקלקה על הכפתור המסומן ב-"X" בפינה עליונה של
+כמו־כן, ניתן לסגור תבנית בדרך הרגילה הנתמכת ע"י מנהל החלונות של המערכת
+שלכם (בדרך־כלל, ע"י הקלקה על הכפתור המסומן ב־"X" בפינה עליונה של
התבנית.) שום מידע אינו הולך לעיבוד כאשר סוגרים תבנית (או חלון). המידע
הזה פשוט יורד מהתצוגה, אבל ניתן לאחזרו מאוחר יותר.
כדי להחלץ מרמת עריכה רקורסיבית יש להקיש <ESC> <ESC> <ESC>. זוהי פקודה
כללית של "הימלטות". ניתן להשתמש בה גם כדי לסלק חלונות מיותרים וליציאה
-מתוך מיני-חוצץ.
+מתוך מיני־חוצץ.
->> הקישו M-x כדי להיכנס למיני-חוצץ; אחר-כך הקישו <ESC> <ESC> <ESC> כדי
+>> הקישו M-x כדי להיכנס למיני־חוצץ; אחר־כך הקישו <ESC> <ESC> <ESC> כדי
להיחלץ משם.
-הקשה על C-g לא תחלץ אתכם מרמות עריכה רקורסיביות. זאת, משום ש-C-g מבטל
+הקשה על C-g לא תחלץ אתכם מרמות עריכה רקורסיביות. זאת, משום ש־C-g מבטל
פקודות וארגומנטים _במסגרת_ הרמה הרקורסיבית, מבלי לצאת ממנה.
------------------
בשיעור הראשון הזה השתדלנו לתת בידיכם מידע שאך יספיק להתחלת השימוש שלכם
-ב-Emacs. Emacs מכיל כל-כך הרבה שאין שום אפשרות לתאר ולהסביר כאן את
+ב־Emacs. Emacs מכיל כל־כך הרבה שאין שום אפשרות לתאר ולהסביר כאן את
הכל. אולם, סביר שתרצו ללמוד יותר על Emacs שכן יש בו עוד הרבה תכונות
שימושיות. Emacs כולל פקודות לשם קריאת תיעוד על הפקודות של Emacs.
-הפעלת פקודות "עזרה" אלו תמיד מתחילה במקש CONTROL-h שעל-כן נקרא "מקש
+הפעלת פקודות "עזרה" אלו תמיד מתחילה במקש CONTROL-h שעל־כן נקרא "מקש
עזרה" ("help").
-להפעלת פקודות עזרה יש להקיש את C-h ואחר-כך עוד תו שמבקש עזרה מסוג
-מסויים. אם אתם _באמת_ אבודים, הקישו C-h ? ו-Emacs יציג את סוגי העזרה
+להפעלת פקודות עזרה יש להקיש את C-h ואחר־כך עוד תו שמבקש עזרה מסוג
+מסויים. אם אתם _באמת_ אבודים, הקישו C-h ? ו־Emacs יציג את סוגי העזרה
שהוא מעמיד לרשותכם. אם הקשתם C-h ובסופו של דבר החלטתם שאין צורך בשום
עזרה, פשוט הקישו C-g לבטל את הפקודה.
כתוצאה, יוצגו השם והתיעוד של הפונקציה בחלון Emacs נפרד. כשתסיימו לקרוא
את התיעוד, הקישו C-x 1 כדי לסלק את חלון העזרה. לא חייבים לעשות זאת
-מיד. אפשר לבצע קצת עריכה תוך שימוש בתיעוד המוצג ורק אחר-כך להקיש C-x 1.
+מיד. אפשר לבצע קצת עריכה תוך שימוש בתיעוד המוצג ורק אחר־כך להקיש C-x 1.
הנה עוד כמה פקודות עזרה שימושיות:
>> נסו להקיש C-h f previous-line <Return>.
כתוצאה, יוצג תיעוד מלא של הפונקציה המממשת את הפקודה C-p כפי שהוא
- ידוע ל-Emacs.
+ ידוע ל־Emacs.
פקודה דומה C-h v מציגה תיעוד של משתנה, כולל אלו שאת הערכים שלהם ניתן
לשנות כדי לקסטם את Emacs. יש להקיש את שם המשתנה כאשר Emacs יבקש זאת.
- C-h a פקודות בנוגע לנושא מסויים. הקישו מילת מפתח ו-Emacs
+ C-h a פקודות בנוגע לנושא מסויים. הקישו מילת מפתח ו־Emacs
יציג את רשימת הפקודות ששמותיהן מכילות את מילת המפתח.
כל הפקודות הללו ניתנות להפעלה ע"י META-x. עבור חלק
מהפקודות תוצג גם סדרת מקשים שמפעילה את הפקודה.
ידועה גם בשם "Info".) פקודה זאת פותחת חוצץ מיוחד הקרוי
"*info*" שבו תוכלו לקרוא מדריכים המותקנים במערכת שלכם.
הקישו m emacs <Return> כדי לקרוא במדריך למשתמשי Emacs.
- אם אינכם מכירים את Info, הקישו ? ו-Emacs יקח אתכם
+ אם אינכם מכירים את Info, הקישו ? ו־Emacs יקח אתכם
לשיעור על התכונות של Info mode. כשתסיימו עם השיעור
הזה, אנו בהחלט ממליצים להשתמש במדריך Emacs בתור התיעוד
העיקרי שלכם.
* עוד תכונות
------------
-תוכלו ללמוד עוד על-אודות Emacs ע"י קריאה במדריך למשתמש שלו, אם כספר
+תוכלו ללמוד עוד על־אודות Emacs ע"י קריאה במדריך למשתמש שלו, אם כספר
מודפס או בגירסה מקוונת בתוך Emacs עצמו. (תוכלו להגיע אל המדריך דרך
תפריט Help או ע"י הקשה על C-h r.) אולם שתי תכונות שבוודאי ימצאו חן
-בעיניכם הן השלמה אשר חוסכת הקשות, ו-dired שמאפשרת טיפול נוח בקבצים.
+בעיניכם הן השלמה אשר חוסכת הקשות, ו־dired שמאפשרת טיפול נוח בקבצים.
השלמה היא דרך להימנע מהקשות מיותרות. למשל, אם ברצונכם לעבור לחוצץ
-*Messages*, תוכלו להקיש C-x b *M<Tab> ו-Emacs ישלים את שאר האותיות של
+*Messages*, תוכלו להקיש C-x b *M<Tab> ו־Emacs ישלים את שאר האותיות של
שם החוצץ ככל שניתן להסיק ממה שהקשתם. השלמה פועלת גם על שמות הפקודות
ושמות קבצים. תכונת ההשלמה מתוארת במלואה במדריך למשתמש Emacs בצומת
(node) בשם "Completion".
* לסיום
-------
-כדי לצאת מ-Emacs יש להקיש C-x C-c.
+כדי לצאת מ־Emacs יש להקיש C-x C-c.
שיעור זה נכתב כדי להיות מובן לכל המשתמשים החדשים, לכן אם מצאתם שמשהו
כאן אינו ברור, אל תשבו ותאשימו את עצמכם -- תתלוננו!
* זכויות שימוש
--------------
-שיעור זה הינו צאצא של שורה ארוכה של שיעורים בשימוש ב-Emacs, החל מהגרסה
-הראשונה שנכתבה ע"י Stuart Cracraft עבור גירסת ה-Emacs המקורית.
+שיעור זה הינו צאצא של שורה ארוכה של שיעורים בשימוש ב־Emacs, החל מהגרסה
+הראשונה שנכתבה ע"י Stuart Cracraft עבור גירסת ה־Emacs המקורית.
גירסה זו של השיעור הינה חלק מחבילת GNU Emacs. היא מוגנת בזכויות יוצרים
וניתנת להעתקה והפצת עותקים בתנאים מסויימים כדלקמן:
בכל גרסא מאוחרת יותר.
GNU Emacs מופץ מתוך תקווה שהוא יביא תועלת, אולם ללא כל כתב אחריות;
-אפילו לא אחריות-במשתמע של סחירות או התאמה לאיזו תכלית מסוימת. לפרטים,
-אנא עיינו ב-GNU General Public License.
+אפילו לא אחריות־במשתמע של סחירות או התאמה לאיזו תכלית מסוימת. לפרטים,
+אנא עיינו ב־GNU General Public License.
GNU Emacs אמור להיות מלווה בעותק של GNU General Public License; אם לא
-קיבלתם אותו, תוכלו למצוא אותו ב-<http://www.gnu.org/licenses/>.
+קיבלתם אותו, תוכלו למצוא אותו ב־<http://www.gnu.org/licenses/>.
הנכם מוזמנים לקרוא את הקובץ COPYING ואז אכן לחלק עותקים של GNU Emacs
לחבריכם. עזרו לנו לחסל את "הבעלות" על תוכנה שאינה אלא חבלה בתוכנה,
+2010-08-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * files.el (locate-file-completion-table): Only list the .el and .elc
+ extensions if there's no other choice (bug#5955).
+
+ * facemenu.el (facemenu-self-insert-data): New var.
+ (facemenu-post-self-insert-function, facemenu-set-self-insert-face):
+ New functions.
+ (facemenu-add-face): Use them.
+
+ * simple.el (blink-matching-open): Obey forward-sexp-function.
+
+2010-08-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * simple.el (prog-mode-map): New var.
+ (prog-indent-sexp): New command.
+
+ * progmodes/octave-mod.el (octave-mode-menu): Make toggle buttons.
+
+ * progmodes/prolog.el (smie): Require.
+
+ * emacs-lisp/smie.el (smie-default-backward-token)
+ (smie-default-forward-token): Strip properties.
+ (smie-next-sexp): Be more careful with associative operators.
+ (smie-forward-sexp-command): Generalize.
+ (smie-backward-sexp-command): Simplify.
+ (smie-closer-alist): New var.
+ (smie-close-block): New command.
+ (smie-indent-debug-log): New var.
+ (smie-indent-offset-rule): Add a few more cases.
+ (smie-indent-column): New function.
+ (smie-indent-after-keyword): Use it.
+ (smie-indent-keyword): Use it.
+ Fix up the opener code's point position.
+ (smie-indent-comment): Only applies at BOL.
+ (smie-indent-debug): New command.
+
+ * emacs-lisp/autoload.el (make-autoload): Preload the macros's
+ declarations that are useful before running the macro.
+
+2010-08-18 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * image.el (create-animated-image): Don't add heuristic mask to image
+ (Bug#6839).
+
+2010-08-18 Jan Djärv <jan.h.d@swipnet.se>
+
+ * term/ns-win.el (ns-get-pasteboard, ns-set-pasteboard):
+ Use QCLIPBOARD instead of QPRIMARY (Bug#6677).
+
+2010-08-17 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * emacs-lisp/lisp.el (up-list): Obey forward-sexp-function if set.
+
+ Font-lock '...' strings, plus various simplifications and fixes.
+ * progmodes/octave-mod.el (octave-font-lock-keywords): Use regexp-opt.
+ (octave-font-lock-close-quotes): New function.
+ (octave-font-lock-syntactic-keywords): New var.
+ (octave-mode): Use it. Set beginning-of-defun-function.
+ (octave-mode-map): Don't override the <foo>-defun commands.
+ (octave-mode-menu): Pass it directly to easy-menu-define;
+ remove (now generic) <foo>-defun commands; use info-lookup-symbol.
+ (octave-block-match-alist): Fix up last change so that
+ octave-close-block uses the more specific keyword.
+ (info-lookup-mode): Silence byte-compiler.
+ (octave-beginning-of-defun): Not interactive any more.
+ Optimize slightly.
+ (octave-end-of-defun, octave-mark-defun, octave-in-defun-p): Remove.
+ (octave-indent-defun, octave-send-defun): Use mark-defun instead.
+ (octave-completion-at-point-function): Make sure point is within
+ beg..end.
+ (octave-reindent-then-newline-and-indent):
+ Use reindent-then-newline-and-indent.
+ (octave-add-octave-menu): Remove.
+
+2010-08-17 Jan Djärv <jan.h.d@swipnet.se>
+
+ * mail/emacsbug.el (report-emacs-bug-insert-to-mailer)
+ (report-emacs-bug-can-use-xdg-email): New functions.
+ (report-emacs-bug): Set can-xdg-email to result of
+ report-emacs-bug-can-use-xdg-email. If can-xdg-email bind
+ \C-cm to report-emacs-bug-insert-to-mailer and add help text
+ about it.
+
+ * net/browse-url.el (browse-url-default-browser): Add cond
+ for browse-url-xdg-open.
+ (browse-url-can-use-xdg-open, browse-url-xdg-open): New functions.
+
+2010-08-17 Glenn Morris <rgm@gnu.org>
+
+ * progmodes/cc-engine.el (c-new-BEG, c-new-END)
+ (c-fontify-recorded-types-and-refs): Define for compiler.
+ * progmodes/cc-mode.el (c-new-BEG, c-new-END): Move definitions
+ before use.
+
+ * calendar/icalendar.el (icalendar--convert-recurring-to-diary):
+ Fix format call.
+
+2010-08-17 Michael Albinus <michael.albinus@gmx.de>
+
+ * net/tramp.el (tramp-handle-make-symbolic-link): Flush file
+ properties.
+ (tramp-handle-process-file): Call the program in a subshell, in
+ order to preserve working directory.
+ (tramp-action-password): Hide password prompt before next run.
+ (tramp-process-actions): Widen connection buffer for the trace.
+
+2010-08-16 Deniz Dogan <deniz.a.m.dogan@gmail.com>
+
+ * net/rcirc.el (rcirc-log-process-buffers): New option.
+ (rcirc-print): Use it.
+ (rcirc-generate-log-filename): New function.
+ (rcirc-log-filename-function): Change default to
+ rcirc-generate-log-filename (Bug#6828).
+
+2010-08-16 Chong Yidong <cyd@stupidchicken.com>
+
+ * simple.el (deactivate-mark): If select-active-regions is `only',
+ only set selection for temporarily active regions.
+
+ * cus-start.el: Change defcustom for select-active-regions.
+
+2010-08-15 Chong Yidong <cyd@stupidchicken.com>
+
+ * mouse.el (mouse--drag-set-mark-and-point): New function.
+ (mouse-drag-track): Use LOCATION arg to push-mark.
+ Use mouse--drag-set-mark-and-point to take click-count into
+ consideration when updating point and mark (Bug#6840).
+
+2010-08-15 Chong Yidong <cyd@stupidchicken.com>
+
+ * progmodes/compile.el (compilation-error-regexp-alist-alist):
+ Give the Ruby rule a lower priority than Gnu (Bug#6778).
+
+2010-08-14 Štěpán Němec <stepnem@gmail.com> (tiny change)
+
+ * font-lock.el (lisp-font-lock-keywords-2):
+ Add combine-after-change-calls, condition-case-no-debug,
+ with-demoted-errors, and with-silent-modifications (Bug#6025).
+
+2010-08-14 Kevin Ryde <user42@zip.com.au>
+
+ * emacs-lisp/copyright.el (copyright-update-year)
+ (copyright-update): Temporary switch-to-buffer to ensure the
+ buffer change being queried is visible (Bug#5394).
+
+2010-08-14 Tom Tromey <tromey@redhat.com>
+
+ * progmodes/etags.el (tags-file-name): Mark safe if stringp
+ (Bug#6733).
+
+2010-08-14 Eli Zaretskii <eliz@gnu.org>
+
+ * mouse.el (mouse-yank-primary): Fix mouse-2 on MS-Windows and
+ MS-DOS. (Bug#6689)
+
+2010-08-13 Jan Djärv <jan.h.d@swipnet.se>
+
+ * menu-bar.el (menu-bar-set-tool-bar-position): New function.
+ (menu-bar-showhide-tool-bar-menu-customize-enable-left)
+ (menu-bar-showhide-tool-bar-menu-customize-enable-right)
+ (menu-bar-showhide-tool-bar-menu-customize-enable-top)
+ (menu-bar-showhide-tool-bar-menu-customize-enable-bottom):
+ Call menu-bar-set-tool-bar-position.
+
2010-08-12 Stefan Monnier <monnier@iro.umontreal.ca>
* progmodes/octave-mod.el (octave-mode-syntax-table): Use the new "c"
(format "(diary-cyclic %d %s) "
(* interval 7)
dtstart-conv))
+ dtstart-conv
(if count until-1-conv until-conv)
))
(setq result
(help-event-list keyboard (repeat (sexp :format "%v")))
(menu-prompting menu boolean)
(select-active-regions killing
- (choice (const :tag "lazy" lazy)
- (const :tag "always" t)
+ (choice (const :tag "always" t)
+ (const :tag "only shift-selection or mouse-drag" only)
(const :tag "off" nil))
"24.1")
(suggest-key-bindings keyboard (choice (const :tag "off" nil)
(let* ((macrop (memq car '(defmacro defmacro*)))
(name (nth 1 form))
(args (case car
- ((defun defmacro defun* defmacro*
- define-overloadable-function) (nth 2 form))
- ((define-skeleton) '(&optional str arg))
- ((define-generic-mode define-derived-mode
- define-compilation-mode) nil)
- (t)))
+ ((defun defmacro defun* defmacro*
+ define-overloadable-function) (nth 2 form))
+ ((define-skeleton) '(&optional str arg))
+ ((define-generic-mode define-derived-mode
+ define-compilation-mode) nil)
+ (t)))
(body (nthcdr (get car 'doc-string-elt) form))
(doc (if (stringp (car body)) (pop body))))
(when (listp args)
;; Add the usage form at the end where describe-function-1
;; can recover it.
(setq doc (help-add-fundoc-usage doc args)))
- ;; `define-generic-mode' quotes the name, so take care of that
- (list 'autoload (if (listp name) name (list 'quote name)) file doc
- (or (and (memq car '(define-skeleton define-derived-mode
- define-generic-mode
- easy-mmode-define-global-mode
- define-global-minor-mode
- define-globalized-minor-mode
- easy-mmode-define-minor-mode
- define-minor-mode)) t)
- (eq (car-safe (car body)) 'interactive))
- (if macrop (list 'quote 'macro) nil))))
+ (let ((exp
+ ;; `define-generic-mode' quotes the name, so take care of that
+ (list 'autoload (if (listp name) name (list 'quote name))
+ file doc
+ (or (and (memq car '(define-skeleton define-derived-mode
+ define-generic-mode
+ easy-mmode-define-global-mode
+ define-global-minor-mode
+ define-globalized-minor-mode
+ easy-mmode-define-minor-mode
+ define-minor-mode)) t)
+ (eq (car-safe (car body)) 'interactive))
+ (if macrop (list 'quote 'macro) nil))))
+ (when macrop
+ ;; Special case to autoload some of the macro's declarations.
+ (let ((decls (nth (if (stringp (nth 3 form)) 4 3) form))
+ (exps '()))
+ (when (eq (car decls) 'declare)
+ ;; FIXME: We'd like to reuse macro-declaration-function,
+ ;; but we can't since it doesn't return anything.
+ (dolist (decl decls)
+ (case (car-safe decl)
+ (indent
+ (push `(put ',name 'lisp-indent-function ',(cadr decl))
+ exps))
+ (doc-string
+ (push `(put ',name 'doc-string-elt ',(cadr decl)) exps))))
+ (when exps
+ (setq exp `(progn ,exp ,@exps))))))
+ exp)))
;; For defclass forms, use `eieio-defclass-autoload'.
((eq car 'defclass)
(unless (string= (buffer-substring (- (match-end 3) 2) (match-end 3))
(substring copyright-current-year -2))
(if (or noquery
- ;; Fixes some point-moving oddness (bug#2209).
- (save-excursion
- (y-or-n-p (if replace
- (concat "Replace copyright year(s) by "
- copyright-current-year "? ")
- (concat "Add " copyright-current-year
- " to copyright? ")))))
+ (save-window-excursion
+ (switch-to-buffer (current-buffer))
+ ;; Fixes some point-moving oddness (bug#2209).
+ (save-excursion
+ (y-or-n-p (if replace
+ (concat "Replace copyright year(s) by "
+ copyright-current-year "? ")
+ (concat "Add " copyright-current-year
+ " to copyright? "))))))
(if replace
(replace-match copyright-current-year t t nil 3)
(let ((size (save-excursion (skip-chars-backward "0-9"))))
(string-to-number copyright-current-gpl-version))
(or noquery
(save-match-data
- (y-or-n-p (format "Replace GPL version by %s? "
- copyright-current-gpl-version))))
+ (save-window-excursion
+ (switch-to-buffer (current-buffer))
+ (y-or-n-p (format "Replace GPL version by %s? "
+ copyright-current-gpl-version)))))
(progn
(if (match-end 2)
;; Esperanto bilingual comment in two-column.el
(or arg (setq arg 1))
(let ((inc (if (> arg 0) 1 -1)))
(while (/= arg 0)
- (goto-char (or (scan-lists (point) inc 1) (buffer-end arg)))
+ (if forward-sexp-function
+ (condition-case err
+ (while (let ((pos (point)))
+ (forward-sexp inc)
+ (/= (point) pos)))
+ (scan-error (goto-char (nth 2 err))))
+ (goto-char (or (scan-lists (point) inc 1) (buffer-end arg))))
(setq arg (- arg inc)))))
(defun kill-sexp (&optional arg)
;;; Code:
+;; FIXME: I think the behavior on empty lines is wrong. It shouldn't
+;; look at the next token on subsequent lines.
+
(eval-when-compile (require 'cl))
(defvar comment-continue)
(if (not (member (car shr) nts))
(pushnew (car shr) last-ops)
(pushnew (car shr) last-nts)
- (when (consp (cdr shr))
- (assert (not (member (cadr shr) nts)))
- (pushnew (cadr shr) last-ops)))))
+ (when (consp (cdr shr))
+ (assert (not (member (cadr shr) nts)))
+ (pushnew (cadr shr) last-ops)))))
(push (cons nt first-ops) first-ops-table)
(push (cons nt last-ops) last-ops-table)
(push (cons nt first-nts) first-nts-table)
prec2))
(defun smie-prec2-levels (prec2)
+ ;; FIXME: Rather than only return an alist of precedence levels, we should
+ ;; also extract other useful data from it:
+ ;; - matching sets of block openers&closers (which can otherwise become
+ ;; collapsed into a single equivalence class in smie-op-levels) for
+ ;; smie-close-block as well as to detect mismatches in smie-next-sexp
+ ;; or in blink-paren (as well as to do the blink-paren for inner
+ ;; keywords like the "in" of "let..in..end").
+ ;; - better default indentation rules (i.e. non-zero indentation after inner
+ ;; keywords like the "in" of "let..in..end") for smie-indent-after-keyword.
+ ;; Of course, maybe those things would be even better handled in the
+ ;; bnf->prec function.
"Take a 2D precedence table and turn it into an alist of precedence levels.
PREC2 is a table as returned by `smie-precs-precedence-table' or
`smie-bnf-precedence-table'."
;; distinguish associative operators (which will have
;; left = right).
(unless (caar cst)
- (setcar (car cst) i)
+ (setcar (car cst) i)
(incf i))
(setq csts (delq cst csts))))
(unless progress
(defun smie-default-backward-token ()
(forward-comment (- (point)))
- (buffer-substring (point)
- (progn (if (zerop (skip-syntax-backward "."))
- (skip-syntax-backward "w_'"))
- (point))))
+ (buffer-substring-no-properties
+ (point)
+ (progn (if (zerop (skip-syntax-backward "."))
+ (skip-syntax-backward "w_'"))
+ (point))))
(defun smie-default-forward-token ()
(forward-comment (point-max))
- (buffer-substring (point)
- (progn (if (zerop (skip-syntax-forward "."))
- (skip-syntax-forward "w_'"))
- (point))))
+ (buffer-substring-no-properties
+ (point)
+ (progn (if (zerop (skip-syntax-forward "."))
+ (skip-syntax-forward "w_'"))
+ (point))))
(defun smie-associative-p (toklevels)
;; in "a + b + c" we want to stop at each +, but in
- ;; "if a then b else c" we don't want to stop at each keyword.
+ ;; "if a then b elsif c then d else c" we don't want to stop at each keyword.
;; To distinguish the two cases, we made smie-prec2-levels choose
;; different levels for each part of "if a then b else c", so that
;; by checking if the left-level is equal to the right level, we can
;; figure out that it's an associative operator.
- ;; This is not 100% foolproof, tho, since a grammar like
- ;; (exp ("A" exp "C") ("A" exp "B" exp "C"))
- ;; will cause "B" to have equal left and right levels, even though
- ;; it is not an associative operator.
- ;; A better check would be the check the actual previous operator
- ;; against this one to see if it's the same, but we'd have to change
- ;; `levels' to keep a stack of operators rather than only levels.
+ ;; This is not 100% foolproof, tho, since the "elsif" will have to have
+ ;; equal left and right levels (since it's optional), so smie-next-sexp
+ ;; has to be careful to distinguish those different cases.
(eq (smie-op-left toklevels) (smie-op-right toklevels)))
(defun smie-next-sexp (next-token next-sexp op-forw op-back halfsexp)
(let* ((pos (point))
(token (funcall next-token))
(toklevels (cdr (assoc token smie-op-levels))))
-
(cond
((null toklevels)
(when (zerop (length token))
- (condition-case err
- (progn (goto-char pos) (funcall next-sexp 1) nil)
- (scan-error (throw 'return (list t (caddr err)))))
+ (condition-case err
+ (progn (goto-char pos) (funcall next-sexp 1) nil)
+ (scan-error (throw 'return
+ (list t (caddr err)
+ (buffer-substring-no-properties
+ (caddr err)
+ (+ (caddr err)
+ (if (< (point) (caddr err))
+ -1 1)))))))
(if (eq pos (point))
;; We did not move, so let's abort the loop.
(throw 'return (list t (point))))))
((null (funcall op-back toklevels))
;; A token like a paren-close.
(assert (funcall op-forw toklevels)) ;Otherwise, why mention it?
- (push (funcall op-forw toklevels) levels))
+ (push toklevels levels))
(t
- (while (and levels (< (funcall op-back toklevels) (car levels)))
+ (while (and levels (< (funcall op-back toklevels)
+ (funcall op-forw (car levels))))
(setq levels (cdr levels)))
(cond
((null levels)
(if (and halfsexp (funcall op-forw toklevels))
- (push (funcall op-forw toklevels) levels)
+ (push toklevels levels)
(throw 'return
(prog1 (list (or (car toklevels) t) (point) token)
(goto-char pos)))))
(t
- (if (and levels (= (funcall op-back toklevels) (car levels)))
- (setq levels (cdr levels)))
- (cond
- ((null levels)
+ (let ((lastlevels levels))
+ (if (and levels (= (funcall op-back toklevels)
+ (funcall op-forw (car levels))))
+ (setq levels (cdr levels)))
+ ;; We may have found a match for the previously pending
+ ;; operator. Is this the end?
(cond
+ ;; Keep looking as long as we haven't matched the
+ ;; topmost operator.
+ (levels
+ (if (funcall op-forw toklevels)
+ (push toklevels levels)))
+ ;; We matched the topmost operator. If the new operator
+ ;; is the last in the corresponding BNF rule, we're done.
((null (funcall op-forw toklevels))
+ ;; It is the last element, let's stop here.
(throw 'return (list nil (point) token)))
- ((smie-associative-p toklevels)
+ ;; If the new operator is not the last in the BNF rule,
+ ;; ans is not associative, it's one of the inner operators
+ ;; (like the "in" in "let .. in .. end"), so keep looking.
+ ((not (smie-associative-p toklevels))
+ (push toklevels levels))
+ ;; The new operator is associative. Two cases:
+ ;; - it's really just an associative operator (like + or ;)
+ ;; in which case we should have stopped right before.
+ ((and lastlevels
+ (smie-associative-p (car lastlevels)))
(throw 'return
(prog1 (list (or (car toklevels) t) (point) token)
(goto-char pos))))
- ;; We just found a match to the previously pending operator
- ;; but this new operator is still part of a larger RHS.
- ;; E.g. we're now looking at the "then" in
- ;; "if a then b else c". So we have to keep parsing the
- ;; rest of the construct.
- (t (push (funcall op-forw toklevels) levels))))
- (t
- (if (funcall op-forw toklevels)
- (push (funcall op-forw toklevels) levels))))))))
+ ;; - it's an associative operator within a larger construct
+ ;; (e.g. an "elsif"), so we should just ignore it and keep
+ ;; looking for the closing element.
+ (t (setq levels lastlevels))))))))
levels)
(setq halfsexp nil)))))
(t POS TOKEN): same thing but for an open-paren or the beginning of buffer.
(nil POS TOKEN): we skipped over a paren-like pair.
nil: we skipped over an identifier, matched parentheses, ..."
- (smie-next-sexp
- (indirect-function smie-backward-token-function)
- (indirect-function 'backward-sexp)
- (indirect-function 'smie-op-left)
- (indirect-function 'smie-op-right)
+ (smie-next-sexp
+ (indirect-function smie-backward-token-function)
+ (indirect-function 'backward-sexp)
+ (indirect-function 'smie-op-left)
+ (indirect-function 'smie-op-right)
halfsexp))
(defun smie-forward-sexp (&optional halfsexp)
(t POS TOKEN): same thing but for an open-paren or the beginning of buffer.
(nil POS TOKEN): we skipped over a paren-like pair.
nil: we skipped over an identifier, matched parentheses, ..."
- (smie-next-sexp
- (indirect-function smie-forward-token-function)
- (indirect-function 'forward-sexp)
- (indirect-function 'smie-op-right)
- (indirect-function 'smie-op-left)
+ (smie-next-sexp
+ (indirect-function smie-forward-token-function)
+ (indirect-function 'forward-sexp)
+ (indirect-function 'smie-op-right)
+ (indirect-function 'smie-op-left)
halfsexp))
+;;; Miscellanous commands using the precedence parser.
+
(defun smie-backward-sexp-command (&optional n)
"Move backward through N logical elements."
- (interactive "p")
- (if (< n 0)
- (smie-forward-sexp-command (- n))
- (let ((forward-sexp-function nil))
- (while (> n 0)
- (decf n)
- (let ((pos (point))
- (res (smie-backward-sexp 'halfsexp)))
- (if (and (car res) (= pos (point)) (not (bolp)))
- (signal 'scan-error
- (list "Containing expression ends prematurely"
- (cadr res) (cadr res)))
- nil))))))
+ (interactive "^p")
+ (smie-forward-sexp-command (- n)))
(defun smie-forward-sexp-command (&optional n)
"Move forward through N logical elements."
- (interactive "p")
- (if (< n 0)
- (smie-backward-sexp-command (- n))
- (let ((forward-sexp-function nil))
- (while (> n 0)
- (decf n)
- (let ((pos (point))
- (res (smie-forward-sexp 'halfsexp)))
- (if (and (car res) (= pos (point)) (not (bolp)))
- (signal 'scan-error
- (list "Containing expression ends prematurely"
- (cadr res) (cadr res)))
- nil))))))
+ (interactive "^p")
+ (let ((forw (> n 0))
+ (forward-sexp-function nil))
+ (while (/= n 0)
+ (setq n (- n (if forw 1 -1)))
+ (let ((pos (point))
+ (res (if forw
+ (smie-forward-sexp 'halfsexp)
+ (smie-backward-sexp 'halfsexp))))
+ (if (and (car res) (= pos (point)) (not (if forw (eobp) (bobp))))
+ (signal 'scan-error
+ (list "Containing expression ends prematurely"
+ (cadr res) (cadr res)))
+ nil)))))
+
+(defvar smie-closer-alist nil
+ "Alist giving the closer corresponding to an opener.")
+
+(defun smie-close-block ()
+ "Close the closest surrounding block."
+ (interactive)
+ (let ((closer
+ (save-excursion
+ (backward-up-list 1)
+ (if (looking-at "\\s(")
+ (string (cdr (syntax-after (point))))
+ (let* ((open (funcall smie-forward-token-function))
+ (closer (cdr (assoc open smie-closer-alist)))
+ (levels (list (assoc open smie-op-levels)))
+ (seen '())
+ (found '()))
+ (cond
+ ;; Even if we improve the auto-computation of closers,
+ ;; there are still cases where we need manual
+ ;; intervention, e.g. for Octave's use of `until'
+ ;; as a pseudo-closer of `do'.
+ (closer)
+ ((or (equal levels '(nil)) (nth 1 (car levels)))
+ (error "Doesn't look like a block"))
+ (t
+ ;; FIXME: With grammars like Octave's, every closer ("end",
+ ;; "endif", "endwhile", ...) has the same level, so we'd need
+ ;; to look at the BNF or at least at the 2D prec-table, in
+ ;; order to find the right closer for a given opener.
+ (while levels
+ (let ((level (pop levels)))
+ (dolist (other smie-op-levels)
+ (when (and (eq (nth 2 level) (nth 1 other))
+ (not (memq other seen)))
+ (push other seen)
+ (if (nth 2 other)
+ (push other levels)
+ (push (car other) found))))))
+ (cond
+ ((null found) (error "No known closer for opener %s" open))
+ ;; FIXME: what should we do if there are various closers?
+ (t (car found))))))))))
+ (unless (save-excursion (skip-chars-backward " \t") (bolp))
+ (newline))
+ (insert closer)
+ (if (save-excursion (skip-chars-forward " \t") (eolp))
+ (indent-according-to-mode)
+ (reindent-then-newline-and-indent))))
;;; The indentation engine.
"Rules of the following form.
\((:before . TOK) . OFFSET-RULES) how to indent TOK itself.
\(TOK . OFFSET-RULES) how to indent right after TOK.
-\((T1 . T2) . OFFSET) how to indent token T2 w.r.t T1.
-\((t . TOK) . OFFSET) how to indent TOK with respect to its parent.
\(list-intro . TOKENS) declare TOKENS as being followed by what may look like
a funcall but is just a sequence of expressions.
\(t . OFFSET) basic indentation step.
\(args . OFFSET) indentation of arguments.
+\((T1 . T2) OFFSET) like ((:before . T2) (:parent T1 OFFSET)).
OFFSET-RULES is a list of elements which can each either be:
\(:hanging . OFFSET-RULES) if TOK is hanging, use OFFSET-RULES.
\(:parent PARENT . OFFSET-RULES) if TOK's parent is PARENT, use OFFSET-RULES.
\(:next TOKEN . OFFSET-RULES) if TOK is followed by TOKEN, use OFFSET-RULES.
-\(:prev TOKEN . OFFSET-RULES) if TOK is preceded by TOKEN, use OFFSET-RULES.
-a number the offset to use.
+\(:prev TOKEN . OFFSET-RULES) if TOK is preceded by TOKEN, use
+\(:bolp . OFFSET-RULES) If TOK is first on a line, use OFFSET-RULES.
+OFFSET the offset to use.
+
+PARENT can be either the name of the parent or `open' to mean any parent
+which acts as an open-paren (i.e. has a nil left-precedence).
+
+OFFSET can be of the form:
`point' align with the token.
`parent' align with the parent.
+NUMBER offset by NUMBER.
+\(+ OFFSETS...) use the sum of OFFSETS.
+
+The precise meaning of `point' depends on various details: it can
+either mean the position of the token we're indenting, or the
+position of its parent, or the position right after its parent.
A nil offset for indentation after a token defaults to `smie-indent-basic'.")
(cdr (assq t smie-indent-rules))
smie-indent-basic))
-(defun smie-indent-offset-rule (tokinfo &optional after)
+(defvar smie-indent-debug-log)
+
+(defun smie-indent-offset-rule (tokinfo &optional after parent)
"Apply the OFFSET-RULES in TOKINFO.
Point is expected to be right in front of the token corresponding to TOKINFO.
If computing the indentation after the token, then AFTER is the position
-after the token."
+after the token, otherwise it should be nil.
+PARENT if non-nil should be the parent info returned by `smie-backward-sexp'."
(let ((rules (cdr tokinfo))
- parent next prev
+ next prev
offset)
(while (consp rules)
(let ((rule (pop rules)))
(cond
((not (consp rule)) (setq offset rule))
+ ((eq (car rule) '+) (setq offset rule))
((eq (car rule) :hanging)
(when (smie-indent-hanging-p)
(setq rules (cdr rule))))
+ ((eq (car rule) :bolp)
+ (when (smie-bolp)
+ (setq rules (cdr rule))))
+ ((eq (car rule) :eolp)
+ (unless after
+ (error "Can't use :eolp in :before indentation rules"))
+ (when (> after (line-end-position))
+ (setq rules (cdr rule))))
((eq (car rule) :prev)
(unless prev
(save-excursion
(save-excursion
(if after (goto-char after))
(setq parent (smie-backward-sexp 'halfsexp))))
- (when (equal (nth 2 parent) (cadr rule))
+ (when (or (equal (nth 2 parent) (cadr rule))
+ (and (eq (cadr rule) 'open) (null (car parent))))
(setq rules (cddr rule))))
(t (error "Unknown rule %s for indentation of %s"
rule (car tokinfo))))))
+ ;; If `offset' is not set yet, use `rules' to handle the case where
+ ;; the tokinfo uses the old-style ((PARENT . TOK). OFFSET).
+ (unless offset (setq offset rules))
+ (when (boundp 'smie-indent-debug-log)
+ (push (list (point) offset tokinfo) smie-indent-debug-log))
offset))
+(defun smie-indent-column (offset &optional base parent virtual-point)
+ "Compute the actual column to use for a given OFFSET.
+BASE is the base position to use, and PARENT is the parent info, if any.
+If VIRTUAL-POINT is non-nil, then `point' is virtual."
+ (cond
+ ((eq (car-safe offset) '+)
+ (apply '+ (mapcar (lambda (offset) (smie-indent-column offset nil parent))
+ (cdr offset))))
+ ((integerp offset)
+ (+ offset
+ (case base
+ ((nil) 0)
+ (parent (goto-char (cadr parent))
+ (smie-indent-virtual))
+ (t
+ (goto-char base)
+ ;; For indentation after "(let" in SML-mode, we end up accumulating
+ ;; the offset of "(" and the offset of "let", so we use `min' to try
+ ;; and get it right either way.
+ (min (smie-indent-virtual) (current-column))))))
+ ((eq offset 'point)
+ ;; In indent-keyword, if we're indenting `then' wrt `if', we want to use
+ ;; indent-virtual rather than use just current-column, so that we can
+ ;; apply the (:before . "if") rule which does the "else if" dance in SML.
+ ;; But in other cases, we do not want to use indent-virtual
+ ;; (e.g. indentation of "*" w.r.t "+", or ";" wrt "("). We could just
+ ;; always use indent-virtual and then have indent-rules say explicitly
+ ;; to use `point' after things like "(" or "+" when they're not at EOL,
+ ;; but you'd end up with lots of those rules.
+ ;; So we use a heuristic here, which is that we only use virtual if
+ ;; the parent is tightly linked to the child token (they're part of
+ ;; the same BNF rule).
+ (if (and virtual-point (null (car parent))) ;Black magic :-(
+ (smie-indent-virtual) (current-column)))
+ ((eq offset 'parent)
+ (unless parent
+ (setq parent (or (smie-backward-sexp 'halfsexp) :notfound)))
+ (if (consp parent) (goto-char (cadr parent)))
+ (smie-indent-virtual))
+ ((eq offset nil) nil)
+ (t (error "Unknown indentation offset %s" offset))))
+
(defun smie-indent-forward-token ()
"Skip token forward and return it, along with its levels."
(let ((tok (funcall smie-forward-token-function)))
;; Obey the `fixindent' special comment.
(and (smie-bolp)
(save-excursion
- (comment-normalize-vars)
- (re-search-forward (concat comment-start-skip
- "fixindent"
- comment-end-skip)
- ;; 1+ to account for the \n comment termination.
- (1+ (line-end-position)) t))
- (current-column)))
+ (comment-normalize-vars)
+ (re-search-forward (concat comment-start-skip
+ "fixindent"
+ comment-end-skip)
+ ;; 1+ to account for the \n comment termination.
+ (1+ (line-end-position)) t))
+ (current-column)))
(defun smie-indent-bob ()
;; Start the file at column 0.
(toklevels (smie-indent-forward-token))
(token (pop toklevels)))
(if (null (car toklevels))
- ;; Different case:
- ;; - smie-bolp: "indent according to others".
- ;; - common hanging: "indent according to others".
- ;; - SML-let hanging: "indent like parent".
- ;; - if-after-else: "indent-like parent".
- ;; - middle-of-line: "trust current position".
- (cond
- ((null (cdr toklevels)) nil) ;Not a keyword.
- ((smie-bolp)
- ;; For an open-paren-like thingy at BOL, always indent only
- ;; based on other rules (typically smie-indent-after-keyword).
- nil)
- (t
- (let* ((tokinfo (or (assoc (cons :before token) smie-indent-rules)
- ;; By default use point unless we're hanging.
- (cons (cons :before token)
- '((:hanging nil) point))))
- (after (prog1 (point) (goto-char pos)))
- (offset (smie-indent-offset-rule tokinfo)))
- (cond
- ((eq offset 'point) (current-column))
- ((eq offset 'parent)
- (let ((parent (smie-backward-sexp 'halfsexp)))
- (if parent (goto-char (cadr parent))))
- (smie-indent-virtual))
- ((eq offset nil) nil)
- (t (error "Unhandled offset %s in %s"
- offset (cons :before token)))))))
+ (save-excursion
+ (goto-char pos)
+ ;; Different cases:
+ ;; - smie-bolp: "indent according to others".
+ ;; - common hanging: "indent according to others".
+ ;; - SML-let hanging: "indent like parent".
+ ;; - if-after-else: "indent-like parent".
+ ;; - middle-of-line: "trust current position".
+ (cond
+ ((null (cdr toklevels)) nil) ;Not a keyword.
+ ((smie-bolp)
+ ;; For an open-paren-like thingy at BOL, always indent only
+ ;; based on other rules (typically smie-indent-after-keyword).
+ nil)
+ (t
+ ;; We're only ever here for virtual-indent, which is why
+ ;; we can use (current-column) as answer for `point'.
+ (let* ((tokinfo (or (assoc (cons :before token)
+ smie-indent-rules)
+ ;; By default use point unless we're hanging.
+ `((:before . ,token) (:hanging nil) point)))
+ ;; (after (prog1 (point) (goto-char pos)))
+ (offset (smie-indent-offset-rule tokinfo)))
+ (smie-indent-column offset)))))
;; FIXME: This still looks too much like black magic!!
;; FIXME: Rather than a bunch of rules like (PARENT . TOKEN), we
;; want a single rule for TOKEN with different cases for each PARENT.
- (let ((res (smie-backward-sexp 'halfsexp)) tmp)
+ (let* ((parent (smie-backward-sexp 'halfsexp))
+ (tokinfo
+ (or (assoc (cons (caddr parent) token)
+ smie-indent-rules)
+ (assoc (cons :before token) smie-indent-rules)
+ ;; Default rule.
+ `((:before . ,token)
+ ;; (:parent open 0)
+ point)))
+ (offset (save-excursion
+ (goto-char pos)
+ (smie-indent-offset-rule tokinfo nil parent))))
+ ;; Different behaviors:
+ ;; - align with parent.
+ ;; - parent + offset.
+ ;; - after parent's column + offset (actually, after or before
+ ;; depending on where backward-sexp stopped).
+ ;; ? let it drop to some other indentation function (almost never).
+ ;; ? parent + offset + parent's own offset.
+ ;; Different cases:
+ ;; - bump into a same-level operator.
+ ;; - bump into a specific known parent.
+ ;; - find a matching open-paren thingy.
+ ;; - bump into some random parent.
+ ;; ? borderline case (almost never).
+ ;; ? bump immediately into a parent.
(cond
((not (or (< (point) pos)
- (and (cadr res) (< (cadr res) pos))))
+ (and (cadr parent) (< (cadr parent) pos))))
;; If we didn't move at all, that means we didn't really skip
- ;; what we wanted.
+ ;; what we wanted. Should almost never happen, other than
+ ;; maybe when an infix or close-paren is at the beginning
+ ;; of a buffer.
nil)
- ((eq (car res) (car toklevels))
+ ((eq (car parent) (car toklevels))
;; We bumped into a same-level operator. align with it.
- (goto-char (cadr res))
- ;; Don't use (smie-indent-virtual :not-hanging) here, because we
- ;; want to jump back over a sequence of same-level ops such as
- ;; a -> b -> c
- ;; -> d
- ;; So as to align with the earliest appropriate place.
- (smie-indent-virtual))
- ((setq tmp (assoc (cons (caddr res) token)
- smie-indent-rules))
- (goto-char (cadr res))
- (+ (cdr tmp) (smie-indent-virtual))) ;:not-hanging
- ;; FIXME: The rules ((t . TOK) . OFFSET) either indent
- ;; relative to "before the parent" or "after the parent",
- ;; depending on details of the grammar.
- ((null (car res))
- (assert (eq (point) (cadr res)))
- (goto-char (cadr res))
- (+ (or (cdr (assoc (cons t token) smie-indent-rules)) 0)
- (smie-indent-virtual))) ;:not-hanging
- ((and (= (point) pos) (smie-bolp))
- ;; Since we started at BOL, we're not computing a virtual
- ;; indentation, and we're still at the starting point, so the
- ;; next (default) rule can't be used since it uses `current-column'
- ;; which would cause. indentation to depend on itself.
- ;; We could just return nil, but OTOH that's not good enough in
- ;; some cases. Instead, we want to combine the offset-rules for
- ;; the current token with the offset-rules of the previous one.
- (+ (or (cdr (assoc (cons t token) smie-indent-rules)) 0)
- ;; FIXME: This is odd. Can't we make it use
- ;; smie-indent-(calculate|virtual) somehow?
- (smie-indent-after-keyword)))
- (t
- (+ (or (cdr (assoc (cons t token) smie-indent-rules)) 0)
- (current-column)))))))))
+ (if (and (smie-bolp) (/= (point) pos)
+ (save-excursion
+ (goto-char (goto-char (cadr parent)))
+ (not (smie-bolp)))
+ ;; Check the offset of `token' rather then its parent
+ ;; because its parent may have used a special rule. E.g.
+ ;; function foo;
+ ;; line2;
+ ;; line3;
+ ;; The ; on the first line had a special rule, but when
+ ;; indenting line3, we don't care about it and want to
+ ;; align with line2.
+ (memq offset '(point nil)))
+ ;; If the parent is at EOL and its children are indented like
+ ;; itself, then we can just obey the indentation chosen for the
+ ;; child.
+ ;; This is important for operators like ";" which
+ ;; are usually at EOL (and have an offset of 0): otherwise we'd
+ ;; always go back over all the statements, which is
+ ;; a performance problem and would also mean that fixindents
+ ;; in the middle of such a sequence would be ignored.
+ ;;
+ ;; This is a delicate point!
+ ;; Even if the offset is not 0, we could follow the same logic
+ ;; and subtract the offset from the child's indentation.
+ ;; But that would more often be a bad idea: OT1H we generally
+ ;; want to reuse the closest similar indentation point, so that
+ ;; the user's choice (or the fixindents) are obeyed. But OTOH
+ ;; we don't want this to affect "unrelated" parts of the code.
+ ;; E.g. a fixindent in the body of a "begin..end" should not
+ ;; affect the indentation of the "end".
+ (current-column)
+ (goto-char (cadr parent))
+ ;; Don't use (smie-indent-virtual :not-hanging) here, because we
+ ;; want to jump back over a sequence of same-level ops such as
+ ;; a -> b -> c
+ ;; -> d
+ ;; So as to align with the earliest appropriate place.
+ (smie-indent-virtual)))
+ (tokinfo
+ (if (and (= (point) pos) (smie-bolp)
+ (or (eq offset 'point)
+ (and (consp offset) (memq 'point offset))))
+ ;; Since we started at BOL, we're not computing a virtual
+ ;; indentation, and we're still at the starting point, so
+ ;; we can't use `current-column' which would cause
+ ;; indentation to depend on itself.
+ nil
+ (smie-indent-column offset 'parent parent
+ ;; If we're still at pos, indent-virtual
+ ;; will inf-loop.
+ (unless (= (point) pos) 'virtual))))))))))
(defun smie-indent-comment ()
- ;; Indentation of a comment.
- (and (looking-at comment-start-skip)
+ "Compute indentation of a comment."
+ ;; Don't do it for virtual indentations. We should normally never be "in
+ ;; front of a comment" when doing virtual-indentation anyway. And if we are
+ ;; (as can happen in octave-mode), moving forward can lead to inf-loops.
+ (and (smie-bolp)
+ (looking-at comment-start-skip)
(save-excursion
(forward-comment (point-max))
(skip-chars-forward " \t\r\n")
(comment-string-strip comment-continue t t))))
(and (< 0 (length continue))
(looking-at (regexp-quote continue)) (nth 4 (syntax-ppss))
- (let ((ppss (syntax-ppss)))
- (save-excursion
- (forward-line -1)
- (if (<= (point) (nth 8 ppss))
- (progn (goto-char (1+ (nth 8 ppss))) (current-column))
- (skip-chars-forward " \t")
+ (let ((ppss (syntax-ppss)))
+ (save-excursion
+ (forward-line -1)
+ (if (<= (point) (nth 8 ppss))
+ (progn (goto-char (1+ (nth 8 ppss))) (current-column))
+ (skip-chars-forward " \t")
(if (looking-at (regexp-quote continue))
(current-column))))))))
(toklevel (smie-indent-backward-token))
(tok (car toklevel))
(tokinfo (assoc tok smie-indent-rules)))
+ ;; Set some default indent rules.
(if (and toklevel (null (cadr toklevel)) (null tokinfo))
(setq tokinfo (list (car toklevel))))
;; (if (and tokinfo (null toklevel))
;; (error "Token %S has indent rule but has no parsing info" tok))
(when toklevel
+ (unless tokinfo
+ ;; The default indentation after a keyword/operator is 0 for
+ ;; infix and t for prefix.
+ ;; Using the BNF syntax, we could come up with better
+ ;; defaults, but we only have the precedence levels here.
+ (setq tokinfo (list tok 'default-rule
+ (if (cadr toklevel) 0 (smie-indent-offset t)))))
(let ((offset
- (cond
- (tokinfo (or (smie-indent-offset-rule tokinfo pos)
- (smie-indent-offset t)))
- ;; The default indentation after a keyword/operator
- ;; is 0 for infix and t for prefix.
- ;; Using the BNF syntax, we could come up with
- ;; better defaults, but we only have the
- ;; precedence levels here.
- ((null (cadr toklevel)) (smie-indent-offset t))
- (t 0))))
- ;; For indentation after "(let" in SML-mode, we end up accumulating
- ;; the offset of "(" and the offset of "let", so we use `min' to try
- ;; and get it right either way.
- (+ (min (smie-indent-virtual) (current-column)) offset))))))
+ (or (smie-indent-offset-rule tokinfo pos)
+ (smie-indent-offset t))))
+ (let ((before (point)))
+ (goto-char pos)
+ (smie-indent-column offset before)))))))
(defun smie-indent-exps ()
;; Indentation of sequences of simple expressions without
(defvar smie-indent-functions
'(smie-indent-fixindent smie-indent-bob smie-indent-close smie-indent-comment
- smie-indent-comment-continue smie-indent-keyword smie-indent-after-keyword
- smie-indent-exps)
+ smie-indent-comment-continue smie-indent-keyword smie-indent-after-keyword
+ smie-indent-exps)
"Functions to compute the indentation.
Each function is called with no argument, shouldn't move point, and should
return either nil if it has no opinion, or an integer representing the column
"Indent current line using the SMIE indentation engine."
(interactive)
(let* ((savep (point))
- (indent (condition-case nil
+ (indent (condition-case-no-debug nil
(save-excursion
(forward-line 0)
(skip-chars-forward " \t")
(save-excursion (indent-line-to indent))
(indent-line-to indent)))))
-;;;###autoload
+(defun smie-indent-debug ()
+ "Show the rules used to compute indentation of current line."
+ (interactive)
+ (let ((smie-indent-debug-log '()))
+ (smie-indent-calculate)
+ ;; FIXME: please improve!
+ (message "%S" smie-indent-debug-log)))
+
(defun smie-setup (op-levels indent-rules)
(set (make-local-variable 'smie-indent-rules) indent-rules)
(set (make-local-variable 'smie-op-levels) op-levels)
+2010-08-14 Vivek Dasmohapatra <vivek@etla.org>
+
+ * erc-join.el (erc-autojoin-timing, erc-autojoin-delay): New vars.
+ (erc-autojoin-channels-delayed, erc-autojoin-after-ident): New
+ functions.
+ (erc-autojoin-channels): Allow autojoining after ident (Bug#5521).
+
2010-08-08 Fran Litterio <flitterio@gmail.com>
* erc-backend.el (erc-server-filter-function): Call
(define-erc-module autojoin nil
"Makes ERC autojoin on connects and reconnects."
((add-hook 'erc-after-connect 'erc-autojoin-channels)
+ (add-hook 'erc-nickserv-identified-hook 'erc-autojoin-after-ident)
(add-hook 'erc-server-JOIN-functions 'erc-autojoin-add)
(add-hook 'erc-server-PART-functions 'erc-autojoin-remove))
((remove-hook 'erc-after-connect 'erc-autojoin-channels)
+ (remove-hook 'erc-nickserv-identified-hook 'erc-autojoin-after-ident)
(remove-hook 'erc-server-JOIN-functions 'erc-autojoin-add)
(remove-hook 'erc-server-PART-functions 'erc-autojoin-remove)))
(repeat :tag "Channels"
(string :tag "Name")))))
+(defcustom erc-autojoin-timing 'connect
+ "When ERC should attempt to autojoin a channel.
+If the value is `connect', autojoin immediately on connecting.
+If the value is `ident', autojoin after successful NickServ
+identification, or after `erc-autojoin-delay' seconds.
+Any other value means the same as `connect'."
+ :group 'erc-autojoin
+ :type '(choice (const :tag "On Connection" 'connect)
+ (const :tag "When Identified" 'ident)))
+
+(defcustom erc-autojoin-delay 30
+ "Number of seconds to wait before attempting to autojoin channels.
+This only takes effect if `erc-autojoin-timing' is `ident'.
+If NickServ identification occurs before this delay expires, ERC
+autojoins immediately at that time."
+ :group 'erc-autojoin
+ :type 'integer)
+
(defcustom erc-autojoin-domain-only t
"Truncate host name to the domain name when joining a server.
If non-nil, and a channel on the server a.b.c is joined, then
:group 'erc-autojoin
:type 'boolean)
+(defvar erc--autojoin-timer nil)
+(make-variable-buffer-local 'erc--autojoin-timer)
+
+(defun erc-autojoin-channels-delayed (server nick buffer)
+ "Attempt to autojoin channels.
+This is called from a timer set up by `erc-autojoin-channels'."
+ (if erc--autojoin-timer
+ (setq erc--autojoin-timer
+ (erc-cancel-timer erc--autojoin-timer)))
+ (with-current-buffer buffer
+ ;; Don't kick of another delayed autojoin or try to wait for
+ ;; another ident response:
+ (let ((erc-autojoin-delay -1)
+ (erc-autojoin-timing 'connect))
+ (erc-log "Delayed autojoin started (no ident success detected yet)")
+ (erc-autojoin-channels server nick))))
+
+(defun erc-autojoin-after-ident (network nick)
+ "Autojoin channels in `erc-autojoin-channels-alist'.
+This function is run from `erc-nickserv-identified-hook'."
+ (if erc--autojoin-timer
+ (setq erc--autojoin-timer
+ (erc-cancel-timer erc--autojoin-timer)))
+ (when (eq erc-autojoin-timing 'ident)
+ (let ((server (or erc-server-announced-name erc-session-server))
+ (joined (mapcar (lambda (buf)
+ (with-current-buffer buf (erc-default-target)))
+ (erc-channel-list erc-server-process))))
+ ;; We may already be in these channels, e.g. because the
+ ;; autojoin timer went off.
+ (dolist (l erc-autojoin-channels-alist)
+ (when (string-match (car l) server)
+ (dolist (chan (cdr l))
+ (unless (erc-member-ignore-case chan joined)
+ (erc-server-send (concat "join " chan))))))))
+ nil)
+
(defun erc-autojoin-channels (server nick)
"Autojoin channels in `erc-autojoin-channels-alist'."
- (dolist (l erc-autojoin-channels-alist)
- (when (string-match (car l) server)
- (dolist (chan (cdr l))
- (erc-server-send (concat "join " chan))))))
+ (if (eq erc-autojoin-timing 'ident)
+ ;; Prepare the delayed autojoin timer, in case ident doesn't
+ ;; happen within the allotted time limit:
+ (when (> erc-autojoin-delay 0)
+ (setq erc--autojoin-timer
+ (run-with-timer erc-autojoin-delay nil
+ 'erc-autojoin-channels-delayed
+ server nick (current-buffer))))
+ ;; `erc-autojoin-timing' is `connect':
+ (dolist (l erc-autojoin-channels-alist)
+ (when (string-match (car l) server)
+ (dolist (chan (cdr l))
+ (erc-server-send (concat "join " chan))))))
+ ;; Return nil to avoid stomping on any other hook funcs.
+ nil)
(defun erc-autojoin-add (proc parsed)
"Add the channel being joined to `erc-autojoin-channels-alist'."
(cond ((equal a b) t)
((equal (color-values a) (color-values b)))))
+
+(defvar facemenu-self-insert-data nil)
+
+(defun facemenu-post-self-insert-function ()
+ (when (and (car facemenu-self-insert-data)
+ (eq last-command (cdr facemenu-self-insert-data)))
+ (put-text-property (1- (point)) (point)
+ 'face (car facemenu-self-insert-data))
+ (setq facemenu-self-insert-data nil))
+ (remove-hook 'post-self-insert-hook 'facemenu-post-self-insert-function))
+
+(defun facemenu-set-self-insert-face (face)
+ "Arrange for the next self-inserted char to have face `face'."
+ (setq facemenu-self-insert-data (cons face this-command))
+ (add-hook 'post-self-insert-hook 'facemenu-post-self-insert-function))
+
(defun facemenu-add-face (face &optional start end)
"Add FACE to text between START and END.
If START is nil or START to END is empty, add FACE to next typed character
text property. Otherwise, selecting the default face would not have any
effect. See `facemenu-remove-face-function'."
(interactive "*xFace: \nr")
- (if (and (eq face 'default)
- (not (eq facemenu-remove-face-function t)))
- (if facemenu-remove-face-function
- (funcall facemenu-remove-face-function start end)
- (if (and start (< start end))
- (remove-text-properties start end '(face default))
- (setq self-insert-face 'default
- self-insert-face-command this-command)))
- (if facemenu-add-face-function
- (save-excursion
- (if end (goto-char end))
- (save-excursion
- (if start (goto-char start))
- (insert-before-markers
- (funcall facemenu-add-face-function face end)))
- (if facemenu-end-add-face
- (insert (if (stringp facemenu-end-add-face)
- facemenu-end-add-face
- (funcall facemenu-end-add-face face)))))
+ (cond
+ ((and (eq face 'default)
+ (not (eq facemenu-remove-face-function t)))
+ (if facemenu-remove-face-function
+ (funcall facemenu-remove-face-function start end)
(if (and start (< start end))
- (let ((part-start start) part-end)
- (while (not (= part-start end))
- (setq part-end (next-single-property-change part-start 'face
- nil end))
- (let ((prev (get-text-property part-start 'face)))
- (put-text-property part-start part-end 'face
- (if (null prev)
- face
- (facemenu-active-faces
- (cons face
- (if (listp prev)
- prev
- (list prev)))
- ;; Specify the selected frame
- ;; because nil would mean to use
- ;; the new-frame default settings,
- ;; and those are usually nil.
- (selected-frame)))))
- (setq part-start part-end)))
- (setq self-insert-face (if (eq last-command self-insert-face-command)
- (cons face (if (listp self-insert-face)
- self-insert-face
- (list self-insert-face)))
- face)
- self-insert-face-command this-command))))
+ (remove-text-properties start end '(face default))
+ (facemenu-set-self-insert-face 'default))))
+ (facemenu-add-face-function
+ (save-excursion
+ (if end (goto-char end))
+ (save-excursion
+ (if start (goto-char start))
+ (insert-before-markers
+ (funcall facemenu-add-face-function face end)))
+ (if facemenu-end-add-face
+ (insert (if (stringp facemenu-end-add-face)
+ facemenu-end-add-face
+ (funcall facemenu-end-add-face face))))))
+ ((and start (< start end))
+ (let ((part-start start) part-end)
+ (while (not (= part-start end))
+ (setq part-end (next-single-property-change part-start 'face
+ nil end))
+ (let ((prev (get-text-property part-start 'face)))
+ (put-text-property part-start part-end 'face
+ (if (null prev)
+ face
+ (facemenu-active-faces
+ (cons face
+ (if (listp prev)
+ prev
+ (list prev)))
+ ;; Specify the selected frame
+ ;; because nil would mean to use
+ ;; the new-frame default settings,
+ ;; and those are usually nil.
+ (selected-frame)))))
+ (setq part-start part-end))))
+ (t
+ (facemenu-set-self-insert-face
+ (if (eq last-command (cdr facemenu-self-insert-data))
+ (cons face (if (listp (car facemenu-self-insert-data))
+ (car facemenu-self-insert-data)
+ (list (car facemenu-self-insert-data))))
+ face))))
(unless (facemenu-enable-faces-p)
(message "Font-lock mode will override any faces you set in this buffer")))
(let ((x (file-name-directory suffix)))
(if x (1- (length x)) (length suffix))))))
(t
- (let ((names nil)
+ (let ((names '())
+ ;; If we have files like "foo.el" and "foo.elc", we could load one of
+ ;; them with "foo.el", "foo.elc", or "foo", where just "foo" is the
+ ;; preferred way. So if we list all 3, that gives a lot of redundant
+ ;; entries for the poor soul looking just for "foo". OTOH, sometimes
+ ;; the user does want to pay attention to the extension. We try to
+ ;; diffuse this tension by stripping the suffix, except when the
+ ;; result is a single element (i.e. usually we only list "foo" unless
+ ;; it's the only remaining element in the list, in which case we do
+ ;; list "foo", "foo.elc" and "foo.el").
+ (fullnames '())
(suffix (concat (regexp-opt suffixes t) "\\'"))
(string-dir (file-name-directory string))
(string-file (file-name-nondirectory string)))
(dolist (dir dirs)
- (unless dir
- (setq dir default-directory))
- (if string-dir (setq dir (expand-file-name string-dir dir)))
- (when (file-directory-p dir)
- (dolist (file (file-name-all-completions
- string-file dir))
- (push file names)
- (when (string-match suffix file)
- (setq file (substring file 0 (match-beginning 0)))
- (push file names)))))
+ (unless dir
+ (setq dir default-directory))
+ (if string-dir (setq dir (expand-file-name string-dir dir)))
+ (when (file-directory-p dir)
+ (dolist (file (file-name-all-completions
+ string-file dir))
+ (if (not (string-match suffix file))
+ (push file names)
+ (push file fullnames)
+ (push (substring file 0 (match-beginning 0)) names)))))
+ ;; Switching from names to names+fullnames creates a non-monotonicity
+ ;; which can cause problems with things like partial-completion.
+ ;; To minimize the problem, filter out completion-regexp-list, so that
+ ;; M-x load-library RET t/x.e TAB finds some files.
+ (if completion-regexp-list
+ (setq names (all-completions "" names)))
+ ;; Remove duplicates of the first element, so that we can easily check
+ ;; if `names' really only contains a single element.
+ (when (cdr names) (setcdr names (delete (car names) (cdr names))))
+ (unless (cdr names)
+ ;; There's no more than one matching non-suffixed element, so expand
+ ;; the list by adding the suffixed elements as well.
+ (setq names (nconc names fullnames)))
(completion-table-with-context
string-dir names string-file pred action)))))
"inline" "lambda" "save-restriction" "save-excursion"
"save-selected-window" "save-window-excursion"
"save-match-data" "save-current-buffer"
- "unwind-protect" "condition-case" "track-mouse"
- "eval-after-load" "eval-and-compile" "eval-when-compile"
- "eval-when" "eval-next-after-load"
+ "combine-after-change-calls" "unwind-protect"
+ "condition-case" "condition-case-no-debug"
+ "track-mouse" "eval-after-load" "eval-and-compile"
+ "eval-when-compile" "eval-when" "eval-next-after-load"
"with-case-table" "with-category-table"
- "with-current-buffer" "with-electric-help"
+ "with-current-buffer" "with-demoted-errors"
+ "with-electric-help"
"with-local-quit" "with-no-warnings"
"with-output-to-string" "with-output-to-temp-buffer"
- "with-selected-window" "with-selected-frame" "with-syntax-table"
+ "with-selected-window" "with-selected-frame"
+ "with-silent-modifications" "with-syntax-table"
"with-temp-buffer" "with-temp-file" "with-temp-message"
"with-timeout" "with-timeout-handler") t)
"\\>")
+2010-08-17 Glenn Morris <rgm@gnu.org>
+
+ * gnus-sync.el: Require gnus components whose functions are used.
+
+ * gnus-art.el (bookmark-make-record-function):
+ * gnus-sum.el (bookmark-yank-point, bookmark-current-bookmark):
+ Declare for compiler.
+
+ * mm-url.el (mml-compute-boundary): Autoload.
+
+2010-08-15 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * gnus-start.el (gnus-start-draft-setup): Move doc string forward.
+
+2010-08-14 Teodor Zlatanov <tzz@lifelogs.com>
+
+ Typo fix "hoo4a" -> "hook".
+
+ * gnus-sync.el (gnus-sync-install-hooks): Typo fix.
+
+2010-08-14 Glenn Morris <rgm@gnu.org>
+
+ * gnus-sync.el (gnus-sync): Fix defgroup version.
+
+2010-08-13 Teodor Zlatanov <tzz@lifelogs.com>
+
+ Doc fixes and keep unknown groups (ammended for nunion bug fix).
+
+ * gnus-sync.el: Fix docs.
+ (gnus-sync-save): Keep unknown groups in `gnus-sync-newsrc-loader'.
+ (gnus-sync-read): Don't wipe `gnus-sync-newsrc-loader' after reading.
+
+2010-08-12 Teodor Zlatanov <tzz@lifelogs.com>
+
+ Optimizations for gnus-sync.el.
+
+ * gnus-sync.el: Add docs about gnus-sync-backend
+ possibilities.
+ (gnus-sync-save): Remove unnecessary message.
+ (gnus-sync-read): Optimize and show what groups were skipped.
+
+2010-08-12 Teodor Zlatanov <tzz@lifelogs.com>
+
+ Minor bug fixes for gnus-sync.el.
+
+ * gnus-sync.el (gnus-sync-unload-hook, gnus-sync-install-hooks): Don't
+ read the sync on get-new-news.
+
+ * gnus-sync.el (gnus-sync-save): Define `variable' so the compiler is
+ quiet.
+
+ * gnus-sync.el (gnus-sync-read): Use `gnus-sync-newsrc-offsets' (fix typo).
+
+2010-07-30 Lawrence Mitchell <wence@gmx.li>
+
+ Make saving and restoring of hidden threads work with overlays.
+ Patch applied by Ted Zlatanov.
+
+ * gnus-sum.el (gnus-hidden-threads-configuration)
+ (gnus-restore-hidden-threads-configuration): Update to deal with text
+ properties, rather than searching for a magic character.
+
+2010-08-12 Teodor Zlatanov <tzz@lifelogs.com>
+
+ New gnus-sync.el library for synchronization of marks.
+
+ * gnus-sync.el: New library for synchronization of marks.
+
+ * gnus-util.el (gnus-grep-in-list): Moved from gnus-registry.el and
+ renamed from `gnus-registry-grep-in-list'.
+
+ * gnus-registry.el (gnus-registry-follow-group-p): Use `gnus-grep-in-list'.
+
+ * gnus-start.el (gnus-start-draft-setup): Make it interactive.
+
2010-08-06 Katsumi Yamaoka <yamaoka@jpl.org>
* rfc2047.el (rfc2047-encode): Use utf-8 as a last resort if
(gnus-run-hooks 'gnus-article-menu-hook)))
+(defvar bookmark-make-record-function)
+
(defun gnus-article-mode ()
"Major mode for displaying an article.
"Determines if a group name should be followed.
Consults `gnus-registry-unfollowed-groups' and
`nnmail-split-fancy-with-parent-ignore-groups'."
- (not (or (gnus-registry-grep-in-list
+ (not (or (gnus-grep-in-list
group
gnus-registry-unfollowed-groups)
- (gnus-registry-grep-in-list
+ (gnus-grep-in-list
group
nnmail-split-fancy-with-parent-ignore-groups))))
(assoc article (gnus-data-list nil)))))
nil))
-(defun gnus-registry-grep-in-list (word list)
-"Find if a WORD matches any regular expression in the given LIST."
- (when (and word list)
- (catch 'found
- (dolist (r list)
- (when (string-match r word)
- (throw 'found r))))))
-
(defun gnus-registry-do-marks (type function)
"For each known mark, call FUNCTION for each cell of type TYPE.
(defun gnus-start-draft-setup ()
"Make sure the draft group exists."
+ (interactive)
(gnus-request-create-group "drafts" '(nndraft ""))
(unless (gnus-group-entry "nndraft:drafts")
(let ((gnus-level-default-subscribed 1))
(save-excursion
(let (config)
(goto-char (point-min))
- (while (search-forward "\r" nil t)
- (push (1- (point)) config))
+ (while (not (eobp))
+ (when (eq (get-char-property (point-at-eol) 'invisible) 'gnus-sum)
+ (push (save-excursion (forward-line 0) (point)) config))
+ (forward-line 1))
config)))
(defun gnus-restore-hidden-threads-configuration (config)
(save-excursion
(let (point (inhibit-read-only t))
(while (setq point (pop config))
- (when (and (< point (point-max))
- (goto-char point)
- (eq (char-after) ?\n))
- (subst-char-in-region point (1+ point) ?\n ?\r))))))
+ (goto-char point)
+ (gnus-summary-hide-thread)))))
;; Various summary mode internalish functions.
(declare-function bookmark-prop-get "bookmark" (bookmark prop))
(declare-function bookmark-default-handler "bookmark" (bmk))
(declare-function bookmark-get-bookmark-record "bookmark" (bmk))
+(defvar bookmark-yank-point)
+(defvar bookmark-current-buffer)
(defun gnus-summary-bookmark-make-record ()
"Make a bookmark entry for a Gnus summary buffer."
--- /dev/null
+;;; gnus-sync.el --- synchronization facility for Gnus
+
+;; Copyright (C) 2010 Free Software Foundation, Inc.
+
+;; Author: Ted Zlatanov <tzz@lifelogs.com>
+;; Keywords: news synchronization nntp nnrss
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This is the gnus-sync.el package.
+
+;; Put this in your startup file (~/.gnus.el for instance)
+
+;; possibilities for gnus-sync-backend:
+;; Tramp over SSH: /ssh:user@host:/path/to/filename
+;; Tramp over IMAP: /imaps:user@yourhosthere.com:/INBOX.test/filename
+;; ...or any other file Tramp and Emacs can handle...
+
+;; (setq gnus-sync-backend "/remote:/path.gpg" ; will use Tramp+EPA if loaded
+;; gnus-sync-global-vars `(gnus-newsrc-last-checked-date)
+;; gnus-sync-newsrc-groups `("nntp" "nnrss")
+;; gnus-sync-newsrc-offsets `(2 3))
+
+;; TODO:
+
+;; - after gnus-sync-read, the message counts are wrong
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'gnus)
+(require 'gnus-start)
+(require 'gnus-util)
+
+(defgroup gnus-sync nil
+ "The Gnus synchronization facility."
+ :version "24.1"
+ :group 'gnus)
+
+(defcustom gnus-sync-newsrc-groups `("nntp" "nnrss")
+ "List of groups to be synchronized in the gnus-newsrc-alist.
+The group names are matched, they don't have to be fully
+qualified. Typically you would choose all of these. That's the
+default because there is no active sync backend by default, so
+this setting is harmless until the user chooses a sync backend."
+ :group 'gnus-sync
+ :type '(repeat regexp))
+
+(defcustom gnus-sync-newsrc-offsets '(2 3)
+ "List of per-group data to be synchronized."
+ :group 'gnus-sync
+ :type '(set (const :tag "Read ranges" 2)
+ (const :tag "Marks" 3)))
+
+(defcustom gnus-sync-global-vars nil
+ "List of global variables to be synchronized.
+You may want to sync `gnus-newsrc-last-checked-date' but pretty
+much any symbol is fair game. You could additionally sync
+`gnus-newsrc-alist', `gnus-server-alist', `gnus-topic-topology',
+and `gnus-topic-alist' to cover all the variables in
+newsrc.eld (except for `gnus-format-specs' which should not be
+synchronized, I believe). Also see `gnus-variable-list'."
+ :group 'gnus-sync
+ :type '(repeat (choice (variable :tag "A known variable")
+ (symbol :tag "Any symbol"))))
+
+(defcustom gnus-sync-backend nil
+ "The synchronization backend."
+ :group 'gnus-sync
+ :type '(radio (const :format "None" nil)
+ (string :tag "Sync to a file")))
+
+(defvar gnus-sync-newsrc-loader nil
+ "Carrier for newsrc data")
+
+(defun gnus-sync-save ()
+"Save the Gnus sync data to the backend."
+ (interactive)
+ (cond
+ ((stringp gnus-sync-backend)
+ (gnus-message 7 "gnus-sync: saving to backend %s" gnus-sync-backend)
+ ;; populate gnus-sync-newsrc-loader from all but the first dummy
+ ;; entry in gnus-newsrc-alist whose group matches any of the
+ ;; gnus-sync-newsrc-groups
+ ;; TODO: keep the old contents for groups we don't have!
+ (let ((gnus-sync-newsrc-loader
+ (loop for entry in (cdr gnus-newsrc-alist)
+ when (gnus-grep-in-list
+ (car entry) ;the group name
+ gnus-sync-newsrc-groups)
+ collect (cons (car entry)
+ (mapcar (lambda (offset)
+ (cons offset (nth offset entry)))
+ gnus-sync-newsrc-offsets)))))
+ (with-temp-file gnus-sync-backend
+ (progn
+ (let ((coding-system-for-write gnus-ding-file-coding-system)
+ (standard-output (current-buffer)))
+ (princ (format ";; -*- mode:emacs-lisp; coding: %s; -*-\n"
+ gnus-ding-file-coding-system))
+ (princ ";; Gnus sync data v. 0.0.1\n")
+ (let* ((print-quoted t)
+ (print-readably t)
+ (print-escape-multibyte nil)
+ (print-escape-nonascii t)
+ (print-length nil)
+ (print-level nil)
+ (print-circle nil)
+ (print-escape-newlines t)
+ (variables (cons 'gnus-sync-newsrc-loader
+ gnus-sync-global-vars))
+ variable)
+ (while variables
+ (if (and (boundp (setq variable (pop variables)))
+ (symbol-value variable))
+ (progn
+ (princ "\n(setq ")
+ (princ (symbol-name variable))
+ (princ " '")
+ (prin1 (symbol-value variable))
+ (princ ")\n"))
+ (princ "\n;;; skipping empty variable ")
+ (princ (symbol-name variable)))))
+ (gnus-message
+ 7
+ "gnus-sync: stored variables %s and %d groups in %s"
+ gnus-sync-global-vars
+ (length gnus-sync-newsrc-loader)
+ gnus-sync-backend)
+
+ ;; Idea from Dan Christensen <jdc@chow.mat.jhu.edu>
+ ;; Save the .eld file with extra line breaks.
+ (gnus-message 8 "gnus-sync: adding whitespace to %s"
+ gnus-sync-backend)
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "^(\\|(\\\"" nil t)
+ (replace-match "\n\\&" t))
+ (goto-char (point-min))
+ (while (re-search-forward " $" nil t)
+ (replace-match "" t t))))))))
+ ;; the pass-through case: gnus-sync-backend is not a known choice
+ (nil)))
+
+(defun gnus-sync-read ()
+"Load the Gnus sync data from the backend."
+ (interactive)
+ (when gnus-sync-backend
+ (gnus-message 7 "gnus-sync: loading from backend %s" gnus-sync-backend)
+ (cond ((stringp gnus-sync-backend)
+ ;; read data here...
+ (if (or debug-on-error debug-on-quit)
+ (load gnus-sync-backend nil t)
+ (condition-case var
+ (load gnus-sync-backend nil t)
+ (error
+ (error "Error in %s: %s" gnus-sync-backend (cadr var)))))
+ (let ((valid-count 0)
+ invalid-groups)
+ (dolist (node gnus-sync-newsrc-loader)
+ (if (gnus-gethash (car node) gnus-newsrc-hashtb)
+ (progn
+ (incf valid-count)
+ (loop for store in (cdr node)
+ do (setf (nth (car store)
+ (assoc (car node) gnus-newsrc-alist))
+ (cdr store))))
+ (push (car node) invalid-groups)))
+ (gnus-message
+ 7
+ "gnus-sync: loaded %d groups (out of %d) from %s"
+ valid-count (length gnus-sync-newsrc-loader)
+ gnus-sync-backend)
+ (when invalid-groups
+ (gnus-message
+ 7
+ "gnus-sync: skipped %d groups (out of %d) from %s"
+ (length invalid-groups)
+ (length gnus-sync-newsrc-loader)
+ gnus-sync-backend)
+ (gnus-message 9 "gnus-sync: skipped groups: %s"
+ (mapconcat 'identity invalid-groups ", ")))))
+ (nil))
+ ;; make the hashtable again because the newsrc-alist may have been modified
+ (when gnus-sync-newsrc-offsets
+ (gnus-message 9 "gnus-sync: remaking the newsrc hashtable")
+ (gnus-make-hashtable-from-newsrc-alist))))
+
+;;;###autoload
+(defun gnus-sync-initialize ()
+"Initialize the Gnus sync facility."
+ (interactive)
+ (gnus-message 5 "Initializing the sync facility")
+ (gnus-sync-install-hooks))
+
+;;;###autoload
+(defun gnus-sync-install-hooks ()
+ "Install the sync hooks."
+ (interactive)
+ ;; (add-hook 'gnus-get-new-news-hook 'gnus-sync-read)
+ (add-hook 'gnus-save-newsrc-hook 'gnus-sync-save)
+ (add-hook 'gnus-read-newsrc-el-hook 'gnus-sync-read))
+
+(defun gnus-sync-unload-hook ()
+ "Uninstall the sync hooks."
+ (interactive)
+ ;; (remove-hook 'gnus-get-new-news-hook 'gnus-sync-read)
+ (remove-hook 'gnus-save-newsrc-hook 'gnus-sync-save)
+ (remove-hook 'gnus-read-newsrc-el-hook 'gnus-sync-read))
+
+(add-hook 'gnus-sync-unload-hook 'gnus-sync-unload-hook)
+
+;; this is harmless by default, until the gnus-sync-backend is set
+(gnus-sync-initialize)
+
+(provide 'gnus-sync)
+
+;;; gnus-sync.el ends here
(setq alist (delq entry alist)))
alist)))
+(defun gnus-grep-in-list (word list)
+ "Find if a WORD matches any regular expression in the given LIST."
+ (when (and word list)
+ (catch 'found
+ (dolist (r list)
+ (when (string-match r word)
+ (throw 'found r))))))
+
(defmacro gnus-pull (key alist &optional assoc-p)
"Modify ALIST to be without KEY."
(unless (symbolp alist)
(mm-url-form-encode-xwfu (cdr data))))
pairs "&"))
+(autoload 'mml-compute-boundary "mml")
+
(defun mm-url-encode-multipart-form-data (pairs &optional boundary)
"Return PAIRS encoded in multipart/form-data."
;; RFC1867
(buffer-substring-no-properties (point-min) (point-max)))
filename))
(type (image-type file-or-data nil data-p))
- (image (create-animated-image file-or-data type data-p))
+ (image0 (create-animated-image file-or-data type data-p))
+ (image (append image0
+ (image-transform-properties image0)
+ ))
(props
`(display ,image
intangible ,image
(when (not (string= image-type (bookmark-prop-get bmk 'image-type)))
(image-toggle-display))))
\f
+
+(defvar image-transform-minor-mode-map
+ (let ((map (make-sparse-keymap)))
+; (define-key map [(control ?+)] 'image-scale-in)
+; (define-key map [(control ?-)] 'image-scale-out)
+; (define-key map [(control ?=)] 'image-scale-none)
+;; (define-key map "c f h" 'image-scale-fit-height)
+;; (define-key map "c ]" 'image-rotate-right)
+ map)
+ "Minor mode keymap for transforming the view of images Image mode.")
+
+(define-minor-mode image-transform-mode
+ "minor mode for scaleing and rotation"
+ nil "image-transform"
+ image-transform-minor-mode-map)
+
+(defvar image-transform-resize nil
+ "The image resize operation. See the command
+ `image-transform-set-scale' for more information." )
+
+(defvar image-transform-rotation 0.0)
+
+
+(defun image-transform-properties (display)
+ "Calculate the display properties for transformations; scaling
+and rotation. "
+ (let*
+ ((size (image-size display t))
+ (height
+ (cond
+ ((and (numberp image-transform-resize) (eq 100 image-transform-resize))
+ nil)
+ ((numberp image-transform-resize)
+ (* image-transform-resize (cdr size)))
+ ((eq image-transform-resize 'fit-height)
+ (- (nth 3 (window-inside-pixel-edges)) (nth 1 (window-inside-pixel-edges))))
+ (t nil)))
+ (width (if (eq image-transform-resize 'fit-width)
+ (- (nth 2 (window-inside-pixel-edges)) (nth 0 (window-inside-pixel-edges))))))
+
+ `(,@(if height (list :height height))
+ ,@(if width (list :width width))
+ ,@(if (not (equal 0.0 image-transform-rotation))
+ (list :rotation image-transform-rotation))
+ ;;TODO fit-to-* should consider the rotation angle
+ )))
+
+(defun image-transform-set-scale (scale)
+ "SCALE sets the scaling for images. "
+ (interactive "nscale:")
+ (image-transform-set-resize (float scale)))
+
+(defun image-transform-fit-to-height ()
+ "Fit image height to window height. "
+ (interactive)
+ (image-transform-set-resize 'fit-height))
+
+(defun image-transform-fit-to-width ()
+ "Fit image width to window width. "
+ (interactive)
+ (image-transform-set-resize 'fit-width))
+
+(defun image-transform-set-resize (resize)
+ "Set the resize mode for images. The RESIZE value can be the
+symbol fit-height which fits the image to the window height. The
+symbol fit-width fits the image to the window width. A number
+indicates a scaling factor. nil indicates scale to 100%. "
+ (setq image-transform-resize resize)
+ (if (eq 'image-mode major-mode) (image-toggle-display-image)))
+
+(defun image-transform-set-rotation (rotation)
+ "Set the image ROTATION angle. "
+ (interactive "nrotation:")
+ ;;TODO 0 90 180 270 degrees are the only reasonable angles here
+ ;;otherwise combining with rescaling will get very awkward
+ (setq image-transform-rotation (float rotation))
+ (if (eq major-mode 'image-mode) (image-toggle-display-image)))
+
(provide 'image-mode)
;; arch-tag: b5b2b7e6-26a7-4b79-96e3-1546b5c4c6cb
(let* ((animate (memq type image-animated-types))
(image
(append (list 'image :type type (if data-p :data :file) file-or-data)
- (if animate '(:index 0 :mask heuristic))
+ (if animate '(:index 0))
props)))
(if animate
(image-animate-start image))
(cons images tmo))))))
\f
+(defcustom imagemagick-types-inhibit
+ '(C HTML HTM TXT PDF)
+ "Types the imagemagick loader should not try to handle.")
+
+;;;###autoload
+(defun imagemagick-register-types ()
+ "Register file types that imagemagick is able to handle."
+ (let ((im-types (imagemagick-types)))
+ (dolist (im-inhibit imagemagick-types-inhibit)
+ (setq im-types (remove im-inhibit im-types)))
+ (dolist (im-type im-types)
+ (let ((extension (downcase (symbol-name im-type))))
+ (push
+ (cons (concat "\\." extension "\\'") 'image-mode)
+ auto-mode-alist)
+ (push
+ (cons (concat "\\." extension "\\'") 'imagemagick)
+ image-type-file-name-regexps)))))
+
+
+
(provide 'image)
;; arch-tag: 8e76a07b-eb48-4f3e-a7a0-1a7ba9f096b3
(declare-function message-sort-headers "message" ())
(defvar message-strip-special-text-properties)
+(defun report-emacs-bug-can-use-xdg-email ()
+ "Check if xdg-email can be used, i.e. we are on Gnome, KDE or xfce4."
+ (and (getenv "DISPLAY")
+ (executable-find "xdg-email")
+ (or (getenv "GNOME_DESKTOP_SESSION_ID")
+ ;; GNOME_DESKTOP_SESSION_ID is deprecated, check on Dbus also.
+ (condition-case nil
+ (eq 0 (call-process
+ "dbus-send" nil nil nil
+ "--dest=org.gnome.SessionManager"
+ "--print-reply"
+ "/org/gnome/SessionManager"
+ "org.gnome.SessionManager.CanShutdown"))
+ (error nil))
+ (equal (getenv "KDE_FULL_SESSION") "true")
+ (condition-case nil
+ (eq 0 (call-process
+ "/bin/sh" nil nil nil
+ "-c"
+ "xprop -root _DT_SAVE_MODE|grep xfce4"))
+ (error nil)))))
+
+(defun report-emacs-bug-insert-to-mailer ()
+ (interactive)
+ (save-excursion
+ (let* ((to (progn
+ (goto-char (point-min))
+ (forward-line)
+ (and (looking-at "^To: \\(.*\\)")
+ (match-string-no-properties 1))))
+ (subject (progn
+ (forward-line)
+ (and (looking-at "^Subject: \\(.*\\)")
+ (match-string-no-properties 1))))
+ (body (progn
+ (forward-line 2)
+ (if (> (point-max) (point))
+ (buffer-substring-no-properties (point) (point-max))))))
+ (if (and to subject body)
+ (start-process "xdg-email" nil "xdg-email"
+ "--subject" subject
+ "--body" body
+ (concat "mailto:" to))
+ (error "Subject, To or body not found")))))
+
+
;;;###autoload
(defun report-emacs-bug (topic &optional recent-keys)
"Report a bug in GNU Emacs.
(prompt-properties '(field emacsbug-prompt
intangible but-helpful
rear-nonsticky t))
+ (can-xdg-email (report-emacs-bug-can-use-xdg-email))
user-point message-end-point)
(setq message-end-point
(with-current-buffer (get-buffer-create "*Messages*")
;; This is so the user has to type something in order to send easily.
(use-local-map (nconc (make-sparse-keymap) (current-local-map)))
(define-key (current-local-map) "\C-c\C-i" 'report-emacs-bug-info)
+ (if can-xdg-email
+ (define-key (current-local-map) "\C-cm"
+ 'report-emacs-bug-insert-to-mailer))
;; Could test major-mode instead.
(cond ((memq mail-user-agent '(message-user-agent gnus-user-agent))
(setq report-emacs-bug-send-command "message-send-and-exit"
report-emacs-bug-send-command))))
(princ (substitute-command-keys
" Type \\[kill-buffer] RET to cancel (don't send it).\n"))
+ (if can-xdg-email
+ (princ (substitute-command-keys
+ " Type \\[report-emacs-bug-insert-to-mailer] to insert text to you preferred mail program.\n")))
(terpri)
(princ (substitute-command-keys
" Type \\[report-emacs-bug-info] to visit in Info the Emacs Manual section
:help ,(purecopy "Turn menu-bar on/off")
:button (:toggle . (> (frame-parameter nil 'menu-bar-lines) 0))))
+(defun menu-bar-set-tool-bar-position (position)
+ (customize-set-variable 'tool-bar-mode t)
+ (set-frame-parameter nil 'tool-bar-position position)
+ (customize-set-variable 'default-frame-alist
+ (cons (cons 'tool-bar-position position)
+ (assq-delete-all 'tool-bar-position
+ default-frame-alist))))
+
(defun menu-bar-showhide-tool-bar-menu-customize-disable ()
"Do not display tool bars."
(interactive)
(defun menu-bar-showhide-tool-bar-menu-customize-enable-left ()
"Display tool bars on the left side."
(interactive)
- (customize-set-variable 'tool-bar-mode t)
- (set-frame-parameter nil 'tool-bar-position 'left))
+ (menu-bar-set-tool-bar-position 'left))
(defun menu-bar-showhide-tool-bar-menu-customize-enable-right ()
"Display tool bars on the right side."
(interactive)
- (customize-set-variable 'tool-bar-mode t)
- (set-frame-parameter nil 'tool-bar-position 'right))
+ (menu-bar-set-tool-bar-position 'right))
(defun menu-bar-showhide-tool-bar-menu-customize-enable-top ()
"Display tool bars on the top side."
(interactive)
- (customize-set-variable 'tool-bar-mode t)
- (set-frame-parameter nil 'tool-bar-position 'top))
+ (menu-bar-set-tool-bar-position 'top))
(defun menu-bar-showhide-tool-bar-menu-customize-enable-bottom ()
"Display tool bars on the bottom side."
(interactive)
- (customize-set-variable 'tool-bar-mode t)
- (set-frame-parameter nil 'tool-bar-position 'bottom))
+ (menu-bar-set-tool-bar-position 'bottom))
(if (featurep 'move-toolbar)
(progn
'(only)
(cons 'only transient-mark-mode)))
(let ((range (mouse-start-end start-point start-point click-count)))
- (goto-char (nth 0 range))
- (push-mark nil t t)
+ (push-mark (nth 0 range) t t)
(goto-char (nth 1 range)))
;; Track the mouse until we get a non-movement event.
end-point (posn-point end))
(if (and (eq (posn-window end) start-window)
(integer-or-marker-p end-point))
- ;; If moving in the original window, move point by going
- ;; to start first, so that if end is in intangible text,
- ;; point jumps away from start. Don't do it if
- ;; start=end, or a single click would select a region if
- ;; it's on intangible text.
- (unless (= start-point end-point)
- (goto-char start-point)
- (goto-char end-point))
+ (mouse--drag-set-mark-and-point start-point
+ end-point click-count)
(let ((mouse-row (cdr (cdr (mouse-position)))))
(cond
((null mouse-row))
(eq (posn-window end) start-window)
(integer-or-marker-p end-point)
(/= start-point end-point))
- (goto-char start-point)
- (goto-char end-point))
+ (mouse--drag-set-mark-and-point start-point
+ end-point click-count))
+
;; Find its binding.
(let* ((fun (key-binding (vector (car event))))
(do-multi-click (and (> (event-click-count event) 0)
(put 'mouse-2 'event-kind 'mouse-click)))
(push event unread-command-events)))))))
+(defun mouse--drag-set-mark-and-point (start click click-count)
+ (let* ((range (mouse-start-end start click click-count))
+ (beg (nth 0 range))
+ (end (nth 1 range)))
+ (cond ((eq (mark) beg)
+ (goto-char end))
+ ((eq (mark) end)
+ (goto-char beg))
+ ((< click (mark))
+ (set-mark end)
+ (goto-char beg))
+ (t
+ (set-mark beg)
+ (goto-char end)))))
+
(defun mouse--remap-link-click-p (start-event end-event)
(or (and (eq mouse-1-click-follows-link 'double)
(= (event-click-count start-event) 2))
((= mode 2)
(list (save-excursion
(goto-char start)
- (beginning-of-line 1)
- (point))
+ (line-beginning-position 1))
(save-excursion
(goto-char end)
(forward-line 1)
;; the middle of an active region.
(deactivate-mark))
(or mouse-yank-at-point (mouse-set-point click))
- (let ((primary (x-get-selection 'PRIMARY)))
+ (let ((primary
+ (cond
+ ((fboundp 'x-get-selection-value) ; MS-DOS and MS-Windows
+ (or (x-get-selection-value)
+ (x-get-selection 'PRIMARY)))
+ ;; FIXME: What about xterm-mouse-mode etc.?
+ (t
+ (x-get-selection 'PRIMARY)))))
(if primary
(insert primary)
- (error "No primary selection"))))
+ (error "No selection is available"))))
(defun mouse-kill-ring-save (click)
"Copy the region between point and the mouse click in the kill ring.
Galeon, Konqueror, Netscape, Mosaic, Lynx in an xterm, and then W3."
(apply
(cond
+ ((browse-url-can-use-xdg-open) 'browse-url-xdg-open)
((executable-find browse-url-gnome-moz-program) 'browse-url-gnome-moz)
((executable-find browse-url-mozilla-program) 'browse-url-mozilla)
((executable-find browse-url-firefox-program) 'browse-url-firefox)
(lambda (&rest ignore) (error "No usable browser found"))))
url args))
+(defun browse-url-can-use-xdg-open ()
+ "Check if xdg-open can be used, i.e. we are on Gnome, KDE or xfce4."
+ (and (getenv "DISPLAY")
+ (executable-find "xdg-open")
+ ;; xdg-open may call gnome-open and that does not wait for its child
+ ;; to finish. This child may then be killed when the parent dies.
+ ;; Use nohup to work around.
+ (executable-find "nohup")
+ (or (getenv "GNOME_DESKTOP_SESSION_ID")
+ ;; GNOME_DESKTOP_SESSION_ID is deprecated, check on Dbus also.
+ (condition-case nil
+ (eq 0 (call-process
+ "dbus-send" nil nil nil
+ "--dest=org.gnome.SessionManager"
+ "--print-reply"
+ "/org/gnome/SessionManager"
+ "org.gnome.SessionManager.CanShutdown"))
+ (error nil))
+ (equal (getenv "KDE_FULL_SESSION") "true")
+ (condition-case nil
+ (eq 0 (call-process
+ "/bin/sh" nil nil nil
+ "-c"
+ "xprop -root _DT_SAVE_MODE|grep xfce4"))
+ (error nil)))))
+
+
+;;;###autoload
+(defun browse-url-xdg-open (url &optional new-window)
+ (interactive (browse-url-interactive-arg "URL: "))
+ (call-process "/bin/sh" nil nil nil
+ "-c"
+ (concat "nohup xdg-open " url
+ ">/dev/null 2>&1 </dev/null")))
+
;;;###autoload
(defun browse-url-netscape (url &optional new-window)
"Ask the Netscape WWW browser to load URL.
:type 'integer
:group 'rcirc)
+(defcustom rcirc-log-process-buffers nil
+ "Non-nil if rcirc process buffers should be logged to disk."
+ :group 'rcirc
+ :type 'boolean
+ :version "24.1")
+
(defun rcirc-last-quit-line (process nick target)
"Return the line number where NICK left TARGET.
Returns nil if the information is not recorded."
(when (not (rcirc-channel-p rcirc-target))
'nick)))
- (when rcirc-log-flag
+ (when (and rcirc-log-flag
+ (or target
+ rcirc-log-process-buffers))
(rcirc-log process sender response target text))
(sit-for 0) ; displayed text before hook
(run-hook-with-args 'rcirc-print-hooks
process sender response target text)))))
-(defcustom rcirc-log-filename-function 'rcirc-generate-new-buffer-name
+(defun rcirc-generate-log-filename (process target)
+ (if target
+ (rcirc-generate-new-buffer-name process target)
+ (process-name process)))
+
+(defcustom rcirc-log-filename-function 'rcirc-generate-log-filename
"A function to generate the filename used by rcirc's logging facility.
It is called with two arguments, PROCESS and TARGET (see
(unless ln
(tramp-error
l 'file-error
- "Making a symbolic link. ln(1) does not exist on the remote host."))
+ "Making a symbolic link. ln(1) does not exist on the remote host."))
;; Do the 'confirm if exists' thing.
(when (file-exists-p linkname)
(tramp-file-name-localname
(tramp-dissect-file-name (expand-file-name filename)))))
+ (tramp-flush-file-property l (file-name-directory l-localname))
+ (tramp-flush-file-property l l-localname)
+
;; Right, they are on the same host, regardless of user, method, etc.
;; We now make the link on the remote machine. This will occur as the user
;; that FILENAME belongs to.
(setq outbuf (current-buffer))))
(when stderr (setq command (format "%s 2>%s" command stderr)))
- ;; Send the command. It might not return in time, so we protect it.
+ ;; Send the command. It might not return in time, so we protect
+ ;; it. Call it in a subshell, in order to preserve working
+ ;; directory.
(condition-case nil
(unwind-protect
(setq ret
v (format "\\cd %s; %s"
(tramp-shell-quote-argument localname)
command)
- nil t))
+ t t))
;; We should show the output anyway.
(when outbuf
(with-current-buffer outbuf
"Query the user for a password."
(with-current-buffer (process-buffer proc)
(tramp-check-for-regexp proc tramp-password-prompt-regexp)
- (tramp-message vec 3 "Sending %s" (match-string 1)))
- (tramp-enter-password proc))
+ (tramp-message vec 3 "Sending %s" (match-string 1))
+ (tramp-enter-password proc)
+ ;; Hide password prompt.
+ (narrow-to-region (point-max) (point-max))))
(defun tramp-action-succeed (proc vec)
"Signal success in finding shell prompt."
(tramp-process-one-action proc vec actions))
(tramp-process-one-action proc vec actions)))))
(with-current-buffer (tramp-get-connection-buffer vec)
+ (widen)
(tramp-message vec 6 "\n%s" (buffer-string)))
(unless (eq exit 'ok)
(tramp-clear-passwd vec)
(delete-char n)
(setq ,bindent (- ,bindent n)))))))))))
-;; Compute the number of extra comment starter characters
-;; (extra semicolons in Lisp mode, extra stars in C mode, etc.)
-;; If ARG is non-nil, just follow ARG.
-;; If the comment-starter is multi-char, just follow ARG.
-;; Otherwise obey comment-add, and double it if EXTRA is non-nil.
(defun comment-add (arg)
+ "Compute the number of extra comment starter characters
+\(extra semicolons in Lisp mode, extra stars in C mode, etc.)
+If ARG is non-nil, just follow ARG.
+If the comment starter is multi-char, just follow ARG.
+Otherwise obey `comment-add'."
(if (and (null arg) (= (string-match "[ \t]*\\'" comment-start) 1))
(* comment-add 1)
(1- (prefix-numeric-value arg))))
+2010-08-19 Glenn Morris <rgm@gnu.org>
+
+ * org.el (org-outline-overlay-data, org-set-outline-overlay-data)
+ (org-save-outline-visibility): Move to org-macs.
+ * org-macs.el (org-outline-overlay-data, org-set-outline-overlay-data)
+ (org-save-outline-visibility): Move here from org.el.
+ (show-all): Autoload it.
+ * ob.el: Don't require org when compiling.
+
+2010-08-18 Glenn Morris <rgm@gnu.org>
+
+ * ob.el: Require org when compiling.
+ (org-save-outline-visibility): Remove macro declaration.
+ * ob-emacs-lisp.el: Require ob-comint when compiling, for macros.
+ Remove unnecessary/macro declarations.
+ * org-docview.el: Require doc-view when compiling.
+ (doc-view-goto-page): Autoload rather than declaring.
+ (doc-view-current-page): Remove macro declaration.
+
+2010-08-17 Glenn Morris <rgm@gnu.org>
+
+ * ob.el (tramp-compat-make-temp-file, org-edit-src-code)
+ (org-entry-get, org-table-import): Fix declarations.
+ (org-match-string-no-properties): Remove unnecessary declaration.
+ * ob-sh.el (org-babel-comint-in-buffer)
+ (org-babel-comint-wait-for-output, org-babel-comint-buffer-livep)
+ (org-babel-comint-with-output): Remove unnecessary declarations.
+ * ob-R.el (orgtbl-to-tsv): Fix declaration.
+ * org-list.el (org-entry-get): Fix declaration.
+
2010-07-19 Eric Schulte <schulte.eric@gmail.com>
* ob-C.el: New file.
(require 'ob-eval)
(eval-when-compile (require 'cl))
-(declare-function orgtbl-to-tsv "ob-table" (table params))
+(declare-function orgtbl-to-tsv "org-table" (table params))
(declare-function R "ext:essd-r" (&optional start-args))
(declare-function inferior-ess-send-input "ext:ess-inf" ())
;;; Code:
(require 'ob)
+(eval-when-compile (require 'ob-comint))
(defvar org-babel-default-header-args:emacs-lisp
'((:hlines . "yes") (:colnames . "no"))
"Default arguments for evaluating an emacs-lisp source block.")
-(declare-function org-babel-comint-with-output "ob-comint" (&rest body))
-(declare-function org-babel-comint-buffer-livep "ob-comint" (buffer))
-(declare-function org-babel-comint-wait-for-output "ob-comint" (buffer))
-(declare-function org-babel-comint-in-buffer "ob-comint" (buffer &rest body))
(declare-function orgtbl-to-generic "org-table" (table params))
(defun org-babel-expand-body:emacs-lisp (body params &optional processed-params)
(eval-when-compile (require 'cl))
(declare-function org-babel-ref-variables "ob-ref" (params))
-(declare-function org-babel-comint-in-buffer "ob-comint" (buffer &rest body))
-(declare-function org-babel-comint-wait-for-output "ob-comint" (buffer))
-(declare-function org-babel-comint-buffer-livep "ob-comint" (buffer))
-(declare-function org-babel-comint-with-output "ob-comint" (meta &rest body))
(declare-function orgtbl-to-generic "org-table" (table params))
(defvar org-babel-default-header-args:sh '())
;;; Commentary:
;; See the online documentation for more information
-;;
+;;
;; http://orgmode.org/worg/org-contrib/babel/
;;; Code:
-(eval-when-compile (require 'cl))
+(eval-when-compile
+ (require 'cl))
(require 'org-macs)
(defvar org-babel-call-process-region-original)
(declare-function show-all "outline" ())
-(declare-function tramp-compat-make-temp-file "tramp" (filename &optional dir-flag))
+(declare-function tramp-compat-make-temp-file "tramp-compat"
+ (filename &optional dir-flag))
(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
(declare-function tramp-file-name-user "tramp" (vec))
(declare-function tramp-file-name-host "tramp" (vec))
(declare-function org-icompleting-read "org" (&rest args))
-(declare-function org-edit-src-code "org" (context code edit-buffer-name))
+(declare-function org-edit-src-code "org-src"
+ (&optional context code edit-buffer-name))
(declare-function org-open-at-point "org" (&optional in-emacs reference-buffer))
-(declare-function org-save-outline-visibility "org" (use-markers &rest body))
(declare-function org-narrow-to-subtree "org" ())
-(declare-function org-entry-get "org" (pom property &optional inherit))
+(declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
(declare-function org-make-options-regexp "org" (kwds &optional extra))
-(declare-function org-match-string-no-properties "org" (num &optional string))
(declare-function org-do-remove-indentation "org" (&optional n))
(declare-function org-show-context "org" (&optional key))
(declare-function org-at-table-p "org" (&optional table-type))
(declare-function org-cycle "org" (&optional arg))
(declare-function org-uniquify "org" (list))
-(declare-function org-table-import "org" (file arg))
+(declare-function org-table-import "org-table" (file arg))
(declare-function org-add-hook "org-compat" (hook function &optional append local))
(declare-function org-table-align "org-table" ())
(declare-function org-table-end "org-table" (&optional table-type))
(require 'org)
+(eval-when-compile (require 'doc-view)) ; doc-view-current-page macro
-(declare-function doc-view-goto-page "doc-view" (page))
-(declare-function doc-view-current-page "doc-view" (&optional win))
+(autoload 'doc-view-goto-page "doc-view")
(org-add-link-type "docview" 'org-docview-open)
(add-hook 'org-store-link-functions 'org-docview-store-link)
(declare-function org-get-indentation "org" (&optional line))
(declare-function org-timer-item "org-timer" (&optional arg))
(declare-function org-combine-plists "org" (&rest plists))
-(declare-function org-entry-get "org" (pom property &optional inherit))
+(declare-function org-entry-get "org"
+ (pom property &optional inherit literal-nil))
(declare-function org-narrow-to-subtree "org" ())
(declare-function org-show-subtree "org" ())
(nstars (if org-odd-levels-only (1- (* limit-level 2)) limit-level)))
(format "\\*\\{1,%d\\} " nstars))))
+
+;;; Saving and restoring visibility
+
+(defun org-outline-overlay-data (&optional use-markers)
+ "Return a list of the locations of all outline overlays.
+The are overlays with the `invisible' property value `outline'.
+The return values is a list of cons cells, with start and stop
+positions for each overlay.
+If USE-MARKERS is set, return the positions as markers."
+ (let (beg end)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (delq nil
+ (mapcar (lambda (o)
+ (when (eq (overlay-get o 'invisible) 'outline)
+ (setq beg (overlay-start o)
+ end (overlay-end o))
+ (and beg end (> end beg)
+ (if use-markers
+ (cons (move-marker (make-marker) beg)
+ (move-marker (make-marker) end))
+ (cons beg end)))))
+ (overlays-in (point-min) (point-max))))))))
+
+(autoload 'show-all "outline" nil t)
+
+(defun org-set-outline-overlay-data (data)
+ "Create visibility overlays for all positions in DATA.
+DATA should have been made by `org-outline-overlay-data'."
+ (let (o)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (show-all)
+ (mapc (lambda (c)
+ (setq o (make-overlay (car c) (cdr c)))
+ (overlay-put o 'invisible 'outline))
+ data)))))
+
+(defmacro org-save-outline-visibility (use-markers &rest body)
+ "Save and restore outline visibility around BODY.
+If USE-MARKERS is non-nil, use markers for the positions.
+This means that the buffer may change while running BODY,
+but it also means that the buffer should stay alive
+during the operation, because otherwise all these markers will
+point nowhere."
+ (declare (indent 1))
+ `(let ((data (org-outline-overlay-data ,use-markers)))
+ (unwind-protect
+ (progn
+ ,@body
+ (org-set-outline-overlay-data data))
+ (when ,use-markers
+ (mapc (lambda (c)
+ (and (markerp (car c)) (move-marker (car c) nil))
+ (and (markerp (cdr c)) (move-marker (cdr c) nil)))
+ data)))))
+
+
(provide 'org-macs)
;; arch-tag: 7e6a73ce-aac9-4fc0-9b30-ce6f89dc6668
(beginning-of-line)
(recenter (prefix-numeric-value N))))
-;;; Saving and restoring visibility
-
-(defun org-outline-overlay-data (&optional use-markers)
- "Return a list of the locations of all outline overlays.
-The are overlays with the `invisible' property value `outline'.
-The return values is a list of cons cells, with start and stop
-positions for each overlay.
-If USE-MARKERS is set, return the positions as markers."
- (let (beg end)
- (save-excursion
- (save-restriction
- (widen)
- (delq nil
- (mapcar (lambda (o)
- (when (eq (overlay-get o 'invisible) 'outline)
- (setq beg (overlay-start o)
- end (overlay-end o))
- (and beg end (> end beg)
- (if use-markers
- (cons (move-marker (make-marker) beg)
- (move-marker (make-marker) end))
- (cons beg end)))))
- (overlays-in (point-min) (point-max))))))))
-
-(defun org-set-outline-overlay-data (data)
- "Create visibility overlays for all positions in DATA.
-DATA should have been made by `org-outline-overlay-data'."
- (let (o)
- (save-excursion
- (save-restriction
- (widen)
- (show-all)
- (mapc (lambda (c)
- (setq o (make-overlay (car c) (cdr c)))
- (overlay-put o 'invisible 'outline))
- data)))))
-
-(defmacro org-save-outline-visibility (use-markers &rest body)
- "Save and restore outline visibility around BODY.
-If USE-MARKERS is non-nil, use markers for the positions.
-This means that the buffer may change while running BODY,
-but it also means that the buffer should stay alive
-during the operation, because otherwise all these markers will
-point nowhere."
- (declare (indent 1))
- `(let ((data (org-outline-overlay-data ,use-markers)))
- (unwind-protect
- (progn
- ,@body
- (org-set-outline-overlay-data data))
- (when ,use-markers
- (mapc (lambda (c)
- (and (markerp (car c)) (move-marker (car c) nil))
- (and (markerp (cdr c)) (move-marker (cdr c) nil)))
- data)))))
-
;;; Folding of blocks
;;; cc-engine.el --- core syntax guessing engine for CC mode
;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-;; Free Software Foundation, Inc.
+;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+;; 2010 Free Software Foundation, Inc.
;; Authors: 2001- Alan Mackenzie
;; 1998- Martin Stjernholm
(c-unmark-<->-as-paren pos))
t)))
+;; Set by c-common-init in cc-mode.el.
+(defvar c-new-BEG)
+(defvar c-new-END)
+
(defun c-before-change-check-<>-operators (beg end)
;; Unmark certain pairs of "< .... >" which are currently marked as
;; template/generic delimiters. (This marking is via syntax-table
(goto-char safe-pos)
t)))
+;; cc-mode requires cc-fonts.
+(declare-function c-fontify-recorded-types-and-refs "cc-fonts" ())
+
(defun c-forward-<>-arglist (all-types)
;; The point is assumed to be at a "<". Try to treat it as the open
;; paren of an angle bracket arglist and move forward to the
;;; cc-mode.el --- major mode for editing C and similar languages
;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-;; Free Software Foundation, Inc.
+;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+;; 2010 Free Software Foundation, Inc.
;; Authors: 2003- Alan Mackenzie
;; 1998- Martin Stjernholm
(font-lock-mode 0)
(font-lock-mode 1)))
+;; Buffer local variables defining the region to be fontified by a font lock
+;; after-change function. They are set in c-after-change to
+;; after-change-function's BEG and END, and may be modified by a
+;; `c-before-font-lock-function'.
+(defvar c-new-BEG 0)
+(make-variable-buffer-local 'c-new-BEG)
+(defvar c-new-END 0)
+(make-variable-buffer-local 'c-new-END)
+
(defun c-common-init (&optional mode)
"Common initialization for all CC Mode modes.
In addition to the work done by `c-basic-common-init' and
\f
;;; Change hooks, linking with Font Lock.
-;; Buffer local variables defining the region to be fontified by a font lock
-;; after-change function. They are set in c-after-change to
-;; after-change-function's BEG and END, and may be modified by a
-;; `c-before-font-lock-function'.
-(defvar c-new-BEG 0)
-(make-variable-buffer-local 'c-new-BEG)
-(defvar c-new-END 0)
-(make-variable-buffer-local 'c-new-END)
-
;; Buffer local variables recording Beginning/End-of-Macro position before a
;; change, when a macro straddles, respectively, the BEG or END (or both) of
;; the change region. Otherwise these have the values BEG/END.
"^[-[:alnum:]_/ ]+: \\(?:\\(?:[sS]evere\\|[eE]rror\\|[wW]arnin\\(g\\)\\|[iI]nf\\(o\\)\\)[0-9 ]*: \\)?\
\\([^,\" \n\t]+\\)\\(?:, line\\|:\\) \\([0-9]+\\):" 3 4 nil (1 . 2))
+ (ruby
+ "^[\t ]*\\(?:from \\)?\
+\\([^\(\n][^[:space:]\n]*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?.*$" 1 2)
+
(java
"^\\(?:[ \t]+at \\|==[0-9]+== +\\(?:at\\|b\\(y\\)\\)\\).+(\\([^()\n]+\\):\\([0-9]+\\))$" 2 3 nil (1))
"\\(?:Parse\\|Fatal\\) error: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)"
2 3 nil nil)
- (ruby
- "^[\t ]*\\(?:from \\)?\
-\\([^\(\n][^[:space:]\n]*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?.*$" 1 2)
-
(ruby-Test::Unit
"[\t ]*\\[\\([^\(].*\\):\\([1-9][0-9]*\\)\\(\\]\\)?:$" 1 2)
Use the `etags' program to make a tags table file.")
;; Make M-x set-variable tags-file-name like M-x visit-tags-table.
;;;###autoload (put 'tags-file-name 'variable-interactive (purecopy "fVisit tags table: "))
+;;;###autoload (put 'tags-file-name 'safe-local-variable 'stringp)
(defgroup etags nil "Tags tables."
:group 'tools)
'font-lock-builtin-face
'font-lock-preprocessor-face))
;; Fontify all builtin variables.
- (cons (concat "\\<\\("
- (mapconcat 'identity octave-variables "\\|")
- "\\)\\>")
+ (cons (concat "\\<" (regexp-opt octave-variables) "\\>")
'font-lock-variable-name-face)
;; Fontify all function declarations.
(list octave-function-header-regexp
'(3 font-lock-function-name-face nil t)))
"Additional Octave expressions to highlight.")
+(defvar octave-font-lock-syntactic-keywords
+ ;; Try to distinguish the string-quotes from the transpose-quotes.
+ '(("[[({,; ]\\('\\)" (1 "\"'"))
+ (octave-font-lock-close-quotes)))
+
+(defun octave-font-lock-close-quotes (limit)
+ "Fix the syntax-table of the closing quotes of single-quote strings."
+ ;; Freely inspired from perl-font-lock-special-syntactic-constructs.
+ (let ((state (syntax-ppss)))
+ (while (< (point) limit)
+ (cond
+ ((eq (nth 3 state) ?\')
+ ;; A '..' string.
+ (save-excursion
+ (when (and (or (looking-at "\\('\\)")
+ (re-search-forward "[^\\]\\(?:\\\\\\\\\\)*\\('\\)"
+ nil t))
+ (not (eobp)))
+ (put-text-property (match-beginning 1) (match-end 1)
+ 'syntax-table (string-to-syntax "\"'"))))))
+
+ (setq state (parse-partial-sexp (point) limit nil nil state
+ 'syntax-table)))))
+
(defcustom inferior-octave-buffer "*Inferior Octave*"
"Name of buffer for running an inferior Octave process."
:type 'string
(define-key map " " 'octave-electric-space)
(define-key map "\n" 'octave-reindent-then-newline-and-indent)
(define-key map "\e\n" 'octave-indent-new-comment-line)
- (define-key map "\M-\C-a" 'octave-beginning-of-defun)
- (define-key map "\M-\C-e" 'octave-end-of-defun)
- (define-key map "\M-\C-h" 'octave-mark-defun)
(define-key map "\M-\C-q" 'octave-indent-defun)
(define-key map "\C-c\C-b" 'octave-submit-bug-report)
(define-key map "\C-c\C-p" 'octave-previous-code-line)
"Keymap used in Octave mode.")
-(defvar octave-mode-menu
+
+(easy-menu-define octave-mode-menu octave-mode-map
+ "Menu for Octave mode."
'("Octave"
("Lines"
["Previous Code Line" octave-previous-code-line t]
["Mark Block" octave-mark-block t]
["Close Block" octave-close-block t])
("Functions"
- ["Begin of Function" octave-beginning-of-defun t]
- ["End of Function" octave-end-of-defun t]
- ["Mark Function" octave-mark-defun t]
["Indent Function" octave-indent-defun t]
["Insert Function" octave-insert-defun t])
"-"
["Indent Line" indent-according-to-mode t]
["Complete Symbol" completion-at-point t]
"-"
- ["Toggle Abbrev Mode" abbrev-mode t]
- ["Toggle Auto-Fill Mode" auto-fill-mode t]
+ ["Toggle Abbrev Mode" abbrev-mode
+ :style toggle :selected abbrev-mode]
+ ["Toggle Auto-Fill Mode" auto-fill-mode
+ :style toggle :selected auto-fill-function]
"-"
["Submit Bug Report" octave-submit-bug-report t]
"-"
["Describe Octave Mode" describe-mode t]
- ["Lookup Octave Index" octave-help t])
- "Menu for Octave mode.")
+ ["Lookup Octave Index" info-lookup-symbol t]))
(defvar octave-mode-syntax-table
(let ((table (make-syntax-table)))
newline or semicolon after an else or end keyword."
:type 'boolean
:group 'octave)
+
(defcustom octave-block-offset 2
"Extra indentation applied to statements in Octave block structures."
:type 'integer
(concat octave-block-else-regexp "\\|" octave-block-end-regexp))
(defvar octave-block-match-alist
'(("do" . ("until"))
- ("for" . ("endfor" "end"))
- ("function" . ("endfunction"))
- ("if" . ("else" "elseif" "endif" "end"))
- ("switch" . ("case" "otherwise" "endswitch" "end"))
- ("try" . ("catch" "end_try_catch"))
- ("unwind_protect" . ("unwind_protect_cleanup" "end_unwind_protect"))
- ("while" . ("endwhile" "end")))
+ ("for" . ("end" "endfor"))
+ ("function" . ("end" "endfunction"))
+ ("if" . ("else" "elseif" "end" "endif"))
+ ("switch" . ("case" "otherwise" "end" "endswitch"))
+ ("try" . ("catch" "end" "end_try_catch"))
+ ("unwind_protect" . ("unwind_protect_cleanup" "end" "end_unwind_protect"))
+ ("while" . ("end" "endwhile")))
"Alist with Octave's matching block keywords.
Has Octave's begin keywords as keys and a list of the matching else or
end keywords as associated values.")
(set (make-local-variable 'normal-auto-fill-function) 'octave-auto-fill)
(set (make-local-variable 'font-lock-defaults)
- '(octave-font-lock-keywords nil nil))
+ '(octave-font-lock-keywords nil nil nil nil
+ (font-lock-syntactic-keywords . octave-font-lock-syntactic-keywords)
+ (parse-sexp-lookup-properties . t)))
(set (make-local-variable 'imenu-generic-expression)
octave-mode-imenu-generic-expression)
(add-hook 'completion-at-point-functions
'octave-completion-at-point-function nil t)
+ (set (make-local-variable 'beginning-of-defun-function)
+ 'octave-beginning-of-defun)
- (octave-add-octave-menu)
+ (easy-menu-add octave-mode-menu)
(octave-initialize-completions)
(run-mode-hooks 'octave-mode-hook))
+(defvar info-lookup-mode)
+
(defun octave-help ()
"Get help on Octave symbols from the Octave info files.
Look up symbol in the function, operator and variable indices of the info files."
(let ((case-fold-search nil))
(re-search-backward regexp nil 'move count)))
-(defun octave-in-defun-p ()
- "Return t if point is inside an Octave function declaration.
-The function is taken to start at the `f' of `function' and to end after
-the end keyword."
- (let ((pos (point)))
- (save-excursion
- (or (and (octave-looking-at-kw "\\<function\\>")
- (octave-not-in-string-or-comment-p))
- (and (octave-beginning-of-defun)
- (condition-case nil
- (progn
- (octave-forward-block)
- t)
- (error nil))
- (< pos (point)))))))
-
(defun octave-maybe-insert-continuation-string ()
(if (or (octave-in-comment-p)
(save-excursion
"Properly indent the Octave function which contains point."
(interactive)
(save-excursion
- (octave-mark-defun)
+ (mark-defun)
(message "Indenting function...")
(indent-region (point) (mark) nil))
(message "Indenting function...done."))
With positive ARG, do it that many times. Negative argument -N means
move forward to Nth following beginning of a function.
Returns t unless search stops at the beginning or end of the buffer."
- (interactive "p")
(let* ((arg (or arg 1))
(inc (if (> arg 0) 1 -1))
- (found))
+ (found nil)
+ (case-fold-search nil))
(and (not (eobp))
- (not (and (> arg 0) (octave-looking-at-kw "\\<function\\>")))
+ (not (and (> arg 0) (looking-at "\\<function\\>")))
(skip-syntax-forward "w"))
(while (and (/= arg 0)
(setq found
- (octave-re-search-backward-kw "\\<function\\>" inc)))
+ (re-search-backward "\\<function\\>" inc)))
(if (octave-not-in-string-or-comment-p)
(setq arg (- arg inc))))
(if found
(and (< inc 0) (goto-char (match-beginning 0)))
t))))
-(defun octave-end-of-defun (&optional arg)
- "Move forward to the end of an Octave function.
-With positive ARG, do it that many times. Negative argument -N means
-move back to Nth preceding end of a function.
-
-An end of a function occurs right after the end keyword matching the
-`function' keyword that starts the function."
- (interactive "p")
- (or arg (setq arg 1))
- (and (< arg 0) (skip-syntax-backward "w"))
- (and (> arg 0) (skip-syntax-forward "w"))
- (if (octave-in-defun-p)
- (setq arg (- arg 1)))
- (if (= arg 0) (setq arg -1))
- (if (octave-beginning-of-defun (- arg))
- (octave-forward-block)))
-
-(defun octave-mark-defun ()
- "Put point at the beginning of this Octave function, mark at its end.
-The function marked is the one containing point or following point."
- (interactive)
- (let ((pos (point)))
- (if (or (octave-in-defun-p)
- (and (octave-beginning-of-defun -1)
- (octave-in-defun-p)))
- (progn
- (skip-syntax-forward "w")
- (octave-beginning-of-defun)
- (push-mark (point))
- (octave-end-of-defun)
- (exchange-point-and-mark))
- (goto-char pos)
- (message "No function to mark found"))))
-
\f
;;; Filling
(defun octave-auto-fill ()
(defun octave-completion-at-point-function ()
"Find the text to complete and the corresponding table."
(let* ((beg (save-excursion (backward-sexp 1) (point)))
- (end (if (< beg (point))
- (save-excursion (goto-char beg) (forward-sexp 1) (point))
- (point))))
+ (end (point)))
+ (if (< beg (point))
+ ;; Extend region past point, if applicable.
+ (save-excursion (goto-char beg) (forward-sexp 1)
+ (setq end (max end (point)))))
(list beg end octave-completion-alist)))
(defun octave-complete-symbol ()
(defun octave-reindent-then-newline-and-indent ()
"Reindent current Octave line, insert newline, and indent the new line.
If Abbrev mode is on, expand abbrevs first."
+ ;; FIXME: None of this is Octave-specific.
(interactive)
(if abbrev-mode (expand-abbrev))
(if octave-blink-matching-block
(octave-blink-matching-block-open))
- (save-excursion
- (delete-region (point) (progn (skip-chars-backward " \t") (point)))
- (indent-according-to-mode))
- (insert "\n")
- (indent-according-to-mode))
+ (reindent-then-newline-and-indent))
(defun octave-electric-semi ()
"Insert a semicolon in Octave mode.
\n _ \n
"endfunction" > \n)
\f
-;;; Menu
-(defun octave-add-octave-menu ()
- "Add the `Octave' menu to the menu bar in Octave mode."
- (require 'easymenu)
- (easy-menu-define octave-mode-menu-map octave-mode-map
- "Menu keymap for Octave mode." octave-mode-menu)
- (easy-menu-add octave-mode-menu-map octave-mode-map))
-
-\f
;;; Communication with the inferior Octave process
(defun octave-kill-process ()
"Kill inferior Octave process and its buffer."
"Send current Octave function to the inferior Octave process."
(interactive)
(save-excursion
- (octave-mark-defun)
+ (mark-defun)
(octave-send-region (point) (mark))))
(defun octave-send-line (&optional arg)
(defvar comint-prompt-regexp)
(defvar comint-process-echoes)
-(defvar smie-indent-basic)
+(require 'smie)
(defgroup prolog nil
"Major mode for editing and running Prolog under Emacs."
;; Major mode meant to be the parent of programming modes.
+(defvar prog-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [?\C-\M-q] 'prog-indent-sexp)
+ map)
+ "Keymap used for programming modes.")
+
+(defun prog-indent-sexp ()
+ "Indent the expression after point."
+ (interactive)
+ (let ((start (point))
+ (end (save-excursion (forward-sexp 1) (point))))
+ (indent-region start end nil)))
+
(define-derived-mode prog-mode fundamental-mode "Prog"
"Major mode for editing programming language source code."
(set (make-local-variable 'require-final-newline) mode-require-final-newline)
Mark mode is disabled.
This function also runs `deactivate-mark-hook'."
(when (or transient-mark-mode force)
- (when (and select-active-regions
+ (when (and (if (eq select-active-regions 'only)
+ (eq (car-safe transient-mark-mode) 'only)
+ select-active-regions)
(region-active-p)
(display-selections-p))
;; The var `saved-region-selection', if non-nil, is the text in
(and parse-sexp-ignore-comments
(not blink-matching-paren-dont-ignore-comments))))
(condition-case ()
- (scan-sexps oldpos -1)
+ (progn
+ (forward-sexp -1)
+ (point))
(error nil))))))
(matching-paren
(and blinkpos
(defun ns-get-pasteboard ()
"Returns the value of the pasteboard."
- (ns-get-cut-buffer-internal 'PRIMARY))
+ (ns-get-cut-buffer-internal 'CLIPBOARD))
(declare-function ns-store-cut-buffer-internal "nsselect.m" (buffer string))
"Store STRING into the pasteboard of the Nextstep display server."
;; Check the data type of STRING.
(if (not (stringp string)) (error "Nonstring given to pasteboard"))
- (ns-store-cut-buffer-internal 'PRIMARY string))
+ (ns-store-cut-buffer-internal 'CLIPBOARD string))
;; We keep track of the last text selected here, so we can check the
;; current selection against it, and avoid passing back our own text
+2010-08-19 Juanma Barranquero <lekktu@gmail.com>
+
+ * addpm.c (add_registry): Create App Paths of type REG_EXPAND_SZ.
+
2010-08-12 Jason Rumney <jasonr@gnu.org>
* addpm.c (add_registry): Set path for runemacs.exe to use.
emacs_path = (char *) alloca (len);
sprintf (emacs_path, "%s\\bin\\emacs.exe", path);
- RegSetValueEx (hrootkey, NULL, 0, REG_SZ, emacs_path, len);
+ RegSetValueEx (hrootkey, NULL, 0, REG_EXPAND_SZ, emacs_path, len);
/* Look for a GTK installation. If found, add it to the library search
path for Emacs so that the image libraries it provides are available
len = strlen (path) + 5 + size;
dll_paths = (char *) alloca (size + strlen (path) + 1);
sprintf (dll_paths, "%s\\bin;%s", path, gtk_path);
- RegSetValueEx (hrootkey, "Path", 0, REG_SZ, dll_paths, len);
+ RegSetValueEx (hrootkey, "Path", 0, REG_EXPAND_SZ,
+ dll_paths, len);
/* Set the same path for runemacs.exe, as the Explorer shell
looks this up, so the above does not take effect when
KEY_WRITE, NULL, &runemacs_key, NULL)
== ERROR_SUCCESS)
{
- RegSetValueEx (runemacs_key, "Path", 0, REG_SZ,
+ RegSetValueEx (runemacs_key, "Path", 0, REG_EXPAND_SZ,
dll_paths, len);
RegCloseKey (runemacs_key);
-2010-08-15 Eli Zaretskii <eliz@gnu.org>
+2010-08-20 Eli Zaretskii <eliz@gnu.org>
* emacs.c <emacs_version>: Add a comment regarding
msdos/mainmake.v2's dependency on the syntax of this declaration.
+2010-08-20 Eli Zaretskii <eliz@gnu.org>
+
+ * dispnew.c (buffer_posn_from_coords): Fix calculation of buffer
+ position for R2L lines by mirroring the pixel position wrt the
+ text are box. Improve commentary.
+
+2010-08-20 Andreas Schwab <schwab@linux-m68k.org>
+
+ * image.c (imagemagick_clear_image): Remove debugging output.
+
+2010-08-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * cmds.c (Vself_insert_face, Vself_insert_face_command): Remove.
+ (Qpost_self_insert_hook, Vpost_self_insert_hook): New vars.
+ (internal_self_insert): Run Qpost_self_insert_hook rather than handle
+ self-insert-face.
+ (syms_of_cmds): Initialize the new vars.
+
+2010-08-19 Jason Rumney <jasonr@gnu.org>
+
+ * w32menu.c (set_frame_menubar): Remove call to undefined function.
+
+ * w32fns.c (w32_wnd_proc): Don't check context before initializing.
+
+2010-08-19 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsselect.m (nxatoms_of_nsselect): Use "Selection" and "Secondary".
+
+2010-08-18 Eli Zaretskii <eliz@gnu.org>
+
+ * xterm.c (x_draw_bar_cursor):
+ * w32term.c (x_draw_bar_cursor): If the character under cursor is
+ R2L, draw the bar cursor on its right rather than on its left.
+
+2010-08-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * eval.c (Fdefmacro): Only obey one declaration.
+
+ * casefiddle.c (casify_region): Setup gl_state.
+
+2010-08-18 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsterm.m (ns_define_frame_cursor): Call x_update_cursor (Bug#6868).
+
+2010-08-18 Jan Djärv <jan.h.d@swipnet.se>
+
+ * gtkutil.c (update_frame_tool_bar): Literal stings are const char*.
+
+2010-08-18 David De La Harpe Golden <david@harpegolden.net>
+
+ * nsselect.m (QCLIPBOARD, NXPrimaryPboard): Define.
+ (symbol_to_nsstring): Map QCLIPBOARD => NSGeneralPboard,
+ QPRIMARY => NXPrimaryPboard.
+ (ns_string_to_symbol): NSGeneralPboard => QCLIPBOARD,
+ NXPrimaryPboard => QPRIMARY.
+ (nxatoms_of_nsselect): NXPrimaryPboard = PrimarySelection,
+ NXSecondaryPboard = SecondarySelection.
+ (syms_of_nsselect): Intern QCLIPBOARD (Bug#6677).
+
+2010-08-17 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * gtkutil.c (update_frame_tool_bar): Don't assume TOOL_BAR_ITEM_LABEL
+ is a string.
+
+2010-08-17 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsfns.m (ns_frame_parm_handlers): Add a slot for the
+ x_set_tool_bar_position handler.
+
+2010-08-17 Eli Zaretskii <eliz@gnu.org>
+
+ * w32fns.c <w32_frame_parm_handlers>: Add a slot for the
+ x_set_tool_bar_position handler, needed to support changes from
+ 2010-07-29T16:49:59Z!jan.h.d@swipnet.se for positioning the tool bar. (Bug#6796)
+
+2010-08-16 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsselect.m: include keyboard.h for QPRIMARY, remove its
+ declaration (Bug#6863).
+ (syms_of_nsselect): Don't intern QPRIMARY.
+
+ * xselect.c: Remove declaration of QPRIMARY (Bug#6864).
+
+ * keyboard.h (QPRIMARY): Declare (Bug#6864).
+
+2010-08-16 Chong Yidong <cyd@stupidchicken.com>
+
+ * keyboard.c (command_loop_1): Avoid setting selection twice,
+ since it's done in deactivate-mark as well.
+ (Vselect_active_regions): Change default to t. Replace `lazy'
+ with non-default value `only', meaning only set PRIMARY for
+ temporarily active regions.
+
+ * insdel.c (prepare_to_modify_buffer): Handle `only' value of
+ select-active-regions.
+
+2010-08-15 Jan Djärv <jan.h.d@swipnet.se>
+
+ * keyboard.c (parse_tool_bar_item): Put in a bad label if :label
+ isn't a string.
+
+2010-08-15 Andreas Schwab <schwab@linux-m68k.org>
+
+ * keyboard.c (parse_tool_bar_item): Avoid excessive use of strlen.
+
+2010-08-15 Jan Djärv <jan.h.d@swipnet.se>
+
+ * keyboard.c (parse_tool_bar_item): malloc buf.
+ Set TOOL_BAR_ITEM_LABEL to empty string if not set to
+ new_lbl (Bug#6855).
+
+2010-08-14 Eli Zaretskii <eliz@gnu.org>
+
+ * xterm.c (x_draw_stretch_glyph_string):
+ * w32term.c (x_draw_stretch_glyph_string): In R2L rows, display
+ the cursor on the right edge of the stretch glyph.
+
+ * xdisp.c (window_box_right_offset, window_box_right):
+ Fix commentary.
+
+ * xdisp.c (Fcurrent_bidi_paragraph_direction): Fix paragraph
+ direction when point is inside a run of whitespace characters.
+
+ * bidi.c (bidi_at_paragraph_end): Remove obsolete comment.
+
+2010-08-14 Jason Rumney <jasonr@gnu.org>
+
+ * keyboard.c (lispy_function_keys): Do not define VK_PACKET (bug#4836)
+
+2010-08-14 Chong Yidong <cyd@stupidchicken.com>
+
+ * fns.c (Fmake_hash_table): Doc fix (Bug#6851).
+
+2010-08-13 Jason Rumney <jasonr@gnu.org>
+
+ * w32menu.c (simple_dialog_show): Use unicode message box if available.
+ (MessageBoxW_Proc): New function typedef.
+ (unicode-message-box): New function pointer.
+ (globals_of_w32menu): Import it from user32.dll. (Bug#5629)
+
+2010-08-13 Jan Djärv <jan.h.d@swipnet.se>
+
+ * frame.h (Qtool_bar_position): Declare.
+
+ * xfns.c (Fx_create_frame): Call x_default_parameter for
+ Qtool_bar_position.
+
2010-08-13 Eli Zaretskii <eliz@gnu.org>
* unexcoff.c: Remove the parts used when "emacs" is not defined.
+
# Makefile for GNU Emacs.
# Copyright (C) 1985, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
RSVG_LIBS= @RSVG_LIBS@
RSVG_CFLAGS= @RSVG_CFLAGS@
+IMAGEMAGICK_LIBS= @IMAGEMAGICK_LIBS@
+IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@
+
+
## widget.o if USE_X_TOOLKIT, otherwise empty.
WIDGET_OBJ=@WIDGET_OBJ@
## FIXME? MYCPPFLAGS only referenced in etc/DEBUG.
ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} \
${C_SWITCH_MACHINE} ${C_SWITCH_SYSTEM} ${C_SWITCH_X_SITE} \
- ${C_SWITCH_X_SYSTEM} ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} \
+ ${C_SWITCH_X_SYSTEM} ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${IMAGEMAGICK_CFLAGS} ${DBUS_CFLAGS} \
${GCONF_CFLAGS} ${FREETYPE_CFLAGS} ${FONTCONFIG_CFLAGS} \
${LIBOTF_CFLAGS} ${M17N_FLT_CFLAGS} ${DEPFLAGS} ${PROFILING_CFLAGS} \
${C_WARNINGS_SWITCH} ${CFLAGS}
## duplicated symbols. If the standard libraries were compiled
## with GCC, we might need LIB_GCC again after them.
LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
- $(RSVG_LIBS) $(DBUS_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
+ $(RSVG_LIBS) ${IMAGEMAGICK_LIBS} $(DBUS_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
$(LIBS_TERMCAP) $(GETLOADAVG_LIBS) ${GCONF_LIBS} ${LIBSELINUX_LIBS} \
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
$(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC)
static EMACS_INT
bidi_at_paragraph_end (EMACS_INT charpos, EMACS_INT bytepos)
{
- /* FIXME: Why Fbuffer_local_value rather than just Fsymbol_value? */
Lisp_Object sep_re;
Lisp_Object start_re;
EMACS_INT val;
we want it to be displayed as
- {RLO}STet{PDF}
+ {PDF}STet{RLO}
not as
start_byte = CHAR_TO_BYTE (start);
end_byte = CHAR_TO_BYTE (end);
+ SETUP_BUFFER_SYNTAX_TABLE(); /* For syntax_prefix_flag_p. */
+
while (start < end)
{
int c2, len;
/* A possible value for a buffer's overwrite-mode variable. */
Lisp_Object Qoverwrite_mode_binary;
-/* Non-nil means put this face on the next self-inserting character. */
-Lisp_Object Vself_insert_face;
-
-/* This is the command that set up Vself_insert_face. */
-Lisp_Object Vself_insert_face_command;
-
static int internal_self_insert (int, int);
\f
DEFUN ("forward-point", Fforward_point, Sforward_point, 1, 1, 0,
A value of 2 means this did things that call for an undo boundary. */
static Lisp_Object Qexpand_abbrev;
+static Lisp_Object Qpost_self_insert_hook, Vpost_self_insert_hook;
static int
internal_self_insert (int c, int noautofill)
&& synt != Sword
&& NILP (current_buffer->read_only)
&& PT > BEGV
- && (!NILP (current_buffer->enable_multibyte_characters)
- ? SYNTAX (XFASTINT (Fprevious_char ())) == Sword
- : (SYNTAX (UNIBYTE_TO_CHAR (XFASTINT (Fprevious_char ())))
- == Sword)))
+ && (SYNTAX (!NILP (current_buffer->enable_multibyte_characters)
+ ? XFASTINT (Fprevious_char ())
+ : UNIBYTE_TO_CHAR (XFASTINT (Fprevious_char ())))
+ == Sword))
{
int modiff = MODIFF;
Lisp_Object sym;
hairy = 2;
}
- /* If previous command specified a face to use, use it. */
- if (!NILP (Vself_insert_face)
- && EQ (current_kboard->Vlast_command, Vself_insert_face_command))
- {
- Fput_text_property (make_number (PT - 1), make_number (PT),
- Qface, Vself_insert_face, Qnil);
- Vself_insert_face = Qnil;
- }
-
if ((synt == Sclose || synt == Smath)
&& !NILP (Vblink_paren_function) && INTERACTIVE
&& !noautofill)
call0 (Vblink_paren_function);
hairy = 2;
}
+ /* Run hooks for electric keys. */
+ call1 (Vrun_hooks, Qpost_self_insert_hook);
+
return hairy;
}
\f
Qexpand_abbrev = intern_c_string ("expand-abbrev");
staticpro (&Qexpand_abbrev);
- DEFVAR_LISP ("self-insert-face", &Vself_insert_face,
- doc: /* If non-nil, set the face of the next self-inserting character to this.
-See also `self-insert-face-command'. */);
- Vself_insert_face = Qnil;
+ Qpost_self_insert_hook = intern_c_string ("post-self-insert-hook");
+ staticpro (&Qpost_self_insert_hook);
- DEFVAR_LISP ("self-insert-face-command", &Vself_insert_face_command,
- doc: /* This is the command that set up `self-insert-face'.
-If `last-command' does not equal this value, we ignore `self-insert-face'. */);
- Vself_insert_face_command = Qnil;
+ DEFVAR_LISP ("post-self-insert-hook", &Vpost_self_insert_hook,
+ doc: /* Hook run at the end of `self-insert-command'.
+This run is run after inserting the charater. */);
+ Vpost_self_insert_hook = Qnil;
DEFVAR_LISP ("blink-paren-function", &Vblink_paren_function,
doc: /* Function called, if non-nil, whenever a close parenthesis is inserted.
/* Define to 1 if netdb.h declares h_errno. */
#undef HAVE_H_ERRNO
+/* Define to 1 if using imagemagick. */
+#undef HAVE_IMAGEMAGICK
+
/* Define to 1 if you have inet sockets. */
#undef HAVE_INET_SOCKETS
/* Define to 1 if you have the <mach/mach.h> header file. */
#undef HAVE_MACH_MACH_H
+/* Define to 1 if you have the `MagickExportImagePixels' function. */
+#undef HAVE_MAGICKEXPORTIMAGEPIXELS
+
/* Define to 1 if you have the <maillock.h> header file. */
#undef HAVE_MAILLOCK_H
***********************************************************************/
/* Determine what's under window-relative pixel position (*X, *Y).
- Return the object (string or buffer) that's there.
+ Return the OBJECT (string or buffer) that's there.
Return in *POS the position in that object.
- Adjust *X and *Y to character positions. */
+ Adjust *X and *Y to character positions.
+ Return in *DX and *DY the pixel coordinates of the click,
+ relative to the top left corner of OBJECT, or relative to
+ the top left corner of the character glyph at (*X, *Y)
+ if OBJECT is nil.
+ Return WIDTH and HEIGHT of the object at (*X, *Y), or zero
+ if the coordinates point to an empty area of the display. */
Lisp_Object
buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *pos, Lisp_Object *object, int *dx, int *dy, int *width, int *height)
#ifdef HAVE_WINDOW_SYSTEM
struct image *img = 0;
#endif
- int x0, x1;
+ int x0, x1, to_x;
/* We used to set current_buffer directly here, but that does the
wrong thing with `face-remapping-alist' (bug#2044). */
start_display (&it, w, startp);
x0 = *x - WINDOW_LEFT_MARGIN_WIDTH (w);
- move_it_to (&it, -1, x0 + it.first_visible_x, *y, -1,
- MOVE_TO_X | MOVE_TO_Y);
+
+ /* First, move to the beginning of the row corresponding to *Y. We
+ need to be in that row to get the correct value of base paragraph
+ direction for the paragraph at *X. */
+ move_it_to (&it, -1, 0, *y, -1, MOVE_TO_X | MOVE_TO_Y);
+
+ /* TO_X is the pixel position that the iterator will compute for the
+ glyph at *X. This is because iterator positions are not offset
+ due to hscroll. */
+ to_x = x0 + it.first_visible_x;
+ if (it.bidi_it.paragraph_dir == R2L)
+ /* For lines in an R2L paragraph, we need to mirror TO_X wrt the
+ text area. This is because the iterator, even in R2L
+ paragraphs, delivers glyphs as if they started at the left
+ margin of the window. (When we actually produce glyphs for
+ display, we reverse their order in PRODUCE_GLYPHS, but the
+ iterator doesn't know about that.) The following line adjusts
+ the pixel position to the iterator geometry, which is what
+ move_it_* routines use. */
+ to_x = window_box_width (w, TEXT_AREA) - to_x;
+
+ /* Now move horizontally in the row to the glyph under *X. */
+ move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
Fset_buffer (old_current_buffer);
tail = XCDR (tail);
}
- while (CONSP (Fcar (tail))
- && EQ (Fcar (Fcar (tail)), Qdeclare))
+ if (CONSP (Fcar (tail))
+ && EQ (Fcar (Fcar (tail)), Qdeclare))
{
if (!NILP (Vmacro_declaration_function))
{
Default is 65.
:rehash-size REHASH-SIZE - Indicates how to expand the table when it
-fills up. If REHASH-SIZE is an integer, add that many space. If it
-is a float, it must be > 1.0, and the new size is computed by
-multiplying the old size with that factor. Default is 1.5.
+fills up. If REHASH-SIZE is an integer, increase the size by that
+amount. If it is a float, it must be > 1.0, and the new size is the
+old size multiplied by that factor. Default is 1.5.
:rehash-threshold THRESHOLD -- THRESHOLD must a float > 0, and <= 1.0.
Resize the hash table when the ratio (number of entries / table size)
-is greater or equal than THRESHOLD. Default is 0.8.
+is greater than or equal to THRESHOLD. Default is 0.8.
:weakness WEAK -- WEAK must be one of nil, t, `key', `value',
`key-or-value', or `key-and-value'. If WEAK is not nil, the table
extern Lisp_Object Qicon, Qicon_name, Qicon_type, Qicon_left, Qicon_top;
extern Lisp_Object Qinternal_border_width;
extern Lisp_Object Qtooltip;
-extern Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
+extern Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
extern Lisp_Object Qmouse_color;
extern Lisp_Object Qname, Qtitle;
extern Lisp_Object Qparent_id;
GtkWidget *wbutton = NULL;
GtkWidget *weventbox;
Lisp_Object specified_file;
- char *label = SSDATA (PROP (TOOL_BAR_ITEM_LABEL));
+ const char *label = (STRINGP (PROP (TOOL_BAR_ITEM_LABEL))
+ ? SSDATA (PROP (TOOL_BAR_ITEM_LABEL)) : "");
ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i);
Lisp_Object QCascent, QCmargin, QCrelief, Qcount, Qextension_data;
Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
-Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
+Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask, QCgeometry, QCcrop, QCrotation;
/* Other symbols. */
#endif /* HAVE_GIF */
+/***********************************************************************
+ imagemagick
+***********************************************************************/
+#if defined (HAVE_IMAGEMAGICK)
+Lisp_Object Vimagemagick_render_type;
+
+/* The symbol `imagemagick' identifying images of this type. */
+
+Lisp_Object Qimagemagick;
+Lisp_Object Vimagemagick_render_type;
+
+/* Indices of image specification fields in imagemagick_format, below. */
+
+enum imagemagick_keyword_index
+ {
+ IMAGEMAGICK_TYPE,
+ IMAGEMAGICK_DATA,
+ IMAGEMAGICK_FILE,
+ IMAGEMAGICK_ASCENT,
+ IMAGEMAGICK_MARGIN,
+ IMAGEMAGICK_RELIEF,
+ IMAGEMAGICK_ALGORITHM,
+ IMAGEMAGICK_HEURISTIC_MASK,
+ IMAGEMAGICK_MASK,
+ IMAGEMAGICK_BACKGROUND,
+ IMAGEMAGICK_HEIGHT,
+ IMAGEMAGICK_WIDTH,
+ IMAGEMAGICK_ROTATION,
+ IMAGEMAGICK_CROP,
+ IMAGEMAGICK_LAST
+ };
+
+/* Vector of image_keyword structures describing the format
+ of valid user-defined image specifications. */
+
+static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
+ {
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":data", IMAGE_STRING_VALUE, 0},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
+ {":height", IMAGE_INTEGER_VALUE, 0},
+ {":width", IMAGE_INTEGER_VALUE, 0},
+ {":rotation", IMAGE_NUMBER_VALUE, 0},
+ {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ };
+/* Free X resources of imagemagick image IMG which is used on frame F. */
+
+static void
+imagemagick_clear_image (struct frame *f,
+ struct image *img)
+{
+ x_clear_image (f, img);
+}
+
+
+
+/* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do
+ this by calling parse_image_spec and supplying the keywords that
+ identify the IMAGEMAGICK format. */
+
+static int
+imagemagick_image_p (Lisp_Object object)
+{
+ struct image_keyword fmt[IMAGEMAGICK_LAST];
+ bcopy (imagemagick_format, fmt, sizeof fmt);
+
+ if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
+ return 0;
+
+ /* Must specify either the :data or :file keyword. */
+ return fmt[IMAGEMAGICK_FILE].count + fmt[IMAGEMAGICK_DATA].count == 1;
+}
+
+/* The GIF library also defines DrawRectangle, but its never used in Emacs.
+ Therefore rename the function so it doesnt collide with ImageMagick. */
+#define DrawRectangle DrawRectangleGif
+#include <wand/MagickWand.h>
+
+/* imagemagick_load_image is a helper function for imagemagick_load,
+ which does the actual loading given contents and size, apart from
+ frame and image structures, passed from imagemagick_load.
+
+ Uses librimagemagick to do most of the image processing.
+
+ non-zero when successful.
+*/
+
+static int
+imagemagick_load_image (/* Pointer to emacs frame structure. */
+ struct frame *f,
+ /* Pointer to emacs image structure. */
+ struct image *img,
+ /* String containing the IMAGEMAGICK data to
+ be parsed. */
+ unsigned char *contents,
+ /* Size of data in bytes. */
+ unsigned int size,
+ /* Filename, either pass filename or
+ contents/size. */
+ unsigned char *filename)
+{
+ size_t width;
+ size_t height;
+
+ MagickBooleanType
+ status;
+
+ XImagePtr ximg;
+ Lisp_Object specified_bg;
+ XColor background;
+ int x;
+ int y;
+
+ MagickWand *image_wand;
+ MagickWand *ping_wand;
+ PixelIterator *iterator;
+ PixelWand **pixels;
+ MagickPixelPacket pixel;
+ Lisp_Object image;
+ Lisp_Object value;
+ Lisp_Object crop, geometry;
+ long ino;
+ int desired_width, desired_height;
+ double rotation;
+ int imagemagick_rendermethod;
+ int pixelwidth;
+ ImageInfo *image_info;
+ ExceptionInfo *exception;
+ Image * im_image;
+
+
+ /* Handle image index for image types who can contain more than one
+ image. Interface :index is same as for GIF. First we "ping" the
+ image to see how many sub-images it contains. Pinging is faster
+ than loading the image to find out things about it. */
+ image = image_spec_value (img->spec, QCindex, NULL);
+ ino = INTEGERP (image) ? XFASTINT (image) : 0;
+ ping_wand=NewMagickWand();
+ MagickSetResolution(ping_wand, 2, 2);
+ if (filename != NULL)
+ {
+ status = MagickPingImage(ping_wand, filename);
+ }
+ else
+ {
+ status = MagickPingImageBlob(ping_wand, contents, size);
+ }
+
+ if (ino >= MagickGetNumberImages(ping_wand))
+ {
+ image_error ("Invalid image number `%s' in image `%s'",
+ image, img->spec);
+ UNGCPRO;
+ return 0;
+ }
+
+ if (MagickGetNumberImages(ping_wand) > 1)
+ img->data.lisp_val =
+ Fcons (Qcount,
+ Fcons (make_number (MagickGetNumberImages(ping_wand)),
+ img->data.lisp_val));
+
+ DestroyMagickWand (ping_wand);
+ /* Now, after pinging, we know how many images are inside the
+ file. If its not a bundle, just one. */
+
+ if (filename != NULL)
+ {
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ (void) strcpy(image_info->filename, filename);
+ image_info -> number_scenes = 1;
+ image_info -> scene = ino;
+ exception=AcquireExceptionInfo();
+
+ im_image = ReadImage (image_info, exception);
+ CatchException(exception);
+
+ image_wand = NewMagickWandFromImage(im_image);
+ }
+ else
+ {
+ image_wand = NewMagickWand();
+ status = MagickReadImageBlob(image_wand, contents, size);
+ }
+ image_error ("im read failed", Qnil, Qnil);
+ if (status == MagickFalse) goto imagemagick_error;
+
+ /* If width and/or height is set in the display spec assume we want
+ to scale to those values. if either h or w is unspecified, the
+ unspecified should be calculated from the specified to preserve
+ aspect ratio. */
+
+ value = image_spec_value (img->spec, QCwidth, NULL);
+ desired_width = (INTEGERP (value) ? XFASTINT (value) : -1);
+ value = image_spec_value (img->spec, QCheight, NULL);
+ desired_height = (INTEGERP (value) ? XFASTINT (value) : -1);
+
+ height = MagickGetImageHeight (image_wand);
+ width = MagickGetImageWidth (image_wand);
+
+ if(desired_width != -1 && desired_height == -1)
+ {
+ /* w known, calculate h. */
+ desired_height = ( (double)desired_width / width ) * height;
+ }
+ if(desired_width == -1 && desired_height != -1)
+ {
+ /* h known, calculate w. */
+ desired_width = ( (double)desired_height / height ) * width;
+ }
+ if(desired_width != -1 && desired_height != -1)
+ {
+ status = MagickScaleImage(image_wand, desired_width, desired_height);
+ if (status == MagickFalse) {
+ image_error ("Imagemagick scale failed", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+ }
+
+
+ /* crop behaves similar to image slicing in Emacs but is more memory
+ efficient */
+ crop = image_spec_value (img->spec, QCcrop, NULL);
+
+ if(CONSP (crop))
+ {
+ /*
+ after some testing, it seems MagickCropImage is the fastest
+ crop function in ImageMagick. This crop function seems to do
+ less copying than the alternatives, but it still reads the
+ entire image into memory before croping, which is aparently
+ difficult to avoid when using imagemagick. */
+
+ int w,h,x,y;
+ w=XFASTINT(XCAR(crop));
+ h=XFASTINT(XCAR(XCDR(crop)));
+ x=XFASTINT(XCAR(XCDR(XCDR(crop))));
+ y=XFASTINT(XCAR(XCDR(XCDR(XCDR(crop)))));
+ MagickCropImage(image_wand, w,h, x,y);
+ }
+
+ /* Furthermore :rotation. we need background color and angle for
+ rotation. */
+ /*
+ TODO background handling for rotation specified_bg =
+ image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
+ (specified_bg). */
+ value = image_spec_value (img->spec, QCrotation, NULL);
+ if (FLOATP (value))
+ {
+ PixelWand* background = NewPixelWand();
+ PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
+
+ rotation = extract_float (value);
+
+ status = MagickRotateImage (image_wand, background, rotation);
+ DestroyPixelWand (background);
+ if (status == MagickFalse)
+ {
+ image_error ("Imagemagick image rotate failed", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+ }
+
+ /* Finaly we are done manipulating the image, figure out resulting
+ width, height, and then transfer ownerwship to Emacs. */
+ height = MagickGetImageHeight (image_wand);
+ width = MagickGetImageWidth (image_wand);
+ if (status == MagickFalse)
+ {
+ image_error ("Imagemagick image get size failed", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
+ if (! check_image_size (f, width, height))
+ {
+ image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
+ /* We can now get a valid pixel buffer from the imagemagick file, if all
+ went ok. */
+
+ init_color_table ();
+ imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
+ ? XFASTINT (Vimagemagick_render_type) : 0);
+ if (imagemagick_rendermethod == 0)
+ {
+ /* Try to create a x pixmap to hold the imagemagick pixmap. */
+ if (!x_create_x_image_and_pixmap (f, width, height, 0,
+ &ximg, &img->pixmap))
+ {
+ image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
+ /* Copy imagegmagick image to x with primitive yet robust pixel
+ pusher loop. This has been tested a lot with many different
+ images. */
+
+ /* Copy pixels from the imagemagick image structure to the x image map. */
+ iterator = NewPixelIterator (image_wand);
+ if ((iterator == (PixelIterator *) NULL))
+ {
+ image_error ("Imagemagick pixel iterator creation failed",
+ Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
+ for (y = 0; y < (long) MagickGetImageHeight(image_wand); y++)
+ {
+ pixels = PixelGetNextIteratorRow (iterator, &width);
+ if ((pixels == (PixelWand **) NULL))
+ break;
+ for (x = 0; x < (long) width; x++)
+ {
+ PixelGetMagickColor (pixels[x], &pixel);
+ XPutPixel (ximg, x, y,
+ lookup_rgb_color (f,
+ pixel.red,
+ pixel.green,
+ pixel.blue));
+ }
+ }
+ DestroyPixelIterator (iterator);
+ }
+
+ if (imagemagick_rendermethod == 1)
+ {
+ /* Magicexportimage is normaly faster than pixelpushing. This
+ method is also well tested. Some aspects of this method are
+ ad-hoc and needs to be more researched. */
+ int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/
+ char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
+ /* Try to create a x pixmap to hold the imagemagick pixmap. */
+ if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
+ &ximg, &img->pixmap)){
+ image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
+
+ /* Oddly, the below code doesnt seem to work:*/
+ /* switch(ximg->bitmap_unit){ */
+ /* case 8: */
+ /* pixelwidth=CharPixel; */
+ /* break; */
+ /* case 16: */
+ /* pixelwidth=ShortPixel; */
+ /* break; */
+ /* case 32: */
+ /* pixelwidth=LongPixel; */
+ /* break; */
+ /* } */
+ /*
+ Here im just guessing the format of the bitmap.
+ happens to work fine for:
+ - bw djvu images
+ on rgb display.
+ seems about 3 times as fast as pixel pushing(not carefully measured)
+ */
+ pixelwidth = CharPixel;/*??? TODO figure out*/
+#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
+ MagickExportImagePixels(image_wand,
+ 0, 0,
+ width, height,
+ exportdepth,
+ pixelwidth,
+ /*&(img->pixmap));*/
+ ximg->data);
+#else
+ image_error("You dont have MagickExportImagePixels, upgrade ImageMagick!",
+ Qnil, Qnil);
+#endif
+ }
+
+
+#ifdef COLOR_TABLE_SUPPORT
+ /* Remember colors allocated for this image. */
+ img->colors = colors_in_color_table (&img->ncolors);
+ free_color_table ();
+#endif /* COLOR_TABLE_SUPPORT */
+
+
+ img->width = width;
+ img->height = height;
+
+ /* Put the image into the pixmap, then free the X image and its
+ buffer. */
+ x_put_x_image (f, ximg, img->pixmap, width, height);
+ x_destroy_x_image (ximg);
+
+
+ /* Final cleanup. image_wand should be the only resource left. */
+ DestroyMagickWand (image_wand);
+
+ return 1;
+
+ imagemagick_error:
+ /* TODO more cleanup. */
+ image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
+ return 0;
+}
+
+
+/* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if
+ successful. this function will go into the imagemagick_type structure, and
+ the prototype thus needs to be compatible with that structure. */
+
+static int
+imagemagick_load (struct frame *f,
+ struct image *img)
+{
+ int success_p = 0;
+ Lisp_Object file_name;
+
+ /* If IMG->spec specifies a file name, create a non-file spec from it. */
+ file_name = image_spec_value (img->spec, QCfile, NULL);
+ if (STRINGP (file_name))
+ {
+ Lisp_Object file;
+ unsigned char *contents;
+ int size;
+ struct gcpro gcpro1;
+
+ file = x_find_image_file (file_name);
+ GCPRO1 (file);
+ if (!STRINGP (file))
+ {
+ image_error ("Cannot find image file `%s'", file_name, Qnil);
+ UNGCPRO;
+ return 0;
+ }
+ success_p = imagemagick_load_image (f, img, 0, 0, SDATA(file_name));
+ UNGCPRO;
+ }
+ /* Else its not a file, its a lisp object. Load the image from a
+ lisp object rather than a file. */
+ else
+ {
+ Lisp_Object data;
+
+ data = image_spec_value (img->spec, QCdata, NULL);
+ success_p = imagemagick_load_image (f, img, SDATA (data),
+ SBYTES (data), NULL);
+ }
+
+ return success_p;
+}
+
+/* Structure describing the image type `imagemagick'. Its the same
+ type of structure defined for all image formats, handled by Emacs
+ image functions. See struct image_type in dispextern.h. */
+
+static struct image_type imagemagick_type =
+ {
+ /* An identifier showing that this is an image structure for the
+ IMAGEMAGICK format. */
+ &Qimagemagick,
+ /* Handle to a function that can be used to identify a IMAGEMAGICK
+ file. */
+ imagemagick_image_p,
+ /* Handle to function used to load a IMAGEMAGICK file. */
+ imagemagick_load,
+ /* Handle to function to free resources for IMAGEMAGICK. */
+ imagemagick_clear_image,
+ /* An internal field to link to the next image type in a list of
+ image types, will be filled in when registering the format. */
+ NULL
+ };
+
+
+
+
+DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
+ doc: /* Return image file types supported by ImageMagick.
+ Since ImageMagick recognizes a lot of file-types that clash with Emacs,
+ such as .c, we want to be able to alter the list at the lisp level. */)
+ (void)
+{
+ Lisp_Object typelist = Qnil;
+ size_t numf;
+ ExceptionInfo ex;
+ char** imtypes = GetMagickList ("*", &numf, &ex);
+ int i;
+ Lisp_Object Qimagemagicktype;
+ for (i = 0; i < numf; i++)
+ {
+ Qimagemagicktype = intern (imtypes[i]);
+ typelist = Fcons (Qimagemagicktype, typelist);
+ }
+ return typelist;
+}
+
+#endif /* defined (HAVE_IMAGEMAGICK) */
+
+
\f
/***********************************************************************
SVG
return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries);
#endif
+#if defined (HAVE_IMAGEMAGICK)
+ if (EQ (type, Qimagemagick)){
+ /* MagickWandGenesis() initalizes the imagemagick library. */
+ MagickWandGenesis();
+ return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
+ libraries);
+ }
+#endif
+
#ifdef HAVE_GHOSTSCRIPT
if (EQ (type, Qpostscript))
return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
staticpro (&QCheuristic_mask);
QCindex = intern_c_string (":index");
staticpro (&QCindex);
+ QCgeometry = intern (":geometry");
+ staticpro (&QCgeometry);
+ QCcrop = intern (":crop");
+ staticpro (&QCcrop);
+ QCrotation = intern (":rotation");
+ staticpro (&QCrotation);
QCmatrix = intern_c_string (":matrix");
staticpro (&QCmatrix);
QCcolor_adjustment = intern_c_string (":color-adjustment");
ADD_IMAGE_TYPE (Qpng);
#endif
+#if defined (HAVE_IMAGEMAGICK)
+ Qimagemagick = intern ("imagemagick");
+ staticpro (&Qimagemagick);
+ ADD_IMAGE_TYPE (Qimagemagick);
+#endif
+
#if defined (HAVE_RSVG)
Qsvg = intern_c_string ("svg");
staticpro (&Qsvg);
#endif /* HAVE_RSVG */
defsubr (&Sinit_image_library);
+#ifdef HAVE_IMAGEMAGICK
+ defsubr (&Simagemagick_types);
+#endif
defsubr (&Sclear_image_cache);
defsubr (&Simage_flush);
defsubr (&Simage_size);
The function `clear-image-cache' disregards this variable. */);
Vimage_cache_eviction_delay = make_number (300);
+#ifdef HAVE_IMAGEMAGICK
+ DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type,
+ doc: /* Choose between ImageMagick render methods. */);
+#endif
+
}
void
Lisp_Object Qinhibit_modification_hooks;
-extern Lisp_Object Vselect_active_regions, Vsaved_region_selection;
+extern Lisp_Object Vselect_active_regions, Vsaved_region_selection, Qonly;
\f
/* Check all markers in the current buffer, looking for something invalid. */
#endif /* not CLASH_DETECTION */
/* If `select-active-regions' is non-nil, save the region text. */
- if (!NILP (Vselect_active_regions)
- && !NILP (current_buffer->mark_active)
- && !NILP (Vtransient_mark_mode)
- && NILP (Vsaved_region_selection))
+ if (!NILP (current_buffer->mark_active)
+ && NILP (Vsaved_region_selection)
+ && (EQ (Vselect_active_regions, Qonly)
+ ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
+ : (!NILP (Vselect_active_regions)
+ && !NILP (Vtransient_mark_mode))))
{
int b = XINT (Fmarker_position (current_buffer->mark));
int e = XINT (make_number (PT));
Used by the `select-active-regions' feature. */
Lisp_Object Vsaved_region_selection;
-Lisp_Object Qx_set_selection, QPRIMARY, Qlazy;
+Lisp_Object Qx_set_selection, QPRIMARY;
Lisp_Object Qself_insert_command;
Lisp_Object Qforward_char;
Vtransient_mark_mode = Qnil;
else if (EQ (Vtransient_mark_mode, Qonly))
Vtransient_mark_mode = Qidentity;
- else if (EQ (Vselect_active_regions, Qlazy)
- ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
- : (!NILP (Vselect_active_regions)
- && !NILP (Vtransient_mark_mode)))
- {
- /* Set window selection. If `select-active-regions' is
- `lazy', only do it for temporarily active regions. */
- int beg = XINT (Fmarker_position (current_buffer->mark));
- int end = XINT (make_number (PT));
- if (beg < end)
- call2 (Qx_set_selection, QPRIMARY,
- make_buffer_string (beg, end, 0));
- else if (beg > end)
- call2 (Qx_set_selection, QPRIMARY,
- make_buffer_string (end, beg, 0));
- }
if (!NILP (Vdeactivate_mark))
+ /* If `select-active-regions' is non-nil, this call to
+ `deactivate-mark' also sets the PRIMARY selection. */
call0 (Qdeactivate_mark);
- else if (current_buffer != prev_buffer || MODIFF != prev_modiff)
- call1 (Vrun_hooks, intern ("activate-mark-hook"));
+ else
+ {
+ /* Even if not deactivating the mark, set PRIMARY if
+ `select-active-regions' is non-nil. */
+ if (EQ (Vselect_active_regions, Qonly)
+ ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
+ : (!NILP (Vselect_active_regions)
+ && !NILP (Vtransient_mark_mode)))
+ {
+ int beg = XINT (Fmarker_position (current_buffer->mark));
+ int end = XINT (make_number (PT));
+ if (beg < end)
+ call2 (Qx_set_selection, QPRIMARY,
+ make_buffer_string (beg, end, 0));
+ else if (beg > end)
+ call2 (Qx_set_selection, QPRIMARY,
+ make_buffer_string (end, beg, 0));
+ /* Don't set empty selections. */
+ }
+
+ if (current_buffer != prev_buffer || MODIFF != prev_modiff)
+ call1 (Vrun_hooks, intern ("activate-mark-hook"));
+ }
Vsaved_region_selection = Qnil;
}
0, /* VK_OEM_102 0xE2 */
"ico-help", /* VK_ICO_HELP 0xE3 */
"ico-00", /* VK_ICO_00 0xE4 */
- 0, /* VK_PROCESSKEY 0xE5 */
+ 0, /* VK_PROCESSKEY 0xE5 - used by IME */
"ico-clear", /* VK_ICO_CLEAR 0xE6 */
- "packet", /* VK_PACKET 0xE7 */
+ 0, /* VK_PACKET 0xE7 - used to pass unicode chars */
0, /* 0xE8 */
"reset", /* VK_OEM_RESET 0xE9 */
"jump", /* VK_OEM_JUMP 0xEA */
return 0;
}
else if (EQ (key, QChelp))
- /* `:help HELP-STRING'. */
- PROP (TOOL_BAR_ITEM_HELP) = value;
+ /* `:help HELP-STRING'. */
+ PROP (TOOL_BAR_ITEM_HELP) = value;
else if (EQ (key, QClabel))
{
+ const char *bad_label = "!!?GARBLED ITEM?!!";
/* `:label LABEL-STRING'. */
- PROP (TOOL_BAR_ITEM_LABEL) = value;
+ PROP (TOOL_BAR_ITEM_HELP) = STRINGP (value)
+ ? value
+ : make_string (bad_label, strlen (bad_label));
have_label = 1;
}
else if (EQ (key, QCfilter))
Lisp_Object capt = PROP (TOOL_BAR_ITEM_CAPTION);
const char *label = SYMBOLP (key) ? (char *) SDATA (SYMBOL_NAME (key)) : "";
const char *caption = STRINGP (capt) ? (char *) SDATA (capt) : "";
- char buf[64];
- EMACS_INT max_lbl = 2*tool_bar_max_label_size;
+ EMACS_INT max_lbl = 2 * tool_bar_max_label_size;
+ char *buf = (char *) xmalloc (max_lbl + 1);
Lisp_Object new_lbl;
+ size_t caption_len = strlen (caption);
- if (strlen (caption) < max_lbl && caption[0] != '\0')
+ if (caption_len <= max_lbl && caption[0] != '\0')
{
strcpy (buf, caption);
- while (buf[0] != '\0' && buf[strlen (buf) -1] == '.')
- buf[strlen (buf)-1] = '\0';
- if (strlen (buf) <= max_lbl)
- caption = buf;
+ while (caption_len > 0 && buf[caption_len - 1] == '.')
+ caption_len--;
+ buf[caption_len] = '\0';
+ label = caption = buf;
}
- if (strlen (caption) <= max_lbl)
- label = caption;
-
if (strlen (label) <= max_lbl && label[0] != '\0')
{
int i;
- if (label != buf) strcpy (buf, label);
+ if (label != buf)
+ strcpy (buf, label);
- for (i = 0; i < strlen (buf); ++i)
- {
- if (buf[i] == '-') buf[i] = ' ';
- }
+ for (i = 0; buf[i] != '\0'; ++i)
+ if (buf[i] == '-')
+ buf[i] = ' ';
label = buf;
}
- else label = "";
+ else
+ label = "";
new_lbl = Fupcase_initials (make_string (label, strlen (label)));
if (SCHARS (new_lbl) <= tool_bar_max_label_size)
PROP (TOOL_BAR_ITEM_LABEL) = new_lbl;
+ else
+ PROP (TOOL_BAR_ITEM_LABEL) = make_string ("", 0);
+ free (buf);
}
/* If got a filter apply it on binding. */
staticpro (&Qx_set_selection);
QPRIMARY = intern_c_string ("PRIMARY");
staticpro (&QPRIMARY);
- Qlazy = intern_c_string ("lazy");
- staticpro (&Qlazy);
Qinput_method_exit_on_first_char = intern_c_string ("input-method-exit-on-first-char");
staticpro (&Qinput_method_exit_on_first_char);
DEFVAR_LISP ("select-active-regions",
&Vselect_active_regions,
doc: /* If non-nil, an active region automatically becomes the window selection.
-This takes effect only when Transient Mark mode is enabled.
-
-If the value is `lazy', Emacs only sets the window selection during
-`deactivate-mark'; unless the region is temporarily active
-(e.g. mouse-drags or shift-selection), in which case it sets the
-window selection after each command.
+If the value is `only', only temporarily active regions (usually made
+by mouse-dragging or shift-selection) set the window selection.
-For other non-nil value, Emacs sets the window selection after every
-command. */);
- Vselect_active_regions = Qlazy;
+This takes effect only when Transient Mark mode is enabled. */);
+ Vselect_active_regions = Qt;
DEFVAR_LISP ("saved-region-selection",
&Vsaved_region_selection,
extern Lisp_Object Vdouble_click_time;
+/* The primary selection. */
+extern Lisp_Object QPRIMARY;
+
/* Forward declaration for prototypes. */
struct input_event;
x_set_font_backend, /* generic OK */
x_set_alpha,
0, /* x_set_sticky */
+ 0, /* x_set_tool_bar_position */
};
#include "lisp.h"
#include "nsterm.h"
#include "termhooks.h"
+#include "keyboard.h"
#define CUT_BUFFER_SUPPORT
-Lisp_Object QPRIMARY, QSECONDARY, QTEXT, QFILE_NAME;
+Lisp_Object QCLIPBOARD, QSECONDARY, QTEXT, QFILE_NAME;
static Lisp_Object Vns_sent_selection_hooks;
static Lisp_Object Vns_lost_selection_hooks;
static Lisp_Object Qforeign_selection;
+/* NSGeneralPboard is pretty much analogous to X11 CLIPBOARD */
+NSString *NXPrimaryPboard;
NSString *NXSecondaryPboard;
symbol_to_nsstring (Lisp_Object sym)
{
CHECK_SYMBOL (sym);
- if (EQ (sym, QPRIMARY)) return NSGeneralPboard;
+ if (EQ (sym, QCLIPBOARD)) return NSGeneralPboard;
+ if (EQ (sym, QPRIMARY)) return NXPrimaryPboard;
if (EQ (sym, QSECONDARY)) return NXSecondaryPboard;
if (EQ (sym, QTEXT)) return NSStringPboardType;
return [NSString stringWithUTF8String: SDATA (XSYMBOL (sym)->xname)];
ns_string_to_symbol (NSString *t)
{
if ([t isEqualToString: NSGeneralPboard])
+ return QCLIPBOARD;
+ if ([t isEqualToString: NXPrimaryPboard])
return QPRIMARY;
if ([t isEqualToString: NXSecondaryPboard])
return QSECONDARY;
void
nxatoms_of_nsselect (void)
{
- NXSecondaryPboard = @"Selection";
+ NXPrimaryPboard = @"Selection";
+ NXSecondaryPboard = @"Secondary";
}
void
syms_of_nsselect (void)
{
- QPRIMARY = intern ("PRIMARY"); staticpro (&QPRIMARY);
+ QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
QSECONDARY = intern ("SECONDARY"); staticpro (&QSECONDARY);
QTEXT = intern ("TEXT"); staticpro (&QTEXT);
QFILE_NAME = intern ("FILE_NAME"); staticpro (&QFILE_NAME);
EmacsView *view = FRAME_NS_VIEW (f);
FRAME_POINTER_TYPE (f) = cursor;
[[view window] invalidateCursorRectsForView: view];
+ /* Redisplay assumes this function also draws the changed frame
+ cursor, but this function doesn't, so do it explicitly. */
+ x_update_cursor (f, 1);
}
}
HIMC context;
struct window *w;
- if (!context)
- break;
-
f = x_window_to_frame (dpyinfo, hwnd);
w = XWINDOW (FRAME_SELECTED_WINDOW (f));
- WINDOW_MODE_LINE_HEIGHT (w));
context = get_ime_context_fn (hwnd);
+
+ if (!context)
+ break;
+
set_ime_composition_window_fn (context, &form);
release_ime_context_fn (hwnd, context);
}
x_set_font_backend,
x_set_alpha,
0, /* x_set_sticky */
+ 0, /* x_set_tool_bar_position */
};
void
IN UINT,
IN BOOL,
IN LPCMENUITEMINFOA);
+typedef int (WINAPI * MessageBoxW_Proc) (
+ IN HWND window,
+ IN WCHAR *text,
+ IN WCHAR *caption,
+ IN UINT type);
GetMenuItemInfoA_Proc get_menu_item_info = NULL;
SetMenuItemInfoA_Proc set_menu_item_info = NULL;
AppendMenuW_Proc unicode_append_menu = NULL;
+MessageBoxW_Proc unicode_message_box = NULL;
Lisp_Object Qdebug_on_next_call;
static Lisp_Object simple_dialog_show (FRAME_PTR, Lisp_Object, Lisp_Object);
#endif
+static void utf8to16 (unsigned char *, int, WCHAR *);
+
void w32_free_menu_strings (HWND);
\f
set_buffer_internal_1 (XBUFFER (buffer));
- /* Run the Lucid hook. */
+ /* Run the hooks. */
safe_run_hooks (Qactivate_menubar_hook);
- /* If it has changed current-menubar from previous value,
- really recompute the menubar from the value. */
- if (! NILP (Vlucid_menu_bar_dirty_flag))
- call0 (Qrecompute_lucid_menubar);
safe_run_hooks (Qmenu_bar_update_hook);
FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
{
int answer;
UINT type;
- char *text, *title;
Lisp_Object lispy_answer = Qnil, temp = XCAR (contents);
- if (STRINGP (temp))
- text = SDATA (temp);
- else
- text = "";
+ type = MB_YESNO;
+
+ /* Since we only handle Yes/No dialogs, and we already checked
+ is_simple_dialog, we don't need to worry about checking contents
+ to see what type of dialog to use. */
- if (NILP (header))
+ /* Use unicode if possible, so any language can be displayed. */
+ if (unicode_message_box)
{
- title = "Question";
- type = MB_ICONQUESTION;
+ WCHAR *text, *title;
+
+ if (STRINGP (temp))
+ {
+ char *utf8_text = SDATA (ENCODE_UTF_8 (temp));
+ /* Be pessimistic about the number of characters needed.
+ Remember characters outside the BMP will take more than
+ one utf16 word, so we cannot simply use the character
+ length of temp. */
+ int utf8_len = strlen (utf8_text);
+ text = alloca ((utf8_len + 1) * sizeof (WCHAR));
+ utf8to16 (utf8_text, utf8_len, text);
+ }
+ else
+ {
+ text = L"";
+ }
+
+ if (NILP (header))
+ {
+ title = L"Question";
+ type |= MB_ICONQUESTION;
+ }
+ else
+ {
+ title = L"Information";
+ type |= MB_ICONINFORMATION;
+ }
+
+ answer = unicode_message_box (FRAME_W32_WINDOW (f), text, title, type);
}
else
{
- title = "Information";
- type = MB_ICONINFORMATION;
- }
- type |= MB_YESNO;
+ char *text, *title;
- /* Since we only handle Yes/No dialogs, and we already checked
- is_simple_dialog, we don't need to worry about checking contents
- to see what type of dialog to use. */
- answer = MessageBox (FRAME_W32_WINDOW (f), text, title, type);
+ /* Fall back on ANSI message box, but at least use system
+ encoding so questions representable by the system codepage
+ are encoded properly. */
+ if (STRINGP (temp))
+ text = SDATA (ENCODE_SYSTEM (temp));
+ else
+ text = "";
+
+ if (NILP (header))
+ {
+ title = "Question";
+ type |= MB_ICONQUESTION;
+ }
+ else
+ {
+ title = "Information";
+ type |= MB_ICONINFORMATION;
+ }
+
+ answer = MessageBox (FRAME_W32_WINDOW (f), text, title, type);
+ }
if (answer == IDYES)
lispy_answer = build_string ("Yes");
get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
unicode_append_menu = (AppendMenuW_Proc) GetProcAddress (user32, "AppendMenuW");
+ unicode_message_box = (MessageBoxW_Proc) GetProcAddress (user32, "MessageBoxW");
}
/* arch-tag: 0eaed431-bb4e-4aac-a527-95a1b4f1fed0
if (s->hl == DRAW_CURSOR
&& !x_stretch_cursor_p)
{
- /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
- as wide as the stretch glyph. */
+ /* If `x-stretch-cursor' is nil, don't draw a block cursor as
+ wide as the stretch glyph. */
int width, background_width = s->background_width;
- int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+ int x = s->x;
- if (x < left_x)
+ if (!s->row->reversed_p)
{
- background_width -= left_x - x;
- x = left_x;
+ int left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ }
+ else
+ {
+ /* In R2L rows, draw the cursor on the right edge of the
+ stretch glyph. */
+ int right_x = window_box_right_offset (s->w, TEXT_AREA);
+
+ if (x + background_width > right_x)
+ background_width -= x - right_x;
+ x += background_width;
}
width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
+ if (s->row->reversed_p)
+ x -= width;
/* Draw cursor. */
x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
RECT r;
HDC hdc = s->hdc;
- x += width;
+ if (!s->row->reversed_p)
+ x += width;
+ else
+ x = s->x;
if (s->row->mouse_face_p
&& cursor_in_mouse_face_p (s->w))
{
w->phys_cursor_width = width;
+ /* If the character under cursor is R2L, draw the bar cursor
+ on the right of its glyph, rather than on the left. */
+ if ((cursor_glyph->resolved_level & 1) != 0)
+ x += cursor_glyph->pixel_width - width;
+
w32_fill_area (f, hdc, cursor_color, x,
WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
width, row->height);
glyph with suitably computed width. Both the blanks and the
stretch glyph are given the face of the background of the line.
This way, the terminal-specific back-end can still draw the glyphs
- left to right, even for R2L lines. */
+ left to right, even for R2L lines.
+
+ Note one important detail mentioned above: that the bidi reordering
+ engine, driven by the iterator, produces characters in R2L rows
+ starting at the character that will be the rightmost on display.
+ As far as the iterator is concerned, the geometry of such rows is
+ still left to right, i.e. the iterator "thinks" the first character
+ is at the leftmost pixel position. The iterator does not know that
+ PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
+ delivers. This is important when functions from the the move_it_*
+ family are used to get to certain screen position or to match
+ screen coordinates with buffer coordinates: these functions use the
+ iterator geometry, which is left to right even in R2L paragraphs.
+ This works well with most callers of move_it_*, because they need
+ to get to a specific column, and columns are still numbered in the
+ reading order, i.e. the rightmost character in a R2L paragraph is
+ still column zero. But some callers do not get well with this; a
+ notable example is mouse clicks that need to find the character
+ that corresponds to certain pixel coordinates. See
+ buffer_posn_from_coords in dispnew.c for how this is handled. */
#include <config.h>
#include <stdio.h>
/* Return the window-relative coordinate of the right edge of display
- area AREA of window W. AREA < 0 means return the left edge of the
+ area AREA of window W. AREA < 0 means return the right edge of the
whole window, to the left of the right fringe of W. */
INLINE int
/* Return the frame-relative coordinate of the right edge of display
- area AREA of window W. AREA < 0 means return the left edge of the
+ area AREA of window W. AREA < 0 means return the right edge of the
whole window, to the left of the right fringe of W. */
INLINE int
struct bidi_it itb;
EMACS_INT pos = BUF_PT (buf);
EMACS_INT bytepos = BUF_PT_BYTE (buf);
+ int c;
if (buf != current_buffer)
set_buffer_temp (buf);
- /* Find previous non-empty line. */
+ /* bidi_paragraph_init finds the base direction of the paragraph
+ by searching forward from paragraph start. We need the base
+ direction of the current or _previous_ paragraph, so we need
+ to make sure we are within that paragraph. To that end, find
+ the previous non-empty line. */
if (pos >= ZV && pos > BEGV)
{
pos--;
bytepos = CHAR_TO_BYTE (pos);
}
- while (FETCH_BYTE (bytepos) == '\n')
+ while ((c = FETCH_BYTE (bytepos)) == '\n'
+ || c == ' ' || c == '\t' || c == '\f')
{
if (bytepos <= BEGV_BYTE)
break;
itb.charpos = pos;
itb.bytepos = bytepos;
itb.first_elt = 1;
+ itb.separator_limit = -1;
bidi_paragraph_init (NEUTRAL_DIR, &itb);
if (buf != current_buffer)
"waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
x_default_parameter (f, parms, Qfullscreen, Qnil,
"fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
+ x_default_parameter (f, parms, Qtool_bar_position,
+ f->tool_bar_position, 0, 0, RES_TYPE_SYMBOL);
/* Compute the size of the X window. */
window_prompting = x_figure_window_size (f, parms, 1);
#define CUT_BUFFER_SUPPORT
-Lisp_Object QPRIMARY, QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP,
+Lisp_Object QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP,
QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL,
QATOM_PAIR;
if (s->hl == DRAW_CURSOR
&& !x_stretch_cursor_p)
{
- /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
- as wide as the stretch glyph. */
+ /* If `x-stretch-cursor' is nil, don't draw a block cursor as
+ wide as the stretch glyph. */
int width, background_width = s->background_width;
- int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+ int x = s->x;
- if (x < left_x)
+ if (!s->row->reversed_p)
{
- background_width -= left_x - x;
- x = left_x;
+ int left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ }
+ else
+ {
+ /* In R2L rows, draw the cursor on the right edge of the
+ stretch glyph. */
+ int right_x = window_box_right_offset (s->w, TEXT_AREA);
+
+ if (x + background_width > right_x)
+ background_width -= x - right_x;
+ x += background_width;
}
width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
+ if (s->row->reversed_p)
+ x -= width;
/* Draw cursor. */
x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
XRectangle r;
GC gc;
- x += width;
+ if (!s->row->reversed_p)
+ x += width;
+ else
+ x = s->x;
if (s->row->mouse_face_p
&& cursor_in_mouse_face_p (s->w))
{
if (kind == BAR_CURSOR)
{
+ int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+
if (width < 0)
width = FRAME_CURSOR_WIDTH (f);
width = min (cursor_glyph->pixel_width, width);
w->phys_cursor_width = width;
- XFillRectangle (dpy, window, gc,
- WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
+ /* If the character under cursor is R2L, draw the bar cursor
+ on the right of its glyph, rather than on the left. */
+ if ((cursor_glyph->resolved_level & 1) != 0)
+ x += cursor_glyph->pixel_width - width;
+
+ XFillRectangle (dpy, window, gc, x,
WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
width, row->height);
}