diff options
Diffstat (limited to 'lisp/progmodes')
| -rw-r--r-- | lisp/progmodes/cmacexp.el | 4 | ||||
| -rw-r--r-- | lisp/progmodes/compile.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/f90.el | 4 | ||||
| -rw-r--r-- | lisp/progmodes/gdb-mi.el | 57 | ||||
| -rw-r--r-- | lisp/progmodes/grep.el | 22 | ||||
| -rw-r--r-- | lisp/progmodes/hideshow.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/js.el | 4 | ||||
| -rw-r--r-- | lisp/progmodes/octave.el | 316 | ||||
| -rw-r--r-- | lisp/progmodes/prog-mode.el | 65 | ||||
| -rw-r--r-- | lisp/progmodes/prolog.el | 47 | ||||
| -rw-r--r-- | lisp/progmodes/python.el | 1 | ||||
| -rw-r--r-- | lisp/progmodes/sh-script.el | 79 |
12 files changed, 399 insertions, 204 deletions
diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el index 0f5b1bb8c6a..9953cae2bef 100644 --- a/lisp/progmodes/cmacexp.el +++ b/lisp/progmodes/cmacexp.el @@ -405,7 +405,3 @@ Optional arg DISPLAY non-nil means show messages in the echo area." (kill-buffer outbuf)))) ;;; cmacexp.el ends here - -;; Local Variables: -;; coding: utf-8 -;; End: diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 9cb367aa633..9e2d625a4d4 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -145,7 +145,7 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) " in line \\([0-9]+\\) of file \\([^ \n]+[^. \n]\\)\\.? " 2 1) (ant - "^[ \t]*\\[[^] \n]+\\][ \t]*\\([^: \n]+\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\):\\)?\ + "^[ \t]*\\[[^] \n]+\\][ \t]*\\(\\(?:[A-Za-z]:\\\\\\)?[^: \n]+\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\):\\)?\ \\( warning\\)?" 1 (2 . 4) (3 . 5) (6)) (bash diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el index 0ac59e1a1ea..5c938fd1a93 100644 --- a/lisp/progmodes/f90.el +++ b/lisp/progmodes/f90.el @@ -2382,8 +2382,4 @@ escape character." (provide 'f90) -;; Local Variables: -;; coding: utf-8 -;; End: - ;;; f90.el ends here diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 3860c81065d..4bee7c1dfa2 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -2315,10 +2315,67 @@ the end of the current result or async record is reached." ; list ==> ; "[]" | "[" value ( "," value )* "]" | "[" result ( "," result )* "]" +(defcustom gdb-mi-decode-strings nil + "When non-nil, decode octal escapes in GDB output into non-ASCII text. + +If the value is a coding-system, use that coding-system to decode +the bytes reconstructed from octal escapes. Any other non-nil value +means to decode using the coding-system set for the GDB process. + +Warning: setting this non-nil might mangle strings reported by GDB +that have literal substrings which match the \\nnn octal escape +patterns, where nnn is an octal number between 200 and 377. So +we only recommend to set this variable non-nil if the program you +are debugging really reports non-ASCII text, or some of its source +file names include non-ASCII characters." + :type '(choice + (const :tag "Don't decode" nil) + (const :tag "Decode using default coding-system" t) + (coding-system :tag "Decode using this coding-system")) + :group 'gdb + :version "25.1") + +;; The idea of the following function was suggested +;; by Kenichi Handa <handa@gnu.org>. +;; +;; FIXME: This is fragile: it relies on the assumption that all the +;; non-ASCII strings output by GDB, including names of the source +;; files, values of string variables in the inferior, etc., are all +;; encoded in the same encoding. It also assumes that the \nnn +;; sequences are not split between chunks of output of the GDB process +;; due to buffering, and arrive together. Finally, if some string +;; included literal \nnn strings (as opposed to non-ASCII characters +;; converted by by GDB/MI to octal escapes), this decoding will mangle +;; those strings. When/if GDB acquires the ability to not +;; escape-protect non-ASCII characters in its MI output, this kludge +;; should be removed. +(defun gdb-mi-decode (string) + "Decode octal escapes in MI output STRING into multibyte text." + (let ((coding + (if (coding-system-p gdb-mi-decode-strings) + gdb-mi-decode-strings + (with-current-buffer + (gdb-get-buffer-create 'gdb-partial-output-buffer) + buffer-file-coding-system)))) + (with-temp-buffer + (set-buffer-multibyte nil) + (prin1 string (current-buffer)) + (goto-char (point-min)) + ;; prin1 quotes the octal escapes as well, which interferes with + ;; their interpretation by 'read' below. Remove the extra + ;; backslashes to countermand that. + (while (re-search-forward "\\\\\\(\\\\[2-3][0-7][0-7]\\)" nil t) + (replace-match "\\1" nil nil)) + (goto-char (point-min)) + (decode-coding-string (read (current-buffer)) coding)))) (defun gud-gdbmi-marker-filter (string) "Filter GDB/MI output." + ;; If required, decode non-ASCII text encoded with octal escapes. + (or (null gdb-mi-decode-strings) + (setq string (gdb-mi-decode string))) + ;; Record transactions if logging is enabled. (when gdb-enable-debug (push (cons 'recv string) gdb-debug-log) diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 3240ee8a0db..452a42f4bc2 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -1039,16 +1039,18 @@ to specify a command to run." ;; we should use shell-quote-argument here " -path " (mapconcat - #'(lambda (ignore) - (cond ((stringp ignore) - (shell-quote-argument - (concat "*/" ignore))) - ((consp ignore) - (and (funcall (car ignore) dir) - (shell-quote-argument - (concat "*/" - (cdr ignore))))))) - grep-find-ignored-directories + 'identity + (delq nil (mapcar + #'(lambda (ignore) + (cond ((stringp ignore) + (shell-quote-argument + (concat "*/" ignore))) + ((consp ignore) + (and (funcall (car ignore) dir) + (shell-quote-argument + (concat "*/" + (cdr ignore))))))) + grep-find-ignored-directories)) " -o -path ") " " (shell-quote-argument ")") diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el index 845abc09842..dba497b1f41 100644 --- a/lisp/progmodes/hideshow.el +++ b/lisp/progmodes/hideshow.el @@ -1,4 +1,4 @@ -;;; hideshow.el --- minor mode cmds to selectively display code/comment blocks -*- coding: utf-8 -*- +;;; hideshow.el --- minor mode cmds to selectively display code/comment blocks ;; Copyright (C) 1994-2015 Free Software Foundation, Inc. diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index ab994f38252..f2140159e64 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3571,8 +3571,4 @@ If one hasn't been set, or if it's stale, prompt for a new one." (provide 'js) -;; Local Variables: -;; coding: utf-8 -;; End: - ;; js.el ends here diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index 70a2b1ab5ad..b54b88dccb5 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -82,25 +82,6 @@ Used in `octave-mode' and `inferior-octave-mode' buffers.") (defvar octave-comment-start-skip "\\(^\\|\\S<\\)\\(?:%!\\|\\s<+\\)\\s-*" "Octave-specific `comment-start-skip' (which see).") -(defvar octave-begin-keywords - '("classdef" "do" "enumeration" "events" "for" "function" "if" "methods" - "parfor" "properties" "switch" "try" "unwind_protect" "while")) - -(defvar octave-else-keywords - '("case" "catch" "else" "elseif" "otherwise" "unwind_protect_cleanup")) - -(defvar octave-end-keywords - '("endclassdef" "endenumeration" "endevents" "endfor" "endfunction" "endif" - "endmethods" "endparfor" "endproperties" "endswitch" "end_try_catch" - "end_unwind_protect" "endwhile" "until" "end")) - -(defvar octave-reserved-words - (append octave-begin-keywords - octave-else-keywords - octave-end-keywords - '("break" "continue" "global" "persistent" "return")) - "Reserved words in Octave.") - (defvar octave-function-header-regexp (concat "^\\s-*\\_<\\(function\\)\\_>" "\\([^=;(\n]*=[ \t]*\\|[ \t]*\\)\\(\\(?:\\w\\|\\s_\\)+\\)\\_>") @@ -231,20 +212,17 @@ parenthetical grouping.") (defcustom octave-font-lock-texinfo-comment t "Control whether to highlight the texinfo comment block." :type 'boolean - :group 'octave :version "24.4") (defcustom octave-blink-matching-block t "Control the blinking of matching Octave block keywords. Non-nil means show matching begin of block when inserting a space, newline or semicolon after an else or end keyword." - :type 'boolean - :group 'octave) + :type 'boolean) (defcustom octave-block-offset 2 "Extra indentation applied to statements in Octave block structures." - :type 'integer - :group 'octave) + :type 'integer) (defvar octave-block-comment-start (concat (make-string 2 octave-comment-char) " ") @@ -252,8 +230,7 @@ newline or semicolon after an else or end keyword." (defcustom octave-continuation-offset 4 "Extra indentation applied to Octave continuation lines." - :type 'integer - :group 'octave) + :type 'integer) (eval-and-compile (defconst octave-continuation-marker-regexp "\\\\\\|\\.\\.\\.")) @@ -274,109 +251,135 @@ newline or semicolon after an else or end keyword." (defcustom octave-mode-hook nil "Hook to be run when Octave mode is started." - :type 'hook - :group 'octave) + :type 'hook) (defcustom octave-send-show-buffer t "Non-nil means display `inferior-octave-buffer' after sending to it." - :type 'boolean - :group 'octave) + :type 'boolean) (defcustom octave-send-line-auto-forward t "Control auto-forward after sending to the inferior Octave process. Non-nil means always go to the next Octave code line after sending." - :type 'boolean - :group 'octave) + :type 'boolean) (defcustom octave-send-echo-input t "Non-nil means echo input sent to the inferior Octave process." - :type 'boolean - :group 'octave) + :type 'boolean) ;;; SMIE indentation (require 'smie) -;; Use '__operators__' in Octave REPL to get a full list. -(defconst octave-operator-table - '((assoc ";" "\n") (assoc ",") ; The doc claims they have equal precedence!? - (right "=" "+=" "-=" "*=" "/=") - (assoc "&&") (assoc "||") ; The doc claims they have equal precedence!? - (assoc "&") (assoc "|") ; The doc claims they have equal precedence!? - (nonassoc "<" "<=" "==" ">=" ">" "!=" "~=") - (nonassoc ":") ;No idea what this is. - (assoc "+" "-") - (assoc "*" "/" "\\" ".\\" ".*" "./") - (nonassoc "'" ".'") - (nonassoc "++" "--" "!" "~") ;And unary "+" and "-". - (right "^" "**" ".^" ".**") - ;; It's not really an operator, but for indentation purposes it - ;; could be convenient to treat it as one. - (assoc "..."))) - -(defconst octave-smie-bnf-table - '((atom) - ;; We can't distinguish the first element in a sequence with - ;; precedence grammars, so we can't distinguish the condition - ;; if the `if' from the subsequent body, for example. - ;; This has to be done later in the indentation rules. - (exp (exp "\n" exp) - ;; We need to mention at least one of the operators in this part - ;; of the grammar: if the BNF and the operator table have - ;; no overlap, SMIE can't know how they relate. - (exp ";" exp) - ("try" exp "catch" exp "end_try_catch") - ("try" exp "catch" exp "end") - ("unwind_protect" exp - "unwind_protect_cleanup" exp "end_unwind_protect") - ("unwind_protect" exp "unwind_protect_cleanup" exp "end") - ("for" exp "endfor") - ("for" exp "end") - ("parfor" exp "endparfor") - ("parfor" exp "end") - ("do" exp "until" atom) - ("while" exp "endwhile") - ("while" exp "end") - ("if" exp "endif") - ("if" exp "else" exp "endif") - ("if" exp "elseif" exp "else" exp "endif") - ("if" exp "elseif" exp "elseif" exp "else" exp "endif") - ("if" exp "elseif" exp "elseif" exp "else" exp "end") - ("switch" exp "case" exp "endswitch") - ("switch" exp "case" exp "otherwise" exp "endswitch") - ("switch" exp "case" exp "case" exp "otherwise" exp "endswitch") - ("switch" exp "case" exp "case" exp "otherwise" exp "end") - ("function" exp "endfunction") - ("function" exp "end") - ("enumeration" exp "endenumeration") - ("enumeration" exp "end") - ("events" exp "endevents") - ("events" exp "end") - ("methods" exp "endmethods") - ("methods" exp "end") - ("properties" exp "endproperties") - ("properties" exp "end") - ("classdef" exp "endclassdef") - ("classdef" exp "end")) - ;; (fundesc (atom "=" atom)) - )) +(let-when-compile + ((operator-table + ;; Use '__operators__' in Octave REPL to get a full list? + '((assoc ";" "\n") (assoc ",") ;The doc says they have equal precedence!? + (right "=" "+=" "-=" "*=" "/=") + (assoc "&&") (assoc "||") ; The doc claims they have equal precedence!? + (assoc "&") (assoc "|") ; The doc claims they have equal precedence!? + (nonassoc "<" "<=" "==" ">=" ">" "!=" "~=") + (nonassoc ":") ;No idea what this is. + (assoc "+" "-") + (assoc "*" "/" "\\" ".\\" ".*" "./") + (nonassoc "'" ".'") + (nonassoc "++" "--" "!" "~") ;And unary "+" and "-". + (right "^" "**" ".^" ".**") + ;; It's not really an operator, but for indentation purposes it + ;; could be convenient to treat it as one. + (assoc "..."))) + + (matchedrules + ;; We can't distinguish the first element in a sequence with + ;; precedence grammars, so we can't distinguish the condition + ;; of the `if' from the subsequent body, for example. + ;; This has to be done later in the indentation rules. + '(("try" exp "catch" exp "end_try_catch") + ("unwind_protect" exp + "unwind_protect_cleanup" exp "end_unwind_protect") + ("for" exp "endfor") + ("parfor" exp "endparfor") + ("while" exp "endwhile") + ("if" exp "endif") + ("if" exp "else" exp "endif") + ("if" exp "elseif" exp "else" exp "endif") + ("if" exp "elseif" exp "elseif" exp "else" exp "endif") + ("switch" exp "case" exp "endswitch") + ("switch" exp "case" exp "otherwise" exp "endswitch") + ("switch" exp "case" exp "case" exp "otherwise" exp "endswitch") + ("function" exp "endfunction") + ("enumeration" exp "endenumeration") + ("events" exp "endevents") + ("methods" exp "endmethods") + ("properties" exp "endproperties") + ("classdef" exp "endclassdef") + )) + + (bnf-table + `((atom) + ;; FIXME: We don't parse these declarations correctly since + ;; SMIE *really* likes to parse "a b = 2 c" as "(a b) = (2 c)". + ;; IOW to do it right, we'd need to change octave-smie-*ward-token + ;; so that the spaces between vars in var-decls are lexed as + ;; something like ",". + ;; Doesn't seem worth the trouble/slowdown for now. + ;; We could hack smie-rules so as to work around the bad parse, + ;; but even that doesn't seem worth the trouble. + (var-decls (atom "=" atom)) ;; (var-decls "," var-decls) + (single-exp (atom "=" atom)) + (exp (exp "\n" exp) + ;; We need to mention at least one of the operators in this part + ;; of the grammar: if the BNF and the operator table have + ;; no overlap, SMIE can't know how they relate. + (exp ";" exp) + ("do" exp "until" single-exp) + ,@matchedrules + ;; For every rule that ends in "endfoo", add a corresponding + ;; rule which uses "end" instead. + ,@(mapcar (lambda (rule) (nconc (butlast rule) '("end"))) + matchedrules) + ("global" var-decls) ("persistent" var-decls) + ;; These aren't super-important, but having them here + ;; makes it easier to extract all keywords. + ("break") ("continue") ("return") + ;; The following rules do not correspond to valid code AFAIK, + ;; but they lead to a grammar that degrades more gracefully + ;; on incomplete/incorrect code. It also helps us in + ;; computing octave--block-offset-keywords. + ("try" exp "end") ("unwind_protect" exp "end") + ) + ;; (fundesc (atom "=" atom)) + ))) (defconst octave-smie-grammar - (smie-prec2->grammar - (smie-merge-prec2s - (smie-bnf->prec2 octave-smie-bnf-table - '((assoc "\n" ";"))) + (eval-when-compile + (smie-prec2->grammar + (smie-merge-prec2s + (smie-bnf->prec2 bnf-table '((assoc "\n" ";"))) + (smie-precs->prec2 operator-table))))) - (smie-precs->prec2 octave-operator-table)))) +(defconst octave-operator-regexp + (eval-when-compile + (regexp-opt (remove "\n" (apply #'append + (mapcar #'cdr operator-table))))))) ;; Tokenizing needs to be refined so that ";;" is treated as two ;; tokens and also so as to recognize the \n separator (and ;; corresponding continuation lines). -(defconst octave-operator-regexp - (regexp-opt (remove "\n" (apply 'append - (mapcar 'cdr octave-operator-table))))) +(defun octave-smie--funcall-p () + "Return non-nil if we're in an expression context. Moves point." + (looking-at "[ \t]*(")) + +(defun octave-smie--end-index-p () + (let ((ppss (syntax-ppss))) + (and (nth 1 ppss) + (memq (char-after (nth 1 ppss)) '(?\( ?\[ ?\{))))) + +(defun octave-smie--in-parens-p () + (let ((ppss (syntax-ppss))) + (and (nth 1 ppss) + (eq ?\( (char-after (nth 1 ppss)))))) (defun octave-smie-backward-token () (let ((pos (point))) @@ -390,10 +393,7 @@ Non-nil means always go to the next Octave code line after sending." (forward-comment (- (point))) nil) t) - ;; Ignore it if it's within parentheses. - (let ((ppss (syntax-ppss))) - (not (and (nth 1 ppss) - (eq ?\( (char-after (nth 1 ppss))))))) + (not (octave-smie--in-parens-p))) (skip-chars-forward " \t") ;; Why bother distinguishing \n and ;? ";") ;;"\n" @@ -403,7 +403,15 @@ Non-nil means always go to the next Octave code line after sending." (goto-char (match-beginning 0)) (match-string-no-properties 0)) (t - (smie-default-backward-token))))) + (let ((tok (smie-default-backward-token))) + (cond + ((equal tok "enumeration") + (if (save-excursion (smie-default-forward-token) + (octave-smie--funcall-p)) + "enumeration (function)" + tok)) + ((equal tok "end") (if (octave-smie--end-index-p) "end (index)" tok)) + (t tok))))))) (defun octave-smie-forward-token () (skip-chars-forward " \t") @@ -417,10 +425,7 @@ Non-nil means always go to the next Octave code line after sending." (not (or (save-excursion (skip-chars-backward " \t") ;; Only add implicit ; when needed. (or (bolp) (eq (char-before) ?\;))) - ;; Ignore it if it's within parentheses. - (let ((ppss (syntax-ppss))) - (and (nth 1 ppss) - (eq ?\( (char-after (nth 1 ppss)))))))) + (octave-smie--in-parens-p)))) (if (eolp) (forward-char 1) (forward-comment 1)) ;; Why bother distinguishing \n and ;? ";") ;;"\n" @@ -436,7 +441,25 @@ Non-nil means always go to the next Octave code line after sending." (goto-char (match-end 0)) (match-string-no-properties 0)) (t - (smie-default-forward-token)))) + (let ((tok (smie-default-forward-token))) + (cond + ((equal tok "enumeration") + (if (octave-smie--funcall-p) + "enumeration (function)" + tok)) + ((equal tok "end") (if (octave-smie--end-index-p) "end (index)" tok)) + (t tok)))))) + +(defconst octave--block-offset-keywords + (let* ((end-prec (nth 1 (assoc "end" octave-smie-grammar))) + (end-matchers + (delq nil + (mapcar (lambda (x) (if (eq end-prec (nth 2 x)) (car x))) + octave-smie-grammar)))) + ;; Not sure if it would harm to keep "switch", but the previous code + ;; excluded it, presumably because there shouldn't be any code on + ;; the lines between "switch" and "case". + (delete "switch" end-matchers))) (defun octave-smie-rules (kind token) (pcase (cons kind token) @@ -445,15 +468,12 @@ Non-nil means always go to the next Octave code line after sending." ;; - changes to octave-block-offset wouldn't take effect immediately. ;; - edebug wouldn't show the use of this variable. (`(:elem . basic) octave-block-offset) + (`(:list-intro . ,(or "global" "persistent")) t) ;; Since "case" is in the same BNF rules as switch..end, SMIE by default ;; aligns it with "switch". (`(:before . "case") (if (not (smie-rule-sibling-p)) octave-block-offset)) (`(:after . ";") - (if (smie-rule-parent-p "classdef" "events" "enumeration" "function" "if" - "while" "else" "elseif" "for" "parfor" - "properties" "methods" "otherwise" "case" - "try" "catch" "unwind_protect" - "unwind_protect_cleanup") + (if (apply #'smie-rule-parent-p octave--block-offset-keywords) (smie-rule-parent octave-block-offset) ;; For (invalid) code between switch and case. ;; (if (smie-rule-parent-p "switch") 4) @@ -473,28 +493,33 @@ Non-nil means always go to the next Octave code line after sending." (comment-choose-indent))))) +(defvar octave-reserved-words + (delq nil + (mapcar (lambda (x) + (setq x (car x)) + (and (stringp x) (string-match "\\`[[:alpha:]]" x) x)) + octave-smie-grammar)) + "Reserved words in Octave.") + (defvar octave-font-lock-keywords (list ;; Fontify all builtin keywords. - (cons (concat "\\_<\\(" - (regexp-opt octave-reserved-words) - "\\)\\_>") + (cons (concat "\\_<" (regexp-opt octave-reserved-words) "\\_>") 'font-lock-keyword-face) - ;; Note: 'end' also serves as the last index in an indexing expression. + ;; Note: 'end' also serves as the last index in an indexing expression, + ;; and 'enumerate' is also a function. ;; Ref: http://www.mathworks.com/help/matlab/ref/end.html + ;; Ref: http://www.mathworks.com/help/matlab/ref/enumeration.html (list (lambda (limit) - (while (re-search-forward "\\_<end\\_>" limit 'move) + (while (re-search-forward "\\_<en\\(?:d\\|umeratio\\(n\\)\\)\\_>" + limit 'move) (let ((beg (match-beginning 0)) (end (match-end 0))) (unless (octave-in-string-or-comment-p) - (condition-case nil - (progn - (goto-char beg) - (backward-up-list) - (when (memq (char-after) '(?\( ?\[ ?\{)) - (put-text-property beg end 'face nil)) - (goto-char end)) - (error (goto-char end)))))) + (when (if (match-end 1) + (octave-smie--funcall-p) + (octave-smie--end-index-p)) + (put-text-property beg end 'face nil))))) nil)) ;; Fontify all operators. (cons octave-operator-regexp 'font-lock-builtin-face) @@ -609,27 +634,23 @@ Key bindings: (defcustom inferior-octave-program "octave" "Program invoked by `inferior-octave'." - :type 'string - :group 'octave) + :type 'string) (defcustom inferior-octave-buffer "*Inferior Octave*" "Name of buffer for running an inferior Octave process." - :type 'string - :group 'octave) + :type 'string) (defcustom inferior-octave-prompt ;; For Octave >= 3.8, default is always 'octave', see ;; http://hg.savannah.gnu.org/hgweb/octave/rev/708173343c50 "\\(?:^octave\\(?:.bin\\|.exe\\)?\\(?:-[.0-9]+\\)?\\(?::[0-9]+\\)?\\|^debug\\|^\\)>+ " "Regexp to match prompts for the inferior Octave process." - :type 'regexp - :group 'octave) + :type 'regexp) (defcustom inferior-octave-prompt-read-only comint-prompt-read-only "If non-nil, the Octave prompt is read only. See `comint-prompt-read-only' for details." :type 'boolean - :group 'octave :version "24.4") (defcustom inferior-octave-startup-file @@ -639,7 +660,6 @@ See `comint-prompt-read-only' for details." The contents of this file are sent to the inferior Octave process on startup." :type '(choice (const :tag "None" nil) file) - :group 'octave :version "24.4") (defcustom inferior-octave-startup-args '("-i" "--no-line-editing") @@ -647,13 +667,11 @@ startup." For example, for suppressing the startup message and using `traditional' mode, include \"-q\" and \"--traditional\"." :type '(repeat string) - :group 'octave :version "24.4") (defcustom inferior-octave-mode-hook nil "Hook to be run when Inferior Octave mode is started." - :type 'hook - :group 'octave) + :type 'hook) (defcustom inferior-octave-error-regexp-alist '(("error:\\s-*\\(.*?\\) at line \\([0-9]+\\), column \\([0-9]+\\)" @@ -663,8 +681,7 @@ mode, include \"-q\" and \"--traditional\"." "Value for `compilation-error-regexp-alist' in inferior octave." :version "24.4" :type '(repeat (choice (symbol :tag "Predefined symbol") - (sexp :tag "Error specification"))) - :group 'octave) + (sexp :tag "Error specification")))) (defvar inferior-octave-compilation-font-lock-keywords '(("\\_<PASS\\_>" . compilation-info-face) @@ -995,7 +1012,6 @@ directory and makes this the current buffer's default directory." (defcustom inferior-octave-minimal-columns 80 "The minimal column width for the inferior Octave process." :type 'integer - :group 'octave :version "24.4") (defvar inferior-octave-last-column-width nil) @@ -1180,8 +1196,7 @@ q: Don't fix\n" func file)) (defface octave-function-comment-block '((t (:inherit font-lock-doc-face))) - "Face used to highlight function comment block." - :group 'octave) + "Face used to highlight function comment block.") (eval-when-compile (require 'texinfo)) @@ -1602,7 +1617,6 @@ code line." :type '(choice (const :tag "Automatic" auto) (const :tag "One Line" oneline) (const :tag "Multi Line" multiline)) - :group 'octave :version "24.4") ;; (FN SIGNATURE1 SIGNATURE2 ...) @@ -1661,7 +1675,6 @@ code line." (defcustom octave-help-buffer "*Octave Help*" "Buffer name for `octave-help'." :type 'string - :group 'octave :version "24.4") ;; Used in a mode derived from help-mode. @@ -1786,7 +1799,6 @@ sentence." "A list of directories for Octave sources. If the environment variable OCTAVE_SRCDIR is set, it is searched first." :type '(repeat directory) - :group 'octave :version "24.4") (defun octave-source-directories () diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el index f1aa35f2871..6696356a2dc 100644 --- a/lisp/progmodes/prog-mode.el +++ b/lisp/progmodes/prog-mode.el @@ -29,7 +29,8 @@ ;;; Code: -(eval-when-compile (require 'cl-lib)) +(eval-when-compile (require 'cl-lib) + (require 'subr-x)) (defgroup prog-mode nil "Generic programming mode, from which others derive." @@ -161,13 +162,20 @@ Regexp match data 0 points to the chars." (let ((start (match-beginning 0)) (end (match-end 0)) (match (match-string 0))) - (if (funcall prettify-symbols-compose-predicate start end match) + (if (and (not (equal prettify-symbols--current-symbol-bounds (list start end))) + (funcall prettify-symbols-compose-predicate start end match)) ;; That's a symbol alright, so add the composition. - (compose-region start end (cdr (assoc match alist))) + (with-silent-modifications + (compose-region start end (cdr (assoc match alist))) + (add-text-properties + start end + `(prettify-symbols-start ,start prettify-symbols-end ,end))) ;; No composition for you. Let's actually remove any ;; composition we may have added earlier and which is now ;; incorrect. - (remove-text-properties start end '(composition)))) + (remove-text-properties start end '(composition + prettify-symbols-start + prettify-symbols-end)))) ;; Return nil because we're not adding any face property. nil) @@ -179,6 +187,46 @@ Regexp match data 0 points to the chars." (defvar-local prettify-symbols--keywords nil) +(defvar-local prettify-symbols--current-symbol-bounds nil) + +(defcustom prettify-symbols-unprettify-at-point nil + "If non-nil, show the non-prettified version of a symbol when point is on it. +If set to the symbol `right-edge', also unprettify if point +is immediately after the symbol. The prettification will be +reapplied as soon as point moves away from the symbol. If +set to nil, the prettification persists even when point is +on the symbol." + :type '(choice (const :tag "Never unprettify" nil) + (const :tag "Unprettify when point is inside" t) + (const :tag "Unprettify when point is inside or at right edge" right-edge)) + :group 'prog-mode) + +(defun prettify-symbols--post-command-hook () + (cl-labels ((get-prop-as-list + (prop) + (remove nil + (list (get-text-property (point) prop) + (when (and (eq prettify-symbols-unprettify-at-point 'right-edge) + (not (bobp))) + (get-text-property (1- (point)) prop)))))) + ;; Re-apply prettification to the previous symbol. + (when (and prettify-symbols--current-symbol-bounds + (or (< (point) (car prettify-symbols--current-symbol-bounds)) + (> (point) (cadr prettify-symbols--current-symbol-bounds)) + (and (not (eq prettify-symbols-unprettify-at-point 'right-edge)) + (= (point) (cadr prettify-symbols--current-symbol-bounds))))) + (apply #'font-lock-flush prettify-symbols--current-symbol-bounds) + (setq prettify-symbols--current-symbol-bounds nil)) + ;; Unprettify the current symbol. + (when-let ((c (get-prop-as-list 'composition)) + (s (get-prop-as-list 'prettify-symbols-start)) + (e (get-prop-as-list 'prettify-symbols-end)) + (s (apply #'min s)) + (e (apply #'max e))) + (with-silent-modifications + (setq prettify-symbols--current-symbol-bounds (list s e)) + (remove-text-properties s e '(composition)))))) + ;;;###autoload (define-minor-mode prettify-symbols-mode "Toggle Prettify Symbols mode. @@ -205,9 +253,16 @@ support it." (when (setq prettify-symbols--keywords (prettify-symbols--make-keywords)) (font-lock-add-keywords nil prettify-symbols--keywords) (setq-local font-lock-extra-managed-props - (cons 'composition font-lock-extra-managed-props)) + (append font-lock-extra-managed-props + '(composition + prettify-symbols-start + prettify-symbols-end))) + (when prettify-symbols-unprettify-at-point + (add-hook 'post-command-hook + #'prettify-symbols--post-command-hook nil t)) (font-lock-flush)) ;; Turn off + (remove-hook 'post-command-hook #'prettify-symbols--post-command-hook t) (when prettify-symbols--keywords (font-lock-remove-keywords nil prettify-symbols--keywords) (setq prettify-symbols--keywords nil)) diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el index 3d9b0c322ab..81aeb8d0f81 100644 --- a/lisp/progmodes/prolog.el +++ b/lisp/progmodes/prolog.el @@ -840,6 +840,8 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24." (require 'smie) +(defconst prolog-operator-chars "-\\\\#&*+./:<=>?@\\^`~") + (defun prolog-smie-forward-token () ;; FIXME: Add support for 0'<char>, if needed after adding it to ;; syntax-propertize-functions. @@ -848,7 +850,7 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24." (point) (progn (cond ((looking-at "[!;]") (forward-char 1)) - ((not (zerop (skip-chars-forward "#&*+-./:<=>?@\\^`~")))) + ((not (zerop (skip-chars-forward prolog-operator-chars)))) ((not (zerop (skip-syntax-forward "w_'")))) ;; In case of non-ASCII punctuation. ((not (zerop (skip-syntax-forward "."))))) @@ -861,8 +863,8 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24." (buffer-substring-no-properties (point) (progn (cond - ((memq (char-before) '(?! ?\;)) (forward-char -1)) - ((not (zerop (skip-chars-backward "#&*+-./:<=>?@\\^`~")))) + ((memq (char-before) '(?! ?\; ?\,)) (forward-char -1)) + ((not (zerop (skip-chars-backward prolog-operator-chars)))) ((not (zerop (skip-syntax-backward "w_'")))) ;; In case of non-ASCII punctuation. ((not (zerop (skip-syntax-backward "."))))) @@ -875,12 +877,21 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24." ;; manual uses precedence levels in the opposite sense (higher ;; numbers bind less tightly) than SMIE, so we use negative numbers. '(("." -10000 -10000) + ("?-" nil -1200) (":-" -1200 -1200) ("-->" -1200 -1200) + ("discontiguous" nil -1150) + ("dynamic" nil -1150) + ("meta_predicate" nil -1150) + ("module_transparent" nil -1150) + ("multifile" nil -1150) + ("public" nil -1150) + ("|" -1105 -1105) (";" -1100 -1100) + ("*->" -1050 -1050) ("->" -1050 -1050) ("," -1000 -1000) - ("\\+" -900 -900) + ("\\+" nil -900) ("=" -700 -700) ("\\=" -700 -700) ("=.." -700 -700) @@ -947,12 +958,36 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24." ;; ; c) ;; ;; based on the space between the open paren and the "a". - (unless (and (smie-rule-parent-p "(") + (unless (and (smie-rule-parent-p "(" ";") (save-excursion (smie-indent-forward-token) (smie-backward-sexp 'halfsexp) - (not (eq ?\( (char-before))))) + (if (smie-rule-parent-p "(") + (not (eq (char-before) ?\()) + (smie-indent-backward-token) + (smie-rule-bolp)))) prolog-indent-width)) + (`(:after . ";") + ;; Align with same-line comment as in: + ;; ; %% Toto + ;; foo + (and (smie-rule-bolp) + (looking-at ";[ \t]*\\(%\\)") + (let ((offset (- (save-excursion (goto-char (match-beginning 1)) + (current-column)) + (current-column)))) + ;; Only do it for small offsets, since the comment may actually be + ;; an "end-of-line" comment at comment-column! + (if (<= offset prolog-indent-width) offset)))) + (`(:after . ",") + ;; Special indent for: + ;; foopredicate(x) :- !, + ;; toto. + (and (eq (char-before) ?!) + (save-excursion + (smie-indent-backward-token) ;Skip ! + (equal ":-" (car (smie-indent-backward-token)))) + (smie-rule-parent prolog-indent-width))) (`(:after . ,(or `":-" `"-->")) prolog-indent-width))) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index b641e300163..6ff12b54976 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -5123,7 +5123,6 @@ returned as is." (provide 'python) ;; Local Variables: -;; coding: utf-8 ;; indent-tabs-mode: nil ;; End: diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 049c93dfae2..fbb4a90db40 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -1991,9 +1991,30 @@ Does not preserve point." (t tok))))))) (defcustom sh-indent-after-continuation t - "If non-nil, try to make sure text is indented after a line continuation." - :version "24.3" - :type 'boolean + "If non-nil, indent relative to the continued line's beginning. +Continued lines can either be indented as \"one long wrapped line\" without +paying attention to the actual syntactic structure, as in: + + for f \ + in a; do \ + toto; \ + done + +or as lines that just don't have implicit semi-colons between them, as in: + + for f \ + in a; do \ + toto; \ + done + +With `always' you get the former behavior whereas with nil you get the latter. +With t, you get the latter as long as that would indent the continuation line +deeper than the initial line." + :version "25.1" + :type '(choice + (const nil :tag "Never") + (const t :tag "Only if needed to make it deeper") + (const always :tag "Always")) :group 'sh-indentation) (defun sh-smie--continuation-start-indent () @@ -2004,24 +2025,49 @@ May return nil if the line should not be treated as continued." (unless (sh-smie--looking-back-at-continuation-p) (current-indentation)))) +(defun sh-smie--indent-continuation () + (cond + ((not (and sh-indent-after-continuation + (save-excursion + (ignore-errors + (skip-chars-backward " \t") + (sh-smie--looking-back-at-continuation-p))))) + nil) + ((eq sh-indent-after-continuation 'always) + (save-excursion + (forward-line -1) + (if (sh-smie--looking-back-at-continuation-p) + (current-indentation) + (+ (current-indentation) sh-indentation)))) + (t + ;; Just make sure a line-continuation is indented deeper. + (save-excursion + (let ((indent (let ((sh-indent-after-continuation nil)) + (smie-indent-calculate))) + (max most-positive-fixnum)) + (if (not (numberp indent)) indent + (while (progn + (forward-line -1) + (let ((ci (current-indentation))) + (cond + ;; Previous line is less indented, we're good. + ((< ci indent) nil) + ((sh-smie--looking-back-at-continuation-p) + (setq max (min max ci)) + ;; Previous line is itself a continuation. + ;; If it's indented like us, we're good, otherwise + ;; check the line before that one. + (> ci indent)) + (t ;Previous line is the beginning of the continued line. + (setq indent (min (+ ci sh-indentation) max)) + nil))))) + indent)))))) + (defun sh-smie-sh-rules (kind token) (pcase (cons kind token) (`(:elem . basic) sh-indentation) (`(:after . "case-)") (- (sh-var-value 'sh-indent-for-case-alt) (sh-var-value 'sh-indent-for-case-label))) - ((and `(:before . ,_) - ;; After a line-continuation, make sure the rest is indented. - (guard sh-indent-after-continuation) - (guard (save-excursion - (ignore-errors - (skip-chars-backward " \t") - (sh-smie--looking-back-at-continuation-p)))) - (let initial (sh-smie--continuation-start-indent)) - (guard (let* ((sh-indent-after-continuation nil) - (indent (smie-indent-calculate))) - (and (numberp indent) (numberp initial) - (<= indent initial))))) - `(column . ,(+ initial sh-indentation))) (`(:before . ,(or `"(" `"{" `"[" "while" "if" "for" "case")) (if (not (smie-rule-prev-p "&&" "||" "|")) (when (smie-rule-hanging-p) @@ -2363,6 +2409,7 @@ Calls the value of `sh-set-shell-hook' if set." (if (looking-at "[ \t]*\\\\\n") (goto-char (match-end 0)) (funcall orig)))) + (add-hook 'smie-indent-functions #'sh-smie--indent-continuation nil t) (smie-setup (symbol-value (funcall mksym "grammar")) (funcall mksym "rules") :forward-token (funcall mksym "forward-token") |
