+++ /dev/null
-(((24 1)
- (functions
- (removed *table--cell-conter-region ad-Orig-gdb-invalidate-frames ad-define-subr-args ad-get-subr-args ad-subr-arglist ad-subr-args-defined-p ad-undefine-subr-args ada-after-change-function ada-handle-syntax-table-properties ada-initialize-syntax-table-properties ada-set-syntax-table-properties allout-auto-save-hook-handler allout-create-encryption-passphrase-verifier allout-encrypted-key-info allout-get-encryption-passphrase-verifier allout-obtain-passphrase allout-setup-mode-map allout-update-passphrase-mnemonic-aids allout-verify-passphrase allout-write-file-hook-handler auth-source-forget-user-or-password auth-source-pick auth-soubmail-refresh-redirect webmail-setdefault webmail-url webmail-url-confirmation-func webmail-yahoo-article webmail-yahoo-list webmail-yahoo-login webmail-yahoo-open widget-color-complete widget-default-complete widget-file-complete widget-string-complete with-progress-reporter with-timeout-handler x-frob-font-slant x-frob-font-weight x-get-cut-buffer x-make-font-bold x-make-font-bold-italic x-make-font-demibold x-make-font-italic x-make-font-oblique x-make-font-unbold x-make-font-unitalic x-menu-activate x-menu-add-item x-menu-change-associated-buffer x-menu-create-menu x-menu-delete-item x-menu-mode x-menu-pick-entry x-set-cut-buffer x-setup-function-keys)
- (added *table--cell-center-region 5x5-defvar-local 5x5-grid-to-vec 5x5-log 5x5-log-init 5x5-solve-rotate-left 5x5-solotal-height window-total-size window-total-width window-use-time window-valid-p window-with-parameter with-buffer-modified-unmodified with-org-lparse-preserve-paragraph-state woman-bookmark-jump woman-bookmark-make-record word-search-regexp x-dnd-more-than-3-from-flags x-dnd-version-from-flags xmodmap-generic-mode xselect--encode-string xselect-convert-to-save-targets y-or-n-minibuffer))
- (variables
- (removed --dolist-tail-- --dotimes-limit-- :auto-postamble :auto-preamble :complete :completion-alist :completion-ignore-case :for-LaTeX :for-ascii :for-docbook :for-html :lables-face :opt :postamble :prop :searchhead :sqli-connect :sqli-prompt-length :sqli-prompt-regexp :ssl :startup :tostring OOOOscore OOOscore OOscore O;webmail-trash-url webmail-type webmail-type-definition webmail-variables webmail-version widget-complete-field x-alternatives-map x-menu-assoc-buffer x-menu-item-spacing x-menu-item-width x-menu-items-alist x-menu-items-per-line x-menu-max-width x-select-enable-clipboard)
- (added *org-babel-use-quick-and-dirty-noweb-expansion* *org-bibtex-entries* 5x5-solver-output :=key= :=type= :R-dev-args :aborted-p :actions :actual-position :added :after-hook :alias-table :alt :always-active :always-query-capabilities :anchor :any :app-icon :app-name :article :attributes :auto-sitemap :backend :backtrace :bail :beamer-frame-level :beamer-header-extra :begin-marker :bg :bgcolor :binddn :binding :bmp :body :body-brevity-p :body-end afe-min-height window-safe-min-width window-sides window-sides-slots window-sides-vertical window-state-put-list))
- (features
- (removed cl-19 earcon eieio-comp emacs-lock esh-test font-setting gdb-ui gnus-audio gnus-move gnus-nocem gnus-soup imap-hash mldrag nndb nnkiboze nnlistserv nnslashdot nnsoup nnultimate nnwarchive nnwfm rnews rnewspost sc tramp-fish tramp-imap webmail x-menu)
- (added allout-widgets bookmark cc-guess cconv cfengine3 color cus-theme desktop ert ert-x filesets gdb-mi gnus-gravatar gnus-html gnus-registry gnus-sync gnutls gravatar gssapi ido image-dired network-stream nnregistry ;shr-color soap-client soap-inspect tabulated-list tramp-loaddefs tramp-sh url-future url-queue)))
- ((24 2)
- (functions
- (removed)
- (added rcirc-split-message))
- (variables
- (removed)
- (added))
- (features
- (removed)
- (added bug-reference misearch multi-isearch)))
- ((24 3)
- (functions
- (removed Buffer-menu-buffer+size Buffer-menu-make-sort-button Buffer-menu-revert-function Buffer-menu-sonnection-property with-file-property xml-parse-fragment xscheme-modeline-initialize zone-hiding-modeline)
- (added Buffer-menu--pretty-file-name Buffer-menu--pretty-name Buffer-menu-info-node-description ange-ftp-ignore-errors-if-non-essential ansi-color--find-face ansi-color-parse-sequence archive-extract-by-file auth-source--aget auth-source--aput auth-source--aput-1 auth-source-backend-list-p auth-source-macos-keychain-create auth-source-macos-keychain-result-append auth-source-macos-keychain-search auth-source-macos-keychain-search-items autoload-do-load autoloadp bbdb-buffer bbdb-create-internal bbdb-gethash bindings--define-key bovine-grammar-mode buffer-narrowed-p byte-compile--reify-function byte-compile-abbreviate-file c-debug-parse-state-double-cons c-state-maybe-marker cal-tex-cursor-week2-summaruence-1006 xterm-mouse-translate-1 xterm-mouse-translate-extended yank-handle-category-property yank-handle-font-lock-face-property zone-hiding-mode-line))
- (variables
- (removed *gensym-counter* *org-bibtex-entries* *random-state* :continue :prompt-time Buffer-menu--buffers Buffer-menu-buffer-column Buffer-menu-short-ellipsis Buffer-menu-sort-button-map Buffer-menu-sort-column Info-next-link-keymap Info-prev-link-keymap Info-up-link-keymap Man-overstrike-face Man-refpages-alist Man-reverse-face Man-sections-alist Man-underline-face activate-menubar-hook apropos-keybinding-face apropos-label-face apropos-property-face apropos-symbol-face autoload-make-program byte-debug-flag bytecomp-load-hook check-markers-debug-flag cl-active-block-names cl-compiling-file&nl-5-face rst-level-6-face rst-level-face-base-color rst-level-face-base-light rst-level-face-format-light rst-level-face-max rst-level-face-step-light rst-mode-lazy rst-new-decoration-down rst-re-bullets rst-re-items rst-section-text-regexp rst-shift-fill-region rst-toc-return-buffer rst-use-char-classes sc-version scoped-class sha1-program term-bold-attribute term-completion-menu term-inout-menu this tramp-default-password-end-of-line unread-command-char url-cookie-two-dot-domains vc-bzr-error-regex-alist vc-bzr-sha1-program vc-checkout-carefully vc-ignore-vc-files vc-master-templates vhdl-93-attributes vhdl-93-enum-values vhdl-93-functions vhdl-93-keywords vhdl-93-packages vhdl-93-types xml-name-regexp)
- (added :action-items :addlevel :allow-list :allow-replacement&;verilog-before-save-font-hook verilog-save-font-mod-hooked verilog-warn-fatal vhdl-02-attributes vhdl-02-enum-values vhdl-02-functions vhdl-02-keywords vhdl-02-packages vhdl-02-types vhdl-ams-constants vhdl-array-index-record-field-in-sensitivity-list vhdl-comment-display-line-char vhdl-compile-absolute-path vhdl-compile-post-command vhdl-constants-regexp vhdl-indent-comment-like-next-code-line vhdl-makefile-default-targets wdired-keep-marker-rename winner-mode-off-hook x-last-selected-text xml-default-ns xml-entity-expansion-limit xml-entity-or-char-ref-re xml-parameter-entity-alist yank-handled-properties))
- (features
- (removed org-install python-21 reftex-vcr)
- (added cl-lib cl-macs erc-desktop-notifications gnus-notifications gv mm-archive ob-io ob-scala org-element org-loaddefs org-version profiler url-domsuf w32-common-fns)))
- ((24 4)
- (functions
- (removed Command-history-setup ad-Orig-copy-region-as-kill ad-Orig-create-file-buffer ad-Orig-dnd-insert-text ad-Orig-dnd-open-file ad-Orig-find-tag ad-Orig-idlwave-shell-electric-debug-mode ad-Orig-newline ad-Orig-org-format-latex-as-mathml ad-Orig-outline-end-of-subtree ad-Orig-rename-buffer ad-Orig-save-place-find-file-hook ad-Orig-server-visit-files ad-Orig-visit-tags-table ad-Orig-yank ad-activate-internal-off ad-advised-definition-p ad-clear-orig-definition ad-handle-definition ad-macro-p ad-make-advised-definition-docstring ad-make-advised-docstring ad-make-freeze-definition ad-make-fr-oracle-show-reserved-words sql-read-passwd sql-signum sql-try-completion text-clone-maintain thumbs-gensym trace-call-tree trace-unsafe trace-use-tree tramp-cleanup tramp-compat-call-process tramp-detect-ssh-controlmaster tramp-sh-handle-call-process-region tramp-sh-handle-executable-find tramp-sh-handle-make-auto-save-file-name universal-argument-minus universal-argument-other-key untranslated-canonical-name untranslated-file-p vc-process-sentinel verilog-get-beg-of-defun verilog-get-list verilog-sk-uvm-class verilog-type-completion vhdl-mode-syntax-table-init viper-envelop-ESC-key widget-remove-if winner-hook-installed-p with-org-lparse-preserve-paragraph-state woman-mark-horizonal-position xmltok-add-dependent xmltok-semi-closed-reparse-p xmltok-unclosed-reparse-p xterm-mouse-event-read)
- (added&nbnbsp;xesam-get-property xesam-highlight-string xesam-kill-buffer-function xesam-minor-mode xesam-mode xesam-new-search xesam-refresh-entry xesam-refresh-search-buffer xesam-search-engines xesam-set-cached-property xesam-set-property xesam-signal-handler zlib-available-p zlib-decompress-region))
- (variables
- (removed *org-babel-use-quick-and-dirty-noweb-expansion* :LaTeX :LaTeX-fragments :TeX-macros :add-text :addlevel :agenda-style :archived-trees :author-info :auto-index :beamer-frame-level :buffer-will-be-killed :choice-function :clock :convert-org-links :creator-info :customtime :docbook :drawers :effective-date :email-info :emph-multiline :expand-quoted-html :fixed-width :footnotes :for-backend :hrule :html-table-tag&nbnbsp;sieve-manage-stream-alist sieve-manage-streams sql-output-by-send thing-at-point-url-regexp tramp-completion-file-name-regexp-url tramp-file-name-regexp-url tramp-message-show-progress-reporter-message universal-argument-num-events vc-diff-knows-L verilog-mode-release-date vhdl-speedbar-key-map whitespace-font-lock whitespace-font-lock-mode xmltok-dependent-regions)
- (added *org-babel-gnuplot-missing* *org-babel-gnuplot-terms* 5x5-mode-abbrev-table 5x5-mode-syntax-table :ALT_TITLE :APPENDIX :APPT_WARNTIME :BEAMER_ACT :BEAMER_COL :BEAMER_ENV :BEAMER_OPT :BEAMER_REF :CATEGORY :COPYING :CUSTOM_ID :DESCRIPTION :HTML_CONTAINER :HTML_CONTAINER_CLASS :ICALENDAR-MARK :ID :INDEX :LOCATION :ORDERED :SUMMARY :after-until :after-while :align :alt-title :always bus-unique-names xesam-engine xesam-minibuffer-query-history xesam-minibuffer-vendor-history xesam-minor-mode xesam-minor-mode-hook xesam-mode-abbrev-table xesam-mode-hook xesam-mode-map xesam-mode-syntax-table xesam-notify-function xesam-objects xesam-query xesam-refreshing xesam-search xesam-search-engines xesam-to xesam-type xesam-vendor xesam-xml-string xterm-mouse-mode-hook))
- (features
- (removed advice-preload delphi find-gc octave-inf octave-mod org-ascii org-beamer org-docbook org-exp org-exp-blocks org-export-latex org-freemind org-html org-icalendar org-infojs org-jsinfo org-latex org-lparse org-mac-message org-mew org-mks org-odt org-publish org-remember org-special-blocks org-taskjuggler org-vm org-wl org-xoxo)
- (added bat-mode cl-indent cl-loaddefs cus-dep dos-vars eieio-core elec-pair em-tramp erc-list eudcb-bbdb eww filenotify frameset gnus-icalendar gnus-vm inotify nadvice ob-core ob-makefile octave opascal org-macro ox ox-ascii ox-beamer ox-html ox-icalendar ox-latex ox-man ox-md ox-odt ox-org ox-publish ox-texinfo pcmpl-x prog-mode smiley subr-x sup-mouse superword tpu-extras tramp-adb xesam)))
- ((24 5)
- (functions
- (removed browse-url-firefox-sentinel cua-repeat-replace-region python-indent-toggle-levels tramp-time-less-p tramp-time-subtract)
- (added c--macroexpand-all c-macro-is-genuine-p delete-selection-repeat-replace-region erc-channel-user-admin erc-channel-user-admin-p erc-channel-user-halfop erc-channel-user-halfop-p erc-channel-user-owner erc-channel-user-owner-p erc-get-user-mode-prefix erc-quit/part-reason-default file-notify--descriptor python-indent--calculate-indentation python-indent--calculate-levels python-indent--previous-level python-info-encoding python-info-encoding-from-cookie python-syntax-closing-paren-p reftex--prepare-syntax-tables todo-revert-buffer))
- (variables
- (removed cua--last-deleted-region-pos cua--last-deleted-region-text cua--repeat-replace-text ispell-hunspell-dictionary-equivs-alist python--use-fake-loc)
- (added :admin :after-backslash :after-backslash-assignment-continuation :after-backslash-block-continuation :after-backslash-dotted-continuation :after-backslash-first-line :after-block-end :after-block-start :after-comment :after-line :at-dedenter-block-start :halfop :inside-paren :inside-paren-at-closing-nested-paren :inside-paren-at-closing-paren :inside-paren-newline-start :inside-paren-newline-start-from-block :inside-string :no-indent :owner delete-selection-save-to-register delsel--replace-text-or-position erc-rename-buffers ispell-dicts-name2locale-equivs-alist mml2015-display-key-image python-shell-unbuffered vc-hg-log-graph))
- (features
- (removed)
- (added cl-extra)))
- ((25 1)
- (functions
- (removed ada-convert-file-name add-to-diary-list american-calendar authors authors-add authors-add-fixed-entries authors-add-to-author-list authors-canonical-author-name authors-canonical-file-name authors-disambiguate-file-name authors-lax-changelog-p authors-no-scan-file-p authors-obsolete-file-p authors-public-domain-p authors-scan-change-log authors-scan-el batch-update-authors byte-compile-file-form-define-abbrev-table byte-compile-track-mouse byte-optimize-zerop c-change-set-fl-decl-start c-context-set-fl-decl-start c-set-fl-decl-start calc-distance-of-robot-from calc-smell-internal calculator-curnum-value calculator-get-prompt calculator-integer-p calendar-absolute-from-astro calendar-absolute-from-bahai calendar-absolute-from-chinese calendar-absolute-from-coptic calendar-absolute-from-ethisp;view-other-diary-entries w3-parse-buffer w32-using-nt w32-version window--even-window-heights window--size-ignore-p window-split-min-size woman-mapcan would-be-symbol x-selection-owner-p x-valid-simple-selection-p xterm-mouse--read-event-sequence-1000 xterm-mouse--read-event-sequence-1006)
- (added \(setf\ ede-object-keybindings\) \(setf\ ede-object-menu\) \(setf\ ede-object-sourcecode\) \(setf\ gnus-icalendar-event:description\) \(setf\ gnus-icalendar-event:end-time\) \(setf\ gnus-icalendar-event:location\) \(setf\ gnus-icalendar-event:method\) \(setf\ gnus-icalendar-event:opt-participants\) \(setf\ gnus-icalendar-event:organizer\) \(setf\ gnus-icalendar-event:participation-type\) \(setf\ gnus-icalendar-event:recur\) \(setf\ gnus-icalendar-event:req-participants\) \(setf\ gnselection-as-kill xwidget-webkit-current-session xwidget-webkit-current-url xwidget-webkit-end-edit-textarea xwidget-webkit-execute-script-rv xwidget-webkit-fit-width xwidget-webkit-get-selection xwidget-webkit-goto-url xwidget-webkit-insert-string xwidget-webkit-last-session xwidget-webkit-mode xwidget-webkit-new-session xwidget-webkit-reload xwidget-webkit-scroll-backward xwidget-webkit-scroll-down xwidget-webkit-scroll-forward xwidget-webkit-scroll-up xwidget-webkit-show-id-element xwidget-webkit-show-id-or-named-element xwidget-webkit-show-named-element zerop--anon-cmacro))
- (variables
- (removed :PRIMARY :STATIC :bgcolor :changed :cols :colspan :cowrote :disabled :element-type :fc-unknown-spec :fgcolor :href :nillable\? :poster :rel :rowspan&nblt-init-revision vc-disable-async-diff vc-keep-workfiles vc-mcvs-diff-switches vc-mcvs-global-switches vc-mcvs-header vc-mcvs-register-switches vc-mcvs-use-edit vc-mistrust-permissions vc-stay-local view-calendar-holidays-initially view-diary-entries-initially window-system-initialization-alist x-last-selected-text)
- (added :alternatives :append :argument-precedence-order :async :attribute-groups :authors :certificate :certificate-security-level :cipher :cl--generic--under-construction :cleanup :close :combining-capability :comment :compiled :conditions :connection-type :current-file :def :diffie-hellman-prime-bits :do :error-form :eww-readability-score :fingerprint :from-end :full :get-finalizer :hashmap :history :home :if :if-not :indicp xwidget-webkit-mode-syntax-table))
- (features
- (removed authors gnus-setup vc-mcvs w32-common-fns)
- (added bruce char-fold charscript cl-generic cl-preloaded cl-seq cp51932 cursor-sensor dom ede/detect eieio-compat elisp-mode eucjp-ms generator gnus-cloud inline let-alist map nsm obarray pinentry project sasl-scram-rfc sasl-scram-sha-1 seq thunk url-tramp vc-filewise vc-src xref xwidget)))
- ((25 2)
- (functions
- (removed electric--insertable-p)
- (added term--xterm-paste tex-handle-newline))
- (variables
- (removed)
- (added inhibit-compacting-font-caches))
- (features
- (removed)
- (added)))
- ((25 3)
- (functions
- (removed)
- (added))
- (variables
- (removed)
- (added))
- (features
- (removed)
- (added)))
- ((26 1)
- (functions
- &nbcontents-literally tramp-user-error undo-auto--undoable-change-no-timer url-cookie-quit verilog-save-font-mods verilog-save-no-change-functions whitespace-ensure-local-variables window--major-non-side-window window--major-side-window window--side-check window--side-window-p window-dot woman-pop woman-push xmltok-forward-special xwidget-webkit-execute-script-rv y-or-n-minibuffer)
- (added Buffer-menu-unmark-all Buffer-menu-unmark-all-buffers Info-node-description ad-Advice-exchange-point-and-mark ad-Advice-pop-global-mark ad-Advice-pop-to-mark-command ad-Advice-xref-find-definitions add-variable-watcher advice--where all-threads allout-count-trailing-whitespace-region allout-nullify-prefix-data allout-produce-mode-menubar-entries allout-regexp-sans-escapes allout-set-regexp allout-solicit-char-in-string profiles with-mutex xdg--dir-home xdg--substitute-home-env xdg--user-dirs-parse-file xdg--user-dirs-parse-line xdg-cache-home xdg-config-dirs xdg-config-home xdg-data-dirs xdg-data-home xdg-desktop-read-file xdg-desktop-read-group xdg-desktop-strings xdg-runtime-dir xdg-thumb-mtime xdg-thumb-name xdg-thumb-uri xdg-user-dir xref--regexp-syntax-dependent-p xref-quit-and-goto-xref xwidget-webkit-adjust-size-in-frame xwidget-webkit-auto-adjust-size xwidget-webkit-scroll-bottom xwidget-webkit-scroll-top xwidget-webkit-show-element xwidget-webkit-zoom-in xwidget-webkit-zoom-out))
- (variables
- (removed *orgtbl-default-fmt* *orgtbl-efmt* *orgtbl-fmt* *orgtbl-hline* *orgtbl-lend* *orgtbl-lfmt* *orgtbl-llend* *orgtbl-llfmt* *orgtbl-llstart* *orgtbl-lsta-cache syntax-ppss-last tex-math-face tex-verbatim-face texinfo-heading-face time-stamp-old-format-warn tramp-color-escape-sequence-regexp tramp-completion-file-name-regexp-unified tramp-file-name-regexp-separate tramp-file-name-regexp-unified tramp-gw-aux-proc tramp-gw-default-socks-port tramp-gw-default-tunnel-port tramp-gw-gw-proc tramp-gw-gw-vector tramp-gw-socks-method tramp-gw-tunnel-method tramp-gw-vector tramp-obsolete-methods tramp-parse-time-months tramp-rfn-eshadow-update-overlay-regexp tramp-warned-obsolete-methods verilog-font-grouping-keywords-face viper-buffer-undo-list-mark viper-undo-needs-adjustment whitespace-indent-tabs-mode whitespace-tab-width window-sides window-text-change-functions woman-justify-list xref--window)
- (added :--found :--map-first-match :TIMEZONE :UNNUMBERED&nc-hg--dirstate-scan-cache vc-hg--elisp-metacharacters vc-hg--pcre-c-escapes vc-hg--pcre-metacharacters vc-hg-parse-hg-data-structures vc-hg-supported-requirements vc-hg-symbolic-revision-styles vc-hg-use-file-version-for-mode-line-version vc-revision-history verilog-auto-inst-param-value-type verilog-auto-wire-comment verilog-default-clocking-re verilog-diff-ignore-regexp verilog-font-lock-grouping-keywords-face viper--advice-list viper--undo-change-group-handle wdired-create-parent-directories while-no-input-ignore-events window--sides-inhibit-check window--sides-shown window-sides-reversed woman-justify-styles woman-mode-abbrev-table woman-mode-hook woman-mode-syntax-table xdg-desktop-entry-regexp xdg-desktop-group-regexp xdg-line-regexp xdg-user-dirs xref--original-window xref--original-window-intent))
- (features
- (removed awk-mode gnus-ems gnus-sync iso-acc iso-insert iso-swed messcompat mh-acros nxml-glyph nxml-uchnm ob-scala ob-sh pinentry resume scribe spell swedish sym-comp tramp-gw)
- (added auth-source-pass charprop cl-print composite dired-loaddefs display-line-numbers eieio-loaddefs flymake-proc gnus-rfc1843 htmlfontify-loaddefs ibuffer-loaddefs isearch less-css-mode mhtml-mode ob-J ob-abc ob-coq ob-ebnf ob-forth ob-groovy ob-hledger ob-lua ob-processing ob-sed ob-shell ob-stan ob-vala org-duration org-eww org-lint pixel-scroll ps-print-loaddefs puny radix-tree reftex-loaddefs replace rmail-loaddefs rmc svg term/tty-colors text-mode timer-list xdg)))
- ((26 2)
- (functions
- (removed dired--yes-no-all-quit-help shadow-get-user shadow-make-cluster shadow-parse-fullname)
- (added assoc-delete-all calc-graph-w32-p copy-shadow-cluster ibuffer-do-toggle-lock make-shadow-cluster make-shadow-cluster--cmacro package--user-installed-p read-answer shadow-cluster-name--cmacro shadow-cluster-p shadow-cluster-p--cmacro shadow-cluster-primary--cmacro shadow-cluster-regexp--cmacro shadow-name-site shadow-site-name soap-type-of term--bash-needs-EMACSp term-watch-for-password-prompt thread-live-p))
- (variables
- (removed dired-delete-help last--line-number-width prolog-hungry-delete-key-flag)
- (added byte-compile--default-val cl-print--depth cl-struct-shadow-cluster-tags ido-fallback read-answer-map--memoize read-answer-short term--bash-needs-EMACS-status xft-ignore-color-fonts))
- (features
- (removed)
- (added threads)))
- ((26 3)
- (functions
- (removed gnus-summary-sort-by-mark)
- (added dir-locals--get-sort-score dir-locals--sort-variables gnus-summary-sort-by-marks package--buffer-string package--cs))
- (variables
- (removed)
- (added help-enable-completion-auto-load))
- (features
- (removed)
- (added))))
+++ /dev/null
-;;; package-lint-autoloads.el --- automatically extracted autoloads
-;;
-;;; Code:
-(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
-\f
-;;;### (autoloads nil "package-lint" "package-lint.el" (23994 46389
-;;;;;; 955377 139000))
-;;; Generated autoloads from package-lint.el
-
-(autoload 'package-lint-buffer "package-lint" "\
-Get linter errors and warnings for BUFFER.
-
-Returns a list, each element of which is list of
-
- (LINE COL TYPE MESSAGE)
-
-where TYPE is either 'warning or 'error.
-
-Current buffer is used if none is specified.
-
-\(fn &optional BUFFER)" nil nil)
-
-(autoload 'package-lint-current-buffer "package-lint" "\
-Display lint errors and warnings for the current buffer.
-
-\(fn)" t nil)
-
-(autoload 'package-lint-batch-and-exit "package-lint" "\
-Run `package-lint-buffer' on the files remaining on the command line.
-Use this only with -batch, it won't work interactively.
-
-When done, exit Emacs with status 0 if there were no errors nor warnings or 1
-otherwise.
-
-\(fn)" nil nil)
-
-(autoload 'package-lint-looks-like-a-package-p "package-lint" "\
-Return non-nil if the current buffer appears to be intended as a package.
-
-\(fn)" nil nil)
-
-;;;***
-\f
-;;;### (autoloads nil nil ("package-lint-pkg.el") (23994 46389 959182
-;;;;;; 422000))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; End:
-;;; package-lint-autoloads.el ends here
+++ /dev/null
-(define-package "package-lint" "20191027.20" "A linting library for elisp package authors"
- '((cl-lib "0.5")
- (emacs "24.1")
- (let-alist "1.0.6"))
- :keywords
- '("lisp")
- :authors
- '(("Steve Purcell" . "steveNOSPAMsanityinc.com")
- ("Fanael Linithien" . "fanael4NOSPAMgmail.com"))
- :maintainer
- '("Steve Purcell" . "steveNOSPAMsanityinc.com")
- :url "https://github.com/purcell/package-lint")
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
+++ /dev/null
-;;; package-lint.el --- A linting library for elisp package authors -*- lexical-binding: t -*-
-
-;; Copyright (C) 2014-2019 Steve Purcell, Fanael Linithien
-
-;; Author: Steve Purcell <steveNOSPAMsanityinc.com>
-;; Fanael Linithien <fanael4NOSPAMgmail.com>
-;; URL: https://github.com/purcell/package-lint
-;; Keywords: lisp
-;; Version: 0
-;; Package-Requires: ((cl-lib "0.5") (emacs "24.1") (let-alist "1.0.6"))
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Provides a list of issues with the package metadata of a file,
-;; e.g. the package dependencies it requires.
-
-;; See function `package-lint-buffer'.
-
-;; Checks will currently be enabled only if a "Package-Requires:" or
-;; "Package-Version:" header is present in the file.
-
-;;; Code:
-
-(eval-when-compile (require 'pcase)) ; `pcase-dolist' is not autoloaded
-(require 'cl-lib)
-(require 'package)
-(require 'lisp-mnt)
-(require 'finder)
-(require 'imenu)
-(require 'let-alist)
-
-\f
-;;; Compatibility
-
-(defalias 'package-lint--package-desc-summary
- (if (fboundp 'package-desc-summary)
- 'package-desc-summary
- 'package-desc-doc))
-
-(defalias 'package-lint--package-desc-name
- (if (fboundp 'package-desc-name)
- 'package-desc-name
- (lambda (desc) (intern (elt desc 0)))))
-
-\f
-;;; Machinery
-
-(defvar package-lint--errors nil
- "List of errors and warnings for the current buffer.
-This is bound dynamically while the checks run.")
-
-(defconst package-lint-backport-libraries
- (list (cons 'cl-lib "\\`cl-")
- (cons 'cl-generic "\\`cl-\\(?:def\\)?generic")
- (cons 'cl-print "\\`cl-print")
- (cons 'map "\\`map-")
- (cons 'nadvice "\\`advice-")
- (cons 'seq "\\`seq-")
- (cons 'let-alist "\\`let-alist"))
- "A sequence of (FEATURE . SYMBOL-NAME-MATCH) for backport libraries.
-These are libraries that are built into newer Emacsen and also
-published in ELPA for use by older Emacsen.")
-
-(eval-and-compile
- (defun package-lint--match-symbols (symbols)
- "Return a predicate which take a symbol and reports whether it is among `SYMBOLS'."
- (let ((tbl (make-hash-table)))
- (dolist (s symbols)
- (puthash s t tbl))
- (lambda (v) (gethash v tbl))))
-
- (let ((stdlib-changes (with-temp-buffer
- (insert-file-contents
- (expand-file-name "data/stdlib-changes"
- (if load-file-name
- (file-name-directory load-file-name)
- default-directory)))
- (read (current-buffer)))))
-
- (defconst package-lint--libraries-added-alist
- (mapcar (lambda (version-data)
- (let ((version (car version-data))
- (added-libraries (let-alist (cdr version-data) .features.added)))
- (cons version (package-lint--match-symbols added-libraries))))
- stdlib-changes)
- "An alist of library names and when they were added to Emacs.")
-
- (defconst package-lint--libraries-removed-alist
- (mapcar (lambda (version-data)
- (let ((version (car version-data))
- (removed-libraries (let-alist (cdr version-data) .features.removed)))
- (cons version (package-lint--match-symbols removed-libraries))))
- stdlib-changes)
- "An alist of library names and when they were added to Emacs.")
-
- (defconst package-lint--functions-and-macros-added-alist
- (mapcar (lambda (version-data)
- (let ((version (car version-data))
- (added-functions (let-alist (cdr version-data) .functions.added)))
- (cons version (package-lint--match-symbols added-functions))))
- stdlib-changes)
- "An alist of function/macro names and when they were added to Emacs.")
-
- (defconst package-lint--functions-and-macros-removed-alist
- (mapcar (lambda (version-data)
- (let ((version (car version-data))
- (removed-functions (let-alist (cdr version-data) .functions.removed)))
- (cons version (package-lint--match-symbols removed-functions))))
- stdlib-changes)
- "An alist of function/macro names and when they were removed from Emacs.")))
-
-(defconst package-lint--sane-prefixes
- (rx
- string-start
- (or
- "org-dblock-write:"
- "org-babel-execute:"
- "org-babel-prep-session:"
- "org-babel-variable-assignments:"
- "org-babel-default-header-args:"
- "pcomplete/"))
- "A regexp matching whitelisted non-standard symbol prefixes.")
-
-(defun package-lint--check-all ()
- "Return a list of errors/warnings for the current buffer."
- (let ((package-lint--errors '())
- (case-fold-search nil))
- (save-match-data
- (save-excursion
- (save-restriction
- (widen)
- (package-lint--check-reserved-keybindings)
- (package-lint--check-keywords-list)
- (package-lint--check-url-header)
- (package-lint--check-package-version-present)
- (package-lint--check-lexical-binding-is-on-first-line)
- (package-lint--check-objects-by-regexp
- "(define-minor-mode\\s-"
- #'package-lint--check-minor-mode)
- (package-lint--check-objects-by-regexp
- "(define-global\\(?:ized\\)?-minor-mode\\s-"
- #'package-lint--check-globalized-minor-mode)
- (package-lint--check-objects-by-regexp
- (concat "(" (regexp-opt '("defalias" "defvaralias")) "\\s-")
- #'package-lint--check-defalias)
- (package-lint--check-objects-by-regexp
- "(defgroup\\s-" #'package-lint--check-defgroup)
- (let ((desc (package-lint--check-package-el-can-parse)))
- (when desc
- (package-lint--check-package-summary desc)
- (package-lint--check-provide-form desc)
- (package-lint--check-no-emacs-in-package-name desc)))
- (package-lint--check-no-use-of-cl)
- (package-lint--check-no-use-of-cl-lib-sublibraries)
- (package-lint--check-eval-after-load)
- (let ((deps (package-lint--check-dependency-list)))
- (package-lint--check-lexical-binding-requires-emacs-24 deps)
- (package-lint--check-libraries-available-in-emacs deps)
- (package-lint--check-libraries-removed-from-emacs)
- (package-lint--check-macros-functions-available-in-emacs deps)
- (package-lint--check-macros-functions-removed-from-emacs)
- (package-lint--check-objects-by-regexp
- (concat "(" (regexp-opt '("format" "message" "error")) "\\s-")
- (lambda (def) (package-lint--check-format-string deps def))))
- (package-lint--check-for-literal-emacs-path)
- (package-lint--check-commentary-existence)
- (let ((definitions (package-lint--get-defs)))
- (package-lint--check-autoloads-on-private-functions definitions)
- (package-lint--check-defs-prefix definitions)
- (package-lint--check-symbol-separators definitions))
- (package-lint--check-lonely-parens))))
- (sort package-lint--errors
- (lambda (a b)
- (pcase-let ((`(,a-line ,a-column ,_ ,a-message) a)
- (`(,b-line ,b-column ,_ ,b-message) b))
- (cond
- ((/= a-line b-line) (< a-line b-line))
- ((/= a-column b-column) (< a-column b-column))
- (t
- (string-lessp a-message b-message))))))))
-
-(defun package-lint--error (line col type message)
- "Construct a datum for error at LINE and COL with TYPE and MESSAGE."
- (push (list line col type message) package-lint--errors))
-
-(defun package-lint--error-at-point (type message &optional pos)
- "Construct a datum for error at POS with TYPE and MESSAGE.
-POS defaults to `point'."
- (save-excursion
- (when pos
- (goto-char pos))
- (package-lint--error (line-number-at-pos) (current-column) type message)))
-
-(defun package-lint--error-at-bol (type message)
- "Construct a datum for error at the beginning of the current line with TYPE and MESSAGE."
- (package-lint--error (line-number-at-pos) 0 type message))
-
-(defun package-lint--error-at-bob (type message)
- "Construct a datum for error at the beginning of the buffer with TYPE and MESSAGE."
- (package-lint--error 1 0 type message))
-
-\f
-;;; Checks
-
-(defun package-lint--check-reserved-keybindings ()
- "Warn about reserved keybindings."
- (let ((re (rx "(" (*? space) (or "kbd" "global-set-key" "local-set-key" "define-key") symbol-end)))
- (goto-char (point-min))
- (while (re-search-forward re nil t)
- (unless (nth 8 (save-match-data (syntax-ppss)))
- ;; Read form and get key-sequence
- (goto-char (match-beginning 0))
- (let ((seq (package-lint--extract-key-sequence
- (read (current-buffer)))))
- (when seq
- (let ((message (package-lint--test-keyseq seq)))
- (when message
- (package-lint--error-at-point 'warning message)))))))))
-
-(defun package-lint--check-commentary-existence ()
- "Warn about nonexistent or empty commentary section."
- (let ((start (lm-commentary-start)))
- (if (null start)
- (package-lint--error-at-bob
- 'error
- "Package should have a ;;; Commentary section.")
- ;; Skip over the section header.
- (goto-char start)
- (forward-line)
- (when (package-lint--region-empty-p (point) (lm-commentary-end))
- (package-lint--error-at-point
- 'error
- "Package should have a non-empty ;;; Commentary section."
- start)))))
-
-(defun package-lint--check-autoloads-on-private-functions (definitions)
- "Verify that private functions DEFINITIONS don't have autoload cookies."
- (pcase-dolist (`(,symbol . ,position) definitions)
- (when (string-match-p (rx "--") symbol)
- (goto-char position)
- (forward-line -1)
- (when (looking-at-p (rx ";;;###autoload"))
- (package-lint--error-at-point
- 'warning
- "Private functions generally should not be autoloaded.")))))
-
-(defun package-lint--check-for-literal-emacs-path ()
- "Verify package does not refer to \"\.emacs\.d\" literally.
-Instead it should use `user-emacs-directory' or `locate-user-emacs-file'."
- (goto-char (point-min))
- ;; \b won't find a word boundary between a symbol and the "." in
- ;; ".emacs.d". / is a valid symbol constituent in Emacs Lisp, so
- ;; must be explicitly blacklisted.
- (while (re-search-forward "\\(?:\\_<\\|/\\)\\.emacs\\.d\\b" nil t)
- (unless (nth 4 (syntax-ppss))
- ;; Not in a comment
- (package-lint--error-at-point
- 'warning
- "Use variable `user-emacs-directory' or function `locate-user-emacs-file' instead of a literal path to the Emacs user directory or files."))))
-
-(defun package-lint--check-keywords-list ()
- "Verify that package keywords are listed in `finder-known-keywords'."
- (when (package-lint--goto-header "Keywords")
- (let ((err-pos (match-beginning 2)))
- (let ((keywords (lm-keywords-list)))
- (unless (cl-some (lambda (keyword) (assoc (intern keyword) finder-known-keywords)) keywords)
- (package-lint--error-at-point
- 'warning
- (format "You should include standard keywords: see the variable `finder-known-keywords'.")
- err-pos))))))
-
-(defun package-lint--check-url-header ()
- "Verify that the package has an HTTPS or HTTP Homepage/URL header."
- (if (package-lint--goto-header "\\(?:URL\\|Homepage\\)")
- (let ((url (match-string 3))
- (url-start (match-beginning 3)))
- (unless (and (equal (thing-at-point 'url) url)
- (string-match-p "^https?://" url))
- (package-lint--error-at-point
- 'error
- "Package URLs should be a single HTTPS or HTTP URL."
- url-start)))
- (package-lint--error-at-bob
- 'error
- "Package should have a Homepage or URL header.")))
-
-(defun package-lint--check-dependency-list ()
- "Check the contents of the \"Package-Requires\" header.
-Return a list of well-formed dependencies, same as
-`package-lint--check-well-formed-dependencies'."
- (when (package-lint--goto-header "Package-Requires")
- (let ((position (match-beginning 3))
- (deps (match-string 3)))
- (condition-case err
- (pcase-let ((`(,parsed-deps . ,parse-end-pos) (read-from-string deps)))
- (unless (= parse-end-pos (length deps))
- (package-lint--error-at-bol
- 'error
- "More than one expression provided."))
- (let ((deps (package-lint--check-well-formed-dependencies position parsed-deps)))
- (package-lint--check-packages-installable deps)
- (package-lint--check-deps-use-non-snapshot-version deps)
- (package-lint--check-deps-do-not-use-zero-versions deps)
- (package-lint--check-do-not-depend-on-cl-lib-1.0 deps)
- deps))
- (error
- (package-lint--error-at-bol
- 'error
- (format "Couldn't parse \"Package-Requires\" header: %s" (error-message-string err)))
- nil)))))
-
-(defun package-lint--check-well-formed-dependencies (position parsed-deps)
- "Check that dependencies listed at POSITION are well-formed.
-These PARSED-DEPS must have the format (name \"version\").
-Return a list of well-formed dependencies, where each element is of
-the form (PACKAGE-NAME PACKAGE-VERSION DEP-POSITION)."
- (let (valid-deps)
- (dolist (entry parsed-deps)
- (pcase entry
- ((and `(,package-name ,package-version)
- (guard (symbolp package-name))
- (guard (stringp package-version)))
- ;; Find the column at which the dependency is declared so we can
- ;; properly report the position of errors.
- (let ((dep-pos
- (save-excursion
- (goto-char position)
- (let ((pattern
- (format "( *\\(%s\\)\\(?:)\\|[^[:alnum:]_\\-].*?)\\)"
- (regexp-quote (symbol-name package-name)))))
- (if (re-search-forward pattern (line-end-position) t)
- (match-beginning 1)
- position)))))
- (if (ignore-errors (version-to-list package-version))
- (push (list package-name
- (version-to-list package-version)
- dep-pos)
- valid-deps)
- (package-lint--error-at-point
- 'error
- (format "%S is not a valid version string: see `version-to-list'."
- package-version)
- dep-pos))))
- (_
- (package-lint--error-at-bol
- 'error
- (format "Expected (package-name \"version-num\"), but found %S." entry)))))
- valid-deps))
-
-(defun package-lint--check-package-installable (archive-entry package-version dep-pos)
- "Check that ARCHIVE-ENTRY is installable from a configured package archive.
-
-Check that package described by ARCHIVE-ENTRY can be installed at
-required version PACKAGE-VERSION. If not, raise an error for DEP-POS."
- (let* ((package-name (car archive-entry))
- (best-version (package-lint--highest-installable-version-of package-name)))
- (when (version-list-< best-version package-version)
- (package-lint--error-at-point
- 'warning
- (format "Version dependency for %s appears too high: try %s" package-name
- (package-version-join best-version))
- dep-pos))))
-
-(defun package-lint--check-packages-installable (valid-deps)
- "Check that all VALID-DEPS are available for installation."
- (pcase-dolist (`(,package-name ,package-version ,dep-pos) valid-deps)
- (if (eq 'emacs package-name)
- (unless (version-list-<= '(24) package-version)
- (package-lint--error-at-point
- 'error
- "You can only depend on Emacs version 24 or greater: package.el for Emacs 23 does not support the \"emacs\" pseudopackage."
- dep-pos))
- ;; Not 'emacs
- (let ((archive-entry (assq package-name package-archive-contents)))
- (if archive-entry
- (package-lint--check-package-installable archive-entry package-version dep-pos)
- (package-lint--error-at-point
- 'error
- (format "Package %S is not installable." package-name)
- dep-pos))))))
-
-(defun package-lint--check-deps-use-non-snapshot-version (valid-deps)
- "Warn about any VALID-DEPS on snapshot versions of packages."
- (pcase-dolist (`(,package-name ,package-version ,dep-pos) valid-deps)
- (unless (version-list-< package-version '(19001201 1))
- (package-lint--error-at-point
- 'warning
- (format "Use a non-snapshot version number for dependency on \"%S\" if possible."
- package-name)
- dep-pos))))
-
-(defun package-lint--check-deps-do-not-use-zero-versions (valid-deps)
- "Warn about VALID-DEPS on \"0\" versions of packages."
- (pcase-dolist (`(,package-name ,package-version ,dep-pos) valid-deps)
- (when (equal package-version '(0))
- (package-lint--error-at-point
- 'warning
- (format "Use a properly versioned dependency on \"%S\" if possible."
- package-name)
- dep-pos))))
-
-(defun package-lint--check-lexical-binding-requires-emacs-24 (valid-deps)
- "Warn about use of `lexical-binding' when Emacs 24 is not among VALID-DEPS."
- (goto-char (point-min))
- (when (package-lint--lexical-binding-declared-in-header-line-p)
- (unless (assq 'emacs valid-deps)
- (package-lint--error-at-point
- 'warning
- "You should depend on (emacs \"24\") if you need lexical-binding."
- (match-beginning 1)))))
-
-(defun package-lint--inside-comment-or-string-p ()
- "Return non-nil if point is inside a comment or string."
- (let ((ppss (save-match-data (syntax-ppss))))
- (or (nth 3 ppss) (nth 4 ppss))))
-
-(defun package-lint--seen-fboundp-check-for (sym)
- "Return non-nil if a `fboundp' check for SYM is present before point."
- (save-excursion
- (save-match-data
- (and (re-search-backward
- (concat "(fboundp\\s-+'" (regexp-quote sym) "\\_>") (point-min) t)
- (not (package-lint--inside-comment-or-string-p))))))
-
-(defun package-lint--map-regexp-match (regexp callback)
- "For every match of REGEXP, call CALLBACK with the first match group.
-If callback returns non-nil, the return value - which must be a
-list - will be applied to `package-lint--error-at-point'. If
-REGEXP doesn't produce a match group 1, then match group
-0 (ie. the whole match string string) will be passed to
-CALLBACK."
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward regexp nil t)
- (let ((sym (or (match-string-no-properties 1)
- (match-string-no-properties 0))))
- (save-excursion
- (goto-char (or (match-beginning 1)
- (match-beginning 0)))
- (let ((err (funcall callback sym)))
- (when err
- ;; Check this as late as possible, just before reporting,
- ;; because otherwise the checking process is extremely slow,
- ;; being bottlenecked by `syntax-ppss'.
- (unless (package-lint--inside-comment-or-string-p)
- (apply #'package-lint--error-at-point err)))))))))
-
-(defun package-lint--check-version-regexp-list (valid-deps list symbol-regexp type)
- "Warn if symbols matched by SYMBOL-REGEXP are unavailable in the target Emacs.
-The target Emacs version is taken from VALID-DEPS, which are the
-declared dependencies of this package. LIST is an alist
-of (VERSION . PRED), where PRED is passed the sym. TYPE is the
-type of the symbol, either FUNCTION or FEATURE."
- (let ((emacs-version-dep (or (cadr (assq 'emacs valid-deps)) '(0))))
- (pcase-dolist (`(,added-in-version . ,pred) list)
- (when (version-list-< emacs-version-dep added-in-version)
- (package-lint--map-regexp-match
- symbol-regexp
- (lambda (sym)
- (when (funcall pred (intern sym))
- (unless (and (eq type 'function) (package-lint--seen-fboundp-check-for sym))
- (let ((available-backport
- (cond
- ((eq type 'feature)
- (cl-some (lambda (bp)
- (when (string= (car bp) sym)
- (car bp)))
- package-lint-backport-libraries))
- ((eq type 'function)
- (cl-some (lambda (bp)
- (when (string-match-p (cdr bp) sym)
- (car bp)))
- package-lint-backport-libraries)))))
- (unless (and available-backport (assoc available-backport valid-deps))
- (list
- 'error
- (format "You should depend on (emacs \"%s\")%s if you need `%s'."
- (mapconcat #'number-to-string added-in-version ".")
- (if available-backport
- (format " or the %s package" available-backport)
- "")
- sym))))))))))))
-
-(defun package-lint--check-eval-after-load ()
- "Warn about use of `eval-after-load' and co."
- (package-lint--map-regexp-match
- "(\\s-*?\\(\\(?:with-\\)?eval-after-load\\)\\_>"
- (lambda (match)
- (list 'warning
- (format "`%s' is for use in configurations, and should rarely be used in packages." match)))))
-
-(defun package-lint--check-no-use-of-cl ()
- "Warn about use of deprecated `cl' library."
- (package-lint--map-regexp-match
- "(\\s-*?require\\s-*?'\\(cl\\)\\_>"
- (lambda (_)
- (list
- 'warning
- "Replace deprecated `cl' with `cl-lib'. The `cl-libify' package can help with this."))))
-
-(defun package-lint--check-no-use-of-cl-lib-sublibraries ()
- "Warn about use of `cl-macs', `cl-seq' etc."
- (package-lint--map-regexp-match
- "(\\s-*?require\\s-*?'\\(cl-macs\\|cl-seq\\)\\_>"
- (lambda (_)
- (list
- 'warning
- "This file is not in the `cl-lib' ELPA compatibility package: require `cl-lib' instead."))))
-
-(defconst package-lint--unconditional-require-regexp
- ;; Match the ending paren so we can be sure it's a single argument
- ;; `require'. If there are additional arguments, we don't want to warn,
- ;; because (require 'foo nil t) indicates an optional dependency and
- ;; (require 'foo "filename") is very uncommon.
- "(\\s-*?require\\s-*?'\\_<\\(.*?\\)\\_>\\s-*?)"
- "Regexp to match unconditional `require' forms.")
-
-(defun package-lint--check-libraries-available-in-emacs (valid-deps)
- "Warn about use of libraries that are not available in the Emacs version in VALID-DEPS."
- (package-lint--check-version-regexp-list
- valid-deps
- package-lint--libraries-added-alist
- package-lint--unconditional-require-regexp
- 'feature))
-
-(defun package-lint--check-libraries-removed-from-emacs ()
- "Warn about use of libraries that have been removed from Emacs."
- (package-lint--map-regexp-match
- package-lint--unconditional-require-regexp
- (lambda (sym)
- (cl-block return
- (pcase-dolist (`(,removed-in-version . ,pred) package-lint--libraries-removed-alist)
- (when (funcall pred (intern sym))
- (cl-return-from return
- (list
- 'error
- (format "The `%s' library was removed in Emacs version %s."
- sym (mapconcat #'number-to-string removed-in-version "."))))))))))
-
-(defconst package-lint--function-name-regexp
- "\\(?:#'\\|(\\s-*?\\)\\(.*?\\)\\_>"
- "Regexp to match function names.")
-
-(defun package-lint--check-macros-functions-available-in-emacs (valid-deps)
- "Warn about use of functions/macros that are not available in the Emacs version in VALID-DEPS."
- (package-lint--check-version-regexp-list
- valid-deps
- package-lint--functions-and-macros-added-alist
- package-lint--function-name-regexp
- 'function))
-
-(defun package-lint--check-macros-functions-removed-from-emacs ()
- "Warn about use of functions/macros that have been removed from Emacs."
- (package-lint--map-regexp-match
- package-lint--function-name-regexp
- (lambda (sym)
- (cl-block return
- (pcase-dolist (`(,removed-in-version . ,pred) package-lint--functions-and-macros-removed-alist)
- (when (funcall pred (intern sym))
- (cl-return-from return
- (list
- 'error
- (format "`%s' was removed in Emacs version %s."
- sym (mapconcat #'number-to-string removed-in-version "."))))))))))
-
-(defun package-lint--check-lexical-binding-is-on-first-line ()
- "Check that any `lexical-binding' declaration is on the first line of the file."
- (cl-block return
- (let ((original-buffer (current-buffer)))
- (with-temp-buffer
- (let ((lexical-binding-found-at-end nil))
- (insert-buffer-substring-no-properties original-buffer)
- (condition-case err
- (cl-letf (((symbol-function #'hack-local-variables-apply) #'ignore)
- ((symbol-function #'hack-local-variables-filter)
- (lambda (variables _dir-name)
- (setq file-local-variables-alist variables)))
- ;; Silence any messages Emacs may want to share with the user.
- ;; There's no user.
- ((symbol-function #'display-warning) #'ignore)
- ((symbol-function #'message) #'ignore))
- ;; HACK: this is an internal variable!
- ;; Unfortunately, Emacsen that have this variable also have
- ;; `hack-local-variables' that doesn't store `lexical-binding'
- ;; in `file-local-variables-alist'.
- (defvar enable-dir-local-variables)
- (defvar hack-local-variables--warned-lexical)
- (let ((hack-local-variables--warned-lexical nil)
- (enable-dir-local-variables nil)
- (enable-local-variables t)
- (local-enable-local-variables t))
- (hack-local-variables)
- (setq lexical-binding-found-at-end
- hack-local-variables--warned-lexical)))
- (error
- (package-lint--error-at-bob 'error (error-message-string err))
- (cl-return-from return nil)))
- (when (or lexical-binding-found-at-end
- ;; In case this is an Emacs from before `hack-local-variables'
- ;; started to warn about `lexical-binding' on a line other
- ;; than the first.
- (and (cdr (assq 'lexical-binding file-local-variables-alist))
- (not (package-lint--lexical-binding-declared-in-header-line-p))))
- (package-lint--error-at-bob
- 'error
- "`lexical-binding' must be set in the first line.")))))))
-
-(defun package-lint--check-do-not-depend-on-cl-lib-1.0 (valid-deps)
- "Check that any dependency in VALID-DEPS on \"cl-lib\" is on a remotely-installable version."
- (let ((cl-lib-dep (assq 'cl-lib valid-deps)))
- (when cl-lib-dep
- (let ((cl-lib-version (nth 1 cl-lib-dep)))
- (when (version-list-<= '(1) cl-lib-version)
- (package-lint--error-at-point
- 'error
- (format "Depend on the latest 0.x version of cl-lib rather than on version \"%S\".
-Alternatively, depend on (emacs \"24.3\") or greater, in which cl-lib is bundled."
- cl-lib-version)
- (nth 2 cl-lib-dep)))))))
-
-(defun package-lint--check-package-version-present ()
- "Check that a valid \"Version\" header is present."
- (let ((version (package-lint--goto-header (rx (? "Package-") "Version"))))
- (if version
- (unless (ignore-errors (version-to-list version))
- (package-lint--error-at-point
- 'warning
- (format "\"%s\" is not a valid version. MELPA will handle this, but other archives will not." version)
- (match-beginning 3)))
- (package-lint--error-at-bob
- 'warning
- "\"Version:\" or \"Package-Version:\" header is missing. MELPA will handle this, but other archives will not."))))
-
-(defun package-lint--check-package-el-can-parse ()
- "Check that `package-buffer-info' can read metadata from this file.
-If it can, return the read metadata."
- (condition-case err
- (let ((orig-buffer (current-buffer)))
- ;; We've reported version header issues separately, so rule them out here
- (with-temp-buffer
- (insert-buffer-substring-no-properties orig-buffer)
- (package-lint--update-or-insert-version "0")
- (package-buffer-info)))
- (error
- (package-lint--error-at-bob
- 'error
- (format "package.el cannot parse this buffer: %s" (error-message-string err)))
- nil)))
-
-(defun package-lint--check-package-summary (desc)
- "Check the summary for package with descriptor DESC.
-DESC is a struct as returned by `package-buffer-info'."
- (let ((summary (package-lint--package-desc-summary desc)))
- (cond
- ((string= summary "")
- (package-lint--error-at-bob
- 'warning
- "Package should have a non-empty summary."))
- (t
- (unless (let ((case-fold-search nil))
- (string-match-p "^[A-Z0-9]" summary))
- (package-lint--error-at-bob
- 'warning
- "The package summary should start with an uppercase letter or a digit."))
- (when (> (length summary) 60)
- (package-lint--error-at-bob
- 'warning
- "The package summary is too long. It should be at most 60 characters."))
- (when (save-match-data
- (let ((case-fold-search t))
- (and (string-match "[^.]\\<emacs\\>" summary)
- (not (string-match-p "[[:space:]]+lisp"
- summary (match-end 0))))))
- (package-lint--error-at-bob
- 'warning
- "Including \"Emacs\" in the package summary is usually redundant."))))))
-
-(defun package-lint--check-provide-form (desc)
- "Check the provide form for package with descriptor DESC.
-DESC is a struct as returned by `package-buffer-info'."
- (let ((name (package-lint--package-desc-name desc))
- (feature (package-lint--provided-feature)))
- (unless (string-equal (symbol-name name) feature)
- (package-lint--error-at-bob
- 'error
- (format "There is no (provide '%s) form." name)))))
-
-(defun package-lint--check-no-emacs-in-package-name (desc)
- "Check that the package name doesn't contain \"emacs\".
-DESC is a struct as returned by `package-buffer-info'."
- (let ((name (package-lint--package-desc-name desc)))
- (when (string-match-p "emacs" (symbol-name name))
- (package-lint--error-at-bob
- 'warning
- "The word \"emacs\" is redundant in Emacs package names."))))
-
-(defun package-lint--check-symbol-separators (definitions)
- "Check that symbol DEFINITIONS don't contain non-standard separators."
- (pcase-dolist (`(,name . ,position) definitions)
- (when (and (string-match "[:/]" name)
- (not (string-match-p package-lint--sane-prefixes name)))
- (let ((match-pos (match-beginning 0)))
- ;; As a special case, allow `/=' when at the end of a symbol.
- (when (or (not (string-match (rx "/=" string-end) name))
- (/= match-pos (match-beginning 0)))
- (goto-char position)
- (package-lint--error
- (line-number-at-pos) 0 'error
- (format "`%s' contains a non-standard separator `%s', use hyphens instead (see Elisp Coding Conventions)."
- name (substring-no-properties name match-pos (1+ match-pos)))))))))
-
-(defun package-lint--valid-definition-name-p (name prefix &optional position)
- "Return non-nil if NAME denotes a valid definition name.
-
-Valid definition names are:
-
-- a NAME starting with PREFIX, a string representing the current
- package prefix,
-
-- a NAME matching `package-lint--sane-prefixes', or
-
-- a NAME whose POSITION in the buffer denotes a global definition."
- (or (string-prefix-p prefix name)
- (string-match-p package-lint--sane-prefixes name)
- (string-match-p (rx-to-string `(seq string-start (or "define" "defun" "defvar") "-" ,prefix)) name)
- (string-match-p (rx-to-string `(seq string-start "global-" ,prefix (or "-mode" (seq "-" (* any) "-mode")) string-end)) name)
- (when position
- (goto-char position)
- (looking-at-p (rx (*? space) "(" (*? space)
- (or "defadvice" "cl-defmethod")
- symbol-end)))))
-
-(defun package-lint--check-defs-prefix (definitions)
- "Verify that symbol DEFINITIONS start with package prefix."
- (let ((prefix (package-lint--get-package-prefix)))
- (when prefix
- (pcase-dolist (`(,name . ,position) definitions)
- (unless (package-lint--valid-definition-name-p name prefix position)
- (package-lint--error-at-point
- 'error
- (format "\"%s\" doesn't start with package's prefix \"%s\"."
- name prefix)
- position))))))
-
-(defun package-lint--check-minor-mode (def)
- "Offer up concerns about the minor mode definition DEF."
- (when (cl-search '(:global t) def)
- (package-lint--check-globalized-minor-mode def)))
-
-(defun package-lint--check-globalized-minor-mode (def)
- "Offer up concerns about the global minor mode definition DEF."
- (let ((feature-name (package-lint--provided-feature)))
- (when feature-name
- (let ((feature (intern feature-name))
- (autoloaded (save-excursion
- (forward-line -1)
- (beginning-of-line)
- (looking-at ";;;###autoload"))))
- (unless (or autoloaded
- (cl-search `(:require ',feature) def :test #'equal))
- (package-lint--error-at-point
- 'error
- (format
- "Global minor modes should be autoloaded or, rarely, `:require' their defining file (i.e. \":require '%s\"), to support the customization variable of the same name." feature)))))))
-
-(defun package-lint--check-defgroup (def)
- "Offer up concerns about the customization group definition DEF."
- (when (symbolp (cadr def))
- (let ((group-name (symbol-name (cadr def))))
- (when (string-match "\\(.*\\)-mode$" group-name)
- (let ((parent (intern (match-string 1 group-name))))
- (unless (cl-search `(:group ',parent) def :test #'equal)
- (package-lint--error-at-point
- 'error
- "Customization groups should not end in \"-mode\" unless that name would conflict with their parent group."))))))
-
- (unless (memq :group def)
- (package-lint--error-at-point
- 'error
- "Customization groups should specify a parent via `:group'.")))
-
-(defun package-lint--check-defalias (def)
- "Offer up concerns about the customization group definition DEF."
- (let ((prefix (package-lint--get-package-prefix)))
- (when prefix
- (pcase (cadr def)
- ((and `(quote ,alias) (guard (symbolp alias)))
- (unless (package-lint--valid-definition-name-p (symbol-name alias) prefix)
- (package-lint--error-at-point
- 'error
- (concat "Aliases should start with the package's prefix \"" prefix "\"."))))))))
-
-(defun package-lint--check-format-string (valid-deps def)
- "Offer up concerns about the format string used in DEF, depending on VALID-DEPS."
- (let ((fmt-str (cadr def))
- (emacs-version-dep (or (cadr (assq 'emacs valid-deps)) '(0))))
- (when (and (version-list-< emacs-version-dep '(26 1))
- ;; We give up on trying to warn about format strings that are
- ;; evaluated at runtime.
- (stringp fmt-str)
- ;; The usual regexp strategy for finding unescaped matches
- ;; requires negative lookbehind:
- ;; (?<!%)(?:%%)*[0-9]+\$
- ;; So instead we make sure the count of escape chars is odd
- (string-match "\\(%+\\)[0-9]+\\$" fmt-str)
- (cl-oddp (length (match-string 1 fmt-str))))
- (package-lint--error-at-point
- 'error
- "You should depend on (emacs \"26.1\") if you need format field numbers."))))
-
-(defun package-lint--check-lonely-parens ()
- "Warn about dangling closing parens."
- (package-lint--map-regexp-match
- "^\\s-*?\\()\\)"
- (lambda (_)
- ;; Allow dangling parentheses if the preceding line ends with a comment, as
- ;; it's not uncommon even in idiomatic lisp.
- (when (save-excursion
- (end-of-line 0)
- (not (nth 4 (syntax-ppss))))
- (list 'warning
- "Closing parens should not be wrapped onto new lines.")))))
-
-
-\f
-;;; Helpers
-
-(defun package-lint--extract-key-sequence (form)
- "Extract the key sequence from FORM."
- (pcase form
- (`(kbd ,seq)
- (package-lint--extract-key-sequence seq))
- ((or `(global-set-key ,seq ,_) `(local-set-key ,seq ,_))
- (package-lint--extract-key-sequence seq))
- (`(define-key ,_ ,seq ,_)
- (package-lint--extract-key-sequence seq))
- ((pred stringp)
- (listify-key-sequence (read-kbd-macro form)))
- ((pred vectorp)
- (unless (listp (elt form 0))
- (listify-key-sequence form)))))
-
-(defun package-lint--test-keyseq (lks)
- "Return a message if the listified key sequence LKS is invalid, otherwise nil."
- (let* ((modifiers (event-modifiers lks))
- (basic-type (event-basic-type lks)))
- (when (or (and (> (length lks) 1) (equal (car (last lks)) ?\C-g))
- (and (equal (car (last lks)) ?\e)
- (not (equal (nthcdr (- (length lks) 2) lks)
- '(?\e ?\e))))
- (equal (car (last lks)) ?\C-h)
- (and (equal modifiers '(control))
- (equal ?c basic-type)
- (cdr lks)
- (let ((v (event-basic-type (cdr lks)))
- (m (event-modifiers (cdr lks))))
- (and (numberp v)
- (<= v ?z)
- (>= v ?a)
- (or (null m) (equal '(shift) m)))))
- (member basic-type '(f5 f6 f7 f8 f9)))
- "This key sequence is reserved (see Key Binding Conventions in the Emacs Lisp manual)")))
-
-(defun package-lint--region-empty-p (start end)
- "Return t iff the region between START and END has no non-empty lines.
-
-Lines consisting only of whitespace or empty comments are considered empty."
- (save-excursion
- (save-restriction
- (let ((inhibit-changing-match-data t))
- (narrow-to-region start end)
- (goto-char start)
- (while (and (looking-at "^[[:space:]]*;*[[:space:]]*$")
- (= 0 (forward-line))))
- (eobp)))))
-
-(defun package-lint--highest-installable-version-of (package)
- "Return the highest version of PACKAGE available for installation."
- (let ((descriptors (cdr (assq package package-archive-contents))))
- (if (fboundp 'package-desc-version)
- (car (sort (mapcar 'package-desc-version descriptors)
- (lambda (v1 v2) (not (version-list-< v1 v2)))))
- (aref descriptors 0))))
-
-(defun package-lint--goto-header (header-name)
- "Move to the first occurrence of HEADER-NAME in the file.
-If the return value is non-nil, then point will be at the end of
-the file, and the second and third match groups will contain the name and
-value of the header with any leading or trailing whitespace removed."
- (let ((initial-point (point)))
- (goto-char (point-min))
- (let ((case-fold-search t))
- (if (re-search-forward (concat (lm-get-header-re header-name) "\\(.*?\\) *$") nil t)
- (match-string-no-properties 3)
- (goto-char initial-point)
- nil))))
-
-(defun package-lint--update-or-insert-version (version)
- "Ensure current buffer has a \"Version: VERSION\" header."
- (if (package-lint--goto-header "Version")
- (move-beginning-of-line nil)
- (forward-line))
- (insert (format ";; Version: %s" version))
- (newline))
-
-(defun package-lint--get-header-line-file-local-variables ()
- "Return local variables specified in the -*- line.
-Returns an alist of elements (VAR . VAL), where VAR is a variable
-and VAL is the specified value.
-
-For details, see `hack-local-variables-prop-line'."
- (cl-letf (((symbol-function #'message) #'ignore))
- (hack-local-variables-prop-line)))
-
-(defun package-lint--lexical-binding-declared-in-header-line-p ()
- "Test if `lexical-binding' is declared in the -*- line."
- ;; Test the `cdr' to see if it's actually true, because
- ;; -*- lexical-binding: nil -*-
- ;; is legal, if silly.
- (cdr (assq 'lexical-binding (package-lint--get-header-line-file-local-variables))))
-
-(defvar semantic-imenu-summary-function)
-
-(defun package-lint--get-defs ()
- "Return a list of all variables and functions defined in the current buffer.
-
-The returned list is of the form (SYMBOL-NAME . POSITION)."
- ;; We probably could use Semantic instead, but it's a *global* minor mode and
- ;; it tends to be quite heavy, so use Imenu instead; if the user has Semantic
- ;; enabled, Imenu will use its index anyway.
- (let ((result '())
- (index
- (save-excursion
- ;; Use the default imenu expression list so that we're not confused
- ;; by user customizations.
- (let ((imenu-generic-expression lisp-imenu-generic-expression)
- ;; In case it's actually Semantic, tell it not to decorate
- ;; symbol names.
- (semantic-imenu-summary-function 'semantic-format-tag-name))
- (funcall imenu-create-index-function)))))
- (dolist (entry index)
- (pcase entry
- ((and `(,submenu-name . ,submenu-elements)
- (guard (consp submenu-elements)))
- (when (member submenu-name '("Variables" "Defuns"))
- (setq result (nconc (reverse submenu-elements) result))))
- (_
- (push entry result))))
- ;; If it's Semantic, then it returns overlays, not positions. Convert
- ;; them.
- (dolist (entry result)
- (when (overlayp (cdr entry))
- (setcdr entry (overlay-start (cdr entry)))))
- (nreverse result)))
-
-(defun package-lint--provided-feature ()
- "Return the first-provided feature name, as a string, or nil if none."
- (save-excursion
- (goto-char (point-max))
- (cond ((re-search-backward (rx "(provide '" (group (1+ (or (syntax word) (syntax symbol))))) nil t)
- (match-string-no-properties 1))
- ((re-search-backward "(provide-me)" nil t)
- (file-name-sans-extension (file-name-nondirectory buffer-file-name))))))
-
-(defun package-lint--get-package-prefix ()
- "Return package prefix string (i.e. the symbol the package `provide's).
-Prefix is returned without any `-mode' suffix."
- (let ((feature (package-lint--provided-feature)))
- (when feature
- (replace-regexp-in-string "-mode\\'" "" feature))))
-
-(defun package-lint--check-objects-by-regexp (regexp function)
- "Check all objects with the literal printed form matching REGEXP.
-
-The objects are parsed with `read'. The FUNCTION is passed the
-read object, with the point at the beginning of the match.
-
-S-expressions in comments or comments, partial s-expressions, or
-otherwise invalid read forms are ignored."
- (goto-char (point-min))
- (while (re-search-forward regexp nil t)
- (save-excursion
- (goto-char (match-beginning 0))
- (let ((obj (unless (package-lint--inside-comment-or-string-p)
- (save-excursion
- (ignore-errors (read (current-buffer)))))))
- (when obj (funcall function obj))))))
-
-\f
-;;; Public interface
-
-;;;###autoload
-(defun package-lint-buffer (&optional buffer)
- "Get linter errors and warnings for BUFFER.
-
-Returns a list, each element of which is list of
-
- (LINE COL TYPE MESSAGE)
-
-where TYPE is either 'warning or 'error.
-
-Current buffer is used if none is specified."
- (with-current-buffer (or buffer (current-buffer))
- (package-lint--check-all)))
-
-;;;###autoload
-(defun package-lint-current-buffer ()
- "Display lint errors and warnings for the current buffer."
- (interactive)
- (let ((errs (package-lint-buffer))
- (buf "*Package-Lint*"))
- (with-current-buffer (get-buffer-create buf)
- (let ((buffer-read-only nil))
- (erase-buffer)
- (cond
- ((null errs) (insert "No issues found."))
- ((null (cdr errs)) (insert "1 issue found:\n\n"))
- (t (insert (format "%d issues found:\n\n" (length errs)))))
- (pcase-dolist (`(,line ,col ,type ,message) errs)
- (insert (format "%d:%d: %s: %s\n" line col type message))))
- (special-mode)
- (view-mode 1))
- (display-buffer buf)))
-
-(defun package-lint-batch-and-exit-1 (filenames)
- "Internal helper function for `package-lint-batch-and-exit'.
-
-Checks FILENAMES using package-lint.
-
-The main loop is this separate function so it's easier to test."
- ;; Make sure package.el is initialized so we can query its database.
- (package-initialize)
- (let ((success t) (last-directory nil) (text-quoting-style 'grave))
- (dolist (file filenames success)
- (let* ((file (expand-file-name file))
- (file-directory (file-name-directory file))
- (base (file-name-nondirectory file)))
- (with-temp-buffer
- (insert-file-contents file t)
- (emacs-lisp-mode)
- (let ((checking-result (package-lint-buffer)))
- (when checking-result
- (setq success nil)
- (unless (equal last-directory file-directory)
- (setq last-directory file-directory)
- (message "Entering directory '%s'" file-directory))
- (pcase-dolist (`(,line ,col ,type ,message) checking-result)
- (message "%s:%d:%d: %s: %s"
- base line col type message)))))))))
-
-;;;###autoload
-(defun package-lint-batch-and-exit ()
- "Run `package-lint-buffer' on the files remaining on the command line.
-Use this only with -batch, it won't work interactively.
-
-When done, exit Emacs with status 0 if there were no errors nor warnings or 1
-otherwise."
- (unless noninteractive
- (error "`package-lint-batch-and-exit' is to be used only with -batch"))
- (let ((success (package-lint-batch-and-exit-1 command-line-args-left)))
- (kill-emacs (if success 0 1))))
-
-;;;###autoload
-(defun package-lint-looks-like-a-package-p ()
- "Return non-nil if the current buffer appears to be intended as a package."
- (save-match-data
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (re-search-forward
- (concat lm-header-prefix
- (rx (or "Version" "Package-Version" "Package-Requires")))
- nil t)))))
-
-(provide 'package-lint)
-;; Local Variables:
-;; indent-tabs-mode: nil
-;; End:
-;;; package-lint.el ends here
--- /dev/null
+(((24 1)
+ (functions
+ (removed *table--cell-conter-region ad-Orig-gdb-invalidate-frames ad-define-subr-args ad-get-subr-args ad-subr-arglist ad-subr-args-defined-p ad-undefine-subr-args ada-after-change-function ada-handle-syntax-table-properties ada-initialize-synsp;x-make-font-unbold x-make-font-unitalic x-menu-activate x-menu-add-item x-menu-change-associated-buffer x-menu-create-menu x-menu-delete-item x-menu-mode x-menu-pick-entry x-set-cut-buffer x-setup-function-keys)
+ (added *table--cell-center-region 5x5-defvar-local 5x5-grid-to-vec 5x5-log 5x5-log-init 5x5-solve-rotate-left 5x5-solve-rotate-right 5x5-solve-suggest 5x5-solver 5x5-vec-to-grid Footnote-unicode Info-isearch-end Man-bookmark-jump Man-bookmark-make-record Man-default-bookmark-title Man-page-from-arguments abbrev-edit-save-buffer abbrev-edit-save-to-file abbrev-table-empty-p ad-Orig-find-tag ad-Orig-org-format-latex-as-mathml ad-Orig-save-place-find-file-hook ad-Orig-visit-tags-table align--set-marker allout-auto-activation-helper allout-body-modification-handler allout-casp;window-normalize-buffer-to-switch-to window-normalize-frame window-normalize-window window-parent window-point-1 window-prev-buffers window-prev-sibling window-resizable window-resize window-resize-apply window-right window-sizable window-sizable-p window-size-fixed-p window-split-min-size window-state-get window-state-put window-top-child window-top-line window-total-height window-total-size window-total-width window-use-time window-valid-p window-with-parameter with-buffer-modified-unmodified with-org-lparse-preserve-paragraph-state woman-bookmark-jump woman-bookmark-make-record word-search-regexp x-dnd-more-than-3-from-flags x-dnd-version-from-flags xmodmap-generic-mode xselect--encode-string xselect-convert-to-save-targets y-or-n-minibuffer))
+ (variables
+ &ndress webmail-article-snarf webmail-article-url webmail-articles webmail-aux webmail-buffer webmail-buffer-list webmail-debug-file webmail-error-function webmail-list-snarf webmail-list-url webmail-login-snarf webmail-login-url webmail-move-to-trash-can webmail-newmail-only webmail-open-snarf webmail-open-url webmail-paranoid webmail-post-process webmail-session webmail-trash-url webmail-type webmail-type-definition webmail-variables webmail-version widget-complete-field x-alternatives-map x-menu-assoc-buffer x-menu-item-spacing x-menu-item-width x-menu-items-alist x-menu-items-per-line x-menu-max-width x-select-enable-clipboard)
+ (added *org-babel-use-quick-and-dirty-noweb-expansion* *org-bibtex-entries* 5x5-solver-output :=key= :=type= :R-dev-args :aborted-p :aauto-delete-trailing-whitespace verilog-auto-inst-sort verilog-auto-reset-blocking-in-non verilog-auto-tieoff-declaration verilog-auto-wire-type verilog-diff-function verilog-in-hooks verilog-inst-comment-re verilog-no-change-functions verilog-uvm-begin-re verilog-uvm-end-re verilog-uvm-statement-re window-combination-limit window-combination-resize window-persistent-parameters window-safe-min-height window-safe-min-width window-sides window-sides-slots window-sides-vertical window-state-put-list))
+ (features
+ (removed cl-19 earcon eieio-comp emacs-lock esh-test font-setting gdb-ui gnus-audio gnus-move gnus-nocem gnus-soup imap-hash mldrag nndb nnkiboze nnlistserv nnslashdot nnsoup nnultimate nnwarchive nnwfm rnews rnewspost sc tramp-fish tramp-imap webmail x-menu)
+ (added allout-widgets bookmark cc-guess cconv cfengine3 color cus-theme desktop ert ert-x filesets gdb-mi gnus-gravatar gnus-html gnus-registry gnus-sync gnutls gravatar gssapi ido image-dired network-stream nnregistry notifications ob ob-C ob-R ob-asymptote ob-awk ob-calc ob-clojure ob-comint ob-css ob-ditaa ob-dot ob-emacs-lisp ob-eval ob-exp ob-fortran ob-gnuplot ob-haskell ob-java ob-js ob-keys ob-latex ob-ledger ob-lilypond ob-lisp ob-lob ob-matlab ob-maxima ob-mscgen ob-ocaml ob-octave ob-org ob-perl ob-picolisp ob-plantuml ob-python ob-ref ob-ruby ob-sass ob-scheme ob-screen ob-sh ob-shen ob-sql ob-sqlite ob-table ob-tangle org-beamer org-capture org-ctags org-docview org-entities org-eshell org-lparse org-mks org-odt org-pcomplete org-special-blocks org-taskjuggler package package-x pcase pcvs pcvs-defs plstore ps-bdf recentf registry rtree savehist saveplace shr shr-color soap-client soap-inspect tabulated-list tramp-loaddefs tramp-sh url-future url-queue)))
+ ((24 2)
+ (functions
+ (removed)
+ (added rcirc-split-message))
+ (variables
+ (removed)
+ (added))
+ (features
+ (removed)
+ (added bug-reference misearch multi-isearch)))
+ ((24 3)
+ (functions
+ (removed Buffer-menu-buffer+size Buffer-menu-make-sort-button Buffer-menu-revert-function Buffer-menu-sort-by-column ad-Orig-comment-region ad-Orig-move-overlay ad-Orig-process-filter ad-Orig-set-process-filter ad-Orig-sit-for ad-copy-tree ad-do-return ad-dolist ad-prognify ansi-color-get-face article-translate-characters battery-yeeloong-sysfs bookmark-insert-current-bookmark bookmark-read-search-input brm-init bruce byte-compile-const-symbol-p byte-compile-constp byte-compile-defalias-warn byte-compile-defmacro byte-compile-defmacro-declaration nbsp;table-set-table-fixed-width-mode term-fake-pager-disable term-fake-pager-enable tmm-delete-map tramp-enter-password tramp-with-progress-reporter turn-off-pdbtrack turn-on-pdbtrack verilog-in-struct-region-p viper-inactivate-input-method viper-inactivate-input-method-action w32-init-info window--display-buffer-1 window--display-buffer-2 window--size-ignore window-point-1 with-connection-property with-file-property xml-parse-fragment xscheme-modeline-initialize zone-hiding-modeline)
+ (added Buffer-menu--pretty-file-name Buffer-menu--pretty-name Buffer-menu-info-node-description ange-ftp-ignore-errors-if-non-essential ansi-color--find-face ansi-color-parse-sequence archive-extract-by-file auth-source--aget auth-source--aput auth-source--aput-1 auth-source-backend-list-p auth-source-macos-keychain-create&nsystem-for-display wisent-grammar-mode with-temp-buffer-window with-tramp-connection-property with-tramp-file-property with-tramp-progress-reporter woman-break-table x-apply-session-resources x-get-selection-value x-selection-value xml--entity-replacement-text xml--parse-buffer xml-parse-tag-1 xscheme-mode-line-initialize xterm-mouse--read-event-sequence-1000 xterm-mouse--read-event-sequence-1006 xterm-mouse-translate-1 xterm-mouse-translate-extended yank-handle-category-property yank-handle-font-lock-face-property zone-hiding-mode-line))
+ (variables
+ (removed *gensym-counter* *org-bibtex-entries* *random-state* :continue :prompt-time Buffer-menu--buffers Buffer-menu-buffer-column Buffer-menu-short-ellipsis Buffer-menu-sort-button-map Buffer-menu-sort-column Info-next-linkd-command-char url-cookie-two-dot-domains vc-bzr-error-regex-alist vc-bzr-sha1-program vc-checkout-carefully vc-ignore-vc-files vc-master-templates vhdl-93-attributes vhdl-93-enum-values vhdl-93-functions vhdl-93-keywords vhdl-93-packages vhdl-93-types xml-name-regexp)
+ (added :action-items :addlevel :allow-list :allow-replacement :already-owner :archivedp :back-end :begin :block-name :bus :clock :clocktable :commentedp :configregex :configregexidx :contents-begin :contents-end :count-percent :counter :decrypted :diff-p :do-not-queue :drawer-name :eavesdrop :empty-lines-after :empty-lines-before :entry :enumeration :exists :export :file-desc :footnote-section-p :fromconfig :grp :hiddenp :ignore-list :in-queue :inl-hook x-last-selected-text xml-default-ns xml-entity-expansion-limit xml-entity-or-char-ref-re xml-parameter-entity-alist yank-handled-properties))
+ (features
+ (removed org-install python-21 reftex-vcr)
+ (added cl-lib cl-macs erc-desktop-notifications gnus-notifications gv mm-archive ob-io ob-scala org-element org-loaddefs org-version profiler url-domsuf w32-common-fns)))
+ ((24 4)
+ (functions
+ (removed Command-history-setup ad-Orig-copy-region-as-kill ad-Orig-create-file-buffer ad-Orig-dnd-insert-text ad-Orig-dnd-open-file ad-Orig-find-tag ad-Orig-idlwave-shell-electric-debug-mode ad-Orig-newline ad-g-get-beg-of-defun verilog-get-list verilog-sk-uvm-class verilog-type-completion vhdl-mode-syntax-table-init viper-envelop-ESC-key widget-remove-if winner-hook-installed-p with-org-lparse-preserve-paragraph-state woman-mark-horizonal-position xmltok-add-dependent xmltok-semi-closed-reparse-p xmltok-unclosed-reparse-p xterm-mouse-event-read)
+ (added Buffer-menu--unmark Buffer-menu-multi-occur Info--search-loop Info-build-node-completions-1 Info-next-reference-or-link Info-prev-reference-or-link Man-parse-man-k Man-start-calling Man-update-manpage abbrev--default-expand abbrev--symbol ad--defalias-fset ad--make-advised-docstring ad-Advice-c-backward-sws ad-Advice-c-beginning-of-macro ad-Advice-c-forward-sws ad-Advice-dnd-insert-text ad-Advice-dnd-open-file ad-Advice-find-tag ad-Advice-idlwave-shell-electsafe-min-pixel-width window-safe-min-size window-screen-lines window-scroll-bar-width window-size window-text-pixel-size window-text-width with-current-buffer-window with-eval-after-load with-isearch-suspended woman-mark-horizontal-position x-focus-frame x-popup-dialog xesam-buffer-name xesam-dbus-call-method xesam-delete-search-engine xesam-get-cached-property xesam-get-hits xesam-get-property xesam-highlight-string xesam-kill-buffer-function xesam-minor-mode xesam-mode xesam-new-search xesam-refresh-entry xesam-refresh-search-buffer xesam-search-engines xesam-set-cached-property xesam-set-property xesam-signal-handler zlib-available-p zlib-decompress-region))
+ (variables
+ (removed *org-babel-use-quick-and-dirty-noweb-expansion* :LaTeX :LaTeX-fragments nd-to-0-flag prolog-tokenize-searchkey prolog-upper-case-string prolog-use-prolog-tokenizer-flag prolog-use-smie ps-lp-system ps-windows-system python-indent-dedenters report-emacs-bug-bug-alist report-emacs-bug-choice-widget report-emacs-bug-tracker-url ruby-keyword-end-re saved-overriding-map set-mark-default-inactive show-paren-idle-timer show-paren-overlay show-paren-overlay-1 sieve-manage-stream-alist sieve-manage-streams sql-output-by-send thing-at-point-url-regexp tramp-completion-file-name-regexp-url tramp-file-name-regexp-url tramp-message-show-progress-reporter-message universal-argument-num-events vc-diff-knows-L verilog-mode-release-date vhdl-speedbar-key-map whitespace-font-lock whitespace-font-lock-mode xmltok-dependent-regions)
+ (added *org-babel-gnuplot-missing* *org-babel-gnuplot-terms*&nbs-direct-print-region-use-command-dot-com w32-untranslated-filesystem-list which-function-mode-hook whitespace-enable-predicate whitespace-global-mode-hook whitespace-mode-hook whitespace-newline-mode-hook widget-minor-mode-hook window-resize-pixelwise window-state-put-stale-windows wordstar-mode-abbrev-table wordstar-mode-hook wordstar-mode-syntax-table xesam-count xesam-current xesam-dbus-unique-names xesam-engine xesam-minibuffer-query-history xesam-minibuffer-vendor-history xesam-minor-mode xesam-minor-mode-hook xesam-mode-abbrev-table xesam-mode-hook xesam-mode-map xesam-mode-syntax-table xesam-notify-function xesam-objects xesam-query xesam-refreshing xesam-search xesam-search-engines xesam-to xesam-type xesam-vendor xesam-xml-string xterm-mouse-mode-hook))
+ (features
+ (removed advice-preload delphi find-gc octave-inf octave-mod org-ascii org-beamer org-docbook org-exp org-exp-blocks org-export-latex org-freemind org-html org-icalendar org-infojs org-jsinfo org-latex org-lparse org-mac-message org-mew org-mks org-odt org-publish org-remember org-special-blocks org-taskjuggler org-vm org-wl org-xoxo)
+ (added bat-mode cl-indent cl-loaddefs cus-dep dos-vars eieio-core elec-pair em-tramp erc-list eudcb-bbdb eww filenotify frameset gnus-icalendar gnus-vm inotify nadvice ob-core ob-makefile octave opascal org-macro ox ox-ascii ox-beamer ox-html ox-icalendar ox-latex ox-man ox-md ox-odt ox-org ox-publish ox-texinfo pcmpl-x prog-mode smiley subr-x sup-mouse superword tpu-extras tramp-adb xesam)))
+ ((24 5)
+ (functions
+ (removed browse-url-firefox-sentinel cua-repeat-replace-region python-indent-toggle-levels tramp-time-less-p tramp-time-subtract)
+ (added c--macroexpand-all c-macro-is-genuine-p delete-selection-repeat-replace-region erc-channel-user-admin erc-channel-user-admin-p erc-channel-user-halfop erc-channel-user-halfop-p erc-channel-user-owner erc-channel-user-owner-p erc-get-user-mode-prefix erc-quit/part-reason-default file-notify--descriptor python-indent--calculate-indentation python-indent--calculate-levels python-indent--previous-level python-info-encoding python-info-encoding-from-cookie python-syntax-closing-paren-p reftex--prepare-syntax-tables todo-revert-buffer))
+ (variables
+ (removed cua--last-deleted-region-pos cua--last-deleted-region-text cua--repeat-replace-text ispell-hunspell-dictionary-equivs-alist python--use-fake-loc)
+ (added :admin :after-backslash :after-backslash-assignment-continuation :after-backslash-block-continuation :after-backslash-dotted-continuation :after-backslash-first-line :after-block-end :after-block-start :after-comment :after-line :at-dedenter-block-start :halfop :inside-paren :inside-paren-at-closing-nested-paren :inside-paren-at-closing-paren :inside-paren-newline-start :inside-paren-newline-start-from-block :inside-string :no-indent :owner delete-selection-save-to-register delsel--replace-text-or-position erc-rename-buffers ispell-dicts-name2locale-equivs-alist mml2015-display-key-image python-shell-unbuffered vc-hg-log-graph))
+ (features
+ (removed)
+ (added cl-extra)))
+ ((25 1)
+ (functions
+ (removed ada-convert-file-name add-to-diary-list american-calendar authors authors-add authors-add-fixed-entries authors-add-to-author-list authors-canonical-author-name authors-canonical-file-name authors-disambiguate-file-name authors-lax-changelog-p authors-no-scan-file-p authors-obsolete-file-p authors-public-domain-p authors-scan-change-log authors-scan-el batch-update-authors byte-compile-file-form-define-abbre-mistrust-permissions vc-mtn-could-register vc-mtn-dir-status vc-mtn-workfile-unchanged-p vc-name vc-rcs-dir-status vc-rcs-rollback vc-rcs-state-heuristic vc-rollback vc-sccs-dir-status vc-sccs-rollback vc-sccs-state-heuristic vc-stay-local-p vc-svn-could-register vc-svn-dir-status vc-svn-repository-hostname vc-svn-state-heuristic vc-workfile-unchanged-p vhdl-goto-line view-other-diary-entries w3-parse-buffer w32-using-nt w32-version window--even-window-heights window--size-ignore-p window-split-min-size woman-mapcan would-be-symbol x-selection-owner-p x-valid-simple-selection-p xterm-mouse--read-event-sequence-1000 xterm-mouse--read-event-sequence-1006)
+ (added \(setf\ ede-object-keybindings\) \(setf\ ede-object-menu\) \(setf\ ede-object-sourcecode\) \(setf\ gnus-icalendahow-id-element xwidget-webkit-show-id-or-named-element xwidget-webkit-show-named-element zerop--anon-cmacro))
+ (variables
+ (removed :PRIMARY :STATIC :bgcolor :changed :cols :colspan :cowrote :disabled :element-type :fc-unknown-spec :fgcolor :href :nillable\? :poster :rel :rowspan :wrote abbreviated-calendar-year all-bahai-calendar-holidays all-christian-calendar-holidays all-hebrew-calendar-holidays all-islamic-calendar-holidays american-calendar-display-form american-date-diary-pattern authors-aliases authors-ambiguous-files authors-coding-system authors-fixed-case authors-fixed-entries authors-ignored-files authors-lax-changelogs authors-many-files authors-no-scan-regexps authors-obsolete-files-regexps authors-public-domain-files a-bnf-table oriental-holidays other-holidays parse-time-digits print-diary-entries-hook ps-mode-auto-indent python-shell-output-syntax-table sexp-diary-entry-symbol shr-inhibit-decoration shr-state solar-holidays table-cell-entered-state tildify-count today-invisible-calendar-hook today-visible-calendar-hook tool-bar-originally-present uniquify-ask-about-buffer-names-p vc-default-init-revision vc-disable-async-diff vc-keep-workfiles vc-mcvs-diff-switches vc-mcvs-global-switches vc-mcvs-header vc-mcvs-register-switches vc-mcvs-use-edit vc-mistrust-permissions vc-stay-local view-calendar-holidays-initially view-diary-entries-initially window-system-initialization-alist x-last-selected-text)
+ (added :alternatives :append :argument-precedence-order :async :attribute-groups :authors :certf-item xref-location xref-marker-ring-length xref-match-item xref-mode-local-find-overloadable-regexp xref-prompt-for-identifier xref-show-xrefs-function xterm-mouse-tracking-disable-sequence xterm-mouse-tracking-enable-sequence xterm-mouse-utf-8 xwidget-webkit-activeelement-js xwidget-webkit-last-session-buffer xwidget-webkit-mode-abbrev-table xwidget-webkit-mode-hook xwidget-webkit-mode-map xwidget-webkit-mode-syntax-table))
+ (features
+ (removed authors gnus-setup vc-mcvs w32-common-fns)
+ (added bruce char-fold charscript cl-generic cl-preloaded cl-seq cp51932 cursor-sensor dom ede/detect eieio-compat elisp-mode eucjp-ms generator gnus-cloud inline let-alist map nsm obarray pinentry project sasl-scram-rfc sasl-scram-sha-1 seq thunk url-tramp vc-filewise vc-src xref xwidget)))
+ ((25 2)
+ (functions
+ (removed electric--insertable-p)
+ (added term--xterm-paste tex-handle-newline))
+ (variables
+ (removed)
+ (added inhibit-compacting-font-caches))
+ (features
+ (removed)
+ (added)))
+ ((25 3)
+ (functions
+ (removed)
+ (added))
+ (variables
+ (removed)
+ (added))
+ (features
+ (removed)
+ (added)))
+ ((26 1)
+ (functions
+ (removed 8859-1-map 8859-to-swascii-buffer Buffer-menu-info-node-description Man-quit ad-Advice-find-tag auto-source--symbol-keyword autoload-ensure-default-file c-clear-cpp-delimiters c-comment-out-cpps c-neutralize-syntax-in-and-mark-CPP c-set-cpp-delimiters c-state-semi-safe-place c-uncomment-out-cpps c-with-all-but-one-cpps-commented-out c-with-cpps-commented-out check-declare-errmsg cl-struct-avl-tree- cl-struct-avl-tree--node cl-struct-avl-tree--stack& tramp-completion-run-real-handler tramp-file-name-real-host tramp-file-name-real-user tramp-gw-aux-proc-sentinel tramp-gw-basic-authentication tramp-gw-gw-proc-sentinel tramp-gw-open-connection tramp-gw-open-network-stream tramp-gw-process-filter tramp-handle-unhandled-file-name-directory tramp-set-auto-save-file-modes tramp-sh-handle-dired-recursive-delete-directory tramp-sh-handle-insert-file-contents-literally tramp-user-error undo-auto--undoable-change-no-timer url-cookie-quit verilog-save-font-mods verilog-save-no-change-functions whitespace-ensure-local-variables window--major-non-side-window window--major-side-window window--side-check window--side-window-p window-dot woman-pop woman-push xmltok-forward-special xwidget-webkit-execute-script-rv y-or-n-minibuffer)
+ (added Buffer-menu-unmark-all Buffer-menubsp;xwidget-webkit-scroll-bottom xwidget-webkit-scroll-top xwidget-webkit-show-element xwidget-webkit-zoom-in xwidget-webkit-zoom-out))
+ (variables
+ (removed *orgtbl-default-fmt* *orgtbl-efmt* *orgtbl-fmt* *orgtbl-hline* *orgtbl-lend* *orgtbl-lfmt* *orgtbl-llend* *orgtbl-llfmt* *orgtbl-llstart* *orgtbl-lstart* *orgtbl-rtn* *orgtbl-sep* *orgtbl-table* 8859-1-map 8859-to-swascii-trans :AFTER :BEFORE :ICALENDAR-MARK :alt-title :beamer-header-extra :cf :conc-name :constructor :csep :days :effort-durations :export-block :filter-comment :filter-comment-block :filter-quote-section :footnote-definition-alist :hiddenp :hlsep :hours :html-link-org-as-html :icalendar-agenda-view :inline-definition :json-eof :latex-hyperref-psp;tramp-rfn-eshadow-update-overlay-regexp tramp-warned-obsolete-methods verilog-font-grouping-keywords-face viper-buffer-undo-list-mark viper-undo-needs-adjustment whitespace-indent-tabs-mode whitespace-tab-width window-sides window-text-change-functions woman-justify-list xref--window)
+ (added :--found :--map-first-match :TIMEZONE :UNNUMBERED :activate-func :ascii-art :ascii-bullets :ascii-caption-above :ascii-format-drawer-function :ascii-format-inlinetask-function :ascii-global-margin :ascii-headline-spacing :ascii-indented-line-width :ascii-inlinetask-width :ascii-inner-margin :ascii-links-to-notes :ascii-list-margin :ascii-paragraph-spacing :ascii-quote-margin :ascii-table-keep-all-vertical-lines :ascii-table-use-ascii-art :ascii-table-widen-columns :ascii-text-width :ascii-underline :a-parent-directories while-no-input-ignore-events window--sides-inhibit-check window--sides-shown window-sides-reversed woman-justify-styles woman-mode-abbrev-table woman-mode-hook woman-mode-syntax-table xdg-desktop-entry-regexp xdg-desktop-group-regexp xdg-line-regexp xdg-user-dirs xref--original-window xref--original-window-intent))
+ (features
+ (removed awk-mode gnus-ems gnus-sync iso-acc iso-insert iso-swed messcompat mh-acros nxml-glyph nxml-uchnm ob-scala ob-sh pinentry resume scribe spell swedish sym-comp tramp-gw)
+ (added auth-source-pass charprop cl-print composite dired-loaddefs display-line-numbers eieio-loaddefs flymake-proc gnus-rfc1843 htmlfontify-loaddefs ibuffer-loaddefs isearch less-css-mode mhtml-mode ob-J ob-abc ob-coq ob-ebnf ob-forth ob-groovy ob-hledger ob-lua ob-processing ob-sed ob-shell ob-stan ob-vala org-duration org-eww org-lint pixel-scroll ps-print-loaddefs puny radix-tree reftex-loaddefs replace rmail-loaddefs rmc svg term/tty-colors text-mode timer-list xdg)))
+ ((26 2)
+ (functions
+ (removed dired--yes-no-all-quit-help shadow-get-user shadow-make-cluster shadow-parse-fullname)
+ (added assoc-delete-all calc-graph-w32-p copy-shadow-cluster ibuffer-do-toggle-lock make-shadow-cluster make-shadow-cluster--cmacro package--user-installed-p read-answer shadow-cluster-name--cmacro shadow-cluster-p shadow-cluster-p--cmacro shadow-cluster-primary--cmacro shadow-cluster-regexp--cmacro shadow-name-site shadow-site-name soap-type-of term--bash-needs-EMACSp term-watch-for-password-prompt thread-live-p))
+ (variables
+ (removed dired-delete-help last--line-number-width prolog-hungry-delete-key-flag)
+ (added byte-compile--default-val cl-print--depth cl-struct-shadow-cluster-tags ido-fallback read-answer-map--memoize read-answer-short term--bash-needs-EMACS-status xft-ignore-color-fonts))
+ (features
+ (removed)
+ (added threads)))
+ ((26 3)
+ (functions
+ (removed gnus-summary-sort-by-mark)
+ (added dir-locals--get-sort-score dir-locals--sort-variables gnus-summary-sort-by-marks package--buffer-string package--cs))
+ (variables
+ (removed)
+ (added help-enable-completion-auto-load))
+ (features
+ (removed)
+ (added))))
--- /dev/null
+;;; package-lint-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "package-lint" "package-lint.el" (0 0 0 0))
+;;; Generated autoloads from package-lint.el
+
+(autoload 'package-lint-buffer "package-lint" "\
+Get linter errors and warnings for BUFFER.
+
+Returns a list, each element of which is list of
+
+ (LINE COL TYPE MESSAGE)
+
+where TYPE is either 'warning or 'error.
+
+Current buffer is used if none is specified.
+
+\(fn &optional BUFFER)" nil nil)
+
+(autoload 'package-lint-current-buffer "package-lint" "\
+Display lint errors and warnings for the current buffer.
+
+\(fn)" t nil)
+
+(autoload 'package-lint-batch-and-exit "package-lint" "\
+Run `package-lint-buffer' on the files remaining on the command line.
+Use this only with -batch, it won't work interactively.
+
+When done, exit Emacs with status 0 if there were no errors nor warnings or 1
+otherwise.
+
+\(fn)" nil nil)
+
+(autoload 'package-lint-looks-like-a-package-p "package-lint" "\
+Return non-nil if the current buffer appears to be intended as a package.
+
+\(fn)" nil nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "package-lint" '("package-lint-")))
+
+;;;***
+\f
+;;;### (autoloads nil nil ("package-lint-pkg.el") (0 0 0 0))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; package-lint-autoloads.el ends here
--- /dev/null
+(define-package "package-lint" "20191220.419" "A linting library for elisp package authors"
+ '((cl-lib "0.5")
+ (emacs "24.1")
+ (let-alist "1.0.6"))
+ :keywords
+ '("lisp")
+ :authors
+ '(("Steve Purcell" . "steveNOSPAMsanityinc.com")
+ ("Fanael Linithien" . "fanael4NOSPAMgmail.com"))
+ :maintainer
+ '("Steve Purcell" . "steveNOSPAMsanityinc.com")
+ :url "https://github.com/purcell/package-lint")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
--- /dev/null
+;;; package-lint.el --- A linting library for elisp package authors -*- lexical-binding: t -*-
+
+;; Copyright (C) 2014-2019 Steve Purcell, Fanael Linithien
+
+;; Author: Steve Purcell <steveNOSPAMsanityinc.com>
+;; Fanael Linithien <fanael4NOSPAMgmail.com>
+;; URL: https://github.com/purcell/package-lint
+;; Keywords: lisp
+;; Version: 0
+;; Package-Requires: ((cl-lib "0.5") (emacs "24.1") (let-alist "1.0.6"))
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Provides a list of issues with the package metadata of a file,
+;; e.g. the package dependencies it requires.
+
+;; See function `package-lint-buffer'.
+
+;; Checks will currently be enabled only if a "Package-Requires:" or
+;; "Package-Version:" header is present in the file.
+
+;;; Code:
+
+(eval-when-compile (require 'pcase)) ; `pcase-dolist' is not autoloaded
+(require 'cl-lib)
+(require 'package)
+(require 'lisp-mnt)
+(require 'finder)
+(require 'imenu)
+(require 'let-alist)
+
+\f
+;;; Compatibility
+
+(defalias 'package-lint--package-desc-summary
+ (if (fboundp 'package-desc-summary)
+ 'package-desc-summary
+ 'package-desc-doc))
+
+(defalias 'package-lint--package-desc-name
+ (if (fboundp 'package-desc-name)
+ 'package-desc-name
+ (lambda (desc) (intern (elt desc 0)))))
+
+\f
+;;; Machinery
+
+(defvar package-lint--errors nil
+ "List of errors and warnings for the current buffer.
+This is bound dynamically while the checks run.")
+
+(defconst package-lint-backport-libraries
+ (list (cons 'cl-lib "\\`cl-")
+ (cons 'cl-generic "\\`cl-\\(?:def\\)?generic")
+ (cons 'cl-print "\\`cl-print")
+ (cons 'map "\\`map-")
+ (cons 'nadvice "\\`advice-")
+ (cons 'seq "\\`seq-")
+ (cons 'let-alist "\\`let-alist"))
+ "A sequence of (FEATURE . SYMBOL-NAME-MATCH) for backport libraries.
+These are libraries that are built into newer Emacsen and also
+published in ELPA for use by older Emacsen.")
+
+(eval-and-compile
+ (defun package-lint--match-symbols (symbols)
+ "Return a predicate which take a symbol and reports whether it is among `SYMBOLS'."
+ (let ((tbl (make-hash-table)))
+ (dolist (s symbols)
+ (puthash s t tbl))
+ (lambda (v) (gethash v tbl))))
+
+ (let ((stdlib-changes (with-temp-buffer
+ (insert-file-contents
+ (expand-file-name "data/stdlib-changes"
+ (if load-file-name
+ (file-name-directory load-file-name)
+ default-directory)))
+ (read (current-buffer)))))
+
+ (defconst package-lint--libraries-added-alist
+ (mapcar (lambda (version-data)
+ (let ((version (car version-data))
+ (added-libraries (let-alist (cdr version-data) .features.added)))
+ (cons version (package-lint--match-symbols added-libraries))))
+ stdlib-changes)
+ "An alist of library names and when they were added to Emacs.")
+
+ (defconst package-lint--libraries-removed-alist
+ (mapcar (lambda (version-data)
+ (let ((version (car version-data))
+ (removed-libraries (let-alist (cdr version-data) .features.removed)))
+ (cons version (package-lint--match-symbols removed-libraries))))
+ stdlib-changes)
+ "An alist of library names and when they were added to Emacs.")
+
+ (defconst package-lint--functions-and-macros-added-alist
+ (mapcar (lambda (version-data)
+ (let ((version (car version-data))
+ (added-functions (let-alist (cdr version-data) .functions.added)))
+ (cons version (package-lint--match-symbols added-functions))))
+ stdlib-changes)
+ "An alist of function/macro names and when they were added to Emacs.")
+
+ (defconst package-lint--functions-and-macros-removed-alist
+ (mapcar (lambda (version-data)
+ (let ((version (car version-data))
+ (removed-functions (let-alist (cdr version-data) .functions.removed)))
+ (cons version (package-lint--match-symbols removed-functions))))
+ stdlib-changes)
+ "An alist of function/macro names and when they were removed from Emacs.")))
+
+(defconst package-lint--sane-prefixes
+ (rx
+ string-start
+ (or
+ "org-dblock-write:"
+ "org-babel-execute:"
+ "org-babel-prep-session:"
+ "org-babel-variable-assignments:"
+ "org-babel-default-header-args:"
+ "pcomplete/"))
+ "A regexp matching whitelisted non-standard symbol prefixes.")
+
+(defun package-lint--check-all ()
+ "Return a list of errors/warnings for the current buffer."
+ (let ((package-lint--errors '())
+ (case-fold-search nil))
+ (save-match-data
+ (save-excursion
+ (save-restriction
+ (widen)
+ (package-lint--check-reserved-keybindings)
+ (package-lint--check-keywords-list)
+ (package-lint--check-url-header)
+ (package-lint--check-package-version-present)
+ (package-lint--check-lexical-binding-is-on-first-line)
+ (let ((prefix (package-lint--get-package-prefix)))
+ (package-lint--check-objects-by-regexp
+ "(define-minor-mode\\s-"
+ #'package-lint--check-minor-mode)
+ (package-lint--check-objects-by-regexp
+ "(define-global\\(?:ized\\)?-minor-mode\\s-"
+ #'package-lint--check-globalized-minor-mode)
+ (when prefix
+ (package-lint--check-objects-by-regexp
+ (concat "(" (regexp-opt '("defalias" "defvaralias")) "\\s-")
+ (apply-partially #'package-lint--check-defalias prefix)))
+ (package-lint--check-objects-by-regexp
+ "(defgroup\\s-" #'package-lint--check-defgroup)
+ (let ((desc (package-lint--check-package-el-can-parse)))
+ (when desc
+ (package-lint--check-package-summary desc)
+ (package-lint--check-provide-form desc)
+ (package-lint--check-no-emacs-in-package-name desc)))
+ (package-lint--check-no-use-of-cl)
+ (package-lint--check-no-use-of-cl-lib-sublibraries)
+ (package-lint--check-eval-after-load)
+ (let ((deps (package-lint--check-dependency-list)))
+ (package-lint--check-lexical-binding-requires-emacs-24 deps)
+ (package-lint--check-libraries-available-in-emacs deps)
+ (package-lint--check-libraries-removed-from-emacs)
+ (package-lint--check-macros-functions-available-in-emacs deps)
+ (package-lint--check-macros-functions-removed-from-emacs)
+ (package-lint--check-objects-by-regexp
+ (concat "(" (regexp-opt '("format" "message" "error")) "\\s-")
+ (apply-partially #'package-lint--check-format-string deps)))
+ (package-lint--check-for-literal-emacs-path)
+ (package-lint--check-commentary-existence)
+ (let ((definitions (package-lint--get-defs)))
+ (package-lint--check-autoloads-on-private-functions definitions)
+ (package-lint--check-defs-prefix prefix definitions)
+ (package-lint--check-symbol-separators definitions)))
+ (package-lint--check-lonely-parens))))
+ (sort package-lint--errors
+ (lambda (a b)
+ (pcase-let ((`(,a-line ,a-column ,_ ,a-message) a)
+ (`(,b-line ,b-column ,_ ,b-message) b))
+ (cond
+ ((/= a-line b-line) (< a-line b-line))
+ ((/= a-column b-column) (< a-column b-column))
+ (t
+ (string-lessp a-message b-message))))))))
+
+(defun package-lint--error (line col type message)
+ "Construct a datum for error at LINE and COL with TYPE and MESSAGE."
+ (push (list line col type message) package-lint--errors))
+
+(defun package-lint--error-at-point (type message &optional pos)
+ "Construct a datum for error at POS with TYPE and MESSAGE.
+POS defaults to `point'."
+ (save-excursion
+ (when pos
+ (goto-char pos))
+ (package-lint--error (line-number-at-pos) (current-column) type message)))
+
+(defun package-lint--error-at-bol (type message)
+ "Construct a datum for error at the beginning of the current line with TYPE and MESSAGE."
+ (package-lint--error (line-number-at-pos) 0 type message))
+
+(defun package-lint--error-at-bob (type message)
+ "Construct a datum for error at the beginning of the buffer with TYPE and MESSAGE."
+ (package-lint--error 1 0 type message))
+
+\f
+;;; Checks
+
+(defun package-lint--check-reserved-keybindings ()
+ "Warn about reserved keybindings."
+ (let ((re (rx "(" (*? space) (or "kbd" "global-set-key" "local-set-key" "define-key") symbol-end)))
+ (goto-char (point-min))
+ (while (re-search-forward re nil t)
+ (unless (nth 8 (save-match-data (syntax-ppss)))
+ ;; Read form and get key-sequence
+ (goto-char (match-beginning 0))
+ (let ((seq (package-lint--extract-key-sequence
+ (read (current-buffer)))))
+ (when seq
+ (let ((message (package-lint--test-keyseq seq)))
+ (when message
+ (package-lint--error-at-point 'warning message)))))))))
+
+(defun package-lint--check-commentary-existence ()
+ "Warn about nonexistent or empty commentary section."
+ (let ((start (lm-commentary-start)))
+ (if (null start)
+ (package-lint--error-at-bob
+ 'error
+ "Package should have a ;;; Commentary section.")
+ ;; Skip over the section header.
+ (goto-char start)
+ (forward-line)
+ (when (package-lint--region-empty-p (point) (lm-commentary-end))
+ (package-lint--error-at-point
+ 'error
+ "Package should have a non-empty ;;; Commentary section."
+ start)))))
+
+(defun package-lint--check-autoloads-on-private-functions (definitions)
+ "Verify that private functions DEFINITIONS don't have autoload cookies."
+ (pcase-dolist (`(,symbol . ,position) definitions)
+ (when (string-match-p (rx "--") symbol)
+ (goto-char position)
+ (forward-line -1)
+ (when (looking-at-p (rx ";;;###autoload"))
+ (package-lint--error-at-point
+ 'warning
+ "Private functions generally should not be autoloaded.")))))
+
+(defun package-lint--check-for-literal-emacs-path ()
+ "Verify package does not refer to \"\.emacs\.d\" literally.
+Instead it should use `user-emacs-directory' or `locate-user-emacs-file'."
+ (goto-char (point-min))
+ ;; \b won't find a word boundary between a symbol and the "." in
+ ;; ".emacs.d". / is a valid symbol constituent in Emacs Lisp, so
+ ;; must be explicitly blacklisted.
+ (while (re-search-forward "\\(?:\\_<\\|/\\)\\.emacs\\.d\\b" nil t)
+ (unless (nth 4 (syntax-ppss))
+ ;; Not in a comment
+ (package-lint--error-at-point
+ 'warning
+ "Use variable `user-emacs-directory' or function `locate-user-emacs-file' instead of a literal path to the Emacs user directory or files."))))
+
+(defun package-lint--check-keywords-list ()
+ "Verify that package keywords are listed in `finder-known-keywords'."
+ (when (package-lint--goto-header "Keywords")
+ (let ((err-pos (match-beginning 2)))
+ (let ((keywords (lm-keywords-list)))
+ (unless (cl-some (lambda (keyword) (assoc (intern keyword) finder-known-keywords)) keywords)
+ (package-lint--error-at-point
+ 'warning
+ (format "You should include standard keywords: see the variable `finder-known-keywords'.")
+ err-pos))))))
+
+(defun package-lint--check-url-header ()
+ "Verify that the package has an HTTPS or HTTP Homepage/URL header."
+ (if (package-lint--goto-header "\\(?:URL\\|Homepage\\)")
+ (let ((url (match-string 3))
+ (url-start (match-beginning 3)))
+ (unless (and (equal (thing-at-point 'url) url)
+ (string-match-p "^https?://" url))
+ (package-lint--error-at-point
+ 'error
+ "Package URLs should be a single HTTPS or HTTP URL."
+ url-start)))
+ (package-lint--error-at-bob
+ 'error
+ "Package should have a Homepage or URL header.")))
+
+(defun package-lint--check-dependency-list ()
+ "Check the contents of the \"Package-Requires\" header.
+Return a list of well-formed dependencies, same as
+`package-lint--check-well-formed-dependencies'."
+ (when (package-lint--goto-header "Package-Requires")
+ (let ((position (match-beginning 3))
+ (deps (match-string 3)))
+ (condition-case err
+ (pcase-let ((`(,parsed-deps . ,parse-end-pos) (read-from-string deps)))
+ (unless (= parse-end-pos (length deps))
+ (package-lint--error-at-bol
+ 'error
+ "More than one expression provided."))
+ (let ((deps (package-lint--check-well-formed-dependencies position parsed-deps)))
+ (package-lint--check-packages-installable deps)
+ (package-lint--check-deps-use-non-snapshot-version deps)
+ (package-lint--check-deps-do-not-use-zero-versions deps)
+ (package-lint--check-do-not-depend-on-cl-lib-1.0 deps)
+ deps))
+ (error
+ (package-lint--error-at-bol
+ 'error
+ (format "Couldn't parse \"Package-Requires\" header: %s" (error-message-string err)))
+ nil)))))
+
+(defun package-lint--check-well-formed-dependencies (position parsed-deps)
+ "Check that dependencies listed at POSITION are well-formed.
+These PARSED-DEPS must have the format (name \"version\").
+Return a list of well-formed dependencies, where each element is of
+the form (PACKAGE-NAME PACKAGE-VERSION DEP-POSITION)."
+ (let (valid-deps)
+ (dolist (entry parsed-deps)
+ (pcase entry
+ ((and `(,package-name ,package-version)
+ (guard (symbolp package-name))
+ (guard (stringp package-version)))
+ ;; Find the column at which the dependency is declared so we can
+ ;; properly report the position of errors.
+ (let ((dep-pos
+ (save-excursion
+ (goto-char position)
+ (let ((pattern
+ (format "( *\\(%s\\)\\(?:)\\|[^[:alnum:]_\\-].*?)\\)"
+ (regexp-quote (symbol-name package-name)))))
+ (if (re-search-forward pattern (line-end-position) t)
+ (match-beginning 1)
+ position)))))
+ (if (ignore-errors (version-to-list package-version))
+ (push (list package-name
+ (version-to-list package-version)
+ dep-pos)
+ valid-deps)
+ (package-lint--error-at-point
+ 'error
+ (format "%S is not a valid version string: see `version-to-list'."
+ package-version)
+ dep-pos))))
+ (_
+ (package-lint--error-at-bol
+ 'error
+ (format "Expected (package-name \"version-num\"), but found %S." entry)))))
+ valid-deps))
+
+(defun package-lint--check-package-installable (archive-entry package-version dep-pos)
+ "Check that ARCHIVE-ENTRY is installable from a configured package archive.
+
+Check that package described by ARCHIVE-ENTRY can be installed at
+required version PACKAGE-VERSION. If not, raise an error for DEP-POS."
+ (let* ((package-name (car archive-entry))
+ (best-version (package-lint--highest-installable-version-of package-name)))
+ (when (version-list-< best-version package-version)
+ (package-lint--error-at-point
+ 'warning
+ (format "Version dependency for %s appears too high: try %s" package-name
+ (package-version-join best-version))
+ dep-pos))))
+
+(defun package-lint--check-packages-installable (valid-deps)
+ "Check that all VALID-DEPS are available for installation."
+ (pcase-dolist (`(,package-name ,package-version ,dep-pos) valid-deps)
+ (if (eq 'emacs package-name)
+ (unless (version-list-<= '(24) package-version)
+ (package-lint--error-at-point
+ 'error
+ "You can only depend on Emacs version 24 or greater: package.el for Emacs 23 does not support the \"emacs\" pseudopackage."
+ dep-pos))
+ ;; Not 'emacs
+ (let ((archive-entry (assq package-name package-archive-contents)))
+ (if archive-entry
+ (package-lint--check-package-installable archive-entry package-version dep-pos)
+ (package-lint--error-at-point
+ 'error
+ (format "Package %S is not installable." package-name)
+ dep-pos))))))
+
+(defun package-lint--check-deps-use-non-snapshot-version (valid-deps)
+ "Warn about any VALID-DEPS on snapshot versions of packages."
+ (pcase-dolist (`(,package-name ,package-version ,dep-pos) valid-deps)
+ (unless (version-list-< package-version '(19001201 1))
+ (package-lint--error-at-point
+ 'warning
+ (format "Use a non-snapshot version number for dependency on \"%S\" if possible."
+ package-name)
+ dep-pos))))
+
+(defun package-lint--check-deps-do-not-use-zero-versions (valid-deps)
+ "Warn about VALID-DEPS on \"0\" versions of packages."
+ (pcase-dolist (`(,package-name ,package-version ,dep-pos) valid-deps)
+ (when (equal package-version '(0))
+ (package-lint--error-at-point
+ 'warning
+ (format "Use a properly versioned dependency on \"%S\" if possible."
+ package-name)
+ dep-pos))))
+
+(defun package-lint--check-lexical-binding-requires-emacs-24 (valid-deps)
+ "Warn about use of `lexical-binding' when Emacs 24 is not among VALID-DEPS."
+ (goto-char (point-min))
+ (when (package-lint--lexical-binding-declared-in-header-line-p)
+ (unless (assq 'emacs valid-deps)
+ (package-lint--error-at-point
+ 'warning
+ "You should depend on (emacs \"24\") if you need lexical-binding."
+ (match-beginning 1)))))
+
+(defun package-lint--inside-comment-or-string-p ()
+ "Return non-nil if point is inside a comment or string."
+ (let ((ppss (save-match-data (syntax-ppss))))
+ (or (nth 3 ppss) (nth 4 ppss))))
+
+(defun package-lint--seen-fboundp-check-for (sym)
+ "Return non-nil if a `fboundp' check for SYM is present before point."
+ (save-excursion
+ (save-match-data
+ (and (re-search-backward
+ (concat "(fboundp\\s-+'" (regexp-quote sym) "\\_>") (point-min) t)
+ (not (package-lint--inside-comment-or-string-p))))))
+
+(defun package-lint--map-regexp-match (regexp callback)
+ "For every match of REGEXP, call CALLBACK with the first match group.
+If callback returns non-nil, the return value - which must be a
+list - will be applied to `package-lint--error-at-point'. If
+REGEXP doesn't produce a match group 1, then match group
+0 (ie. the whole match string string) will be passed to
+CALLBACK."
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward regexp nil t)
+ (let ((sym (or (match-string-no-properties 1)
+ (match-string-no-properties 0))))
+ (save-excursion
+ (goto-char (or (match-beginning 1)
+ (match-beginning 0)))
+ (let ((err (funcall callback sym)))
+ (when err
+ ;; Check this as late as possible, just before reporting,
+ ;; because otherwise the checking process is extremely slow,
+ ;; being bottlenecked by `syntax-ppss'.
+ (unless (package-lint--inside-comment-or-string-p)
+ (apply #'package-lint--error-at-point err)))))))))
+
+(defun package-lint--check-version-regexp-list (valid-deps list symbol-regexp type)
+ "Warn if symbols matched by SYMBOL-REGEXP are unavailable in the target Emacs.
+The target Emacs version is taken from VALID-DEPS, which are the
+declared dependencies of this package. LIST is an alist
+of (VERSION . PRED), where PRED is passed the sym. TYPE is the
+type of the symbol, either FUNCTION or FEATURE."
+ (let ((emacs-version-dep (or (cadr (assq 'emacs valid-deps)) '(0))))
+ (pcase-dolist (`(,added-in-version . ,pred) list)
+ (when (version-list-< emacs-version-dep added-in-version)
+ (package-lint--map-regexp-match
+ symbol-regexp
+ (lambda (sym)
+ (when (funcall pred (intern sym))
+ (unless (and (eq type 'function) (package-lint--seen-fboundp-check-for sym))
+ (let ((available-backport
+ (cond
+ ((eq type 'feature)
+ (cl-some (lambda (bp)
+ (when (string= (car bp) sym)
+ (car bp)))
+ package-lint-backport-libraries))
+ ((eq type 'function)
+ (cl-some (lambda (bp)
+ (when (string-match-p (cdr bp) sym)
+ (car bp)))
+ package-lint-backport-libraries)))))
+ (unless (and available-backport (assoc available-backport valid-deps))
+ (list
+ 'error
+ (format "You should depend on (emacs \"%s\")%s if you need `%s'."
+ (mapconcat #'number-to-string added-in-version ".")
+ (if available-backport
+ (format " or the %s package" available-backport)
+ "")
+ sym))))))))))))
+
+(defun package-lint--check-eval-after-load ()
+ "Warn about use of `eval-after-load' and co."
+ (package-lint--map-regexp-match
+ "(\\s-*?\\(\\(?:with-\\)?eval-after-load\\)\\_>"
+ (lambda (match)
+ (list 'warning
+ (format "`%s' is for use in configurations, and should rarely be used in packages." match)))))
+
+(defun package-lint--check-no-use-of-cl ()
+ "Warn about use of deprecated `cl' library."
+ (package-lint--map-regexp-match
+ "(\\s-*?require\\s-*?'\\(cl\\)\\_>"
+ (lambda (_)
+ (list
+ 'warning
+ "Replace deprecated `cl' with `cl-lib'. The `cl-libify' package can help with this."))))
+
+(defun package-lint--check-no-use-of-cl-lib-sublibraries ()
+ "Warn about use of `cl-macs', `cl-seq' etc."
+ (package-lint--map-regexp-match
+ "(\\s-*?require\\s-*?'\\(cl-macs\\|cl-seq\\)\\_>"
+ (lambda (_)
+ (list
+ 'warning
+ "This file is not in the `cl-lib' ELPA compatibility package: require `cl-lib' instead."))))
+
+(defconst package-lint--unconditional-require-regexp
+ ;; Match the ending paren so we can be sure it's a single argument
+ ;; `require'. If there are additional arguments, we don't want to warn,
+ ;; because (require 'foo nil t) indicates an optional dependency and
+ ;; (require 'foo "filename") is very uncommon.
+ "(\\s-*?require\\s-*?'\\_<\\(.*?\\)\\_>\\s-*?)"
+ "Regexp to match unconditional `require' forms.")
+
+(defun package-lint--check-libraries-available-in-emacs (valid-deps)
+ "Warn about use of libraries that are not available in the Emacs version in VALID-DEPS."
+ (package-lint--check-version-regexp-list
+ valid-deps
+ package-lint--libraries-added-alist
+ package-lint--unconditional-require-regexp
+ 'feature))
+
+(defun package-lint--check-libraries-removed-from-emacs ()
+ "Warn about use of libraries that have been removed from Emacs."
+ (package-lint--map-regexp-match
+ package-lint--unconditional-require-regexp
+ (lambda (sym)
+ (cl-block return
+ (pcase-dolist (`(,removed-in-version . ,pred) package-lint--libraries-removed-alist)
+ (when (funcall pred (intern sym))
+ (cl-return-from return
+ (list
+ 'error
+ (format "The `%s' library was removed in Emacs version %s."
+ sym (mapconcat #'number-to-string removed-in-version "."))))))))))
+
+(defconst package-lint--function-name-regexp
+ "\\(?:#'\\|(\\s-*?\\)\\(.*?\\)\\_>"
+ "Regexp to match function names.")
+
+(defun package-lint--check-macros-functions-available-in-emacs (valid-deps)
+ "Warn about use of functions/macros that are not available in the Emacs version in VALID-DEPS."
+ (package-lint--check-version-regexp-list
+ valid-deps
+ package-lint--functions-and-macros-added-alist
+ package-lint--function-name-regexp
+ 'function))
+
+(defun package-lint--check-macros-functions-removed-from-emacs ()
+ "Warn about use of functions/macros that have been removed from Emacs."
+ (package-lint--map-regexp-match
+ package-lint--function-name-regexp
+ (lambda (sym)
+ (cl-block return
+ (pcase-dolist (`(,removed-in-version . ,pred) package-lint--functions-and-macros-removed-alist)
+ (when (funcall pred (intern sym))
+ (cl-return-from return
+ (list
+ 'error
+ (format "`%s' was removed in Emacs version %s."
+ sym (mapconcat #'number-to-string removed-in-version "."))))))))))
+
+(defun package-lint--check-lexical-binding-is-on-first-line ()
+ "Check that any `lexical-binding' declaration is on the first line of the file."
+ (cl-block return
+ (let ((original-buffer (current-buffer)))
+ (with-temp-buffer
+ (let ((lexical-binding-found-at-end nil))
+ (insert-buffer-substring-no-properties original-buffer)
+ (condition-case err
+ (cl-letf (((symbol-function #'hack-local-variables-apply) #'ignore)
+ ((symbol-function #'hack-local-variables-filter)
+ (lambda (variables _dir-name)
+ (setq file-local-variables-alist variables)))
+ ;; Silence any messages Emacs may want to share with the user.
+ ;; There's no user.
+ ((symbol-function #'display-warning) #'ignore)
+ ((symbol-function #'message) #'ignore))
+ ;; HACK: this is an internal variable!
+ ;; Unfortunately, Emacsen that have this variable also have
+ ;; `hack-local-variables' that doesn't store `lexical-binding'
+ ;; in `file-local-variables-alist'.
+ (defvar enable-dir-local-variables)
+ (defvar hack-local-variables--warned-lexical)
+ (let ((hack-local-variables--warned-lexical nil)
+ (enable-dir-local-variables nil)
+ (enable-local-variables t)
+ (local-enable-local-variables t))
+ (hack-local-variables)
+ (setq lexical-binding-found-at-end
+ hack-local-variables--warned-lexical)))
+ (error
+ (package-lint--error-at-bob 'error (error-message-string err))
+ (cl-return-from return nil)))
+ (when (or lexical-binding-found-at-end
+ ;; In case this is an Emacs from before `hack-local-variables'
+ ;; started to warn about `lexical-binding' on a line other
+ ;; than the first.
+ (and (cdr (assq 'lexical-binding file-local-variables-alist))
+ (not (package-lint--lexical-binding-declared-in-header-line-p))))
+ (package-lint--error-at-bob
+ 'error
+ "`lexical-binding' must be set in the first line.")))))))
+
+(defun package-lint--check-do-not-depend-on-cl-lib-1.0 (valid-deps)
+ "Check that any dependency in VALID-DEPS on \"cl-lib\" is on a remotely-installable version."
+ (let ((cl-lib-dep (assq 'cl-lib valid-deps)))
+ (when cl-lib-dep
+ (let ((cl-lib-version (nth 1 cl-lib-dep)))
+ (when (version-list-<= '(1) cl-lib-version)
+ (package-lint--error-at-point
+ 'error
+ (format "Depend on the latest 0.x version of cl-lib rather than on version \"%S\".
+Alternatively, depend on (emacs \"24.3\") or greater, in which cl-lib is bundled."
+ cl-lib-version)
+ (nth 2 cl-lib-dep)))))))
+
+(defun package-lint--check-package-version-present ()
+ "Check that a valid \"Version\" header is present."
+ (let ((version (package-lint--goto-header (rx (? "Package-") "Version"))))
+ (if version
+ (unless (ignore-errors (version-to-list version))
+ (package-lint--error-at-point
+ 'warning
+ (format "\"%s\" is not a valid version. MELPA will handle this, but other archives will not." version)
+ (match-beginning 3)))
+ (package-lint--error-at-bob
+ 'warning
+ "\"Version:\" or \"Package-Version:\" header is missing. MELPA will handle this, but other archives will not."))))
+
+(defun package-lint--check-package-el-can-parse ()
+ "Check that `package-buffer-info' can read metadata from this file.
+If it can, return the read metadata."
+ (condition-case err
+ (let ((orig-buffer (current-buffer)))
+ ;; We've reported version header issues separately, so rule them out here
+ (with-temp-buffer
+ (insert-buffer-substring-no-properties orig-buffer)
+ (package-lint--update-or-insert-version "0")
+ (package-buffer-info)))
+ (error
+ (package-lint--error-at-bob
+ 'error
+ (format "package.el cannot parse this buffer: %s" (error-message-string err)))
+ nil)))
+
+(defun package-lint--check-package-summary (desc)
+ "Check the summary for package with descriptor DESC.
+DESC is a struct as returned by `package-buffer-info'."
+ (let ((summary (package-lint--package-desc-summary desc)))
+ (cond
+ ((string= summary "")
+ (package-lint--error-at-bob
+ 'warning
+ "Package should have a non-empty summary."))
+ (t
+ (unless (let ((case-fold-search nil))
+ (string-match-p "^[A-Z0-9]" summary))
+ (package-lint--error-at-bob
+ 'warning
+ "The package summary should start with an uppercase letter or a digit."))
+ (when (> (length summary) 60)
+ (package-lint--error-at-bob
+ 'warning
+ "The package summary is too long. It should be at most 60 characters."))
+ (when (string-match "\\.\\'" summary)
+ (package-lint--error-at-bob
+ 'warning
+ "The package summary should not end with a period."))
+ (when (save-match-data
+ (let ((case-fold-search t))
+ (and (string-match "[^.]\\<emacs\\>" summary)
+ (not (string-match-p "[[:space:]]+lisp"
+ summary (match-end 0))))))
+ (package-lint--error-at-bob
+ 'warning
+ "Including \"Emacs\" in the package summary is usually redundant."))))))
+
+(defun package-lint--check-provide-form (desc)
+ "Check the provide form for package with descriptor DESC.
+DESC is a struct as returned by `package-buffer-info'."
+ (let ((name (package-lint--package-desc-name desc))
+ (feature (package-lint--provided-feature)))
+ (unless (string-equal (symbol-name name) feature)
+ (package-lint--error-at-bob
+ 'error
+ (format "There is no (provide '%s) form." name)))))
+
+(defun package-lint--check-no-emacs-in-package-name (desc)
+ "Check that the package name doesn't contain \"emacs\".
+DESC is a struct as returned by `package-buffer-info'."
+ (let ((name (package-lint--package-desc-name desc)))
+ (when (string-match-p "emacs" (symbol-name name))
+ (package-lint--error-at-bob
+ 'warning
+ "The word \"emacs\" is redundant in Emacs package names."))))
+
+(defun package-lint--check-symbol-separators (definitions)
+ "Check that symbol DEFINITIONS don't contain non-standard separators."
+ (pcase-dolist (`(,name . ,position) definitions)
+ (when (and (string-match "[:/]" name)
+ (not (string-match-p package-lint--sane-prefixes name)))
+ (let ((match-pos (match-beginning 0)))
+ ;; As a special case, allow `/=' when at the end of a symbol.
+ (when (or (not (string-match (rx "/=" string-end) name))
+ (/= match-pos (match-beginning 0)))
+ (goto-char position)
+ (package-lint--error
+ (line-number-at-pos) 0 'error
+ (format "`%s' contains a non-standard separator `%s', use hyphens instead (see Elisp Coding Conventions)."
+ name (substring-no-properties name match-pos (1+ match-pos)))))))))
+
+(defun package-lint--valid-definition-name-p (name prefix &optional position)
+ "Return non-nil if NAME denotes a valid definition name.
+
+Valid definition names are:
+
+- a NAME starting with PREFIX, a string representing the current
+ package prefix,
+
+- a NAME matching `package-lint--sane-prefixes', or
+
+- a NAME whose POSITION in the buffer denotes a global definition."
+ (or (string-prefix-p prefix name)
+ (string-match-p package-lint--sane-prefixes name)
+ (string-match-p (rx-to-string `(seq string-start (or "define" "defun" "defvar" "with") "-" ,prefix)) name)
+ (string-match-p (rx-to-string `(seq string-start "global-" ,prefix (or "-mode" (seq "-" (* any) "-mode")) string-end)) name)
+ (when position
+ (goto-char position)
+ (looking-at-p (rx (*? space) "(" (*? space)
+ (or "defadvice" "cl-defmethod")
+ symbol-end)))))
+
+(defun package-lint--check-defs-prefix (prefix definitions)
+ "Verify that symbol DEFINITIONS start with package PREFIX."
+ (pcase-dolist (`(,name . ,position) definitions)
+ (unless (package-lint--valid-definition-name-p name prefix position)
+ (package-lint--error-at-point
+ 'error
+ (format "\"%s\" doesn't start with package's prefix \"%s\"."
+ name prefix)
+ position))))
+
+(defun package-lint--check-minor-mode (def)
+ "Offer up concerns about the minor mode definition DEF."
+ (when (cl-search '(:global t) def)
+ (package-lint--check-globalized-minor-mode def)))
+
+(defun package-lint--check-globalized-minor-mode (def)
+ "Offer up concerns about the global minor mode definition DEF."
+ (let ((feature-name (package-lint--provided-feature)))
+ (when feature-name
+ (let ((feature (intern feature-name))
+ (autoloaded (save-excursion
+ (forward-line -1)
+ (beginning-of-line)
+ (looking-at ";;;###autoload"))))
+ (unless (or autoloaded
+ (cl-search `(:require ',feature) def :test #'equal))
+ (package-lint--error-at-point
+ 'error
+ (format
+ "Global minor modes should be autoloaded or, rarely, `:require' their defining file (i.e. \":require '%s\"), to support the customization variable of the same name." feature)))))))
+
+(defun package-lint--check-defgroup (def)
+ "Offer up concerns about the customization group definition DEF."
+ (when (symbolp (cadr def))
+ (let ((group-name (symbol-name (cadr def))))
+ (when (string-match "\\(.*\\)-mode$" group-name)
+ (let ((parent (intern (match-string 1 group-name))))
+ (unless (cl-search `(:group ',parent) def :test #'equal)
+ (package-lint--error-at-point
+ 'error
+ "Customization groups should not end in \"-mode\" unless that name would conflict with their parent group."))))))
+
+ (unless (memq :group def)
+ (package-lint--error-at-point
+ 'error
+ "Customization groups should specify a parent via `:group'.")))
+
+(defun package-lint--check-defalias (prefix def)
+ "Offer up concerns about the customization group definition DEF.
+PREFIX is the package prefix."
+ (pcase (cadr def)
+ ((and `(quote ,alias) (guard (symbolp alias)))
+ (unless (package-lint--valid-definition-name-p (symbol-name alias) prefix)
+ (package-lint--error-at-point
+ 'error
+ (concat "Aliases should start with the package's prefix \"" prefix "\"."))))))
+
+(defun package-lint--check-format-string (valid-deps def)
+ "Offer up concerns about the format string used in DEF, depending on VALID-DEPS."
+ (let ((emacs-version-dep (or (cadr (assq 'emacs valid-deps)) '(0))))
+ (when (consp (cdr def))
+ (let ((fmt-str (cadr def)))
+ (when (and (version-list-< emacs-version-dep '(26 1))
+ ;; We give up on trying to warn about format strings that are
+ ;; evaluated at runtime.
+ (stringp fmt-str)
+ ;; The usual regexp strategy for finding unescaped matches
+ ;; requires negative lookbehind:
+ ;; (?<!%)(?:%%)*[0-9]+\$
+ ;; So instead we make sure the count of escape chars is odd
+ (string-match "\\(%+\\)[0-9]+\\$" fmt-str)
+ (cl-oddp (length (match-string 1 fmt-str))))
+ (package-lint--error-at-point
+ 'error
+ "You should depend on (emacs \"26.1\") if you need format field numbers."))))))
+
+(defun package-lint--check-lonely-parens ()
+ "Warn about dangling closing parens."
+ (package-lint--map-regexp-match
+ "^\\s-*?\\()\\)"
+ (lambda (_)
+ ;; Allow dangling parentheses if the preceding line ends with a comment, as
+ ;; it's not uncommon even in idiomatic lisp.
+ (when (save-excursion
+ (end-of-line 0)
+ (not (nth 4 (syntax-ppss))))
+ (list 'warning
+ "Closing parens should not be wrapped onto new lines.")))))
+
+
+\f
+;;; Helpers
+
+(defun package-lint--extract-key-sequence (form)
+ "Extract the key sequence from FORM."
+ (pcase form
+ (`(kbd ,seq)
+ (package-lint--extract-key-sequence seq))
+ ((or `(global-set-key ,seq ,_) `(local-set-key ,seq ,_))
+ (package-lint--extract-key-sequence seq))
+ (`(define-key ,_ ,seq ,_)
+ (package-lint--extract-key-sequence seq))
+ ((pred stringp)
+ (listify-key-sequence (read-kbd-macro form)))
+ ((pred vectorp)
+ (unless (listp (elt form 0))
+ (listify-key-sequence form)))))
+
+(defun package-lint--test-keyseq (lks)
+ "Return a message if the listified key sequence LKS is invalid, otherwise nil."
+ (let* ((modifiers (event-modifiers lks))
+ (basic-type (event-basic-type lks)))
+ (when (or (and (> (length lks) 1) (equal (car (last lks)) ?\C-g))
+ (and (equal (car (last lks)) ?\e)
+ (not (equal (nthcdr (- (length lks) 2) lks)
+ '(?\e ?\e))))
+ (equal (car (last lks)) ?\C-h)
+ (and (equal modifiers '(control))
+ (equal ?c basic-type)
+ (cdr lks)
+ (let ((v (event-basic-type (cdr lks)))
+ (m (event-modifiers (cdr lks))))
+ (and (numberp v)
+ (<= v ?z)
+ (>= v ?a)
+ (or (null m) (equal '(shift) m)))))
+ (member basic-type '(f5 f6 f7 f8 f9)))
+ "This key sequence is reserved (see Key Binding Conventions in the Emacs Lisp manual)")))
+
+(defun package-lint--region-empty-p (start end)
+ "Return t iff the region between START and END has no non-empty lines.
+
+Lines consisting only of whitespace or empty comments are considered empty."
+ (save-excursion
+ (save-restriction
+ (let ((inhibit-changing-match-data t))
+ (narrow-to-region start end)
+ (goto-char start)
+ (while (and (looking-at "^[[:space:]]*;*[[:space:]]*$")
+ (= 0 (forward-line))))
+ (eobp)))))
+
+(defun package-lint--highest-installable-version-of (package)
+ "Return the highest version of PACKAGE available for installation."
+ (let ((descriptors (cdr (assq package package-archive-contents))))
+ (if (fboundp 'package-desc-version)
+ (car (sort (mapcar 'package-desc-version descriptors)
+ (lambda (v1 v2) (not (version-list-< v1 v2)))))
+ (aref descriptors 0))))
+
+(defun package-lint--goto-header (header-name)
+ "Move to the first occurrence of HEADER-NAME in the file.
+If the return value is non-nil, then point will be at the end of
+the file, and the second and third match groups will contain the name and
+value of the header with any leading or trailing whitespace removed."
+ (let ((initial-point (point)))
+ (goto-char (point-min))
+ (let ((case-fold-search t))
+ (if (re-search-forward (concat (lm-get-header-re header-name) "\\(.*?\\) *$") nil t)
+ (match-string-no-properties 3)
+ (goto-char initial-point)
+ nil))))
+
+(defun package-lint--update-or-insert-version (version)
+ "Ensure current buffer has a \"Version: VERSION\" header."
+ (if (package-lint--goto-header "Version")
+ (move-beginning-of-line nil)
+ (forward-line))
+ (insert (format ";; Version: %s" version))
+ (newline))
+
+(defun package-lint--get-header-line-file-local-variables ()
+ "Return local variables specified in the -*- line.
+Returns an alist of elements (VAR . VAL), where VAR is a variable
+and VAL is the specified value.
+
+For details, see `hack-local-variables-prop-line'."
+ (cl-letf (((symbol-function #'message) #'ignore))
+ (hack-local-variables-prop-line)))
+
+(defun package-lint--lexical-binding-declared-in-header-line-p ()
+ "Test if `lexical-binding' is declared in the -*- line."
+ ;; Test the `cdr' to see if it's actually true, because
+ ;; -*- lexical-binding: nil -*-
+ ;; is legal, if silly.
+ (cdr (assq 'lexical-binding (package-lint--get-header-line-file-local-variables))))
+
+(defvar semantic-imenu-summary-function)
+
+(defun package-lint--get-defs ()
+ "Return a list of all variables and functions defined in the current buffer.
+
+The returned list is of the form (SYMBOL-NAME . POSITION)."
+ ;; We probably could use Semantic instead, but it's a *global* minor mode and
+ ;; it tends to be quite heavy, so use Imenu instead; if the user has Semantic
+ ;; enabled, Imenu will use its index anyway.
+ (let ((result '())
+ (index
+ (save-excursion
+ ;; Use the default imenu expression list so that we're not confused
+ ;; by user customizations.
+ (let ((imenu-generic-expression lisp-imenu-generic-expression)
+ ;; In case it's actually Semantic, tell it not to decorate
+ ;; symbol names.
+ (semantic-imenu-summary-function 'semantic-format-tag-name))
+ (funcall imenu-create-index-function)))))
+ (dolist (entry index)
+ (pcase entry
+ ((and `(,submenu-name . ,submenu-elements)
+ (guard (consp submenu-elements)))
+ (when (member submenu-name '("Variables" "Defuns"))
+ (setq result (nconc (reverse submenu-elements) result))))
+ (_
+ (push entry result))))
+ ;; If it's Semantic, then it returns overlays, not positions. Convert
+ ;; them.
+ (dolist (entry result)
+ (when (overlayp (cdr entry))
+ (setcdr entry (overlay-start (cdr entry)))))
+ (nreverse result)))
+
+(defun package-lint--provided-feature ()
+ "Return the first-provided feature name, as a string, or nil if none."
+ (save-excursion
+ (goto-char (point-max))
+ (cond ((re-search-backward (rx "(provide '" (group (1+ (or (syntax word) (syntax symbol))))) nil t)
+ (match-string-no-properties 1))
+ ((re-search-backward "(provide-me)" nil t)
+ (file-name-sans-extension (file-name-nondirectory buffer-file-name))))))
+
+(defun package-lint--get-package-prefix ()
+ "Return package prefix string (i.e. the symbol the package `provide's).
+Prefix is returned without any `-mode' suffix."
+ (let ((feature (package-lint--provided-feature)))
+ (when feature
+ (replace-regexp-in-string "-mode\\'" "" feature))))
+
+(defun package-lint--check-objects-by-regexp (regexp function)
+ "Check all objects with the literal printed form matching REGEXP.
+
+The objects are parsed with `read'. The FUNCTION is passed the
+read object, with the point at the beginning of the match.
+
+S-expressions in comments or comments, partial s-expressions, or
+otherwise invalid read forms are ignored."
+ (goto-char (point-min))
+ (while (re-search-forward regexp nil t)
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (let ((obj (unless (package-lint--inside-comment-or-string-p)
+ (save-excursion
+ (ignore-errors (read (current-buffer)))))))
+ (when obj (funcall function obj))))))
+
+\f
+;;; Public interface
+
+;;;###autoload
+(defun package-lint-buffer (&optional buffer)
+ "Get linter errors and warnings for BUFFER.
+
+Returns a list, each element of which is list of
+
+ (LINE COL TYPE MESSAGE)
+
+where TYPE is either 'warning or 'error.
+
+Current buffer is used if none is specified."
+ (with-current-buffer (or buffer (current-buffer))
+ (package-lint--check-all)))
+
+;;;###autoload
+(defun package-lint-current-buffer ()
+ "Display lint errors and warnings for the current buffer."
+ (interactive)
+ (let ((errs (package-lint-buffer))
+ (buf "*Package-Lint*"))
+ (with-current-buffer (get-buffer-create buf)
+ (let ((buffer-read-only nil))
+ (erase-buffer)
+ (cond
+ ((null errs) (insert "No issues found."))
+ ((null (cdr errs)) (insert "1 issue found:\n\n"))
+ (t (insert (format "%d issues found:\n\n" (length errs)))))
+ (pcase-dolist (`(,line ,col ,type ,message) errs)
+ (insert (format "%d:%d: %s: %s\n" line col type message))))
+ (special-mode)
+ (view-mode 1))
+ (display-buffer buf)))
+
+(defun package-lint-batch-and-exit-1 (filenames)
+ "Internal helper function for `package-lint-batch-and-exit'.
+
+Checks FILENAMES using package-lint.
+
+The main loop is this separate function so it's easier to test."
+ ;; Make sure package.el is initialized so we can query its database.
+ (package-initialize)
+ (let ((success t) (last-directory nil) (text-quoting-style 'grave))
+ (dolist (file filenames success)
+ (let* ((file (expand-file-name file))
+ (file-directory (file-name-directory file))
+ (base (file-name-nondirectory file)))
+ (with-temp-buffer
+ (insert-file-contents file t)
+ (emacs-lisp-mode)
+ (let ((checking-result (package-lint-buffer)))
+ (when checking-result
+ (setq success nil)
+ (unless (equal last-directory file-directory)
+ (setq last-directory file-directory)
+ (message "Entering directory '%s'" file-directory))
+ (pcase-dolist (`(,line ,col ,type ,message) checking-result)
+ (message "%s:%d:%d: %s: %s"
+ base line col type message)))))))))
+
+;;;###autoload
+(defun package-lint-batch-and-exit ()
+ "Run `package-lint-buffer' on the files remaining on the command line.
+Use this only with -batch, it won't work interactively.
+
+When done, exit Emacs with status 0 if there were no errors nor warnings or 1
+otherwise."
+ (unless noninteractive
+ (error "`package-lint-batch-and-exit' is to be used only with -batch"))
+ (let ((success (package-lint-batch-and-exit-1 command-line-args-left)))
+ (kill-emacs (if success 0 1))))
+
+;;;###autoload
+(defun package-lint-looks-like-a-package-p ()
+ "Return non-nil if the current buffer appears to be intended as a package."
+ (save-match-data
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (re-search-forward
+ (concat lm-header-prefix
+ (rx (or "Version" "Package-Version" "Package-Requires")))
+ nil t)))))
+
+(provide 'package-lint)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; package-lint.el ends here
--- /dev/null
+Provides a list of issues with the package metadata of a file,
+e.g. the package dependencies it requires.
+
+See function `package-lint-buffer'.
+
+Checks will currently be enabled only if a "Package-Requires:" or
+"Package-Version:" header is present in the file.