37 changed files with 0 additions and 20905 deletions
			
			
		@ -1 +0,0 @@ | 
				
			|||||||
(define-package "ag" "20150814.1655" "A front-end for ag ('the silver searcher'), the C ack replacement." '((dash "2.8.0") (s "1.9.0") (cl-lib "0.5"))) | 
					 | 
				
			||||||
@ -1,617 +0,0 @@ | 
				
			|||||||
;;; ag.el --- A front-end for ag ('the silver searcher'), the C ack replacement. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; Copyright (C) 2013-2014 Wilfred Hughes <me@wilfred.me.uk> | 
					 | 
				
			||||||
;; | 
					 | 
				
			||||||
;; Author: Wilfred Hughes <me@wilfred.me.uk> | 
					 | 
				
			||||||
;; Created: 11 January 2013 | 
					 | 
				
			||||||
;; Version: 0.47 | 
					 | 
				
			||||||
;; Package-Version: 20150814.1655 | 
					 | 
				
			||||||
;; Package-Requires: ((dash "2.8.0") (s "1.9.0") (cl-lib "0.5")) | 
					 | 
				
			||||||
;;; Commentary: | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; Please see README.md for documentation, or read it online at | 
					 | 
				
			||||||
;; https://github.com/Wilfred/ag.el/#agel | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;; License: | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; This file is not part of GNU Emacs. | 
					 | 
				
			||||||
;; However, it is distributed under the same license. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; GNU Emacs 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, or (at your option) | 
					 | 
				
			||||||
;; any later version. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to the | 
					 | 
				
			||||||
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 
					 | 
				
			||||||
;; Boston, MA 02110-1301, USA. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;; Code: | 
					 | 
				
			||||||
(eval-when-compile (require 'cl)) ;; dolist, defun*, flet | 
					 | 
				
			||||||
(require 'cl-lib) ;; cl-letf | 
					 | 
				
			||||||
(require 'dired) ;; dired-sort-inhibit | 
					 | 
				
			||||||
(require 'dash) | 
					 | 
				
			||||||
(require 's) | 
					 | 
				
			||||||
(require 'find-dired) ;; find-dired-filter | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defcustom ag-executable | 
					 | 
				
			||||||
  "ag" | 
					 | 
				
			||||||
  "Name of the ag executable to use." | 
					 | 
				
			||||||
  :type 'string | 
					 | 
				
			||||||
  :group 'ag) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defcustom ag-arguments | 
					 | 
				
			||||||
  (list "--line-number" "--smart-case" "--nogroup" "--column" "--stats" "--") | 
					 | 
				
			||||||
  "Default arguments passed to ag. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Ag.el requires --nogroup and --column, so we recommend you add any | 
					 | 
				
			||||||
additional arguments to the start of this list. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--line-number is required on Window, as otherwise ag will not | 
					 | 
				
			||||||
print line numbers when the input is a stream." | 
					 | 
				
			||||||
  :type '(repeat (string)) | 
					 | 
				
			||||||
  :group 'ag) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defcustom ag-highlight-search nil | 
					 | 
				
			||||||
  "Non-nil means we highlight the current search term in results. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This requires the ag command to support --color-match, which is only in v0.14+" | 
					 | 
				
			||||||
  :type 'boolean | 
					 | 
				
			||||||
  :group 'ag) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defcustom ag-reuse-buffers nil | 
					 | 
				
			||||||
  "Non-nil means we reuse the existing search results buffer or | 
					 | 
				
			||||||
dired results buffer, rather than creating one buffer per unique | 
					 | 
				
			||||||
search." | 
					 | 
				
			||||||
  :type 'boolean | 
					 | 
				
			||||||
  :group 'ag) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defcustom ag-reuse-window nil | 
					 | 
				
			||||||
  "Non-nil means we open search results in the same window, | 
					 | 
				
			||||||
hiding the results buffer." | 
					 | 
				
			||||||
  :type 'boolean | 
					 | 
				
			||||||
  :group 'ag) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defcustom ag-project-root-function nil | 
					 | 
				
			||||||
  "A function to determine the project root for `ag-project'. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If set to a function, call this function with the name of the | 
					 | 
				
			||||||
file or directory for which to determine the project root | 
					 | 
				
			||||||
directory. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If set to nil, fall back to finding VCS root directories." | 
					 | 
				
			||||||
  :type '(choice (const :tag "Default (VCS root)" nil) | 
					 | 
				
			||||||
                 (function :tag "Function")) | 
					 | 
				
			||||||
  :group 'ag) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defcustom ag-ignore-list nil | 
					 | 
				
			||||||
  "A list of patterns to ignore when searching." | 
					 | 
				
			||||||
  :type '(repeat (string)) | 
					 | 
				
			||||||
  :group 'ag) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(require 'compile) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; Although ag results aren't exactly errors, we treat them as errors | 
					 | 
				
			||||||
;; so `next-error' and `previous-error' work. However, we ensure our | 
					 | 
				
			||||||
;; face inherits from `compilation-info-face' so the results are | 
					 | 
				
			||||||
;; styled appropriately. | 
					 | 
				
			||||||
(defface ag-hit-face '((t :inherit compilation-info)) | 
					 | 
				
			||||||
  "Face name to use for ag matches." | 
					 | 
				
			||||||
  :group 'ag) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defface ag-match-face '((t :inherit match)) | 
					 | 
				
			||||||
  "Face name to use for ag matches." | 
					 | 
				
			||||||
  :group 'ag) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defvar ag-search-finished-hook nil | 
					 | 
				
			||||||
  "Hook run when ag completes a search in a buffer.") | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/run-finished-hook (buffer how-finished) | 
					 | 
				
			||||||
  "Run the ag hook to signal that the search has completed." | 
					 | 
				
			||||||
  (with-current-buffer buffer | 
					 | 
				
			||||||
    (run-hooks 'ag-search-finished-hook))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defmacro ag/with-patch-function (fun-name fun-args fun-body &rest body) | 
					 | 
				
			||||||
  "Temporarily override the definition of FUN-NAME whilst BODY is executed. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Assumes FUNCTION is already defined (see http://emacs.stackexchange.com/a/3452/304)." | 
					 | 
				
			||||||
  `(cl-letf (((symbol-function ,fun-name) | 
					 | 
				
			||||||
              (lambda ,fun-args ,fun-body))) | 
					 | 
				
			||||||
     ,@body)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/next-error-function (n &optional reset) | 
					 | 
				
			||||||
  "Open the search result at point in the current window or a | 
					 | 
				
			||||||
different window, according to `ag-reuse-window'." | 
					 | 
				
			||||||
  (if ag-reuse-window | 
					 | 
				
			||||||
      ;; prevent changing the window | 
					 | 
				
			||||||
      (ag/with-patch-function | 
					 | 
				
			||||||
       'pop-to-buffer (buffer &rest args) (switch-to-buffer buffer) | 
					 | 
				
			||||||
       (compilation-next-error-function n reset)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ;; just navigate to the results as normal | 
					 | 
				
			||||||
    (compilation-next-error-function n reset))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; Note that we want to use as tight a regexp as we can to try and | 
					 | 
				
			||||||
;; handle weird file names (with colons in them) as well as possible. | 
					 | 
				
			||||||
;; E.g. we use [1-9][0-9]* rather than [0-9]+ so as to accept ":034:" | 
					 | 
				
			||||||
;; in file names. | 
					 | 
				
			||||||
(defvar ag/file-column-pattern | 
					 | 
				
			||||||
  "^\\(.+?\\):\\([1-9][0-9]*\\):\\([1-9][0-9]*\\):" | 
					 | 
				
			||||||
  "A regexp pattern that groups output into filename, line number and column number.") | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(define-compilation-mode ag-mode "Ag" | 
					 | 
				
			||||||
  "Ag results compilation mode" | 
					 | 
				
			||||||
  (set (make-local-variable 'compilation-error-regexp-alist) | 
					 | 
				
			||||||
       (list 'compilation-ag-nogroup)) | 
					 | 
				
			||||||
  (set (make-local-variable 'compilation-error-regexp-alist-alist) | 
					 | 
				
			||||||
       (list (cons 'compilation-ag-nogroup (list ag/file-column-pattern 1 2 3)))) | 
					 | 
				
			||||||
  (set (make-local-variable 'compilation-error-face) 'ag-hit-face) | 
					 | 
				
			||||||
  (set (make-local-variable 'next-error-function) #'ag/next-error-function) | 
					 | 
				
			||||||
  (set (make-local-variable 'compilation-finish-functions) | 
					 | 
				
			||||||
       #'ag/run-finished-hook) | 
					 | 
				
			||||||
  (add-hook 'compilation-filter-hook 'ag-filter nil t)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(define-key ag-mode-map (kbd "p") #'compilation-previous-error) | 
					 | 
				
			||||||
(define-key ag-mode-map (kbd "n") #'compilation-next-error) | 
					 | 
				
			||||||
(define-key ag-mode-map (kbd "k") '(lambda () (interactive)  | 
					 | 
				
			||||||
                                     (let (kill-buffer-query-functions) (kill-buffer)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/buffer-name (search-string directory regexp) | 
					 | 
				
			||||||
  "Return a buffer name formatted according to ag.el conventions." | 
					 | 
				
			||||||
  (cond | 
					 | 
				
			||||||
   (ag-reuse-buffers "*ag search*") | 
					 | 
				
			||||||
   (regexp (format "*ag search regexp:%s dir:%s*" search-string directory)) | 
					 | 
				
			||||||
   (:else (format "*ag search text:%s dir:%s*" search-string directory)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/format-ignore (ignores) | 
					 | 
				
			||||||
  "Prepend '--ignore' to every item in IGNORES." | 
					 | 
				
			||||||
  (apply #'append | 
					 | 
				
			||||||
         (mapcar (lambda (item) (list "--ignore" item)) ignores))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun* ag/search (string directory | 
					 | 
				
			||||||
                          &key (regexp nil) (file-regex nil) (file-type nil)) | 
					 | 
				
			||||||
  "Run ag searching for the STRING given in DIRECTORY. | 
					 | 
				
			||||||
If REGEXP is non-nil, treat STRING as a regular expression." | 
					 | 
				
			||||||
  (let ((default-directory (file-name-as-directory directory)) | 
					 | 
				
			||||||
        (arguments ag-arguments) | 
					 | 
				
			||||||
        (shell-command-switch "-c")) | 
					 | 
				
			||||||
    (unless regexp | 
					 | 
				
			||||||
      (setq arguments (cons "--literal" arguments))) | 
					 | 
				
			||||||
    (if ag-highlight-search | 
					 | 
				
			||||||
        (setq arguments (append '("--color" "--color-match" "30;43") arguments)) | 
					 | 
				
			||||||
      (setq arguments (append '("--nocolor") arguments))) | 
					 | 
				
			||||||
    (when (char-or-string-p file-regex) | 
					 | 
				
			||||||
      (setq arguments (append `("--file-search-regex" ,file-regex) arguments))) | 
					 | 
				
			||||||
    (when file-type | 
					 | 
				
			||||||
      (setq arguments (cons (format "--%s" file-type) arguments))) | 
					 | 
				
			||||||
    (when ag-ignore-list | 
					 | 
				
			||||||
      (setq arguments (append (ag/format-ignore ag-ignore-list) arguments))) | 
					 | 
				
			||||||
    (unless (file-exists-p default-directory) | 
					 | 
				
			||||||
      (error "No such directory %s" default-directory)) | 
					 | 
				
			||||||
    (let ((command-string | 
					 | 
				
			||||||
           (mapconcat #'shell-quote-argument | 
					 | 
				
			||||||
                      (append (list ag-executable) arguments (list string ".")) | 
					 | 
				
			||||||
                      " "))) | 
					 | 
				
			||||||
      ;; If we're called with a prefix, let the user modify the command before | 
					 | 
				
			||||||
      ;; running it. Typically this means they want to pass additional arguments. | 
					 | 
				
			||||||
      (when current-prefix-arg | 
					 | 
				
			||||||
        ;; Make a space in the command-string for the user to enter more arguments. | 
					 | 
				
			||||||
        (setq command-string (ag/replace-first command-string " -- " "  -- ")) | 
					 | 
				
			||||||
        ;; Prompt for the command. | 
					 | 
				
			||||||
        (let ((adjusted-point (- (length command-string) (length string) 5))) | 
					 | 
				
			||||||
          (setq command-string | 
					 | 
				
			||||||
                (read-from-minibuffer "ag command: " | 
					 | 
				
			||||||
                                      (cons command-string adjusted-point))))) | 
					 | 
				
			||||||
      ;; Call ag. | 
					 | 
				
			||||||
      (compilation-start | 
					 | 
				
			||||||
       command-string | 
					 | 
				
			||||||
       #'ag-mode | 
					 | 
				
			||||||
       `(lambda (mode-name) ,(ag/buffer-name string directory regexp)))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/dwim-at-point () | 
					 | 
				
			||||||
  "If there's an active selection, return that. | 
					 | 
				
			||||||
Otherwise, get the symbol at point, as a string." | 
					 | 
				
			||||||
  (cond ((use-region-p) | 
					 | 
				
			||||||
         (buffer-substring-no-properties (region-beginning) (region-end))) | 
					 | 
				
			||||||
        ((symbol-at-point) | 
					 | 
				
			||||||
         (substring-no-properties | 
					 | 
				
			||||||
          (symbol-name (symbol-at-point)))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/buffer-extension-regex () | 
					 | 
				
			||||||
  "If the current buffer has an extension, return | 
					 | 
				
			||||||
a PCRE pattern that matches files with that extension. | 
					 | 
				
			||||||
Returns an empty string otherwise." | 
					 | 
				
			||||||
  (let ((file-name (buffer-file-name))) | 
					 | 
				
			||||||
    (if (stringp file-name) | 
					 | 
				
			||||||
        (format "\\.%s$" (ag/escape-pcre (file-name-extension file-name))) | 
					 | 
				
			||||||
      ""))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/longest-string (&rest strings) | 
					 | 
				
			||||||
  "Given a list of strings and nils, return the longest string." | 
					 | 
				
			||||||
  (let ((longest-string nil)) | 
					 | 
				
			||||||
    (dolist (string strings) | 
					 | 
				
			||||||
      (cond ((null longest-string) | 
					 | 
				
			||||||
             (setq longest-string string)) | 
					 | 
				
			||||||
            ((stringp string) | 
					 | 
				
			||||||
             (when (< (length longest-string) | 
					 | 
				
			||||||
                      (length string)) | 
					 | 
				
			||||||
               (setq longest-string string))))) | 
					 | 
				
			||||||
    longest-string)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/replace-first (string before after) | 
					 | 
				
			||||||
  "Replace the first occurrence of BEFORE in STRING with AFTER." | 
					 | 
				
			||||||
  (replace-regexp-in-string | 
					 | 
				
			||||||
   (concat "\\(" (regexp-quote before) "\\)" ".*\\'") | 
					 | 
				
			||||||
   after string | 
					 | 
				
			||||||
   nil nil 1)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(autoload 'vc-git-root "vc-git") | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(require 'vc-svn) | 
					 | 
				
			||||||
;; Emacs 23.4 doesn't provide vc-svn-root. | 
					 | 
				
			||||||
(unless (functionp 'vc-svn-root) | 
					 | 
				
			||||||
  (defun vc-svn-root (file) | 
					 | 
				
			||||||
    (vc-find-root file vc-svn-admin-directory))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(autoload 'vc-hg-root "vc-hg") | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/project-root (file-path) | 
					 | 
				
			||||||
  "Guess the project root of the given FILE-PATH. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Use `ag-project-root-function' if set, or fall back to VCS | 
					 | 
				
			||||||
roots." | 
					 | 
				
			||||||
  (if ag-project-root-function | 
					 | 
				
			||||||
      (funcall ag-project-root-function file-path) | 
					 | 
				
			||||||
    (or (ag/longest-string | 
					 | 
				
			||||||
       (vc-git-root file-path) | 
					 | 
				
			||||||
       (vc-svn-root file-path) | 
					 | 
				
			||||||
       (vc-hg-root file-path)) | 
					 | 
				
			||||||
      file-path))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/dired-align-size-column () | 
					 | 
				
			||||||
  (beginning-of-line) | 
					 | 
				
			||||||
  (when (looking-at "^  ") | 
					 | 
				
			||||||
    (forward-char 2) | 
					 | 
				
			||||||
    (search-forward " " nil t 4) | 
					 | 
				
			||||||
    (let* ((size-start (point)) | 
					 | 
				
			||||||
           (size-end (search-forward " " nil t)) | 
					 | 
				
			||||||
           (width (and size-end (- size-end size-start)))) | 
					 | 
				
			||||||
      (when (and size-end | 
					 | 
				
			||||||
                 (< width 12) | 
					 | 
				
			||||||
                 (> width 1)) | 
					 | 
				
			||||||
        (goto-char size-start) | 
					 | 
				
			||||||
        (insert (make-string (- 12 width) ? )))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/dired-filter (proc string) | 
					 | 
				
			||||||
  "Filter the output of ag to make it suitable for `dired-mode'." | 
					 | 
				
			||||||
  (let ((buf (process-buffer proc)) | 
					 | 
				
			||||||
        (inhibit-read-only t)) | 
					 | 
				
			||||||
    (if (buffer-name buf) | 
					 | 
				
			||||||
        (with-current-buffer buf | 
					 | 
				
			||||||
          (save-excursion | 
					 | 
				
			||||||
            (save-restriction | 
					 | 
				
			||||||
              (widen) | 
					 | 
				
			||||||
              (let ((beg (point-max))) | 
					 | 
				
			||||||
                (goto-char beg) | 
					 | 
				
			||||||
                (insert string) | 
					 | 
				
			||||||
                (goto-char beg) | 
					 | 
				
			||||||
                (or (looking-at "^") | 
					 | 
				
			||||||
                    (progn | 
					 | 
				
			||||||
                      (ag/dired-align-size-column) | 
					 | 
				
			||||||
                      (forward-line 1))) | 
					 | 
				
			||||||
                (while (looking-at "^") | 
					 | 
				
			||||||
                  (insert "  ") | 
					 | 
				
			||||||
                  (ag/dired-align-size-column) | 
					 | 
				
			||||||
                  (forward-line 1)) | 
					 | 
				
			||||||
                (goto-char beg) | 
					 | 
				
			||||||
                (beginning-of-line) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                ;; Remove occurrences of default-directory. | 
					 | 
				
			||||||
                (while (search-forward (concat " " default-directory) nil t) | 
					 | 
				
			||||||
                  (replace-match " " nil t)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                (goto-char (point-max)) | 
					 | 
				
			||||||
                (if (search-backward "\n" (process-mark proc) t) | 
					 | 
				
			||||||
                    (progn | 
					 | 
				
			||||||
                      (dired-insert-set-properties (process-mark proc) | 
					 | 
				
			||||||
                                                   (1+ (point))) | 
					 | 
				
			||||||
                      (move-marker (process-mark proc) (1+ (point))))))))) | 
					 | 
				
			||||||
      (delete-process proc)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/dired-sentinel (proc state) | 
					 | 
				
			||||||
  "Update the status/modeline after the process finishes." | 
					 | 
				
			||||||
  (let ((buf (process-buffer proc)) | 
					 | 
				
			||||||
        (inhibit-read-only t)) | 
					 | 
				
			||||||
    (if (buffer-name buf) | 
					 | 
				
			||||||
        (with-current-buffer buf | 
					 | 
				
			||||||
          (let ((buffer-read-only nil)) | 
					 | 
				
			||||||
            (save-excursion | 
					 | 
				
			||||||
              (goto-char (point-max)) | 
					 | 
				
			||||||
              (insert "\n  ag " state) | 
					 | 
				
			||||||
              (forward-char -1)     ;Back up before \n at end of STATE. | 
					 | 
				
			||||||
              (insert " at " (substring (current-time-string) 0 19)) | 
					 | 
				
			||||||
              (forward-char 1) | 
					 | 
				
			||||||
              (setq mode-line-process | 
					 | 
				
			||||||
                    (concat ":" (symbol-name (process-status proc)))) | 
					 | 
				
			||||||
              ;; Since the buffer and mode line will show that the | 
					 | 
				
			||||||
              ;; process is dead, we can delete it now.  Otherwise it | 
					 | 
				
			||||||
              ;; will stay around until M-x list-processes. | 
					 | 
				
			||||||
              (delete-process proc) | 
					 | 
				
			||||||
              (force-mode-line-update))) | 
					 | 
				
			||||||
          (run-hooks 'dired-after-readin-hook) | 
					 | 
				
			||||||
          (message "%s finished." (current-buffer)))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/kill-process () | 
					 | 
				
			||||||
  "Kill the `ag' process running in the current buffer." | 
					 | 
				
			||||||
  (interactive) | 
					 | 
				
			||||||
  (let ((ag (get-buffer-process (current-buffer)))) | 
					 | 
				
			||||||
    (and ag (eq (process-status ag) 'run) | 
					 | 
				
			||||||
         (eq (process-filter ag) (function find-dired-filter)) | 
					 | 
				
			||||||
         (condition-case nil | 
					 | 
				
			||||||
             (delete-process ag) | 
					 | 
				
			||||||
           (error nil))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/escape-pcre (regexp) | 
					 | 
				
			||||||
  "Escape the PCRE-special characters in REGEXP so that it is | 
					 | 
				
			||||||
matched literally." | 
					 | 
				
			||||||
  (let ((alphanum "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")) | 
					 | 
				
			||||||
    (apply #'concat | 
					 | 
				
			||||||
           (mapcar | 
					 | 
				
			||||||
            (lambda (c) | 
					 | 
				
			||||||
              (cond | 
					 | 
				
			||||||
               ((not (string-match-p (regexp-quote c) alphanum)) | 
					 | 
				
			||||||
                (concat "\\" c)) | 
					 | 
				
			||||||
               (t c))) | 
					 | 
				
			||||||
            (mapcar #'char-to-string (string-to-list regexp)))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag (string directory) | 
					 | 
				
			||||||
  "Search using ag in a given DIRECTORY for a given search STRING, | 
					 | 
				
			||||||
with STRING defaulting to the symbol under point. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If called with a prefix, prompts for flags to pass to ag." | 
					 | 
				
			||||||
  (interactive (list (ag/read-from-minibuffer "Search string") | 
					 | 
				
			||||||
                     (read-directory-name "Directory: "))) | 
					 | 
				
			||||||
  (ag/search string directory)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-files (string file-type directory) | 
					 | 
				
			||||||
  "Search using ag in a given DIRECTORY for a given search STRING, | 
					 | 
				
			||||||
limited to files that match FILE-TYPE. STRING defaults to | 
					 | 
				
			||||||
the symbol under point. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If called with a prefix, prompts for flags to pass to ag." | 
					 | 
				
			||||||
  (interactive (list (ag/read-from-minibuffer "Search string") | 
					 | 
				
			||||||
                     (ag/read-file-type) | 
					 | 
				
			||||||
                     (read-directory-name "Directory: "))) | 
					 | 
				
			||||||
  (apply #'ag/search string directory file-type)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-regexp (string directory) | 
					 | 
				
			||||||
  "Search using ag in a given directory for a given regexp. | 
					 | 
				
			||||||
The regexp should be in PCRE syntax, not Emacs regexp syntax. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If called with a prefix, prompts for flags to pass to ag." | 
					 | 
				
			||||||
  (interactive "sSearch regexp: \nDDirectory: ") | 
					 | 
				
			||||||
  (ag/search string directory :regexp t)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-project (string) | 
					 | 
				
			||||||
  "Guess the root of the current project and search it with ag | 
					 | 
				
			||||||
for the given string. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If called with a prefix, prompts for flags to pass to ag." | 
					 | 
				
			||||||
  (interactive (list (ag/read-from-minibuffer "Search string"))) | 
					 | 
				
			||||||
  (ag/search string (ag/project-root default-directory))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-project-files (string file-type) | 
					 | 
				
			||||||
  "Search using ag for a given search STRING, | 
					 | 
				
			||||||
limited to files that match FILE-TYPE. STRING defaults to the | 
					 | 
				
			||||||
symbol under point. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If called with a prefix, prompts for flags to pass to ag." | 
					 | 
				
			||||||
  (interactive (list (ag/read-from-minibuffer "Search string") | 
					 | 
				
			||||||
                     (ag/read-file-type))) | 
					 | 
				
			||||||
  (apply 'ag/search string (ag/project-root default-directory) file-type)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/read-from-minibuffer (prompt) | 
					 | 
				
			||||||
  "Read a value from the minibuffer with PROMPT. | 
					 | 
				
			||||||
If there's a string at point, offer that as a default." | 
					 | 
				
			||||||
  (let* ((suggested (ag/dwim-at-point)) | 
					 | 
				
			||||||
         (final-prompt | 
					 | 
				
			||||||
          (if suggested | 
					 | 
				
			||||||
              (format "%s (default %s): " prompt suggested) | 
					 | 
				
			||||||
            (format "%s: " prompt))) | 
					 | 
				
			||||||
         ;; Ask the user for input, but add `suggested' to the history | 
					 | 
				
			||||||
         ;; so they can use M-n if they want to modify it. | 
					 | 
				
			||||||
         (user-input (read-from-minibuffer | 
					 | 
				
			||||||
                      final-prompt | 
					 | 
				
			||||||
                      nil nil nil nil suggested))) | 
					 | 
				
			||||||
    ;; Return the input provided by the user, or use `suggested' if | 
					 | 
				
			||||||
    ;; the input was empty. | 
					 | 
				
			||||||
    (if (> (length user-input) 0) | 
					 | 
				
			||||||
        user-input | 
					 | 
				
			||||||
      suggested))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-project-regexp (regexp) | 
					 | 
				
			||||||
  "Guess the root of the current project and search it with ag | 
					 | 
				
			||||||
for the given regexp. The regexp should be in PCRE syntax, not | 
					 | 
				
			||||||
Emacs regexp syntax. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If called with a prefix, prompts for flags to pass to ag." | 
					 | 
				
			||||||
  (interactive (list (ag/read-from-minibuffer "Search regexp"))) | 
					 | 
				
			||||||
  (ag/search regexp (ag/project-root default-directory) :regexp t)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(autoload 'symbol-at-point "thingatpt") | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defalias 'ag-project-at-point 'ag-project) | 
					 | 
				
			||||||
(make-obsolete 'ag-project-at-point 'ag-project "0.19") | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defalias 'ag-regexp-project-at-point 'ag-project-regexp) | 
					 | 
				
			||||||
(make-obsolete 'ag-regexp-project-at-point 'ag-project-regexp "0.46") | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-dired (dir pattern) | 
					 | 
				
			||||||
  "Recursively find files in DIR matching PATTERN. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The PATTERN is matched against the full path to the file, not | 
					 | 
				
			||||||
only against the file name. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The results are presented as a `dired-mode' buffer with | 
					 | 
				
			||||||
`default-directory' being DIR. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See also `ag-dired-regexp'." | 
					 | 
				
			||||||
  (interactive "DDirectory: \nsFile pattern: ") | 
					 | 
				
			||||||
  (ag-dired-regexp dir (ag/escape-pcre pattern))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-dired-regexp (dir regexp) | 
					 | 
				
			||||||
  "Recursively find files in DIR matching REGEXP. | 
					 | 
				
			||||||
REGEXP should be in PCRE syntax, not Emacs regexp syntax. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The REGEXP is matched against the full path to the file, not | 
					 | 
				
			||||||
only against the file name. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Results are presented as a `dired-mode' buffer with | 
					 | 
				
			||||||
`default-directory' being DIR. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See also `find-dired'." | 
					 | 
				
			||||||
  (interactive "DDirectory: \nsFile regexp: ") | 
					 | 
				
			||||||
  (let* ((dired-buffers dired-buffers) ;; do not mess with regular dired buffers | 
					 | 
				
			||||||
         (orig-dir dir) | 
					 | 
				
			||||||
         (dir (file-name-as-directory (expand-file-name dir))) | 
					 | 
				
			||||||
         (buffer-name (if ag-reuse-buffers | 
					 | 
				
			||||||
                          "*ag dired*" | 
					 | 
				
			||||||
                        (format "*ag dired pattern:%s dir:%s*" regexp dir))) | 
					 | 
				
			||||||
         (cmd (concat ag-executable " --nocolor -g '" regexp "' " | 
					 | 
				
			||||||
                      (shell-quote-argument dir) | 
					 | 
				
			||||||
                      " | grep -v '^$' | sed s/\\'/\\\\\\\\\\'/ | xargs -I '{}' ls " | 
					 | 
				
			||||||
                      dired-listing-switches " '{}' &"))) | 
					 | 
				
			||||||
    (with-current-buffer (get-buffer-create buffer-name) | 
					 | 
				
			||||||
      (switch-to-buffer (current-buffer)) | 
					 | 
				
			||||||
      (widen) | 
					 | 
				
			||||||
      (kill-all-local-variables) | 
					 | 
				
			||||||
      (if (fboundp 'read-only-mode) | 
					 | 
				
			||||||
          (read-only-mode -1) | 
					 | 
				
			||||||
        (setq buffer-read-only nil)) | 
					 | 
				
			||||||
      (let ((inhibit-read-only t)) (erase-buffer)) | 
					 | 
				
			||||||
      (setq default-directory dir) | 
					 | 
				
			||||||
      (run-hooks 'dired-before-readin-hook) | 
					 | 
				
			||||||
      (shell-command cmd (current-buffer)) | 
					 | 
				
			||||||
      (insert "  " dir ":\n") | 
					 | 
				
			||||||
      (insert "  " cmd "\n") | 
					 | 
				
			||||||
      (dired-mode dir) | 
					 | 
				
			||||||
      (let ((map (make-sparse-keymap))) | 
					 | 
				
			||||||
        (set-keymap-parent map (current-local-map)) | 
					 | 
				
			||||||
        (define-key map "\C-c\C-k" 'ag/kill-process) | 
					 | 
				
			||||||
        (use-local-map map)) | 
					 | 
				
			||||||
      (set (make-local-variable 'dired-sort-inhibit) t) | 
					 | 
				
			||||||
      (set (make-local-variable 'revert-buffer-function) | 
					 | 
				
			||||||
           `(lambda (ignore-auto noconfirm) | 
					 | 
				
			||||||
              (ag-dired-regexp ,orig-dir ,regexp))) | 
					 | 
				
			||||||
      (if (fboundp 'dired-simple-subdir-alist) | 
					 | 
				
			||||||
          (dired-simple-subdir-alist) | 
					 | 
				
			||||||
        (set (make-local-variable 'dired-subdir-alist) | 
					 | 
				
			||||||
             (list (cons default-directory (point-min-marker))))) | 
					 | 
				
			||||||
      (let ((proc (get-buffer-process (current-buffer)))) | 
					 | 
				
			||||||
        (set-process-filter proc #'ag/dired-filter) | 
					 | 
				
			||||||
        (set-process-sentinel proc #'ag/dired-sentinel) | 
					 | 
				
			||||||
        ;; Initialize the process marker; it is used by the filter. | 
					 | 
				
			||||||
        (move-marker (process-mark proc) 1 (current-buffer))) | 
					 | 
				
			||||||
      (setq mode-line-process '(":%s"))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-project-dired (pattern) | 
					 | 
				
			||||||
  "Recursively find files in current project matching PATTERN. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See also `ag-dired'." | 
					 | 
				
			||||||
  (interactive "sFile pattern: ") | 
					 | 
				
			||||||
  (ag-dired-regexp (ag/project-root default-directory) (ag/escape-pcre pattern))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-project-dired-regexp (regexp) | 
					 | 
				
			||||||
  "Recursively find files in current project matching REGEXP. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See also `ag-dired-regexp'." | 
					 | 
				
			||||||
  (interactive "sFile regexp: ") | 
					 | 
				
			||||||
  (ag-dired-regexp (ag/project-root default-directory) regexp)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-kill-buffers () | 
					 | 
				
			||||||
  "Kill all `ag-mode' buffers." | 
					 | 
				
			||||||
  (interactive) | 
					 | 
				
			||||||
  (dolist (buffer (buffer-list)) | 
					 | 
				
			||||||
    (when (eq (buffer-local-value 'major-mode buffer) 'ag-mode) | 
					 | 
				
			||||||
      (kill-buffer buffer)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;;###autoload | 
					 | 
				
			||||||
(defun ag-kill-other-buffers () | 
					 | 
				
			||||||
  "Kill all `ag-mode' buffers other than the current buffer." | 
					 | 
				
			||||||
  (interactive) | 
					 | 
				
			||||||
  (let ((current-buffer (current-buffer))) | 
					 | 
				
			||||||
    (dolist (buffer (buffer-list)) | 
					 | 
				
			||||||
      (when (and | 
					 | 
				
			||||||
             (eq (buffer-local-value 'major-mode buffer) 'ag-mode) | 
					 | 
				
			||||||
             (not (eq buffer current-buffer))) | 
					 | 
				
			||||||
        (kill-buffer buffer))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; Taken from grep-filter, just changed the color regex. | 
					 | 
				
			||||||
(defun ag-filter () | 
					 | 
				
			||||||
  "Handle match highlighting escape sequences inserted by the ag process. | 
					 | 
				
			||||||
This function is called from `compilation-filter-hook'." | 
					 | 
				
			||||||
  (when ag-highlight-search | 
					 | 
				
			||||||
    (save-excursion | 
					 | 
				
			||||||
      (forward-line 0) | 
					 | 
				
			||||||
      (let ((end (point)) beg) | 
					 | 
				
			||||||
        (goto-char compilation-filter-start) | 
					 | 
				
			||||||
        (forward-line 0) | 
					 | 
				
			||||||
        (setq beg (point)) | 
					 | 
				
			||||||
        ;; Only operate on whole lines so we don't get caught with part of an | 
					 | 
				
			||||||
        ;; escape sequence in one chunk and the rest in another. | 
					 | 
				
			||||||
        (when (< (point) end) | 
					 | 
				
			||||||
          (setq end (copy-marker end)) | 
					 | 
				
			||||||
          ;; Highlight ag matches and delete marking sequences. | 
					 | 
				
			||||||
          (while (re-search-forward "\033\\[30;43m\\(.*?\\)\033\\[[0-9]*m" end 1) | 
					 | 
				
			||||||
            (replace-match (propertize (match-string 1) | 
					 | 
				
			||||||
                                       'face nil 'font-lock-face 'ag-match-face) | 
					 | 
				
			||||||
                           t t)) | 
					 | 
				
			||||||
          ;; Delete all remaining escape sequences | 
					 | 
				
			||||||
          (goto-char beg) | 
					 | 
				
			||||||
          (while (re-search-forward "\033\\[[0-9;]*[mK]" end 1) | 
					 | 
				
			||||||
            (replace-match "" t t))))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/get-supported-types () | 
					 | 
				
			||||||
  "Query the ag executable for which file types it recognises." | 
					 | 
				
			||||||
  (let* ((ag-output (shell-command-to-string (format "%s --list-file-types" ag-executable))) | 
					 | 
				
			||||||
         (lines (-map #'s-trim (s-lines ag-output))) | 
					 | 
				
			||||||
         (types (--keep (when (s-starts-with? "--" it) (s-chop-prefix "--" it )) lines)) | 
					 | 
				
			||||||
         (extensions (--map (s-split "  " it) (--filter (s-starts-with? "." it) lines)))) | 
					 | 
				
			||||||
    (-zip types extensions))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun ag/read-file-type () | 
					 | 
				
			||||||
  "Prompt the user for a known file type, or let them specify a PCRE regex." | 
					 | 
				
			||||||
  (let* ((all-types-with-extensions (ag/get-supported-types)) | 
					 | 
				
			||||||
         (all-types (mapcar 'car all-types-with-extensions)) | 
					 | 
				
			||||||
         (file-type | 
					 | 
				
			||||||
          (completing-read "Select file type: " | 
					 | 
				
			||||||
                           (append '("custom (provide a PCRE regex)") all-types))) | 
					 | 
				
			||||||
         (file-type-extensions | 
					 | 
				
			||||||
          (cdr (assoc file-type all-types-with-extensions)))) | 
					 | 
				
			||||||
    (if file-type-extensions | 
					 | 
				
			||||||
        (list :file-type file-type) | 
					 | 
				
			||||||
      (list :file-regex | 
					 | 
				
			||||||
            (read-from-minibuffer "Filenames which match PCRE: " | 
					 | 
				
			||||||
                                  (ag/buffer-extension-regex)))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(provide 'ag) | 
					 | 
				
			||||||
;;; ag.el ends here | 
					 | 
				
			||||||
@ -1,777 +0,0 @@ | 
				
			|||||||
(1 | 
					 | 
				
			||||||
 (ace-window . | 
					 | 
				
			||||||
	     [(0 9 0) | 
					 | 
				
			||||||
	      ((avy | 
					 | 
				
			||||||
		(0 2 0))) | 
					 | 
				
			||||||
	      "Quickly switch windows." single | 
					 | 
				
			||||||
	      ((:url . "https://github.com/abo-abo/ace-window") | 
					 | 
				
			||||||
	       (:keywords "window" "location"))]) | 
					 | 
				
			||||||
 (ack . | 
					 | 
				
			||||||
      [(1 5) | 
					 | 
				
			||||||
       nil "interface to ack-like tools" tar | 
					 | 
				
			||||||
       ((:keywords "tools" "processes" "convenience") | 
					 | 
				
			||||||
	(:url . "https://github.com/leoliu/ack-el"))]) | 
					 | 
				
			||||||
 (ada-mode . | 
					 | 
				
			||||||
	   [(5 1 8) | 
					 | 
				
			||||||
	    ((wisi | 
					 | 
				
			||||||
	      (1 1 1)) | 
					 | 
				
			||||||
	     (cl-lib | 
					 | 
				
			||||||
	      (0 4)) | 
					 | 
				
			||||||
	     (emacs | 
					 | 
				
			||||||
	      (24 2))) | 
					 | 
				
			||||||
	    "major-mode for editing Ada sources" tar | 
					 | 
				
			||||||
	    ((:keywords "languages" "ada") | 
					 | 
				
			||||||
	     (:url . "http://stephe-leake.org/emacs/ada-mode/emacs-ada-mode.html"))]) | 
					 | 
				
			||||||
 (ada-ref-man . | 
					 | 
				
			||||||
	      [(2012 0) | 
					 | 
				
			||||||
	       nil "Ada Reference Manual 2012" tar | 
					 | 
				
			||||||
	       ((:keywords "languages" "ada") | 
					 | 
				
			||||||
		(:url . "http://stephe-leake.org/ada/arm.html"))]) | 
					 | 
				
			||||||
 (adaptive-wrap . | 
					 | 
				
			||||||
		[(0 5) | 
					 | 
				
			||||||
		 nil "Smart line-wrapping with wrap-prefix" single | 
					 | 
				
			||||||
		 ((:url . "http://elpa.gnu.org/packages/adaptive-wrap.html") | 
					 | 
				
			||||||
		  (:keywords))]) | 
					 | 
				
			||||||
 (adjust-parens . | 
					 | 
				
			||||||
		[(3 0) | 
					 | 
				
			||||||
		 nil "Indent and dedent Lisp code, automatically adjust close parens" tar | 
					 | 
				
			||||||
		 ((:url . "http://elpa.gnu.org/packages/adjust-parens.html"))]) | 
					 | 
				
			||||||
 (aggressive-indent . | 
					 | 
				
			||||||
		    [(1 4) | 
					 | 
				
			||||||
		     ((emacs | 
					 | 
				
			||||||
		       (24 1)) | 
					 | 
				
			||||||
		      (cl-lib | 
					 | 
				
			||||||
		       (0 5))) | 
					 | 
				
			||||||
		     "Minor mode to aggressively keep your code always indented" single | 
					 | 
				
			||||||
		     ((:url . "http://github.com/Malabarba/aggressive-indent-mode") | 
					 | 
				
			||||||
		      (:keywords "indent" "lisp" "maint" "tools"))]) | 
					 | 
				
			||||||
 (ahungry-theme . | 
					 | 
				
			||||||
		[(1 0 12) | 
					 | 
				
			||||||
		 ((emacs | 
					 | 
				
			||||||
		   (24))) | 
					 | 
				
			||||||
		 "Ahungry color theme for Emacs.  Make sure to (load-theme 'ahungry)." tar | 
					 | 
				
			||||||
		 ((:keywords "ahungry" "palette" "color" "theme" "emacs" "color-theme" "deftheme") | 
					 | 
				
			||||||
		  (:url . "https://github.com/ahungry/color-theme-ahungry"))]) | 
					 | 
				
			||||||
 (all . | 
					 | 
				
			||||||
      [(1 0) | 
					 | 
				
			||||||
       nil "Edit all lines matching a given regexp" single | 
					 | 
				
			||||||
       ((:url . "http://elpa.gnu.org/packages/all.html") | 
					 | 
				
			||||||
	(:keywords "matching"))]) | 
					 | 
				
			||||||
 (ascii-art-to-unicode . | 
					 | 
				
			||||||
		       [(1 9) | 
					 | 
				
			||||||
			nil "a small artist adjunct" single | 
					 | 
				
			||||||
			((:url . "http://www.gnuvola.org/software/aa2u/") | 
					 | 
				
			||||||
			 (:keywords "ascii" "unicode" "box-drawing"))]) | 
					 | 
				
			||||||
 (auctex . | 
					 | 
				
			||||||
	 [(11 88 9) | 
					 | 
				
			||||||
	  nil "Integrated environment for *TeX*" tar | 
					 | 
				
			||||||
	  ((:url . "http://www.gnu.org/software/auctex/"))]) | 
					 | 
				
			||||||
 (aumix-mode . | 
					 | 
				
			||||||
	     [(7) | 
					 | 
				
			||||||
	      nil "run the aumix program in a buffer" single | 
					 | 
				
			||||||
	      ((:url . "http://user42.tuxfamily.org/aumix-mode/index.html") | 
					 | 
				
			||||||
	       (:keywords "multimedia" "mixer" "aumix"))]) | 
					 | 
				
			||||||
 (auto-overlays . | 
					 | 
				
			||||||
		[(0 10 9) | 
					 | 
				
			||||||
		 nil "Automatic regexp-delimited overlays" tar | 
					 | 
				
			||||||
		 ((:keywords "extensions") | 
					 | 
				
			||||||
		  (:url . "http://www.dr-qubit.org/emacs.php"))]) | 
					 | 
				
			||||||
 (avy . | 
					 | 
				
			||||||
      [(0 3 0) | 
					 | 
				
			||||||
       ((emacs | 
					 | 
				
			||||||
	 (24 1)) | 
					 | 
				
			||||||
	(cl-lib | 
					 | 
				
			||||||
	 (0 5))) | 
					 | 
				
			||||||
       "set-based completion" tar | 
					 | 
				
			||||||
       ((:keywords "point" "location") | 
					 | 
				
			||||||
	(:url . "https://github.com/abo-abo/avy"))]) | 
					 | 
				
			||||||
 (beacon . | 
					 | 
				
			||||||
	 [(0 2 1) | 
					 | 
				
			||||||
	  ((seq | 
					 | 
				
			||||||
	    (1 9))) | 
					 | 
				
			||||||
	  "Highlight the cursor whenever the window scrolls" single | 
					 | 
				
			||||||
	  ((:url . "https://github.com/Malabarba/beacon") | 
					 | 
				
			||||||
	   (:keywords "convenience"))]) | 
					 | 
				
			||||||
 (bug-hunter . | 
					 | 
				
			||||||
	     [(1 0) | 
					 | 
				
			||||||
	      ((seq | 
					 | 
				
			||||||
		(1 3)) | 
					 | 
				
			||||||
	       (cl-lib | 
					 | 
				
			||||||
		(0 5))) | 
					 | 
				
			||||||
	      "Hunt down errors in elisp files" single | 
					 | 
				
			||||||
	      ((:url . "http://github.com/Malabarba/elisp-bug-hunter") | 
					 | 
				
			||||||
	       (:keywords "lisp"))]) | 
					 | 
				
			||||||
 (caps-lock . | 
					 | 
				
			||||||
	    [(1 0) | 
					 | 
				
			||||||
	     nil "Caps-lock as a minor mode" single | 
					 | 
				
			||||||
	     ((:url . "http://elpa.gnu.org/packages/caps-lock.html") | 
					 | 
				
			||||||
	      (:keywords))]) | 
					 | 
				
			||||||
 (chess . | 
					 | 
				
			||||||
	[(2 0 4) | 
					 | 
				
			||||||
	 ((cl-lib | 
					 | 
				
			||||||
	   (0 5))) | 
					 | 
				
			||||||
	 "Play chess in GNU Emacs" tar | 
					 | 
				
			||||||
	 ((:keywords "games") | 
					 | 
				
			||||||
	  (:url . "http://elpa.gnu.org/packages/chess.html"))]) | 
					 | 
				
			||||||
 (cl-generic . | 
					 | 
				
			||||||
	     [(0 2) | 
					 | 
				
			||||||
	      nil "Forward cl-generic compatibility for Emacs<25" single | 
					 | 
				
			||||||
	      ((:url . "http://elpa.gnu.org/packages/cl-generic.html") | 
					 | 
				
			||||||
	       (:keywords))]) | 
					 | 
				
			||||||
 (cl-lib . | 
					 | 
				
			||||||
	 [(0 5) | 
					 | 
				
			||||||
	  nil "Properly prefixed CL functions and macros" single | 
					 | 
				
			||||||
	  ((:url . "http://elpa.gnu.org/packages/cl-lib.html") | 
					 | 
				
			||||||
	   (:keywords))]) | 
					 | 
				
			||||||
 (coffee-mode . | 
					 | 
				
			||||||
	      [(0 4 1 1) | 
					 | 
				
			||||||
	       nil "Major mode for CoffeeScript files" single | 
					 | 
				
			||||||
	       ((:url . "http://github.com/defunkt/coffee-mode") | 
					 | 
				
			||||||
		(:keywords "coffeescript" "major" "mode"))]) | 
					 | 
				
			||||||
 (company . | 
					 | 
				
			||||||
	  [(0 8 12) | 
					 | 
				
			||||||
	   ((emacs | 
					 | 
				
			||||||
	     (24 1)) | 
					 | 
				
			||||||
	    (cl-lib | 
					 | 
				
			||||||
	     (0 5))) | 
					 | 
				
			||||||
	   "Modular text completion framework" tar | 
					 | 
				
			||||||
	   ((:keywords "abbrev" "convenience" "matching") | 
					 | 
				
			||||||
	    (:url . "http://company-mode.github.io/"))]) | 
					 | 
				
			||||||
 (company-math . | 
					 | 
				
			||||||
	       [(1 0 1) | 
					 | 
				
			||||||
		((company | 
					 | 
				
			||||||
		  (0 8 0)) | 
					 | 
				
			||||||
		 (math-symbol-lists | 
					 | 
				
			||||||
		  (1 0))) | 
					 | 
				
			||||||
		"Completion backends for unicode math symbols and latex tags" single | 
					 | 
				
			||||||
		((:url . "https://github.com/vspinu/company-math") | 
					 | 
				
			||||||
		 (:keywords "unicode" "symbols" "completion"))]) | 
					 | 
				
			||||||
 (company-statistics . | 
					 | 
				
			||||||
		     [(0 2 1) | 
					 | 
				
			||||||
		      ((emacs | 
					 | 
				
			||||||
			(24 3)) | 
					 | 
				
			||||||
		       (company | 
					 | 
				
			||||||
			(0 8 5))) | 
					 | 
				
			||||||
		      "Sort candidates using completion history" tar | 
					 | 
				
			||||||
		      ((:keywords "abbrev" "convenience" "matching") | 
					 | 
				
			||||||
		       (:url . "https://github.com/company-mode/company-statistics"))]) | 
					 | 
				
			||||||
 (context-coloring . | 
					 | 
				
			||||||
		   [(7 1 0) | 
					 | 
				
			||||||
		    ((emacs | 
					 | 
				
			||||||
		      (24 3)) | 
					 | 
				
			||||||
		     (js2-mode | 
					 | 
				
			||||||
		      (20150713))) | 
					 | 
				
			||||||
		    "Highlight by scope" single | 
					 | 
				
			||||||
		    ((:url . "https://github.com/jacksonrayhamilton/context-coloring") | 
					 | 
				
			||||||
		     (:keywords "convenience" "faces" "tools"))]) | 
					 | 
				
			||||||
 (crisp . | 
					 | 
				
			||||||
	[(1 3 4) | 
					 | 
				
			||||||
	 nil "CRiSP/Brief Emacs emulator" single | 
					 | 
				
			||||||
	 ((:url . "http://elpa.gnu.org/packages/crisp.html") | 
					 | 
				
			||||||
	  (:keywords "emulations" "brief" "crisp"))]) | 
					 | 
				
			||||||
 (csv-mode . | 
					 | 
				
			||||||
	   [(1 5) | 
					 | 
				
			||||||
	    nil "Major mode for editing comma/char separated values" single | 
					 | 
				
			||||||
	    ((:url . "http://centaur.maths.qmul.ac.uk/Emacs/") | 
					 | 
				
			||||||
	     (:keywords "convenience"))]) | 
					 | 
				
			||||||
 (darkroom . | 
					 | 
				
			||||||
	   [(0 1) | 
					 | 
				
			||||||
	    ((cl-lib | 
					 | 
				
			||||||
	      (0 5))) | 
					 | 
				
			||||||
	    "Remove visual distractions and focus on writing" single | 
					 | 
				
			||||||
	    ((:url . "http://elpa.gnu.org/packages/darkroom.html") | 
					 | 
				
			||||||
	     (:keywords "convenience" "emulations"))]) | 
					 | 
				
			||||||
 (dash . | 
					 | 
				
			||||||
       [(2 12 0) | 
					 | 
				
			||||||
	nil "A modern list library for Emacs" tar | 
					 | 
				
			||||||
	((:keywords "lists") | 
					 | 
				
			||||||
	 (:url . "http://elpa.gnu.org/packages/dash.html"))]) | 
					 | 
				
			||||||
 (dbus-codegen . | 
					 | 
				
			||||||
	       [(0 1) | 
					 | 
				
			||||||
		((cl-lib | 
					 | 
				
			||||||
		  (0 5))) | 
					 | 
				
			||||||
		"Lisp code generation for D-Bus." single | 
					 | 
				
			||||||
		((:url . "http://elpa.gnu.org/packages/dbus-codegen.html") | 
					 | 
				
			||||||
		 (:keywords "comm" "dbus" "convenience"))]) | 
					 | 
				
			||||||
 (debbugs . | 
					 | 
				
			||||||
	  [(0 7) | 
					 | 
				
			||||||
	   nil "SOAP library to access debbugs servers" tar | 
					 | 
				
			||||||
	   ((:keywords "comm" "hypermedia") | 
					 | 
				
			||||||
	    (:url . "http://elpa.gnu.org/packages/debbugs.html"))]) | 
					 | 
				
			||||||
 (dict-tree . | 
					 | 
				
			||||||
	    [(0 12 8) | 
					 | 
				
			||||||
	     ((trie | 
					 | 
				
			||||||
	       (0 2 5)) | 
					 | 
				
			||||||
	      (tNFA | 
					 | 
				
			||||||
	       (0 1 1)) | 
					 | 
				
			||||||
	      (heap | 
					 | 
				
			||||||
	       (0 3))) | 
					 | 
				
			||||||
	     "Dictionary data structure" single | 
					 | 
				
			||||||
	     ((:url . "http://www.dr-qubit.org/emacs.php") | 
					 | 
				
			||||||
	      (:keywords "extensions" "matching" "data structures trie" "tree" "dictionary" "completion" "regexp"))]) | 
					 | 
				
			||||||
 (diff-hl . | 
					 | 
				
			||||||
	  [(1 8 0) | 
					 | 
				
			||||||
	   ((cl-lib | 
					 | 
				
			||||||
	     (0 2))) | 
					 | 
				
			||||||
	   "Highlight uncommitted changes" tar | 
					 | 
				
			||||||
	   ((:keywords "vc" "diff") | 
					 | 
				
			||||||
	    (:url . "https://github.com/dgutov/diff-hl"))]) | 
					 | 
				
			||||||
 (dismal . | 
					 | 
				
			||||||
	 [(1 5) | 
					 | 
				
			||||||
	  ((cl-lib | 
					 | 
				
			||||||
	    (0))) | 
					 | 
				
			||||||
	  "Dis Mode Ain't Lotus: Spreadsheet program Emacs" tar | 
					 | 
				
			||||||
	  ((:url . "http://elpa.gnu.org/packages/dismal.html"))]) | 
					 | 
				
			||||||
 (djvu . | 
					 | 
				
			||||||
       [(0 5) | 
					 | 
				
			||||||
	nil "Edit and view Djvu files via djvused" single | 
					 | 
				
			||||||
	((:url . "http://elpa.gnu.org/packages/djvu.html") | 
					 | 
				
			||||||
	 (:keywords "files" "wp"))]) | 
					 | 
				
			||||||
 (docbook . | 
					 | 
				
			||||||
	  [(0 1) | 
					 | 
				
			||||||
	   nil "Info-like viewer for DocBook" single | 
					 | 
				
			||||||
	   ((:url . "http://elpa.gnu.org/packages/docbook.html") | 
					 | 
				
			||||||
	    (:keywords "docs" "help"))]) | 
					 | 
				
			||||||
 (dts-mode . | 
					 | 
				
			||||||
	   [(0 1 0) | 
					 | 
				
			||||||
	    nil "Major mode for Device Tree source files" single | 
					 | 
				
			||||||
	    ((:url . "http://elpa.gnu.org/packages/dts-mode.html") | 
					 | 
				
			||||||
	     (:keywords "languages"))]) | 
					 | 
				
			||||||
 (easy-kill . | 
					 | 
				
			||||||
	    [(0 9 3) | 
					 | 
				
			||||||
	     ((emacs | 
					 | 
				
			||||||
	       (24)) | 
					 | 
				
			||||||
	      (cl-lib | 
					 | 
				
			||||||
	       (0 5))) | 
					 | 
				
			||||||
	     "kill & mark things easily" tar | 
					 | 
				
			||||||
	     ((:keywords "killing" "convenience") | 
					 | 
				
			||||||
	      (:url . "https://github.com/leoliu/easy-kill"))]) | 
					 | 
				
			||||||
 (ediprolog . | 
					 | 
				
			||||||
	    [(1 1) | 
					 | 
				
			||||||
	     nil "Emacs Does Interactive Prolog" single | 
					 | 
				
			||||||
	     ((:url . "http://elpa.gnu.org/packages/ediprolog.html") | 
					 | 
				
			||||||
	      (:keywords "languages" "processes"))]) | 
					 | 
				
			||||||
 (el-search . | 
					 | 
				
			||||||
	    [(0 0 3) | 
					 | 
				
			||||||
	     ((emacs | 
					 | 
				
			||||||
	       (25))) | 
					 | 
				
			||||||
	     "Expression based incremental search for emacs-lisp-mode" single | 
					 | 
				
			||||||
	     ((:url . "http://elpa.gnu.org/packages/el-search.html") | 
					 | 
				
			||||||
	      (:keywords "lisp"))]) | 
					 | 
				
			||||||
 (eldoc-eval . | 
					 | 
				
			||||||
	     [(0 1) | 
					 | 
				
			||||||
	      nil "Enable eldoc support when minibuffer is in use." single | 
					 | 
				
			||||||
	      ((:url . "http://elpa.gnu.org/packages/eldoc-eval.html") | 
					 | 
				
			||||||
	       (:keywords))]) | 
					 | 
				
			||||||
 (electric-spacing . | 
					 | 
				
			||||||
		   [(5 0) | 
					 | 
				
			||||||
		    nil "Insert operators with surrounding spaces smartly" single | 
					 | 
				
			||||||
		    ((:url . "http://elpa.gnu.org/packages/electric-spacing.html") | 
					 | 
				
			||||||
		     (:keywords))]) | 
					 | 
				
			||||||
 (enwc . | 
					 | 
				
			||||||
       [(1 0) | 
					 | 
				
			||||||
	nil "The Emacs Network Client" tar | 
					 | 
				
			||||||
	((:keywords "enwc" "network" "wicd" "manager" "nm") | 
					 | 
				
			||||||
	 (:url . "http://elpa.gnu.org/packages/enwc.html"))]) | 
					 | 
				
			||||||
 (epoch-view . | 
					 | 
				
			||||||
	     [(0 0 1) | 
					 | 
				
			||||||
	      nil "Minor mode to visualize epoch timestamps" single | 
					 | 
				
			||||||
	      ((:url . "http://elpa.gnu.org/packages/epoch-view.html") | 
					 | 
				
			||||||
	       (:keywords "data" "timestamp" "epoch" "unix"))]) | 
					 | 
				
			||||||
 (ergoemacs-mode . | 
					 | 
				
			||||||
		 [(5 14 7 3) | 
					 | 
				
			||||||
		  ((emacs | 
					 | 
				
			||||||
		    (24 1)) | 
					 | 
				
			||||||
		   (undo-tree | 
					 | 
				
			||||||
		    (0 6 5))) | 
					 | 
				
			||||||
		  "Emacs mode based on common modern interface and ergonomics." tar | 
					 | 
				
			||||||
		  ((:keywords "convenience") | 
					 | 
				
			||||||
		   (:url . "https://github.com/ergoemacs/ergoemacs-mode"))]) | 
					 | 
				
			||||||
 (f90-interface-browser . | 
					 | 
				
			||||||
			[(1 1) | 
					 | 
				
			||||||
			 nil "Parse and browse f90 interfaces" single | 
					 | 
				
			||||||
			 ((:url . "http://github.com/wence-/f90-iface/") | 
					 | 
				
			||||||
			  (:keywords))]) | 
					 | 
				
			||||||
 (flylisp . | 
					 | 
				
			||||||
	  [(0 2) | 
					 | 
				
			||||||
	   ((emacs | 
					 | 
				
			||||||
	     (24 1)) | 
					 | 
				
			||||||
	    (cl-lib | 
					 | 
				
			||||||
	     (0 4))) | 
					 | 
				
			||||||
	   "Color unbalanced parentheses and parentheses inconsistent with indentation" single | 
					 | 
				
			||||||
	   ((:url . "http://elpa.gnu.org/packages/flylisp.html") | 
					 | 
				
			||||||
	    (:keywords))]) | 
					 | 
				
			||||||
 (fsm . | 
					 | 
				
			||||||
      [(0 2) | 
					 | 
				
			||||||
       ((emacs | 
					 | 
				
			||||||
	 (24 1)) | 
					 | 
				
			||||||
	(cl-lib | 
					 | 
				
			||||||
	 (0 5))) | 
					 | 
				
			||||||
       "state machine library" single | 
					 | 
				
			||||||
       ((:url . "http://elpa.gnu.org/packages/fsm.html") | 
					 | 
				
			||||||
	(:keywords "extensions"))]) | 
					 | 
				
			||||||
 (ggtags . | 
					 | 
				
			||||||
	 [(0 8 10) | 
					 | 
				
			||||||
	  ((emacs | 
					 | 
				
			||||||
	    (24)) | 
					 | 
				
			||||||
	   (cl-lib | 
					 | 
				
			||||||
	    (0 5))) | 
					 | 
				
			||||||
	  "emacs frontend to GNU Global source code tagging system" single | 
					 | 
				
			||||||
	  ((:url . "https://github.com/leoliu/ggtags") | 
					 | 
				
			||||||
	   (:keywords "tools" "convenience"))]) | 
					 | 
				
			||||||
 (gnorb . | 
					 | 
				
			||||||
	[(1 1 1) | 
					 | 
				
			||||||
	 ((cl-lib | 
					 | 
				
			||||||
	   (0 5))) | 
					 | 
				
			||||||
	 "Glue code between Gnus, Org, and BBDB" tar | 
					 | 
				
			||||||
	 ((:keywords "mail" "org" "gnus" "bbdb" "todo" "task") | 
					 | 
				
			||||||
	  (:url . "https://github.com/girzel/gnorb"))]) | 
					 | 
				
			||||||
 (gnugo . | 
					 | 
				
			||||||
	[(3 0 0) | 
					 | 
				
			||||||
	 ((ascii-art-to-unicode | 
					 | 
				
			||||||
	   (1 5)) | 
					 | 
				
			||||||
	  (xpm | 
					 | 
				
			||||||
	   (1 0 1)) | 
					 | 
				
			||||||
	  (cl-lib | 
					 | 
				
			||||||
	   (0 5))) | 
					 | 
				
			||||||
	 "play GNU Go in a buffer" tar | 
					 | 
				
			||||||
	 ((:keywords "games" "processes") | 
					 | 
				
			||||||
	  (:url . "http://www.gnuvola.org/software/gnugo/"))]) | 
					 | 
				
			||||||
 (heap . | 
					 | 
				
			||||||
       [(0 3) | 
					 | 
				
			||||||
	nil "Heap (a.k.a. priority queue) data structure" single | 
					 | 
				
			||||||
	((:url . "http://www.dr-qubit.org/emacs.php") | 
					 | 
				
			||||||
	 (:keywords "extensions" "data structures" "heap" "priority queue"))]) | 
					 | 
				
			||||||
 (hydra . | 
					 | 
				
			||||||
	[(0 13 3) | 
					 | 
				
			||||||
	 ((cl-lib | 
					 | 
				
			||||||
	   (0 5))) | 
					 | 
				
			||||||
	 "Make bindings that stick around." tar | 
					 | 
				
			||||||
	 ((:keywords "bindings") | 
					 | 
				
			||||||
	  (:url . "https://github.com/abo-abo/hydra"))]) | 
					 | 
				
			||||||
 (ioccur . | 
					 | 
				
			||||||
	 [(2 4) | 
					 | 
				
			||||||
	  nil "Incremental occur" single | 
					 | 
				
			||||||
	  ((:url . "http://elpa.gnu.org/packages/ioccur.html") | 
					 | 
				
			||||||
	   (:keywords))]) | 
					 | 
				
			||||||
 (iterators . | 
					 | 
				
			||||||
	    [(0 1) | 
					 | 
				
			||||||
	     ((emacs | 
					 | 
				
			||||||
	       (25))) | 
					 | 
				
			||||||
	     "Functions for working with iterators" single | 
					 | 
				
			||||||
	     ((:url . "http://elpa.gnu.org/packages/iterators.html") | 
					 | 
				
			||||||
	      (:keywords "extensions" "elisp"))]) | 
					 | 
				
			||||||
 (javaimp . | 
					 | 
				
			||||||
	  [(0 5) | 
					 | 
				
			||||||
	   nil "Add and reorder Java import statements in Maven projects" single | 
					 | 
				
			||||||
	   ((:url . "http://elpa.gnu.org/packages/javaimp.html") | 
					 | 
				
			||||||
	    (:keywords "java" "maven" "programming"))]) | 
					 | 
				
			||||||
 (jgraph-mode . | 
					 | 
				
			||||||
	      [(1 1) | 
					 | 
				
			||||||
	       ((cl-lib | 
					 | 
				
			||||||
		 (0 5))) | 
					 | 
				
			||||||
	       "Major mode for Jgraph files" single | 
					 | 
				
			||||||
	       ((:url . "http://elpa.gnu.org/packages/jgraph-mode.html") | 
					 | 
				
			||||||
		(:keywords "tex" "wp"))]) | 
					 | 
				
			||||||
 (js2-mode . | 
					 | 
				
			||||||
	   [(20150909) | 
					 | 
				
			||||||
	    ((emacs | 
					 | 
				
			||||||
	      (24 1)) | 
					 | 
				
			||||||
	     (cl-lib | 
					 | 
				
			||||||
	      (0 5))) | 
					 | 
				
			||||||
	    "Improved JavaScript editing mode" tar | 
					 | 
				
			||||||
	    ((:keywords "languages" "javascript") | 
					 | 
				
			||||||
	     (:url . "https://github.com/mooz/js2-mode/"))]) | 
					 | 
				
			||||||
 (jumpc . | 
					 | 
				
			||||||
	[(3 0) | 
					 | 
				
			||||||
	 nil "jump to previous insertion points" single | 
					 | 
				
			||||||
	 ((:url . "http://elpa.gnu.org/packages/jumpc.html") | 
					 | 
				
			||||||
	  (:keywords))]) | 
					 | 
				
			||||||
 (landmark . | 
					 | 
				
			||||||
	   [(1 0) | 
					 | 
				
			||||||
	    nil "Neural-network robot that learns landmarks" single | 
					 | 
				
			||||||
	    ((:url . "http://elpa.gnu.org/packages/landmark.html") | 
					 | 
				
			||||||
	     (:keywords "games" "neural network" "adaptive search" "chemotaxis"))]) | 
					 | 
				
			||||||
 (let-alist . | 
					 | 
				
			||||||
	    [(1 0 4) | 
					 | 
				
			||||||
	     nil "Easily let-bind values of an assoc-list by their names" single | 
					 | 
				
			||||||
	     ((:url . "http://elpa.gnu.org/packages/let-alist.html") | 
					 | 
				
			||||||
	      (:keywords "extensions" "lisp"))]) | 
					 | 
				
			||||||
 (lex . | 
					 | 
				
			||||||
      [(1 1) | 
					 | 
				
			||||||
       nil "Lexical analyser construction" tar | 
					 | 
				
			||||||
       ((:url . "http://elpa.gnu.org/packages/lex.html"))]) | 
					 | 
				
			||||||
 (lmc . | 
					 | 
				
			||||||
      [(1 3) | 
					 | 
				
			||||||
       nil "Little Man Computer in Elisp" single | 
					 | 
				
			||||||
       ((:url . "http://elpa.gnu.org/packages/lmc.html") | 
					 | 
				
			||||||
	(:keywords))]) | 
					 | 
				
			||||||
 (load-dir . | 
					 | 
				
			||||||
	   [(0 0 3) | 
					 | 
				
			||||||
	    nil "Load all Emacs Lisp files in a given directory" single | 
					 | 
				
			||||||
	    ((:url . "http://elpa.gnu.org/packages/load-dir.html") | 
					 | 
				
			||||||
	     (:keywords "lisp" "files" "convenience"))]) | 
					 | 
				
			||||||
 (load-relative . | 
					 | 
				
			||||||
		[(1 2) | 
					 | 
				
			||||||
		 nil "relative file load (within a multi-file Emacs package)" single | 
					 | 
				
			||||||
		 ((:url . "http://github.com/rocky/emacs-load-relative") | 
					 | 
				
			||||||
		  (:keywords "internal"))]) | 
					 | 
				
			||||||
 (loc-changes . | 
					 | 
				
			||||||
	      [(1 2) | 
					 | 
				
			||||||
	       nil "keep track of positions even after buffer changes" single | 
					 | 
				
			||||||
	       ((:url . "http://github.com/rocky/emacs-loc-changes") | 
					 | 
				
			||||||
		(:keywords))]) | 
					 | 
				
			||||||
 (markchars . | 
					 | 
				
			||||||
	    [(0 2 0) | 
					 | 
				
			||||||
	     nil "Mark chars fitting certain characteristics" single | 
					 | 
				
			||||||
	     ((:url . "http://elpa.gnu.org/packages/markchars.html") | 
					 | 
				
			||||||
	      (:keywords))]) | 
					 | 
				
			||||||
 (math-symbol-lists . | 
					 | 
				
			||||||
		    [(1 0) | 
					 | 
				
			||||||
		     nil "Lists of Unicode math symbols and latex commands" single | 
					 | 
				
			||||||
		     ((:url . "https://github.com/vspinu/math-symbol-lists") | 
					 | 
				
			||||||
		      (:keywords "unicode" "symbols" "mathematics"))]) | 
					 | 
				
			||||||
 (memory-usage . | 
					 | 
				
			||||||
	       [(0 2) | 
					 | 
				
			||||||
		nil "Analyze the memory usage of Emacs in various ways" single | 
					 | 
				
			||||||
		((:url . "http://elpa.gnu.org/packages/memory-usage.html") | 
					 | 
				
			||||||
		 (:keywords "maint"))]) | 
					 | 
				
			||||||
 (metar . | 
					 | 
				
			||||||
	[(0 1) | 
					 | 
				
			||||||
	 ((cl-lib | 
					 | 
				
			||||||
	   (0 5))) | 
					 | 
				
			||||||
	 "Retrieve and decode METAR weather information" single | 
					 | 
				
			||||||
	 ((:url . "http://elpa.gnu.org/packages/metar.html") | 
					 | 
				
			||||||
	  (:keywords "comm"))]) | 
					 | 
				
			||||||
 (midi-kbd . | 
					 | 
				
			||||||
	   [(0 2) | 
					 | 
				
			||||||
	    ((emacs | 
					 | 
				
			||||||
	      (25))) | 
					 | 
				
			||||||
	    "Create keyboard events from Midi input" single | 
					 | 
				
			||||||
	    ((:url . "http://elpa.gnu.org/packages/midi-kbd.html") | 
					 | 
				
			||||||
	     (:keywords "convenience" "hardware" "multimedia"))]) | 
					 | 
				
			||||||
 (minibuffer-line . | 
					 | 
				
			||||||
		  [(0 1) | 
					 | 
				
			||||||
		   nil "Display status info in the minibuffer window" single | 
					 | 
				
			||||||
		   ((:url . "http://elpa.gnu.org/packages/minibuffer-line.html") | 
					 | 
				
			||||||
		    (:keywords))]) | 
					 | 
				
			||||||
 (minimap . | 
					 | 
				
			||||||
	  [(1 2) | 
					 | 
				
			||||||
	   nil "Sidebar showing a \"mini-map\" of a buffer" single | 
					 | 
				
			||||||
	   ((:url . "http://elpa.gnu.org/packages/minimap.html") | 
					 | 
				
			||||||
	    (:keywords))]) | 
					 | 
				
			||||||
 (muse . | 
					 | 
				
			||||||
       [(3 20) | 
					 | 
				
			||||||
	nil "Authoring and publishing tool for Emacs" tar | 
					 | 
				
			||||||
	((:keywords "hypermedia") | 
					 | 
				
			||||||
	 (:url . "http://mwolson.org/projects/EmacsMuse.html"))]) | 
					 | 
				
			||||||
 (nameless . | 
					 | 
				
			||||||
	   [(0 5 1) | 
					 | 
				
			||||||
	    ((emacs | 
					 | 
				
			||||||
	      (24 4))) | 
					 | 
				
			||||||
	    "Hide package namespace in your emacs-lisp code" single | 
					 | 
				
			||||||
	    ((:url . "https://github.com/Malabarba/nameless") | 
					 | 
				
			||||||
	     (:keywords "convenience" "lisp"))]) | 
					 | 
				
			||||||
 (names . | 
					 | 
				
			||||||
	[(20150723 0) | 
					 | 
				
			||||||
	 ((emacs | 
					 | 
				
			||||||
	   (24 1)) | 
					 | 
				
			||||||
	  (cl-lib | 
					 | 
				
			||||||
	   (0 5))) | 
					 | 
				
			||||||
	 "Namespaces for emacs-lisp. Avoid name clobbering without hiding symbols." tar | 
					 | 
				
			||||||
	 ((:keywords "extensions" "lisp") | 
					 | 
				
			||||||
	  (:url . "https://github.com/Bruce-Connor/names"))]) | 
					 | 
				
			||||||
 (nhexl-mode . | 
					 | 
				
			||||||
	     [(0 1) | 
					 | 
				
			||||||
	      nil "Minor mode to edit files via hex-dump format" single | 
					 | 
				
			||||||
	      ((:url . "http://elpa.gnu.org/packages/nhexl-mode.html") | 
					 | 
				
			||||||
	       (:keywords "data"))]) | 
					 | 
				
			||||||
 (nlinum . | 
					 | 
				
			||||||
	 [(1 6) | 
					 | 
				
			||||||
	  nil "Show line numbers in the margin" single | 
					 | 
				
			||||||
	  ((:url . "http://elpa.gnu.org/packages/nlinum.html") | 
					 | 
				
			||||||
	   (:keywords "convenience"))]) | 
					 | 
				
			||||||
 (notes-mode . | 
					 | 
				
			||||||
	     [(1 30) | 
					 | 
				
			||||||
	      nil "Indexing system for on-line note-taking" tar | 
					 | 
				
			||||||
	      ((:url . "http://elpa.gnu.org/packages/notes-mode.html"))]) | 
					 | 
				
			||||||
 (num3-mode . | 
					 | 
				
			||||||
	    [(1 2) | 
					 | 
				
			||||||
	     nil "highlight groups of digits in long numbers" single | 
					 | 
				
			||||||
	     ((:url . "http://elpa.gnu.org/packages/num3-mode.html") | 
					 | 
				
			||||||
	      (:keywords "faces" "minor-mode"))]) | 
					 | 
				
			||||||
 (oauth2 . | 
					 | 
				
			||||||
	 [(0 10) | 
					 | 
				
			||||||
	  nil "OAuth 2.0 Authorization Protocol" single | 
					 | 
				
			||||||
	  ((:url . "http://elpa.gnu.org/packages/oauth2.html") | 
					 | 
				
			||||||
	   (:keywords "comm"))]) | 
					 | 
				
			||||||
 (omn-mode . | 
					 | 
				
			||||||
	   [(1 2) | 
					 | 
				
			||||||
	    nil "Support for OWL Manchester Notation" single | 
					 | 
				
			||||||
	    ((:url . "http://elpa.gnu.org/packages/omn-mode.html") | 
					 | 
				
			||||||
	     (:keywords))]) | 
					 | 
				
			||||||
 (org . | 
					 | 
				
			||||||
      [(20151005) | 
					 | 
				
			||||||
       nil "Outline-based notes management and organizer" tar nil]) | 
					 | 
				
			||||||
 (osc . | 
					 | 
				
			||||||
      [(0 1) | 
					 | 
				
			||||||
       nil "Open Sound Control protocol library" single | 
					 | 
				
			||||||
       ((:url . "http://elpa.gnu.org/packages/osc.html") | 
					 | 
				
			||||||
	(:keywords "comm" "processes" "multimedia"))]) | 
					 | 
				
			||||||
 (other-frame-window . | 
					 | 
				
			||||||
		     [(1 0 1) | 
					 | 
				
			||||||
		      ((emacs | 
					 | 
				
			||||||
			(24 4))) | 
					 | 
				
			||||||
		      "Minor mode to enable global prefix keys for other frame/window buffer placement" single | 
					 | 
				
			||||||
		      ((:url . "http://elpa.gnu.org/packages/other-frame-window.html") | 
					 | 
				
			||||||
		       (:keywords "frame" "window"))]) | 
					 | 
				
			||||||
 (pabbrev . | 
					 | 
				
			||||||
	  [(4 2 1) | 
					 | 
				
			||||||
	   nil "Predictive abbreviation expansion" single | 
					 | 
				
			||||||
	   ((:url . "http://elpa.gnu.org/packages/pabbrev.html") | 
					 | 
				
			||||||
	    (:keywords))]) | 
					 | 
				
			||||||
 (pinentry . | 
					 | 
				
			||||||
	   [(0 1) | 
					 | 
				
			||||||
	    nil "GnuPG Pinentry server implementation" single | 
					 | 
				
			||||||
	    ((:url . "http://elpa.gnu.org/packages/pinentry.html") | 
					 | 
				
			||||||
	     (:keywords "gnupg"))]) | 
					 | 
				
			||||||
 (poker . | 
					 | 
				
			||||||
	[(0 1) | 
					 | 
				
			||||||
	 nil "Texas hold'em poker" single | 
					 | 
				
			||||||
	 ((:url . "http://elpa.gnu.org/packages/poker.html") | 
					 | 
				
			||||||
	  (:keywords "games"))]) | 
					 | 
				
			||||||
 (quarter-plane . | 
					 | 
				
			||||||
		[(0 1) | 
					 | 
				
			||||||
		 nil "Minor mode for quarter-plane style editing" single | 
					 | 
				
			||||||
		 ((:url . "http://elpa.gnu.org/packages/quarter-plane.html") | 
					 | 
				
			||||||
		  (:keywords "convenience" "wp"))]) | 
					 | 
				
			||||||
 (queue . | 
					 | 
				
			||||||
	[(0 1 1) | 
					 | 
				
			||||||
	 nil "Queue data structure" single | 
					 | 
				
			||||||
	 ((:url . "http://www.dr-qubit.org/emacs.php") | 
					 | 
				
			||||||
	  (:keywords "extensions" "data structures" "queue"))]) | 
					 | 
				
			||||||
 (rainbow-mode . | 
					 | 
				
			||||||
	       [(0 12) | 
					 | 
				
			||||||
		nil "Colorize color names in buffers" single | 
					 | 
				
			||||||
		((:url . "http://elpa.gnu.org/packages/rainbow-mode.html") | 
					 | 
				
			||||||
		 (:keywords "faces"))]) | 
					 | 
				
			||||||
 (register-list . | 
					 | 
				
			||||||
		[(0 1) | 
					 | 
				
			||||||
		 nil "Interactively list/edit registers" single | 
					 | 
				
			||||||
		 ((:url . "http://elpa.gnu.org/packages/register-list.html") | 
					 | 
				
			||||||
		  (:keywords "register"))]) | 
					 | 
				
			||||||
 (rich-minority . | 
					 | 
				
			||||||
		[(1 0) | 
					 | 
				
			||||||
		 ((cl-lib | 
					 | 
				
			||||||
		   (0 5))) | 
					 | 
				
			||||||
		 "Clean-up and Beautify the list of minor-modes." single | 
					 | 
				
			||||||
		 ((:url . "https://github.com/Malabarba/rich-minority") | 
					 | 
				
			||||||
		  (:keywords "mode-line" "faces"))]) | 
					 | 
				
			||||||
 (rudel . | 
					 | 
				
			||||||
	[(0 3) | 
					 | 
				
			||||||
	 nil "A collaborative editing framework for Emacs" tar | 
					 | 
				
			||||||
	 ((:keywords "rudel" "collaboration") | 
					 | 
				
			||||||
	  (:url . "http://rudel.sourceforge.net/"))]) | 
					 | 
				
			||||||
 (scroll-restore . | 
					 | 
				
			||||||
		 [(1 0) | 
					 | 
				
			||||||
		  nil "restore original position after scrolling" single | 
					 | 
				
			||||||
		  ((:url . "http://elpa.gnu.org/packages/scroll-restore.html") | 
					 | 
				
			||||||
		   (:keywords "scrolling"))]) | 
					 | 
				
			||||||
 (seq . | 
					 | 
				
			||||||
      [(1 11) | 
					 | 
				
			||||||
       nil "Sequence manipulation functions" single | 
					 | 
				
			||||||
       ((:url . "http://elpa.gnu.org/packages/seq.html") | 
					 | 
				
			||||||
	(:keywords "sequences"))]) | 
					 | 
				
			||||||
 (shen-mode . | 
					 | 
				
			||||||
	    [(0 1) | 
					 | 
				
			||||||
	     nil "A major mode for editing shen source code" tar | 
					 | 
				
			||||||
	     ((:keywords "languages" "shen") | 
					 | 
				
			||||||
	      (:url . "http://elpa.gnu.org/packages/shen-mode.html"))]) | 
					 | 
				
			||||||
 (sisu-mode . | 
					 | 
				
			||||||
	    [(3 0 3) | 
					 | 
				
			||||||
	     nil "Major mode for SiSU markup text" single | 
					 | 
				
			||||||
	     ((:url . "http://elpa.gnu.org/packages/sisu-mode.html") | 
					 | 
				
			||||||
	      (:keywords "text" "processes" "tools"))]) | 
					 | 
				
			||||||
 (sml-mode . | 
					 | 
				
			||||||
	   [(6 7) | 
					 | 
				
			||||||
	    nil "Major mode for editing (Standard) ML" single | 
					 | 
				
			||||||
	    ((:url . "http://elpa.gnu.org/packages/sml-mode.html") | 
					 | 
				
			||||||
	     (:keywords "sml"))]) | 
					 | 
				
			||||||
 (sokoban . | 
					 | 
				
			||||||
	  [(1 4) | 
					 | 
				
			||||||
	   nil "Implementation of Sokoban for Emacs." tar | 
					 | 
				
			||||||
	   ((:keywords "games") | 
					 | 
				
			||||||
	    (:url . "http://elpa.gnu.org/packages/sokoban.html"))]) | 
					 | 
				
			||||||
 (sotlisp . | 
					 | 
				
			||||||
	  [(1 4 1) | 
					 | 
				
			||||||
	   ((emacs | 
					 | 
				
			||||||
	     (24 1))) | 
					 | 
				
			||||||
	   "Write lisp at the speed of thought." single | 
					 | 
				
			||||||
	   ((:url . "https://github.com/Malabarba/speed-of-thought-lisp") | 
					 | 
				
			||||||
	    (:keywords "convenience" "lisp"))]) | 
					 | 
				
			||||||
 (spinner . | 
					 | 
				
			||||||
	  [(1 4) | 
					 | 
				
			||||||
	   nil "Add spinners and progress-bars to the mode-line for ongoing operations" single | 
					 | 
				
			||||||
	   ((:url . "https://github.com/Malabarba/spinner.el") | 
					 | 
				
			||||||
	    (:keywords "processes" "mode-line"))]) | 
					 | 
				
			||||||
 (stream . | 
					 | 
				
			||||||
	 [(1 0) | 
					 | 
				
			||||||
	  ((emacs | 
					 | 
				
			||||||
	    (25))) | 
					 | 
				
			||||||
	  "Implementation of streams" single | 
					 | 
				
			||||||
	  ((:url . "http://elpa.gnu.org/packages/stream.html") | 
					 | 
				
			||||||
	   (:keywords "stream" "laziness" "sequences"))]) | 
					 | 
				
			||||||
 (svg . | 
					 | 
				
			||||||
      [(0 1) | 
					 | 
				
			||||||
       ((emacs | 
					 | 
				
			||||||
	 (25))) | 
					 | 
				
			||||||
       "svg image creation functions" single | 
					 | 
				
			||||||
       ((:url . "http://elpa.gnu.org/packages/svg.html") | 
					 | 
				
			||||||
	(:keywords "image"))]) | 
					 | 
				
			||||||
 (svg-clock . | 
					 | 
				
			||||||
	    [(0 5) | 
					 | 
				
			||||||
	     ((svg | 
					 | 
				
			||||||
	       (0 1)) | 
					 | 
				
			||||||
	      (emacs | 
					 | 
				
			||||||
	       (25 0))) | 
					 | 
				
			||||||
	     "Analog clock using Scalable Vector Graphics" single | 
					 | 
				
			||||||
	     ((:url . "http://elpa.gnu.org/packages/svg-clock.html") | 
					 | 
				
			||||||
	      (:keywords "demo" "svg" "clock"))]) | 
					 | 
				
			||||||
 (swiper . | 
					 | 
				
			||||||
	 [(0 5 1) | 
					 | 
				
			||||||
	  ((emacs | 
					 | 
				
			||||||
	    (24 1))) | 
					 | 
				
			||||||
	  "Isearch with an overview. Oh, man!" tar | 
					 | 
				
			||||||
	  ((:keywords "matching") | 
					 | 
				
			||||||
	   (:url . "https://github.com/abo-abo/swiper"))]) | 
					 | 
				
			||||||
 (tNFA . | 
					 | 
				
			||||||
       [(0 1 1) | 
					 | 
				
			||||||
	((queue | 
					 | 
				
			||||||
	  (0 1))) | 
					 | 
				
			||||||
	"Tagged non-deterministic finite-state automata" single | 
					 | 
				
			||||||
	((:url . "http://www.dr-qubit.org/emacs.php") | 
					 | 
				
			||||||
	 (:keywords "extensions" "matching" "data structures tnfa" "nfa" "dfa" "finite state automata" "automata" "regexp"))]) | 
					 | 
				
			||||||
 (temp-buffer-browse . | 
					 | 
				
			||||||
		     [(1 4) | 
					 | 
				
			||||||
		      nil "temp buffer browse mode" single | 
					 | 
				
			||||||
		      ((:url . "http://elpa.gnu.org/packages/temp-buffer-browse.html") | 
					 | 
				
			||||||
		       (:keywords "convenience"))]) | 
					 | 
				
			||||||
 (test-simple . | 
					 | 
				
			||||||
	      [(1 1) | 
					 | 
				
			||||||
	       ((cl-lib | 
					 | 
				
			||||||
		 (0))) | 
					 | 
				
			||||||
	       "Simple Unit Test Framework for Emacs Lisp" single | 
					 | 
				
			||||||
	       ((:url . "http://github.com/rocky/emacs-test-simple") | 
					 | 
				
			||||||
		(:keywords "unit-test"))]) | 
					 | 
				
			||||||
 (timerfunctions . | 
					 | 
				
			||||||
		 [(1 4 2) | 
					 | 
				
			||||||
		  ((cl-lib | 
					 | 
				
			||||||
		    (0 5))) | 
					 | 
				
			||||||
		  "Enhanced versions of some timer.el functions" single | 
					 | 
				
			||||||
		  ((:url . "http://elpa.gnu.org/packages/timerfunctions.html") | 
					 | 
				
			||||||
		   (:keywords))]) | 
					 | 
				
			||||||
 (tiny . | 
					 | 
				
			||||||
       [(0 1) | 
					 | 
				
			||||||
	nil "Quickly generate linear ranges in Emacs" tar | 
					 | 
				
			||||||
	((:keywords "convenience") | 
					 | 
				
			||||||
	 (:url . "https://github.com/abo-abo/tiny"))]) | 
					 | 
				
			||||||
 (trie . | 
					 | 
				
			||||||
       [(0 2 6) | 
					 | 
				
			||||||
	((tNFA | 
					 | 
				
			||||||
	  (0 1 1)) | 
					 | 
				
			||||||
	 (heap | 
					 | 
				
			||||||
	  (0 3))) | 
					 | 
				
			||||||
	"Trie data structure" single | 
					 | 
				
			||||||
	((:url . "http://www.dr-qubit.org/emacs.php") | 
					 | 
				
			||||||
	 (:keywords "extensions" "matching" "data structures trie" "ternary search tree" "tree" "completion" "regexp"))]) | 
					 | 
				
			||||||
 (undo-tree . | 
					 | 
				
			||||||
	    [(0 6 5) | 
					 | 
				
			||||||
	     nil "Treat undo history as a tree" single | 
					 | 
				
			||||||
	     ((:url . "http://www.dr-qubit.org/emacs.php") | 
					 | 
				
			||||||
	      (:keywords "convenience" "files" "undo" "redo" "history" "tree"))]) | 
					 | 
				
			||||||
 (uni-confusables . | 
					 | 
				
			||||||
		  [(0 1) | 
					 | 
				
			||||||
		   nil "Unicode confusables table" tar | 
					 | 
				
			||||||
		   ((:url . "http://elpa.gnu.org/packages/uni-confusables.html"))]) | 
					 | 
				
			||||||
 (vlf . | 
					 | 
				
			||||||
      [(1 7) | 
					 | 
				
			||||||
       nil "View Large Files" tar | 
					 | 
				
			||||||
       ((:keywords "large files" "utilities") | 
					 | 
				
			||||||
	(:url . "https://github.com/m00natic/vlfi"))]) | 
					 | 
				
			||||||
 (w3 . | 
					 | 
				
			||||||
     [(4 0 49) | 
					 | 
				
			||||||
      nil "Fully customizable, largely undocumented web browser for Emacs" tar | 
					 | 
				
			||||||
      ((:keywords "faces" "help" "comm" "news" "mail" "processes" "mouse" "hypermedia") | 
					 | 
				
			||||||
       (:url . "http://elpa.gnu.org/packages/w3.html"))]) | 
					 | 
				
			||||||
 (wcheck-mode . | 
					 | 
				
			||||||
	      [(2014 6 21) | 
					 | 
				
			||||||
	       nil "General interface for text checkers" single | 
					 | 
				
			||||||
	       ((:url . "https://github.com/tlikonen/wcheck-mode") | 
					 | 
				
			||||||
		(:keywords "text" "spell" "check" "languages" "ispell"))]) | 
					 | 
				
			||||||
 (wconf . | 
					 | 
				
			||||||
	[(0 2 0) | 
					 | 
				
			||||||
	 ((emacs | 
					 | 
				
			||||||
	   (24 4))) | 
					 | 
				
			||||||
	 "Minimal window layout manager" single | 
					 | 
				
			||||||
	 ((:url . "https://github.com/ilohmar/wconf") | 
					 | 
				
			||||||
	  (:keywords "windows" "frames" "layout"))]) | 
					 | 
				
			||||||
 (web-server . | 
					 | 
				
			||||||
	     [(0 1 1) | 
					 | 
				
			||||||
	      ((emacs | 
					 | 
				
			||||||
		(24 3))) | 
					 | 
				
			||||||
	      "Emacs Web Server" tar | 
					 | 
				
			||||||
	      ((:keywords "http" "server" "network") | 
					 | 
				
			||||||
	       (:url . "https://github.com/eschulte/emacs-web-server"))]) | 
					 | 
				
			||||||
 (websocket . | 
					 | 
				
			||||||
	    [(1 5) | 
					 | 
				
			||||||
	     nil "Emacs WebSocket client and server" tar | 
					 | 
				
			||||||
	     ((:keywords "communication" "websocket" "server") | 
					 | 
				
			||||||
	      (:url . "http://elpa.gnu.org/packages/websocket.html"))]) | 
					 | 
				
			||||||
 (windresize . | 
					 | 
				
			||||||
	     [(0 1) | 
					 | 
				
			||||||
	      nil "Resize windows interactively" single | 
					 | 
				
			||||||
	      ((:url . "http://elpa.gnu.org/packages/windresize.html") | 
					 | 
				
			||||||
	       (:keywords "window"))]) | 
					 | 
				
			||||||
 (wisi . | 
					 | 
				
			||||||
       [(1 1 1) | 
					 | 
				
			||||||
	((cl-lib | 
					 | 
				
			||||||
	  (0 4)) | 
					 | 
				
			||||||
	 (emacs | 
					 | 
				
			||||||
	  (24 2))) | 
					 | 
				
			||||||
	"Utilities for implementing an indentation/navigation engine using a generalized LALR parser" tar | 
					 | 
				
			||||||
	((:keywords "parser" "indentation" "navigation") | 
					 | 
				
			||||||
	 (:url . "http://stephe-leake.org/emacs/ada-mode/emacs-ada-mode.html"))]) | 
					 | 
				
			||||||
 (wpuzzle . | 
					 | 
				
			||||||
	  [(1 1) | 
					 | 
				
			||||||
	   nil "find as many word in a given time" single | 
					 | 
				
			||||||
	   ((:url . "http://elpa.gnu.org/packages/wpuzzle.html") | 
					 | 
				
			||||||
	    (:keywords))]) | 
					 | 
				
			||||||
 (xclip . | 
					 | 
				
			||||||
	[(1 3) | 
					 | 
				
			||||||
	 nil "use xclip to copy&paste" single | 
					 | 
				
			||||||
	 ((:url . "http://elpa.gnu.org/packages/xclip.html") | 
					 | 
				
			||||||
	  (:keywords "convenience" "tools"))]) | 
					 | 
				
			||||||
 (xelb . | 
					 | 
				
			||||||
       [(0 2) | 
					 | 
				
			||||||
	((emacs | 
					 | 
				
			||||||
	  (24 4)) | 
					 | 
				
			||||||
	 (cl-generic | 
					 | 
				
			||||||
	  (0 2))) | 
					 | 
				
			||||||
	"X protocol Emacs Lisp Binding" tar | 
					 | 
				
			||||||
	((:keywords "unix") | 
					 | 
				
			||||||
	 (:url . "https://github.com/ch11ng/xelb"))]) | 
					 | 
				
			||||||
 (xpm . | 
					 | 
				
			||||||
      [(1 0 3) | 
					 | 
				
			||||||
       nil "edit XPM images" tar | 
					 | 
				
			||||||
       ((:keywords "multimedia" "xpm") | 
					 | 
				
			||||||
	(:url . "http://www.gnuvola.org/software/xpm/"))]) | 
					 | 
				
			||||||
 (yasnippet . | 
					 | 
				
			||||||
	    [(0 8 0) | 
					 | 
				
			||||||
	     nil "Yet another snippet extension for Emacs." tar | 
					 | 
				
			||||||
	     ((:keywords "convenience" "emulation") | 
					 | 
				
			||||||
	      (:url . "http://github.com/capitaomorte/yasnippet"))]) | 
					 | 
				
			||||||
 (ztree . | 
					 | 
				
			||||||
	[(1 0 2) | 
					 | 
				
			||||||
	 nil "Text mode directory tree" tar | 
					 | 
				
			||||||
	 ((:keywords "files" "tools") | 
					 | 
				
			||||||
	  (:url . "https://github.com/fourier/ztree"))])) | 
					 | 
				
			||||||
@ -1 +0,0 @@ | 
				
			|||||||
Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2015-10-24T02:05:02-0700 using DSA | 
					 | 
				
			||||||
									
										
											File diff suppressed because one or more lines are too long
										
									
								
							
						@ -1 +0,0 @@ | 
				
			|||||||
(define-package "clojure-mode" "20151022.27" "Major mode for Clojure code" '((emacs "24.3")) :url "http://github.com/clojure-emacs/clojure-mode" :keywords '("languages" "clojure" "clojurescript" "lisp")) | 
					 | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -1 +0,0 @@ | 
				
			|||||||
(define-package "coffee-mode" "20151019.2009" "Major mode to edit CoffeeScript files in Emacs" '((emacs "24.1") (cl-lib "0.5")) :url "http://github.com/defunkt/coffee-mode" :keywords '("coffeescript" "major" "mode")) | 
					 | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -1 +0,0 @@ | 
				
			|||||||
(define-package "dash" "20151021.113" "A modern list library for Emacs" 'nil :keywords '("lists")) | 
					 | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -1 +0,0 @@ | 
				
			|||||||
(define-package "epl" "20150517.433" "Emacs Package Library" '((cl-lib "0.3")) :url "http://github.com/cask/epl" :keywords '("convenience")) | 
					 | 
				
			||||||
@ -1,11 +0,0 @@ | 
				
			|||||||
(define-package "flycheck" "20151022.1349" "On-the-fly syntax checking" | 
					 | 
				
			||||||
  '((dash "2.4.0") | 
					 | 
				
			||||||
    (pkg-info "0.4") | 
					 | 
				
			||||||
    (let-alist "1.0.1") | 
					 | 
				
			||||||
    (cl-lib "0.3") | 
					 | 
				
			||||||
    (emacs "24.3")) | 
					 | 
				
			||||||
  :url "https://www.flycheck.org" :keywords | 
					 | 
				
			||||||
  '("convenience" "languages" "tools")) | 
					 | 
				
			||||||
;; Local Variables: | 
					 | 
				
			||||||
;; no-byte-compile: t | 
					 | 
				
			||||||
;; End: | 
					 | 
				
			||||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						
									
										Binary file not shown.
									
								
							
						
									
										Binary file not shown.
									
								
							
						@ -1 +0,0 @@ | 
				
			|||||||
Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2015-06-12T02:05:02-0700 using DSA | 
					 | 
				
			||||||
@ -1 +0,0 @@ | 
				
			|||||||
(define-package "let-alist" "1.0.4" "Easily let-bind values of an assoc-list by their names" 'nil :url "http://elpa.gnu.org/packages/let-alist.html" :keywords '("extensions" "lisp")) | 
					 | 
				
			||||||
@ -1 +0,0 @@ | 
				
			|||||||
(define-package "pkg-info" "20150517.443" "Information about packages" '((epl "0.8")) :url "https://github.com/lunaryorn/pkg-info.el" :keywords '("convenience")) | 
					 | 
				
			||||||
@ -1 +0,0 @@ | 
				
			|||||||
(define-package "s" "20150924.406" "The long lost Emacs string manipulation library." 'nil :keywords '("strings")) | 
					 | 
				
			||||||
@ -1,605 +0,0 @@ | 
				
			|||||||
;;; s.el --- The long lost Emacs string manipulation library. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; Copyright (C) 2012-2015 Magnar Sveen | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; Author: Magnar Sveen <magnars@gmail.com> | 
					 | 
				
			||||||
;; Version: 1.10.0 | 
					 | 
				
			||||||
;; Package-Version: 20150924.406 | 
					 | 
				
			||||||
;; Keywords: strings | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; 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: | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; The long lost Emacs string manipulation library. | 
					 | 
				
			||||||
;; | 
					 | 
				
			||||||
;; See documentation on https://github.com/magnars/s.el#functions | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;; Code: | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(require 'ucs-normalize) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-trim-left (s) | 
					 | 
				
			||||||
  "Remove whitespace at the beginning of S." | 
					 | 
				
			||||||
  (if (string-match "\\`[ \t\n\r]+" s) | 
					 | 
				
			||||||
      (replace-match "" t t s) | 
					 | 
				
			||||||
    s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-trim-right (s) | 
					 | 
				
			||||||
  "Remove whitespace at the end of S." | 
					 | 
				
			||||||
  (if (string-match "[ \t\n\r]+\\'" s) | 
					 | 
				
			||||||
      (replace-match "" t t s) | 
					 | 
				
			||||||
    s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-trim (s) | 
					 | 
				
			||||||
  "Remove whitespace at the beginning and end of S." | 
					 | 
				
			||||||
  (s-trim-left (s-trim-right s))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-collapse-whitespace (s) | 
					 | 
				
			||||||
  "Convert all adjacent whitespace characters to a single space." | 
					 | 
				
			||||||
  (replace-regexp-in-string "[ \t\n\r]+" " " s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-split (separator s &optional omit-nulls) | 
					 | 
				
			||||||
  "Split S into substrings bounded by matches for regexp SEPARATOR. | 
					 | 
				
			||||||
If OMIT-NULLS is non-nil, zero-length substrings are omitted. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a simple wrapper around the built-in `split-string'." | 
					 | 
				
			||||||
  (split-string s separator omit-nulls)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-split-up-to (separator s n &optional omit-nulls) | 
					 | 
				
			||||||
  "Split S up to N times into substrings bounded by matches for regexp SEPARATOR. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If OMIT-NULLS is non-nil, zero-length substrings are omitted. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See also `s-split'." | 
					 | 
				
			||||||
  (save-match-data | 
					 | 
				
			||||||
    (let ((op 0) | 
					 | 
				
			||||||
          (r nil)) | 
					 | 
				
			||||||
      (with-temp-buffer | 
					 | 
				
			||||||
        (insert s) | 
					 | 
				
			||||||
        (setq op (goto-char (point-min))) | 
					 | 
				
			||||||
        (while (and (re-search-forward separator nil t) | 
					 | 
				
			||||||
                    (< 0 n)) | 
					 | 
				
			||||||
          (let ((sub (buffer-substring-no-properties op (match-beginning 0)))) | 
					 | 
				
			||||||
            (unless (and omit-nulls | 
					 | 
				
			||||||
                         (equal sub "")) | 
					 | 
				
			||||||
              (push sub r))) | 
					 | 
				
			||||||
          (setq op (goto-char (match-end 0))) | 
					 | 
				
			||||||
          (setq n (1- n))) | 
					 | 
				
			||||||
        (let ((sub (buffer-substring-no-properties op (point-max)))) | 
					 | 
				
			||||||
          (unless (and omit-nulls | 
					 | 
				
			||||||
                       (equal sub "")) | 
					 | 
				
			||||||
            (push sub r)))) | 
					 | 
				
			||||||
      (nreverse r)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-lines (s) | 
					 | 
				
			||||||
  "Splits S into a list of strings on newline characters." | 
					 | 
				
			||||||
  (s-split "\\(\r\n\\|[\n\r]\\)" s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-join (separator strings) | 
					 | 
				
			||||||
  "Join all the strings in STRINGS with SEPARATOR in between." | 
					 | 
				
			||||||
  (mapconcat 'identity strings separator)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-concat (&rest strings) | 
					 | 
				
			||||||
  "Join all the string arguments into one string." | 
					 | 
				
			||||||
  (apply 'concat strings)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-prepend (prefix s) | 
					 | 
				
			||||||
  "Concatenate PREFIX and S." | 
					 | 
				
			||||||
  (concat prefix s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-append (suffix s) | 
					 | 
				
			||||||
  "Concatenate S and SUFFIX." | 
					 | 
				
			||||||
  (concat s suffix)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-repeat (num s) | 
					 | 
				
			||||||
  "Make a string of S repeated NUM times." | 
					 | 
				
			||||||
  (let (ss) | 
					 | 
				
			||||||
    (while (> num 0) | 
					 | 
				
			||||||
      (setq ss (cons s ss)) | 
					 | 
				
			||||||
      (setq num (1- num))) | 
					 | 
				
			||||||
    (apply 'concat ss))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-chop-suffix (suffix s) | 
					 | 
				
			||||||
  "Remove SUFFIX if it is at end of S." | 
					 | 
				
			||||||
  (let ((pos (- (length suffix)))) | 
					 | 
				
			||||||
    (if (and (>= (length s) (length suffix)) | 
					 | 
				
			||||||
             (string= suffix (substring s pos))) | 
					 | 
				
			||||||
        (substring s 0 pos) | 
					 | 
				
			||||||
      s))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-chop-suffixes (suffixes s) | 
					 | 
				
			||||||
  "Remove SUFFIXES one by one in order, if they are at the end of S." | 
					 | 
				
			||||||
  (while suffixes | 
					 | 
				
			||||||
    (setq s (s-chop-suffix (car suffixes) s)) | 
					 | 
				
			||||||
    (setq suffixes (cdr suffixes))) | 
					 | 
				
			||||||
  s) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-chop-prefix (prefix s) | 
					 | 
				
			||||||
  "Remove PREFIX if it is at the start of S." | 
					 | 
				
			||||||
  (let ((pos (length prefix))) | 
					 | 
				
			||||||
    (if (and (>= (length s) (length prefix)) | 
					 | 
				
			||||||
             (string= prefix (substring s 0 pos))) | 
					 | 
				
			||||||
        (substring s pos) | 
					 | 
				
			||||||
      s))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-chop-prefixes (prefixes s) | 
					 | 
				
			||||||
  "Remove PREFIXES one by one in order, if they are at the start of S." | 
					 | 
				
			||||||
  (while prefixes | 
					 | 
				
			||||||
    (setq s (s-chop-prefix (car prefixes) s)) | 
					 | 
				
			||||||
    (setq prefixes (cdr prefixes))) | 
					 | 
				
			||||||
  s) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-shared-start (s1 s2) | 
					 | 
				
			||||||
  "Returns the longest prefix S1 and S2 have in common." | 
					 | 
				
			||||||
  (let ((search-length (min (length s1) (length s2))) | 
					 | 
				
			||||||
        (i 0)) | 
					 | 
				
			||||||
    (while (and (< i search-length) | 
					 | 
				
			||||||
                (= (aref s1 i) (aref s2 i))) | 
					 | 
				
			||||||
      (setq i (1+ i))) | 
					 | 
				
			||||||
    (substring s1 0 i))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-shared-end (s1 s2) | 
					 | 
				
			||||||
  "Returns the longest suffix S1 and S2 have in common." | 
					 | 
				
			||||||
  (let* ((l1 (length s1)) | 
					 | 
				
			||||||
         (l2 (length s2)) | 
					 | 
				
			||||||
         (search-length (min l1 l2)) | 
					 | 
				
			||||||
         (i 0)) | 
					 | 
				
			||||||
    (while (and (< i search-length) | 
					 | 
				
			||||||
                (= (aref s1 (- l1 i 1)) (aref s2 (- l2 i 1)))) | 
					 | 
				
			||||||
      (setq i (1+ i))) | 
					 | 
				
			||||||
    ;; If I is 0, then it means that there's no common suffix between | 
					 | 
				
			||||||
    ;; S1 and S2. | 
					 | 
				
			||||||
    ;; | 
					 | 
				
			||||||
    ;; However, since (substring s (- 0)) will return the whole | 
					 | 
				
			||||||
    ;; string, `s-shared-end' should simply return the empty string | 
					 | 
				
			||||||
    ;; when I is 0. | 
					 | 
				
			||||||
    (if (zerop i) | 
					 | 
				
			||||||
        "" | 
					 | 
				
			||||||
      (substring s1 (- i))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-chomp (s) | 
					 | 
				
			||||||
  "Remove one trailing `\\n`, `\\r` or `\\r\\n` from S." | 
					 | 
				
			||||||
  (s-chop-suffixes '("\n" "\r") s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-truncate (len s) | 
					 | 
				
			||||||
  "If S is longer than LEN, cut it down to LEN - 3 and add ... at the end." | 
					 | 
				
			||||||
  (if (> (length s) len) | 
					 | 
				
			||||||
      (format "%s..." (substring s 0 (- len 3))) | 
					 | 
				
			||||||
    s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-word-wrap (len s) | 
					 | 
				
			||||||
  "If S is longer than LEN, wrap the words with newlines." | 
					 | 
				
			||||||
  (with-temp-buffer | 
					 | 
				
			||||||
    (insert s) | 
					 | 
				
			||||||
    (let ((fill-column len)) | 
					 | 
				
			||||||
      (fill-region (point-min) (point-max))) | 
					 | 
				
			||||||
    (buffer-substring-no-properties (point-min) (point-max)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-center (len s) | 
					 | 
				
			||||||
  "If S is shorter than LEN, pad it with spaces so it is centered." | 
					 | 
				
			||||||
  (let ((extra (max 0 (- len (length s))))) | 
					 | 
				
			||||||
    (concat | 
					 | 
				
			||||||
     (make-string (ceiling extra 2) ? ) | 
					 | 
				
			||||||
     s | 
					 | 
				
			||||||
     (make-string (floor extra 2) ? )))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-pad-left (len padding s) | 
					 | 
				
			||||||
  "If S is shorter than LEN, pad it with PADDING on the left." | 
					 | 
				
			||||||
  (let ((extra (max 0 (- len (length s))))) | 
					 | 
				
			||||||
    (concat (make-string extra (string-to-char padding)) | 
					 | 
				
			||||||
            s))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-pad-right (len padding s) | 
					 | 
				
			||||||
  "If S is shorter than LEN, pad it with PADDING on the right." | 
					 | 
				
			||||||
  (let ((extra (max 0 (- len (length s))))) | 
					 | 
				
			||||||
    (concat s | 
					 | 
				
			||||||
            (make-string extra (string-to-char padding))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-left (len s) | 
					 | 
				
			||||||
  "Returns up to the LEN first chars of S." | 
					 | 
				
			||||||
  (if (> (length s) len) | 
					 | 
				
			||||||
      (substring s 0 len) | 
					 | 
				
			||||||
    s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-right (len s) | 
					 | 
				
			||||||
  "Returns up to the LEN last chars of S." | 
					 | 
				
			||||||
  (let ((l (length s))) | 
					 | 
				
			||||||
    (if (> l len) | 
					 | 
				
			||||||
        (substring s (- l len) l) | 
					 | 
				
			||||||
      s))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-ends-with? (suffix s &optional ignore-case) | 
					 | 
				
			||||||
  "Does S end with SUFFIX? | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If IGNORE-CASE is non-nil, the comparison is done without paying | 
					 | 
				
			||||||
attention to case differences. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Alias: `s-suffix?'" | 
					 | 
				
			||||||
  (let ((start-pos (- (length s) (length suffix)))) | 
					 | 
				
			||||||
    (and (>= start-pos 0) | 
					 | 
				
			||||||
         (eq t (compare-strings suffix nil nil | 
					 | 
				
			||||||
                                s start-pos nil ignore-case))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defalias 's-ends-with-p 's-ends-with?) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-starts-with? (prefix s &optional ignore-case) | 
					 | 
				
			||||||
  "Does S start with PREFIX? | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If IGNORE-CASE is non-nil, the comparison is done without paying | 
					 | 
				
			||||||
attention to case differences. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Alias: `s-prefix?'. This is a simple wrapper around the built-in | 
					 | 
				
			||||||
`string-prefix-p'." | 
					 | 
				
			||||||
  (string-prefix-p prefix s ignore-case)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defalias 's-starts-with-p 's-starts-with?) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defalias 's-suffix? 's-ends-with?) | 
					 | 
				
			||||||
(defalias 's-prefix? 's-starts-with?) | 
					 | 
				
			||||||
(defalias 's-suffix-p 's-ends-with?) | 
					 | 
				
			||||||
(defalias 's-prefix-p 's-starts-with?) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s--truthy? (val) | 
					 | 
				
			||||||
  (not (null val))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-contains? (needle s &optional ignore-case) | 
					 | 
				
			||||||
  "Does S contain NEEDLE? | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If IGNORE-CASE is non-nil, the comparison is done without paying | 
					 | 
				
			||||||
attention to case differences." | 
					 | 
				
			||||||
  (let ((case-fold-search ignore-case)) | 
					 | 
				
			||||||
    (s--truthy? (string-match-p (regexp-quote needle) s)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defalias 's-contains-p 's-contains?) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-equals? (s1 s2) | 
					 | 
				
			||||||
  "Is S1 equal to S2? | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a simple wrapper around the built-in `string-equal'." | 
					 | 
				
			||||||
  (string-equal s1 s2)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defalias 's-equals-p 's-equals?) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-less? (s1 s2) | 
					 | 
				
			||||||
  "Is S1 less than S2? | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a simple wrapper around the built-in `string-lessp'." | 
					 | 
				
			||||||
  (string-lessp s1 s2)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defalias 's-less-p 's-less?) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-matches? (regexp s &optional start) | 
					 | 
				
			||||||
  "Does REGEXP match S? | 
					 | 
				
			||||||
If START is non-nil the search starts at that index. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a simple wrapper around the built-in `string-match-p'." | 
					 | 
				
			||||||
  (s--truthy? (string-match-p regexp s start))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defalias 's-matches-p 's-matches?) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-blank? (s) | 
					 | 
				
			||||||
  "Is S nil or the empty string?" | 
					 | 
				
			||||||
  (or (null s) (string= "" s))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-present? (s) | 
					 | 
				
			||||||
  "Is S anything but nil or the empty string?" | 
					 | 
				
			||||||
  (not (s-blank? s))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-presence (s) | 
					 | 
				
			||||||
  "Return S if it's `s-present?', otherwise return nil." | 
					 | 
				
			||||||
  (and (s-present? s) s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-lowercase? (s) | 
					 | 
				
			||||||
  "Are all the letters in S in lower case?" | 
					 | 
				
			||||||
  (let ((case-fold-search nil)) | 
					 | 
				
			||||||
    (not (string-match-p "[[:upper:]]" s)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-uppercase? (s) | 
					 | 
				
			||||||
  "Are all the letters in S in upper case?" | 
					 | 
				
			||||||
  (let ((case-fold-search nil)) | 
					 | 
				
			||||||
    (not (string-match-p "[[:lower:]]" s)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-mixedcase? (s) | 
					 | 
				
			||||||
  "Are there both lower case and upper case letters in S?" | 
					 | 
				
			||||||
  (let ((case-fold-search nil)) | 
					 | 
				
			||||||
    (s--truthy? | 
					 | 
				
			||||||
     (and (string-match-p "[[:lower:]]" s) | 
					 | 
				
			||||||
          (string-match-p "[[:upper:]]" s))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-capitalized? (s) | 
					 | 
				
			||||||
  "In S, is the first letter upper case, and all other letters lower case?" | 
					 | 
				
			||||||
  (let ((case-fold-search nil)) | 
					 | 
				
			||||||
    (s--truthy? | 
					 | 
				
			||||||
     (string-match-p "^[[:upper:]][^[:upper:]]*$" s)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-numeric? (s) | 
					 | 
				
			||||||
  "Is S a number?" | 
					 | 
				
			||||||
  (s--truthy? | 
					 | 
				
			||||||
   (string-match-p "^[0-9]+$" s))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-replace (old new s) | 
					 | 
				
			||||||
  "Replaces OLD with NEW in S." | 
					 | 
				
			||||||
  (replace-regexp-in-string (regexp-quote old) new s t t)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s--aget (alist key) | 
					 | 
				
			||||||
  (cdr (assoc key alist))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-replace-all (replacements s) | 
					 | 
				
			||||||
  "REPLACEMENTS is a list of cons-cells. Each `car` is replaced with `cdr` in S." | 
					 | 
				
			||||||
  (replace-regexp-in-string (regexp-opt (mapcar 'car replacements)) | 
					 | 
				
			||||||
                            (lambda (it) (s--aget replacements it)) | 
					 | 
				
			||||||
                            s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-downcase (s) | 
					 | 
				
			||||||
  "Convert S to lower case. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a simple wrapper around the built-in `downcase'." | 
					 | 
				
			||||||
  (downcase s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-upcase (s) | 
					 | 
				
			||||||
  "Convert S to upper case. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a simple wrapper around the built-in `upcase'." | 
					 | 
				
			||||||
  (upcase s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-capitalize (s) | 
					 | 
				
			||||||
  "Convert the first word's first character to upper case and the rest to lower case in S." | 
					 | 
				
			||||||
  (concat (upcase (substring s 0 1)) (downcase (substring s 1)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-titleize (s) | 
					 | 
				
			||||||
  "Convert each word's first character to upper case and the rest to lower case in S. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a simple wrapper around the built-in `capitalize'." | 
					 | 
				
			||||||
  (capitalize s)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defmacro s-with (s form &rest more) | 
					 | 
				
			||||||
  "Threads S through the forms. Inserts S as the last item | 
					 | 
				
			||||||
in the first form, making a list of it if it is not a list | 
					 | 
				
			||||||
already. If there are more forms, inserts the first form as the | 
					 | 
				
			||||||
last item in second form, etc." | 
					 | 
				
			||||||
  (declare (debug (form &rest [&or (function &rest form) fboundp]))) | 
					 | 
				
			||||||
  (if (null more) | 
					 | 
				
			||||||
      (if (listp form) | 
					 | 
				
			||||||
          `(,(car form) ,@(cdr form) ,s) | 
					 | 
				
			||||||
        (list form s)) | 
					 | 
				
			||||||
    `(s-with (s-with ,s ,form) ,@more))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(put 's-with 'lisp-indent-function 1) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-index-of (needle s &optional ignore-case) | 
					 | 
				
			||||||
  "Returns first index of NEEDLE in S, or nil. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If IGNORE-CASE is non-nil, the comparison is done without paying | 
					 | 
				
			||||||
attention to case differences." | 
					 | 
				
			||||||
  (let ((case-fold-search ignore-case)) | 
					 | 
				
			||||||
    (string-match-p (regexp-quote needle) s))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-reverse (s) | 
					 | 
				
			||||||
  "Return the reverse of S." | 
					 | 
				
			||||||
  (if (multibyte-string-p s) | 
					 | 
				
			||||||
      (let ((input (string-to-list s)) | 
					 | 
				
			||||||
            (output ())) | 
					 | 
				
			||||||
        (while input | 
					 | 
				
			||||||
          ;; Handle entire grapheme cluster as a single unit | 
					 | 
				
			||||||
          (let ((grapheme (list (pop input)))) | 
					 | 
				
			||||||
            (while (memql (car input) ucs-normalize-combining-chars) | 
					 | 
				
			||||||
              (push (pop input) grapheme)) | 
					 | 
				
			||||||
            (setq output (nconc (nreverse grapheme) output)))) | 
					 | 
				
			||||||
        (concat output)) | 
					 | 
				
			||||||
    (concat (nreverse (string-to-list s))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-match-strings-all (regex string) | 
					 | 
				
			||||||
  "Return a list of matches for REGEX in STRING. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Each element itself is a list of matches, as per | 
					 | 
				
			||||||
`match-string'. Multiple matches at the same position will be | 
					 | 
				
			||||||
ignored after the first." | 
					 | 
				
			||||||
  (let ((all-strings ()) | 
					 | 
				
			||||||
        (i 0)) | 
					 | 
				
			||||||
    (while (and (< i (length string)) | 
					 | 
				
			||||||
                (string-match regex string i)) | 
					 | 
				
			||||||
      (setq i (1+ (match-beginning 0))) | 
					 | 
				
			||||||
      (let (strings | 
					 | 
				
			||||||
            (num-matches (/ (length (match-data)) 2)) | 
					 | 
				
			||||||
            (match 0)) | 
					 | 
				
			||||||
        (while (/= match num-matches) | 
					 | 
				
			||||||
          (push (match-string match string) strings) | 
					 | 
				
			||||||
          (setq match (1+ match))) | 
					 | 
				
			||||||
        (push (nreverse strings) all-strings))) | 
					 | 
				
			||||||
    (nreverse all-strings))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-match (regexp s &optional start) | 
					 | 
				
			||||||
  "When the given expression matches the string, this function returns a list | 
					 | 
				
			||||||
of the whole matching string and a string for each matched subexpressions. | 
					 | 
				
			||||||
If it did not match the returned value is an empty list (nil). | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
When START is non-nil the search will start at that index." | 
					 | 
				
			||||||
  (save-match-data | 
					 | 
				
			||||||
    (if (string-match regexp s start) | 
					 | 
				
			||||||
        (let ((match-data-list (match-data)) | 
					 | 
				
			||||||
              result) | 
					 | 
				
			||||||
          (while match-data-list | 
					 | 
				
			||||||
            (let* ((beg (car match-data-list)) | 
					 | 
				
			||||||
                   (end (cadr match-data-list)) | 
					 | 
				
			||||||
                   (subs (if (and beg end) (substring s beg end) nil))) | 
					 | 
				
			||||||
              (setq result (cons subs result)) | 
					 | 
				
			||||||
              (setq match-data-list | 
					 | 
				
			||||||
                    (cddr match-data-list)))) | 
					 | 
				
			||||||
          (nreverse result))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-slice-at (regexp s) | 
					 | 
				
			||||||
  "Slices S up at every index matching REGEXP." | 
					 | 
				
			||||||
  (save-match-data | 
					 | 
				
			||||||
    (let (i) | 
					 | 
				
			||||||
      (setq i (string-match regexp s 1)) | 
					 | 
				
			||||||
      (if i | 
					 | 
				
			||||||
          (cons (substring s 0 i) | 
					 | 
				
			||||||
                (s-slice-at regexp (substring s i))) | 
					 | 
				
			||||||
        (list s))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-split-words (s) | 
					 | 
				
			||||||
  "Split S into list of words." | 
					 | 
				
			||||||
  (s-split | 
					 | 
				
			||||||
   "[^[:word:]0-9]+" | 
					 | 
				
			||||||
   (let ((case-fold-search nil)) | 
					 | 
				
			||||||
     (replace-regexp-in-string | 
					 | 
				
			||||||
      "\\([[:lower:]]\\)\\([[:upper:]]\\)" "\\1 \\2" | 
					 | 
				
			||||||
      (replace-regexp-in-string "\\([[:upper:]]\\)\\([[:upper:]][0-9[:lower:]]\\)" "\\1 \\2" s))) | 
					 | 
				
			||||||
   t)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s--mapcar-head (fn-head fn-rest list) | 
					 | 
				
			||||||
  "Like MAPCAR, but applies a different function to the first element." | 
					 | 
				
			||||||
  (if list | 
					 | 
				
			||||||
      (cons (funcall fn-head (car list)) (mapcar fn-rest (cdr list))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-lower-camel-case (s) | 
					 | 
				
			||||||
  "Convert S to lowerCamelCase." | 
					 | 
				
			||||||
  (s-join "" (s--mapcar-head 'downcase 'capitalize (s-split-words s)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-upper-camel-case (s) | 
					 | 
				
			||||||
  "Convert S to UpperCamelCase." | 
					 | 
				
			||||||
  (s-join "" (mapcar 'capitalize (s-split-words s)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-snake-case (s) | 
					 | 
				
			||||||
  "Convert S to snake_case." | 
					 | 
				
			||||||
  (s-join "_" (mapcar 'downcase (s-split-words s)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-dashed-words (s) | 
					 | 
				
			||||||
  "Convert S to dashed-words." | 
					 | 
				
			||||||
  (s-join "-" (mapcar 'downcase (s-split-words s)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-capitalized-words (s) | 
					 | 
				
			||||||
  "Convert S to Capitalized words." | 
					 | 
				
			||||||
  (let ((words (s-split-words s))) | 
					 | 
				
			||||||
    (s-join " " (cons (capitalize (car words)) (mapcar 'downcase (cdr words)))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-titleized-words (s) | 
					 | 
				
			||||||
  "Convert S to Titleized Words." | 
					 | 
				
			||||||
  (s-join " " (mapcar 's-titleize (s-split-words s)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-word-initials (s) | 
					 | 
				
			||||||
  "Convert S to its initials." | 
					 | 
				
			||||||
  (s-join "" (mapcar (lambda (ss) (substring ss 0 1)) | 
					 | 
				
			||||||
                     (s-split-words s)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;; Errors for s-format | 
					 | 
				
			||||||
(progn | 
					 | 
				
			||||||
  (put 's-format-resolve | 
					 | 
				
			||||||
       'error-conditions | 
					 | 
				
			||||||
       '(error s-format s-format-resolve)) | 
					 | 
				
			||||||
  (put 's-format-resolve | 
					 | 
				
			||||||
       'error-message | 
					 | 
				
			||||||
       "Cannot resolve a template to values")) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-format (template replacer &optional extra) | 
					 | 
				
			||||||
  "Format TEMPLATE with the function REPLACER. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
REPLACER takes an argument of the format variable and optionally | 
					 | 
				
			||||||
an extra argument which is the EXTRA value from the call to | 
					 | 
				
			||||||
`s-format'. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Several standard `s-format' helper functions are recognized and | 
					 | 
				
			||||||
adapted for this: | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (s-format \"${name}\" 'gethash hash-table) | 
					 | 
				
			||||||
    (s-format \"${name}\" 'aget alist) | 
					 | 
				
			||||||
    (s-format \"$0\" 'elt sequence) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The REPLACER function may be used to do any other kind of | 
					 | 
				
			||||||
transformation." | 
					 | 
				
			||||||
  (let ((saved-match-data (match-data))) | 
					 | 
				
			||||||
    (unwind-protect | 
					 | 
				
			||||||
        (replace-regexp-in-string | 
					 | 
				
			||||||
         "\\$\\({\\([^}]+\\)}\\|[0-9]+\\)" | 
					 | 
				
			||||||
         (lambda (md) | 
					 | 
				
			||||||
           (let ((var | 
					 | 
				
			||||||
                  (let ((m (match-string 2 md))) | 
					 | 
				
			||||||
                    (if m m | 
					 | 
				
			||||||
                      (string-to-number (match-string 1 md))))) | 
					 | 
				
			||||||
                 (replacer-match-data (match-data))) | 
					 | 
				
			||||||
             (unwind-protect | 
					 | 
				
			||||||
                 (let ((v | 
					 | 
				
			||||||
                        (cond | 
					 | 
				
			||||||
                         ((eq replacer 'gethash) | 
					 | 
				
			||||||
                          (funcall replacer var extra)) | 
					 | 
				
			||||||
                         ((eq replacer 'aget) | 
					 | 
				
			||||||
                          (funcall 's--aget extra var)) | 
					 | 
				
			||||||
                         ((eq replacer 'elt) | 
					 | 
				
			||||||
                          (funcall replacer extra var)) | 
					 | 
				
			||||||
                         (t | 
					 | 
				
			||||||
                          (set-match-data saved-match-data) | 
					 | 
				
			||||||
                          (if extra | 
					 | 
				
			||||||
                              (funcall replacer var extra) | 
					 | 
				
			||||||
                            (funcall replacer var)))))) | 
					 | 
				
			||||||
                   (if v v (signal 's-format-resolve md))) | 
					 | 
				
			||||||
               (set-match-data replacer-match-data)))) template | 
					 | 
				
			||||||
               ;; Need literal to make sure it works | 
					 | 
				
			||||||
               t t) | 
					 | 
				
			||||||
      (set-match-data saved-match-data)))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defvar s-lex-value-as-lisp nil | 
					 | 
				
			||||||
  "If `t' interpolate lisp values as lisp. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`s-lex-format' inserts values with (format \"%S\").") | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-lex-fmt|expand (fmt) | 
					 | 
				
			||||||
  "Expand FMT into lisp." | 
					 | 
				
			||||||
  (list 's-format fmt (quote 'aget) | 
					 | 
				
			||||||
        (append '(list) | 
					 | 
				
			||||||
                (mapcar | 
					 | 
				
			||||||
                 (lambda (matches) | 
					 | 
				
			||||||
                   (list | 
					 | 
				
			||||||
                    'cons | 
					 | 
				
			||||||
                    (cadr matches) | 
					 | 
				
			||||||
                    `(format | 
					 | 
				
			||||||
                      (if s-lex-value-as-lisp "%S" "%s") | 
					 | 
				
			||||||
                      ,(intern (cadr matches))))) | 
					 | 
				
			||||||
                 (s-match-strings-all "${\\([^}]+\\)}" fmt))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defmacro s-lex-format (format-str) | 
					 | 
				
			||||||
  "`s-format` with the current environment. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FORMAT-STR may use the `s-format' variable reference to refer to | 
					 | 
				
			||||||
any variable: | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 (let ((x 1)) | 
					 | 
				
			||||||
   (s-lex-format \"x is: ${x}\")) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The values of the variables are interpolated with \"%s\" unless | 
					 | 
				
			||||||
the variable `s-lex-value-as-lisp' is `t' and then they are | 
					 | 
				
			||||||
interpolated with \"%S\"." | 
					 | 
				
			||||||
  (declare (debug (form))) | 
					 | 
				
			||||||
  (s-lex-fmt|expand format-str)) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-count-matches (regexp s &optional start end) | 
					 | 
				
			||||||
  "Count occurrences of `regexp' in `s'. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`start', inclusive, and `end', exclusive, delimit the part of `s' | 
					 | 
				
			||||||
to match. " | 
					 | 
				
			||||||
  (with-temp-buffer | 
					 | 
				
			||||||
    (insert s) | 
					 | 
				
			||||||
    (goto-char (point-min)) | 
					 | 
				
			||||||
    (count-matches regexp (or start 1) (or end (point-max))))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(defun s-wrap (s prefix &optional suffix) | 
					 | 
				
			||||||
  "Wrap string S with PREFIX and optionally SUFFIX. | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Return string S with PREFIX prepended.  If SUFFIX is present, it | 
					 | 
				
			||||||
is appended, otherwise PREFIX is used as both prefix and | 
					 | 
				
			||||||
suffix." | 
					 | 
				
			||||||
  (concat prefix s (or suffix prefix))) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(provide 's) | 
					 | 
				
			||||||
;;; s.el ends here | 
					 | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue