------------------------------------------------------------ revno: 114797 committer: Dmitry Antipov branch nick: trunk timestamp: Fri 2013-10-25 11:28:16 +0400 message: Perform font-specific cleanup when font object is swept by GC. See http://lists.gnu.org/archive/html/emacs-devel/2013-10/msg00740.html. * alloc.c (cleanup_vector): New function. (sweep_vector): Call it for each reclaimed vector object. * font.h (struct font): Adjust comment. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-10-25 06:55:36 +0000 +++ src/ChangeLog 2013-10-25 07:28:16 +0000 @@ -9,9 +9,15 @@ * nsfont.m (nsfont_close): * w32font.c (w32font_close): * xfont.c (xfont_close): - * xftfont.c (xftfont_close): Adjust driver-specific close - functions, tweak comments and make functions safe if called - more than once for the same font object. + * xftfont.c (xftfont_close): Adjust driver-specific close functions, + tweak comments and make functions safe if called more than once for + the same font object. + + Perform font-specific cleanup when font object is swept by GC. See + http://lists.gnu.org/archive/html/emacs-devel/2013-10/msg00740.html. + * alloc.c (cleanup_vector): New function. + (sweep_vector): Call it for each reclaimed vector object. + * font.h (struct font): Adjust comment. 2013-10-24 Glenn Morris === modified file 'src/alloc.c' --- src/alloc.c 2013-10-23 16:07:30 +0000 +++ src/alloc.c 2013-10-25 07:28:16 +0000 @@ -2837,6 +2837,19 @@ return vroundup (size); } +/* Release extra resources still in use by VECTOR, which may be any + vector-like object. For now, this is used just to free data in + font objects. */ + +static void +cleanup_vector (struct Lisp_Vector *vector) +{ + if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT) + && ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) + == FONT_OBJECT_MAX)) + ((struct font *) vector)->driver->close ((struct font *) vector); +} + /* Reclaim space used by unmarked vectors. */ static void @@ -2871,6 +2884,7 @@ { ptrdiff_t total_bytes; + cleanup_vector (vector); nbytes = vector_nbytes (vector); total_bytes = nbytes; next = ADVANCE (vector, nbytes); @@ -2882,6 +2896,7 @@ { if (VECTOR_MARKED_P (next)) break; + cleanup_vector (next); nbytes = vector_nbytes (next); total_bytes += nbytes; next = ADVANCE (next, nbytes); === modified file 'src/font.h' --- src/font.h 2013-10-25 06:55:36 +0000 +++ src/font.h 2013-10-25 07:28:16 +0000 @@ -545,7 +545,7 @@ Lisp_Object (*open) (struct frame *f, Lisp_Object font_entity, int pixel_size); - /* Close FONT. */ + /* Close FONT. NOTE: this can be called by GC. */ void (*close) (struct font *font); /* Optional (if FACE->extra is not used). ------------------------------------------------------------ revno: 114796 committer: Dmitry Antipov branch nick: trunk timestamp: Fri 2013-10-25 10:55:36 +0400 message: Omit unused frame argument of font API's close function. * font.h (struct font): Drop frame argument. Adjust comment. * font.c (font_clear_cache, font_close_object): Adjust users. * ftfont.c (ftfont_close): * ftxfont.c (ftxfont_close): * macfont.m (macfont_close): * nsfont.m (nsfont_close): * w32font.c (w32font_close): * xfont.c (xfont_close): * xftfont.c (xftfont_close): Adjust driver-specific close functions, tweak comments and make functions safe if called more than once for the same font object. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-10-24 07:04:01 +0000 +++ src/ChangeLog 2013-10-25 06:55:36 +0000 @@ -1,3 +1,18 @@ +2013-10-25 Dmitry Antipov + + Omit unused frame argument of font API's close function. + * font.h (struct font): Drop frame argument. Adjust comment. + * font.c (font_clear_cache, font_close_object): Adjust users. + * ftfont.c (ftfont_close): + * ftxfont.c (ftxfont_close): + * macfont.m (macfont_close): + * nsfont.m (nsfont_close): + * w32font.c (w32font_close): + * xfont.c (xfont_close): + * xftfont.c (xftfont_close): Adjust driver-specific close + functions, tweak comments and make functions safe if called + more than once for the same font object. + 2013-10-24 Glenn Morris * Makefile.in (abs_top_srcdir): New, set by configure. === modified file 'src/font.c' --- src/font.c 2013-09-16 15:55:02 +0000 +++ src/font.c 2013-10-25 06:55:36 +0000 @@ -2591,7 +2591,7 @@ if (! NILP (AREF (val, FONT_TYPE_INDEX))) { eassert (font && driver == font->driver); - driver->close (f, font); + driver->close (font); } } if (driver->free_entity) @@ -2892,7 +2892,7 @@ /* Already closed. */ return; FONT_ADD_LOG ("close", font_object, Qnil); - font->driver->close (f, font); + font->driver->close (font); #ifdef HAVE_WINDOW_SYSTEM eassert (FRAME_DISPLAY_INFO (f)->n_fonts); FRAME_DISPLAY_INFO (f)->n_fonts--; === modified file 'src/font.h' --- src/font.h 2013-09-15 17:58:46 +0000 +++ src/font.h 2013-10-25 06:55:36 +0000 @@ -545,8 +545,8 @@ Lisp_Object (*open) (struct frame *f, Lisp_Object font_entity, int pixel_size); - /* Close FONT on frame F. */ - void (*close) (struct frame *f, struct font *font); + /* Close FONT. */ + void (*close) (struct font *font); /* Optional (if FACE->extra is not used). Prepare FACE for displaying characters by FONT on frame F by === modified file 'src/ftfont.c' --- src/ftfont.c 2013-10-11 06:32:29 +0000 +++ src/ftfont.c 2013-10-25 06:55:36 +0000 @@ -498,7 +498,7 @@ static Lisp_Object ftfont_match (struct frame *, Lisp_Object); static Lisp_Object ftfont_list_family (struct frame *); static Lisp_Object ftfont_open (struct frame *, Lisp_Object, int); -static void ftfont_close (struct frame *, struct font *); +static void ftfont_close (struct font *); static int ftfont_has_char (Lisp_Object, int); static unsigned ftfont_encode_char (struct font *, int); static int ftfont_text_extents (struct font *, unsigned *, int, @@ -1317,7 +1317,7 @@ } static void -ftfont_close (struct frame *f, struct font *font) +ftfont_close (struct font *font) { struct ftfont_info *ftfont_info = (struct ftfont_info *) font; Lisp_Object val, cache; === modified file 'src/ftxfont.c' --- src/ftxfont.c 2013-08-03 03:29:03 +0000 +++ src/ftxfont.c 2013-10-25 06:55:36 +0000 @@ -260,9 +260,9 @@ } static void -ftxfont_close (struct frame *f, struct font *font) +ftxfont_close (struct font *font) { - ftfont_driver.close (f, font); + ftfont_driver.close (font); } static int === modified file 'src/macfont.m' --- src/macfont.m 2013-10-11 06:32:29 +0000 +++ src/macfont.m 2013-10-25 06:55:36 +0000 @@ -1518,7 +1518,7 @@ static Lisp_Object macfont_list_family (struct frame *); static void macfont_free_entity (Lisp_Object); static Lisp_Object macfont_open (struct frame *, Lisp_Object, int); -static void macfont_close (struct frame *, struct font *); +static void macfont_close (struct font *); static int macfont_has_char (Lisp_Object, int); static unsigned macfont_encode_char (struct font *, int); static int macfont_text_extents (struct font *, unsigned int *, int, @@ -2580,23 +2580,28 @@ } static void -macfont_close (struct frame * f, struct font *font) +macfont_close (struct font *font) { struct macfont_info *macfont_info = (struct macfont_info *) font; - int i; - - block_input (); - CFRelease (macfont_info->macfont); - CGFontRelease (macfont_info->cgfont); - if (macfont_info->screen_font) - CFRelease (macfont_info->screen_font); - macfont_release_cache (macfont_info->cache); - for (i = 0; i < macfont_info->metrics_nrows; i++) - if (macfont_info->metrics[i]) - xfree (macfont_info->metrics[i]); - if (macfont_info->metrics) - xfree (macfont_info->metrics); - unblock_input (); + + if (macfont_info->cache) + { + int i; + + block_input (); + CFRelease (macfont_info->macfont); + CGFontRelease (macfont_info->cgfont); + if (macfont_info->screen_font) + CFRelease (macfont_info->screen_font); + macfont_release_cache (macfont_info->cache); + macfont_info->cache = NULL; + for (i = 0; i < macfont_info->metrics_nrows; i++) + if (macfont_info->metrics[i]) + xfree (macfont_info->metrics[i]); + if (macfont_info->metrics) + xfree (macfont_info->metrics); + unblock_input (); + } } static int === modified file 'src/nsfont.m' --- src/nsfont.m 2013-09-22 14:26:10 +0000 +++ src/nsfont.m 2013-10-25 06:55:36 +0000 @@ -624,7 +624,7 @@ static Lisp_Object nsfont_list_family (struct frame *); static Lisp_Object nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size); -static void nsfont_close (struct frame *f, struct font *font); +static void nsfont_close (struct font *font); static int nsfont_has_char (Lisp_Object entity, int c); static unsigned int nsfont_encode_char (struct font *font, int c); static int nsfont_text_extents (struct font *font, unsigned int *code, @@ -929,29 +929,30 @@ } -/* Close FONT on frame F. */ +/* Close FONT. */ static void -nsfont_close (struct frame *f, struct font *font) +nsfont_close (struct font *font) { - struct nsfont_info *font_info = (struct nsfont_info *)font; - int i; - - /* FIXME: this occurs apparently due to same failure to detect same font - that causes need for cache in nsfont_open () */ - if (!font_info) - return; - - for (i =0; i<0x100; i++) + struct nsfont_info *font_info = (struct nsfont_info *) font; + + /* FIXME: font_info may be NULL due to same failure to detect + same font that causes need for cache in nsfont_open. */ + if (font_info && font_info->name) { - xfree (font_info->glyphs[i]); - xfree (font_info->metrics[i]); - } - [font_info->nsfont release]; + int i; + + for (i = 0; i < 0x100; i++) + { + xfree (font_info->glyphs[i]); + xfree (font_info->metrics[i]); + } + [font_info->nsfont release]; #ifdef NS_IMPL_COCOA - CGFontRelease (font_info->cgfont); + CGFontRelease (font_info->cgfont); #endif - xfree (font_info->name); - xfree (font_info); + xfree (font_info->name); + font_info->name = NULL; + } } === modified file 'src/w32font.c' --- src/w32font.c 2013-09-13 15:03:51 +0000 +++ src/w32font.c 2013-10-25 06:55:36 +0000 @@ -376,26 +376,26 @@ return font_object; } -/* w32 implementation of close for font_backend. - Close FONT on frame F. */ +/* w32 implementation of close for font_backend. */ void -w32font_close (struct frame *f, struct font *font) +w32font_close (struct font *font) { - int i; struct w32font_info *w32_font = (struct w32font_info *) font; - /* Delete the GDI font object. */ - DeleteObject (w32_font->hfont); - - /* Free all the cached metrics. */ - if (w32_font->cached_metrics) + if (w32_font->hfont) { - for (i = 0; i < w32_font->n_cache_blocks; i++) - { - xfree (w32_font->cached_metrics[i]); - } - xfree (w32_font->cached_metrics); - w32_font->cached_metrics = NULL; + /* Delete the GDI font object. */ + DeleteObject (w32_font->hfont); + w32_font->hfont = NULL; + + /* Free all the cached metrics. */ + if (w32_font->cached_metrics) + { + for (i = 0; i < w32_font->n_cache_blocks; i++) + xfree (w32_font->cached_metrics[i]); + xfree (w32_font->cached_metrics); + w32_font->cached_metrics = NULL; + } } } === modified file 'src/xfont.c' --- src/xfont.c 2013-09-24 06:43:20 +0000 +++ src/xfont.c 2013-10-25 06:55:36 +0000 @@ -119,7 +119,7 @@ static Lisp_Object xfont_match (struct frame *, Lisp_Object); static Lisp_Object xfont_list_family (struct frame *); static Lisp_Object xfont_open (struct frame *, Lisp_Object, int); -static void xfont_close (struct frame *, struct font *); +static void xfont_close (struct font *); static int xfont_prepare_face (struct frame *, struct face *); static int xfont_has_char (Lisp_Object, int); static unsigned xfont_encode_char (struct font *, int); @@ -890,11 +890,17 @@ } static void -xfont_close (struct frame *f, struct font *font) +xfont_close (struct font *font) { - block_input (); - XFreeFont (FRAME_X_DISPLAY (f), ((struct xfont_info *) font)->xfont); - unblock_input (); + struct xfont_info *xfi = (struct xfont_info *) font; + + if (xfi->xfont) + { + block_input (); + XFreeFont (xfi->display, xfi->xfont); + unblock_input (); + xfi->xfont = NULL; + } } static int === modified file 'src/xftfont.c' --- src/xftfont.c 2013-08-03 03:29:03 +0000 +++ src/xftfont.c 2013-10-25 06:55:36 +0000 @@ -486,18 +486,26 @@ } static void -xftfont_close (struct frame *f, struct font *font) +xftfont_close (struct font *font) { struct xftfont_info *xftfont_info = (struct xftfont_info *) font; #ifdef HAVE_LIBOTF if (xftfont_info->otf) - OTF_close (xftfont_info->otf); + { + OTF_close (xftfont_info->otf); + xftfont_info->otf = NULL; + } #endif - block_input (); - XftUnlockFace (xftfont_info->xftfont); - XftFontClose (xftfont_info->display, xftfont_info->xftfont); - unblock_input (); + + if (xftfont_info->xftfont) + { + block_input (); + XftUnlockFace (xftfont_info->xftfont); + XftFontClose (xftfont_info->display, xftfont_info->xftfont); + unblock_input (); + xftfont_info->xftfont = NULL; + } } static int ------------------------------------------------------------ revno: 114795 committer: Dmitry Gutov branch nick: trunk timestamp: Fri 2013-10-25 08:35:56 +0400 message: * lisp/progmodes/ruby-mode.el (ruby-mode-menu): Use proper capitalization. Use :visible instead of :active. Fix `ruby-indent-exp' reference. Add menu items for the generic commands that are used with SMIE. (ruby-do-end-to-brace): Insert space after `{'. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-25 02:38:39 +0000 +++ lisp/ChangeLog 2013-10-25 04:35:56 +0000 @@ -1,3 +1,11 @@ +2013-10-25 Dmitry Gutov + + * progmodes/ruby-mode.el (ruby-mode-menu): Use proper + capitalization. Use :visible instead of :active. Fix + `ruby-indent-exp' reference. Add menu items for the generic + commands that are used with SMIE. + (ruby-do-end-to-brace): Insert space after `{'. + 2013-10-25 John Anthony * progmodes/ruby-mode.el (ruby-mode-menu): Add a menu. (Bug#15600) === modified file 'lisp/progmodes/ruby-mode.el' --- lisp/progmodes/ruby-mode.el 2013-10-25 02:38:39 +0000 +++ lisp/progmodes/ruby-mode.el 2013-10-25 04:35:56 +0000 @@ -165,16 +165,22 @@ ruby-mode-map "Ruby Mode Menu" '("Ruby" - ["Beginning Of Block" ruby-beginning-of-block t] - ["End Of Block" ruby-end-of-block t] + ["Beginning of Block" ruby-beginning-of-block t] + ["End of Block" ruby-end-of-block t] ["Toggle Block" ruby-toggle-block t] "--" ["Backward Sexp" ruby-backward-sexp - :active (not ruby-use-smie)] + :visible (not ruby-use-smie)] + ["Backward Sexp" backward-sexp + :visible ruby-use-smie] ["Forward Sexp" ruby-forward-sexp - :active (not ruby-use-smie)] - ["Indent Sexp" ruby-indent-sexp - :active (not ruby-use-smie)])) + :visible (not ruby-use-smie)] + ["Forward Sexp" forward-sexp + :visible ruby-use-smie] + ["Indent Sexp" ruby-indent-exp + :visible (not ruby-use-smie)] + ["Indent Sexp" prog-indent-sexp + :visible ruby-use-smie])) (defvar ruby-mode-syntax-table (let ((table (make-syntax-table))) @@ -1461,7 +1467,8 @@ (insert "}") (goto-char orig) (delete-char 2) - (insert "{") + ;; Maybe this should be customizable, let's see if anyone asks. + (insert "{ ") (setq beg-marker (point-marker)) (when (looking-at "\\s +|") (delete-char (- (match-end 0) (match-beginning 0) 1)) ------------------------------------------------------------ revno: 114794 fixes bug: http://debbugs.gnu.org/15600 author: John Anthony committer: Glenn Morris branch nick: trunk timestamp: Thu 2013-10-24 19:38:39 -0700 message: * lisp/progmodes/ruby-mode.el (ruby-mode-menu): Add a menu diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-25 02:35:55 +0000 +++ lisp/ChangeLog 2013-10-25 02:38:39 +0000 @@ -1,6 +1,8 @@ 2013-10-25 John Anthony - * progmodes/inf-lisp.el (inferior-lisp-menu): Add menu. (Bug#15599) + * progmodes/ruby-mode.el (ruby-mode-menu): Add a menu. (Bug#15600) + + * progmodes/inf-lisp.el (inferior-lisp-menu): Add a menu. (Bug#15599) 2013-10-25 Glenn Morris === modified file 'lisp/progmodes/ruby-mode.el' --- lisp/progmodes/ruby-mode.el 2013-10-24 00:47:28 +0000 +++ lisp/progmodes/ruby-mode.el 2013-10-25 02:38:39 +0000 @@ -160,6 +160,22 @@ map) "Keymap used in Ruby mode.") +(easy-menu-define + ruby-mode-menu + ruby-mode-map + "Ruby Mode Menu" + '("Ruby" + ["Beginning Of Block" ruby-beginning-of-block t] + ["End Of Block" ruby-end-of-block t] + ["Toggle Block" ruby-toggle-block t] + "--" + ["Backward Sexp" ruby-backward-sexp + :active (not ruby-use-smie)] + ["Forward Sexp" ruby-forward-sexp + :active (not ruby-use-smie)] + ["Indent Sexp" ruby-indent-sexp + :active (not ruby-use-smie)])) + (defvar ruby-mode-syntax-table (let ((table (make-syntax-table))) (modify-syntax-entry ?\' "\"" table) ------------------------------------------------------------ revno: 114793 fixes bug: http://debbugs.gnu.org/15599 author: John Anthony committer: Glenn Morris branch nick: trunk timestamp: Thu 2013-10-24 19:35:55 -0700 message: * lisp/progmodes/inf-lisp.el (inferior-lisp-menu): Add menu. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-25 02:33:42 +0000 +++ lisp/ChangeLog 2013-10-25 02:35:55 +0000 @@ -1,3 +1,7 @@ +2013-10-25 John Anthony + + * progmodes/inf-lisp.el (inferior-lisp-menu): Add menu. (Bug#15599) + 2013-10-25 Glenn Morris * vc/vc.el (vc-print-log): Don't use a working revision unless @@ -617,7 +621,7 @@ * textmodes/text-mode.el (text-mode-map): Use auto-fill help text from menu-bar.el. -2013-10-10 John Anthony (tiny change) +2013-10-10 John Anthony * textmodes/text-mode.el (text-mode-map): Add a menu. (Bug#15562) === modified file 'lisp/progmodes/inf-lisp.el' --- lisp/progmodes/inf-lisp.el 2013-02-22 01:59:28 +0000 +++ lisp/progmodes/inf-lisp.el 2013-10-25 02:35:55 +0000 @@ -91,6 +91,21 @@ (define-key map "\C-c\C-v" 'lisp-show-variable-documentation) map)) +(easy-menu-define + inferior-lisp-menu + inferior-lisp-mode-map + "Inferior Lisp Menu" + '("Inf-Lisp" + ["Eval Last Sexp" lisp-eval-last-sexp t] + "--" + ["Load File..." lisp-load-file t] + ["Compile File..." lisp-compile-file t] + "--" + ["Show Arglist..." lisp-show-arglist t] + ["Describe Symbol..." lisp-describe-sym t] + ["Show Documentation for Function..." lisp-show-function-documentation t] + ["Show Documentation for Variable..." lisp-show-variable-documentation t])) + ;;; These commands augment Lisp mode, so you can process Lisp code in ;;; the source files. (define-key lisp-mode-map "\M-\C-x" 'lisp-eval-defun) ; Gnu convention ------------------------------------------------------------ revno: 114792 fixes bug: http://debbugs.gnu.org/15322 committer: Glenn Morris branch nick: trunk timestamp: Thu 2013-10-24 19:33:42 -0700 message: * lisp/vc/vc.el (vc-print-log): Don't use a working revision unless one was explicitly specified. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-25 01:10:27 +0000 +++ lisp/ChangeLog 2013-10-25 02:33:42 +0000 @@ -1,3 +1,8 @@ +2013-10-25 Glenn Morris + + * vc/vc.el (vc-print-log): Don't use a working revision unless + one was explicitly specified. (Bug#15322) + 2013-10-25 Stefan Monnier * subr.el (add-to-list): Preserve return value in compiler-macro === modified file 'lisp/vc/vc.el' --- lisp/vc/vc.el 2013-10-24 01:27:29 +0000 +++ lisp/vc/vc.el 2013-10-25 02:33:42 +0000 @@ -2302,7 +2302,8 @@ (let* ((vc-fileset (vc-deduce-fileset t)) ;FIXME: Why t? --Stef (backend (car vc-fileset)) (files (cadr vc-fileset)) - (working-revision (or working-revision (vc-working-revision (car files))))) +;; (working-revision (or working-revision (vc-working-revision (car files)))) + ) (vc-print-log-internal backend files working-revision nil limit))) ;;;###autoload ------------------------------------------------------------ revno: 114791 committer: Glenn Morris branch nick: trunk timestamp: Thu 2013-10-24 19:22:13 -0700 message: * configure.ac: It seems _installing_ in non-ASCII is ok, not building. diff: === modified file 'ChangeLog' --- ChangeLog 2013-10-24 23:04:33 +0000 +++ ChangeLog 2013-10-25 02:22:13 +0000 @@ -1,3 +1,7 @@ +2013-10-25 Glenn Morris + + * configure.ac: It seems _installing_ in non-ASCII is ok, not building. + 2013-10-24 Glenn Morris * configure.ac: === modified file 'configure.ac' --- configure.ac 2013-10-24 23:04:33 +0000 +++ configure.ac 2013-10-25 02:22:13 +0000 @@ -74,23 +74,19 @@ AC_ARG_PROGRAM dnl http://debbugs.gnu.org/15260 -dnl I think we have to check, eg, both exec_prefix and bindir, -dnl because the latter by default is not yet expanded, but the user -dnl may have specified a value for it via --bindir. dnl Note that abs_srcdir and abs_builddir are not yet defined. :( -dnl "`cd \"$srcdir\" is not portable. +dnl "`cd \"$srcdir\"`" is not portable. dnl See autoconf manual "Shell Substitutions": dnl "There is just no portable way to use double-quoted strings inside dnl double-quoted back-quoted expressions (pfew!)." temp_srcdir=`cd "$srcdir"; pwd` -for var in "`pwd`" "$temp_srcdir" "$prefix" "$exec_prefix" \ - "$datarootdir" "$bindir" "$datadir" "$sharedstatedir" "$libexecdir"; do +for var in "`pwd`" "$temp_srcdir"; do dnl configure sets LC_ALL=C early on, so this range should work. case "$var" in - *[[^\ -~]]*) AC_MSG_ERROR([Emacs cannot be built or installed in a directory whose name contains non-ASCII characters: $var]) ;; + *[[^\ -~]]*) AC_MSG_ERROR([Emacs cannot be built in a directory whose name contains non-ASCII characters: $var]) ;; esac done ------------------------------------------------------------ revno: 114790 fixes bug: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15692 committer: Stefan Monnier branch nick: trunk timestamp: Thu 2013-10-24 21:10:27 -0400 message: * lisp/subr.el (add-to-list): Preserve return value in compiler-macro. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-25 00:49:33 +0000 +++ lisp/ChangeLog 2013-10-25 01:10:27 +0000 @@ -1,3 +1,8 @@ +2013-10-25 Stefan Monnier + + * subr.el (add-to-list): Preserve return value in compiler-macro + (bug#15692). + 2013-10-25 Rüdiger Sonderfeld * progmodes/octave.el (octave-lookfor): Handle empty lookfor === modified file 'lisp/subr.el' --- lisp/subr.el 2013-10-18 04:27:34 +0000 +++ lisp/subr.el 2013-10-25 01:10:27 +0000 @@ -1541,13 +1541,14 @@ (byte-compile-log-warning msg t :error)))) (code (macroexp-let2 macroexp-copyable-p x element - `(unless ,(if compare-fn - (progn - (require 'cl-lib) - `(cl-member ,x ,sym :test ,compare-fn)) - ;; For bootstrapping reasons, don't rely on - ;; cl--compiler-macro-member for the base case. - `(member ,x ,sym)) + `(if ,(if compare-fn + (progn + (require 'cl-lib) + `(cl-member ,x ,sym :test ,compare-fn)) + ;; For bootstrapping reasons, don't rely on + ;; cl--compiler-macro-member for the base case. + `(member ,x ,sym)) + ,sym ,(if append `(setq ,sym (append ,sym (list ,x))) `(push ,x ,sym)))))) ------------------------------------------------------------ revno: 114789 committer: Leo Liu branch nick: trunk timestamp: Fri 2013-10-25 08:52:26 +0800 message: Small fix to last change diff: === modified file 'lisp/progmodes/octave.el' --- lisp/progmodes/octave.el 2013-10-25 00:49:33 +0000 +++ lisp/progmodes/octave.el 2013-10-25 00:52:26 +0000 @@ -1747,7 +1747,7 @@ (insert "\nRetry with ") (insert-text-button "'-all'" 'follow-link t - 'action #'(lambda (b) + 'action #'(lambda (_b) (octave-lookfor str '-all))) (insert ".\n")) (octave-help-mode))))) ------------------------------------------------------------ revno: 114788 fixes bug: http://debbugs.gnu.org/15701 author: Rüdiger Sonderfeld committer: Leo Liu branch nick: trunk timestamp: Fri 2013-10-25 08:49:33 +0800 message: * progmodes/octave.el (octave-lookfor): Handle empty lookfor result. Ask user to retry using '-all' flag. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-24 21:16:20 +0000 +++ lisp/ChangeLog 2013-10-25 00:49:33 +0000 @@ -1,3 +1,8 @@ +2013-10-25 Rüdiger Sonderfeld + + * progmodes/octave.el (octave-lookfor): Handle empty lookfor + result. Ask user to retry using '-all' flag. (Bug#15701) + 2013-10-24 Stefan Monnier * emacs-lisp/smie.el: New smie-config system. === modified file 'lisp/progmodes/octave.el' --- lisp/progmodes/octave.el 2013-10-05 02:45:24 +0000 +++ lisp/progmodes/octave.el 2013-10-25 00:49:33 +0000 @@ -1724,20 +1724,32 @@ (if all "'-all', " "") str))) (let ((lines inferior-octave-output-list)) - (when (string-match "error: \\(.*\\)$" (car lines)) + (when (and (stringp (car lines)) + (string-match "error: \\(.*\\)$" (car lines))) (error "%s" (match-string 1 (car lines)))) (with-help-window octave-help-buffer - (princ (mapconcat 'identity lines "\n")) (with-current-buffer octave-help-buffer + (if lines + (insert (mapconcat 'identity lines "\n")) + (insert (format "Nothing found for \"%s\".\n" str))) ;; Bound to t so that `help-buffer' returns current buffer for ;; `help-setup-xref'. (let ((help-xref-following t)) (help-setup-xref (list 'octave-lookfor str all) (called-interactively-p 'interactive))) (goto-char (point-min)) - (while (re-search-forward "^\\([^[:blank:]]+\\) " nil 'noerror) - (make-text-button (match-beginning 1) (match-end 1) - :type 'octave-help-function)) + (when lines + (while (re-search-forward "^\\([^[:blank:]]+\\) " nil 'noerror) + (make-text-button (match-beginning 1) (match-end 1) + :type 'octave-help-function))) + (unless all + (goto-char (point-max)) + (insert "\nRetry with ") + (insert-text-button "'-all'" + 'follow-link t + 'action #'(lambda (b) + (octave-lookfor str '-all))) + (insert ".\n")) (octave-help-mode))))) (defcustom octave-source-directories nil ------------------------------------------------------------ revno: 114787 committer: Glenn Morris branch nick: trunk timestamp: Thu 2013-10-24 19:04:33 -0400 message: Avoid non-portable "` ... \"...\" ... `" nesting * configure.ac: * Makefile.in (install-arch-indep, install-etcdoc, install-info): * lib-src/Makefile.in ($(DESTDIR)${archlibdir}): * nt/Makefile.in ($(DESTDIR)${archlibdir}): Avoid non-portable "`\" nesting. diff: === modified file 'ChangeLog' --- ChangeLog 2013-10-24 02:15:16 +0000 +++ ChangeLog 2013-10-24 23:04:33 +0000 @@ -1,5 +1,9 @@ 2013-10-24 Glenn Morris + * configure.ac: + * Makefile.in (install-arch-indep, install-etcdoc, install-info): + Avoid non-portable "`\" nesting. + * configure.ac (CPPFLAGS) [mingw32]: Use abs_top_srcdir. * Makefile.in (abs_top_srcdir): New, set by configure. === modified file 'Makefile.in' --- Makefile.in 2013-10-24 04:05:54 +0000 +++ Makefile.in 2013-10-24 23:04:33 +0000 @@ -571,9 +571,11 @@ for dir in ${COPYDIR} ; do \ [ -d $${dir} ] || exit 1 ; \ dest="$$1" ; shift ; \ - [ -d "$${dest}" ] && \ - [ "`cd \"$${dest}\" && /bin/pwd`" = "`cd $${dir} && /bin/pwd`" ] && \ - continue ; \ + if [ -d "$${dest}" ]; then \ + exp_dest=`cd "$${dest}" && /bin/pwd`; \ + [ "$$exp_dest" = "`cd $${dir} && /bin/pwd`" ] && continue ; \ + else true; \ + fi; \ if [ "$${dir}" = "leim/quail" ]; then \ [ "`cd $${dir} && /bin/pwd`" = "`cd ${srcdir}/leim/quail && /bin/pwd`" ] && \ continue ; \ @@ -623,7 +625,8 @@ cd "$${thisdir}" ; \ cd "$${dir}" || exit 1 ; \ for f in `find . -name "*.elc" -print`; do \ - ${GZIP_PROG} -9n "`echo \"$$f\" | sed 's/.elc$$/.el/'`" ; \ + f_el=`echo "$$f" | sed 's/.elc$$/.el/'`; \ + ${GZIP_PROG} -9n "$$f_el" ; \ done ; \ done ) -chmod -R a+r "$(DESTDIR)${datadir}/emacs/${version}" ${COPYDESTS} @@ -637,7 +640,8 @@ install-etcdoc: src install-arch-indep -unset CDPATH; \ umask 022; ${MKDIR_P} "$(DESTDIR)${etcdocdir}" ; \ - if [ "`cd ./etc; /bin/pwd`" != "`cd \"$(DESTDIR)${etcdocdir}\"; /bin/pwd`" ]; \ + exp_etcdocdir=`cd "$(DESTDIR)${etcdocdir}"; /bin/pwd`; \ + if [ "`cd ./etc; /bin/pwd`" != "$$exp_etcdocdir" ]; \ then \ docfile="DOC"; \ echo "Copying etc/$${docfile} to $(DESTDIR)${etcdocdir} ..." ; \ @@ -650,7 +654,8 @@ umask 022; ${MKDIR_P} "$(DESTDIR)${infodir}" -unset CDPATH; \ thisdir=`/bin/pwd`; \ - if [ "`cd ${srcdir}/info && /bin/pwd`" = "`cd \"$(DESTDIR)${infodir}\" && /bin/pwd`" ]; then \ + exp_infodir=`cd "$(DESTDIR)${infodir}" && /bin/pwd`; \ + if [ "`cd ${srcdir}/info && /bin/pwd`" = "$$exp_infodir" ]; then \ true; \ else \ (cd "$(DESTDIR)${infodir}"; \ === modified file 'configure.ac' --- configure.ac 2013-10-24 02:15:16 +0000 +++ configure.ac 2013-10-24 23:04:33 +0000 @@ -78,7 +78,14 @@ dnl because the latter by default is not yet expanded, but the user dnl may have specified a value for it via --bindir. dnl Note that abs_srcdir and abs_builddir are not yet defined. :( -for var in "`pwd`" "`cd \"$srcdir\"; pwd`" "$prefix" "$exec_prefix" \ + +dnl "`cd \"$srcdir\" is not portable. +dnl See autoconf manual "Shell Substitutions": +dnl "There is just no portable way to use double-quoted strings inside +dnl double-quoted back-quoted expressions (pfew!)." +temp_srcdir=`cd "$srcdir"; pwd` + +for var in "`pwd`" "$temp_srcdir" "$prefix" "$exec_prefix" \ "$datarootdir" "$bindir" "$datadir" "$sharedstatedir" "$libexecdir"; do dnl configure sets LC_ALL=C early on, so this range should work. === modified file 'lib-src/ChangeLog' --- lib-src/ChangeLog 2013-10-24 02:15:16 +0000 +++ lib-src/ChangeLog 2013-10-24 23:04:33 +0000 @@ -1,5 +1,8 @@ 2013-10-24 Glenn Morris + * Makefile.in ($(DESTDIR)${archlibdir}): + Avoid non-portable "`\" nesting. + * Makefile.in (abs_top_srcdir): New, set by configure. 2013-10-23 Glenn Morris === modified file 'lib-src/Makefile.in' --- lib-src/Makefile.in 2013-10-24 04:05:54 +0000 +++ lib-src/Makefile.in 2013-10-24 23:04:33 +0000 @@ -234,7 +234,8 @@ @echo @echo "Installing utilities run internally by Emacs." umask 022; ${MKDIR_P} "$(DESTDIR)${archlibdir}" - if [ "`cd \"$(DESTDIR)${archlibdir}\" && /bin/pwd`" != "`/bin/pwd`" ]; then \ + exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && /bin/pwd`; \ + if [ "$$exp_archlibdir" != "`/bin/pwd`" ]; then \ for file in ${UTILITIES}; do \ $(INSTALL_PROGRAM) $(INSTALL_STRIP) $$file "$(DESTDIR)${archlibdir}/$$file" ; \ done ; \ === modified file 'nt/ChangeLog' --- nt/ChangeLog 2013-10-24 02:15:16 +0000 +++ nt/ChangeLog 2013-10-24 23:04:33 +0000 @@ -1,5 +1,8 @@ 2013-10-24 Glenn Morris + * Makefile.in ($(DESTDIR)${archlibdir}): + Avoid non-portable "`\" nesting. + * Makefile.in (abs_top_srcdir): New, set by configure. 2013-10-23 Glenn Morris === modified file 'nt/Makefile.in' --- nt/Makefile.in 2013-10-24 04:05:54 +0000 +++ nt/Makefile.in 2013-10-24 23:04:33 +0000 @@ -144,7 +144,8 @@ @echo @echo "Installing utilities run internally by Emacs." umask 022; ${MKDIR_P} "$(DESTDIR)${archlibdir}" - if [ "`cd \"$(DESTDIR)${archlibdir}\" && /bin/pwd`" != "`/bin/pwd`" ]; then \ + exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && /bin/pwd`; \ + if [ "$$exp_archlibdir" != "`/bin/pwd`" ]; then \ for file in ${UTILITIES}; do \ $(INSTALL_PROGRAM) $(INSTALL_STRIP) $$file "$(DESTDIR)${archlibdir}/$$file" ; \ done ; \ ------------------------------------------------------------ revno: 114786 committer: Stefan Monnier branch nick: trunk timestamp: Thu 2013-10-24 17:16:20 -0400 message: * lisp/emacs-lisp/smie.el: New smie-config system. (smie-config): New defcustom. (smie-edebug, smie-config-show-indent, smie-config-set-indent) (smie-config-guess, smie-config-save): New commands. (smie-config--mode-local, smie-config--buffer-local) (smie-config--trace, smie-config--modefuns): New vars. (smie-config--advice, smie-config--mode-hook) (smie-config--setter, smie-config-local, smie-config--get-trace) (smie-config--guess-value, smie-config--guess): New functions. (smie-indent-forward-token, smie-indent-backward-token): Don't copy text properties. Treat "string fence" syntax like string syntax. * lisp/progmodes/sh-script.el (sh-use-smie): Change default. (sh-smie-sh-rules, sh-smie-rc-rules): Obey legacy sh-indent-* vars. (sh-var-value): Simplify by CSE. (sh-show-indent, sh-set-indent, sh-learn-line-indent) (sh-learn-buffer-indent): Redirect to their SMIE equivalent when SMIE is used. (sh-guess-basic-offset): Use cl-incf. (sh-guess-basic-offset): Use push+nreverse to avoid O(n^2). diff: === modified file 'etc/NEWS' --- etc/NEWS 2013-10-24 07:42:18 +0000 +++ etc/NEWS 2013-10-24 21:16:20 +0000 @@ -216,6 +216,12 @@ * Changes in Specialized Modes and Packages in Emacs 24.4 +** SMIE indentation can be customized via `smie-config'. +The customizaton can be guessed by Emacs by providing a sample indented +file and letting SMIE learn from it. + +** sh-script now uses its SMIE indentation algorithm by default. + ** The debugger's `e' command evaluates the code in the context at point. This includes using the lexical environment at point, which means that `e' now lets you access lexical variables as well. === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-24 17:49:12 +0000 +++ lisp/ChangeLog 2013-10-24 21:16:20 +0000 @@ -1,3 +1,26 @@ +2013-10-24 Stefan Monnier + + * emacs-lisp/smie.el: New smie-config system. + (smie-config): New defcustom. + (smie-edebug, smie-config-show-indent, smie-config-set-indent) + (smie-config-guess, smie-config-save): New commands. + (smie-config--mode-local, smie-config--buffer-local) + (smie-config--trace, smie-config--modefuns): New vars. + (smie-config--advice, smie-config--mode-hook) + (smie-config--setter, smie-config-local, smie-config--get-trace) + (smie-config--guess-value, smie-config--guess): New functions. + (smie-indent-forward-token, smie-indent-backward-token): Don't copy + text properties. Treat "string fence" syntax like string syntax. + + * progmodes/sh-script.el (sh-use-smie): Change default. + (sh-smie-sh-rules, sh-smie-rc-rules): Obey legacy sh-indent-* vars. + (sh-var-value): Simplify by CSE. + (sh-show-indent, sh-set-indent, sh-learn-line-indent) + (sh-learn-buffer-indent): Redirect to their SMIE equivalent when SMIE + is used. + (sh-guess-basic-offset): Use cl-incf. + (sh-guess-basic-offset): Use push+nreverse to avoid O(n^2). + 2013-10-24 Helmut Eller * emacs-lisp/lisp-mode.el (lisp-cl-font-lock-keywords-2): Fix cut&paste === modified file 'lisp/emacs-lisp/smie.el' --- lisp/emacs-lisp/smie.el 2013-10-22 15:45:56 +0000 +++ lisp/emacs-lisp/smie.el 2013-10-24 21:16:20 +0000 @@ -1370,9 +1370,9 @@ ((< 0 (length tok)) (assoc tok smie-grammar)) ((looking-at "\\s(\\|\\s)\\(\\)") (forward-char 1) - (cons (buffer-substring (1- (point)) (point)) + (cons (buffer-substring-no-properties (1- (point)) (point)) (if (match-end 1) '(0 nil) '(nil 0)))) - ((looking-at "\\s\"") + ((looking-at "\\s\"\\|\\s|") (forward-sexp 1) nil) ((eobp) nil) @@ -1387,9 +1387,9 @@ ;; 4 == open paren syntax, 5 == close. ((memq (setq class (syntax-class (syntax-after (1- (point))))) '(4 5)) (forward-char -1) - (cons (buffer-substring (point) (1+ (point))) + (cons (buffer-substring-no-properties (point) (1+ (point))) (if (eq class 4) '(nil 0) '(0 nil)))) - ((eq class 7) + ((memq class '(7 15)) (backward-sexp 1) nil) ((bobp) nil) @@ -1829,6 +1829,352 @@ (append smie-blink-matching-triggers (delete-dups triggers))))))) +(defun smie-edebug () + "Instrument the `smie-rules-function' for Edebug." + (interactive) + (require 'edebug) + (if (symbolp smie-rules-function) + (edebug-instrument-function smie-rules-function) + (error "Sorry, don't know how to instrument a lambda expression"))) + +;;; User configuration + +;; This is designed to be a completely independent "module", so we can play +;; with various kinds of smie-config modules without having to change the core. + +;; This smie-config module is fairly primitive and suffers from serious +;; restrictions: +;; - You can only change a returned offset, so you can't change the offset +;; passed to smie-rule-parent, nor can you change the object with which +;; to align (in general). +;; - The rewrite rule can only distinguish cases based on the kind+token arg +;; and smie-rules-function's return value, so you can't distinguish cases +;; where smie-rules-function returns the same value. +;; - Since config-rules depend on the return value of smie-rules-function, any +;; config change that modifies this return value (e.g. changing +;; foo-indent-basic) ends up invalidating config-rules. +;; This last one is a serious problem since it means that file-local +;; config-rules will only work if the user hasn't changed foo-indent-basic. +;; One possible way to change it is to modify smie-rules-functions so they can +;; return special symbols like +, ++, -, etc. Or make them use a new +;; smie-rule-basic function which can then be used to know when a returned +;; offset was computed based on foo-indent-basic. + +(defvar-local smie-config--mode-local nil + "Indentation config rules installed for this major mode. +Typically manipulated from the major-mode's hook.") +(defvar-local smie-config--buffer-local nil + "Indentation config rules installed for this very buffer. +E.g. provided via a file-local call to `smie-config-local'.") +(defvar smie-config--trace nil + "Variable used to trace calls to `smie-rules-function'.") + +(defun smie-config--advice (orig kind token) + (let* ((ret (funcall orig kind token)) + (sig (list kind token ret)) + (brule (rassoc sig smie-config--buffer-local)) + (mrule (rassoc sig smie-config--mode-local))) + (when smie-config--trace + (setq smie-config--trace (or brule mrule))) + (cond + (brule (car brule)) + (mrule (car mrule)) + (t ret)))) + +(defun smie-config--mode-hook (rules) + (setq smie-config--mode-local + (append rules smie-config--mode-local)) + (add-function :around (local 'smie-rules-function) #'smie-config--advice)) + +(defvar smie-config--modefuns nil) + +(defun smie-config--setter (var value) + (setq-default var value) + (let ((old-modefuns smie-config--modefuns)) + (setq smie-config--modefuns nil) + (pcase-dolist (`(,mode . ,rules) value) + (let ((modefunname (intern (format "smie-config--modefun-%s" mode)))) + (fset modefunname (lambda () (smie-config--mode-hook rules))) + (push modefunname smie-config--modefuns) + (add-hook (intern (format "%s-hook" mode)) modefunname))) + ;; Neuter any left-over previously installed hook. + (dolist (modefun old-modefuns) + (unless (memq modefun smie-config--modefuns) + (fset modefun #'ignore))))) + +(defcustom smie-config nil + ;; FIXME: there should be a file-local equivalent. + "User configuration of SMIE indentation. +This is a list of elements (MODE . RULES), where RULES is a list +of elements describing when and how to change the indentation rules. +Each RULE element should be of the form (NEW KIND TOKEN NORMAL), +where KIND and TOKEN are the elements passed to `smie-rules-function', +NORMAL is the value returned by `smie-rules-function' and NEW is the +value with which to replace it." + :set #'smie-config--setter) + +(defun smie-config-local (rules) + "Add RULES as local indentation rules to use in this buffer. +These replace any previous local rules, but supplement the rules +specified in `smie-config'." + (setq smie-config--buffer-local rules) + (add-function :around (local 'smie-rules-function) #'smie-config--advice)) + +;; Make it so we can set those in the file-local block. +;; FIXME: Better would be to be able to write "smie-config-local: (...)" rather +;; than "eval: (smie-config-local '(...))". +(put 'smie-config-local 'safe-local-eval-function t) + +(defun smie-config--get-trace () + (save-excursion + (forward-line 0) + (skip-chars-forward " \t") + (let* ((trace ()) + (srf-fun (lambda (orig kind token) + (let* ((pos (point)) + (smie-config--trace t) + (res (funcall orig kind token))) + (push (if (consp smie-config--trace) + (list pos kind token res smie-config--trace) + (list pos kind token res)) + trace) + res)))) + (unwind-protect + (progn + (add-function :around (local 'smie-rules-function) srf-fun) + (cons (smie-indent-calculate) + trace)) + (remove-function (local 'smie-rules-function) srf-fun))))) + +(defun smie-config-show-indent (&optional arg) + "Display the SMIE rules that are used to indent the current line. +If prefix ARG is given, then move briefly point to the buffer +position corresponding to each rule." + (interactive "P") + (let ((trace (cdr (smie-config--get-trace)))) + (cond + ((null trace) (message "No SMIE rules involved")) + ((not arg) + (message "Rules used: %s" + (mapconcat (lambda (elem) + (pcase-let ((`(,_pos ,kind ,token ,res ,rewrite) + elem)) + (format "%S %S -> %S%s" kind token res + (if (null rewrite) "" + (format "(via %S)" (nth 3 rewrite)))))) + trace + ", "))) + (t + (save-excursion + (pcase-dolist (`(,pos ,kind ,token ,res ,rewrite) trace) + (message "%S %S -> %S%s" kind token res + (if (null rewrite) "" + (format "(via %S)" (nth 3 rewrite)))) + (goto-char pos) + (sit-for blink-matching-delay))))))) + +(defun smie-config--guess-value (sig) + (add-function :around (local 'smie-rules-function) #'smie-config--advice) + (let* ((rule (cons 0 sig)) + (smie-config--buffer-local (cons rule smie-config--buffer-local)) + (goal (current-indentation)) + (cur (smie-indent-calculate))) + (cond + ((and (eq goal + (progn (setf (car rule) (- goal cur)) + (smie-indent-calculate)))) + (- goal cur))))) + +(defun smie-config-set-indent () + "Add a rule to adjust the indentation of current line." + (interactive) + (let* ((trace (cdr (smie-config--get-trace))) + (_ (unless trace (error "No SMIE rules involved"))) + (sig (if (null (cdr trace)) + (pcase-let* ((elem (car trace)) + (`(,_pos ,kind ,token ,res ,rewrite) elem)) + (list kind token (or (nth 3 rewrite) res))) + (let* ((choicestr + (completing-read + "Adjust rule: " + (mapcar (lambda (elem) + (format "%s %S" + (substring (symbol-name (cadr elem)) + 1) + (nth 2 elem))) + trace) + nil t nil nil + nil)) ;FIXME: Provide good default! + (choicelst (car (read-from-string + (concat "(:" choicestr ")"))))) + (catch 'found + (pcase-dolist (`(,_pos ,kind ,token ,res ,rewrite) trace) + (when (and (eq kind (car choicelst)) + (equal token (nth 1 choicelst))) + (throw 'found (list kind token + (or (nth 3 rewrite) res))))))))) + (default-new (smie-config--guess-value sig)) + (newstr (read-string (format "Adjust rule (%S %S -> %S) to%s: " + (nth 0 sig) (nth 1 sig) (nth 2 sig) + (if (not default-new) "" + (format " (default %S)" default-new))) + nil nil (format "%S" default-new))) + (new (car (read-from-string newstr)))) + (let ((old (rassoc sig smie-config--buffer-local))) + (when old + (setq smie-config--buffer-local + (remove old smie-config--buffer-local)))) + (push (cons new sig) smie-config--buffer-local) + (message "Added rule %S %S -> %S (via %S)" + (nth 0 sig) (nth 1 sig) new (nth 2 sig)) + (add-function :around (local 'smie-rules-function) #'smie-config--advice))) + +(defun smie-config--guess (beg end) + (let ((otraces (make-hash-table :test #'equal)) + (smie-config--buffer-local nil) + (smie-config--mode-local nil) + (pr (make-progress-reporter "Analyzing the buffer" beg end))) + + ;; First, lets get the indentation traces and offsets for the region. + (save-excursion + (goto-char beg) + (forward-line 0) + (while (< (point) end) + (skip-chars-forward " \t") + (unless (eolp) ;Skip empty lines. + (progress-reporter-update pr (point)) + (let* ((itrace (smie-config--get-trace)) + (nindent (car itrace)) + (trace (mapcar #'cdr (cdr itrace))) + (cur (current-indentation))) + (when (numberp nindent) ;Skip `noindent' and friends. + (cl-incf (gethash (cons (- cur nindent) trace) otraces 0))))) + (forward-line 1))) + (progress-reporter-done pr) + + ;; Second, compile the data. Our algorithm only knows how to adjust rules + ;; where the smie-rules-function returns an integer. We call those + ;; "adjustable sigs". We build a table mapping each adjustable sig + ;; to its data, describing the total number of times we encountered it, + ;; the offsets found, and the traces in which it was found. + (message "Guessing...") + (let ((sigs (make-hash-table :test #'equal))) + (maphash (lambda (otrace count) + (let ((offset (car otrace)) + (trace (cdr otrace)) + (double nil)) + (let ((sigs trace)) + (while sigs + (let ((sig (pop sigs))) + (if (and (integerp (nth 2 sig)) (member sig sigs)) + (setq double t))))) + (if double + ;; Disregard those traces where an adjustable sig + ;; appears twice, because the rest of the code assumes + ;; that adding a rule to add an offset N will change the + ;; end result by N rather than 2*N or more. + nil + (dolist (sig trace) + (if (not (integerp (nth 2 sig))) + ;; Disregard those sigs that return nil or a column, + ;; because our algorithm doesn't know how to adjust + ;; them anyway. + nil + (let ((sig-data (or (gethash sig sigs) + (let ((data (list 0 nil nil))) + (puthash sig data sigs) + data)))) + (cl-incf (nth 0 sig-data) count) + (push (cons count otrace) (nth 2 sig-data)) + (let ((sig-off-data + (or (assq offset (nth 1 sig-data)) + (let ((off-data (cons offset 0))) + (push off-data (nth 1 sig-data)) + off-data)))) + (cl-incf (cdr sig-off-data) count)))))))) + otraces) + + ;; Finally, guess the indentation rules. + (let ((ssigs nil) + (rules nil)) + ;; Sort the sigs by frequency of occurrence. + (maphash (lambda (sig sig-data) (push (cons sig sig-data) ssigs)) sigs) + (setq ssigs (sort ssigs (lambda (sd1 sd2) (> (cadr sd1) (cadr sd2))))) + (while ssigs + (pcase-let ((`(,sig ,total ,off-alist ,cotraces) (pop ssigs))) + (cl-assert (= total (apply #'+ (mapcar #'cdr off-alist)))) + (let* ((sorted-off-alist + (sort off-alist (lambda (x y) (> (cdr x) (cdr y))))) + (offset (caar sorted-off-alist))) + (if (zerop offset) + ;; Nothing to do with this sig; indentation is + ;; correct already. + nil + (push (cons (+ offset (nth 2 sig)) sig) rules) + ;; Adjust the rest of the data. + (pcase-dolist ((and cotrace `(,count ,toffset ,trace)) + cotraces) + (setf (nth 1 cotrace) (- toffset offset)) + (dolist (sig trace) + (let ((sig-data (cdr (assq sig ssigs)))) + (when sig-data + (let* ((ooff-data (assq toffset (nth 1 sig-data))) + (noffset (- toffset offset)) + (noff-data + (or (assq noffset (nth 1 sig-data)) + (let ((off-data (cons noffset 0))) + (push off-data (nth 1 sig-data)) + off-data)))) + (cl-assert (>= (cdr ooff-data) count)) + (cl-decf (cdr ooff-data) count) + (cl-incf (cdr noff-data) count)))))))))) + (message "Guessing...done") + rules)))) + +(defun smie-config-guess () + "Try and figure out this buffer's indentation settings." + (interactive) + (let ((config (smie-config--guess (point-min) (point-max)))) + (cond + ((null config) (message "Nothing to change")) + ((null smie-config--buffer-local) + (message "Local rules set") + (setq smie-config--buffer-local config)) + ((y-or-n-p "Replace existing local config? ") + (message "Local rules replaced") + (setq smie-config--buffer-local config)) + ((y-or-n-p "Merge with existing local config? ") + (message "Local rules adjusted") + (setq smie-config--buffer-local + (append config smie-config--buffer-local))) + (t + (message "Rules guessed: %S" config))))) + +(defun smie-config-save () + "Save local rules for use with this major mode." + (interactive) + (cond + ((null smie-config--buffer-local) + (message "No local rules to save")) + (t + (let* ((existing (assq major-mode smie-config)) + (config + (cond ((null existing) + (message "Local rules saved in `smie-config'") + smie-config--buffer-local) + ((y-or-n-p "Replace the existing mode's config? ") + (message "Mode rules replaced in `smie-config'") + smie-config--buffer-local) + ((y-or-n-p "Merge with existing mode's config? ") + (message "Mode rules adjusted in `smie-config'") + (append smie-config--buffer-local (cdr existing))) + (t (error "Abort"))))) + (if existing + (setcdr existing config) + (push (cons major-mode config) smie-config)) + (setq smie-config--mode-local config) + (kill-local-variable smie-config--buffer-local) + (customize-mark-as-set 'smie-config))))) (provide 'smie) ;;; smie.el ends here === modified file 'lisp/progmodes/sh-script.el' --- lisp/progmodes/sh-script.el 2013-10-17 03:56:51 +0000 +++ lisp/progmodes/sh-script.el 2013-10-24 21:16:20 +0000 @@ -1721,7 +1721,7 @@ ;; the various indentation custom-vars, and it misses some important features ;; of the old code, mostly: sh-learn-line/buffer-indent, sh-show-indent, ;; sh-name/save/load-style. -(defvar sh-use-smie nil +(defvar sh-use-smie t "Whether to use the SMIE code for navigation and indentation.") (defun sh-smie--keyword-p () @@ -1926,7 +1926,8 @@ (defun sh-smie-sh-rules (kind token) (pcase (cons kind token) (`(:elem . basic) sh-indentation) - (`(:after . "case-)") (or sh-indentation smie-indent-basic)) + (`(:after . "case-)") (- (sh-var-value 'sh-indent-for-case-alt) + (sh-var-value 'sh-indent-for-case-label))) ((and `(:before . ,_) (guard (when sh-indent-after-continuation (save-excursion @@ -1960,6 +1961,21 @@ (current-column) (smie-indent-calculate))))) (`(:after . "|") (if (smie-rule-parent-p "|") nil 4)) + ;; Attempt at backward compatibility with the old config variables. + (`(:before . "fi") (sh-var-value 'sh-indent-for-fi)) + (`(:before . "done") (sh-var-value 'sh-indent-for-done)) + (`(:after . "else") (sh-var-value 'sh-indent-after-else)) + (`(:after . "if") (sh-var-value 'sh-indent-after-if)) + (`(:before . "then") (sh-var-value 'sh-indent-for-then)) + (`(:before . "do") (sh-var-value 'sh-indent-for-do)) + (`(:after . "do") + (sh-var-value (if (smie-rule-hanging-p) + 'sh-indent-after-loop-construct 'sh-indent-after-do))) + ;; sh-indent-after-done: aligned completely differently. + (`(:after . "in") (sh-var-value 'sh-indent-for-case-label)) + ;; sh-indent-for-continuation: Line continuations are handled differently. + (`(:after . ,(or `"(" `"{" `"[")) (sh-var-value 'sh-indent-after-open)) + ;; sh-indent-after-function: we don't handle it differently. )) ;; (defconst sh-smie-csh-grammar @@ -2119,8 +2135,9 @@ (pcase (cons kind token) (`(:elem . basic) sh-indentation) ;; (`(:after . "case") (or sh-indentation smie-indent-basic)) - (`(:after . ";") (if (smie-rule-parent-p "case") - (smie-rule-parent sh-indentation))) + (`(:after . ";") + (if (smie-rule-parent-p "case") + (smie-rule-parent (sh-var-value 'sh-indent-after-case)))) (`(:before . "{") (save-excursion (when (sh-smie--rc-after-special-arg-p) @@ -2135,6 +2152,7 @@ ;; with "(exp)", which is rarely the right thing to do, but is better ;; than nothing. (`(:list-intro . ,(or `"for" `"if" `"while")) t) + ;; sh-indent-after-switch: handled implicitly by the default { rule. )) ;;; End of SMIE code. @@ -3154,12 +3172,9 @@ ((eq val '/) (/ (- sh-basic-offset) 2)) (t - (if ignore-error - (progn - (message "Don't know how to handle %s's value of %s" var val) - 0) - (error "Don't know how to handle %s's value of %s" var val)) - )))) + (funcall (if ignore-error #'message #'error) + "Don't know how to handle %s's value of %s" var val) + 0)))) (defun sh-set-var-value (var value &optional no-symbol) "Set variable VAR to VALUE. @@ -3284,33 +3299,35 @@ we are indenting relative to, if applicable." (interactive "P") (sh-must-support-indent) - (let* ((info (sh-get-indent-info)) - (var (sh-get-indent-var-for-line info)) - (curr-indent (current-indentation)) - val msg) - (if (stringp var) - (message "%s" (setq msg var)) - (setq val (sh-calculate-indent info)) + (if sh-use-smie + (smie-config-show-indent) + (let* ((info (sh-get-indent-info)) + (var (sh-get-indent-var-for-line info)) + (curr-indent (current-indentation)) + val msg) + (if (stringp var) + (message "%s" (setq msg var)) + (setq val (sh-calculate-indent info)) - (if (eq curr-indent val) - (setq msg (format "%s is %s" var (symbol-value var))) - (setq msg - (if val - (format "%s (%s) would change indent from %d to: %d" - var (symbol-value var) curr-indent val) - (format "%s (%s) would leave line as is" - var (symbol-value var))) - )) - (if (and arg var) - (describe-variable var))) - (if sh-blink - (let ((info (sh-get-indent-info))) - (if (and info (listp (car info)) - (eq (car (car info)) t)) - (sh-blink (nth 1 (car info)) msg) - (message "%s" msg))) - (message "%s" msg)) - )) + (if (eq curr-indent val) + (setq msg (format "%s is %s" var (symbol-value var))) + (setq msg + (if val + (format "%s (%s) would change indent from %d to: %d" + var (symbol-value var) curr-indent val) + (format "%s (%s) would leave line as is" + var (symbol-value var))) + )) + (if (and arg var) + (describe-variable var))) + (if sh-blink + (let ((info (sh-get-indent-info))) + (if (and info (listp (car info)) + (eq (car (car info)) t)) + (sh-blink (nth 1 (car info)) msg) + (message "%s" msg))) + (message "%s" msg)) + ))) (defun sh-set-indent () "Set the indentation for the current line. @@ -3318,34 +3335,36 @@ for a new value for it." (interactive) (sh-must-support-indent) - (let* ((info (sh-get-indent-info)) - (var (sh-get-indent-var-for-line info)) - val old-val indent-val) - (if (stringp var) - (message "Cannot set indent - %s" var) - (setq old-val (symbol-value var)) - (setq val (sh-read-variable var)) - (condition-case nil - (progn - (set var val) - (setq indent-val (sh-calculate-indent info)) - (if indent-val - (message "Variable: %s Value: %s would indent to: %d" - var (symbol-value var) indent-val) - (message "Variable: %s Value: %s would leave line as is." - var (symbol-value var))) - ;; I'm not sure about this, indenting it now? - ;; No. Because it would give the impression that an undo would - ;; restore thing, but the value has been altered. - ;; (sh-indent-line) - ) - (error - (set var old-val) - (message "Bad value for %s, restoring to previous value %s" - var old-val) - (sit-for 1) - nil)) - ))) + (if sh-use-smie + (smie-config-set-indent) + (let* ((info (sh-get-indent-info)) + (var (sh-get-indent-var-for-line info)) + val old-val indent-val) + (if (stringp var) + (message "Cannot set indent - %s" var) + (setq old-val (symbol-value var)) + (setq val (sh-read-variable var)) + (condition-case nil + (progn + (set var val) + (setq indent-val (sh-calculate-indent info)) + (if indent-val + (message "Variable: %s Value: %s would indent to: %d" + var (symbol-value var) indent-val) + (message "Variable: %s Value: %s would leave line as is." + var (symbol-value var))) + ;; I'm not sure about this, indenting it now? + ;; No. Because it would give the impression that an undo would + ;; restore thing, but the value has been altered. + ;; (sh-indent-line) + ) + (error + (set var old-val) + (message "Bad value for %s, restoring to previous value %s" + var old-val) + (sit-for 1) + nil)) + )))) (defun sh-learn-line-indent (arg) @@ -3359,55 +3378,57 @@ unless optional argument ARG (the prefix when interactive) is non-nil." (interactive "*P") (sh-must-support-indent) - ;; I'm not sure if we show allow learning on an empty line. - ;; Though it might occasionally be useful I think it usually - ;; would just be confusing. - (if (save-excursion - (beginning-of-line) - (looking-at "\\s-*$")) - (message "sh-learn-line-indent ignores empty lines.") - (let* ((info (sh-get-indent-info)) - (var (sh-get-indent-var-for-line info)) - ival sval diff new-val - (no-symbol arg) - (curr-indent (current-indentation))) - (cond - ((stringp var) - (message "Cannot learn line - %s" var)) - ((eq var 'sh-indent-comment) - ;; This is arbitrary... - ;; - if curr-indent is 0, set to curr-indent - ;; - else if it has the indentation of a "normal" line, - ;; then set to t - ;; - else set to curr-indent. - (setq sh-indent-comment - (if (= curr-indent 0) - 0 - (let* ((sh-indent-comment t) - (val2 (sh-calculate-indent info))) - (if (= val2 curr-indent) - t - curr-indent)))) - (message "%s set to %s" var (symbol-value var)) - ) - ((numberp (setq sval (sh-var-value var))) - (setq ival (sh-calculate-indent info)) - (setq diff (- curr-indent ival)) + (if sh-use-smie + (smie-config-set-indent) + ;; I'm not sure if we show allow learning on an empty line. + ;; Though it might occasionally be useful I think it usually + ;; would just be confusing. + (if (save-excursion + (beginning-of-line) + (looking-at "\\s-*$")) + (message "sh-learn-line-indent ignores empty lines.") + (let* ((info (sh-get-indent-info)) + (var (sh-get-indent-var-for-line info)) + ival sval diff new-val + (no-symbol arg) + (curr-indent (current-indentation))) + (cond + ((stringp var) + (message "Cannot learn line - %s" var)) + ((eq var 'sh-indent-comment) + ;; This is arbitrary... + ;; - if curr-indent is 0, set to curr-indent + ;; - else if it has the indentation of a "normal" line, + ;; then set to t + ;; - else set to curr-indent. + (setq sh-indent-comment + (if (= curr-indent 0) + 0 + (let* ((sh-indent-comment t) + (val2 (sh-calculate-indent info))) + (if (= val2 curr-indent) + t + curr-indent)))) + (message "%s set to %s" var (symbol-value var)) + ) + ((numberp (setq sval (sh-var-value var))) + (setq ival (sh-calculate-indent info)) + (setq diff (- curr-indent ival)) - (sh-debug "curr-indent: %d ival: %d diff: %d var:%s sval %s" - curr-indent ival diff var sval) - (setq new-val (+ sval diff)) -;;; I commented out this because someone might want to replace -;;; a value of `+' with the current value of sh-basic-offset -;;; or vice-versa. -;;; (if (= 0 diff) -;;; (message "No change needed!") - (sh-set-var-value var new-val no-symbol) - (message "%s set to %s" var (symbol-value var)) - ) - (t - (debug) - (message "Cannot change %s" var)))))) + (sh-debug "curr-indent: %d ival: %d diff: %d var:%s sval %s" + curr-indent ival diff var sval) + (setq new-val (+ sval diff)) + ;; I commented out this because someone might want to replace + ;; a value of `+' with the current value of sh-basic-offset + ;; or vice-versa. + ;;(if (= 0 diff) + ;; (message "No change needed!") + (sh-set-var-value var new-val no-symbol) + (message "%s set to %s" var (symbol-value var)) + ) + (t + (debug) + (message "Cannot change %s" var))))))) @@ -3505,202 +3526,204 @@ This command can often take a long time to run." (interactive "P") (sh-must-support-indent) - (save-excursion - (goto-char (point-min)) - (let ((learned-var-list nil) - (out-buffer "*indent*") - (num-diffs 0) - previous-set-info - (max 17) - vec - msg - (comment-col nil) ;; number if all same, t if seen diff values - (comments-always-default t) ;; nil if we see one not default - initial-msg - (specified-basic-offset (and arg (numberp arg) - (> arg 0))) - (linenum 0) - suggested) - (setq vec (make-vector max 0)) - (sh-mark-init out-buffer) - - (if specified-basic-offset - (progn - (setq sh-basic-offset arg) - (setq initial-msg - (format "Using specified sh-basic-offset of %d" - sh-basic-offset))) - (setq initial-msg - (format "Initial value of sh-basic-offset: %s" - sh-basic-offset))) - - (while (< (point) (point-max)) - (setq linenum (1+ linenum)) - ;; (if (zerop (% linenum 10)) - (message "line %d" linenum) - ;; ) - (unless (looking-at "\\s-*$") ;; ignore empty lines! - (let* ((sh-indent-comment t) ;; info must return default indent - (info (sh-get-indent-info)) - (var (sh-get-indent-var-for-line info)) - sval ival diff new-val - (curr-indent (current-indentation))) - (cond - ((null var) - nil) - ((stringp var) - nil) - ((numberp (setq sval (sh-var-value var 'no-error))) - ;; the numberp excludes comments since sval will be t. - (setq ival (sh-calculate-indent)) - (setq diff (- curr-indent ival)) - (setq new-val (+ sval diff)) - (sh-set-var-value var new-val 'no-symbol) - (unless (looking-at "\\s-*#") ;; don't learn from comments - (if (setq previous-set-info (assoc var learned-var-list)) - (progn - ;; it was already there, is it same value ? - (unless (eq (symbol-value var) - (nth 1 previous-set-info)) - (sh-mark-line - (format "Variable %s was set to %s" - var (symbol-value var)) - (point) out-buffer t t) - (sh-mark-line - (format " but was previously set to %s" - (nth 1 previous-set-info)) - (nth 2 previous-set-info) out-buffer t) - (setq num-diffs (1+ num-diffs)) - ;; (delete previous-set-info learned-var-list) - (setcdr previous-set-info - (list (symbol-value var) (point))) - ) - ) - (setq learned-var-list - (append (list (list var (symbol-value var) - (point))) - learned-var-list))) - (if (numberp new-val) - (progn - (sh-debug - "This line's indent value: %d" new-val) - (if (< new-val 0) - (setq new-val (- new-val))) - (if (< new-val max) - (aset vec new-val (1+ (aref vec new-val)))))) - )) - ((eq var 'sh-indent-comment) - (unless (= curr-indent (sh-calculate-indent info)) - ;; this is not the default indentation - (setq comments-always-default nil) - (if comment-col ;; then we have see one before - (or (eq comment-col curr-indent) - (setq comment-col t)) ;; seen a different one - (setq comment-col curr-indent)) - )) - (t - (sh-debug "Cannot learn this line!!!") - )) - (sh-debug - "at %s learned-var-list is %s" (point) learned-var-list) - )) - (forward-line 1) - ) ;; while - (if sh-debug - (progn - (setq msg (format - "comment-col = %s comments-always-default = %s" - comment-col comments-always-default)) - ;; (message msg) - (sh-mark-line msg nil out-buffer))) - (cond - ((eq comment-col 0) - (setq msg "\nComments are all in 1st column.\n")) - (comments-always-default - (setq msg "\nComments follow default indentation.\n") - (setq comment-col t)) - ((numberp comment-col) - (setq msg (format "\nComments are in col %d." comment-col))) - (t - (setq msg "\nComments seem to be mixed, leaving them as is.\n") - (setq comment-col nil) - )) - (sh-debug msg) - (sh-mark-line msg nil out-buffer) - - (sh-mark-line initial-msg nil out-buffer t t) - - (setq suggested (sh-guess-basic-offset vec)) - - (if (and suggested (not specified-basic-offset)) - (let ((new-value - (cond - ;; t => set it if we have a single value as a number - ((and (eq sh-learn-basic-offset t) (numberp suggested)) - suggested) - ;; other non-nil => set it if only one value was found - (sh-learn-basic-offset - (if (numberp suggested) - suggested - (if (= (length suggested) 1) - (car suggested)))) - (t - nil)))) - (if new-value - (progn - (setq learned-var-list - (append (list (list 'sh-basic-offset - (setq sh-basic-offset new-value) - (point-max))) - learned-var-list)) - ;; Not sure if we need to put this line in, since - ;; it will appear in the "Learned variable settings". - (sh-mark-line - (format "Changed sh-basic-offset to: %d" sh-basic-offset) - nil out-buffer)) - (sh-mark-line - (if (listp suggested) - (format "Possible value(s) for sh-basic-offset: %s" - (mapconcat 'int-to-string suggested " ")) - (format "Suggested sh-basic-offset: %d" suggested)) - nil out-buffer)))) - - - (setq learned-var-list - (append (list (list 'sh-indent-comment comment-col (point-max))) - learned-var-list)) - (setq sh-indent-comment comment-col) - (let ((name (buffer-name))) - (sh-mark-line "\nLearned variable settings:" nil out-buffer) - (if arg - ;; Set learned variables to symbolic rather than numeric - ;; values where possible. - (dolist (learned-var (reverse learned-var-list)) - (let ((var (car learned-var)) - (val (nth 1 learned-var))) - (when (and (not (eq var 'sh-basic-offset)) - (numberp val)) - (sh-set-var-value var val))))) - (dolist (learned-var (reverse learned-var-list)) - (let ((var (car learned-var))) - (sh-mark-line (format " %s %s" var (symbol-value var)) - (nth 2 learned-var) out-buffer))) - (with-current-buffer out-buffer - (goto-char (point-min)) - (let ((inhibit-read-only t)) - (insert - (format "Indentation values for buffer %s.\n" name) - (format "%d indentation variable%s different values%s\n\n" - num-diffs - (if (= num-diffs 1) - " has" "s have") - (if (zerop num-diffs) - "." ":")))))) - ;; Are abnormal hooks considered bad form? - (run-hook-with-args 'sh-learned-buffer-hook learned-var-list) - (and (called-interactively-p 'any) - (or sh-popup-occur-buffer (> num-diffs 0)) - (pop-to-buffer out-buffer))))) + (if sh-use-smie + (smie-config-guess) + (save-excursion + (goto-char (point-min)) + (let ((learned-var-list nil) + (out-buffer "*indent*") + (num-diffs 0) + previous-set-info + (max 17) + vec + msg + (comment-col nil) ;; number if all same, t if seen diff values + (comments-always-default t) ;; nil if we see one not default + initial-msg + (specified-basic-offset (and arg (numberp arg) + (> arg 0))) + (linenum 0) + suggested) + (setq vec (make-vector max 0)) + (sh-mark-init out-buffer) + + (if specified-basic-offset + (progn + (setq sh-basic-offset arg) + (setq initial-msg + (format "Using specified sh-basic-offset of %d" + sh-basic-offset))) + (setq initial-msg + (format "Initial value of sh-basic-offset: %s" + sh-basic-offset))) + + (while (< (point) (point-max)) + (setq linenum (1+ linenum)) + ;; (if (zerop (% linenum 10)) + (message "line %d" linenum) + ;; ) + (unless (looking-at "\\s-*$") ;; ignore empty lines! + (let* ((sh-indent-comment t) ;; info must return default indent + (info (sh-get-indent-info)) + (var (sh-get-indent-var-for-line info)) + sval ival diff new-val + (curr-indent (current-indentation))) + (cond + ((null var) + nil) + ((stringp var) + nil) + ((numberp (setq sval (sh-var-value var 'no-error))) + ;; the numberp excludes comments since sval will be t. + (setq ival (sh-calculate-indent)) + (setq diff (- curr-indent ival)) + (setq new-val (+ sval diff)) + (sh-set-var-value var new-val 'no-symbol) + (unless (looking-at "\\s-*#") ;; don't learn from comments + (if (setq previous-set-info (assoc var learned-var-list)) + (progn + ;; it was already there, is it same value ? + (unless (eq (symbol-value var) + (nth 1 previous-set-info)) + (sh-mark-line + (format "Variable %s was set to %s" + var (symbol-value var)) + (point) out-buffer t t) + (sh-mark-line + (format " but was previously set to %s" + (nth 1 previous-set-info)) + (nth 2 previous-set-info) out-buffer t) + (setq num-diffs (1+ num-diffs)) + ;; (delete previous-set-info learned-var-list) + (setcdr previous-set-info + (list (symbol-value var) (point))) + ) + ) + (setq learned-var-list + (append (list (list var (symbol-value var) + (point))) + learned-var-list))) + (if (numberp new-val) + (progn + (sh-debug + "This line's indent value: %d" new-val) + (if (< new-val 0) + (setq new-val (- new-val))) + (if (< new-val max) + (aset vec new-val (1+ (aref vec new-val)))))) + )) + ((eq var 'sh-indent-comment) + (unless (= curr-indent (sh-calculate-indent info)) + ;; this is not the default indentation + (setq comments-always-default nil) + (if comment-col ;; then we have see one before + (or (eq comment-col curr-indent) + (setq comment-col t)) ;; seen a different one + (setq comment-col curr-indent)) + )) + (t + (sh-debug "Cannot learn this line!!!") + )) + (sh-debug + "at %s learned-var-list is %s" (point) learned-var-list) + )) + (forward-line 1) + ) ;; while + (if sh-debug + (progn + (setq msg (format + "comment-col = %s comments-always-default = %s" + comment-col comments-always-default)) + ;; (message msg) + (sh-mark-line msg nil out-buffer))) + (cond + ((eq comment-col 0) + (setq msg "\nComments are all in 1st column.\n")) + (comments-always-default + (setq msg "\nComments follow default indentation.\n") + (setq comment-col t)) + ((numberp comment-col) + (setq msg (format "\nComments are in col %d." comment-col))) + (t + (setq msg "\nComments seem to be mixed, leaving them as is.\n") + (setq comment-col nil) + )) + (sh-debug msg) + (sh-mark-line msg nil out-buffer) + + (sh-mark-line initial-msg nil out-buffer t t) + + (setq suggested (sh-guess-basic-offset vec)) + + (if (and suggested (not specified-basic-offset)) + (let ((new-value + (cond + ;; t => set it if we have a single value as a number + ((and (eq sh-learn-basic-offset t) (numberp suggested)) + suggested) + ;; other non-nil => set it if only one value was found + (sh-learn-basic-offset + (if (numberp suggested) + suggested + (if (= (length suggested) 1) + (car suggested)))) + (t + nil)))) + (if new-value + (progn + (setq learned-var-list + (append (list (list 'sh-basic-offset + (setq sh-basic-offset new-value) + (point-max))) + learned-var-list)) + ;; Not sure if we need to put this line in, since + ;; it will appear in the "Learned variable settings". + (sh-mark-line + (format "Changed sh-basic-offset to: %d" sh-basic-offset) + nil out-buffer)) + (sh-mark-line + (if (listp suggested) + (format "Possible value(s) for sh-basic-offset: %s" + (mapconcat 'int-to-string suggested " ")) + (format "Suggested sh-basic-offset: %d" suggested)) + nil out-buffer)))) + + + (setq learned-var-list + (append (list (list 'sh-indent-comment comment-col (point-max))) + learned-var-list)) + (setq sh-indent-comment comment-col) + (let ((name (buffer-name))) + (sh-mark-line "\nLearned variable settings:" nil out-buffer) + (if arg + ;; Set learned variables to symbolic rather than numeric + ;; values where possible. + (dolist (learned-var (reverse learned-var-list)) + (let ((var (car learned-var)) + (val (nth 1 learned-var))) + (when (and (not (eq var 'sh-basic-offset)) + (numberp val)) + (sh-set-var-value var val))))) + (dolist (learned-var (reverse learned-var-list)) + (let ((var (car learned-var))) + (sh-mark-line (format " %s %s" var (symbol-value var)) + (nth 2 learned-var) out-buffer))) + (with-current-buffer out-buffer + (goto-char (point-min)) + (let ((inhibit-read-only t)) + (insert + (format "Indentation values for buffer %s.\n" name) + (format "%d indentation variable%s different values%s\n\n" + num-diffs + (if (= num-diffs 1) + " has" "s have") + (if (zerop num-diffs) + "." ":")))))) + ;; Are abnormal hooks considered bad form? + (run-hook-with-args 'sh-learned-buffer-hook learned-var-list) + (and (called-interactively-p 'any) + (or sh-popup-occur-buffer (> num-diffs 0)) + (pop-to-buffer out-buffer)))))) (defun sh-guess-basic-offset (vec) "See if we can determine a reasonable value for `sh-basic-offset'. @@ -3716,11 +3739,11 @@ (i 1) (totals (make-vector max 0))) (while (< i max) - (aset totals i (+ (aref totals i) (* 4 (aref vec i)))) + (cl-incf (aref totals i) (* 4 (aref vec i))) (if (zerop (% i 2)) - (aset totals i (+ (aref totals i) (aref vec (/ i 2))))) + (cl-incf (aref totals i) (aref vec (/ i 2)))) (if (< (* i 2) max) - (aset totals i (+ (aref totals i) (aref vec (* i 2))))) + (cl-incf (aref totals i) (aref vec (* i 2)))) (setq i (1+ i))) (let ((x nil) @@ -3729,10 +3752,10 @@ (setq i 1) (while (< i max) (if (/= (aref totals i) 0) - (setq x (append x (list (cons i (aref totals i)))))) + (push (cons i (aref totals i)) x)) (setq i (1+ i))) - (setq x (sort x (lambda (a b) (> (cdr a) (cdr b))))) + (setq x (sort (nreverse x) (lambda (a b) (> (cdr a) (cdr b))))) (setq tot (apply '+ (append totals nil))) (sh-debug (format "vec: %s\ntotals: %s\ntot: %d" vec totals tot)) ------------------------------------------------------------ revno: 114785 fixes bug: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15699 author: Helmut Eller committer: Stefan Monnier branch nick: trunk timestamp: Thu 2013-10-24 13:49:12 -0400 message: * lisp/emacs-lisp/lisp-mode.el (lisp-cl-font-lock-keywords-2): Fix cut&paste. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-24 17:18:46 +0000 +++ lisp/ChangeLog 2013-10-24 17:49:12 +0000 @@ -1,3 +1,8 @@ +2013-10-24 Helmut Eller + + * emacs-lisp/lisp-mode.el (lisp-cl-font-lock-keywords-2): Fix cut&paste + (bug#15699). + 2013-10-24 Glenn Morris * Makefile.in (abs_top_srcdir): Remove. @@ -7,8 +12,8 @@ * Makefile.in ($(MH_E_DIR)/mh-loaddefs.el) ($(TRAMP_DIR)/tramp-loaddefs.el, $(CAL_DIR)/cal-loaddefs.el) - ($(CAL_DIR)/diary-loaddefs.el, $(CAL_DIR)/hol-loaddefs.el): Call - unmsys--file-name before expand-file-name, not after it. + ($(CAL_DIR)/diary-loaddefs.el, $(CAL_DIR)/hol-loaddefs.el): + Call unmsys--file-name before expand-file-name, not after it. 2013-10-24 Michael Albinus @@ -21,8 +26,8 @@ (ert-test-result-expected-p, ert--stats, ert-stats-completed) (ert--stats-set-test-and-result, ert-char-for-test-result) (ert-string-for-test-result, ert-run-tests-batch) - (ert--results-update-ewoc-hf, ert-run-tests-interactively): Handle - skipped tests. + (ert--results-update-ewoc-hf, ert-run-tests-interactively): + Handle skipped tests. 2013-10-24 Glenn Morris === modified file 'lisp/emacs-lisp/lisp-mode.el' --- lisp/emacs-lisp/lisp-mode.el 2013-10-08 14:57:18 +0000 +++ lisp/emacs-lisp/lisp-mode.el 2013-10-24 17:49:12 +0000 @@ -251,9 +251,7 @@ (cons "go" (mapcar (lambda (s) (concat "cl-" s)) (remove "go" cl-lib-kw)))) t) - (regexp-opt (append lisp-kw el-kw eieio-kw - (cons "go" (mapcar (lambda (s) (concat "cl-" s)) - (remove "go" cl-kw)))) + (regexp-opt (append lisp-kw cl-kw eieio-kw cl-lib-kw) t) ;; Elisp and Common Lisp "errors". @@ -360,7 +358,7 @@ ;; Control structures. Common Lisp forms. (,(concat "(" cl-kws-re "\\_>") . 1) ;; Exit/Feature symbols as constants. - (,(concat "(\\(catch\\|throw\\|featurep\\|provide\\|require\\)\\_>" + (,(concat "(\\(catch\\|throw\\|provide\\|require\\)\\_>" "[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?") (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) ------------------------------------------------------------ revno: 114784 committer: Glenn Morris branch nick: trunk timestamp: Thu 2013-10-24 13:18:46 -0400 message: * lisp/Makefile.in (abs_top_srcdir): Remove. (update-subdirs): Use relative path to update-subdirs. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-24 16:28:05 +0000 +++ lisp/ChangeLog 2013-10-24 17:18:46 +0000 @@ -1,3 +1,8 @@ +2013-10-24 Glenn Morris + + * Makefile.in (abs_top_srcdir): Remove. + (update-subdirs): Use relative path to update-subdirs. + 2013-10-24 Eli Zaretskii * Makefile.in ($(MH_E_DIR)/mh-loaddefs.el) === modified file 'lisp/Makefile.in' --- lisp/Makefile.in 2013-10-24 16:28:05 +0000 +++ lisp/Makefile.in 2013-10-24 17:18:46 +0000 @@ -22,7 +22,6 @@ srcdir = @srcdir@ abs_srcdir = @abs_srcdir@ top_srcdir = @top_srcdir@ -abs_top_srcdir = @abs_top_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_lisp = $(abs_srcdir) lisp = $(srcdir) @@ -194,7 +193,7 @@ update-subdirs: doit cd $(lisp); $(setwins_for_subdirs); \ for file in $$wins; do \ - $(abs_top_srcdir)/build-aux/update-subdirs $$file; \ + ../build-aux/update-subdirs $$file; \ done; .PHONY: updates bzr-update update-authors ------------------------------------------------------------ revno: 114783 committer: Eli Zaretskii branch nick: trunk timestamp: Thu 2013-10-24 19:28:05 +0300 message: Fix last changes to support whitespace in directory names. lisp/Makefile.in ($(MH_E_DIR)/mh-loaddefs.el) ($(TRAMP_DIR)/tramp-loaddefs.el, $(CAL_DIR)/cal-loaddefs.el) ($(CAL_DIR)/diary-loaddefs.el, $(CAL_DIR)/hol-loaddefs.el): Call unmsys--file-name before expand-file-name, not after it. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-24 07:34:41 +0000 +++ lisp/ChangeLog 2013-10-24 16:28:05 +0000 @@ -1,3 +1,10 @@ +2013-10-24 Eli Zaretskii + + * Makefile.in ($(MH_E_DIR)/mh-loaddefs.el) + ($(TRAMP_DIR)/tramp-loaddefs.el, $(CAL_DIR)/cal-loaddefs.el) + ($(CAL_DIR)/diary-loaddefs.el, $(CAL_DIR)/hol-loaddefs.el): Call + unmsys--file-name before expand-file-name, not after it. + 2013-10-24 Michael Albinus * emacs-lisp/ert.el (ert-deftest): Bind macro `skip-unless'. === modified file 'lisp/Makefile.in' --- lisp/Makefile.in 2013-10-24 02:21:23 +0000 +++ lisp/Makefile.in 2013-10-24 16:28:05 +0000 @@ -381,7 +381,7 @@ $(MH_E_DIR)/mh-loaddefs.el: $(MH_E_SRC) $(emacs) -l autoload \ --eval "(setq generate-autoload-cookie \";;;###mh-autoload\")" \ - --eval "(setq generated-autoload-file (unmsys--file-name (expand-file-name \"$@\")))" \ + --eval "(setq generated-autoload-file (expand-file-name (unmsys--file-name \"$@\")))" \ --eval "(setq make-backup-files nil)" \ -f batch-update-autoloads $(MH_E_DIR) @@ -399,7 +399,7 @@ $(TRAMP_DIR)/tramp-loaddefs.el: $(TRAMP_SRC) $(emacs) -l autoload \ --eval "(setq generate-autoload-cookie \";;;###tramp-autoload\")" \ - --eval "(setq generated-autoload-file (unmsys--file-name (expand-file-name \"$@\")))" \ + --eval "(setq generated-autoload-file (expand-file-name (unmsys--file-name \"$@\")))" \ --eval "(setq make-backup-files nil)" \ -f batch-update-autoloads $(TRAMP_DIR) @@ -421,21 +421,21 @@ $(CAL_DIR)/cal-loaddefs.el: $(CAL_SRC) $(emacs) -l autoload \ --eval "(setq generate-autoload-cookie \";;;###cal-autoload\")" \ - --eval "(setq generated-autoload-file (unmsys--file-name (expand-file-name \"$@\")))" \ + --eval "(setq generated-autoload-file (expand-file-name (unmsys--file-name \"$@\")))" \ --eval "(setq make-backup-files nil)" \ -f batch-update-autoloads $(CAL_DIR) $(CAL_DIR)/diary-loaddefs.el: $(CAL_SRC) $(emacs) -l autoload \ --eval "(setq generate-autoload-cookie \";;;###diary-autoload\")" \ - --eval "(setq generated-autoload-file (unmsys--file-name (expand-file-name \"$@\")))" \ + --eval "(setq generated-autoload-file (expand-file-name (unmsys--file-name \"$@\")))" \ --eval "(setq make-backup-files nil)" \ -f batch-update-autoloads $(CAL_DIR) $(CAL_DIR)/hol-loaddefs.el: $(CAL_SRC) $(emacs) -l autoload \ --eval "(setq generate-autoload-cookie \";;;###holiday-autoload\")" \ - --eval "(setq generated-autoload-file (unmsys--file-name (expand-file-name \"$@\")))" \ + --eval "(setq generated-autoload-file (expand-file-name (unmsys--file-name \"$@\")))" \ --eval "(setq make-backup-files nil)" \ -f batch-update-autoloads $(CAL_DIR) ------------------------------------------------------------ revno: 114782 committer: Xue Fuqiao branch nick: trunk timestamp: Thu 2013-10-24 22:00:59 +0800 message: Improve indexing. diff: === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2013-10-24 13:53:20 +0000 +++ doc/lispref/ChangeLog 2013-10-24 14:00:59 +0000 @@ -1,7 +1,7 @@ 2013-10-24 Xue Fuqiao * display.texi (Face Remapping): Add indexes for face remapping. - (Font Selection): Add indexes for font selection. + (Font Selection): Add indexes. (Low-Level Font): Add an index for font registry. 2013-10-23 Glenn Morris === modified file 'doc/lispref/display.texi' --- doc/lispref/display.texi 2013-10-24 13:53:20 +0000 +++ doc/lispref/display.texi 2013-10-24 14:00:59 +0000 @@ -2936,6 +2936,7 @@ until it finds a registry that does exist. @end defopt +@cindex scalable fonts Emacs can make use of scalable fonts, but by default it does not use them. ------------------------------------------------------------ revno: 114781 committer: Xue Fuqiao branch nick: trunk timestamp: Thu 2013-10-24 21:53:20 +0800 message: * doc/lispref/display.texi (Low-Level Font): Add an index for font registry. diff: === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2013-10-24 13:16:51 +0000 +++ doc/lispref/ChangeLog 2013-10-24 13:53:20 +0000 @@ -2,6 +2,7 @@ * display.texi (Face Remapping): Add indexes for face remapping. (Font Selection): Add indexes for font selection. + (Low-Level Font): Add an index for font registry. 2013-10-23 Glenn Morris === modified file 'doc/lispref/display.texi' --- doc/lispref/display.texi 2013-10-24 13:16:51 +0000 +++ doc/lispref/display.texi 2013-10-24 13:53:20 +0000 @@ -3241,6 +3241,7 @@ Additional typographic style information for the font, such as @samp{sans}. The value should be a string or a symbol. +@cindex font registry @item :registry The charset registry and encoding of the font, such as @samp{iso8859-1}. The value should be a string or a symbol. ------------------------------------------------------------ revno: 114780 committer: Xue Fuqiao branch nick: trunk timestamp: Thu 2013-10-24 21:16:51 +0800 message: * doc/lispref/display.texi (Font Selection): Add indexes for font selection. diff: === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2013-10-24 12:17:57 +0000 +++ doc/lispref/ChangeLog 2013-10-24 13:16:51 +0000 @@ -1,6 +1,7 @@ 2013-10-24 Xue Fuqiao * display.texi (Face Remapping): Add indexes for face remapping. + (Font Selection): Add indexes for font selection. 2013-10-23 Glenn Morris === modified file 'doc/lispref/display.texi' --- doc/lispref/display.texi 2013-10-24 12:17:57 +0000 +++ doc/lispref/display.texi 2013-10-24 13:16:51 +0000 @@ -2864,6 +2864,8 @@ @node Font Selection @subsection Font Selection +@cindex font selection +@cindex selecting a font Before Emacs can draw a character on a graphical display, it must select a @dfn{font} for that character@footnote{In this context, the ------------------------------------------------------------ revno: 114779 committer: Xue Fuqiao branch nick: trunk timestamp: Thu 2013-10-24 20:17:57 +0800 message: * doc/lispref/display.texi (Face Remapping): Add indexes for face remapping. diff: === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2013-10-23 17:20:09 +0000 +++ doc/lispref/ChangeLog 2013-10-24 12:17:57 +0000 @@ -1,3 +1,7 @@ +2013-10-24 Xue Fuqiao + + * display.texi (Face Remapping): Add indexes for face remapping. + 2013-10-23 Glenn Morris * eval.texi, files.texi, intro.texi, objects.texi, searching.texi: === modified file 'doc/lispref/display.texi' --- doc/lispref/display.texi 2013-10-23 13:29:39 +0000 +++ doc/lispref/display.texi 2013-10-24 12:17:57 +0000 @@ -2651,6 +2651,8 @@ @code{mode-line} face. @end defvar +@cindex relative remapping, faces +@cindex base remapping, faces The following functions implement a higher-level interface to @code{face-remapping-alist}. Most Lisp code should use these functions instead of setting @code{face-remapping-alist} directly, to ------------------------------------------------------------ revno: 114778 committer: Glenn Morris branch nick: trunk timestamp: Thu 2013-10-24 06:17:42 -0400 message: Auto-commit of generated files. diff: === modified file 'autogen/configure' --- autogen/configure 2013-10-23 10:17:41 +0000 +++ autogen/configure 2013-10-24 10:17:42 +0000 @@ -4034,6 +4034,15 @@ +for var in "`pwd`" "`cd \"$srcdir\"; pwd`" "$prefix" "$exec_prefix" \ + "$datarootdir" "$bindir" "$datadir" "$sharedstatedir" "$libexecdir"; do + + case "$var" in + *[^\ -~]*) as_fn_error "Emacs cannot be built or installed in a directory whose name contains non-ASCII characters: $var" "$LINENO" 5 ;; + esac + +done + lispdir='${datadir}/emacs/${version}/lisp' leimdir='${datadir}/emacs/${version}/leim' standardlisppath='${lispdir}:${leimdir}' @@ -29289,7 +29298,7 @@ LIBS=$SAVE_LIBS if test "${opsys}" = "mingw32"; then - CPPFLAGS="$CPPFLAGS -DUSE_CRT_DLL=1 -I $srcdir/nt/inc" + CPPFLAGS="$CPPFLAGS -DUSE_CRT_DLL=1 -I \${abs_top_srcdir}/nt/inc" # Remove unneeded switches from the value of CC that goes to Makefiles CC=`echo $CC | sed -e "s,$GCC_TEST_OPTIONS,,"` fi @@ -31140,7 +31149,7 @@ ;; "src/.gdbinit":C) if test ! -f src/.gdbinit && test -f "$srcdir/src/.gdbinit"; then - echo "source $srcdir/src/.gdbinit" > src/.gdbinit + echo "source $ac_abs_top_srcdir/src/.gdbinit" > src/.gdbinit fi ;; ------------------------------------------------------------ revno: 114777 committer: Michael Albinus branch nick: trunk timestamp: Thu 2013-10-24 09:42:18 +0200 message: Mention the `skip-unless' macro of ert.el. diff: === modified file 'etc/NEWS' --- etc/NEWS 2013-10-19 15:30:39 +0000 +++ etc/NEWS 2013-10-24 07:42:18 +0000 @@ -591,6 +591,9 @@ whether it is safe to use Bash's --noediting option. These days --noediting is ubiquitous; it was introduced in 1996 in Bash version 2. ++++ +** There is a new macro `skip-unless' for skipping ERT tests. See the manual. + * New Modes and Packages in Emacs 24.4