aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes
diff options
context:
space:
mode:
authorJoakim Verona2013-06-12 12:32:25 +0200
committerJoakim Verona2013-06-12 12:32:25 +0200
commite6fa6da6899bf1b4877b96c450eae3934085d560 (patch)
tree48e6fda463d24a792ec8428fb8044a250ee2ff82 /lisp/progmodes
parent4f0994366d33f8f76db4662cc126720866df3461 (diff)
parent84d6f46535554f9f51aae3314313112e8d755c65 (diff)
downloademacs-e6fa6da6899bf1b4877b96c450eae3934085d560.tar.gz
emacs-e6fa6da6899bf1b4877b96c450eae3934085d560.zip
Merge branch 'trunk' into xwidget
Conflicts: src/Makefile.in src/keyboard.c src/termhooks.h
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/cc-bytecomp.el16
-rw-r--r--lisp/progmodes/cc-cmds.el1
-rw-r--r--lisp/progmodes/cc-defs.el14
-rw-r--r--lisp/progmodes/cc-engine.el7
-rw-r--r--lisp/progmodes/cc-fonts.el1
-rw-r--r--lisp/progmodes/cc-mode.el5
-rw-r--r--lisp/progmodes/cc-vars.el23
-rw-r--r--lisp/progmodes/cfengine.el10
-rw-r--r--lisp/progmodes/compile.el6
-rw-r--r--lisp/progmodes/gdb-mi.el2
-rw-r--r--lisp/progmodes/octave.el185
-rw-r--r--lisp/progmodes/perl-mode.el49
-rw-r--r--lisp/progmodes/prog-mode.el119
-rw-r--r--lisp/progmodes/prolog.el44
-rw-r--r--lisp/progmodes/python.el5
-rw-r--r--lisp/progmodes/ruby-mode.el110
-rw-r--r--lisp/progmodes/tcl.el2
17 files changed, 359 insertions, 240 deletions
diff --git a/lisp/progmodes/cc-bytecomp.el b/lisp/progmodes/cc-bytecomp.el
index e41455f7883..337a5292417 100644
--- a/lisp/progmodes/cc-bytecomp.el
+++ b/lisp/progmodes/cc-bytecomp.el
@@ -232,6 +232,9 @@ perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere"))
232 (cc-bytecomp-setup-environment) 232 (cc-bytecomp-setup-environment)
233 t)))) 233 t))))
234 234
235(defvar cc-bytecomp-noruntime-functions nil
236 "Saved value of `byte-compile-noruntime-functions'.")
237
235(defmacro cc-require (cc-part) 238(defmacro cc-require (cc-part)
236 "Force loading of the corresponding .el file in the current directory 239 "Force loading of the corresponding .el file in the current directory
237during compilation, but compile in a `require'. Don't use within 240during compilation, but compile in a `require'. Don't use within
@@ -240,7 +243,16 @@ during compilation, but compile in a `require'. Don't use within
240Having cyclic cc-require's will result in infinite recursion. That's 243Having cyclic cc-require's will result in infinite recursion. That's
241somewhat intentional." 244somewhat intentional."
242 `(progn 245 `(progn
243 (eval-when-compile (cc-bytecomp-load (symbol-name ,cc-part))) 246 (eval-when-compile
247 (setq cc-bytecomp-noruntime-functions byte-compile-noruntime-functions)
248 (cc-bytecomp-load (symbol-name ,cc-part)))
249 ;; Hack to suppress spurious "might not be defined at runtime" warnings.
250 ;; The basic issue is that
251 ;; (eval-when-compile (require 'foo))
252 ;; (require 'foo)
253 ;; produces bogus noruntime warnings about functions from foo.
254 (eval-when-compile
255 (setq byte-compile-noruntime-functions cc-bytecomp-noruntime-functions))
244 (require ,cc-part))) 256 (require ,cc-part)))
245 257
246(defmacro cc-provide (feature) 258(defmacro cc-provide (feature)
@@ -266,7 +278,7 @@ somewhat intentional."
266during compilation, but do a compile time `require' otherwise. Don't 278during compilation, but do a compile time `require' otherwise. Don't
267use within `eval-when-compile'." 279use within `eval-when-compile'."
268 `(eval-when-compile 280 `(eval-when-compile
269 (if (and (featurep 'cc-bytecomp) 281 (if (and (fboundp 'cc-bytecomp-is-compiling)
270 (cc-bytecomp-is-compiling)) 282 (cc-bytecomp-is-compiling))
271 (if (or (not load-in-progress) 283 (if (or (not load-in-progress)
272 (not (featurep ,cc-part))) 284 (not (featurep ,cc-part)))
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 0bb804799dc..dc6ed1348d1 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -45,7 +45,6 @@
45(cc-require 'cc-engine) 45(cc-require 'cc-engine)
46 46
47;; Silence the compiler. 47;; Silence the compiler.
48(cc-bytecomp-defun delete-forward-p) ; XEmacs
49(cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge 48(cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge
50 ; which looks at this. 49 ; which looks at this.
51 50
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index e7f96767675..b90a01dcb3b 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -48,16 +48,12 @@
48 48
49;; Silence the compiler. 49;; Silence the compiler.
50(cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el 50(cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el
51(cc-bytecomp-defun buffer-syntactic-context-depth) ; XEmacs
52(cc-bytecomp-defun region-active-p) ; XEmacs 51(cc-bytecomp-defun region-active-p) ; XEmacs
53(cc-bytecomp-defvar zmacs-region-stays) ; XEmacs
54(cc-bytecomp-defvar zmacs-regions) ; XEmacs
55(cc-bytecomp-defvar mark-active) ; Emacs 52(cc-bytecomp-defvar mark-active) ; Emacs
56(cc-bytecomp-defvar deactivate-mark) ; Emacs 53(cc-bytecomp-defvar deactivate-mark) ; Emacs
57(cc-bytecomp-defvar inhibit-point-motion-hooks) ; Emacs 54(cc-bytecomp-defvar inhibit-point-motion-hooks) ; Emacs
58(cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs 55(cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs
59(cc-bytecomp-defvar text-property-default-nonsticky) ; Emacs 21 56(cc-bytecomp-defvar text-property-default-nonsticky) ; Emacs 21
60(cc-bytecomp-defvar lookup-syntax-properties) ; XEmacs
61(cc-bytecomp-defun string-to-syntax) ; Emacs 21 57(cc-bytecomp-defun string-to-syntax) ; Emacs 21
62 58
63 59
@@ -334,6 +330,8 @@ to it is returned. This function does not modify the point or the mark."
334(defmacro c-region-is-active-p () 330(defmacro c-region-is-active-p ()
335 ;; Return t when the region is active. The determination of region 331 ;; Return t when the region is active. The determination of region
336 ;; activeness is different in both Emacs and XEmacs. 332 ;; activeness is different in both Emacs and XEmacs.
333 ;; FIXME? Emacs has region-active-p since 23.1, so maybe this test
334 ;; should be updated.
337 (if (cc-bytecomp-boundp 'mark-active) 335 (if (cc-bytecomp-boundp 'mark-active)
338 ;; Emacs. 336 ;; Emacs.
339 'mark-active 337 'mark-active
@@ -343,7 +341,7 @@ to it is returned. This function does not modify the point or the mark."
343(defmacro c-set-region-active (activate) 341(defmacro c-set-region-active (activate)
344 ;; Activate the region if ACTIVE is non-nil, deactivate it 342 ;; Activate the region if ACTIVE is non-nil, deactivate it
345 ;; otherwise. Covers the differences between Emacs and XEmacs. 343 ;; otherwise. Covers the differences between Emacs and XEmacs.
346 (if (cc-bytecomp-fboundp 'zmacs-activate-region) 344 (if (fboundp 'zmacs-activate-region)
347 ;; XEmacs. 345 ;; XEmacs.
348 `(if ,activate 346 `(if ,activate
349 (zmacs-activate-region) 347 (zmacs-activate-region)
@@ -707,9 +705,9 @@ be after it."
707 ;; `c-parse-state'. 705 ;; `c-parse-state'.
708 706
709 `(progn 707 `(progn
710 (if (and ,(cc-bytecomp-fboundp 'buffer-syntactic-context-depth) 708 (if (and ,(fboundp 'buffer-syntactic-context-depth)
711 c-enable-xemacs-performance-kludge-p) 709 c-enable-xemacs-performance-kludge-p)
712 ,(when (cc-bytecomp-fboundp 'buffer-syntactic-context-depth) 710 ,(when (fboundp 'buffer-syntactic-context-depth)
713 ;; XEmacs only. This can improve the performance of 711 ;; XEmacs only. This can improve the performance of
714 ;; c-parse-state to between 3 and 60 times faster when 712 ;; c-parse-state to between 3 and 60 times faster when
715 ;; braces are hung. It can also degrade performance by 713 ;; braces are hung. It can also degrade performance by
@@ -1606,7 +1604,7 @@ non-nil, a caret is prepended to invert the set."
1606 (let ((buf (generate-new-buffer " test")) 1604 (let ((buf (generate-new-buffer " test"))
1607 parse-sexp-lookup-properties 1605 parse-sexp-lookup-properties
1608 parse-sexp-ignore-comments 1606 parse-sexp-ignore-comments
1609 lookup-syntax-properties) 1607 lookup-syntax-properties) ; XEmacs
1610 (with-current-buffer buf 1608 (with-current-buffer buf
1611 (set-syntax-table (make-syntax-table)) 1609 (set-syntax-table (make-syntax-table))
1612 1610
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 6a23da1f2cd..9077bdbb513 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -147,9 +147,6 @@
147(cc-require-when-compile 'cc-langs) 147(cc-require-when-compile 'cc-langs)
148(cc-require 'cc-vars) 148(cc-require 'cc-vars)
149 149
150;; Silence the compiler.
151(cc-bytecomp-defun buffer-syntactic-context) ; XEmacs
152
153 150
154;; Make declarations for all the `c-lang-defvar' variables in cc-langs. 151;; Make declarations for all the `c-lang-defvar' variables in cc-langs.
155 152
@@ -9358,10 +9355,6 @@ comment at the start of cc-engine.el for more info."
9358 containing-sexp nil))) 9355 containing-sexp nil)))
9359 (setq lim (1+ containing-sexp)))) 9356 (setq lim (1+ containing-sexp))))
9360 (setq lim (point-min))) 9357 (setq lim (point-min)))
9361 (when (c-beginning-of-macro)
9362 (goto-char indent-point)
9363 (let ((lim1 (c-determine-limit 2000)))
9364 (setq lim (max lim lim1))))
9365 9358
9366 ;; If we're in a parenthesis list then ',' delimits the 9359 ;; If we're in a parenthesis list then ',' delimits the
9367 ;; "statements" rather than being an operator (with the 9360 ;; "statements" rather than being an operator (with the
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 83343b23014..6a4bfd9e875 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -176,7 +176,6 @@
176 'font-lock-negation-char-face)) 176 'font-lock-negation-char-face))
177 177
178(cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs. 178(cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs.
179(cc-bytecomp-defun face-property-instance) ; Only in XEmacs.
180 179
181(defun c-make-inverse-face (oldface newface) 180(defun c-make-inverse-face (oldface newface)
182 ;; Emacs and XEmacs have completely different face manipulation 181 ;; Emacs and XEmacs have completely different face manipulation
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 746b75d962b..74818b7e1ea 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -86,8 +86,8 @@
86 (load "cc-bytecomp" nil t))) 86 (load "cc-bytecomp" nil t)))
87 87
88(cc-require 'cc-defs) 88(cc-require 'cc-defs)
89(cc-require-when-compile 'cc-langs)
90(cc-require 'cc-vars) 89(cc-require 'cc-vars)
90(cc-require-when-compile 'cc-langs)
91(cc-require 'cc-engine) 91(cc-require 'cc-engine)
92(cc-require 'cc-styles) 92(cc-require 'cc-styles)
93(cc-require 'cc-cmds) 93(cc-require 'cc-cmds)
@@ -97,7 +97,6 @@
97 97
98;; Silence the compiler. 98;; Silence the compiler.
99(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs 99(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
100(cc-bytecomp-defun set-keymap-parents) ; XEmacs
101(cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1 100(cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1
102 101
103;; We set these variables during mode init, yet we don't require 102;; We set these variables during mode init, yet we don't require
@@ -212,7 +211,7 @@ control). See \"cc-mode.el\" for more info."
212 ((cc-bytecomp-fboundp 'set-keymap-parent) 211 ((cc-bytecomp-fboundp 'set-keymap-parent)
213 (set-keymap-parent map c-mode-base-map)) 212 (set-keymap-parent map c-mode-base-map))
214 ;; XEmacs 213 ;; XEmacs
215 ((cc-bytecomp-fboundp 'set-keymap-parents) 214 ((fboundp 'set-keymap-parents)
216 (set-keymap-parents map c-mode-base-map)) 215 (set-keymap-parents map c-mode-base-map))
217 ;; incompatible 216 ;; incompatible
218 (t (error "CC Mode is incompatible with this version of Emacs"))) 217 (t (error "CC Mode is incompatible with this version of Emacs")))
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index f830cc7edc1..c89402c63a3 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -42,23 +42,25 @@
42 42
43(cc-require 'cc-defs) 43(cc-require 'cc-defs)
44 44
45;; Silence the compiler.
46(cc-bytecomp-defun get-char-table) ; XEmacs
47
48(cc-eval-when-compile 45(cc-eval-when-compile
49 (require 'custom) 46 (require 'custom)
50 (require 'widget)) 47 (require 'widget))
51 48
52;;; Helpers 49;;; Helpers
53 50
54;; This widget exists in newer versions of the Custom library 51
55(or (get 'other 'widget-type) 52;; Emacs has 'other since at least version 21.1.
56 (define-widget 'other 'sexp 53;; FIXME this is probably broken, since the widget is defined
57 "Matches everything, but doesn't let the user edit the value. 54;; in wid-edit, which this file does not load. So we will always
55;; define the widget, even when we don't need to.
56(when (featurep 'xemacs)
57 (or (get 'other 'widget-type)
58 (define-widget 'other 'sexp
59 "Matches everything, but doesn't let the user edit the value.
58Useful as last item in a `choice' widget." 60Useful as last item in a `choice' widget."
59 :tag "Other" 61 :tag "Other"
60 :format "%t%n" 62 :format "%t%n"
61 :value 'other)) 63 :value 'other)))
62 64
63;; The next defun will supersede c-const-symbol. 65;; The next defun will supersede c-const-symbol.
64(eval-and-compile 66(eval-and-compile
@@ -1645,6 +1647,7 @@ and is likely to disappear or change its form soon.")
1645 ;; `c-macro-with-semi-re' (or just copy it if it's already a re). 1647 ;; `c-macro-with-semi-re' (or just copy it if it's already a re).
1646 (setq c-macro-with-semi-re 1648 (setq c-macro-with-semi-re
1647 (and 1649 (and
1650 (boundp 'c-opt-cpp-macro-define)
1648 c-opt-cpp-macro-define 1651 c-opt-cpp-macro-define
1649 (cond 1652 (cond
1650 ((stringp c-macro-names-with-semicolon) 1653 ((stringp c-macro-names-with-semicolon)
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el
index 11eb0eeaf49..01b5faef5b3 100644
--- a/lisp/progmodes/cfengine.el
+++ b/lisp/progmodes/cfengine.el
@@ -527,6 +527,11 @@ Intended as the value of `indent-line-function'."
527 ;; Doze path separators. 527 ;; Doze path separators.
528 (modify-syntax-entry ?\\ "." table)) 528 (modify-syntax-entry ?\\ "." table))
529 529
530(defconst cfengine3--prettify-symbols-alist
531 '(("->" . ?→)
532 ("=>" . ?⇒)
533 ("::" . ?∷)))
534
530;;;###autoload 535;;;###autoload
531(define-derived-mode cfengine3-mode prog-mode "CFE3" 536(define-derived-mode cfengine3-mode prog-mode "CFE3"
532 "Major mode for editing CFEngine3 input. 537 "Major mode for editing CFEngine3 input.
@@ -538,8 +543,11 @@ to the action header."
538 (cfengine-common-syntax cfengine3-mode-syntax-table) 543 (cfengine-common-syntax cfengine3-mode-syntax-table)
539 544
540 (set (make-local-variable 'indent-line-function) #'cfengine3-indent-line) 545 (set (make-local-variable 'indent-line-function) #'cfengine3-indent-line)
546
541 (setq font-lock-defaults 547 (setq font-lock-defaults
542 '(cfengine3-font-lock-keywords nil nil nil beginning-of-defun)) 548 '(cfengine3-font-lock-keywords
549 nil nil nil beginning-of-defun))
550 (prog-prettify-install cfengine3--prettify-symbols-alist)
543 551
544 ;; Use defuns as the essential syntax block. 552 ;; Use defuns as the essential syntax block.
545 (set (make-local-variable 'beginning-of-defun-function) 553 (set (make-local-variable 'beginning-of-defun-function)
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index d6f136ec92d..d9c482330cc 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -1002,7 +1002,7 @@ POS and RES.")
1002 (let ((win (get-buffer-window buffer 0))) 1002 (let ((win (get-buffer-window buffer 0)))
1003 (if win (set-window-point win pos))) 1003 (if win (set-window-point win pos)))
1004 (if compilation-auto-jump-to-first-error 1004 (if compilation-auto-jump-to-first-error
1005 (compile-goto-error)))) 1005 (compile-goto-error nil t))))
1006 1006
1007;; This function is the central driver, called when font-locking to gather 1007;; This function is the central driver, called when font-locking to gather
1008;; all information needed to later jump to corresponding source code. 1008;; all information needed to later jump to corresponding source code.
@@ -2317,7 +2317,7 @@ Prefix arg N says how many files to move backwards (or forwards, if negative)."
2317 2317
2318(defalias 'compile-mouse-goto-error 'compile-goto-error) 2318(defalias 'compile-mouse-goto-error 'compile-goto-error)
2319 2319
2320(defun compile-goto-error (&optional event) 2320(defun compile-goto-error (&optional event nomsg)
2321 "Visit the source for the error message at point. 2321 "Visit the source for the error message at point.
2322Use this command in a compilation log buffer. Sets the mark at point there." 2322Use this command in a compilation log buffer. Sets the mark at point there."
2323 (interactive (list last-input-event)) 2323 (interactive (list last-input-event))
@@ -2328,7 +2328,7 @@ Use this command in a compilation log buffer. Sets the mark at point there."
2328 (if (get-text-property (point) 'compilation-directory) 2328 (if (get-text-property (point) 'compilation-directory)
2329 (dired-other-window 2329 (dired-other-window
2330 (car (get-text-property (point) 'compilation-directory))) 2330 (car (get-text-property (point) 'compilation-directory)))
2331 (push-mark) 2331 (push-mark nil nomsg)
2332 (setq compilation-current-error (point)) 2332 (setq compilation-current-error (point))
2333 (next-error-internal))) 2333 (next-error-internal)))
2334 2334
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index a6ad5736576..0b52302a98d 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -345,7 +345,7 @@ triggers in `gdb-handler-list'."
345 `(run-with-timer 345 `(run-with-timer
346 0.5 nil 346 0.5 nil
347 '(lambda () 347 '(lambda ()
348 (if (not (gdb-find-if (lambda (handler) 348 (if (not (cl-find-if (lambda (handler)
349 (gdb-handler-pending-trigger handler)) 349 (gdb-handler-pending-trigger handler))
350 gdb-handler-list)) 350 gdb-handler-list))
351 (progn ,@body) 351 (progn ,@body)
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index bacd37b3d3c..b1936467274 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -89,7 +89,7 @@ Used in `octave-mode' and `inferior-octave-mode' buffers.")
89 89
90(defvar octave-function-header-regexp 90(defvar octave-function-header-regexp
91 (concat "^\\s-*\\_<\\(function\\)\\_>" 91 (concat "^\\s-*\\_<\\(function\\)\\_>"
92 "\\([^=;\n]*=[ \t]*\\|[ \t]*\\)\\(\\(?:\\w\\|\\s_\\)+\\)\\_>") 92 "\\([^=;(\n]*=[ \t]*\\|[ \t]*\\)\\(\\(?:\\w\\|\\s_\\)+\\)\\_>")
93 "Regexp to match an Octave function header. 93 "Regexp to match an Octave function header.
94The string `function' and its name are given by the first and third 94The string `function' and its name are given by the first and third
95parenthetical grouping.") 95parenthetical grouping.")
@@ -153,10 +153,10 @@ parenthetical grouping.")
153 'eldoc-mode)) 153 'eldoc-mode))
154 :style toggle :selected (or eldoc-post-insert-mode eldoc-mode) 154 :style toggle :selected (or eldoc-post-insert-mode eldoc-mode)
155 :help "Display function signatures after typing `SPC' or `('"] 155 :help "Display function signatures after typing `SPC' or `('"]
156 ["Delimiter Matching" smie-highlight-matching-block-mode 156 ["Delimiter Matching" show-paren-mode
157 :style toggle :selected smie-highlight-matching-block-mode 157 :style toggle :selected show-paren-mode
158 :help "Highlight matched pairs such as `if ... end'" 158 :help "Highlight matched pairs such as `if ... end'"
159 :visible (fboundp 'smie-highlight-matching-block-mode)] 159 :visible (fboundp 'smie--matching-block-data)]
160 ["Auto Fill" auto-fill-mode 160 ["Auto Fill" auto-fill-mode
161 :style toggle :selected auto-fill-function 161 :style toggle :selected auto-fill-function
162 :help "Automatic line breaking"] 162 :help "Automatic line breaking"]
@@ -191,10 +191,9 @@ parenthetical grouping.")
191 (modify-syntax-entry ?! "." table) 191 (modify-syntax-entry ?! "." table)
192 (modify-syntax-entry ?\\ "." table) 192 (modify-syntax-entry ?\\ "." table)
193 (modify-syntax-entry ?\' "." table) 193 (modify-syntax-entry ?\' "." table)
194 ;; Was "w" for abbrevs, but now that it's not necessary any more,
195 (modify-syntax-entry ?\` "." table) 194 (modify-syntax-entry ?\` "." table)
195 (modify-syntax-entry ?. "." table)
196 (modify-syntax-entry ?\" "\"" table) 196 (modify-syntax-entry ?\" "\"" table)
197 (modify-syntax-entry ?. "_" table)
198 (modify-syntax-entry ?_ "_" table) 197 (modify-syntax-entry ?_ "_" table)
199 ;; The "b" flag only applies to the second letter of the comstart 198 ;; The "b" flag only applies to the second letter of the comstart
200 ;; and the first letter of the comend, i.e. the "4b" below is ineffective. 199 ;; and the first letter of the comend, i.e. the "4b" below is ineffective.
@@ -541,6 +540,7 @@ definitions can also be stored in files and used in batch mode."
541 ;; a ";" at those places where it's correct (i.e. outside of parens). 540 ;; a ";" at those places where it's correct (i.e. outside of parens).
542 (setq-local electric-layout-rules '((?\; . after))) 541 (setq-local electric-layout-rules '((?\; . after)))
543 542
543 (setq-local comment-use-global-state t)
544 (setq-local comment-start octave-comment-start) 544 (setq-local comment-start octave-comment-start)
545 (setq-local comment-end "") 545 (setq-local comment-end "")
546 (setq-local comment-start-skip octave-comment-start-skip) 546 (setq-local comment-start-skip octave-comment-start-skip)
@@ -564,6 +564,8 @@ definitions can also be stored in files and used in batch mode."
564 (setq-local imenu-generic-expression octave-mode-imenu-generic-expression) 564 (setq-local imenu-generic-expression octave-mode-imenu-generic-expression)
565 (setq-local imenu-case-fold-search nil) 565 (setq-local imenu-case-fold-search nil)
566 566
567 (setq-local add-log-current-defun-function #'octave-add-log-current-defun)
568
567 (add-hook 'completion-at-point-functions 'octave-completion-at-point nil t) 569 (add-hook 'completion-at-point-functions 'octave-completion-at-point nil t)
568 (add-hook 'before-save-hook 'octave-sync-function-file-names nil t) 570 (add-hook 'before-save-hook 'octave-sync-function-file-names nil t)
569 (setq-local beginning-of-defun-function 'octave-beginning-of-defun) 571 (setq-local beginning-of-defun-function 'octave-beginning-of-defun)
@@ -606,12 +608,13 @@ startup."
606 :group 'octave 608 :group 'octave
607 :version "24.4") 609 :version "24.4")
608 610
609(defcustom inferior-octave-startup-args nil 611(defcustom inferior-octave-startup-args '("-i" "--no-line-editing")
610 "List of command line arguments for the inferior Octave process. 612 "List of command line arguments for the inferior Octave process.
611For example, for suppressing the startup message and using `traditional' 613For example, for suppressing the startup message and using `traditional'
612mode, set this to (\"-q\" \"--traditional\")." 614mode, include \"-q\" and \"--traditional\"."
613 :type '(repeat string) 615 :type '(repeat string)
614 :group 'octave) 616 :group 'octave
617 :version "24.4")
615 618
616(defcustom inferior-octave-mode-hook nil 619(defcustom inferior-octave-mode-hook nil
617 "Hook to be run when Inferior Octave mode is started." 620 "Hook to be run when Inferior Octave mode is started."
@@ -665,6 +668,7 @@ in the Inferior Octave buffer.")
665 :abbrev-table octave-abbrev-table 668 :abbrev-table octave-abbrev-table
666 (setq comint-prompt-regexp inferior-octave-prompt) 669 (setq comint-prompt-regexp inferior-octave-prompt)
667 670
671 (setq-local comment-use-global-state t)
668 (setq-local comment-start octave-comment-start) 672 (setq-local comment-start octave-comment-start)
669 (setq-local comment-end "") 673 (setq-local comment-end "")
670 (setq comment-column 32) 674 (setq comment-column 32)
@@ -676,13 +680,16 @@ in the Inferior Octave buffer.")
676 (setq-local eldoc-documentation-function 'octave-eldoc-function) 680 (setq-local eldoc-documentation-function 'octave-eldoc-function)
677 681
678 (setq comint-input-ring-file-name 682 (setq comint-input-ring-file-name
679 (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist") 683 (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist")
680 comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024)) 684 comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024))
681 (setq-local comint-dynamic-complete-functions 685 (setq-local comint-dynamic-complete-functions
682 inferior-octave-dynamic-complete-functions) 686 inferior-octave-dynamic-complete-functions)
683 (setq-local comint-prompt-read-only inferior-octave-prompt-read-only) 687 (setq-local comint-prompt-read-only inferior-octave-prompt-read-only)
684 (add-hook 'comint-input-filter-functions 688 (add-hook 'comint-input-filter-functions
685 'inferior-octave-directory-tracker nil t) 689 'inferior-octave-directory-tracker nil t)
690 ;; http://thread.gmane.org/gmane.comp.gnu.octave.general/48572
691 (add-hook 'window-configuration-change-hook
692 'inferior-octave-track-window-width-change nil t)
686 (comint-read-input-ring t)) 693 (comint-read-input-ring t))
687 694
688;;;###autoload 695;;;###autoload
@@ -717,13 +724,13 @@ startup file, `~/.emacs-octave'."
717 (substring inferior-octave-buffer 1 -1) 724 (substring inferior-octave-buffer 1 -1)
718 inferior-octave-buffer 725 inferior-octave-buffer
719 inferior-octave-program 726 inferior-octave-program
720 (append (list "-i" "--no-line-editing") 727 (append
721 ;; --no-gui is introduced in Octave > 3.7 728 inferior-octave-startup-args
722 (when (zerop (process-file inferior-octave-program 729 ;; --no-gui is introduced in Octave > 3.7
723 nil nil nil 730 (and (not (member "--no-gui" inferior-octave-startup-args))
724 "--no-gui" "--help")) 731 (zerop (process-file inferior-octave-program
725 (list "--no-gui")) 732 nil nil nil "--no-gui" "--help"))
726 inferior-octave-startup-args)))) 733 '("--no-gui"))))))
727 (set-process-filter proc 'inferior-octave-output-digest) 734 (set-process-filter proc 'inferior-octave-output-digest)
728 (setq inferior-octave-process proc 735 (setq inferior-octave-process proc
729 inferior-octave-output-list nil 736 inferior-octave-output-list nil
@@ -753,10 +760,10 @@ startup file, `~/.emacs-octave'."
753 (inferior-octave-send-list-and-digest (list "PS2\n")) 760 (inferior-octave-send-list-and-digest (list "PS2\n"))
754 (when (string-match "\\(PS2\\|ans\\) = *$" 761 (when (string-match "\\(PS2\\|ans\\) = *$"
755 (car inferior-octave-output-list)) 762 (car inferior-octave-output-list))
756 (inferior-octave-send-list-and-digest (list "PS2 (\"> \");\n"))) 763 (inferior-octave-send-list-and-digest (list "PS2 ('> ');\n")))
757 764
758 (inferior-octave-send-list-and-digest 765 (inferior-octave-send-list-and-digest
759 (list "disp(getenv(\"OCTAVE_SRCDIR\"))\n")) 766 (list "disp (getenv ('OCTAVE_SRCDIR'))\n"))
760 (process-put proc 'octave-srcdir 767 (process-put proc 'octave-srcdir
761 (unless (equal (car inferior-octave-output-list) "") 768 (unless (equal (car inferior-octave-output-list) "")
762 (car inferior-octave-output-list))) 769 (car inferior-octave-output-list)))
@@ -765,19 +772,19 @@ startup file, `~/.emacs-octave'."
765 (inferior-octave-send-list-and-digest 772 (inferior-octave-send-list-and-digest
766 (list "more off;\n" 773 (list "more off;\n"
767 (unless (equal inferior-octave-output-string ">> ") 774 (unless (equal inferior-octave-output-string ">> ")
768 "PS1 (\"\\\\s> \");\n") 775 "PS1 ('\\s> ');\n")
769 (when (and inferior-octave-startup-file 776 (when (and inferior-octave-startup-file
770 (file-exists-p inferior-octave-startup-file)) 777 (file-exists-p inferior-octave-startup-file))
771 (format "source (\"%s\");\n" inferior-octave-startup-file)))) 778 (format "source ('%s');\n" inferior-octave-startup-file))))
772 (when inferior-octave-output-list 779 (when inferior-octave-output-list
773 (insert-before-markers 780 (insert-before-markers
774 (mapconcat 'identity inferior-octave-output-list "\n"))) 781 (mapconcat 'identity inferior-octave-output-list "\n")))
775 782
776 ;; And finally, everything is back to normal. 783 ;; And finally, everything is back to normal.
777 (set-process-filter proc 'comint-output-filter) 784 (set-process-filter proc 'comint-output-filter)
778 ;; Just in case, to be sure a cd in the startup file 785 ;; Just in case, to be sure a cd in the startup file won't have
779 ;; won't have detrimental effects. 786 ;; detrimental effects.
780 (inferior-octave-resync-dirs) 787 (with-demoted-errors (inferior-octave-resync-dirs))
781 ;; Generate a proper prompt, which is critical to 788 ;; Generate a proper prompt, which is critical to
782 ;; `comint-history-isearch-backward-regexp'. Bug#14433. 789 ;; `comint-history-isearch-backward-regexp'. Bug#14433.
783 (comint-send-string proc "\n"))) 790 (comint-send-string proc "\n")))
@@ -793,7 +800,7 @@ startup file, `~/.emacs-octave'."
793 (unless (and (equal (car cache) command) 800 (unless (and (equal (car cache) command)
794 (< (float-time) (+ 5 (cadr cache)))) 801 (< (float-time) (+ 5 (cadr cache))))
795 (inferior-octave-send-list-and-digest 802 (inferior-octave-send-list-and-digest
796 (list (concat "completion_matches (\"" command "\");\n"))) 803 (list (format "completion_matches ('%s');\n" command)))
797 (setq cache (list command (float-time) 804 (setq cache (list command (float-time)
798 (delete-consecutive-dups 805 (delete-consecutive-dups
799 (sort inferior-octave-output-list 'string-lessp))))) 806 (sort inferior-octave-output-list 'string-lessp)))))
@@ -892,8 +899,8 @@ output is passed to the filter `inferior-octave-output-digest'."
892 "Tracks `cd' commands issued to the inferior Octave process. 899 "Tracks `cd' commands issued to the inferior Octave process.
893Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused." 900Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused."
894 (when inferior-octave-directory-tracker-resync 901 (when inferior-octave-directory-tracker-resync
895 (setq inferior-octave-directory-tracker-resync nil) 902 (or (inferior-octave-resync-dirs 'noerror)
896 (inferior-octave-resync-dirs)) 903 (setq inferior-octave-directory-tracker-resync nil)))
897 (cond 904 (cond
898 ((string-match "^[ \t]*cd[ \t;]*$" string) 905 ((string-match "^[ \t]*cd[ \t;]*$" string)
899 (cd "~")) 906 (cd "~"))
@@ -905,13 +912,35 @@ Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused."
905 (error-message-string err) 912 (error-message-string err)
906 (match-string 1 string))))))) 913 (match-string 1 string)))))))
907 914
908(defun inferior-octave-resync-dirs () 915(defun inferior-octave-resync-dirs (&optional noerror)
909 "Resync the buffer's idea of the current directory. 916 "Resync the buffer's idea of the current directory.
910This command queries the inferior Octave process about its current 917This command queries the inferior Octave process about its current
911directory and makes this the current buffer's default directory." 918directory and makes this the current buffer's default directory."
912 (interactive) 919 (interactive)
913 (inferior-octave-send-list-and-digest '("disp (pwd ())\n")) 920 (inferior-octave-send-list-and-digest '("disp (pwd ())\n"))
914 (cd (car inferior-octave-output-list))) 921 (condition-case err
922 (progn
923 (cd (car inferior-octave-output-list))
924 t)
925 (error (unless noerror (signal (car err) (cdr err))))))
926
927(defcustom inferior-octave-minimal-columns 80
928 "The minimal column width for the inferior Octave process."
929 :type 'integer
930 :group 'octave
931 :version "24.4")
932
933(defvar inferior-octave-last-column-width nil)
934
935(defun inferior-octave-track-window-width-change ()
936 ;; http://thread.gmane.org/gmane.comp.gnu.octave.general/48572
937 (let ((width (max inferior-octave-minimal-columns (window-width))))
938 (unless (eq inferior-octave-last-column-width width)
939 (setq-local inferior-octave-last-column-width width)
940 (when (and inferior-octave-process
941 (process-live-p inferior-octave-process))
942 (inferior-octave-send-list-and-digest
943 (list (format "putenv ('COLUMNS', '%s');\n" width)))))))
915 944
916 945
917;;; Miscellaneous useful functions 946;;; Miscellaneous useful functions
@@ -955,16 +984,17 @@ directory and makes this the current buffer's default directory."
955 984
956(defun octave-goto-function-definition (fn) 985(defun octave-goto-function-definition (fn)
957 "Go to the function definition of FN in current buffer." 986 "Go to the function definition of FN in current buffer."
958 (goto-char (point-min))
959 (let ((search 987 (let ((search
960 (lambda (re sub) 988 (lambda (re sub)
961 (let (done) 989 (let ((orig (point)) found)
962 (while (and (not done) (re-search-forward re nil t)) 990 (goto-char (point-min))
991 (while (and (not found) (re-search-forward re nil t))
963 (when (and (equal (match-string sub) fn) 992 (when (and (equal (match-string sub) fn)
964 (not (nth 8 (syntax-ppss)))) 993 (not (nth 8 (syntax-ppss))))
965 (setq done t))) 994 (setq found t)))
966 (or done (goto-char (point-min))))))) 995 (unless found (goto-char orig))
967 (pcase (file-name-extension (buffer-file-name)) 996 found))))
997 (pcase (and buffer-file-name (file-name-extension buffer-file-name))
968 (`"cc" (funcall search 998 (`"cc" (funcall search
969 "\\_<DEFUN\\(?:_DLD\\)?\\s-*(\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)" 1)) 999 "\\_<DEFUN\\(?:_DLD\\)?\\s-*(\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)" 1))
970 (t (funcall search octave-function-header-regexp 3))))) 1000 (t (funcall search octave-function-header-regexp 3)))))
@@ -1325,8 +1355,6 @@ The block marked is the one that contains point or follows point."
1325 (forward-line 1)))) 1355 (forward-line 1))))
1326 t))) 1356 t)))
1327 1357
1328;;; Completions
1329
1330(defun octave-completion-at-point () 1358(defun octave-completion-at-point ()
1331 "Find the text to complete and the corresponding table." 1359 "Find the text to complete and the corresponding table."
1332 (let* ((beg (save-excursion (skip-syntax-backward "w_") (point))) 1360 (let* ((beg (save-excursion (skip-syntax-backward "w_") (point)))
@@ -1343,6 +1371,16 @@ The block marked is the one that contains point or follows point."
1343 1371
1344(define-obsolete-function-alias 'octave-complete-symbol 1372(define-obsolete-function-alias 'octave-complete-symbol
1345 'completion-at-point "24.1") 1373 'completion-at-point "24.1")
1374
1375(defun octave-add-log-current-defun ()
1376 "A function for `add-log-current-defun-function' (which see)."
1377 (save-excursion
1378 (end-of-line)
1379 (and (beginning-of-defun)
1380 (re-search-forward octave-function-header-regexp
1381 (line-end-position) t)
1382 (match-string 3))))
1383
1346 1384
1347;;; Electric characters && friends 1385;;; Electric characters && friends
1348(define-skeleton octave-insert-defun 1386(define-skeleton octave-insert-defun
@@ -1367,7 +1405,7 @@ entered without parens)."
1367 "function " > str \n 1405 "function " > str \n
1368 _ \n 1406 _ \n
1369 "endfunction" > \n) 1407 "endfunction" > \n)
1370 1408
1371;;; Communication with the inferior Octave process 1409;;; Communication with the inferior Octave process
1372(defun octave-kill-process () 1410(defun octave-kill-process ()
1373 "Kill inferior Octave process and its buffer." 1411 "Kill inferior Octave process and its buffer."
@@ -1486,9 +1524,7 @@ code line."
1486(defun octave-eldoc-function-signatures (fn) 1524(defun octave-eldoc-function-signatures (fn)
1487 (unless (equal fn (car octave-eldoc-cache)) 1525 (unless (equal fn (car octave-eldoc-cache))
1488 (inferior-octave-send-list-and-digest 1526 (inferior-octave-send-list-and-digest
1489 (list (format "\ 1527 (list (format "print_usage ('%s');\n" fn)))
1490if ismember(exist(\"%s\"), [2 3 5 103]) print_usage(\"%s\") endif\n"
1491 fn fn)))
1492 (let (result) 1528 (let (result)
1493 (dolist (line inferior-octave-output-list) 1529 (dolist (line inferior-octave-output-list)
1494 (when (string-match 1530 (when (string-match
@@ -1585,20 +1621,11 @@ if ismember(exist(\"%s\"), [2 3 5 103]) print_usage(\"%s\") endif\n"
1585 (when (or help-xref-stack help-xref-forward-stack) 1621 (when (or help-xref-stack help-xref-forward-stack)
1586 (insert "\n")))) 1622 (insert "\n"))))
1587 1623
1588(defvar octave-help-mode-finish-hook nil
1589 "Octave specific hook for `temp-buffer-show-hook'.")
1590
1591(defun octave-help-mode-finish ()
1592 (when (eq major-mode 'octave-help-mode)
1593 (run-hooks 'octave-help-mode-finish-hook)))
1594
1595(add-hook 'temp-buffer-show-hook 'octave-help-mode-finish)
1596
1597(defun octave-help (fn) 1624(defun octave-help (fn)
1598 "Display the documentation of FN." 1625 "Display the documentation of FN."
1599 (interactive (list (octave-completing-read))) 1626 (interactive (list (octave-completing-read)))
1600 (inferior-octave-send-list-and-digest 1627 (inferior-octave-send-list-and-digest
1601 (list (format "help \"%s\"\n" fn))) 1628 (list (format "help ('%s');\n" fn)))
1602 (let ((lines inferior-octave-output-list) 1629 (let ((lines inferior-octave-output-list)
1603 (inhibit-read-only t)) 1630 (inhibit-read-only t))
1604 (when (string-match "error: \\(.*\\)$" (car lines)) 1631 (when (string-match "error: \\(.*\\)$" (car lines))
@@ -1634,16 +1661,15 @@ if ismember(exist(\"%s\"), [2 3 5 103]) print_usage(\"%s\") endif\n"
1634 (help-insert-xref-button (file-relative-name file dir) 1661 (help-insert-xref-button (file-relative-name file dir)
1635 'octave-help-file fn) 1662 'octave-help-file fn)
1636 (insert "'"))) 1663 (insert "'")))
1637 ;; Make 'See also' clickable 1664 ;; Make 'See also' clickable.
1638 (with-syntax-table octave-mode-syntax-table 1665 (with-syntax-table octave-mode-syntax-table
1639 (when (re-search-forward "^\\s-*See also:" nil t) 1666 (when (re-search-forward "^\\s-*See also:" nil t)
1640 (let ((end (save-excursion (re-search-forward "^\\s-*$" nil t)))) 1667 (let ((end (save-excursion (re-search-forward "^\\s-*$" nil t))))
1641 (while (re-search-forward "\\_<\\(?:\\sw\\|\\s_\\)+\\_>" end t) 1668 (while (re-search-forward
1642 (make-text-button (match-beginning 0) 1669 ;; Match operators and symbols.
1643 ;; If the match ends with . exclude it. 1670 "\\(?1:\\s.+?\\)\\(?:$\\|[,;]\\|\\s-\\)\\|\\_<\\(?1:\\(?:\\sw\\|\\s_\\)+\\)\\_>"
1644 (if (eq (char-before (match-end 0)) ?.) 1671 end t)
1645 (1- (match-end 0)) 1672 (make-text-button (match-beginning 1) (match-end 1)
1646 (match-end 0))
1647 :type 'octave-help-function))))) 1673 :type 'octave-help-function)))))
1648 (octave-help-mode))))) 1674 (octave-help-mode)))))
1649 1675
@@ -1694,23 +1720,30 @@ If the environment variable OCTAVE_SRCDIR is set, it is searched first."
1694Functions implemented in C++ can be found if 1720Functions implemented in C++ can be found if
1695`octave-source-directories' is set correctly." 1721`octave-source-directories' is set correctly."
1696 (interactive (list (octave-completing-read))) 1722 (interactive (list (octave-completing-read)))
1697 (inferior-octave-send-list-and-digest 1723 (require 'etags)
1698 ;; help NAME is more verbose 1724 (let ((orig (point)))
1699 (list (format "\ 1725 (if (and (derived-mode-p 'octave-mode)
1700if iskeyword(\"%s\") disp(\"`%s' is a keyword\") else which(\"%s\") endif\n" 1726 (octave-goto-function-definition fn))
1701 fn fn fn))) 1727 (ring-insert find-tag-marker-ring (copy-marker orig))
1702 (let* ((line (car inferior-octave-output-list)) 1728 (inferior-octave-send-list-and-digest
1703 (file (when (and line (string-match "from the file \\(.*\\)$" line)) 1729 ;; help NAME is more verbose
1704 (match-string 1 line)))) 1730 (list (format "\
1705 (if (not file) 1731if iskeyword('%s') disp('`%s'' is a keyword') else which('%s') endif\n"
1706 (user-error "%s" (or line (format "`%s' not found" fn))) 1732 fn fn fn)))
1707 (require 'etags) 1733 (let (line file)
1708 (ring-insert find-tag-marker-ring (point-marker)) 1734 ;; Skip garbage lines such as
1709 (setq file (funcall octave-find-definition-filename-function file)) 1735 ;; warning: fmincg.m: possible Matlab-style ....
1710 (when file 1736 (while (and (not file) (consp inferior-octave-output-list))
1711 (find-file file) 1737 (setq line (pop inferior-octave-output-list))
1712 (octave-goto-function-definition fn))))) 1738 (when (string-match "from the file \\(.*\\)$" line)
1713 1739 (setq file (match-string 1 line))))
1740 (if (not file)
1741 (user-error "%s" (or line (format "`%s' not found" fn)))
1742 (ring-insert find-tag-marker-ring (point-marker))
1743 (setq file (funcall octave-find-definition-filename-function file))
1744 (when file
1745 (find-file file)
1746 (octave-goto-function-definition fn)))))))
1714 1747
1715(provide 'octave) 1748(provide 'octave)
1716;;; octave.el ends here 1749;;; octave.el ends here
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index 01ac8584e19..1d5052bede4 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -158,44 +158,10 @@
158;; Regexps updated with help from Tom Tromey <tromey@cambric.colorado.edu> and 158;; Regexps updated with help from Tom Tromey <tromey@cambric.colorado.edu> and
159;; Jim Campbell <jec@murzim.ca.boeing.com>. 159;; Jim Campbell <jec@murzim.ca.boeing.com>.
160 160
161(defcustom perl-prettify-symbols t
162 "If non-nil, some symbols will be displayed using Unicode chars."
163 :version "24.4"
164 :type 'boolean)
165
166(defconst perl--prettify-symbols-alist 161(defconst perl--prettify-symbols-alist
167 '(;;("andalso" . ?∧) ("orelse" . ?∨) ("as" . ?≡)("not" . ?¬) 162 '(("->" . ?→)
168 ;;("div" . ?÷) ("*" . ?×) ("o" . ?○)
169 ("->" . ?→)
170 ("=>" . ?⇒) 163 ("=>" . ?⇒)
171 ;;("<-" . ?←) ("<>" . ?≠) (">=" . ?≥) ("<=" . ?≤) ("..." . ?⋯) 164 ("::" . ?∷)))
172 ("::" . ?∷)
173 ))
174
175(defun perl--font-lock-compose-symbol ()
176 "Compose a sequence of ascii chars into a symbol.
177Regexp match data 0 points to the chars."
178 ;; Check that the chars should really be composed into a symbol.
179 (let* ((start (match-beginning 0))
180 (end (match-end 0))
181 (syntaxes (if (eq (char-syntax (char-after start)) ?w)
182 '(?w) '(?. ?\\))))
183 (if (or (memq (char-syntax (or (char-before start) ?\ )) syntaxes)
184 (memq (char-syntax (or (char-after end) ?\ )) syntaxes)
185 (nth 8 (syntax-ppss)))
186 ;; No composition for you. Let's actually remove any composition
187 ;; we may have added earlier and which is now incorrect.
188 (remove-text-properties start end '(composition))
189 ;; That's a symbol alright, so add the composition.
190 (compose-region start end (cdr (assoc (match-string 0)
191 perl--prettify-symbols-alist)))))
192 ;; Return nil because we're not adding any face property.
193 nil)
194
195(defun perl--font-lock-symbols-keywords ()
196 (when perl-prettify-symbols
197 `((,(regexp-opt (mapcar 'car perl--prettify-symbols-alist) t)
198 (0 (perl--font-lock-compose-symbol))))))
199 165
200(defconst perl-font-lock-keywords-1 166(defconst perl-font-lock-keywords-1
201 '(;; What is this for? 167 '(;; What is this for?
@@ -243,8 +209,7 @@ Regexp match data 0 points to the chars."
243 ;; Fontify keywords with/and labels as we do in `c++-font-lock-keywords'. 209 ;; Fontify keywords with/and labels as we do in `c++-font-lock-keywords'.
244 ("\\<\\(continue\\|goto\\|last\\|next\\|redo\\)\\>[ \t]*\\(\\sw+\\)?" 210 ("\\<\\(continue\\|goto\\|last\\|next\\|redo\\)\\>[ \t]*\\(\\sw+\\)?"
245 (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) 211 (1 font-lock-keyword-face) (2 font-lock-constant-face nil t))
246 ("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-constant-face) 212 ("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-constant-face)))
247 ,@(perl--font-lock-symbols-keywords)))
248 "Gaudy level highlighting for Perl mode.") 213 "Gaudy level highlighting for Perl mode.")
249 214
250(defvar perl-font-lock-keywords perl-font-lock-keywords-1 215(defvar perl-font-lock-keywords perl-font-lock-keywords-1
@@ -685,13 +650,15 @@ Turning on Perl mode runs the normal hook `perl-mode-hook'."
685 (setq-local comment-start-skip "\\(^\\|\\s-\\);?#+ *") 650 (setq-local comment-start-skip "\\(^\\|\\s-\\);?#+ *")
686 (setq-local comment-indent-function #'perl-comment-indent) 651 (setq-local comment-indent-function #'perl-comment-indent)
687 (setq-local parse-sexp-ignore-comments t) 652 (setq-local parse-sexp-ignore-comments t)
653
688 ;; Tell font-lock.el how to handle Perl. 654 ;; Tell font-lock.el how to handle Perl.
689 (setq font-lock-defaults '((perl-font-lock-keywords 655 (setq font-lock-defaults '((perl-font-lock-keywords
690 perl-font-lock-keywords-1 656 perl-font-lock-keywords-1
691 perl-font-lock-keywords-2) 657 perl-font-lock-keywords-2)
692 nil nil ((?\_ . "w")) nil 658 nil nil ((?\_ . "w")) nil
693 (font-lock-syntactic-face-function 659 (font-lock-syntactic-face-function
694 . perl-font-lock-syntactic-face-function))) 660 . perl-font-lock-syntactic-face-function)))
661 (prog-prettify-install perl--prettify-symbols-alist)
695 (setq-local syntax-propertize-function #'perl-syntax-propertize-function) 662 (setq-local syntax-propertize-function #'perl-syntax-propertize-function)
696 (add-hook 'syntax-propertize-extend-region-functions 663 (add-hook 'syntax-propertize-extend-region-functions
697 #'syntax-propertize-multiline 'append 'local) 664 #'syntax-propertize-multiline 'append 'local)
diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el
new file mode 100644
index 00000000000..e2700414636
--- /dev/null
+++ b/lisp/progmodes/prog-mode.el
@@ -0,0 +1,119 @@
1;;; prog-mode.el --- Generic major mode for programming -*- lexical-binding: t -*-
2
3;; Copyright (C) 2013 Free Software Foundation, Inc.
4
5;; Maintainer: FSF
6;; Keywords: internal
7;; Package: emacs
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software: you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
23
24;;; Commentary:
25
26;; This major mode is mostly intended as a parent of other programming
27;; modes. All major modes for programming languages should derive from this
28;; mode so that users can put generic customization on prog-mode-hook.
29
30;;; Code:
31
32(eval-when-compile (require 'cl-lib))
33
34(defgroup prog-mode nil
35 "Generic programming mode, from which others derive."
36 :group 'languages)
37
38(defvar prog-mode-map
39 (let ((map (make-sparse-keymap)))
40 (define-key map [?\C-\M-q] 'prog-indent-sexp)
41 map)
42 "Keymap used for programming modes.")
43
44(defun prog-indent-sexp (&optional defun)
45 "Indent the expression after point.
46When interactively called with prefix, indent the enclosing defun
47instead."
48 (interactive "P")
49 (save-excursion
50 (when defun
51 (end-of-line)
52 (beginning-of-defun))
53 (let ((start (point))
54 (end (progn (forward-sexp 1) (point))))
55 (indent-region start end nil))))
56
57(defvar prog-prettify-symbols-alist nil)
58
59(defcustom prog-prettify-symbols nil
60 "Whether symbols should be prettified.
61When set to an alist in the form `((STRING . CHARACTER)...)' it
62will augment the mode's native prettify alist."
63 :type '(choice
64 (const :tag "No thanks" nil)
65 (const :tag "Mode defaults" t)
66 (alist :tag "Mode defaults augmented with your own list"
67 :key-type string :value-type character))
68 :version "24.4")
69
70(defun prog--prettify-font-lock-compose-symbol (alist)
71 "Compose a sequence of ascii chars into a symbol.
72Regexp match data 0 points to the chars."
73 ;; Check that the chars should really be composed into a symbol.
74 (let* ((start (match-beginning 0))
75 (end (match-end 0))
76 (syntaxes (if (eq (char-syntax (char-after start)) ?w)
77 '(?w) '(?. ?\\))))
78 (if (or (memq (char-syntax (or (char-before start) ?\ )) syntaxes)
79 (memq (char-syntax (or (char-after end) ?\ )) syntaxes)
80 (nth 8 (syntax-ppss)))
81 ;; No composition for you. Let's actually remove any composition
82 ;; we may have added earlier and which is now incorrect.
83 (remove-text-properties start end '(composition))
84 ;; That's a symbol alright, so add the composition.
85 (compose-region start end (cdr (assoc (match-string 0) alist)))))
86 ;; Return nil because we're not adding any face property.
87 nil)
88
89(defun prog-prettify-font-lock-symbols-keywords ()
90 (when prog-prettify-symbols
91 (let ((alist (append prog-prettify-symbols-alist
92 (if (listp prog-prettify-symbols)
93 prog-prettify-symbols
94 nil))))
95 `((,(regexp-opt (mapcar 'car alist) t)
96 (0 (prog--prettify-font-lock-compose-symbol ',alist)))))))
97
98(defun prog-prettify-install (alist)
99"Install prog-mode support to prettify symbols according to ALIST.
100
101ALIST is in the format `((STRING . CHARACTER)...)' like
102`prog-prettify-symbols'.
103
104Internally, `font-lock-add-keywords' is called."
105 (setq-local prog-prettify-symbols-alist alist)
106 (let ((keywords (prog-prettify-font-lock-symbols-keywords)))
107 (if keywords (font-lock-add-keywords nil keywords))))
108
109;;;###autoload
110(define-derived-mode prog-mode fundamental-mode "Prog"
111 "Major mode for editing programming language source code."
112 (set (make-local-variable 'require-final-newline) mode-require-final-newline)
113 (set (make-local-variable 'parse-sexp-ignore-comments) t)
114 ;; Any programming language is always written left to right.
115 (setq bidi-paragraph-direction 'left-to-right))
116
117(provide 'prog-mode)
118
119;;; prog-mode.el ends here
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index 63bd9258d69..0f3c1504ee9 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -1149,11 +1149,7 @@ VERSION is of the format (Major . Minor)"
1149 (set (make-local-variable 'comment-start) "%") 1149 (set (make-local-variable 'comment-start) "%")
1150 (set (make-local-variable 'comment-end) "") 1150 (set (make-local-variable 'comment-end) "")
1151 (set (make-local-variable 'comment-add) 1) 1151 (set (make-local-variable 'comment-add) 1)
1152 (set (make-local-variable 'comment-start-skip) 1152 (set (make-local-variable 'comment-start-skip) "\\(?:/\\*+ *\\|%%+ *\\)")
1153 ;; This complex regexp makes sure that comments cannot start
1154 ;; inside quoted atoms or strings
1155 (format "^\\(\\(%s\\|%s\\|[^\n\'\"%%]\\)*\\)\\(/\\*+ *\\|%%+ *\\)"
1156 prolog-quoted-atom-regexp prolog-string-regexp))
1157 (set (make-local-variable 'parens-require-spaces) nil) 1153 (set (make-local-variable 'parens-require-spaces) nil)
1158 ;; Initialize Prolog system specific variables 1154 ;; Initialize Prolog system specific variables
1159 (dolist (var '(prolog-keywords prolog-types prolog-mode-specificators 1155 (dolist (var '(prolog-keywords prolog-types prolog-mode-specificators
@@ -1739,8 +1735,7 @@ This function must be called from the source code buffer."
1739 (real-file buffer-file-name) 1735 (real-file buffer-file-name)
1740 (command-string (prolog-build-prolog-command compilep file 1736 (command-string (prolog-build-prolog-command compilep file
1741 real-file first-line)) 1737 real-file first-line))
1742 (process (get-process "prolog")) 1738 (process (get-process "prolog")))
1743 (old-filter (process-filter process)))
1744 (with-current-buffer buffer 1739 (with-current-buffer buffer
1745 (delete-region (point-min) (point-max)) 1740 (delete-region (point-min) (point-max))
1746 ;; FIXME: Wasn't this supposed to use prolog-inferior-mode? 1741 ;; FIXME: Wasn't this supposed to use prolog-inferior-mode?
@@ -1759,8 +1754,7 @@ This function must be called from the source code buffer."
1759 'prolog-parse-sicstus-compilation-errors)) 1754 'prolog-parse-sicstus-compilation-errors))
1760 (setq buffer-read-only nil) 1755 (setq buffer-read-only nil)
1761 (insert command-string "\n")) 1756 (insert command-string "\n"))
1762 (save-selected-window 1757 (display-buffer buffer)
1763 (pop-to-buffer buffer))
1764 (setq prolog-process-flag t 1758 (setq prolog-process-flag t
1765 prolog-consult-compile-output "" 1759 prolog-consult-compile-output ""
1766 prolog-consult-compile-first-line (if first-line (1- first-line) 0) 1760 prolog-consult-compile-first-line (if first-line (1- first-line) 0)
@@ -1954,20 +1948,6 @@ If COMPILEP is non-nil, compile, otherwise consult."
1954;;------------------------------------------------------------------- 1948;;-------------------------------------------------------------------
1955 1949
1956;; Auxiliary functions 1950;; Auxiliary functions
1957(defun prolog-make-keywords-regexp (keywords &optional protect)
1958 "Create regexp from the list of strings KEYWORDS.
1959If PROTECT is non-nil, surround the result regexp by word breaks."
1960 (let ((regexp
1961 (if (fboundp 'regexp-opt)
1962 ;; Emacs 20
1963 ;; Avoid compile warnings under earlier versions by using eval
1964 (eval '(regexp-opt keywords))
1965 ;; Older Emacsen
1966 (concat (mapconcat 'regexp-quote keywords "\\|")))
1967 ))
1968 (if protect
1969 (concat "\\<\\(" regexp "\\)\\>")
1970 regexp)))
1971 1951
1972(defun prolog-font-lock-object-matcher (bound) 1952(defun prolog-font-lock-object-matcher (bound)
1973 "Find SICStus objects method name for font lock. 1953 "Find SICStus objects method name for font lock.
@@ -2084,20 +2064,16 @@ Argument BOUND is a buffer position limiting searching."
2084 (if (eq prolog-system 'mercury) 2064 (if (eq prolog-system 'mercury)
2085 (concat 2065 (concat
2086 "\\<\\(" 2066 "\\<\\("
2087 (prolog-make-keywords-regexp prolog-keywords-i) 2067 (regexp-opt prolog-keywords-i)
2088 "\\|" 2068 "\\|"
2089 (prolog-make-keywords-regexp 2069 (regexp-opt
2090 prolog-determinism-specificators-i) 2070 prolog-determinism-specificators-i)
2091 "\\)\\>") 2071 "\\)\\>")
2092 (concat 2072 (concat
2093 "^[?:]- *\\(" 2073 "^[?:]- *\\("
2094 (prolog-make-keywords-regexp prolog-keywords-i) 2074 (regexp-opt prolog-keywords-i)
2095 "\\)\\>")) 2075 "\\)\\>"))
2096 1 prolog-builtin-face)) 2076 1 prolog-builtin-face))
2097 (quoted_atom (list prolog-quoted-atom-regexp
2098 2 'font-lock-string-face 'append))
2099 (string (list prolog-string-regexp
2100 1 'font-lock-string-face 'append))
2101 ;; SICStus specific patterns 2077 ;; SICStus specific patterns
2102 (sicstus-object-methods 2078 (sicstus-object-methods
2103 (if (eq prolog-system 'sicstus) 2079 (if (eq prolog-system 'sicstus)
@@ -2107,17 +2083,17 @@ Argument BOUND is a buffer position limiting searching."
2107 (types 2083 (types
2108 (if (eq prolog-system 'mercury) 2084 (if (eq prolog-system 'mercury)
2109 (list 2085 (list
2110 (prolog-make-keywords-regexp prolog-types-i t) 2086 (regexp-opt prolog-types-i 'words)
2111 0 'font-lock-type-face))) 2087 0 'font-lock-type-face)))
2112 (modes 2088 (modes
2113 (if (eq prolog-system 'mercury) 2089 (if (eq prolog-system 'mercury)
2114 (list 2090 (list
2115 (prolog-make-keywords-regexp prolog-mode-specificators-i t) 2091 (regexp-opt prolog-mode-specificators-i 'words)
2116 0 'font-lock-constant-face))) 2092 0 'font-lock-constant-face)))
2117 (directives 2093 (directives
2118 (if (eq prolog-system 'mercury) 2094 (if (eq prolog-system 'mercury)
2119 (list 2095 (list
2120 (prolog-make-keywords-regexp prolog-directives-i t) 2096 (regexp-opt prolog-directives-i 'words)
2121 0 'prolog-warning-face))) 2097 0 'prolog-warning-face)))
2122 ;; Inferior mode specific patterns 2098 ;; Inferior mode specific patterns
2123 (prompt 2099 (prompt
@@ -2211,8 +2187,6 @@ Argument BOUND is a buffer position limiting searching."
2211 (list 2187 (list
2212 head-predicates 2188 head-predicates
2213 head-predicates-1 2189 head-predicates-1
2214 quoted_atom
2215 string
2216 variables 2190 variables
2217 important-elements 2191 important-elements
2218 important-elements-1 2192 important-elements-1
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 641563ae0ab..ccb2dcba42e 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -157,7 +157,7 @@
157 157
158;; Skeletons: 6 skeletons are provided for simple inserting of class, 158;; Skeletons: 6 skeletons are provided for simple inserting of class,
159;; def, for, if, try and while. These skeletons are integrated with 159;; def, for, if, try and while. These skeletons are integrated with
160;; dabbrev. If you have `dabbrev-mode' activated and 160;; abbrev. If you have `abbrev-mode' activated and
161;; `python-skeleton-autoinsert' is set to t, then whenever you type 161;; `python-skeleton-autoinsert' is set to t, then whenever you type
162;; the name of any of those defined and hit SPC, they will be 162;; the name of any of those defined and hit SPC, they will be
163;; automatically expanded. As an alternative you can use the defined 163;; automatically expanded. As an alternative you can use the defined
@@ -642,7 +642,8 @@ It makes underscores and dots word constituent chars.")
642These make `python-indent-calculate-indentation' subtract the value of 642These make `python-indent-calculate-indentation' subtract the value of
643`python-indent-offset'.") 643`python-indent-offset'.")
644 644
645(defvar python-indent-block-enders '("return" "pass") 645(defvar python-indent-block-enders
646 '("break" "continue" "pass" "raise" "return")
646 "List of words that mark the end of a block. 647 "List of words that mark the end of a block.
647These make `python-indent-calculate-indentation' subtract the 648These make `python-indent-calculate-indentation' subtract the
648value of `python-indent-offset' when `python-indent-context' is 649value of `python-indent-offset' when `python-indent-context' is
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index a96ee64a229..fa4efe49b7b 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -1349,6 +1349,7 @@ If the result is do-end block, it will always be multiline."
1349(declare-function ruby-syntax-propertize-percent-literal "ruby-mode" (limit)) 1349(declare-function ruby-syntax-propertize-percent-literal "ruby-mode" (limit))
1350;; Unusual code layout confuses the byte-compiler. 1350;; Unusual code layout confuses the byte-compiler.
1351(declare-function ruby-syntax-propertize-expansion "ruby-mode" ()) 1351(declare-function ruby-syntax-propertize-expansion "ruby-mode" ())
1352(declare-function ruby-syntax-expansion-allowed-p "ruby-mode" (parse-state))
1352 1353
1353(if (eval-when-compile (fboundp #'syntax-propertize-rules)) 1354(if (eval-when-compile (fboundp #'syntax-propertize-rules))
1354 ;; New code that works independently from font-lock. 1355 ;; New code that works independently from font-lock.
@@ -1380,51 +1381,52 @@ It will be properly highlighted even when the call omits parens.")
1380 1381
1381 (defun ruby-syntax-propertize-function (start end) 1382 (defun ruby-syntax-propertize-function (start end)
1382 "Syntactic keywords for Ruby mode. See `syntax-propertize-function'." 1383 "Syntactic keywords for Ruby mode. See `syntax-propertize-function'."
1383 (goto-char start) 1384 (let (case-fold-search)
1384 (remove-text-properties start end '(ruby-expansion-match-data)) 1385 (goto-char start)
1385 (ruby-syntax-propertize-heredoc end) 1386 (remove-text-properties start end '(ruby-expansion-match-data))
1386 (ruby-syntax-enclosing-percent-literal end) 1387 (ruby-syntax-propertize-heredoc end)
1387 (funcall 1388 (ruby-syntax-enclosing-percent-literal end)
1388 (syntax-propertize-rules 1389 (funcall
1389 ;; $' $" $` .... are variables. 1390 (syntax-propertize-rules
1390 ;; ?' ?" ?` are ascii codes. 1391 ;; $' $" $` .... are variables.
1391 ("\\([?$]\\)[#\"'`]" 1392 ;; ?' ?" ?` are ascii codes.
1392 (1 (unless (save-excursion 1393 ("\\([?$]\\)[#\"'`]"
1393 ;; Not within a string. 1394 (1 (unless (save-excursion
1394 (nth 3 (syntax-ppss (match-beginning 0)))) 1395 ;; Not within a string.
1395 (string-to-syntax "\\")))) 1396 (nth 3 (syntax-ppss (match-beginning 0))))
1396 ;; Regular expressions. Start with matching unescaped slash. 1397 (string-to-syntax "\\"))))
1397 ("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)" 1398 ;; Regular expressions. Start with matching unescaped slash.
1398 (1 (let ((state (save-excursion (syntax-ppss (match-beginning 1))))) 1399 ("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)"
1399 (when (or 1400 (1 (let ((state (save-excursion (syntax-ppss (match-beginning 1)))))
1400 ;; Beginning of a regexp. 1401 (when (or
1401 (and (null (nth 8 state)) 1402 ;; Beginning of a regexp.
1402 (save-excursion 1403 (and (null (nth 8 state))
1403 (forward-char -1) 1404 (save-excursion
1404 (looking-back ruby-syntax-before-regexp-re 1405 (forward-char -1)
1405 (point-at-bol)))) 1406 (looking-back ruby-syntax-before-regexp-re
1406 ;; End of regexp. We don't match the whole 1407 (point-at-bol))))
1407 ;; regexp at once because it can have 1408 ;; End of regexp. We don't match the whole
1408 ;; string interpolation inside, or span 1409 ;; regexp at once because it can have
1409 ;; several lines. 1410 ;; string interpolation inside, or span
1410 (eq ?/ (nth 3 state))) 1411 ;; several lines.
1411 (string-to-syntax "\"/"))))) 1412 (eq ?/ (nth 3 state)))
1412 ;; Expression expansions in strings. We're handling them 1413 (string-to-syntax "\"/")))))
1413 ;; here, so that the regexp rule never matches inside them. 1414 ;; Expression expansions in strings. We're handling them
1414 (ruby-expression-expansion-re 1415 ;; here, so that the regexp rule never matches inside them.
1415 (0 (ignore (ruby-syntax-propertize-expansion)))) 1416 (ruby-expression-expansion-re
1416 ("^=en\\(d\\)\\_>" (1 "!")) 1417 (0 (ignore (ruby-syntax-propertize-expansion))))
1417 ("^\\(=\\)begin\\_>" (1 "!")) 1418 ("^=en\\(d\\)\\_>" (1 "!"))
1418 ;; Handle here documents. 1419 ("^\\(=\\)begin\\_>" (1 "!"))
1419 ((concat ruby-here-doc-beg-re ".*\\(\n\\)") 1420 ;; Handle here documents.
1420 (7 (unless (ruby-singleton-class-p (match-beginning 0)) 1421 ((concat ruby-here-doc-beg-re ".*\\(\n\\)")
1421 (put-text-property (match-beginning 7) (match-end 7) 1422 (7 (unless (ruby-singleton-class-p (match-beginning 0))
1422 'syntax-table (string-to-syntax "\"")) 1423 (put-text-property (match-beginning 7) (match-end 7)
1423 (ruby-syntax-propertize-heredoc end)))) 1424 'syntax-table (string-to-syntax "\""))
1424 ;; Handle percent literals: %w(), %q{}, etc. 1425 (ruby-syntax-propertize-heredoc end))))
1425 ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re) 1426 ;; Handle percent literals: %w(), %q{}, etc.
1426 (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end))))) 1427 ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
1427 (point) end)) 1428 (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
1429 (point) end)))
1428 1430
1429 (defun ruby-syntax-propertize-heredoc (limit) 1431 (defun ruby-syntax-propertize-heredoc (limit)
1430 (let ((ppss (syntax-ppss)) 1432 (let ((ppss (syntax-ppss))
@@ -1496,9 +1498,10 @@ It will be properly highlighted even when the call omits parens.")
1496 (defun ruby-syntax-propertize-expansion () 1498 (defun ruby-syntax-propertize-expansion ()
1497 ;; Save the match data to a text property, for font-locking later. 1499 ;; Save the match data to a text property, for font-locking later.
1498 ;; Set the syntax of all double quotes and backticks to punctuation. 1500 ;; Set the syntax of all double quotes and backticks to punctuation.
1499 (let ((beg (match-beginning 2)) 1501 (let* ((beg (match-beginning 2))
1500 (end (match-end 2))) 1502 (end (match-end 2))
1501 (when (and beg (save-excursion (nth 3 (syntax-ppss beg)))) 1503 (state (and beg (save-excursion (syntax-ppss beg)))))
1504 (when (ruby-syntax-expansion-allowed-p state)
1502 (put-text-property beg (1+ beg) 'ruby-expansion-match-data 1505 (put-text-property beg (1+ beg) 'ruby-expansion-match-data
1503 (match-data)) 1506 (match-data))
1504 (goto-char beg) 1507 (goto-char beg)
@@ -1506,6 +1509,17 @@ It will be properly highlighted even when the call omits parens.")
1506 (put-text-property (match-beginning 0) (match-end 0) 1509 (put-text-property (match-beginning 0) (match-end 0)
1507 'syntax-table (string-to-syntax ".")))))) 1510 'syntax-table (string-to-syntax "."))))))
1508 1511
1512 (defun ruby-syntax-expansion-allowed-p (parse-state)
1513 "Return non-nil if expression expansion is allowed."
1514 (let ((term (nth 3 parse-state)))
1515 (cond
1516 ((memq term '(?\" ?` ?\n ?/)))
1517 ((eq term t)
1518 (save-match-data
1519 (save-excursion
1520 (goto-char (nth 8 parse-state))
1521 (looking-at "%\\(?:[QWrx]\\|\\W\\)")))))))
1522
1509 (defun ruby-syntax-propertize-expansions (start end) 1523 (defun ruby-syntax-propertize-expansions (start end)
1510 (save-excursion 1524 (save-excursion
1511 (goto-char start) 1525 (goto-char start)
diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el
index 9169a433015..3e91aeba9a1 100644
--- a/lisp/progmodes/tcl.el
+++ b/lisp/progmodes/tcl.el
@@ -266,7 +266,7 @@ quoted for Tcl."
266 ;; Maybe someone has a better set? 266 ;; Maybe someone has a better set?
267 (let ((map (make-sparse-keymap))) 267 (let ((map (make-sparse-keymap)))
268 ;; Will inherit from `comint-mode-map' thanks to define-derived-mode. 268 ;; Will inherit from `comint-mode-map' thanks to define-derived-mode.
269 (define-key map "\t" 'comint-dynamic-complete) 269 (define-key map "\t" 'completion-at-point)
270 (define-key map "\M-?" 'comint-dynamic-list-filename-completions) 270 (define-key map "\M-?" 'comint-dynamic-list-filename-completions)
271 (define-key map "\177" 'backward-delete-char-untabify) 271 (define-key map "\177" 'backward-delete-char-untabify)
272 (define-key map "\M-\C-x" 'tcl-eval-defun) 272 (define-key map "\M-\C-x" 'tcl-eval-defun)