commit 52d7486d8bc5e55c7bc7ef764c9b4fd38062761e (HEAD, refs/remotes/origin/master) Author: Tassilo Horn Date: Wed May 6 07:49:20 2015 +0200 Support the biblatex journaltitle field * lisp/textmodes/reftex-cite.el (reftex-format-bib-entry): Support the biblatex journaltitle field. diff --git a/lisp/textmodes/reftex-cite.el b/lisp/textmodes/reftex-cite.el index b22e8b1..17e8cfd 100644 --- a/lisp/textmodes/reftex-cite.el +++ b/lisp/textmodes/reftex-cite.el @@ -543,7 +543,14 @@ If FORMAT is non-nil `format' entry accordingly." (extra (cond ((equal type "article") - (concat (reftex-get-bib-field "journal" entry) " " + (concat (let ((jt (reftex-get-bib-field "journal" entry))) + ;; biblatex prefers the alternative journaltitle + ;; field, so check if that exists in case journal + ;; is empty. + (if (zerop (length jt)) + (reftex-get-bib-field "journaltitle" entry) + jt)) + " " (reftex-get-bib-field "volume" entry) ", " (reftex-get-bib-field "pages" entry))) ((equal type "book") commit 276f5d9e108378e13afd26b412526fc57a1f0032 Author: Glenn Morris Date: Tue May 5 20:13:10 2015 -0700 Minor declare-function improvement * lisp/emacs-lisp/bytecomp.el (byte-compile-macroexpand-declare-function): Handle declarations after calls. (Bug#20509) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index f0d2ee4..67744c6 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2920,11 +2920,17 @@ for symbols generated by the byte compiler itself." ;; Special macro-expander used during byte-compilation. (defun byte-compile-macroexpand-declare-function (fn file &rest args) - (push (cons fn - (if (and (consp args) (listp (car args))) - (list 'declared (car args)) - t)) ; Arglist not specified. - byte-compile-function-environment) + (let ((gotargs (and (consp args) (listp (car args)))) + (unresolved (assq fn byte-compile-unresolved-functions))) + (when unresolved ; function was called before declaration + (if (and gotargs (byte-compile-warning-enabled-p 'callargs)) + (byte-compile-arglist-warn fn (car args) nil) + (setq byte-compile-unresolved-functions + (delq unresolved byte-compile-unresolved-functions)))) + (push (cons fn (if gotargs + (list 'declared (car args)) + t)) ; Arglist not specified. + byte-compile-function-environment)) ;; We are stating that it _will_ be defined at runtime. (setq byte-compile-noruntime-functions (delq fn byte-compile-noruntime-functions)) commit 754fdb1280dfe56a0b94b20c1d7ab0fb5b5615d1 Author: Glenn Morris Date: Tue May 5 20:11:22 2015 -0700 * lisp/progmodes/js.el (js--optimize-arglist): Remove declaration. diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 62f19f4..f06c5c7 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -2852,10 +2852,6 @@ with `js--js-encode-value'." (defsubst js--js-true (value) (not (js--js-not value))) -;; The somewhat complex code layout confuses the byte-compiler into -;; thinking this function "might not be defined at runtime". -(declare-function js--optimize-arglist "js" (arglist)) - (eval-and-compile (defun js--optimize-arglist (arglist) "Convert immediate js< and js! references to deferred ones." commit 118bb49ab3f27e6011754e47e3056e917d2dcac1 Author: Glenn Morris Date: Tue May 5 20:10:59 2015 -0700 * lisp/w32-fns.el (w32-shell-name): Silence compiler. diff --git a/lisp/w32-fns.el b/lisp/w32-fns.el index 876df87..6f8fa84 100644 --- a/lisp/w32-fns.el +++ b/lisp/w32-fns.el @@ -44,7 +44,7 @@ (or (bound-and-true-p shell-file-name) (getenv "ESHELL") (getenv "SHELL") - (and (w32-using-nt) "cmd.exe") + (and (fboundp 'w32-using-nt) (w32-using-nt) "cmd.exe") "command.com")) (defun w32-system-shell-p (shell-name) commit d804150fb26c5c46cf8c7bc6bac1cbf88c3d5bed Author: Dmitry Gutov Date: Wed May 6 05:54:52 2015 +0300 Pulse using a timer * lisp/cedet/pulse.el (pulse-momentary-stop-time): New variable. (pulse-momentary-highlight-overlay): Set up the timer instead of calling `pulse' (http://lists.gnu.org/archive/html/emacs-devel/2015-05/). (pulse-tick): New function. (pulse-momentary-unhighlight): Cut off the stop time. (pulse-delay): Update the docstring WRT to not using sit-for. diff --git a/lisp/cedet/pulse.el b/lisp/cedet/pulse.el index 07882ef..fcc47b9 100644 --- a/lisp/cedet/pulse.el +++ b/lisp/cedet/pulse.el @@ -121,7 +121,7 @@ http://www.emacswiki.org/cgi-bin/wiki/hexrgb.el" :group 'pulse :type 'number) (defcustom pulse-delay .03 - "Delay between face lightening iterations, as used by `sit-for'." + "Delay between face lightening iterations." :group 'pulse :type 'number) @@ -179,6 +179,9 @@ Be sure to call `pulse-reset-face' after calling pulse." (defvar pulse-momentary-overlay nil "The current pulsing overlay.") +(defvar pulse-momentary-stop-time nil + "The current stop time.") + (defun pulse-momentary-highlight-overlay (o &optional face) "Pulse the overlay O, unhighlighting before next command. Optional argument FACE specifies the face to do the highlighting." @@ -192,15 +195,25 @@ Optional argument FACE specifies the face to do the highlighting." (overlay-put o 'face (or face 'pulse-highlight-start-face)) (add-hook 'pre-command-hook 'pulse-momentary-unhighlight)) - ;; pulse it. - (unwind-protect - (progn - (overlay-put o 'face 'pulse-highlight-face) - ;; The pulse function puts FACE onto 'pulse-highlight-face. - ;; Thus above we put our face on the overlay, but pulse - ;; with a reference face needed for the color. - (pulse face)) - (pulse-momentary-unhighlight))))) + ;; Pulse it. + (overlay-put o 'face 'pulse-highlight-face) + ;; The pulse function puts FACE onto 'pulse-highlight-face. + ;; Thus above we put our face on the overlay, but pulse + ;; with a reference face needed for the color. + (pulse-reset-face face) + (setq pulse-momentary-stop-time (time-add (current-time) + (* pulse-delay + pulse-iterations))) + (let ((timer (run-with-timer 0 pulse-delay #'ignore))) + (timer-set-function timer #'pulse-tick + (list + timer)))))) + +(defun pulse-tick (timer) + (if (time-less-p (current-time) pulse-momentary-stop-time) + (pulse-lighten-highlight) + (pulse-momentary-unhighlight) + (cancel-timer timer))) (defun pulse-momentary-unhighlight () "Unhighlight a line recently highlighted." @@ -222,6 +235,9 @@ Optional argument FACE specifies the face to do the highlighting." ;; Reset the pulsing face. (pulse-reset-face) + ;; Signal the timer to cancel. + (setq pulse-momentary-stop-time (current-time)) + ;; Remove this hook. (remove-hook 'pre-command-hook 'pulse-momentary-unhighlight)) commit 4d3fed0157e96c0f9a8138ad52530d7fa53b1833 Author: Dmitry Gutov Date: Wed May 6 04:49:01 2015 +0300 Add semantic/symref/grep file patterns for ruby-mode * lisp/cedet/semantic/symref/grep.el (semantic-symref-filepattern-alist): Add patterns for ruby-mode. Clarify the docstring. diff --git a/lisp/cedet/semantic/symref/grep.el b/lisp/cedet/semantic/symref/grep.el index d57b50f..4598a2c 100644 --- a/lisp/cedet/semantic/symref/grep.el +++ b/lisp/cedet/semantic/symref/grep.el @@ -46,9 +46,11 @@ and those hits returned.") '((c-mode "*.[ch]") (c++-mode "*.[chCH]" "*.[ch]pp" "*.cc" "*.hh") (html-mode "*.s?html" "*.php") + (ruby-mode "*.r[bu]" "*.rake" "*.gemspec" "*.erb" "*.haml" + "Rakefile" "Thorfile" "Capfile" "Guardfile" "Vagrantfile") ) - "List of major modes and file extension pattern regexp. -See find -regex man page for format.") + "List of major modes and file extension pattern. +See find -name man page for format.") (defun semantic-symref-derive-find-filepatterns (&optional mode) "Derive a list of file patterns for the current buffer. commit f96313f1101c02fba910d85d63148d402397be3e Author: Dmitry Gutov Date: Wed May 6 04:35:46 2015 +0300 Don't require match * lisp/progmodes/xref.el (xref--read-identifier): Don't require match. That doesn't work for every command, and some identifier completion tables are bound to be imperfect anyway. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index f11dff1..f6faaf6 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -624,7 +624,7 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (cond ((or current-prefix-arg xref-prompt-for-identifier (not id)) (completing-read prompt (funcall xref-identifier-completion-table-function) - nil t nil + nil nil nil 'xref--read-identifier-history id)) (t id)))) commit a7d630eb4895a392bcc0d9986d1ca5382a4f7b96 Author: Stefan Monnier Date: Tue May 5 22:18:19 2015 -0400 * lisp/cedet/semantic/grammar.el: Fix compiler warnings (bug#20505) (semantic-grammar--template-expand): New function. (semantic-grammar-header, semantic-grammar-footer): Use it. (semantic-grammar--lex-block-specs): Remove unused var `block-spec'. (semantic-grammar-file-regexp): Refine regexp. (semantic-grammar-eldoc-get-macro-docstring): Use elisp-get-fnsym-args-string when available. (semantic-idle-summary-current-symbol-info): Use new elisp-* names instead of the old eldoc-* names. * lisp/emacs-lisp/eldoc.el (eldoc-docstring-format-sym-doc): Move back from elisp-mode.el. Tweak calling convention. * lisp/progmodes/elisp-mode.el (package-user-dir): Declare. (elisp-get-fnsym-args-string): Add `prefix' argument. Rename from elisp--get-fnsym-args-string. (elisp--highlight-function-argument): Add `prefix' arg. (elisp-get-var-docstring): Rename from elisp--get-var-docstring. (elisp--docstring-format-sym-doc): Move back to eldoc.el. diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el index 15ad987..fc7e9e6 100644 --- a/lisp/cedet/semantic/grammar.el +++ b/lisp/cedet/semantic/grammar.el @@ -628,39 +628,38 @@ The symbols in the list are local variables in t) (match-string 0)))) +(defun semantic-grammar--template-expand (template env) + (mapconcat (lambda (S) + (if (stringp S) S + (let ((x (assq S env))) + (cond + (x (cdr x)) + ((symbolp S) (symbol-value S)))))) + template "")) + (defun semantic-grammar-header () "Return text of a generated standard header." - (let ((file (semantic-grammar-buffer-file + (semantic-grammar--template-expand + semantic-grammar-header-template + `((file . ,(semantic-grammar-buffer-file semantic--grammar-output-buffer)) - (gram (semantic-grammar-buffer-file)) - (date (format-time-string "%Y-%m-%d %T%z")) - (vcid (concat "$" "Id" "$")) ;; Avoid expansion - ;; Try to get the copyright from the input grammar, or - ;; generate a new one if not found. - (copy (or (semantic-grammar-copyright-line) + (gram . ,(semantic-grammar-buffer-file)) + (date . ,(format-time-string "%Y-%m-%d %T%z")) + (vcid . ,(concat "$" "Id" "$")) ;; Avoid expansion + ;; Try to get the copyright from the input grammar, or + ;; generate a new one if not found. + (copy . ,(or (semantic-grammar-copyright-line) (concat (format-time-string ";; Copyright (C) %Y ") - user-full-name))) - (out "")) - (dolist (S semantic-grammar-header-template) - (cond ((stringp S) - (setq out (concat out S))) - ((symbolp S) - (setq out (concat out (symbol-value S)))))) - out)) + user-full-name)))))) (defun semantic-grammar-footer () "Return text of a generated standard footer." - (let* ((file (semantic-grammar-buffer-file - semantic--grammar-output-buffer)) - (libr (or semantic--grammar-provide - semantic--grammar-package)) - (out "")) - (dolist (S semantic-grammar-footer-template) - (cond ((stringp S) - (setq out (concat out S))) - ((symbolp S) - (setq out (concat out (symbol-value S)))))) - out)) + (semantic-grammar--template-expand + semantic-grammar-footer-template + `((file . ,(semantic-grammar-buffer-file + semantic--grammar-output-buffer)) + (libr . ,(or semantic--grammar-provide + semantic--grammar-package))))) (defun semantic-grammar-token-data () "Return the string value of the table of lexical tokens." @@ -714,7 +713,7 @@ Block definitions are read from the current table of lexical types." (let* ((blocks (cdr (semantic-lex-type-value "block" t))) (open-delims (cdr (semantic-lex-type-value "open-paren" t))) (close-delims (cdr (semantic-lex-type-value "close-paren" t))) - olist clist block-spec delim-spec open-spec close-spec) + olist clist delim-spec open-spec close-spec) (dolist (block-spec blocks) (setq delim-spec (semantic-grammar--lex-delim-spec block-spec) open-spec (assq (car delim-spec) open-delims) @@ -818,7 +817,7 @@ Block definitions are read from the current table of lexical types." ;;; Generation of the grammar support file. ;; -(defcustom semantic-grammar-file-regexp "\\.[wb]y$" +(defcustom semantic-grammar-file-regexp "\\.[wb]y\\'" "Regexp which matches grammar source files." :group 'semantic :type 'regexp) @@ -1073,7 +1072,7 @@ See also the variable `semantic-grammar-file-regexp'." (defvar semantic--grammar-macros-regexp-2 nil) (make-variable-buffer-local 'semantic--grammar-macros-regexp-2) -(defun semantic--grammar-clear-macros-regexp-2 (&rest ignore) +(defun semantic--grammar-clear-macros-regexp-2 (&rest _) "Clear the cached regexp that match macros local in this grammar. IGNORE arguments. Added to `before-change-functions' hooks to be run before each text @@ -1665,9 +1664,11 @@ Select the buffer containing the tag's definition, and move point there." "Return a one-line docstring for the given grammar MACRO. EXPANDER is the name of the function that expands MACRO." (require 'eldoc) - (if (eq expander (car semantic-grammar-eldoc-last-data)) - (cdr semantic-grammar-eldoc-last-data) - (let ((doc (help-split-fundoc (documentation expander t) expander))) + (cond + ((eq expander (car semantic-grammar-eldoc-last-data)) + (cdr semantic-grammar-eldoc-last-data)) + ((fboundp 'eldoc-function-argstring) ;; Emacs<25 + (let* ((doc (help-split-fundoc (documentation expander t) expander))) (cond (doc (setq doc (car doc)) @@ -1680,7 +1681,16 @@ EXPANDER is the name of the function that expands MACRO." (eldoc-docstring-format-sym-doc macro (format "==> %s %s" expander doc) 'default)) (setq semantic-grammar-eldoc-last-data (cons expander doc))) - doc))) + doc)) + ((fboundp 'elisp-get-fnsym-args-string) ;; Emacs≄25 + (elisp-get-fnsym-args-string + expander nil + (concat (propertize (symbol-name macro) + 'face 'font-lock-keyword-face) + " ==> " + (propertize (symbol-name macro) + 'face 'font-lock-function-name-face) + ": "))))) (define-mode-local-override semantic-idle-summary-current-symbol-info semantic-grammar-mode () @@ -1711,10 +1721,14 @@ Otherwise return nil." (setq val (semantic-grammar-eldoc-get-macro-docstring elt val))) ;; Function ((and elt (fboundp elt)) - (setq val (eldoc-get-fnsym-args-string elt))) + (setq val (if (fboundp 'eldoc-get-fnsym-args-string) + (eldoc-get-fnsym-args-string elt) + (elisp-get-fnsym-args-string elt)))) ;; Variable ((and elt (boundp elt)) - (setq val (eldoc-get-var-docstring elt))) + (setq val (if (fboundp 'eldoc-get-var-docstring) + (eldoc-get-var-docstring elt) + (elisp-get-var-docstring elt)))) (t nil))) (or val (semantic-idle-summary-current-symbol-info-default)))) diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index d527d67..0091cdb 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -354,7 +354,32 @@ return any documentation.") nil)) (eldoc-message (funcall eldoc-documentation-function))))) - +;; If the entire line cannot fit in the echo area, the symbol name may be +;; truncated or eliminated entirely from the output to make room for the +;; description. +(defun eldoc-docstring-format-sym-doc (prefix doc &optional face) + (when (symbolp prefix) + (setq prefix (concat (propertize (symbol-name prefix) 'face face) ": "))) + (let* ((ea-multi eldoc-echo-area-use-multiline-p) + ;; Subtract 1 from window width since emacs will not write + ;; any chars to the last column, or in later versions, will + ;; cause a wraparound and resize of the echo area. + (ea-width (1- (window-width (minibuffer-window)))) + (strip (- (+ (length prefix) (length doc)) ea-width))) + (cond ((or (<= strip 0) + (eq ea-multi t) + (and ea-multi (> (length doc) ea-width))) + (concat prefix doc)) + ((> (length doc) ea-width) + (substring (format "%s" doc) 0 ea-width)) + ((>= strip (string-match-p ":? *\\'" prefix)) + doc) + (t + ;; Show the end of the partial symbol name, rather + ;; than the beginning, since the former is more likely + ;; to be unique given package namespace conventions. + (concat (substring prefix strip) doc))))) + ;; When point is in a sexp, the function args are not reprinted in the echo ;; area after every possible interactive command because some of them print ;; their own messages in the echo area; the eldoc functions would instantly diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index dac807e..7bc7798 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -650,11 +650,14 @@ It can be quoted, or be inside a quoted form." lst)))) lst))) +(defvar package-user-dir) + (defun elisp--xref-find-references (symbol) (let* ((dirs (sort (mapcar (lambda (dir) (file-name-as-directory (expand-file-name dir))) + ;; FIXME: Why add package-user-dir? (cons package-user-dir load-path)) #'string<)) (ref dirs)) @@ -1174,13 +1177,13 @@ which see." (cond ((null current-fnsym) nil) ((eq current-symbol (car current-fnsym)) - (or (apply #'elisp--get-fnsym-args-string current-fnsym) - (elisp--get-var-docstring current-symbol))) + (or (apply #'elisp-get-fnsym-args-string current-fnsym) + (elisp-get-var-docstring current-symbol))) (t - (or (elisp--get-var-docstring current-symbol) - (apply #'elisp--get-fnsym-args-string current-fnsym)))))) + (or (elisp-get-var-docstring current-symbol) + (apply #'elisp-get-fnsym-args-string current-fnsym)))))) -(defun elisp--get-fnsym-args-string (sym &optional index) +(defun elisp-get-fnsym-args-string (sym &optional index prefix) "Return a string containing the parameter list of the function SYM. If SYM is a subr and no arglist is obtainable from the docstring or elsewhere, return a 1-line docstring." @@ -1204,16 +1207,22 @@ or elsewhere, return a 1-line docstring." (car doc)) (t (help-function-arglist sym))))) ;; Stringify, and store before highlighting, downcasing, etc. - ;; FIXME should truncate before storing. - (elisp--last-data-store sym (elisp--function-argstring args) + (elisp--last-data-store sym (elisp-function-argstring args) 'function)))))) ;; Highlight, truncate. (if argstring - (elisp--highlight-function-argument sym argstring index)))) - -(defun elisp--highlight-function-argument (sym args index) + (elisp--highlight-function-argument + sym argstring index + (or prefix + (concat (propertize (symbol-name sym) 'face + (if (functionp sym) + 'font-lock-function-name-face + 'font-lock-keyword-face)) + ": ")))))) + +(defun elisp--highlight-function-argument (sym args index prefix) "Highlight argument INDEX in ARGS list for function SYM. -In the absence of INDEX, just call `elisp--docstring-format-sym-doc'." +In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'." ;; FIXME: This should probably work on the list representation of `args' ;; rather than its string representation. ;; FIXME: This function is much too long, we need to split it up! @@ -1298,9 +1307,9 @@ In the absence of INDEX, just call `elisp--docstring-format-sym-doc'." ((string= argument "&allow-other-keys")) ; Skip. ;; Back to index 0 in ARG1 ARG2 ARG2 ARG3 etc... ;; like in `setq'. - ((or (and (string-match-p "\\.\\.\\.$" argument) + ((or (and (string-match-p "\\.\\.\\.\\'" argument) (string= argument (car (last args-lst)))) - (and (string-match-p "\\.\\.\\.$" + (and (string-match-p "\\.\\.\\.\\'" (substring args 1 (1- (length args)))) (= (length (remove "..." args-lst)) 2) (> index 1) (eq (logand index 1) 1))) @@ -1315,14 +1324,12 @@ In the absence of INDEX, just call `elisp--docstring-format-sym-doc'." (when start (setq doc (copy-sequence args)) (add-text-properties start end (list 'face argument-face) doc)) - (setq doc (elisp--docstring-format-sym-doc - sym doc (if (functionp sym) 'font-lock-function-name-face - 'font-lock-keyword-face))) + (setq doc (eldoc-docstring-format-sym-doc prefix doc)) doc))) ;; Return a string containing a brief (one-line) documentation string for ;; the variable. -(defun elisp--get-var-docstring (sym) +(defun elisp-get-var-docstring (sym) (cond ((not sym) nil) ((and (eq sym (aref elisp--eldoc-last-data 0)) (eq 'variable (aref elisp--eldoc-last-data 2))) @@ -1330,7 +1337,7 @@ In the absence of INDEX, just call `elisp--docstring-format-sym-doc'." (t (let ((doc (documentation-property sym 'variable-documentation t))) (when doc - (let ((doc (elisp--docstring-format-sym-doc + (let ((doc (eldoc-docstring-format-sym-doc sym (elisp--docstring-first-line doc) 'font-lock-variable-name-face))) (elisp--last-data-store sym doc 'variable))))))) @@ -1354,36 +1361,6 @@ In the absence of INDEX, just call `elisp--docstring-format-sym-doc'." (substring doc start (match-beginning 0))) ((zerop start) doc) (t (substring doc start)))))))) - -(defvar eldoc-echo-area-use-multiline-p) - -;; If the entire line cannot fit in the echo area, the symbol name may be -;; truncated or eliminated entirely from the output to make room for the -;; description. -(defun elisp--docstring-format-sym-doc (sym doc face) - (save-match-data - (let* ((name (symbol-name sym)) - (ea-multi eldoc-echo-area-use-multiline-p) - ;; Subtract 1 from window width since emacs will not write - ;; any chars to the last column, or in later versions, will - ;; cause a wraparound and resize of the echo area. - (ea-width (1- (window-width (minibuffer-window)))) - (strip (- (+ (length name) (length ": ") (length doc)) ea-width))) - (cond ((or (<= strip 0) - (eq ea-multi t) - (and ea-multi (> (length doc) ea-width))) - (format "%s: %s" (propertize name 'face face) doc)) - ((> (length doc) ea-width) - (substring (format "%s" doc) 0 ea-width)) - ((>= strip (length name)) - (format "%s" doc)) - (t - ;; Show the end of the partial symbol name, rather - ;; than the beginning, since the former is more likely - ;; to be unique given package namespace conventions. - (setq name (substring name strip)) - (format "%s: %s" (propertize name 'face face) doc)))))) - ;; Return a list of current function name and argument index. (defun elisp--fnsym-in-current-sexp () @@ -1428,7 +1405,7 @@ In the absence of INDEX, just call `elisp--docstring-format-sym-doc'." (memq (char-syntax c) '(?w ?_)) (intern-soft (current-word))))) -(defun elisp--function-argstring (arglist) +(defun elisp-function-argstring (arglist) "Return ARGLIST as a string enclosed by (). ARGLIST is either a string, or a list of strings or symbols." (let ((str (cond ((stringp arglist) arglist) commit 0ed044dc1b524370f02f531b3b6fcc1ef45c395d Author: Glenn Morris Date: Tue May 5 19:50:43 2015 -0400 * lisp/help-fns.el (describe-function-1): Handle builtins with advertised calling conventions. (Bug#20479) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 9020037..4982ee5 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -495,6 +495,9 @@ FILE is the file where FUNCTION was probably defined." f)) ((subrp def) (intern (subr-name def))) (t def))) + (sig-key (if (subrp def) + (indirect-function real-def) + real-def)) (file-name (find-lisp-object-file-name function def)) (pt1 (with-current-buffer (help-buffer) (point))) (beg (if (and (or (byte-code-function-p def) @@ -586,7 +589,7 @@ FILE is the file where FUNCTION was probably defined." (help-fns--key-bindings function) (with-current-buffer standard-output - (setq doc (help-fns--signature function doc real-def real-function)) + (setq doc (help-fns--signature function doc sig-key real-function)) (run-hook-with-args 'help-fns-describe-function-functions function) (insert "\n" (or doc "Not documented."))))))) commit 4ac426a1b90912ea947d46a57b6fcbbbf7586da1 Merge: 0508aa2 8cb4b4f Author: Nicolas Petton Date: Tue May 5 22:10:32 2015 +0200 Merge branch 'seq-let' commit 8cb4b4f98aa2758a016df25e39ff48cf132ed39c Author: Nicolas Petton Date: Tue May 5 22:04:18 2015 +0200 Update `seq-let' documentation * doc/lispref/sequences.texi: Update the documentation of `seq-let' with the support of `&rest'. diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index e58f039..1166ef8 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -413,7 +413,7 @@ but their relative order is also preserved: (9 . "aaa") (9 . "zzz") (9 . "ppp") (9 . "fff")] @end group @end example - + @xref{Sorting}, for more functions that perform sorting. See @code{documentation} in @ref{Accessing Documentation}, for a useful example of @code{sort}. @@ -804,6 +804,10 @@ vector or string (@pxref{Iteration} for more information about the @var{arguments} can itself include sequences allowing for nested destructuring. +The @var{arguments} sequence can also include the `&rest' marker +followed by a variable name to be bound to the rest of +@code{sequence}. + @example @group (seq-let [first second] [1 2 3 4] @@ -820,6 +824,11 @@ destructuring. (list a b c)) @result{} (1 2 3) @end group +@group +(seq-let [a b &rest others] [1 2 3 4] + others) +@end group +@result{} [3 4] @end example @end defmac commit 6cd74155985f6335e26ffa419c38d0d2f91e3b4e Author: Nicolas Petton Date: Tue May 5 21:45:36 2015 +0200 Add support for &rest in `seq-let' * lisp/emacs-lisp/seq.el (seq--make-bindings): Add support for `&rest' in the argument list. * test/automated/seq-tests.el: Add a test for parsing and binding `&rest' in `seq-let'. diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index ea7a613..3938945 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -42,7 +42,8 @@ ;;; TODO: -;; - Add support for &rest in the argument list of seq-let +;; - Add a pcase macro named using `pcase-defmacro' that `seq-let' +;; - could wrap. ;;; Code: @@ -350,20 +351,28 @@ This is an optimization for lists in `seq-take-while'." (font-lock-add-keywords 'emacs-lisp-mode '("\\" "\\"))) -(defun seq--make-bindings (args seq &optional initial-bindings) - "Return an alist of bindings of the variables in ARGS to the elements of SEQ. -if INITIAL-BINDINGS is non-nil, append new bindings to it, and -return INITIAL-BINDINGS." - (let ((index 0)) +(defun seq--make-bindings (args seq &optional bindings) + "Return a list of bindings of the variables in ARGS to the elements of SEQ. +if BINDINGS is non-nil, append new bindings to it, and +return BINDINGS." + (let ((index 0) + (rest-bound nil)) (seq-doseq (name args) - (if (sequencep name) - (setq initial-bindings (seq--make-bindings - (seq--elt-safe args index) - `(seq--elt-safe ,seq ,index) - initial-bindings)) - (push `(,name (seq--elt-safe ,seq ,index)) initial-bindings)) + (unless rest-bound + (pcase name + ((pred seq-p) + (setq bindings (seq--make-bindings (seq--elt-safe args index) + `(seq--elt-safe ,seq ,index) + bindings))) + (`&rest + (progn (push `(,(seq--elt-safe args (1+ index)) + (seq-drop ,seq ,index)) + bindings) + (setq rest-bound t))) + (t + (push `(,name (seq--elt-safe ,seq ,index)) bindings)))) (setq index (1+ index))) - initial-bindings)) + bindings)) (defun seq--elt-safe (seq n) "Return element of SEQ at the index N. diff --git a/test/automated/seq-tests.el b/test/automated/seq-tests.el index e1e8ae0..ab46eb8 100644 --- a/test/automated/seq-tests.el +++ b/test/automated/seq-tests.el @@ -283,7 +283,11 @@ Evaluate BODY for each created sequence. (should (= b 2)) (should (= c 3)) (should (= d 4)) - (should (null e)))) + (should (null e))) + (seq-let (a b &rest others) seq + (should (= a 1)) + (should (= b 2)) + (should (same-contents-p others (seq-drop seq 2))))) (let ((seq '(1 (2 (3 (4)))))) (seq-let (_ (_ (_ (a)))) seq (should (= a 4)))) commit 0508aa26705b3507d9afac54ada4eac47f8cf8a5 Author: Paul Eggert Date: Tue May 5 12:25:18 2015 -0700 Spelling fixes diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index 8e19544..31d0b85 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -299,9 +299,9 @@ Optional argument IGNORE is an extraneous parameter." (props (cl--slot-descriptor-props slot)) (cust (alist-get :custom props))) ;; - ;; Shouldn't i be incremented unconditionnaly ? Or + ;; Shouldn't I be incremented unconditionally? Or ;; better shouldn't we simply mapc on the slots vector - ;; avoiding use of this integer variable ? PLN Sat May + ;; avoiding use of this integer variable? PLN Sat May ;; 2 07:35:45 2015 ;; (setq i (+ i 1)) diff --git a/test/automated/cl-lib-tests.el b/test/automated/cl-lib-tests.el index ece1d45..1bdc6d7 100644 --- a/test/automated/cl-lib-tests.el +++ b/test/automated/cl-lib-tests.el @@ -444,7 +444,7 @@ (should (eq nums (cl-adjoin 2 nums :test-not myfn-p))) ; 1 matches (should (eq nums (cl-adjoin 3 nums :test-not myfn-p))) ; 1 and 2 matches - ;; according to CLTL2 passing both :test and :test-not should signal error + ;; according to CLtL2 passing both :test and :test-not should signal error ;;(should-error (cl-adjoin 3 nums :test 'myfn-p :test-not myfn-p)) ;; own :key fn commit ad9e659b30545e9476c2166fed469d7a03b2f554 Author: (tiny change) Pierre Lorenzon Date: Tue May 5 14:47:58 2015 -0400 * eieio-custom.el (eieio-object-value-get): Add missing increment Fixes: debbugs:20467 diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index f3ec1b6..8e19544 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -298,6 +298,13 @@ Optional argument IGNORE is an extraneous parameter." (let* ((slot (aref slots i)) (props (cl--slot-descriptor-props slot)) (cust (alist-get :custom props))) + ;; + ;; Shouldn't i be incremented unconditionnaly ? Or + ;; better shouldn't we simply mapc on the slots vector + ;; avoiding use of this integer variable ? PLN Sat May + ;; 2 07:35:45 2015 + ;; + (setq i (+ i 1)) (if (and cust (or eieio-custom-ignore-eieio-co (not master-group) commit a53545fc4bac86baabb0316f2a3bd7cc992f5b52 Author: (tiny change) Pierre Lorenzon Date: Tue May 5 14:43:48 2015 -0400 (eieio-object-value-create): Adjust to new slots representation Fixes: debbugs:20467 * eieio-custom.el (eieio-object-value-create): Fix missed adjustment to new representation of slots metadata. diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index 26fc452..f3ec1b6 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -223,6 +223,7 @@ Optional argument IGNORE is an extraneous parameter." ;; Loop over all the slots, creating child widgets. (dotimes (i (length slots)) (let* ((slot (aref slots i)) + (sname (eieio-slot-descriptor-name slot)) (props (cl--slot-descriptor-props slot))) ;; Output this slot if it has a customize flag associated with it. (when (and (alist-get :custom props) @@ -261,13 +262,13 @@ Optional argument IGNORE is an extraneous parameter." (or (eieio--class-slot-initarg (eieio--object-class obj) - (car slots)) - (car slots))))) + sname) + sname)))) (capitalize (if (string-match "^:" s) (substring s (match-end 0)) s))))) - :value (slot-value obj (car slots)) + :value (slot-value obj sname) :doc (or (alist-get :documentation props) "Slot not Documented.") :eieio-custom-visibility 'visible commit b096be2aa8f2eeaef12cb4e19994f40ab85a342c Author: Nicolas Petton Date: Tue May 5 20:39:40 2015 +0200 * lisp/emacs-lisp/seq.el (seq--make-bindings): Improve the docstring. diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index d22bbc5..ea7a613 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -351,7 +351,7 @@ This is an optimization for lists in `seq-take-while'." '("\\" "\\"))) (defun seq--make-bindings (args seq &optional initial-bindings) - "Return an alist of the bindings the variables in ARGS to the elements of SEQ. + "Return an alist of bindings of the variables in ARGS to the elements of SEQ. if INITIAL-BINDINGS is non-nil, append new bindings to it, and return INITIAL-BINDINGS." (let ((index 0)) commit 755045e1eb27703a117e74bd5047928795f4a4e9 Author: Dmitry Gutov Date: Tue May 5 15:28:41 2015 +0300 Work around "Attempt to modify read-only object" * lisp/progmodes/elisp-mode.el (elisp--xref-format): Extract from elisp--xref-find-definitions, to work around "Attempt to modify read-only object" error. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index f085dcf..dac807e 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -628,12 +628,15 @@ It can be quoted, or be inside a quoted form." (setq file (substring file 0 -1))) (xref-make-elisp-location sym type file)))) +(defvar elisp--xref-format + (let ((str "(%s %s)")) + (put-text-property 1 3 'face 'font-lock-keyword-face str) + (put-text-property 4 6 'face 'font-lock-function-name-face str) + str)) + (defun elisp--xref-find-definitions (symbol) (save-excursion - (let ((fmt "(%s %s)") - lst) - (put-text-property 1 3 'face 'font-lock-keyword-face fmt) - (put-text-property 4 6 'face 'font-lock-function-name-face fmt) + (let (lst) (dolist (type '(feature defface defvar defun)) (let ((loc (condition-case err @@ -642,7 +645,7 @@ It can be quoted, or be inside a quoted form." (xref-make-bogus-location (error-message-string err)))))) (when loc (push - (xref-make (format fmt type symbol) + (xref-make (format elisp--xref-format type symbol) loc) lst)))) lst))) commit fbe7fb054755b9bfe1375691d3c774cb84236859 Author: Dmitry Gutov Date: Tue May 5 15:11:14 2015 +0300 Only skip some variables that have function counterparts * lisp/progmodes/elisp-mode.el (elisp--xref-identifier-location): Only skip minor-mode-named variable if it's defined in a Lisp file, and it's in minor-mode-list (bug#20506). * test/automated/elisp-mode-tests.el (elisp-xref-finds-both-function-and-variable) (elisp-xref-finds-only-function-for-minor-mode): New tests. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 4056151..f085dcf 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -604,12 +604,16 @@ It can be quoted, or be inside a quoted form." (setq sym (car fun-lib)) (cdr fun-lib)))) (`defvar (and (boundp sym) - ;; Don't show minor modes twice. - ;; TODO: If TYPE ever becomes dependent on the - ;; context, move this check outside. - (not (fboundp sym)) - (or (symbol-file sym 'defvar) - (help-C-file-name sym 'var)))) + (let ((el-file (symbol-file sym 'defvar))) + (if el-file + (and + ;; Don't show minor modes twice. + ;; TODO: If TYPE ever becomes dependent on the + ;; context, move this check outside. + (not (and (fboundp sym) + (memq sym minor-mode-list))) + el-file) + (help-C-file-name sym 'var))))) (`feature (and (featurep sym) ;; Skip when a function with the same name ;; is defined, because it's probably in the diff --git a/test/automated/elisp-mode-tests.el b/test/automated/elisp-mode-tests.el index bfecfe7..7af6dfc 100644 --- a/test/automated/elisp-mode-tests.el +++ b/test/automated/elisp-mode-tests.el @@ -22,6 +22,9 @@ ;;; Code: (require 'ert) +(require 'xref) + +;;; Completion (defun elisp--test-completions () (let ((data (elisp-completion-at-point))) @@ -101,5 +104,26 @@ (should (member "backup-buffer" comps)) (should-not (member "backup-inhibited" comps))))) +;;; Navigation + +(ert-deftest elisp-xref-finds-both-function-and-variable () + ;; "system-name" is both: a variable and a function + (let ((defs (elisp-xref-find 'definitions "system-name"))) + (should (= (length defs) 2)) + (should (string= (xref--xref-description (nth 0 defs)) + "(defun system-name)")) + (should (string= (xref--xref-description (nth 1 defs)) + "(defvar system-name)"))) + ;; It's a minor mode, but the variable is defined in buffer.c + (let ((defs (elisp-xref-find 'definitions "abbrev-mode"))) + (should (= (length defs) 2)))) + +(ert-deftest elisp-xref-finds-only-function-for-minor-mode () + ;; Both variable and function are defined in the same place. + (let ((defs (elisp-xref-find 'definitions "visible-mode"))) + (should (= (length defs) 1)) + (should (string= (xref--xref-description (nth 0 defs)) + "(defun visible-mode)")))) + (provide 'elisp-mode-tests) ;;; elisp-mode-tests.el ends here commit c856843f6b83d4578e7fab3d9821802f2a542540 (refs/remotes/origin/seq-let) Author: Nicolas Petton Date: Fri May 1 19:30:56 2015 +0200 New macro seq-let, providing destructuring support to seq.el * lisp/emacs-lisp/seq.el (seq-let): New macro. `seq-let' is similar to `cl-destructuring-bind' but works on all sequence types supported by `seq.el'. Bump version number to 1.6. * test/automated/seq-tests.el: Add tests for seq-let. * doc/lispref/sequences.texi: Add documentation for seq-let. diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index b48fae4..e58f039 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -797,6 +797,33 @@ vector or string (@pxref{Iteration} for more information about the @code{dolist} macro). This is primarily useful for side-effects. @end defmac +@defmac seq-let arguments sequense body@dots{} +@cindex sequence destructuring + This macro binds the variables in defined in the sequence +@var{arguments} to the elements of the sequence @var{sequence}. +@var{arguments} can itself include sequences allowing for nested +destructuring. + +@example +@group +(seq-let [first second] [1 2 3 4] + (list first second)) +@result{} (1 2) +@end group +@group +(seq-let (_ a _ b) '(1 2 3 4) + (list a b)) +@result{} (2 4) +@end group +@group +(seq-let [a [b [c]]] [1 [2 [3]]] + (list a b c)) +@result{} (1 2 3) +@end group +@end example +@end defmac + + @node Arrays @section Arrays @cindex array diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 2f3f519..d22bbc5 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -4,7 +4,7 @@ ;; Author: Nicolas Petton ;; Keywords: sequences -;; Version: 1.5 +;; Version: 1.6 ;; Package: seq ;; Maintainer: emacs-devel@gnu.org @@ -40,6 +40,10 @@ ;; ;; All functions are tested in test/automated/seq-tests.el +;;; TODO: + +;; - Add support for &rest in the argument list of seq-let + ;;; Code: (defmacro seq-doseq (spec &rest body) @@ -65,6 +69,14 @@ Evaluate BODY with VAR bound to each element of SEQ, in turn. (pop ,index)))) ,@body))))) +(defmacro seq-let (args seq &rest body) + "Bind the variables in ARGS to the elements of SEQ then evaluate BODY." + (declare (indent 2) (debug t)) + (let ((seq-var (make-symbol "seq"))) + `(let* ((,seq-var ,seq) + ,@(seq--make-bindings args seq-var)) + ,@body))) + (defun seq-drop (seq n) "Return a subsequence of SEQ without its first N elements. The result is a sequence of the same type as SEQ. @@ -336,7 +348,30 @@ This is an optimization for lists in `seq-take-while'." (defun seq--activate-font-lock-keywords () "Activate font-lock keywords for some symbols defined in seq." (font-lock-add-keywords 'emacs-lisp-mode - '("\\"))) + '("\\" "\\"))) + +(defun seq--make-bindings (args seq &optional initial-bindings) + "Return an alist of the bindings the variables in ARGS to the elements of SEQ. +if INITIAL-BINDINGS is non-nil, append new bindings to it, and +return INITIAL-BINDINGS." + (let ((index 0)) + (seq-doseq (name args) + (if (sequencep name) + (setq initial-bindings (seq--make-bindings + (seq--elt-safe args index) + `(seq--elt-safe ,seq ,index) + initial-bindings)) + (push `(,name (seq--elt-safe ,seq ,index)) initial-bindings)) + (setq index (1+ index))) + initial-bindings)) + +(defun seq--elt-safe (seq n) + "Return element of SEQ at the index N. +If no element is found, return nil." + (when (or (listp seq) + (and (sequencep seq) + (> (seq-length seq) n))) + (seq-elt seq n))) (defalias 'seq-copy #'copy-sequence) (defalias 'seq-elt #'elt) diff --git a/test/automated/seq-tests.el b/test/automated/seq-tests.el index 7f6e06c..e1e8ae0 100644 --- a/test/automated/seq-tests.el +++ b/test/automated/seq-tests.el @@ -276,5 +276,22 @@ Evaluate BODY for each created sequence. (v2 [2 4 6])) (should (seq-empty-p (seq-difference v1 v2))))) +(ert-deftest test-seq-let () + (with-test-sequences (seq '(1 2 3 4)) + (seq-let (a b c d e) seq + (should (= a 1)) + (should (= b 2)) + (should (= c 3)) + (should (= d 4)) + (should (null e)))) + (let ((seq '(1 (2 (3 (4)))))) + (seq-let (_ (_ (_ (a)))) seq + (should (= a 4)))) + (let (seq) + (seq-let (a b c) seq + (should (null a)) + (should (null b)) + (should (null c))))) + (provide 'seq-tests) ;;; seq-tests.el ends here