* lisp/progmodes/perl-mode.el (perl-prettify-symbols): New defcustom.

(perl--prettify-symbols-alist): New const.
(perl--font-lock-compose-symbol, perl--font-lock-symbols-keywords): New funs.
(perl-font-lock-keywords-2): Use them.
(perl-electric-noindent-p): New function.
(perl-mode): Use it to set up electric-indent-mode.
(perl-electric-terminator, perl-indent-command): Mark obsolete.
(perl-mode-map): Remove bindings for them.
(perl-imenu-generic-expression, perl-outline-level):
Match functions&packages in column>0.
This commit is contained in:
Stefan Monnier 2012-11-08 10:35:32 -05:00
parent 3b11e6ac60
commit 79b3e37656
2 changed files with 80 additions and 22 deletions

View file

@ -1,5 +1,17 @@
2012-11-08 Stefan Monnier <monnier@iro.umontreal.ca> 2012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
* progmodes/perl-mode.el (perl-prettify-symbols): New defcustom.
(perl--prettify-symbols-alist): New const.
(perl--font-lock-compose-symbol, perl--font-lock-symbols-keywords):
New functions.
(perl-font-lock-keywords-2): Use them.
(perl-electric-noindent-p): New function.
(perl-mode): Use it to set up electric-indent-mode.
(perl-electric-terminator, perl-indent-command): Mark obsolete.
(perl-mode-map): Remove bindings for them.
(perl-imenu-generic-expression, perl-outline-level):
Match functions&packages in column>0.
* env.el (env--substitute-vars-regexp): New const. * env.el (env--substitute-vars-regexp): New const.
(substitute-env-vars): Use it. Add `only-defined' arg. (substitute-env-vars): Use it. Add `only-defined' arg.
* net/tramp.el (tramp-replace-environment-variables): Use it. * net/tramp.el (tramp-replace-environment-variables): Use it.

View file

@ -119,16 +119,11 @@
(defvar perl-mode-map (defvar perl-mode-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map "{" 'perl-electric-terminator)
(define-key map "}" 'perl-electric-terminator)
(define-key map ";" 'perl-electric-terminator)
(define-key map ":" 'perl-electric-terminator)
(define-key map "\e\C-a" 'perl-beginning-of-function) (define-key map "\e\C-a" 'perl-beginning-of-function)
(define-key map "\e\C-e" 'perl-end-of-function) (define-key map "\e\C-e" 'perl-end-of-function)
(define-key map "\e\C-h" 'perl-mark-function) (define-key map "\e\C-h" 'perl-mark-function)
(define-key map "\e\C-q" 'perl-indent-exp) (define-key map "\e\C-q" 'perl-indent-exp)
(define-key map "\177" 'backward-delete-char-untabify) (define-key map "\177" 'backward-delete-char-untabify)
(define-key map "\t" 'perl-indent-command)
map) map)
"Keymap used in Perl mode.") "Keymap used in Perl mode.")
@ -158,16 +153,54 @@
(defvar perl-imenu-generic-expression (defvar perl-imenu-generic-expression
'(;; Functions '(;; Functions
(nil "^sub\\s-+\\([-A-Za-z0-9+_:]+\\)" 1) (nil "^[ \t]*sub\\s-+\\([-A-Za-z0-9+_:]+\\)" 1)
;;Variables ;;Variables
("Variables" "^\\(?:my\\|our\\)\\s-+\\([$@%][-A-Za-z0-9+_:]+\\)\\s-*=" 1) ("Variables" "^\\(?:my\\|our\\)\\s-+\\([$@%][-A-Za-z0-9+_:]+\\)\\s-*=" 1)
("Packages" "^package\\s-+\\([-A-Za-z0-9+_:]+\\);" 1) ("Packages" "^[ \t]*package\\s-+\\([-A-Za-z0-9+_:]+\\);" 1)
("Doc sections" "^=head[0-9][ \t]+\\(.*\\)" 1)) ("Doc sections" "^=head[0-9][ \t]+\\(.*\\)" 1))
"Imenu generic expression for Perl mode. See `imenu-generic-expression'.") "Imenu generic expression for Perl mode. See `imenu-generic-expression'.")
;; Regexps updated with help from Tom Tromey <tromey@cambric.colorado.edu> and ;; Regexps updated with help from Tom Tromey <tromey@cambric.colorado.edu> and
;; Jim Campbell <jec@murzim.ca.boeing.com>. ;; Jim Campbell <jec@murzim.ca.boeing.com>.
(defcustom perl-prettify-symbols t
"If non-nil, some symbols will be displayed using Unicode chars."
:type 'boolean)
(defconst perl--prettify-symbols-alist
'(;;("andalso" . ?∧) ("orelse" . ?) ("as" . ?≡)("not" . ?¬)
;;("div" . ?÷) ("*" . ?×) ("o" . ?○)
("->" . ?→)
("=>" . ?⇒)
;;("<-" . ?←) ("<>" . ?≠) (">=" . ?≥) ("<=" . ?≤) ("..." . ?⋯)
("::" . ?∷)
))
(defun perl--font-lock-compose-symbol ()
"Compose a sequence of ascii chars into a symbol.
Regexp match data 0 points to the chars."
;; Check that the chars should really be composed into a symbol.
(let* ((start (match-beginning 0))
(end (match-end 0))
(syntaxes (if (eq (char-syntax (char-after start)) ?w)
'(?w) '(?. ?\\))))
(if (or (memq (char-syntax (or (char-before start) ?\ )) syntaxes)
(memq (char-syntax (or (char-after end) ?\ )) syntaxes)
(nth 8 (syntax-ppss)))
;; 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))
;; That's a symbol alright, so add the composition.
(compose-region start end (cdr (assoc (match-string 0)
perl--prettify-symbols-alist)))))
;; Return nil because we're not adding any face property.
nil)
(defun perl--font-lock-symbols-keywords ()
(when perl-prettify-symbols
`((,(regexp-opt (mapcar 'car perl--prettify-symbols-alist) t)
(0 (perl--font-lock-compose-symbol))))))
(defconst perl-font-lock-keywords-1 (defconst perl-font-lock-keywords-1
'(;; What is this for? '(;; What is this for?
;;("\\(--- .* ---\\|=== .* ===\\)" . font-lock-string-face) ;;("\\(--- .* ---\\|=== .* ===\\)" . font-lock-string-face)
@ -190,32 +223,32 @@
"Subdued level highlighting for Perl mode.") "Subdued level highlighting for Perl mode.")
(defconst perl-font-lock-keywords-2 (defconst perl-font-lock-keywords-2
(append perl-font-lock-keywords-1 (append
(list perl-font-lock-keywords-1
;; `( ;; Fontify keywords, except those fontified otherwise.
;; Fontify keywords, except those fontified otherwise. ,(concat "\\<"
(concat "\\<"
(regexp-opt '("if" "until" "while" "elsif" "else" "unless" (regexp-opt '("if" "until" "while" "elsif" "else" "unless"
"do" "dump" "for" "foreach" "exit" "die" "do" "dump" "for" "foreach" "exit" "die"
"BEGIN" "END" "return" "exec" "eval") t) "BEGIN" "END" "return" "exec" "eval") t)
"\\>") "\\>")
;; ;;
;; Fontify local and my keywords as types. ;; Fontify local and my keywords as types.
'("\\<\\(local\\|my\\)\\>" . font-lock-type-face) ("\\<\\(local\\|my\\)\\>" . font-lock-type-face)
;; ;;
;; Fontify function, variable and file name references. ;; Fontify function, variable and file name references.
'("&\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-function-name-face) ("&\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-function-name-face)
;; Additionally underline non-scalar variables. Maybe this is a bad idea. ;; Additionally underline non-scalar variables. Maybe this is a bad idea.
;;'("[$@%*][#{]?\\(\\sw+\\)" 1 font-lock-variable-name-face) ;;'("[$@%*][#{]?\\(\\sw+\\)" 1 font-lock-variable-name-face)
'("[$*]{?\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-variable-name-face) ("[$*]{?\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-variable-name-face)
'("\\([@%]\\|\\$#\\)\\(\\sw+\\(::\\sw+\\)*\\)" ("\\([@%]\\|\\$#\\)\\(\\sw+\\(::\\sw+\\)*\\)"
(2 (cons font-lock-variable-name-face '(underline)))) (2 (cons font-lock-variable-name-face '(underline))))
'("<\\(\\sw+\\)>" 1 font-lock-constant-face) ("<\\(\\sw+\\)>" 1 font-lock-constant-face)
;; ;;
;; Fontify keywords with/and labels as we do in `c++-font-lock-keywords'. ;; Fontify keywords with/and labels as we do in `c++-font-lock-keywords'.
'("\\<\\(continue\\|goto\\|last\\|next\\|redo\\)\\>[ \t]*\\(\\sw+\\)?" ("\\<\\(continue\\|goto\\|last\\|next\\|redo\\)\\>[ \t]*\\(\\sw+\\)?"
(1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) (1 font-lock-keyword-face) (2 font-lock-constant-face nil t))
'("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-constant-face))) ("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-constant-face)
,@(perl--font-lock-symbols-keywords)))
"Gaudy level highlighting for Perl mode.") "Gaudy level highlighting for Perl mode.")
(defvar perl-font-lock-keywords perl-font-lock-keywords-1 (defvar perl-font-lock-keywords perl-font-lock-keywords-1
@ -543,8 +576,10 @@ create a new comment."
(defun perl-outline-level () (defun perl-outline-level ()
(cond (cond
((looking-at "package\\s-") 0) ((looking-at "[ \t]*\\(package\\)\\s-")
((looking-at "sub\\s-") 1) (- (match-beginning 1) (match-beginning 0)))
((looking-at "[ \t]*s\\(ub\\)\\s-")
(- (match-beginning 1) (match-beginning 0)))
((looking-at "=head[0-9]") (- (char-before (match-end 0)) ?0)) ((looking-at "=head[0-9]") (- (char-before (match-end 0)) ?0))
((looking-at "=cut") 1) ((looking-at "=cut") 1)
(t 3))) (t 3)))
@ -621,6 +656,11 @@ Turning on Perl mode runs the normal hook `perl-mode-hook'."
#'perl-syntax-propertize-function) #'perl-syntax-propertize-function)
(add-hook 'syntax-propertize-extend-region-functions (add-hook 'syntax-propertize-extend-region-functions
#'syntax-propertize-multiline 'append 'local) #'syntax-propertize-multiline 'append 'local)
;; Electricity.
;; FIXME: setup electric-layout-rules.
(set (make-local-variable 'electric-indent-chars)
(append '(?\{ ?\} ?\; ?\:) electric-indent-chars))
(add-hook 'electric-indent-functions #'perl-electric-noindent-p nil t)
;; Tell imenu how to handle Perl. ;; Tell imenu how to handle Perl.
(set (make-local-variable 'imenu-generic-expression) (set (make-local-variable 'imenu-generic-expression)
perl-imenu-generic-expression) perl-imenu-generic-expression)
@ -637,7 +677,11 @@ Turning on Perl mode runs the normal hook `perl-mode-hook'."
0 ;Existing comment at bol stays there. 0 ;Existing comment at bol stays there.
comment-column)) comment-column))
(defalias 'electric-perl-terminator 'perl-electric-terminator) (define-obsolete-function-alias 'electric-perl-terminator
'perl-electric-terminator "22.1")
(defun perl-electric-noindent-p (char)
(unless (eolp) 'no-indent))
(defun perl-electric-terminator (arg) (defun perl-electric-terminator (arg)
"Insert character and maybe adjust indentation. "Insert character and maybe adjust indentation.
If at end-of-line, and not in a comment or a quote, correct the indentation." If at end-of-line, and not in a comment or a quote, correct the indentation."
@ -661,6 +705,7 @@ If at end-of-line, and not in a comment or a quote, correct the indentation."
(perl-indent-line) (perl-indent-line)
(delete-char -1)))) (delete-char -1))))
(self-insert-command (prefix-numeric-value arg))) (self-insert-command (prefix-numeric-value arg)))
(make-obsolete 'perl-electric-terminator 'electric-indent-mode "24.4")
;; not used anymore, but may be useful someday: ;; not used anymore, but may be useful someday:
;;(defun perl-inside-parens-p () ;;(defun perl-inside-parens-p ()
@ -744,6 +789,7 @@ following list:
(t (t
(message "Use backslash to quote # characters.") (message "Use backslash to quote # characters.")
(ding t))))))))) (ding t)))))))))
(make-obsolete 'perl-indent-command 'indent-according-to-mode "24.4")
(defun perl-indent-line (&optional nochange parse-start) (defun perl-indent-line (&optional nochange parse-start)
"Indent current line as Perl code. "Indent current line as Perl code.