diff --git a/emacs.d/.mc-lists.el b/emacs.d/.mc-lists.el new file mode 100644 index 0000000..e01a98e --- /dev/null +++ b/emacs.d/.mc-lists.el @@ -0,0 +1,11 @@ +;; This file is automatically generated by the multiple-cursors extension. +;; It keeps track of your preferences for running commands with multiple cursors. + +(setq mc/cmds-to-run-for-all + '( + )) + +(setq mc/cmds-to-run-once + '( + end-of-buffer + )) diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-autoloads.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-autoloads.el deleted file mode 100644 index 49ed786..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-autoloads.el +++ /dev/null @@ -1,81 +0,0 @@ -;;; alchemist-autoloads.el --- automatically extracted autoloads -;; -;;; Code: -(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) - -;;;### (autoloads nil "alchemist" "alchemist.el" (21898 47984 0 0)) -;;; Generated autoloads from alchemist.el - -(autoload 'alchemist-version "alchemist" "\ -Display Alchemist's version. - -\(fn &optional SHOW-VERSION)" t nil) - -(autoload 'alchemist-mode "alchemist" "\ -Toggle alchemist mode. - -Key bindings: -\\{alchemist-mode-map} - -\(fn &optional ARG)" t nil) - -;;;*** - -;;;### (autoloads nil "alchemist-iex" "alchemist-iex.el" (21898 47984 -;;;;;; 0 0)) -;;; Generated autoloads from alchemist-iex.el - -(defalias 'run-elixir 'alchemist-iex-run) - -(autoload 'alchemist-iex-run "alchemist-iex" "\ -Start an IEx process. -Show the IEx buffer if an IEx process is already run. - -\(fn &optional ARG)" t nil) - -(autoload 'alchemist-iex-project-run "alchemist-iex" "\ -Start an IEx process with mix 'iex -S mix' in the -context of an Elixir project. -Show the IEx buffer if an IEx process is already run. - -\(fn)" t nil) - -;;;*** - -;;;### (autoloads nil "alchemist-test-mode" "alchemist-test-mode.el" -;;;;;; (21898 47984 0 0)) -;;; Generated autoloads from alchemist-test-mode.el - -(autoload 'alchemist-test-mode "alchemist-test-mode" "\ -Minor mode for Elixir ExUnit files. - -The following commands are available: - -\\{alchemist-test-mode-map} - -\(fn &optional ARG)" t nil) - -(autoload 'alchemist-test-enable-mode "alchemist-test-mode" "\ - - -\(fn)" nil nil) - -(dolist (hook '(alchemist-mode-hook)) (add-hook hook 'alchemist-test-enable-mode)) - -;;;*** - -;;;### (autoloads nil nil ("alchemist-buffer.el" "alchemist-company.el" -;;;;;; "alchemist-compile.el" "alchemist-complete.el" "alchemist-eval.el" -;;;;;; "alchemist-execute.el" "alchemist-goto.el" "alchemist-help.el" -;;;;;; "alchemist-hooks.el" "alchemist-message.el" "alchemist-mix.el" -;;;;;; "alchemist-pkg.el" "alchemist-project.el" "alchemist-server.el" -;;;;;; "alchemist-utils.el") (21898 47984 781999 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; alchemist-autoloads.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-buffer.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-buffer.el deleted file mode 100644 index e9b2afd..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-buffer.el +++ /dev/null @@ -1,152 +0,0 @@ -;;; alchemist-buffer.el --- Custom compilation mode for Alchemist - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Custom compilation mode for Alchemist - -;;; Code: - -(require 'compile) -(require 'ansi-color) - -;; Variables - -(defgroup alchemist-buffer nil - "Custom compilation mode for Alchemist." - :prefix "alchemist-buffer-" - :group 'alchemist) - -(defcustom alchemist-buffer-status-modeline t - "if t, the face of local `mode-name' variable will change with compilation status. - -For example, when `alchemist-mix-test' failes, the `mode-name' will be -formated with the `alchemist-buffer--failed-face' face, to symbolize failing tests." - :type 'boolean - :group 'alchemist-buffer) - -(defvar alchemist-buffer--mode-name-face 'mode-line) - -(defvar alchemist-buffer--buffer-name nil - "Used to store compilation name so recompilation works as expected.") -(make-variable-buffer-local 'alchemist-buffer--buffer-name) - -(defvar alchemist-buffer--error-link-options - '(elixir "\\([-A-Za-z0-9./_]+\\):\\([0-9]+\\)\\(?: warning\\)?" 1 2 nil (3) 1) - "File link matcher for `compilation-error-regexp-alist-alist' (matches path/to/file:line).") - -;; Faces - -(defface alchemist-buffer--success-face - '((t (:inherit font-lock-variable-name-face :bold t :background "darkgreen" :foreground "#e0ff00"))) - "Face for successful compilation run." - :group 'alchemist-buffer) - -(defface alchemist-buffer--failed-face - '((t (:inherit font-lock-variable-name-face :bold t :background "red" :foreground "white"))) - "Face for failed compilation run." - :group 'alchemist-buffer) - -(defface alchemist-buffer--running-face - '((t (:inherit font-lock-variable-name-face :bold nil :background "gray" :foreground "black"))) - "Face for running compilation." - :group 'alchemist-buffer) - -(defun alchemist-buffer--kill-any-orphan-proc () - "Ensure any dangling buffer process is killed." - (let ((orphan-proc (get-buffer-process (buffer-name)))) - (when orphan-proc - (kill-process orphan-proc)))) - -;; Private functions - -(defvar alchemist-buffer--save-buffers-predicate - (lambda () - (not (string= (substring (buffer-name) 0 1) "*")))) - -(defun alchemist-buffer-init-test-report (buffer status) - (when (string= "*alchemist-test-report*" (buffer-name buffer)) - (alchemist-test-mode))) - -(defun alchemist-buffer--remove-dispensable-output () - (delete-matching-lines "\\(-*- mode:\\|Compiled \\|elixir-compilation;\\|Elixir started\\|^$\\)" (point-min) (point-max)) - (remove-hook 'compilation-filter-hook 'alchemist-buffer--remove-dispensable-output t)) - -(defun alchemist-buffer--remove-dispensable-output-after-finish (buffer msg) - (delete-matching-lines "\\(Excluding tags\\|Including tags\\|Elixir exited\\|Elixir finished\\)" (point-min) (point-max))) - -(defun alchemist-buffer--handle-compilation () - (ansi-color-apply-on-region (point-min) (point-max))) - -(defun alchemist-buffer--set-modeline-color (buffer status) - (setq alchemist-buffer--mode-name-face - (if (string-prefix-p "finished" status) - 'alchemist-buffer--success-face - 'alchemist-buffer--failed-face)) - - (remove-hook 'compilation-finish-functions 'alchemist-buffer--set-modeline-color)) - -;; Public functions - -(defun alchemist-buffer-initialize-modeline () - "Initialize the mode-line face." - (setq mode-name - '(:eval (propertize "Elixir" 'face alchemist-buffer--mode-name-face)))) - -(defun alchemist-buffer-reset-modeline () - "Reset the current mode-line face to default." - (setq mode-name "Elixir")) - -(define-compilation-mode alchemist-buffer-mode "Elixir" - "Elixir compilation mode." - (progn - (font-lock-add-keywords nil - '(("^Finished in .*$" . font-lock-string-face))) - ;; Set any bound buffer name buffer-locally - (setq alchemist-buffer--buffer-name alchemist-buffer--buffer-name) - (set (make-local-variable 'kill-buffer-hook) - 'alchemist-buffer--kill-any-orphan-proc))) - -(defun alchemist-buffer-run (cmdlist buffer-name) - "Run CMDLIST in `alchemist-buffer-mode'. -Returns the compilation buffer. -Argument BUFFER-NAME for the compilation." - (save-some-buffers (not compilation-ask-about-save) alchemist-buffer--save-buffers-predicate) - (let* ((alchemist-buffer--buffer-name buffer-name) - (compilation-filter-start (point-min))) - (with-current-buffer - (compilation-start (mapconcat 'concat cmdlist " ") - 'alchemist-buffer-mode - (lambda (b) alchemist-buffer--buffer-name)) - (set (make-local-variable 'compilation-error-regexp-alist-alist) - (cons alchemist-buffer--error-link-options compilation-error-regexp-alist-alist)) - (set (make-local-variable 'compilation-error-regexp-alist) - (cons 'elixir compilation-error-regexp-alist)) - (add-hook 'compilation-filter-hook 'alchemist-buffer--handle-compilation nil t) - (add-hook 'compilation-filter-hook 'alchemist-buffer--remove-dispensable-output nil t) - (add-to-list 'compilation-finish-functions 'alchemist-buffer-init-test-report) - (add-to-list 'compilation-finish-functions 'alchemist-buffer--remove-dispensable-output-after-finish) - (when alchemist-buffer-status-modeline - (add-hook 'compilation-finish-functions 'alchemist-buffer--set-modeline-color nil t))))) - -(provide 'alchemist-buffer) - -;;; alchemist-buffer.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-company.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-company.el deleted file mode 100644 index 1d54663..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-company.el +++ /dev/null @@ -1,83 +0,0 @@ -;;; alchemist-company.el --- Elixir company-mode backend -*- lexical-binding: t -*- - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Elixir company-mode backend. - -;;; Code: - -(require 'company) - -(defgroup alchemist-company nil - "Elixir company-mode backend." - :prefix "alchemist-company-" - :group 'alchemist) - -;; Variables - -(defcustom alchemist-company-show-annotation t - "Show an annotation inline with the candidate." - :type 'boolean - :group 'alchemist-company) - -(defun alchemist-company--show-documentation (selected) - (interactive) - (company--electric-do - (let* ((candidate (format "%s%s" selected (alchemist-company--annotation selected)))) - (alchemist-help--execute-without-complete candidate)))) -(put 'alchemist-company--show-documentation 'company-keep t) - -(defun alchemist-company--open-definition (selected) - (interactive) - (company--electric-do - (alchemist-goto--open-definition selected))) -(put 'alchemist-company--open-definition 'company-keep t) - -(defun alchemist-company--annotation (candidate) - (get-text-property 0 'meta candidate)) - -(defun alchemist-company (command &optional arg &rest ignored) - "`company-mode' completion back-end for Elixir." - (interactive (list 'interactive)) - (when alchemist-company-show-annotation - (set 'company-tooltip-align-annotations t)) - (case command - (interactive (company-begin-backend 'alchemist-company)) - (init (when (or (eq major-mode 'elixir-mode) - (string= mode-name "Alchemist-IEx")))) - (prefix (and (or (eq major-mode 'elixir-mode) - (string= mode-name "Alchemist-IEx")) - (alchemist-help--exp-at-point))) - (doc-buffer (alchemist-company--show-documentation arg)) - (location (alchemist-company--open-definition arg)) - (candidates (cons :async - (lambda (cb) - (setq alchemist-server-company-callback cb) - (alchemist-server-complete-candidates arg)))) - (annotation (when alchemist-company-show-annotation - (alchemist-company--annotation arg))))) - -(add-to-list 'company-backends 'alchemist-company) - -(provide 'alchemist-company) - -;;; alchemist-company.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-compile.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-compile.el deleted file mode 100644 index 5dc5369..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-compile.el +++ /dev/null @@ -1,73 +0,0 @@ -;;; alchemist-compile.el --- Elixir compilation functionality - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Elixir compilation functionality. - -;;; Code: - -(defgroup alchemist-compile nil - "Elixir compilation functionality." - :prefix "alchemist-compile-" - :group 'alchemist) - -;; Variables - -(defcustom alchemist-compile-command "elixirc" - "The shell command for elixirc." - :type 'string - :group 'alchemist-compile) - -(defvar alchemist-compile-buffer-name "*elixirc*" - "Name of the elixir output buffer.") - -;; Private functions - -(defun alchemist-compile--file (filename) - (cond ((not (file-exists-p filename)) (error "The given file doesn't exist")) - ((string-match "\.exs$" filename) (error "The given file is an Elixir Script")) - (t (alchemist-compile (list alchemist-compile-command (expand-file-name filename)))))) - -(defun alchemist-compile--read-command (command) - (read-shell-command "elixirc command: " (concat command " "))) - -;; Public functions - -(defun alchemist-compile-this-buffer () - "Compile the current buffer with elixirc." - (interactive) - (alchemist-compile--file buffer-file-name)) - -(defun alchemist-compile-file (filename) - "Compile the given FILENAME." - (interactive "Felixirc: ") - (alchemist-compile--file (expand-file-name filename))) - -(defun alchemist-compile (cmdlist) - "Compile CMDLIST with elixirc." - (interactive (list (alchemist-compile--read-command alchemist-compile-command))) - (alchemist-buffer-run (alchemist-utils--build-runner-cmdlist cmdlist) - alchemist-compile-buffer-name)) - -(provide 'alchemist-compile) - -;;; alchemist-compile.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-complete.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-complete.el deleted file mode 100644 index c7e07c2..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-complete.el +++ /dev/null @@ -1,135 +0,0 @@ -;;; alchemist-complete.el --- Complete functionality for Elixir source code -*- lexical-binding: t -*- - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Complete functionality for Elixir and Erlang source code. - -;;; Code: - -(defgroup alchemist-complete nil - "Complete functionality for Elixir source code." - :prefix "alchemist-complete-" - :group 'alchemist) - -(defun alchemist-complete--concat-prefix-with-functions (prefix functions &optional add-prefix) - (let* ((prefix (mapconcat 'concat (butlast (split-string prefix "\\.") 1) ".")) - (candidates (mapcar (lambda (c) (concat prefix "." c)) (cdr functions)))) - (if add-prefix - (push prefix candidates) - candidates))) - -(defun alchemist-complete--add-prefix-to-function (prefix function) - (let* ((prefix (mapconcat 'concat (butlast (split-string prefix "\\.") 1) ".")) - (candidate (concat prefix "." function))) - candidate)) - -(defun alchemist-complete--build-candidates (a-list) - (let* ((search-term (car a-list)) - (candidates (if (string-match-p "^.+\/" search-term) - a-list - (cdr a-list))) - (candidates (mapcar (lambda (f) - (let* ((candidate f) - (meta (if (string-match-p "^.+/" f) - (replace-regexp-in-string "^.+/" "/" f) - ""))) - (cond - ((and (string-match-p "^:" search-term) - (not (string-match-p "\\.$" search-term))) - (propertize (concat ":" candidate))) - ((string-match-p "\\." search-term) - (propertize (alchemist-complete--add-prefix-to-function search-term - (replace-regexp-in-string "/[0-9]$" "" candidate)) 'meta meta)) - (t (propertize (replace-regexp-in-string "/[0-9]$" "" candidate) 'meta meta))))) - candidates))) - candidates)) - -(defun alchemist-complete--build-help-candidates (a-list) - (let* ((search-term (car a-list)) - (candidates (cond ((> (alchemist-utils--count-char-in-str "\\." search-term) 1) - (let ((search (if (string-match-p "\\.[a-z0-9_\?!]+$" search-term) - (list (replace-regexp-in-string "\\.[a-z0-9_\?!]+$" "" search-term)) - (list (replace-regexp-in-string "\\.$" "" search-term)))) - (candidates (mapcar (lambda (c) - (if (string-match-p "\\.[a-z0-9_\?!]+$" search-term) - (concat (replace-regexp-in-string "\\.[a-z0-9_\?!]+$" "." search-term) c) - (concat search-term c))) - (cdr a-list)))) - (append search candidates))) - ((string-match-p "\\.$" search-term) - (alchemist-complete--concat-prefix-with-functions search-term a-list t)) - ((string-match-p "\\.[a-z0-9_\?!]+$" search-term) - (alchemist-complete--concat-prefix-with-functions search-term a-list)) - (t - a-list)))) - (delete-dups candidates))) - -(defun alchemist-complete--output-to-list (output) - (let* ((output (replace-regexp-in-string "^cmp:" "" output)) - (output (split-string output)) - (output (delete nil output))) - output) - ) - -(defun alchemist-complete--clear-buffer (buffer) - "Clears the BUFFER from not used lines." - (with-current-buffer buffer - (delete-non-matching-lines "^cmp:" (point-min) (point-max)))) - -(defun alchemist-complete--completing-prompt (initial completing-collection) - (let* ((completing-collection (alchemist-complete--build-help-candidates completing-collection))) - (cond ((equal (length completing-collection) 1) - (car completing-collection)) - (completing-collection - (completing-read - "Elixir help: " - completing-collection - nil - nil - (replace-regexp-in-string "\\.$" "" initial))) - (t initial)))) - -(defun alchemsit-complete--dabbrev-code-candidates () - "This function uses a piece of functionality of company-dabbrev-code backend. - -Please have a look at the company-dabbrev-code function for more -detailed information." - (let ((case-fold-search company-dabbrev-code-ignore-case) - (candidates (company-dabbrev--search - (company-dabbrev-code--make-regexp alchemist-server--last-completion-exp) - company-dabbrev-code-time-limit - (pcase company-dabbrev-code-other-buffers - (`t (list major-mode)) - (`code company-dabbrev-code-modes) - (`all `all)) - t))) - (delete-dups candidates))) - -(defun alchemist-complete--serve-candidates-to-company (candidates) - (let ((candidates (if candidates - candidates - (alchemsit-complete--dabbrev-code-candidates)))) - (funcall alchemist-server-company-callback candidates))) - -(provide 'alchemist-complete) - -;;; alchemist-complete.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-eval.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-eval.el deleted file mode 100644 index f376d65..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-eval.el +++ /dev/null @@ -1,185 +0,0 @@ -;;; alchemist-eval.el --- Elixir code inline evaluation functionality - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Elixir code inline evaluation functionality - -;;; Code: - -(defgroup alchemist-eval nil - "Elixir code inline evaluation functionality." - :prefix "alchemist-eval-" - :group 'alchemist) - -;; Private functions - -(defun alchemist-eval--insert (string) - (let ((lines (split-string string "\n"))) - (if (> (length lines) 1) - (progn - (save-excursion - (end-of-line) - (mapc (lambda (s) - (newline) - (insert (format "# => %s" s)) - (indent-according-to-mode)) - lines))) - (save-excursion - (end-of-line) - (insert (format " # => %s" string)))))) - -(defun alchemist-eval--evaluate-code (string) - (let ((tmp-file ".alchemist-eval.exs") - (old-directory default-directory)) - (when (alchemist-project-p) - (alchemist-project--establish-root-directory)) - (with-temp-file tmp-file - (insert string)) - (let ((output (shell-command-to-string - (alchemist-eval--build-code-evaluation-command tmp-file)))) - (delete-file tmp-file) - (cd old-directory) - (alchemist-utils--remove-newline-at-end output)))) - -(defun alchemist-eval--evaluate-code-as-quoted (string) - (let ((tmp-file ".alchemist-eval.exs") - (old-directory default-directory)) - (when (alchemist-project-p) - (alchemist-project--establish-root-directory)) - (with-temp-file tmp-file - (insert string)) - (let ((output (shell-command-to-string - (alchemist-eval--build-code-evaluation-as-quoted-command tmp-file)))) - (delete-file tmp-file) - (cd old-directory) - (alchemist-utils--remove-newline-at-end output)))) - -(defun alchemist-eval--expression (expression) - (let ((file (make-temp-file "alchemist-eval" nil ".exs"))) - (with-temp-file file - (insert expression)) - (alchemist-server-eval file))) - -(defun alchemist-eval--expression-and-print (expression) - (let ((file (make-temp-file "alchemist-eval" nil ".exs"))) - (with-temp-file file - (insert expression)) - (alchemist-server-eval-and-insert file))) - -(defun alchemist-eval--quote-expression (expression) - (let ((file (make-temp-file "alchemist-eval" nil ".exs"))) - (with-temp-file file - (insert expression)) - (alchemist-server-eval-quote file))) - -(defun alchemist-eval--quote-expression-and-print (expression) - (let ((file (make-temp-file "alchemist-eval" nil ".exs"))) - (with-temp-file file - (insert expression)) - (alchemist-server-eval-quote-and-insert file))) - -;; Public functions - -(defun alchemist-eval-current-line () - "Evaluate the Elixir code on the current line." - (interactive) - (alchemist-eval--expression (thing-at-point 'line))) - -(defun alchemist-eval-print-current-line () - "Evaluate the Elixir code on the current line and insert the result." - (interactive) - (alchemist-eval--expression-and-print (thing-at-point 'line))) - -(defun alchemist-eval-region (beg end) - "Evaluate the Elixir code on marked region." - (interactive (list (point) (mark))) - (unless (and beg end) - (error "The mark is not set now, so there is no region")) - (let ((string (buffer-substring-no-properties beg end))) - (alchemist-eval--expression string))) - -(defun alchemist-eval-print-region (beg end) - "Evaluate the Elixir code on marked region and insert the result." - (interactive (list (point) (mark))) - (unless (and beg end) - (error "The mark is not set now, so there is no region")) - (let ((string (buffer-substring-no-properties beg end))) - (when (> end beg) - (exchange-point-and-mark)) - (alchemist-eval--expression-and-print string))) - -(defun alchemist-eval-buffer () - "Evaluate the Elixir code in the current buffer." - (interactive) - (let ((string (buffer-substring-no-properties (point-min) (point-max)))) - (alchemist-eval--expression string))) - -(defun alchemist-eval-print-buffer () - "Evaluate the Elixir code in the current buffer and insert the result." - (interactive) - (let ((string (buffer-substring-no-properties (point-min) (point-max)))) - (end-of-buffer) - (alchemist-eval--expression-and-print string))) - -(defun alchemist-eval-quoted-current-line () - "Get the Elixir code representation of the expression on the current line." - (interactive) - (alchemist-eval--quote-expression (thing-at-point 'line))) - -(defun alchemist-eval-print-quoted-current-line () - "Get the Elixir code representation of the expression on the current line and insert the result." - (interactive) - (alchemist-eval--quote-expression-and-print (thing-at-point 'line))) - -(defun alchemist-eval-quoted-region (beg end) - "Get the Elixir code representation of the expression on marked region." - (interactive (list (point) (mark))) - (unless (and beg end) - (error "The mark is not set now, so there is no region")) - (let ((string (buffer-substring-no-properties beg end))) - (alchemist-eval--quote-expression string))) - -(defun alchemist-eval-print-quoted-region (beg end) - "Get the Elixir code representation of the expression on marked region and insert the result." - (interactive (list (point) (mark))) - (unless (and beg end) - (error "The mark is not set now, so there is no region")) - (let ((string (buffer-substring-no-properties beg end))) - (when (> end beg) - (exchange-point-and-mark)) - (alchemist-eval--quote-expression-and-print string))) - -(defun alchemist-eval-quoted-buffer () - "Get the Elixir code representation of the expression in the current buffer." - (interactive) - (let ((string (buffer-substring-no-properties (point-min) (point-max)))) - (alchemist-eval--quote-expression string))) - -(defun alchemist-eval-print-quoted-buffer () - "Get the Elixir code representation of the expression in the current buffer and insert result." - (interactive) - (let ((string (buffer-substring-no-properties (point-min) (point-max)))) - (alchemist-eval--quote-expression-and-print string))) - -(provide 'alchemist-eval) - -;;; alchemist-eval.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-execute.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-execute.el deleted file mode 100644 index 6481695..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-execute.el +++ /dev/null @@ -1,73 +0,0 @@ -;;; alchemist-execute.el --- Elixir's script execution integration - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Elixir's script execution integration - -;;; Code: - -(defgroup alchemist-execute nil - "Elixir's script execution integration." - :prefix "alchemist-execute-" - :group 'alchemist) - -;; Variables - -(defcustom alchemist-execute-command "elixir" - "The shell command for elixir." - :type 'string - :group 'alchemist-execute) - -(defvar alchemist-execute-buffer-name "*elixir*" - "Name of the elixir output buffer.") - -;; Private functions - -(defun alchemist-execute--file (filename) - (when (not (file-exists-p filename)) - (error "The given file doesn't exists")) - (alchemist-execute (list alchemist-execute-command (expand-file-name filename)))) - -(defun alchemist-execute--read-command (command) - (read-shell-command "elixir command: " (concat command " "))) - -;; Public functions - -(defun alchemist-execute-this-buffer () - "Run the current buffer through elixir." - (interactive) - (alchemist-execute--file buffer-file-name)) - -(defun alchemist-execute-file (filename) - "Run elixir with the given FILENAME." - (interactive "Felixir: ") - (alchemist-execute--file (expand-file-name filename))) - -(defun alchemist-execute (cmdlist) - "Run a elixir with CMDLIST." - (interactive (list (alchemist-execute--read-command alchemist-execute-command))) - (alchemist-buffer-run (alchemist-utils--build-runner-cmdlist cmdlist) - alchemist-execute-buffer-name)) - -(provide 'alchemist-execute) - -;;; alchemist-execute.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-goto.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-goto.el deleted file mode 100644 index c36d0a1..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-goto.el +++ /dev/null @@ -1,336 +0,0 @@ -;;; alchemist-goto.el --- Functionality to jump modules and function definitions - -;; Copyright © 2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Functionality to jump modules and function definitions - -;;; Code: - -(require 'etags) - -(defgroup alchemist-goto nil - "Functionality to jump modules and function definitions." - :prefix "alchemist-goto-" - :group 'alchemist) - -;; Variables - -(defcustom alchemist-goto-erlang-source-dir "" - "Path to the erlang source code." - :type 'string - :group 'alchemist-goto) - -(defcustom alchemist-goto-elixir-source-dir "" - "Path to the elixir source code." - :type 'string - :group 'alchemist-goto) - -(defvar alchemist-goto--symbol-list '()) -(defvar alchemist-goto--symbol-name-and-pos '()) -(defvar alchemist-goto--symbol-list-bare '()) -(defvar alchemist-goto--symbol-name-and-pos-bare '()) - -;; Private functions - -(defun alchemist-goto--current-module-name () - "Searches backward in the current buffer until a module -declaration has been found." - (save-excursion - (let ((found-flag-p nil) - (module-name "")) - (save-match-data - (while (and (not found-flag-p) - (re-search-backward "defmodule \\([A-Za-z\._]+\\)\s+" nil t)) - (when (not (alchemist-goto--string-at-point-p)) - (setq module-name (match-string 1)) - (setq found-flag-p t)) - (when (equal 1 (line-number-at-pos (point))) - (setq found-flag-p t))) - module-name)))) - -(defun alchemist-goto--use-modules-in-the-current-module-context () - (let ((modules '()) - (context (alchemist-goto--current-module-name))) - (save-excursion - (while (re-search-backward "^\s+use\s+\\([A-Za-z0-9\.]+\\)" nil t) - (if (and (match-string 1) - (not (alchemist-goto--string-at-point-p)) - (equal context (alchemist-goto--current-module-name))) - (setq modules (add-to-list 'modules (substring-no-properties (match-string 1)))) - )) - modules))) - -(defun alchemist-goto--import-modules-in-the-current-module-context () - (let ((modules '()) - (context (alchemist-goto--current-module-name))) - (save-excursion - (while (re-search-backward "^\s+import\s+\\([A-Za-z0-9\.]+\\)" nil t) - (if (and (match-string 1) - (not (alchemist-goto--string-at-point-p)) - (equal context (alchemist-goto--current-module-name))) - (setq modules (add-to-list 'modules (substring-no-properties (match-string 1)))) - )) - modules))) - -(defun alchemist-goto--extract-module (code) - "Extract module from CODE." - (let* ((parts (split-string code "\\.")) - (function (car (last parts))) - (case-fold-search nil)) - (when (string-match-p "^[a-z_\?!]+" function) - (delete function parts)) - (unless (string-match-p "^[a-z_\?!]+" (car parts)) - (replace-regexp-in-string "\\.$" "" (mapconcat 'concat parts "."))))) - -(defun alchemist-goto--extract-function (code) - "Extract function from CODE." - (let* ((parts (split-string code "\\.")) - (function (car (last parts))) - (case-fold-search nil)) - (when (and function - (string-match-p "^[a-z_\?!]+" function)) - function))) - -(defun alchemist-goto--build-elixir-ex-core-file (file) - (when (string-match "\\/\\(lib\\/.+\\/lib\\)\\/.+\.ex$" file) - (let* ((file (substring-no-properties file (match-beginning 1))) - (source-directory (expand-file-name alchemist-goto-elixir-source-dir))) - (concat source-directory file)))) - -(defun alchemist-goto--build-elixir-erl-core-file (file) - (when (string-match "\\/\\(lib\\/.+\\/src\\)\\/.+\.erl$" file) - (let* ((file (substring-no-properties file (match-beginning 1))) - (source-directory (expand-file-name alchemist-goto-elixir-source-dir))) - (concat source-directory file)))) - -(defun alchemist-goto--build-erlang-core-file (file) - (when (string-match "\\/\\(lib\\/.+\\/src\\)\\/.+\.erl$" file) - (let* ((file (substring-no-properties file (match-beginning 1))) - (source-directory (expand-file-name alchemist-goto-erlang-source-dir))) - (concat source-directory file)))) - -(defun alchemist-goto--elixir-file-p (file) - (string-match-p "\\.ex\\(s\\)?$" file)) - -(defun alchemist-goto--erlang-file-p (file) - (string-match-p "\\.erl$" file)) - -(defun alchemist-goto--get-full-path-of-alias (module) - (if (not (alchemist-utils--empty-string-p module)) - (let* ((aliases (mapcar (lambda (m) - (when (string-match-p (format "^%s" (car (cdr m))) module) - (replace-regexp-in-string (format "^%s" (car (cdr m))) (car m) module t))) - (alchemist-goto--alises-of-current-buffer))) - (aliases (delete nil aliases))) - (if aliases - (car aliases) - module)))) - -(defun alchemist-goto--string-at-point-p (&optional complete) - "Return non-nil if cursor is at a string." - (save-excursion - (or (and (nth 3 (save-excursion - (let ((pos (point))) - (when complete - (end-of-buffer)) - (parse-partial-sexp 1 pos)))) - (nth 8 (save-excursion - (let ((pos (point))) - (when complete - (end-of-buffer)) - (parse-partial-sexp 1 pos))))) - (and (looking-at "\"\"\"\\|'''\\|\"\\|\'") - (match-beginning 0))))) - -(defun alchemist-goto--symbol-definition-p (symbol) - (alchemist-goto--fetch-symbol-definitions) - (if (member symbol alchemist-goto--symbol-list-bare) - t - nil)) - -(defun alchemist-goto--goto-symbol (symbol) - (let ((position (cdr (assoc symbol alchemist-goto--symbol-name-and-pos-bare)))) - (goto-char (if (overlayp position) (overlay-start position) position)))) - -(defun alchemist-goto-list-symbol-definitions () - "List all symbol definitions in the current file like functions/macros/modules. - -It will jump to the position of the symbol definition after selection." - (interactive) - (alchemist-goto--fetch-symbol-definitions) - (ring-insert find-tag-marker-ring (point-marker)) - (let* ((selected-def (completing-read "Symbol definitions:" alchemist-goto--symbol-list)) - (position (cdr (assoc selected-def alchemist-goto--symbol-name-and-pos)))) - (goto-char (if (overlayp position) (overlay-start position) position)))) - -(defun alchemist-goto--fetch-symbol-definitions () - (alchemist-goto--search-for-symbols "^\\s-*\\(defp?\\|defmacrop?\\|defmodule\\)\s.*")) - -(defface alchemist-goto--def-face - '((t (:inherit font-lock-constant-face))) - "" - :group 'alchemist-goto) - -(defface alchemist-goto--name-face - '((t (:bold t))) - "" - :group 'alchemist-goto) - -(defvar alchemist-goto--symbol-def-extract-regex - "^\\s-*\\(defp?\\|defmacrop?\\|defmodule\\)[ \n\t]+\\([a-z_\?!]+\\)\\(.*\\)\\(do\\|\n\\)?$") - -(defun alchemist-goto--extract-symbol (str) - (save-match-data - (when (string-match alchemist-goto--symbol-def-extract-regex str) - (let ((type (substring str (match-beginning 1) (match-end 1))) - (name (substring str (match-beginning 2) (match-end 2))) - (arguments (substring str (match-beginning 3) (match-end 3)))) - (concat - (propertize type - 'face 'alchemist-goto--def-face) - " " - (propertize name - 'face 'alchemist-goto--name-face) - (replace-regexp-in-string ",?\s+do:.*$" "" (replace-regexp-in-string "\s+do$" "" arguments))))))) - -(defun alchemist-goto--extract-symbol-bare (str) - (save-match-data - (when (string-match alchemist-goto--symbol-def-extract-regex str) - (let ((type (substring str (match-beginning 1) (match-end 1))) - (name (substring str (match-beginning 2) (match-end 2))) - (arguments (substring str (match-beginning 3) (match-end 3)))) - name)))) - -(defun alchemist-goto--get-symbol-from-position (position) - (with-current-buffer (buffer-name) - (save-excursion - (goto-char position) - (end-of-line) - (let* ((end-position (point)) - (line (buffer-substring-no-properties position end-position))) - (alchemist-goto--extract-symbol line))))) - -(defun alchemist-goto--get-symbol-from-position-bare (position) - (with-current-buffer (buffer-name) - (save-excursion - (goto-char position) - (end-of-line) - (let* ((end-position (point)) - (line (buffer-substring-no-properties position end-position))) - (alchemist-goto--extract-symbol-bare line))))) - -(defun alchemist-goto--search-for-symbols (regex) - (setq alchemist-goto--symbol-list '()) - (setq alchemist-goto--symbol-name-and-pos '()) - (with-current-buffer (buffer-name) - (save-excursion - (goto-char (point-max)) - (goto-char (point-min)) - (let () - (save-match-data - (while (re-search-forward regex nil t) - (when (not (alchemist-goto--string-at-point-p t)) - (when (alchemist-goto--get-symbol-from-position (car (match-data))) - (let* ((position (car (match-data))) - (symbol (alchemist-goto--get-symbol-from-position position)) - (symbol-bare (alchemist-goto--get-symbol-from-position-bare position))) - (setq alchemist-goto--symbol-list (append alchemist-goto--symbol-list (list symbol))) - (setq alchemist-goto--symbol-name-and-pos (append alchemist-goto--symbol-name-and-pos (list (cons symbol position)))) - (setq alchemist-goto--symbol-list-bare (append alchemist-goto--symbol-list-bare (list symbol-bare))) - (setq alchemist-goto--symbol-name-and-pos-bare (append alchemist-goto--symbol-name-and-pos-bare (list (cons symbol-bare position))))))))))))) - -(defun alchemist-goto--open-definition (expr) - (let* ((module (alchemist-goto--extract-module expr)) - (module (alchemist-goto--get-full-path-of-alias module)) - (module (if module module "nil")) - (function (alchemist-goto--extract-function expr)) - (function (if function function "\"\""))) - (ring-insert find-tag-marker-ring (point-marker)) - (cond - ((and (string-equal module "nil") - (string-equal major-mode "elixir-mode") - (alchemist-goto--symbol-definition-p function)) - (alchemist-goto--goto-symbol function)) - (t (alchemist-server-goto module function expr) - )))) - -(defun alchemist-goto--open-file (file module function) - (let* ((buf (find-file-noselect file))) - (switch-to-buffer buf) - (beginning-of-buffer) - (cond ((alchemist-goto--elixir-file-p file) - (alchemist-goto--jump-to-elixir-source module function)) - ((alchemist-goto--erlang-file-p file) - (alchemist-goto--jump-to-erlang-source module function))))) - -(defun alchemist-gogo--symbol-definition-regex (symbol) - (format "^\s+\\(defp?\s+%s\(?\\|defmacrop?\s+%s\(?\\)" symbol symbol)) - -(defun alchemist-goto--jump-to-elixir-source (module function) - (let ((function (replace-regexp-in-string "\?" "\\?" function))) - (when (re-search-forward (alchemist-gogo--symbol-definition-regex function) nil t) - (goto-char (match-beginning 0))) - (when (re-search-forward (format "\\(defmodule\\|defimpl\\|defprotocol\\)\s+%s\s+do" module) nil t) - (goto-char (match-beginning 0))))) - -(defun alchemist-goto--jump-to-erlang-source (module function) - (when (re-search-forward (format "\\(^%s\(\\)" function) nil t) - (goto-char (match-beginning 0))) - (when (re-search-forward (format "\\(^-module\(%s\)\\)" (substring module 1)) nil t) - (goto-char (match-beginning 0)))) - -(defun alchemist-goto--context-exists-p () - (interactive) - (save-excursion - (goto-char (point-min)) - (if (re-search-forward "defmodule \\([A-Za-z\._]+\\)\s+" nil t) - t - nil))) - -(defun alchemist-goto--alises-of-current-buffer () - (let* ((aliases '())) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward "^\s+alias\s+\\([-:_A-Za-z0-9,\.\?!\]+\\)\\(\s*,\s*as:\s*\\)?\\([-_A-Za-z0-9,\.\?!\]+\\)?\n" nil t) - (let* ((alias (match-string 1)) - (as (if (match-string 3) (match-string 3) nil)) - (as (if as as (car (last (split-string alias "\\.")))))) - (setq aliases (append aliases (list (list alias as))))))) - aliases)) - -;; Public functions - -(defun alchemist-goto-definition-at-point () - "Jump to the elixir expression definition at point." - (interactive) - (let (p1 p2) - (skip-chars-backward "-_A-Za-z0-9.?!:") - (setq p1 (point)) - (skip-chars-forward "-_A-Za-z0-9.?!:") - (setq p2 (point)) - (alchemist-goto--open-definition (buffer-substring-no-properties p1 p2)))) - -(defalias 'alchemist-goto-jump-back 'pop-tag-mark) - -(provide 'alchemist-goto) - -;;; alchemist-goto.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-help.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-help.el deleted file mode 100644 index 5d670cc..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-help.el +++ /dev/null @@ -1,204 +0,0 @@ -;;; alchemist-help.el --- Functionality for Elixir documentation lookup -*- lexical-binding: t -*- - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Functionality for Elixir documentation lookup. - -;;; Code: - -(defgroup alchemist-help nil - "Functionality for Elixir documentation lookup." - :prefix "alchemist-help-" - :group 'alchemist) - -;; Variables - -(defcustom alchemist-help-buffer-name "*elixir help*" - "Name of the Elixir help buffer." - :type 'string - :group 'alchemist-help) - -(defvar alchemist-help-search-history '() - "Storage for the search history.") - -(defvar alchemist-help-current-search-text '() - "Stores the current search.") - -;; Faces - -(defface alchemist-help--key-face - '((t (:inherit font-lock-variable-name-face :bold t :foreground "red"))) - "Fontface for the letter keys in the summary." - :group 'alchemist-help) - -(defun alchemist-help--exp-at-point () - "Return the expression under the cursor." - (let (p1 p2) - (save-excursion - (skip-chars-backward "-_A-Za-z0-9.?!:") - (setq p1 (point)) - (skip-chars-forward "-_A-Za-z0-9.?!:") - (setq p2 (point)) - (buffer-substring-no-properties p1 p2)))) - -(defun alchemist-help--execute (search) - (alchemist-server-help-with-complete search)) - -(defun alchemist-help--execute-without-complete (search) - (alchemist-server-help-without-complete search)) - -(defun alchemist-help--bad-search-output-p (string) - (let ((match (or (string-match-p "No documentation for " string) - (string-match-p "Invalid arguments for h helper" string) - (string-match-p "** (TokenMissingError)" string) - (string-match-p "** (SyntaxError)" string) - (string-match-p "** (FunctionClauseError)" string) - (string-match-p "** (CompileError)" string) - (string-match-p "Could not load module" string)))) - (if match - t - nil))) - -(defun alchemist-help--initialize-buffer (content) - (let ((default-directory (if (alchemist-project-root) - (alchemist-project-root) - default-directory))) - (cond - ((alchemist-help--bad-search-output-p content) - (message (propertize - (format "No documentation for [ %s ] found." alchemist-help-current-search-text) - 'face 'alchemist-help--key-face))) - (t - (if (get-buffer alchemist-help-buffer-name) - (kill-buffer alchemist-help-buffer-name)) - (pop-to-buffer alchemist-help-buffer-name) - (setq buffer-undo-list nil) - (let ((inhibit-read-only t) - (buffer-undo-list t)) - (erase-buffer) - (insert content) - (unless (memq 'alchemist-help-current-search-text alchemist-help-search-history) - (add-to-list 'alchemist-help-search-history alchemist-help-current-search-text)) - (delete-matching-lines "do not show this result in output" (point-min) (point-max)) - (delete-matching-lines "^Compiled lib\\/" (point-min) (point-max)) - (ansi-color-apply-on-region (point-min) (point-max)) - (read-only-mode 1) - (alchemist-help-minor-mode 1)))))) - -(defun alchemist-help-minor-mode-key-binding-summary () - (interactive) - (message - (concat "[" (propertize "q" 'face 'alchemist-help--key-face) - "]-quit [" - (propertize "e" 'face 'alchemist-help--key-face) - "]-search-at-point [" - (propertize "m" 'face 'alchemist-help--key-face) - "]-search-marked-region [" - (propertize "s" 'face 'alchemist-help--key-face) - "]-search [" - (propertize "h" 'face 'alchemist-help--key-face) - "]-history [" - (propertize "?" 'face 'alchemist-help--key-face) - "]-keys"))) - -(defun alchemist-help-search-at-point () - "Search through `alchemist-help' with the expression under the cursor." - (interactive) - (let* ((expr (alchemist-help--exp-at-point)) - (module (alchemist-goto--extract-module expr)) - (module (alchemist-goto--get-full-path-of-alias module)) - (module (if module module "")) - (function (alchemist-goto--extract-function expr)) - (function (if function function "")) - (expr (cond - ((and (not (alchemist-utils--empty-string-p module)) - (not (alchemist-utils--empty-string-p function))) - (format "%s.%s" module function)) - ((not (alchemist-utils--empty-string-p module)) - module) - (t - expr)))) - (alchemist-help--execute expr))) - -(defun alchemist-help-search-marked-region (begin end) - "Run `alchemist-help' with the marked region. -Argument BEGIN where the mark starts. -Argument END where the mark ends." - (interactive "r") - (let* ((expr (filter-buffer-substring begin end)) - (module (alchemist-goto--extract-module expr)) - (module (alchemist-goto--get-full-path-of-alias module)) - (module (if module module "")) - (function (alchemist-goto--extract-function expr)) - (function (if function function "")) - (expr (cond - ((and (not (alchemist-utils--empty-string-p module)) - (not (alchemist-utils--empty-string-p function))) - (format "%s.%s" module function)) - ((not (alchemist-utils--empty-string-p module)) - module) - (t - expr)))) - (alchemist-help--execute expr))) - -(defun alchemist-help--elixir-modules-to-list (str) - (let* ((modules (split-string str)) - (modules (mapcar (lambda (m) - (when (string-match-p "Elixir\\." m) - (replace-regexp-in-string "Elixir\\." "" m))) modules)) - (modules (delete nil modules)) - (modules (cl-sort modules 'string-lessp :key 'downcase)) - (modules (delete-dups modules))) - modules)) - -(defvar alchemist-help-minor-mode-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "q") #'quit-window) - (define-key map (kbd "e") #'alchemist-help-search-at-point) - (define-key map (kbd "m") #'alchemist-help-search-marked-region) - (define-key map (kbd "s") #'alchemist-help) - (define-key map (kbd "h") #'alchemist-help-history) - (define-key map (kbd "M-.") #'alchemist-goto-definition-at-point) - (define-key map (kbd "?") #'alchemist-help-minor-mode-key-binding-summary) - map) - "Keymap for `alchemist-help-minor-mode'.") - -(define-minor-mode alchemist-help-minor-mode - "Minor mode for displaying elixir help." - :group 'alchemist-help - :keymap alchemist-help-minor-mode-map) - -(defun alchemist-help () - "Load Elixir documentation for SEARCH." - (interactive) - (alchemist-server-help)) - -(defun alchemist-help-history (search) - "Load Elixir from the documentation history for SEARCH." - (interactive - (list - (completing-read "Elixir help history: " alchemist-help-search-history nil nil ""))) - (alchemist-help--execute-without-complete search)) - -(provide 'alchemist-help) - -;;; alchemist-help.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-hooks.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-hooks.el deleted file mode 100644 index 3d45bf1..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-hooks.el +++ /dev/null @@ -1,50 +0,0 @@ -;;; alchemist-hooks.el --- Hooks functionality - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini - -;; This file is not part of GNU Emacs. - -;; 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 . - -;;; Commentary: - -;; Hooks functionality - -;;; Code: - -(defgroup alchemist-hooks nil - "Hooks" - :prefix "alchemist-hooks-" - :group 'alchemist) - -(defcustom alchemist-hooks-test-on-save nil - "If t, run `alchemist-mix-test' on save." - :type 'boolean - :group 'alchemist-hooks) - -(defun alchemist-hooks--test-on-save () - (when (and alchemist-hooks-test-on-save - (alchemist-utils--elixir-project-root)) - (alchemist-mix-test))) - -(eval-after-load 'elixir-mode - '(progn - (add-hook 'after-save-hook 'alchemist-hooks--test-on-save nil nil))) - -(provide 'alchemist-hooks) - -;;; alchemist-hooks.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-iex.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-iex.el deleted file mode 100644 index 3c78d67..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-iex.el +++ /dev/null @@ -1,201 +0,0 @@ -;;; alchemist-help.el --- Interaction with an Elixir IEx process - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Interaction with an Elixir IEx process - -;;; Code: - -(require 'comint) - -(defgroup alchemist-iex nil - "Interaction with an Elixir IEx process." - :prefix "alchemist-iex-" - :group 'alchemist) - -(defcustom alchemist-iex-program-name "iex" - "The shell command for iex." - :type 'string - :group 'alchemist-iex) - -(defcustom alchemist-iex-prompt-read-only t - "If non-nil, the prompt will be read-only." - :type 'boolean - :group 'alchemist-iex) - -(defvar alchemist-iex-buffer nil - "The buffer in which the Elixir IEx process is running.") - -(defvar alchemist-iex-mode-hook nil - "Hook for customizing `alchemist-iex-mode'.") - -(defvar alchemist-iex-mode-map - (let ((map (nconc (make-sparse-keymap) comint-mode-map))) - (define-key map "\t" 'completion-at-point) - (define-key map (kbd (format "%s i r" alchemist-key-command-prefix)) 'alchemist-iex-open-input-ring) - (define-key map (kbd (format "%s i c" alchemist-key-command-prefix)) 'alchemist-iex-clear-buffer) - (define-key map (kbd (format "%s h e" alchemist-key-command-prefix)) 'alchemist-help-search-at-point) - (define-key map (kbd (format "%s h m" alchemist-key-command-prefix)) 'alchemist-help-search-marked-region) - (define-key map (kbd "M-.") 'alchemist-goto-definition-at-point) - map)) - -(eval-after-load 'company - '(progn - (defun alchemist-iex--set-company-as-completion-at-point-function () - (setq completion-at-point-functions '(company-complete))) - (add-hook 'alchemist-iex-mode-hook 'alchemist-iex--set-company-as-completion-at-point-function))) - -(define-derived-mode alchemist-iex-mode comint-mode "Alchemist-IEx" - "Major mode for interacting with an Elixir IEx process. - -\\" - nil "Alchemist-IEx" - (set (make-local-variable 'comint-prompt-regexp) "^iex\(.+\)>") - (set (make-local-variable 'comint-prompt-read-only) alchemist-iex-prompt-read-only) - (set (make-local-variable 'comint-input-autoexpand) nil)) - -(defun alchemist-iex-command (arg) - (split-string-and-unquote - (if (null arg) alchemist-iex-program-name - (read-string "Command to run Elixir IEx: " (concat alchemist-iex-program-name arg))))) - -(defun alchemist-iex-start-process (command) - "Start an IEX process. -With universal prefix \\[universal-argument], prompts for a COMMAND, -otherwise uses `alchemist-iex-program-name'. -It runs the hook `alchemist-iex-mode-hook' after starting the process and -setting up the IEx buffer." - (interactive (list (alchemist-iex-command current-prefix-arg))) - (setq alchemist-iex-buffer - (apply 'make-comint "Alchemist-IEx" (car command) nil (cdr command))) - (with-current-buffer alchemist-iex-buffer - (alchemist-iex-mode) - (run-hooks 'alchemist-iex-mode-hook))) - -(defun alchemist-iex-process (&optional arg) - (or (if (buffer-live-p alchemist-iex-buffer) - (get-buffer-process alchemist-iex-buffer)) - (progn - (let ((current-prefix-arg arg)) - (call-interactively 'alchemist-iex-start-process)) - (alchemist-iex-process arg)))) - -(defun alchemist-iex--remove-newlines (string) - (replace-regexp-in-string "\n" " " string)) - -(defun alchemist-iex-send-last-sexp () - "Send the previous sexp to the inferior IEx process." - (interactive) - (alchemist-iex-send-region (save-excursion (backward-sexp) (point)) (point))) - -(defun alchemist-iex-send-current-line () - "Sends the current line to the IEx process." - (interactive) - (let ((str (thing-at-point 'line))) - (alchemist-iex--send-command (alchemist-iex-process) str))) - -(defun alchemist-iex-send-current-line-and-go () - "Sends the current line to the inferior IEx process -and jump to the buffer." - (interactive) - (call-interactively 'alchemist-iex-send-current-line) - (pop-to-buffer (process-buffer (alchemist-iex-process)))) - -(defun alchemist-iex-send-region-and-go () - "Sends the marked region to the inferior IEx process -and jump to the buffer." - (interactive) - (call-interactively 'alchemist-iex-send-region) - (pop-to-buffer (process-buffer (alchemist-iex-process)))) - -(defun alchemist-iex-send-region (beg end) - "Sends the marked region to the IEx process." - (interactive (list (point) (mark))) - (unless (and beg end) - (error "The mark is not set now, so there is no region")) - (let* ((region (buffer-substring-no-properties beg end))) - (alchemist-iex--send-command (alchemist-iex-process) region))) - -(defun alchemist-iex-compile-this-buffer () - "Compiles the current buffer in the IEx process." - (interactive) - (let ((str (format "c(\"%s\")" (buffer-file-name)))) - (alchemist-iex--send-command (alchemist-iex-process) str))) - -(defun alchemist-iex-recompile-this-buffer () - "Recompiles and reloads the current buffer in the IEx process." - (interactive) - (let ((str (format "r(\"%s\")" (buffer-file-name)))) - (alchemist-iex--send-command (alchemist-iex-process) str))) - -(defun alchemist-iex--send-command (proc str) - (let ((str-no-newline (concat (alchemist-iex--remove-newlines str) "\n")) - (str (concat str "\n"))) - (with-current-buffer (process-buffer proc) - (goto-char (process-mark proc)) - (insert-before-markers str) - (move-marker comint-last-input-end (point)) - (comint-send-string proc str-no-newline)))) - -(defun alchemist-iex-clear-buffer () - "Clear the current iex process buffer." - (interactive) - (let ((comint-buffer-maximum-size 0)) - (comint-truncate-buffer))) - -(defun alchemist-iex-open-input-ring () - "Open the buffer containing the input history." - (interactive) - (progn - (comint-dynamic-list-input-ring) - (other-window 1))) - -;;;###autoload -(defalias 'run-elixir 'alchemist-iex-run) -(defalias 'inferior-elixir 'alchemist-iex-run) - -;;;###autoload -(defun alchemist-iex-run (&optional arg) - "Start an IEx process. -Show the IEx buffer if an IEx process is already run." - (interactive "P") - (let ((proc (alchemist-iex-process arg))) - (pop-to-buffer (process-buffer proc)))) - -;;;###autoload -(defun alchemist-iex-project-run () - "Start an IEx process with mix 'iex -S mix' in the -context of an Elixir project. -Show the IEx buffer if an IEx process is already run." - (interactive) - (let ((old-directory default-directory)) - (if (alchemist-project-p) - (progn - (alchemist-project--establish-root-directory) - (let ((proc (alchemist-iex-process " -S mix"))) - (cd old-directory) - (pop-to-buffer (process-buffer proc)))) - (message "No mix.exs file available. Please use `alchemist-iex-run' instead.")))) - -(provide 'alchemist-iex) - -;;; alchemist-iex.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-mix.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-mix.el deleted file mode 100644 index 7375c82..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-mix.el +++ /dev/null @@ -1,217 +0,0 @@ -;;; alchemist-mix.el --- Emacs integration for Elixir's mix - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Emacs integration for Elixir's mix - -;;; Code: - -(defgroup alchemist-mix nil - "Emacs integration for Elixir's mix." - :prefix "alchemist-mix-" - :group 'alchemist) - -;; Variables - -(defcustom alchemist-mix-command "mix" - "The shell command for mix." - :type 'string - :group 'alchemist-mix) - -(defcustom alchemist-mix-test-default-options '("--exclude pending:true") - "Default options for alchemist test command." - :type '(repeat string) - :group 'alchemist-mix) - -(defcustom alchemist-mix-env nil - "The default mix env to run mix commands with. If nil, the mix env is -not set explicitly." - :type '(string boolean) - :group 'alchemist-mix) - -(defvar alchemist-mix-buffer-name "*mix*" - "Name of the mix output buffer.") - -(defvar alchemist-mix--envs '("dev" "prod" "test") - "The list of mix envs to use as defaults.") - -(defvar alchemist-mix--deps-commands - '("deps" "deps.clean" "deps.compile" "deps.get" "deps.unlock" "deps.unlock") - "List of all deps.* available commands.") - -(defvar alchemist-mix--local-commands - '("local" "local.install" "local.rebar" "local.uninstall") - "List of all local.* available commands.") - -(defvar alchemist-mix--local-install-option-types '("path" "url") - "List of local.install option types.") - -;; Private functions - -(defun alchemist-mix--completing-read (prompt cmdlist) - (completing-read prompt cmdlist nil t nil nil (car cmdlist))) - -(defun alchemist-mix--test-file (filename) - "Run a specific FILENAME as argument for the mix command test." - (when (not (file-exists-p filename)) - (error "The given file doesn't exists")) - (alchemist-mix-execute `("test" ,(expand-file-name filename) ,@alchemist-mix-test-default-options) - alchemist-test-mode-buffer-name)) - -(defun alchemist-mix--commands () - (let ((mix-cmd-list (shell-command-to-string (format "%s help" alchemist-mix-command)))) - (mapcar (lambda (s) - (cdr (split-string (car (split-string s "#"))))) - (cdr (split-string mix-cmd-list "\n"))))) - -;; Public functions - -(defun alchemist-mix-display-mix-buffer () - "Display the mix buffer when exists." - (interactive) - (when (get-buffer alchemist-mix-buffer-name) - (display-buffer alchemist-mix-buffer-name))) - -(defun alchemist-mix-new (name) - "Create a new elixir project named by NAME." - (interactive "Gmix new: ") - (alchemist-mix-execute (list "new" (expand-file-name name)) - alchemist-mix-buffer-name)) - -(defun alchemist-mix-test () - "Run the whole elixir test suite." - (interactive) - (alchemist-mix-execute `("test" ,@alchemist-mix-test-default-options) - alchemist-test-mode-buffer-name)) - -(defun alchemist-mix-test-this-buffer () - "Run the current buffer through mix test." - (interactive) - (alchemist-mix--test-file buffer-file-name)) - -(defun alchemist-mix-test-file (filename) - "Run `alchemist-mix--test-file' with the FILENAME." - (interactive "Fmix test: ") - (alchemist-mix--test-file (expand-file-name filename))) - -(defun alchemist-mix-test-at-point () - "Run the test at point." - (interactive) - (let* ((line (line-number-at-pos (point))) - (file-and-line (format "%s:%s" buffer-file-name line))) - (alchemist-mix-execute (list "test" file-and-line) - alchemist-test-mode-buffer-name))) - -(defun alchemist-mix-compile (command &optional prefix) - "Compile the whole elixir project. Prompt for the mix env if the prefix -arg is set." - (interactive "Mmix compile: \nP") - (alchemist-mix-execute (list "compile" command) - alchemist-mix-buffer-name prefix)) - -(defun alchemist-mix-run (command &optional prefix) - "Runs the given file or expression in the context of the application. -Prompt for the mix env if the prefix arg is set." - (interactive "Mmix run: \nP") - (alchemist-mix-execute (list "run" command) - alchemist-mix-buffer-name prefix)) - -(defun alchemist-mix-deps-with-prompt (command &optional prefix) - "Prompt for mix deps commands." - (interactive - (list (alchemist-mix--completing-read "mix deps: " alchemist-mix--deps-commands) - current-prefix-arg)) - (alchemist-mix-execute (list command) - alchemist-mix-buffer-name prefix)) - -(defun alchemist-mix (command &optional prefix) - "Prompt for mix commands. Prompt for the mix env if the prefix arg is set." - (interactive - (list (alchemist-mix--completing-read "mix: " (alchemist-mix--commands)) - current-prefix-arg)) - (let ((command (read-string "mix " (concat command " ")))) - (alchemist-mix-execute (list command) - alchemist-mix-buffer-name prefix))) - -(defun alchemist-mix-local-with-prompt (command) - "Prompt for mix local commands." - (interactive - (list (alchemist-mix--completing-read "mix local: " alchemist-mix--local-commands))) - (if (string= command "local.install") - (call-interactively 'alchemist-mix-local-install) - (alchemist-mix-execute (list command) - alchemist-mix-buffer-name))) - -(defun alchemist-mix-local-install (path-or-url) - "Prompt for mix local.install PATH-OR-URL." - (interactive - (list (completing-read "mix local.install FORMAT: " - alchemist-mix--local-install-option-types - nil t nil nil (car alchemist-mix--local-install-option-types)))) - (if (string= path-or-url (car alchemist-mix--local-install-option-types)) - (call-interactively 'alchemist-mix-local-install-with-path) - (call-interactively 'alchemist-mix-local-install-with-url))) - -(defun alchemist-mix-local-install-with-path (path) - "Runs local.install and prompt for a PATH as argument." - (interactive "fmix local.install PATH: ") - (alchemist-mix-execute (list "local.install" path) - alchemist-mix-buffer-name)) - -(defun alchemist-mix-local-install-with-url (url) - "Runs local.install and prompt for a URL as argument." - (interactive "Mmix local.install URL: ") - (alchemist-mix-execute (list "local.install" url) - alchemist-mix-buffer-name)) - -(defun alchemist-mix-hex-search (command &optional prefix) - "Display packages matching the given search query. Prompt for the mix env -if the prefix arg is set." - (interactive "Mmix hex.search: \nP") - (alchemist-mix-execute (list "hex.search" command) - alchemist-mix-buffer-name prefix)) - -(defun alchemist-mix-help (command &optional prefix) - "Show help output for a specific mix command. Prompt for the mix env if -the prefix arg is set." - (interactive "Mmix help: \nP") - (alchemist-mix-execute (list "help" command) - alchemist-mix-buffer-name prefix)) - -(defun alchemist-mix-execute (cmdlist buffer-name &optional prefix) - "Run a mix command. Prompt for the mix env if the prefix arg is set." - (interactive "Mmix: \nP") - (let ((old-directory default-directory) - (mix-env (if prefix - (completing-read "mix env: " - alchemist-mix--envs nil nil alchemist-mix-env) - alchemist-mix-env))) - (alchemist-project--establish-root-directory) - (alchemist-buffer-run (alchemist-utils--build-runner-cmdlist - (list (if mix-env (concat "MIX_ENV=" mix-env) "") - alchemist-mix-command cmdlist)) - buffer-name) - (cd old-directory))) - -(provide 'alchemist-mix) - -;;; alchemist-mix.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-pkg.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-pkg.el deleted file mode 100644 index 4cee708..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-pkg.el +++ /dev/null @@ -1,7 +0,0 @@ -(define-package "alchemist" "20150624.159" "Elixir tooling integration into Emacs" - '((emacs "24")) - :url "http://www.github.com/tonini/alchemist.el" :keywords - '("languages" "mix" "elixir" "elixirc" "hex")) -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-project.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-project.el deleted file mode 100644 index b643ff0..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-project.el +++ /dev/null @@ -1,163 +0,0 @@ -;;; alchemist-project.el --- API to identify Elixir mix projects. - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; API to identify Elixir mix projects. - -;;; Code: - -(require 'cl) - -(defgroup alchemist-project nil - "API to identify Elixir mix projects." - :prefix "alchemist-help-" - :group 'alchemist) - -(defvar alchemist-project-root-indicators - '("mix.exs") - "list of file-/directory-names which indicate a root of a elixir project") - -(defvar alchemist-project-deps-indicators - '(".hex") - "list of file-/directory-names which indicate a root of a elixir project") - -(defun alchemist-project-p () - "Returns whether alchemist has access to a elixir project root or not" - (stringp (alchemist-project-root))) - -(defun alchemist-project-parent-directory (a-directory) - "Returns the directory of which a-directory is a child" - (file-name-directory (directory-file-name a-directory))) - -(defun alchemist-project-root-directory-p (a-directory) - "Returns t if a-directory is the root" - (equal a-directory (alchemist-project-parent-directory a-directory))) - -(defun alchemist-project-root (&optional directory) - "Finds the root directory of the project by walking the directory tree until it finds a project root indicator." - (let* ((directory (file-name-as-directory (or directory (expand-file-name default-directory)))) - (present-files (directory-files directory))) - (cond ((alchemist-project-root-directory-p directory) nil) - ((> (length (intersection present-files alchemist-project-deps-indicators :test 'string=)) 0) - (alchemist-project-root (file-name-directory (directory-file-name directory)))) - ((> (length (intersection present-files alchemist-project-root-indicators :test 'string=)) 0) directory) - (t (alchemist-project-root (file-name-directory (directory-file-name directory))))))) - -(defun alchemist-project--establish-root-directory () - "Set the default-directory to the Elixir project root." - (let ((project-root (alchemist-project-root))) - (when project-root - (setq default-directory project-root)))) - -(defun alchemist-project-toggle-file-and-tests-other-window () - "Toggle between a file and its tests in other window." - (interactive) - (if (alchemist-utils--is-test-file-p) - (alchemist--project-open-file-for-current-tests 'find-file-other-window) - (alchemist--project-open-tests-for-current-file 'find-file-other-window))) - -(defun alchemist-project-toggle-file-and-tests () - "Toggle between a file and its tests in the current window." - (interactive) - (if (alchemist-utils--is-test-file-p) - (alchemist--project-open-file-for-current-tests 'find-file) - (alchemist--project-open-tests-for-current-file 'find-file))) - -(defun alchemist--project-open-file-for-current-tests (toggler) - "Open the appropriate implementation file for the current buffer by calling TOGGLER with filename." - (let* ((filename (file-relative-name (buffer-file-name) (alchemist-project-root))) - (filename (replace-regexp-in-string "^test/" "lib/" filename)) - (filename (replace-regexp-in-string "_test\.exs$" "\.ex" filename)) - (filename (format "%s/%s" (alchemist-project-root) filename))) - (funcall toggler filename))) - -(defun alchemist--project-open-tests-for-current-file (toggler) - "Opens the appropriate test file by calling TOGGLER with filename." - (let* ((filename (file-relative-name (buffer-file-name) (alchemist-project-root))) - (filename (replace-regexp-in-string "^lib/" "test/" filename)) - (filename (replace-regexp-in-string "\.ex$" "_test\.exs" filename)) - (filename (format "%s/%s" (alchemist-project-root) filename))) - (if (file-exists-p filename) - (funcall toggler filename) - (if (y-or-n-p "No test file found; create one now?") - (alchemist-project--create-test-for-current-file - filename (current-buffer)) - (message "No test file found."))))) - -(defun alchemist-project--create-test-for-current-file (filename buffer) - "Creates and populates a test module, FILENAME, for the code in BUFFER. -The module name given to the test module is determined from the name of the -first module defined in BUFFER." - (let* ((directory-name (file-name-directory filename)) - (module-name (alchemist-project--grok-module-name buffer)) - (test-module-name (concat module-name "Test"))) - (unless (file-exists-p directory-name) - (make-directory (file-name-directory filename) t)) - (alchemist-project--insert-test-boilerplate - (find-file-other-window filename) test-module-name))) - -(defun alchemist-project--grok-module-name (buffer) - "Determines the name of the first module defined in BUFFER." - (save-excursion - (set-buffer buffer) - (goto-line 1) - (re-search-forward "defmodule\\s-\\(.+?\\)\\s-?,?\\s-do") - (match-string 1))) - -(defun alchemist-project--insert-test-boilerplate (buffer module) - "Inserts ExUnit boilerplate for MODULE in BUFFER. -Point is left in a convenient location." - (set-buffer buffer) - (insert (concat "defmodule " module " do\n" - " use ExUnit.Case\n" - "\n" - "end\n")) - (goto-char (point-min)) - (beginning-of-line 3)) - -(defun alchemist-project-find-test () - "Open project test directory and list all test files." - (interactive) - (when (alchemist-project-p) - (find-file (alchemist-project--open-directory-files "test")))) - -(defun alchemist-project--open-directory-files (directory) - (let ((directory (concat (replace-regexp-in-string "\/?$" "" (concat (alchemist-project-root) directory) "/")))) - (message directory) - (concat directory "/" (completing-read (concat directory ": ") - (mapcar (lambda (path) - (replace-regexp-in-string (concat "^" (regexp-quote directory) "/") "" path)) - (split-string - (shell-command-to-string - (concat - "find \"" directory - "\" -type f | grep \"_test\.exs\" | grep -v \"/.git/\"")))))))) - -(defun alchemist-project-name () - "Return the name of the current Elixir project." - (if (alchemist-project-p) - (car (cdr (reverse (split-string (alchemist-project-root) "/")))) - "")) - -(provide 'alchemist-project) - -;;; alchemist-project.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-server.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-server.el deleted file mode 100644 index 7753e22..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-server.el +++ /dev/null @@ -1,308 +0,0 @@ -;;; alchemist-server.el --- -*- lexical-binding: t -*- - -;; Copyright © 2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; - -;;; Code: - -(defvar alchemist-server - (concat (file-name-directory load-file-name) "server/server.exs") - "Script file with alchemist server.") - -(defvar alchemist-server--processes '()) -(defvar alchemist-server--env "dev") - -(defvar alchemist-server-command - (format "elixir %s %s" alchemist-server alchemist-server--env)) - -(defun alchemist-server-start (env) - "Start alchemist server for the current mix project in specific ENV." - (interactive (list - (completing-read (format "(Alchemist-Server) run in environment: (default: %s) " alchemist-server--env) - alchemist-mix--envs nil nil nil))) - (when (alchemist-server--process-p) - (kill-process (alchemist-server--process))) - (alchemist-server--start-with-env env)) - -(defun alchemist-server--start () - (unless (alchemist-server--process-p) - (alchemist-server--start-with-env alchemist-server--env))) - -(defun alchemist-server--start-with-env (env) - (let* ((process-name (alchemist-server--process-name)) - (default-directory (if (string= process-name "alchemist-server") - default-directory - process-name)) - (server-command (format "elixir %s %s" alchemist-server env)) - (process (start-process-shell-command process-name "*alchemist-server*" server-command))) - (set-process-query-on-exit-flag process nil) - (alchemist-server--store-process process))) - -(defun alchemist-server--store-process (process) - (let ((process-name (alchemist-server--process-name))) - (if (cdr (assoc process-name alchemist-server--processes)) - (setq alchemist-server--processes - (delq (assoc process-name alchemist-server--processes) alchemist-server--processes))) - (add-to-list 'alchemist-server--processes (cons process-name process)))) - -(defun alchemist-server--process-p () - (process-live-p (alchemist-server--process))) - -(defun alchemist-server--process () - (cdr (assoc (alchemist-server--process-name) alchemist-server--processes))) - -(defun alchemist-server--process-name () - (let* ((process-name (alchemist-project-root)) - (process-name (if process-name - process-name - "alchemist-server"))) - process-name)) - -(defun alchemist-server-eval-filter (process output) - (setq alchemist-server--output (cons output alchemist-server--output)) - (if (string-match "END-OF-EVAL$" output) - (let* ((output (apply #'concat (reverse alchemist-server--output))) - (output (replace-regexp-in-string "END-OF-EVAL" "" output)) - (output (replace-regexp-in-string "\n$" "" output))) - (funcall alchemist-server-eval-callback output)))) - -(defun alchemist-server-eval-quoted-filter (process output) - (setq alchemist-server--output (cons output alchemist-server--output)) - (if (string-match "END-OF-QUOTE$" output) - (let* ((output (apply #'concat (reverse alchemist-server--output))) - (output (replace-regexp-in-string "END-OF-QUOTE" "" output)) - (output (replace-regexp-in-string "\n$" "" output))) - (funcall alchemist-server-eval-callback output)))) - -(defun alchemist-server-doc-filter (process output) - (setq alchemist-server--output (cons output alchemist-server--output)) - (if (string-match "END-OF-DOC$" output) - (let* ((string (apply #'concat (reverse alchemist-server--output))) - (string (replace-regexp-in-string "END-OF-DOC$" "" string))) - (alchemist-help--initialize-buffer string)))) - -(defun alchemist-server-complete-canidates-filter (process output) - (setq alchemist-server--output (cons output alchemist-server--output)) - (unless (alchemist-utils--empty-string-p output) - (if (string-match "END-OF-COMPLETE$" output) - (let* ((string (apply #'concat (reverse alchemist-server--output))) - (string (replace-regexp-in-string "END-OF-COMPLETE$" "" string)) - (candidates (if (not (alchemist-utils--empty-string-p string)) - (alchemist-complete--output-to-list - (alchemist--utils-clear-ansi-sequences string)) - '())) - (candidates (if candidates - (remove-duplicates candidates) - '())) - (candidates (if candidates - (alchemist-complete--build-candidates candidates) - '()))) - (alchemist-complete--serve-candidates-to-company candidates))))) - -(defun alchemist-server-complete-canidates-filter-with-context (process output) - (setq alchemist-server--output (cons output alchemist-server--output)) - (if (string-match "END-OF-COMPLETE-WITH-CONTEXT$" output) - (let* ((string (apply #'concat (reverse alchemist-server--output))) - (string (replace-regexp-in-string "END-OF-COMPLETE-WITH-CONTEXT$" "" string)) - (candidates (if (not (alchemist-utils--empty-string-p string)) - (alchemist-complete--output-to-list - (alchemist--utils-clear-ansi-sequences string)) - '())) - (candidates (if candidates - (remove-duplicates candidates) - '())) - (candidates (if candidates - (alchemist-complete--build-candidates candidates) - '()))) - (alchemist-complete--serve-candidates-to-company candidates)))) - -(defun alchemist-server-complete-filter (process output) - (with-local-quit - (setq alchemist-server--output (cons output alchemist-server--output)) - (if (string-match "END-OF-COMPLETE$" output) - (let* ((string (apply #'concat (reverse alchemist-server--output))) - (string (replace-regexp-in-string "END-OF-COMPLETE$" "" string)) - (candidates (alchemist-complete--output-to-list - (alchemist--utils-clear-ansi-sequences string)))) - (funcall alchemist-server-help-callback candidates))))) - -(defun alchemist-server-help-complete-modules-filter (process output) - (with-local-quit - (setq alchemist-server--output (cons output alchemist-server--output)) - (if (string-match "END-OF-MODULES$" output) - (let* ((output (apply #'concat (reverse alchemist-server--output))) - (modules (alchemist-help--elixir-modules-to-list output)) - (search (completing-read - "Elixir help: " - modules - nil - nil - nil))) - (alchemist-help--execute (if (string-match-p "\\.$" search) - search - (concat search "."))))))) - -(defun alchemist-server-goto-filter (process output) - (setq alchemist-server--output (cons output alchemist-server--output)) - (if (string-match "END-OF-SOURCE$" output) - (let* ((output (apply #'concat (reverse alchemist-server--output))) - (output (replace-regexp-in-string "END-OF-SOURCE" "" output)) - (output (replace-regexp-in-string "\n" "" output)) - (file (replace-regexp-in-string "source-file-path:" "" output))) - (funcall alchemist-server-goto-callback file)))) - -(defun alchemist-server-goto (module function expr) - (setq alchemist-server--output nil) - (alchemist-server--start) - (setq alchemist-server-goto-callback (lambda (file) - (cond ((alchemist-utils--empty-string-p file) - (message "Don't know how to find: %s" expr)) - ((file-exists-p file) - (alchemist-goto--open-file file module function)) - ((alchemist-goto--elixir-file-p file) - (let* ((elixir-source-file (alchemist-goto--build-elixir-ex-core-file file))) - (if (file-exists-p elixir-source-file) - (alchemist-goto--open-file elixir-source-file module function) - (message "Don't know how to find: %s" expr)))) - ((alchemist-goto--erlang-file-p file) - (let* ((elixir-source-file (alchemist-goto--build-elixir-erl-core-file file)) - (erlang-source-file (alchemist-goto--build-erlang-core-file file))) - (cond ((file-exists-p elixir-source-file) - (alchemist-goto--open-file elixir-source-file module function)) - ((file-exists-p erlang-source-file) - (alchemist-goto--open-file erlang-source-file module function)) - (t - (message "Don't know how to find: %s" expr))))) - (t - (pop-tag-mark) - (message "Don't know how to find: %s" expr))))) - (set-process-filter (alchemist-server--process) #'alchemist-server-goto-filter) - (process-send-string (alchemist-server--process) (format "SOURCE %s,%s\n" module function))) - -(defun alchemist-server-help () - (setq alchemist-server--output nil) - (alchemist-server--start) - (set-process-filter (alchemist-server--process) #'alchemist-server-help-complete-modules-filter) - (process-send-string (alchemist-server--process) "MODULES\n")) - -(defun alchemist-server-eval (exp) - (setq alchemist-server--output nil) - (alchemist-server--start) - (setq alchemist-server-eval-callback (lambda (string) - (message "%s" string))) - (set-process-filter (alchemist-server--process) #'alchemist-server-eval-filter) - (process-send-string (alchemist-server--process) (format "EVAL %s\n" exp))) - -(defun alchemist-server-eval-and-insert (exp) - (setq alchemist-server--output nil) - (alchemist-server--start) - (setq alchemist-server-eval-callback (lambda (string) - (alchemist-eval--insert string))) - (set-process-filter (alchemist-server--process) #'alchemist-server-eval-filter) - (process-send-string (alchemist-server--process) (format "EVAL %s\n" exp))) - -(defun alchemist-server-eval-quote (exp) - (setq alchemist-server--output nil) - (alchemist-server--start) - (setq alchemist-server-eval-callback (lambda (string) - (message "%s" string))) - (set-process-filter (alchemist-server--process) #'alchemist-server-eval-quoted-filter) - (process-send-string (alchemist-server--process) (format "QUOTE %s\n" exp))) - -(defun alchemist-server-eval-quote-and-insert (exp) - (setq alchemist-server--output nil) - (alchemist-server--start) - (setq alchemist-server-eval-callback (lambda (string) - (alchemist-eval--insert string))) - (set-process-filter (alchemist-server--process) #'alchemist-server-eval-quoted-filter) - (process-send-string (alchemist-server--process) (format "QUOTE %s\n" exp))) - -(defun alchemist-server-complete-candidates (exp) - (setq alchemist-server--output nil) - (setq alchemist-server--last-completion-exp exp) - (alchemist-server--start) - (if (or (equal major-mode 'alchemist-iex-mode) - (not (alchemist-goto--context-exists-p))) - (alchemist-server--iex-complete exp) - (alchemist-server--complete-with-context exp))) - -(defun alchemist-server--complete-with-context (exp) - (let* ((module (alchemist-goto--current-module-name)) - (modules '()) - (aliases (mapcar (lambda (a) - (if (not (or (alchemist-utils--empty-string-p (replace-regexp-in-string "\\.$" "" (car (cdr a)))) - (string= (replace-regexp-in-string "\\.$" "" (car (cdr a))) - (replace-regexp-in-string "\\.$" "" (car a))))) - (format "{%s, %s}" - (if (alchemist-utils--empty-string-p (replace-regexp-in-string "\\.$" "" (car (cdr a)))) - (replace-regexp-in-string "\\.$" "" (car a)) - (replace-regexp-in-string "\\.$" "" (car (cdr a)))) - (replace-regexp-in-string "\\.$" "" (car a)) - ))) (alchemist-goto--alises-of-current-buffer))) - (use-modules (alchemist-goto--use-modules-in-the-current-module-context)) - (import-modules (alchemist-goto--import-modules-in-the-current-module-context))) - (if (not (alchemist-utils--empty-string-p module)) - (push module modules)) - (push use-modules modules) - (push import-modules modules) - (if (not modules) - (progn - (set-process-filter (alchemist-server--process) #'alchemist-server-complete-canidates-filter) - (process-send-string (alchemist-server--process) (format "COMPLETE %s\n" exp))) - (progn - (set-process-filter (alchemist-server--process) #'alchemist-server-complete-canidates-filter-with-context) - (process-send-string (alchemist-server--process) (format "COMPLETE-WITH-CONTEXT %s;[%s];%s\n" - exp - (mapconcat #'identity (alchemist-utils--flatten modules) ",") - (format "[%s]" (if (mapconcat #'identity aliases ",") - (mapconcat #'identity aliases ",") - "")))))))) - -(defun alchemist-server--iex-complete (exp) - (set-process-filter (alchemist-server--process) #'alchemist-server-complete-canidates-filter) - (process-send-string (alchemist-server--process) (format "COMPLETE %s\n" exp))) - -(defun alchemist-server-help-with-complete (search) - (setq alchemist-server--output nil) - (alchemist-server--start) - (setq alchemist-server-help-callback (lambda (candidates) - (if candidates - (let* ((search (alchemist-complete--completing-prompt search candidates))) - (alchemist-server-help-without-complete search)) - (message "No documentation found for '%s'" search)) - )) - (set-process-filter (alchemist-server--process) #'alchemist-server-complete-filter) - (process-send-string (alchemist-server--process) (format "COMPLETE %s\n" search))) - -(defun alchemist-server-help-without-complete (search) - (setq alchemist-help-current-search-text search) - (setq alchemist-server--output nil) - (alchemist-server--start) - (setq alchemist-server--output nil) - (set-process-filter (alchemist-server--process) #'alchemist-server-doc-filter) - (process-send-string (alchemist-server--process) (format "DOC %s\n" search))) - - -(provide 'alchemist-server) - -;;; alchemist-server.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-test-mode.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-test-mode.el deleted file mode 100644 index 0b04d18..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-test-mode.el +++ /dev/null @@ -1,169 +0,0 @@ -;;; alchemist-test-mode.el --- Minor mode for Elixir test files. - -;; Copyright © 2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;; Minor mode for Elixir test files. - -;;; Code: - -(defgroup alchemist-test-mode nil - "Minor mode for Elixir ExUnit files." - :prefix "alchemist-test-mode-" - :group 'alchemist) - -;; Variables - -(defvar alchemist-test-mode-buffer-name "*alchemist-test-report*" - "Name of the test report buffer.") - -(defcustom alchemist-test-mode-highlight-tests t - "Non-nil means that specific functions for testing will -be highlighted with more significant font faces." - :type 'boolean - :group 'alchemist-test-mode) - -(defvar alchemist-test-at-point #'alchemist-mix-test-at-point) -(defvar alchemist-test-this-buffer #'alchemist-mix-test-this-buffer) -(defvar alchemist-test #'alchemist-mix-test) -(defvar alchemist-test-file #'alchemist-mix-test-file) -(defvar alchemist-test-jump-to-previous-test #'alchemist-test-mode-jump-to-previous-test) -(defvar alchemist-test-jump-to-next-test #'alchemist-test-mode-jump-to-next-test) -(defvar alchemist-test-list-tests #'alchemist-test-mode-list-tests) - -(defvar alchemist-test-mode-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "C-c , s") alchemist-test-at-point) - (define-key map (kbd "C-c , v") alchemist-test-this-buffer) - (define-key map (kbd "C-c , a") alchemist-test) - (define-key map (kbd "C-c , f") alchemist-test-file) - (define-key map (kbd "C-c , p") alchemist-test-jump-to-previous-test) - (define-key map (kbd "C-c , n") alchemist-test-jump-to-next-test) - (define-key map (kbd "C-c , l") alchemist-test-list-tests) - map) - "Keymap for `alchemist-test-mode'.") - -(let ((whitespace-opt "[[:space:]]*") - (whitespace "[[:space:]]+")) - (setq alchemist-test-mode--test-regex - (concat - "\\(^" whitespace-opt "test" whitespace "\\(?10:.+\\)" whitespace "do" whitespace-opt "$" - "\\|" - whitespace " [0-9]+) test .+\\)"))) - -;; Private functions - -(defun alchemist-test-mode--buffer-contains-tests-p () - "Return nil if the current buffer contains no tests, non-nil if it does." - (save-excursion - (save-match-data - (beginning-of-buffer) - (re-search-forward alchemist-test-mode--test-regex nil t)))) - -(defun alchemist-test-mode--jump-to-test (search-fn reset-fn) - "Move the point to the next/previous test, based on `search-fn' (which is the -function that searches for the next test, can be re-search-forward or -re-search-backward) and `reset-fn' (which is used when wrapping at the -beginning/end of the buffer if no results were found)." - (when (alchemist-test-mode--buffer-contains-tests-p) - (save-match-data - (unless (funcall search-fn alchemist-test-mode--test-regex nil t) - (funcall reset-fn) - (funcall search-fn alchemist-test-mode--test-regex nil t)) - (back-to-indentation)))) - -(defun alchemist-test-mode--tests-in-buffer () - "Return an alist of tests in this buffer. - -The keys in the list are the test names (e.g., the string passed to the test/2 -macro) while the values are the position at which the test matched." - (save-match-data - (save-excursion - (beginning-of-buffer) - (let ((tests '())) - (while (re-search-forward alchemist-test-mode--test-regex nil t) - (let* ((position (car (match-data))) - (matched-string (match-string 10))) - (set-text-properties 0 (length matched-string) nil matched-string) - (add-to-list 'tests (cons matched-string position) t))) - tests)))) - -;; Public functions - -(defun alchemist-test-mode-jump-to-next-test () - "Jump to the next ExUnit test. If there are no tests after the current -position, jump to the first test in the buffer. Do nothing if there are no tests -in this buffer." - (interactive) - (alchemist-test-mode--jump-to-test 're-search-forward 'beginning-of-buffer)) - -(defun alchemist-test-mode-jump-to-previous-test () - "Jump to the previous ExUnit test. If there are no tests before the current -position, jump to the last test in the buffer. Do nothing if there are no tests -in this buffer." - (interactive) - (alchemist-test-mode--jump-to-test 're-search-backward 'end-of-buffer)) - -(defun alchemist-test-mode-list-tests () - "List ExUnit tests (calls to the test/2 macro) in the current buffer and jump -to the selected one." - (interactive) - (let* ((tests (alchemist-test-mode--tests-in-buffer)) - (selected (completing-read "Test: " tests)) - (position (cdr (assoc selected tests)))) - (goto-char position) - (back-to-indentation))) - -(defun alchemist-test-mode--highlight-syntax () - (if alchemist-test-mode-highlight-tests - (font-lock-add-keywords nil - '(("^\s+\\(test\\)\s+" 1 - font-lock-variable-name-face t) - ("^\s+\\(assert[_a-z]*\\|refute[_a-z]*\\)\s+" 1 - font-lock-type-face t) - ("^\s+\\(assert[_a-z]*\\|refute[_a-z]*\\)\(" 1 - font-lock-type-face t))))) - - -;;;###autoload -(define-minor-mode alchemist-test-mode - "Minor mode for Elixir ExUnit files. - -The following commands are available: - -\\{alchemist-test-mode-map}" - :lighter "" :keymap alchemist-test-mode-map - :group 'alchemist - (when alchemist-test-mode - (alchemist-test-mode--highlight-syntax))) - -;;;###autoload -(defun alchemist-test-enable-mode () - (if (alchemist-utils--is-test-file-p) - (alchemist-test-mode))) - -;;;###autoload -(dolist (hook '(alchemist-mode-hook)) - (add-hook hook 'alchemist-test-enable-mode)) - -(provide 'alchemist-test-mode) - -;;; alchemist-test-mode.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-utils.el b/emacs.d/elpa/alchemist-20150624.159/alchemist-utils.el deleted file mode 100644 index f45cebc..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist-utils.el +++ /dev/null @@ -1,94 +0,0 @@ -;;; alchemist-utils.el --- - -;; Copyright © 2014-2015 Samuel Tonini - -;; Author: Samuel Tonini . - -;;; Commentary: - -;;; Code: - -(require 'ansi-color) - -(defvar alchemist-utils--elixir-project-root-indicator - "mix.exs" - "The file which indicate an elixir project root.") - -(defun alchemist-utils--elixir-project-root () - "Finds the root directory of the project. -It walks the directory tree until it finds a elixir project root indicator." - (let* ((file (file-name-as-directory (expand-file-name default-directory)))) - (locate-dominating-file file alchemist-utils--elixir-project-root-indicator))) - -(defun alchemist-utils--flatten (alist) - (cond ((null alist) nil) - ((atom alist) (list alist)) - (t (append (alchemist-utils--flatten (car alist)) - (alchemist-utils--flatten (cdr alist)))))) - -(defun alchemist-utils--build-runner-cmdlist (command) - "Build the commands list for the runner." - (remove "" (alchemist-utils--flatten - (list (if (stringp command) - (split-string command) - command))))) - -(defun alchemist-utils--clear-search-text (search-text) - (let* ((search-text (replace-regexp-in-string "\\.$" "" search-text)) - (search-text (replace-regexp-in-string "^\\.$" "" search-text)) - (search-text (replace-regexp-in-string ",$" "" search-text)) - (search-text (replace-regexp-in-string "^,$" "" search-text))) - search-text)) - -(defun alchemist-utils--erase-buffer (buffer) - "Use `erase-buffer' inside BUFFER." - (with-current-buffer buffer - (erase-buffer))) - -(defun alchemist-utils--get-buffer-content (buffer) - "Return the content of BUFFER." - (with-current-buffer buffer - (buffer-substring (point-min) (point-max)))) - -(defun alchemist--utils-clear-ansi-sequences (string) - "Clear STRING from all ansi escape sequences." - (ansi-color-filter-apply string)) - -(defun alchemist-utils--remove-newline-at-end (string) - (replace-regexp-in-string "\n$" "" string)) - -(defun alchemist-utils--count-char-in-str (regexp str) - (loop with start = 0 - for count from 0 - while (string-match regexp str start) - do (setq start (match-end 0)) - finally return count)) - -(defun alchemist-utils--is-test-file-p () - "Check wether the visited file is a test file." - (string-match "_test\.exs$" (or (buffer-file-name) ""))) - -(defun alchemist-utils--empty-string-p (string) - (or (null string) - (let* ((string (replace-regexp-in-string "^\s+" "" string )) - (string (replace-regexp-in-string "\s+$" "" string))) - (string= string "")))) - -(provide 'alchemist-utils) - -;;; alchemist-utils.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist.el b/emacs.d/elpa/alchemist-20150624.159/alchemist.el deleted file mode 100644 index 811a4f2..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/alchemist.el +++ /dev/null @@ -1,224 +0,0 @@ -;;; alchemist.el --- Elixir tooling integration into Emacs - -;; Copyright © 2014-2015 Samuel Tonini -;; -;; Author: Samuel Tonini - -;; URL: http://www.github.com/tonini/alchemist.el -;; Version: 1.1.0 -;; Package-Requires: ((emacs "24")) -;; Keywords: languages, mix, elixir, elixirc, hex - -;; This file is not part of GNU Emacs. - -;; 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 . - -;;; Commentary: - -;; Alchemist integrate Elixir's tooling into Emacs - -;;; Code: - -(require 'easymenu) - -(defgroup alchemist nil - "Elixir Tooling Integration Into Emacs." - :prefix "alchemist-" - :group 'applications - :link '(url-link :tag "Github" "https://github.com/tonini/alchemist.el") - :link '(emacs-commentary-link :tag "Commentary" "alchemist")) - -(defcustom alchemist-key-command-prefix - (kbd "C-c a") - "The prefix for alchemist related key commands." - :type 'string - :group 'alchemist) - -(require 'alchemist-utils) -(require 'alchemist-project) -(require 'alchemist-server) -(require 'alchemist-buffer) -(require 'alchemist-compile) -(require 'alchemist-execute) -(require 'alchemist-mix) -(require 'alchemist-hooks) -(require 'alchemist-help) -(require 'alchemist-complete) -(require 'alchemist-message) -(require 'alchemist-iex) -(require 'alchemist-eval) -(require 'alchemist-goto) -(require 'alchemist-test-mode) - -(eval-after-load 'company - '(progn - (require 'alchemist-company))) - -(defun alchemist-mode-hook () - "Hook which enables `alchemist-mode'" - (alchemist-mode 1)) - -(defvar alchemist--version "1.1.0") - -;;;###autoload -(defun alchemist-version (&optional show-version) - "Display Alchemist's version." - (interactive) - (message "Alchemist %s" (replace-regexp-in-string "-cvs" "snapshot" alchemist--version))) - -(define-prefix-command 'alchemist-mode-keymap) - -;;;###autoload -(define-minor-mode alchemist-mode - "Toggle alchemist mode. - -Key bindings: -\\{alchemist-mode-map}" - nil - ;; The indicator for the mode line. - " alchemist" - :group 'alchemist - :global nil - :keymap `((,alchemist-key-command-prefix . alchemist-mode-keymap)) - (cond (alchemist-mode - (alchemist-buffer-initialize-modeline)) - (t - (alchemist-buffer-reset-modeline)))) - -(let ((map alchemist-mode-keymap)) - (define-key map (kbd "x") 'alchemist-mix) - (define-key map (kbd "t") 'alchemist-mix-test) - (define-key map (kbd "m c") 'alchemist-mix-compile) - (define-key map (kbd "m t f") 'alchemist-mix-test-file) - (define-key map (kbd "m t b") 'alchemist-mix-test-this-buffer) - (define-key map (kbd "m t .") 'alchemist-mix-test-at-point) - (define-key map (kbd "c c") 'alchemist-compile) - (define-key map (kbd "c f") 'alchemist-compile-file) - (define-key map (kbd "c b") 'alchemist-compile-this-buffer) - (define-key map (kbd "e e") 'alchemist-execute) - (define-key map (kbd "e f") 'alchemist-execute-file) - (define-key map (kbd "e b") 'alchemist-execute-this-buffer) - (define-key map (kbd "h h") 'alchemist-help) - (define-key map (kbd "h i") 'alchemist-help-history) - (define-key map (kbd "h e") 'alchemist-help-search-at-point) - (define-key map (kbd "h m") 'alchemist-help-search-marked-region) - (define-key map (kbd "p f") 'alchemist-project-find-test) - (define-key map (kbd "p s") 'alchemist-project-toggle-file-and-tests) - (define-key map (kbd "p o") 'alchemist-project-toggle-file-and-tests-other-window) - (define-key map (kbd "i i") 'alchemist-iex-run) - (define-key map (kbd "i p") 'alchemist-iex-project-run) - (define-key map (kbd "i l") 'alchemist-iex-send-current-line) - (define-key map (kbd "i c") 'alchemist-iex-send-current-line-and-go) - (define-key map (kbd "i r") 'alchemist-iex-send-region) - (define-key map (kbd "i m") 'alchemist-iex-send-region-and-go) - (define-key map (kbd "i b") 'alchemist-iex-compile-this-buffer) - (define-key map (kbd "v l") 'alchemist-eval-current-line) - (define-key map (kbd "v k") 'alchemist-eval-print-current-line) - (define-key map (kbd "v j") 'alchemist-eval-quoted-current-line) - (define-key map (kbd "v h") 'alchemist-eval-print-quoted-current-line) - (define-key map (kbd "v o") 'alchemist-eval-region) - (define-key map (kbd "v i") 'alchemist-eval-print-region) - (define-key map (kbd "v u") 'alchemist-eval-quoted-region) - (define-key map (kbd "v y") 'alchemist-eval-print-quoted-region) - (define-key map (kbd "v q") 'alchemist-eval-buffer) - (define-key map (kbd "v w") 'alchemist-eval-print-buffer) - (define-key map (kbd "v e") 'alchemist-eval-quoted-buffer) - (define-key map (kbd "v r") 'alchemist-eval-print-quoted-buffer)) - -(define-key alchemist-mode-map (kbd "M-.") 'alchemist-goto-definition-at-point) -(define-key alchemist-mode-map (kbd "M-,") 'alchemist-goto-jump-back) -(define-key alchemist-mode-map (kbd "C-c , .") 'alchemist-goto-list-symbol-definitions) - -(easy-menu-define alchemist-mode-menu alchemist-mode-map - "Alchemist mode menu." - '("Alchemist" - ("Goto" - ["Jump to definiton at point" alchemist-goto-definition-at-point] - ["Jump back" alchemist-goto-jump-back]) - ("Evaluate" - ["Evaluate current line" alchemist-eval-current-line] - ["Evaluate current line and print" alchemist-eval-print-current-line] - ["Evaluate quoted current line" alchemist-eval-quoted-current-line] - ["Evaluate quoted current line and print" alchemist-eval-print-quoted-current-line] - "---" - ["Evaluate region" alchemist-eval-region] - ["Evaluate region and print" alchemist-eval-print-region] - ["Evaluate quoted region" alchemist-eval-quoted-region] - ["Evaluate quoted region and print" alchemist-eval-print-quoted-region] - "---" - ["Evaluate buffer" alchemist-eval-buffer] - ["Evaluate buffer and print" alchemist-eval-print-buffer] - ["Evaluate quoted buffer" alchemist-eval-quoted-buffer] - ["Evaluate quoted buffer and print" alchemist-eval-print-quoted-buffer]) - ("Compile" - ["Compile..." alchemist-compile] - ["Compile this buffer" alchemist-compile-this-buffer] - ["Compile file" alchemist-compile-file]) - ("Execute" - ["Execute..." alchemist-compile] - ["Execute this buffer" alchemist-execute-this-buffer] - ["Execute file" alchemist-execute-file]) - ("Mix" - ["Mix deps..." alchemist-mix-deps-with-prompt] - ["Mix compile..." alchemist-mix-compile] - ["Mix run..." alchemist-mix-run] - "---" - ["Mix test this buffer" alchemist-mix-test-this-buffer] - ["Mix test file..." alchemist-mix-test-file] - ["Mix test at point" alchemist-mix-test-at-point] - "---" - ["Mix..." alchemist-mix] - ["Mix new..." alchemist-mix-new] - ["Mix hex search..." alchemist-mix-hex-search] - "---" - ["Mix local..." alchemist-mix-local-with-prompt] - ["Mix local install..." alchemist-mix-local-install] - ["Mix local install (Path)..." alchemist-mix-local-install-with-path] - ["Mix local install (URL)..." alchemist-mix-local-install-with-url] - "---" - ["Display mix buffer" alchemist-mix-display-mix-buffer] - "---" - ["Mix help..." alchemist-mix-help]) - ("IEx" - ["IEx send current line" alchemist-iex-send-current-line] - ["IEx send current line and go" alchemist-iex-send-current-line-and-go] - "---" - ["IEx send last region" alchemist-iex-send-last-sexp] - ["IEx send region" alchemist-iex-send-region] - ["IEx send region and go" alchemist-iex-send-region-and-go] - "---" - ["IEx compile this buffer" alchemist-iex-compile-this-buffer] - ["IEx recompile this buffer" alchemist-iex-recompile-this-buffer] - "---" - ["IEx run" alchemist-iex-run]) - ("Project" - ["Project find all tests" alchemist-project-find-test] - ["Project toggle between file and test" alchemist-project-toggle-file-and-tests] - ["Project toggle between file and test in other window" alchemist-project-toggle-file-and-tests-other-window] - "---" - ["Project toggle compile when needed" alchemist-project-toggle-compile-when-needed - :style toggle :selected alchemist-project-compile-when-needed]) - ("Documentation" - ["Documentation search..." alchemist-help] - ["Documentation search history..." alchemist-help-history] - "---" - ["Documentation search at point..." alchemist-help-search-at-point] - ["Documentation search marked region..." alchemist-help-search-marked-region]) - )) - -(add-hook 'elixir-mode-hook 'alchemist-mode-hook) - -(provide 'alchemist) - -;;; alchemist.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/server/case.exs b/emacs.d/elpa/alchemist-20150624.159/server/case.exs deleted file mode 100644 index 3131346..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/server/case.exs +++ /dev/null @@ -1,96 +0,0 @@ -defmodule Alchemist.Case do - - alias Alchemist.Completer - alias Alchemist.Utils - alias Alchemist.Informant - - defmodule Complete do - def process! do - :ets.insert(:alchemist, {"aliases", []}) - Completer.run('') - |> Enum.map &IO.puts('cmp:' ++ &1) - print_end_of_complete_signal - end - - def process!(hint) do - :ets.insert(:alchemist, {"aliases", []}) - Completer.run(hint) - |> Enum.map &IO.puts('cmp:' ++ &1) - print_end_of_complete_signal - end - - defp print_end_of_complete_signal do - IO.puts "END-OF-COMPLETE" - end - - def process_with_context!(hint) do - [hint, modules, aliases] = String.split(hint, ";", parts: 3) - modules = Utils.clear_context_list(modules) - {modules, _} = Code.eval_string(modules) - {aliases, _} = Code.eval_string(aliases) - :ets.insert(:alchemist, {"aliases", aliases}) - - Completer.run(hint) - |> Enum.map &IO.puts('cmp:' ++ &1) - Enum.each modules, fn(module) -> - Informant.get_functions(module, hint) - |> Enum.map &IO.puts('cmp:' ++ &1) - end - IO.puts "END-OF-COMPLETE-WITH-CONTEXT" - end - end - - defmodule Modules do - def process! do - Informant.get_modules |> Enum.map &IO.puts/1 - IO.puts "END-OF-MODULES" - end - end - - defmodule Doc do - def process!(exp) do - Code.eval_string("import IEx.Helpers \nApplication.put_env(:iex, :colors, [enabled: true])\nh(#{exp})", [], __ENV__) - IO.puts "END-OF-DOC" - end - end - - defmodule Eval do - def process!(file) do - try do - File.read!("#{file}") - |> Code.eval_string - |> Tuple.to_list - |> List.first - |> IO.inspect - rescue - e -> IO.inspect e - end - IO.puts "END-OF-EVAL" - end - end - - defmodule Quote do - def process!(file) do - try do - File.read!("#{file}") - |> Code.string_to_quoted - |> Tuple.to_list - |> List.last - |> IO.inspect - rescue - e -> IO.inspect e - end - IO.puts "END-OF-QUOTE" - end - end - - defmodule Find do - def process!(exp) do - [module, function] = String.split(exp, ",", parts: 2) - module = String.to_char_list module - function = String.to_atom function - Code.eval_string("Alchemist.Source.find(#{module}, :#{function})", [], __ENV__) - IO.puts "END-OF-SOURCE" - end - end -end diff --git a/emacs.d/elpa/alchemist-20150624.159/server/completer.exs b/emacs.d/elpa/alchemist-20150624.159/server/completer.exs deleted file mode 100644 index 2e94a66..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/server/completer.exs +++ /dev/null @@ -1,340 +0,0 @@ -defmodule Alchemist.Completer do - @moduledoc false - - def run(exp) do - code = case is_bitstring(exp) do - true -> exp |> String.to_char_list - _ -> exp - end - - {status, result, list } = expand(code |> Enum.reverse) - - case { status, result, list } do - { :no, _, _ } -> '' - { :yes, [], _ } -> List.insert_at(list, 0, exp) - { :yes, _, _ } -> run(code ++ result) - end - end - - def expand('') do - expand_import("") - end - - def expand([h|t]=expr) do - cond do - h === ?. and t != []-> - expand_dot(reduce(t)) - h === ?: -> - expand_erlang_modules() - identifier?(h) -> - expand_expr(reduce(expr)) - (h == ?/) and t != [] and identifier?(hd(t)) -> - expand_expr(reduce(t)) - h in '([{' -> - expand('') - true -> - no() - end - end - - defp identifier?(h) do - (h in ?a..?z) or (h in ?A..?Z) or (h in ?0..?9) or h in [?_, ??, ?!] - end - - defp expand_dot(expr) do - case Code.string_to_quoted expr do - {:ok, atom} when is_atom(atom) -> - expand_call(atom, "") - {:ok, {:__aliases__, _, list}} -> - expand_elixir_modules(list, "") - _ -> - no() - end - end - - defp expand_expr(expr) do - case Code.string_to_quoted expr do - {:ok, atom} when is_atom(atom) -> - expand_erlang_modules(Atom.to_string(atom)) - {:ok, {atom, _, nil}} when is_atom(atom) -> - expand_import(Atom.to_string(atom)) - {:ok, {:__aliases__, _, [root]}} -> - expand_elixir_modules([], Atom.to_string(root)) - {:ok, {:__aliases__, _, [h|_] = list}} when is_atom(h) -> - hint = Atom.to_string(List.last(list)) - list = Enum.take(list, length(list) - 1) - expand_elixir_modules(list, hint) - {:ok, {{:., _, [mod, fun]}, _, []}} when is_atom(fun) -> - expand_call(mod, Atom.to_string(fun)) - _ -> - no() - end - end - - defp reduce(expr) do - Enum.reverse Enum.reduce ' ([{', expr, fn token, acc -> - hd(:string.tokens(acc, [token])) - end - end - - defp yes(hint, entries) do - {:yes, String.to_char_list(hint), Enum.map(entries, &String.to_char_list/1)} - end - - defp no do - {:no, '', []} - end - - ## Formatting - - defp format_expansion([], _) do - no() - end - - defp format_expansion([uniq], hint) do - case to_hint(uniq, hint) do - "" -> yes("", to_uniq_entries(uniq)) - hint -> yes(hint, []) - end - end - - defp format_expansion([first|_]=entries, hint) do - binary = Enum.map(entries, &(&1.name)) - length = byte_size(hint) - prefix = :binary.longest_common_prefix(binary) - if prefix in [0, length] do - yes("", Enum.flat_map(entries, &to_entries/1)) - else - yes(:binary.part(first.name, prefix, length-prefix), []) - end - end - - ## Expand calls - - # :atom.fun - defp expand_call(mod, hint) when is_atom(mod) do - expand_require(mod, hint) - end - - # Elixir.fun - defp expand_call({:__aliases__, _, list}, hint) do - expand_alias(list) - |> normalize_module - |> expand_require(hint) - end - - defp expand_call(_, _) do - no() - end - - defp expand_require(mod, hint) do - format_expansion match_module_funs(mod, hint), hint - end - - defp expand_import(hint) do - funs = match_module_funs(IEx.Helpers, hint) ++ - match_module_funs(Kernel, hint) ++ - match_module_funs(Kernel.SpecialForms, hint) - format_expansion funs, hint - end - - ## Erlang modules - - defp expand_erlang_modules(hint \\ "") do - format_expansion match_erlang_modules(hint), hint - end - - defp match_erlang_modules(hint) do - for mod <- match_modules(hint, true) do - %{kind: :module, name: mod, type: :erlang} - end - end - - ## Elixir modules - - defp expand_elixir_modules([], hint) do - expand_elixir_modules(Elixir, hint, match_aliases(hint)) - end - - defp expand_elixir_modules(list, hint) do - expand_alias(list) - |> normalize_module - |> expand_elixir_modules(hint, []) - end - - defp expand_elixir_modules(mod, hint, aliases) do - aliases - |> Kernel.++(match_elixir_modules(mod, hint)) - |> Kernel.++(match_module_funs(mod, hint)) - |> format_expansion(hint) - end - - defp expand_alias([name | rest] = list) do - module = Module.concat(Elixir, name) - Enum.find_value env_aliases(), list, fn {alias, mod} -> - if alias === module do - case Atom.to_string(mod) do - "Elixir." <> mod -> - Module.concat [mod|rest] - _ -> - mod - end - end - end - end - - defp env_aliases() do - :ets.lookup(:alchemist, "aliases") - |> format_ets_aliases - end - - defp format_ets_aliases([{"aliases", []}]) do - [] - end - - defp format_ets_aliases(list) do - list - |> List.first - |> Tuple.to_list - |> List.last - end - - defp match_aliases(hint) do - for {alias, _mod} <- env_aliases(), - [name] = Module.split(alias), - starts_with?(name, hint) do - %{kind: :module, type: :alias, name: name} - end - end - - defp match_elixir_modules(module, hint) do - name = Atom.to_string(module) - depth = length(String.split(name, ".")) + 1 - base = name <> "." <> hint - - for mod <- match_modules(base, module === Elixir), - parts = String.split(mod, "."), - depth <= length(parts) do - %{kind: :module, type: :elixir, name: Enum.at(parts, depth-1)} - end - |> Enum.uniq - end - - ## Helpers - - defp normalize_module(mod) do - if is_list(mod) do - Module.concat(mod) - else - mod - end - end - - defp match_modules(hint, root) do - get_modules(root) - |> :lists.usort() - |> Enum.drop_while(& not starts_with?(&1, hint)) - |> Enum.take_while(& starts_with?(&1, hint)) - end - - defp get_modules(true) do - ["Elixir.Elixir"] ++ get_modules(false) - end - - defp get_modules(false) do - modules = Enum.map(:code.all_loaded(), &Atom.to_string(elem(&1, 0))) - case :code.get_mode() do - :interactive -> modules ++ get_modules_from_applications() - _otherwise -> modules - end - end - - defp get_modules_from_applications do - for [app] <- loaded_applications(), - {:ok, modules} = :application.get_key(app, :modules), - module <- modules do - Atom.to_string(module) - end - end - - defp loaded_applications do - # If we invoke :application.loaded_applications/0, - # it can error if we don't call safe_fixtable before. - # Since in both cases we are reaching over the - # application controller internals, we choose to match - # for performance. - :ets.match(:ac_tab, {{:loaded, :"$1"}, :_}) - end - - defp match_module_funs(mod, hint) do - case ensure_loaded(mod) do - {:module, _} -> - falist = get_module_funs(mod) - - list = Enum.reduce falist, [], fn {f, a}, acc -> - case :lists.keyfind(f, 1, acc) do - {f, aa} -> :lists.keyreplace(f, 1, acc, {f, [a|aa]}) - false -> [{f, [a]}|acc] - end - end - - for {fun, arities} <- list, - name = Atom.to_string(fun), - starts_with?(name, hint) do - %{kind: :function, name: name, arities: arities} - end |> :lists.sort() - - _otherwise -> [] - end - end - - defp get_module_funs(mod) do - if function_exported?(mod, :__info__, 1) do - if docs = Code.get_docs(mod, :docs) do - for {tuple, _line, _kind, _sign, doc} <- docs, doc != false, do: tuple - else - mod.__info__(:macros) ++ (mod.__info__(:functions) -- [__info__: 1]) - end - else - mod.module_info(:exports) - end - end - - defp ensure_loaded(Elixir), do: {:error, :nofile} - defp ensure_loaded(mod), - do: Code.ensure_compiled(mod) - - defp starts_with?(_string, ""), do: true - defp starts_with?(string, hint), do: String.starts_with?(string, hint) - - ## Ad-hoc conversions - - defp to_entries(%{kind: :module, name: name}) do - [name] - end - - defp to_entries(%{kind: :function, name: name, arities: arities}) do - for a <- :lists.sort(arities), do: "#{name}/#{a}" - end - - defp to_uniq_entries(%{kind: :module}) do - [] - end - - defp to_uniq_entries(%{kind: :function} = fun) do - to_entries(fun) - end - - defp to_hint(%{kind: :module, name: name}, hint) do - format_hint(name, hint) <> "." - end - - defp to_hint(%{kind: :function, name: name}, hint) do - format_hint(name, hint) - end - - defp format_hint(name, hint) do - hint_size = byte_size(hint) - :binary.part(name, hint_size, byte_size(name) - hint_size) - end -end diff --git a/emacs.d/elpa/alchemist-20150624.159/server/informant.exs b/emacs.d/elpa/alchemist-20150624.159/server/informant.exs deleted file mode 100644 index f32f18d..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/server/informant.exs +++ /dev/null @@ -1,55 +0,0 @@ -defmodule Alchemist.Informant do - def get_functions(mod, hint) do - {mod, _} = Code.eval_string(mod) - falist = get_module_funs(mod) - - list = Enum.reduce falist, [], fn({f, a}, acc) -> - case :lists.keyfind(f, 1, acc) do - {f, aa} -> :lists.keyreplace(f, 1, acc, {f, [a|aa]}) - false -> [{f, [a]}|acc] - end - end - - case hint do - "" -> - for {fun, arities} <- list, - name = Atom.to_string(fun) do - "#{name}/#{List.first(arities)}" - end |> :lists.sort() - _otherwise -> - for {fun, arities} <- list, - name = Atom.to_string(fun), - String.starts_with?(name, hint) do - "#{name}/#{List.first(arities)}" - end |> :lists.sort() - end - end - - defp get_module_funs(mod) do - case Code.ensure_loaded(mod) do - {:module, _} -> - mod.module_info(:functions) ++ mod.__info__(:macros) - _otherwise -> - [] - end - end - - def get_modules do - modules = Enum.map(:code.all_loaded, fn({m, _}) -> Atom.to_string(m) end) - - if :code.get_mode() === :interactive do - modules ++ get_modules_from_applications() - else - modules - end - end - - defp get_modules_from_applications do - for {app, _, _} <- :application.loaded_applications, - {_, modules} = :application.get_key(app, :modules), - module <- modules, - has_doc = Code.get_docs(module, :moduledoc), elem(has_doc, 1) do - Atom.to_string(module) - end - end -end diff --git a/emacs.d/elpa/alchemist-20150624.159/server/server.exs b/emacs.d/elpa/alchemist-20150624.159/server/server.exs deleted file mode 100644 index 098ec99..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/server/server.exs +++ /dev/null @@ -1,92 +0,0 @@ -Code.require_file "utils.exs", __DIR__ -Code.require_file "completer.exs", __DIR__ -Code.require_file "informant.exs", __DIR__ -Code.require_file "source.exs", __DIR__ -Code.require_file "case.exs", __DIR__ - -defmodule Alchemist.Server do - - alias Alchemist.Case - - def start([env]) do - # Preload Enum so we load basic Elixir/Erlang code - IEx.Autocomplete.expand('.munE') - :ets.new(:alchemist, [:named_table]) - loop(all_loaded(), env) - end - - def loop(loaded, env) do - line = IO.gets("") |> String.rstrip() - paths = load_paths(env) - apps = load_apps(env) - - read_input(line) - - purge_modules(loaded) - purge_paths(paths) - purge_apps(apps) - - :ets.delete_all_objects(:alchemist) - - loop(loaded, env) - end - - def read_input(line) do - case line |> String.split(" ", parts: 2) do - ["COMPLETE"] -> - Case.Complete.process! - ["COMPLETE", hint] -> - Case.Complete.process!(hint) - ["COMPLETE-WITH-CONTEXT", hint] -> - Case.Complete.process_with_context!(hint) - ["DOC", exp] -> - Case.Doc.process!(exp) - ["MODULES"] -> - Case.Modules.process! - ["EVAL", exp] -> - Case.Eval.process!(exp) - ["QUOTE", file] -> - Case.Quote.process!(file) - ["SOURCE", exp] -> - Case.Find.process!(exp) - _ -> - nil - end - end - - defp all_loaded() do - for {m,_} <- :code.all_loaded, do: m - end - - defp load_paths(env) do - for path <- Path.wildcard("_build/#{env}/lib/*/ebin") do - Code.prepend_path(path) - path - end - end - - defp load_apps(env) do - for path <- Path.wildcard("_build/#{env}/lib/*/ebin/*.app") do - app = path |> Path.basename() |> Path.rootname() |> String.to_atom - Application.load(app) - app - end - end - - defp purge_modules(loaded) do - for m <- (all_loaded() -- loaded) do - :code.delete(m) - :code.purge(m) - end - end - - defp purge_paths(paths) do - for p <- paths, do: Code.delete_path(p) - end - - defp purge_apps(apps) do - for a <- apps, do: Application.unload(a) - end -end - -Alchemist.Server.start([System.argv]) diff --git a/emacs.d/elpa/alchemist-20150624.159/server/source.exs b/emacs.d/elpa/alchemist-20150624.159/server/source.exs deleted file mode 100644 index 5ec5c1c..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/server/source.exs +++ /dev/null @@ -1,46 +0,0 @@ -defmodule Alchemist.Source do - def find(nil, function) do - cond do - List.keymember?(get_module_funs(Kernel), function, 0) -> - IO.puts source(Kernel) - List.keymember?(get_module_funs(Kernel.SpecialForms), function, 0) -> - IO.puts source(Kernel.SpecialForms) - true -> - IO.puts "" - end - end - - def find(module, function) do - cond do - Code.ensure_loaded?(module) -> - IO.puts source(module) - List.keymember?(Kernel.module_info[:exports], function, 0) -> - IO.puts source(Kernel) - List.keymember?(Kernel.SpecialForms.module_info[:exports], function, 0) -> - IO.puts source(Kernel.SpecialForms) - true -> - IO.puts "" - end - end - - defp source(module) do - source = module.module_info(:compile)[:source] - - case source do - nil -> nil - source -> "source-file-path:" <> List.to_string(source) - end - end - - defp get_module_funs(mod) do - if function_exported?(mod, :__info__, 1) do - if docs = Code.get_docs(mod, :docs) do - for {tuple, _line, _kind, _sign, doc} <- docs, doc != false, do: tuple - else - (mod.__info__(:functions) -- [__info__: 1]) ++ mod.__info__(:macros) - end - else - mod.module_info(:exports) - end - end -end diff --git a/emacs.d/elpa/alchemist-20150624.159/server/utils.exs b/emacs.d/elpa/alchemist-20150624.159/server/utils.exs deleted file mode 100644 index 3165e79..0000000 --- a/emacs.d/elpa/alchemist-20150624.159/server/utils.exs +++ /dev/null @@ -1,6 +0,0 @@ -defmodule Alchemist.Utils do - def clear_context_list(modules) do - cleared = Regex.replace ~r/\.\]/, modules, "]" - Regex.replace ~r/\.\,/, cleared, "," - end -end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-autoloads.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-autoloads.el new file mode 100644 index 0000000..8235240 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-autoloads.el @@ -0,0 +1,116 @@ +;;; alchemist-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) + +;;;### (autoloads nil "alchemist" "alchemist.el" (22171 46586 0 0)) +;;; Generated autoloads from alchemist.el + +(autoload 'alchemist-mode "alchemist" "\ +Toggle alchemist mode. + +Key bindings: +\\{alchemist-mode-map} + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads nil "alchemist-iex" "alchemist-iex.el" (22171 46586 +;;;;;; 0 0)) +;;; Generated autoloads from alchemist-iex.el + +(defalias 'run-elixir 'alchemist-iex-run) + +(autoload 'alchemist-iex-run "alchemist-iex" "\ +Start an IEx process. +Show the IEx buffer if an IEx process is already run. + +\(fn &optional ARG)" t nil) + +(autoload 'alchemist-iex-project-run "alchemist-iex" "\ +Start an IEx process with mix 'iex -S mix' in the +context of an Elixir project. +Show the IEx buffer if an IEx process is already run. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil "alchemist-phoenix" "alchemist-phoenix.el" +;;;;;; (22171 46586 0 0)) +;;; Generated autoloads from alchemist-phoenix.el + +(autoload 'alchemist-phoenix-project-p "alchemist-phoenix" "\ +Return non-nil if `default-directory' is inside an Phoenix project. + +\(fn)" nil nil) + +(autoload 'alchemist-phoenix-mode "alchemist-phoenix" "\ +Minor mode for Elixir Phoenix web framework projects. + +The following commands are available: + +\\{alchemist-phoenix-mode-map} + +\(fn &optional ARG)" t nil) + +(autoload 'alchemist-phoenix-enable-mode "alchemist-phoenix" "\ + + +\(fn)" nil nil) + +(dolist (hook '(alchemist-mode-hook)) (add-hook hook 'alchemist-phoenix-enable-mode)) + +;;;*** + +;;;### (autoloads nil "alchemist-refcard" "alchemist-refcard.el" +;;;;;; (22171 46586 0 0)) +;;; Generated autoloads from alchemist-refcard.el + +(autoload 'alchemist-refcard "alchemist-refcard" "\ +Generate an Alchemist refcard of all the features. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil "alchemist-test-mode" "alchemist-test-mode.el" +;;;;;; (22171 46586 0 0)) +;;; Generated autoloads from alchemist-test-mode.el + +(autoload 'alchemist-test-mode "alchemist-test-mode" "\ +Minor mode for Elixir ExUnit files. + +The following commands are available: + +\\{alchemist-test-mode-map} + +\(fn &optional ARG)" t nil) + +(autoload 'alchemist-test-enable-mode "alchemist-test-mode" "\ + + +\(fn)" nil nil) + +(dolist (hook '(alchemist-mode-hook)) (add-hook hook 'alchemist-test-enable-mode)) + +;;;*** + +;;;### (autoloads nil nil ("alchemist-company.el" "alchemist-compile.el" +;;;;;; "alchemist-complete.el" "alchemist-eval.el" "alchemist-execute.el" +;;;;;; "alchemist-file.el" "alchemist-goto.el" "alchemist-help.el" +;;;;;; "alchemist-hooks.el" "alchemist-info.el" "alchemist-interact.el" +;;;;;; "alchemist-key.el" "alchemist-macroexpand.el" "alchemist-message.el" +;;;;;; "alchemist-mix.el" "alchemist-pkg.el" "alchemist-project.el" +;;;;;; "alchemist-report.el" "alchemist-scope.el" "alchemist-server.el" +;;;;;; "alchemist-utils.el") (22171 46586 526902 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; alchemist-autoloads.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-company.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-company.el new file mode 100644 index 0000000..113f33d --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-company.el @@ -0,0 +1,146 @@ +;;; alchemist-company.el --- Elixir company-mode backend -*- lexical-binding: t -*- + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Elixir company-mode backend. + +;;; Code: + +(require 'cl-lib) +(require 'company) +(require 'alchemist-help) +(require 'alchemist-goto) +(require 'alchemist-scope) +(require 'alchemist-server) +(require 'alchemist-complete) + +(defgroup alchemist-company nil + "Elixir company-mode backend." + :prefix "alchemist-company-" + :group 'alchemist) + +;; Variables + +(defcustom alchemist-company-show-annotation t + "Show an annotation inline with the candidate." + :type 'boolean + :group 'alchemist-company) + +(defvar alchemist-company-callback nil) +(defvar alchemist-company-filter-output nil) +(defvar alchemist-company-last-completion nil) +(defvar alchemist-company-doc-lookup-done nil) + +(defun alchemist-company--wait-for-doc-buffer () + (while (not alchemist-company-doc-lookup-done) + (sit-for 0.01))) + +(defun alchemist-company-show-documentation (candidate) + (interactive) + (let* ((annotation (alchemist-company--annotation candidate)) + (candidate (if annotation + (format "%s%s" candidate annotation) + candidate)) + (candidate (alchemist-help--prepare-search-expr candidate))) + (setq alchemist-company-doc-lookup-done nil) + (alchemist-server-help (alchemist-help--server-arguments candidate) #'alchemist-company-doc-buffer-filter) + (alchemist-company--wait-for-doc-buffer) + (get-buffer alchemist-help-buffer-name))) + +(defun alchemist-company-open-definition (candidate) + (interactive) + (alchemist-goto--open-definition candidate)) + +(defun alchemist-company--annotation (candidate) + (get-text-property 0 'meta candidate)) + +(defun alchemist-company-build-scope-arg (arg) + "Build informations about the current context." + (let* ((modules (alchemist-utils-prepare-modules-for-elixir + (alchemist-scope-all-modules))) + (aliases (alchemist-utils-prepare-aliases-for-elixir + (alchemist-scope-aliases)))) + (format "{ \"%s\", [ context: Elixir, imports: %s, aliases: %s ] }" arg modules aliases))) + +(defun alchemist-company-build-server-arg (arg) + (if (not (equal major-mode 'alchemist-iex-mode)) + (alchemist-company-build-scope-arg arg) + (format "{ \"%s\", [ context: [], imports: [], aliases: [] ] }" arg))) + +(defun alchemist-company-filter (_process output) + (setq alchemist-company-filter-output (cons output alchemist-company-filter-output)) + (if (alchemist-server-contains-end-marker-p output) + (let* ((candidates (alchemist-complete--build-candidates-from-process-output alchemist-company-filter-output))) + (setq alchemist-company-filter-output nil) + (alchemist-company-serve-candidates-to-callback (-distinct candidates))))) + +(defun alchemist-company-doc-buffer-filter (_process output) + (setq alchemist-company-filter-output (cons output alchemist-company-filter-output)) + (if (alchemist-server-contains-end-marker-p output) + (let ((string (alchemist-server-prepare-filter-output alchemist-company-filter-output))) + (setq alchemist-company-filter-output nil) + (if (get-buffer alchemist-help-buffer-name) + (kill-buffer alchemist-help-buffer-name)) + (with-current-buffer (get-buffer-create alchemist-help-buffer-name) + (insert string) + (ansi-color-apply-on-region (point-min) (point-max)) + (alchemist-help-minor-mode 1)) + (setq alchemist-company-doc-lookup-done t)))) + +(defun alchemist-company-serve-candidates-to-callback (candidates) + (let* ((candidates (if candidates + candidates + (alchemsit-complete--dabbrev-code-candidates))) + (candidates (if (eq (length candidates) 1) + (-insert-at 0 company-prefix candidates) + candidates)) + (candidates (-distinct candidates))) + (funcall alchemist-company-callback candidates))) + +(defun alchemist-company (command &optional arg &rest ignored) + "`company-mode' completion back-end for Elixir." + (interactive (list 'interactive)) + (when alchemist-company-show-annotation + (set 'company-tooltip-align-annotations t)) + (cl-case command + (interactive (company-begin-backend 'alchemist-company)) + (init (or (eq major-mode 'elixir-mode) + (string= mode-name "Alchemist-IEx"))) + (prefix (and (or (eq major-mode 'elixir-mode) + (string= mode-name "Alchemist-IEx")) + (alchemist-scope-expression))) + (doc-buffer (alchemist-company-show-documentation arg)) + (location (alchemist-company-open-definition arg)) + (candidates (cons :async + (lambda (cb) + (setq alchemist-company-last-completion arg) + (setq alchemist-company-callback cb) + (alchemist-server-complete-candidates (alchemist-company-build-server-arg arg) + #'alchemist-company-filter)))) + (annotation (when alchemist-company-show-annotation + (alchemist-company--annotation arg))))) + +(add-to-list 'company-backends 'alchemist-company) + +(provide 'alchemist-company) + +;;; alchemist-company.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-compile.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-compile.el new file mode 100644 index 0000000..6d7bdc9 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-compile.el @@ -0,0 +1,89 @@ +;;; alchemist-compile.el --- Elixir compilation functionality + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Elixir compilation functionality. + +;;; Code: + +(require 'alchemist-utils) +(require 'alchemist-report) + +(defgroup alchemist-compile nil + "Elixir compilation functionality." + :prefix "alchemist-compile-" + :group 'alchemist) + +;; Variables + +(defcustom alchemist-compile-command "elixirc" + "The shell command for elixirc." + :type 'string + :group 'alchemist-compile) + +(defvar alchemist-compile-buffer-name "*alchemist elixirc*" + "Name of the elixir output buffer.") + +(defvar alchemist-compile-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "q" #'quit-window) + map)) + +;; Private functions + +(defun alchemist-compile--file (filename) + (cond ((not (file-exists-p filename)) (error "The given file doesn't exist")) + ((string-match "\.exs$" filename) (error "The given file is an Elixir Script")) + (t (alchemist-compile (list alchemist-compile-command (expand-file-name filename)))))) + +(defun alchemist-compile--read-command (command) + (read-shell-command "elixirc command: " (concat command " "))) + +;; Public functions + +(defun alchemist-compile-this-buffer () + "Compile the current buffer with elixirc." + (interactive) + (alchemist-compile--file buffer-file-name)) + +(defun alchemist-compile-file (filename) + "Compile the given FILENAME." + (interactive "Felixirc: ") + (alchemist-compile--file (expand-file-name filename))) + +(define-derived-mode alchemist-compile-mode fundamental-mode "Elixir Compile Mode" + "Major mode for compiling Elixir files. + +\\{alchemist-compile-mode-map}" + (setq buffer-read-only t) + (setq-local truncate-lines t) + (setq-local electric-indent-chars nil)) + +(defun alchemist-compile (cmdlist) + "Compile CMDLIST with elixirc." + (interactive (list (alchemist-compile--read-command alchemist-compile-command))) + (let ((command (alchemist-utils-build-command cmdlist))) + (alchemist-report-run command "alchemist-compile-report" alchemist-compile-buffer-name 'alchemist-compile-mode))) + +(provide 'alchemist-compile) + +;;; alchemist-compile.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-complete.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-complete.el new file mode 100644 index 0000000..053ef16 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-complete.el @@ -0,0 +1,142 @@ +;;; alchemist-complete.el --- Complete functionality for Elixir source code -*- lexical-binding: t -*- + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Complete functionality for Elixir and Erlang source code. + +;;; Code: + +(require 'cl-lib) +(require 'dash) +(require 'ansi-color) +(require 'company-dabbrev-code) +(require 'alchemist-utils) + +(defgroup alchemist-complete nil + "Complete functionality for Elixir source code." + :prefix "alchemist-complete-" + :group 'alchemist) + +(defvar alchemist-company-last-completion nil) + +(defun alchemist-complete--concat-prefix-with-functions (prefix functions &optional add-prefix) + (let* ((prefix (mapconcat 'concat (butlast (split-string prefix "\\.") 1) ".")) + (candidates (-map (lambda (c) (concat prefix "." c)) (cdr functions)))) + (if add-prefix + (push prefix candidates) + candidates))) + +(defun alchemist-complete--add-prefix-to-function (prefix function) + (let* ((prefix (mapconcat 'concat (butlast (split-string prefix "\\.") 1) ".")) + (candidate (concat prefix "." function))) + candidate)) + +(defun alchemist-complete--build-candidates (a-list) + (let* ((search-term (car a-list)) + (candidates a-list) + (candidates (-map (lambda (f) + (let* ((candidate f) + (meta (if (string-match-p "^.+/" f) + (replace-regexp-in-string "^.+/" "/" f) + ""))) + (cond + ((and (string-match-p "^:" search-term) + (not (string-match-p "\\." search-term))) + (unless (string= search-term candidate) + (propertize (concat ":" candidate)) + )) + ((string-match-p "\\." search-term) + (unless (string= search-term candidate) + (propertize (alchemist-complete--add-prefix-to-function (concat (alchemist-scope-extract-module search-term) ".") + (replace-regexp-in-string "/[0-9]$" "" candidate)) 'meta meta))) + (t (propertize (replace-regexp-in-string "/[0-9]$" "" candidate) 'meta meta))))) + candidates)) + (candidates (-remove 'null candidates))) + (cond + ((and (string-match-p "\\.$" search-term) + (not (string-match-p "\\.$" alchemist-company-last-completion))) + (push (alchemist-utils-remove-dot-at-the-end search-term) candidates)) + (t candidates)))) + +(defun alchemist-complete--build-help-candidates (a-list) + (let* ((search-term (car a-list)) + (candidates (cond ((> (alchemist-utils-count-char-occurence "\\." search-term) 1) + (let ((search (if (string-match-p "\\.[a-z0-9_\?!]+$" search-term) + (list (replace-regexp-in-string "\\.[a-z0-9_\?!]+$" "" search-term)) + (list (alchemist-utils-remove-dot-at-the-end search-term)))) + (candidates (-map (lambda (c) + (if (string-match-p "\\.[a-z0-9_\?!]+$" search-term) + (concat (replace-regexp-in-string "\\.[a-z0-9_\?!]+$" "." search-term) c) + (concat search-term c))) + (cdr a-list)))) + (append search candidates))) + ((string-match-p "\\.$" search-term) + (alchemist-complete--concat-prefix-with-functions search-term a-list t)) + ((string-match-p "\\.[a-z0-9_\?!]+$" search-term) + (alchemist-complete--concat-prefix-with-functions search-term a-list)) + (t + a-list)))) + (-distinct candidates))) + +(defun alchemist-complete--output-to-list (output) + (let* ((output (split-string output))) + (-remove 'null output))) + +(defun alchemist-complete--build-candidates-from-process-output (output) + (let* ((output (alchemist-server-prepare-filter-output output)) + (candidates (if (not (alchemist-utils-empty-string-p output)) + (alchemist-complete--output-to-list + (ansi-color-filter-apply output)) + '())) + (candidates (if candidates + (alchemist-complete--build-candidates candidates) + '()))) + candidates)) + +(defun alchemist-complete--completing-prompt (initial completing-collection) + (let* ((completing-collection (alchemist-complete--build-help-candidates completing-collection))) + (cond ((equal (length completing-collection) 1) + (car completing-collection)) + (completing-collection + (completing-read + "Elixir help: " + completing-collection + nil + nil + (replace-regexp-in-string "\\.$" "" initial))) + (t initial)))) + +(defun alchemsit-complete--dabbrev-code-candidates () + "This function uses a piece of functionality of company-dabbrev-code backend. + +Please have a look at the company-dabbrev-code function for more +detailed information." + (let ((case-fold-search nil)) + (-distinct (company-dabbrev--search + (company-dabbrev-code--make-regexp alchemist-company-last-completion) + company-dabbrev-code-time-limit + (list major-mode) + t)))) + +(provide 'alchemist-complete) + +;;; alchemist-complete.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-eval.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-eval.el new file mode 100644 index 0000000..a3c4c5d --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-eval.el @@ -0,0 +1,219 @@ +;;; alchemist-eval.el --- Elixir code inline evaluation functionality + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Elixir code inline evaluation functionality + +;;; Code: + +(require 'elixir-mode) +(require 'alchemist-server) +(require 'alchemist-interact) + +(defgroup alchemist-eval nil + "Elixir code inline evaluation functionality." + :prefix "alchemist-eval-" + :group 'alchemist) + +(defconst alchemist-eval-buffer-name "*alchemist-eval-mode*" + "Name of the Elixir evaluation buffer.") + +(defvar alchemist-eval-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "q") #'quit-window) + map) + "Keymap for `alchemist-eval-mode'.") + +(defvar alchemist-eval-filter-output nil) + +;; Private functions + +(defun alchemist-eval--insert (string) + (let ((lines (split-string string "\n"))) + (if (> (length lines) 1) + (progn + (save-excursion + (end-of-line) + (mapc (lambda (s) + (newline) + (insert (format "# => %s" s)) + (indent-according-to-mode)) + lines))) + (save-excursion + (end-of-line) + (insert (format " # => %s" string)))))) + +(defun alchemist-eval--expression (expression) + (let ((file (make-temp-file "alchemist-eval" nil ".exs"))) + (with-temp-file file + (insert expression)) + (alchemist-server-eval (format "{ :eval, '%s' }" file) #'alchemist-eval-filter))) + +(defun alchemist-eval--expression-and-print (expression) + (let ((file (make-temp-file "alchemist-eval" nil ".exs"))) + (with-temp-file file + (insert expression)) + (alchemist-server-eval (format "{ :eval, '%s' }" file) #'alchemist-eval-insert-filter))) + +(defun alchemist-eval--quote-expression (expression) + (let ((file (make-temp-file "alchemist-eval" nil ".exs"))) + (with-temp-file file + (insert expression)) + (alchemist-server-eval (format "{ :quote, '%s' }" file) #'alchemist-eval-quoted-filter))) + +(defun alchemist-eval--quote-expression-and-print (expression) + (let ((file (make-temp-file "alchemist-eval" nil ".exs"))) + (with-temp-file file + (insert expression)) + (alchemist-server-eval (format "{ :quote, '%s' }" file) #'alchemist-eval-quoted-insert-filter))) + +(defun alchemist-eval-filter (_process output) + (setq alchemist-eval-filter-output (cons output alchemist-eval-filter-output)) + (when (alchemist-server-contains-end-marker-p output) + (alchemist-interact-create-popup alchemist-eval-buffer-name + (alchemist-server-prepare-filter-output alchemist-eval-filter-output) + #'(lambda () + (elixir-mode) + (alchemist-eval-mode) + (ansi-color-apply-on-region (point-min) (point-max)))) + (setq alchemist-eval-filter-output nil))) + +(defun alchemist-eval-insert-filter (_process output) + (setq alchemist-eval-filter-output (cons output alchemist-eval-filter-output)) + (when (alchemist-server-contains-end-marker-p output) + (alchemist-interact-insert-as-comment + (alchemist-server-prepare-filter-output alchemist-eval-filter-output)) + (setq alchemist-eval-filter-output nil))) + +(defun alchemist-eval-quoted-filter (_process output) + (setq alchemist-eval-filter-output (cons output alchemist-eval-filter-output)) + (when (alchemist-server-contains-end-marker-p output) + (alchemist-interact-create-popup alchemist-eval-buffer-name + (alchemist-server-prepare-filter-output alchemist-eval-filter-output) + #'alchemist-eval-mode) + (setq alchemist-eval-filter-output nil))) + +(defun alchemist-eval-quoted-insert-filter (_process output) + (setq alchemist-eval-filter-output (cons output alchemist-eval-filter-output)) + (when (alchemist-server-contains-end-marker-p output) + (alchemist-interact-insert-as-comment + (alchemist-server-prepare-filter-output alchemist-eval-filter-output)) + (setq alchemist-eval-filter-output nil))) + +;; Public functions + +(defun alchemist-eval-current-line () + "Evaluate the Elixir code on the current line." + (interactive) + (alchemist-eval--expression (thing-at-point 'line))) + +(defun alchemist-eval-print-current-line () + "Evaluate the Elixir code on the current line and insert the result." + (interactive) + (alchemist-eval--expression-and-print (thing-at-point 'line))) + +(defun alchemist-eval-region (beg end) + "Evaluate the Elixir code on marked region." + (interactive (list (point) (mark))) + (unless (and beg end) + (error "The mark is not set now, so there is no region")) + (let ((string (buffer-substring-no-properties beg end))) + (alchemist-eval--expression string))) + +(defun alchemist-eval-print-region (beg end) + "Evaluate the Elixir code on marked region and insert the result." + (interactive (list (point) (mark))) + (unless (and beg end) + (error "The mark is not set now, so there is no region")) + (let ((string (buffer-substring-no-properties beg end))) + (when (> end beg) + (exchange-point-and-mark)) + (alchemist-eval--expression-and-print string))) + +(defun alchemist-eval-buffer () + "Evaluate the Elixir code in the current buffer." + (interactive) + (let ((string (buffer-substring-no-properties (point-min) (point-max)))) + (alchemist-eval--expression string))) + +(defun alchemist-eval-print-buffer () + "Evaluate the Elixir code in the current buffer and insert the result." + (interactive) + (let ((string (buffer-substring-no-properties (point-min) (point-max)))) + (goto-char (point-max)) + (alchemist-eval--expression-and-print string))) + +(defun alchemist-eval-quoted-current-line () + "Get the Elixir code representation of the expression on the current line." + (interactive) + (alchemist-eval--quote-expression (thing-at-point 'line))) + +(defun alchemist-eval-print-quoted-current-line () + "Get the Elixir code representation of the expression on the current line and insert the result." + (interactive) + (alchemist-eval--quote-expression-and-print (thing-at-point 'line))) + +(defun alchemist-eval-quoted-region (beg end) + "Get the Elixir code representation of the expression on marked region." + (interactive (list (point) (mark))) + (unless (and beg end) + (error "The mark is not set now, so there is no region")) + (let ((string (buffer-substring-no-properties beg end))) + (alchemist-eval--quote-expression string))) + +(defun alchemist-eval-print-quoted-region (beg end) + "Get the Elixir code representation of the expression on marked region and insert the result." + (interactive (list (point) (mark))) + (unless (and beg end) + (error "The mark is not set now, so there is no region")) + (let ((string (buffer-substring-no-properties beg end))) + (when (> end beg) + (exchange-point-and-mark)) + (alchemist-eval--quote-expression-and-print string))) + +(defun alchemist-eval-quoted-buffer () + "Get the Elixir code representation of the expression in the current buffer." + (interactive) + (let ((string (buffer-substring-no-properties (point-min) (point-max)))) + (alchemist-eval--quote-expression string))) +(defun alchemist-eval-print-quoted-buffer () + "Get the Elixir code representation of the expression in the current buffer and insert result." + (interactive) + (let ((string (buffer-substring-no-properties (point-min) (point-max)))) + (alchemist-eval--quote-expression-and-print string))) + +(defun alchemist-eval-close-popup () + "Quit the evaluation buffer window." + (interactive) + (quit-windows-on alchemist-eval-buffer-name)) + +(define-minor-mode alchemist-eval-mode + "Minor mode for Alchemist Elixir code evaluation. + +\\{alchemist-eval-mode-map}" + nil + " Alchemist-Eval" + alchemist-eval-mode-map) + +(provide 'alchemist-eval) + +;;; alchemist-eval.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-execute.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-execute.el new file mode 100644 index 0000000..4cd0eda --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-execute.el @@ -0,0 +1,93 @@ +;;; alchemist-execute.el --- Elixir's script execution integration + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Elixir's script execution integration + +;;; Code: + +(require 'alchemist-utils) +(require 'alchemist-test-mode) +(require 'alchemist-report) + +(defgroup alchemist-execute nil + "Elixir's script execution integration." + :prefix "alchemist-execute-" + :group 'alchemist) + +;; Variables + +(defcustom alchemist-execute-command "elixir" + "The shell command for elixir." + :type 'string + :group 'alchemist-execute) + +(defvar alchemist-execute-buffer-name "*alchemist elixir*" + "Name of the elixir output buffer.") + +(defvar alchemist-execute-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "q" #'quit-window) + map)) + +;; Private functions + +(defun alchemist-execute--file (filename) + (when (not (file-exists-p filename)) + (error "The given file doesn't exist")) + (alchemist-execute (list alchemist-execute-command (expand-file-name filename)))) + +(defun alchemist-execute--read-command (command) + (read-shell-command "elixir command: " (concat command " "))) + +;; Public functions + +(defun alchemist-execute-this-buffer () + "Run the current buffer through elixir." + (interactive) + (alchemist-execute--file buffer-file-name)) + +(defun alchemist-execute-file (filename) + "Run elixir with the given FILENAME." + (interactive "Felixir: ") + (alchemist-execute--file (expand-file-name filename))) + +(define-derived-mode alchemist-execute-mode fundamental-mode "Elixir Execute Mode" + "Major mode for execute Elixir files. + +\\{alchemist-execute-mode-map}" + (setq buffer-read-only t) + (setq-local truncate-lines t) + (setq-local electric-indent-chars nil)) + +(defun alchemist-execute (cmdlist) + "Run a elixir with CMDLIST." + (interactive (list (alchemist-execute--read-command alchemist-execute-command))) + (let ((command (alchemist-utils-build-command cmdlist))) + (alchemist-report-run command + "alchemist-execute-report" + alchemist-execute-buffer-name + 'alchemist-execute-mode))) + +(provide 'alchemist-execute) + +;;; alchemist-execute.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-file.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-file.el new file mode 100644 index 0000000..5a021d5 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-file.el @@ -0,0 +1,57 @@ +;;; alchemist-file.el --- Functionality to work with directory content + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Functionality to work with directory content. + +;;; Code: + +(defgroup alchemist-file nil + "Functionality to work with directory content." + :prefix "alchemist-file-" + :group 'alchemist) + +(defun alchemist-file-find-files (root directory) + "Open DIRECTORY inside ROOT and prompt for a file." + (let* ((files (alchemist-file-read-dir root directory)) + (root-name (car (cdr (reverse (split-string root "/"))))) + (file (completing-read (format "[%s] %s: " root-name directory) files))) + (find-file (expand-file-name file root)))) + +(defun alchemist-file-read-dir (root directory) + "Return all files in DIRECTORY and use ROOT as `default-directory'." + (let ((default-directory root)) + (-map (lambda (file) (file-relative-name file root)) + (alchemist-file--files-from directory)))) + +(defun alchemist-file--files-from (directory) + (--mapcat + (if (file-directory-p it) + (unless (or (equal (file-relative-name it directory) "..") + (equal (file-relative-name it directory) ".")) + (alchemist-file--files-from it)) + (list it)) + (directory-files directory t))) + +(provide 'alchemist-file) + +;;; alchemist-file.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-goto.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-goto.el new file mode 100644 index 0000000..2f461b0 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-goto.el @@ -0,0 +1,297 @@ +;;; alchemist-goto.el --- Functionality to jump modules and function definitions -*- lexical-binding: t -*- + +;; Copyright © 2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Functionality to jump modules and function definitions + +;;; Code: + +(require 'cl-lib) +(require 'etags) +(require 'dash) +(require 'alchemist-utils) +(require 'alchemist-server) +(require 'alchemist-scope) + +(defgroup alchemist-goto nil + "Functionality to jump modules and function definitions." + :prefix "alchemist-goto-" + :group 'alchemist) + +;; Variables + +(defcustom alchemist-goto-erlang-source-dir "" + "Path to the erlang source code." + :type 'string + :group 'alchemist-goto) + +(defcustom alchemist-goto-elixir-source-dir "" + "Path to the elixir source code." + :type 'string + :group 'alchemist-goto) + +(defvar alchemist-goto--symbol-list '()) +(defvar alchemist-goto--symbol-name-and-pos '()) +(defvar alchemist-goto--symbol-list-bare '()) +(defvar alchemist-goto--symbol-name-and-pos-bare '()) +(defvar alchemist-goto-filter-output nil) +(defvar alchemist-goto-callback nil) + +(defconst alchemist-goto--symbol-def-extract-regex + "^\\s-*\\(defp?\\|defmacrop?\\|defmodule\\|defimpl\\)[ \n\t]+\\([a-z_\?!]+\\)\\(.*\\)\\(do\\|\n\\)?$") + +(defconst alchemist-goto--symbol-def-regex + "^[[:space:]]*\\(defmodule\\|defmacrop?\\|defimpl\\|defp?\\)") + +;; Faces + +(defface alchemist-goto--def-face + '((t (:inherit font-lock-constant-face))) + "Face for def* symbols." + :group 'alchemist-goto) + +(defface alchemist-goto--name-face + '((t (:bold t))) + "Face for def* symbol names." + :group 'alchemist-goto) + +;; Private functions + +(defun alchemist-goto--build-elixir-ex-core-file (file) + (when (string-match "\\/\\(lib\\/.+\\/lib\\)\\/.+\.ex$" file) + (let* ((file (substring-no-properties file (match-beginning 1))) + (source-directory (alchemist-utils-add-trailing-slash + (expand-file-name alchemist-goto-elixir-source-dir)))) + (concat source-directory file)))) + +(defun alchemist-goto--build-elixir-erl-core-file (file) + (when (string-match "\\/\\(lib\\/.+\\/src\\)\\/.+\.erl$" file) + (let* ((file (substring-no-properties file (match-beginning 1))) + (source-directory (alchemist-utils-add-trailing-slash + (expand-file-name alchemist-goto-elixir-source-dir)))) + (concat source-directory file)))) + +(defun alchemist-goto--build-erlang-core-file (file) + (when (string-match "\\/\\(lib\\/.+\\/src\\)\\/.+\.erl$" file) + (let* ((file (substring-no-properties file (match-beginning 1))) + (source-directory (alchemist-utils-add-trailing-slash + (expand-file-name alchemist-goto-erlang-source-dir)))) + (concat source-directory file)))) + +(defun alchemist-goto-elixir-file-p (file) + "Return non-nil if FILE is an Elixir file type." + (string-match-p "\\.ex\\(s\\)?$" file)) + +(defun alchemist-goto-erlang-file-p (file) + "Return non-nil if FILE is an Erlang file type." + (string-match-p "\\.erl$" file)) + +(defun alchemist-goto--symbol-definition-p (symbol) + (alchemist-goto--fetch-symbol-definitions) + (if (member symbol alchemist-goto--symbol-list-bare) + t + nil)) + +(defun alchemist-goto--fetch-symbols-from-propertize-list (symbol) + (-remove 'null (-map (lambda (e) + (when (string-match-p (format "^\\s-*\\(defp?\\|defmacrop?\\|defimpl\\|defmodule\\)\s+%s\\((.*\\)?$" symbol) e) + e)) alchemist-goto--symbol-list))) + +(defun alchemist-goto--goto-symbol (symbol) + (let ((amount (length (-remove 'null (-map (lambda (e) (when (string= symbol e) e)) + alchemist-goto--symbol-list-bare))))) + (if (> amount 1) + (let* ((selected-def (completing-read "Symbol definitions:" + (alchemist-goto--fetch-symbols-from-propertize-list symbol))) + (position (cdr (assoc selected-def alchemist-goto--symbol-name-and-pos)))) + (goto-char (if (overlayp position) (overlay-start position) position))) + (let* ((position (cdr (assoc symbol alchemist-goto--symbol-name-and-pos-bare))) + (position (if (overlayp position) (overlay-start position) position))) + (when (not (equal (line-number-at-pos) + (line-number-at-pos position))) + (goto-char position)))))) + +(defun alchemist-goto-list-symbol-definitions () + "List all symbol definitions in the current file like functions/macros/modules. + +It will jump to the position of the symbol definition after selection." + (interactive) + (alchemist-goto--fetch-symbol-definitions) + (ring-insert find-tag-marker-ring (point-marker)) + (let* ((selected-def (completing-read "Symbol definitions:" alchemist-goto--symbol-list)) + (position (cdr (assoc selected-def alchemist-goto--symbol-name-and-pos)))) + (goto-char (if (overlayp position) (overlay-start position) position)))) + +(defun alchemist-goto--fetch-symbol-definitions () + (alchemist-goto--search-for-symbols "^\\s-*\\(defp?\\|defmacrop?\\|defimpl\\|defstruct\\|defmodule\\)\s.*")) + +(defun alchemist-goto--extract-symbol (str) + (save-match-data + (when (string-match alchemist-goto--symbol-def-extract-regex str) + (let ((type (substring str (match-beginning 1) (match-end 1))) + (name (substring str (match-beginning 2) (match-end 2))) + (arguments (substring str (match-beginning 3) (match-end 3)))) + (concat + (propertize type + 'face 'alchemist-goto--def-face) + " " + (propertize name + 'face 'alchemist-goto--name-face) + (replace-regexp-in-string ",?\s+do:.*$" "" (replace-regexp-in-string "\s+do$" "" arguments))))))) + +(defun alchemist-goto--file-contains-defs-p () + (alchemist-utils-occur-in-buffer-p (current-buffer) alchemist-goto--symbol-def-extract-regex)) + +(defun alchemist-goto-jump-to-next-def-symbol () + (interactive) + (alchemist-utils-jump-to-next-matching-line alchemist-goto--symbol-def-regex 'back-to-indentation)) + +(defun alchemist-goto-jump-to-previous-def-symbol () + (interactive) + (alchemist-utils-jump-to-previous-matching-line alchemist-goto--symbol-def-regex 'back-to-indentation)) + +(defun alchemist-goto--extract-symbol-bare (str) + (save-match-data + (when (string-match alchemist-goto--symbol-def-extract-regex str) + (let ((name (substring str (match-beginning 2) (match-end 2)))) + name)))) + +(defun alchemist-goto--get-symbol-from-position (position) + (goto-char position) + (end-of-line) + (let* ((end-position (point)) + (line (buffer-substring-no-properties position end-position))) + (alchemist-goto--extract-symbol line))) + +(defun alchemist-goto--get-symbol-from-position-bare (position) + (with-current-buffer (buffer-name) + (save-excursion + (goto-char position) + (end-of-line) + (let* ((end-position (point)) + (line (buffer-substring-no-properties position end-position))) + (alchemist-goto--extract-symbol-bare line))))) + +(defun alchemist-goto--search-for-symbols (regex) + (setq alchemist-goto--symbol-list '()) + (setq alchemist-goto--symbol-name-and-pos '()) + (setq alchemist-goto--symbol-list-bare '()) + (setq alchemist-goto--symbol-name-and-pos-bare '()) + (with-current-buffer (buffer-name) + (save-excursion + (goto-char (point-min)) + (save-match-data + (while (re-search-forward regex nil t) + (when (not (alchemist-scope-inside-string-p)) + (when (alchemist-goto--get-symbol-from-position (car (match-data))) + (let* ((position (car (match-data))) + (symbol (alchemist-goto--get-symbol-from-position position)) + (symbol-bare (alchemist-goto--get-symbol-from-position-bare position))) + (setq alchemist-goto--symbol-list (append alchemist-goto--symbol-list (list symbol))) + (setq alchemist-goto--symbol-name-and-pos (append alchemist-goto--symbol-name-and-pos (list (cons symbol position)))) + (setq alchemist-goto--symbol-list-bare (append alchemist-goto--symbol-list-bare (list symbol-bare))) + (setq alchemist-goto--symbol-name-and-pos-bare (append alchemist-goto--symbol-name-and-pos-bare (list (cons symbol-bare position)))))))))))) + +(defun alchemist-goto--open-definition (expr) + (let* ((module (alchemist-scope-extract-module expr)) + (aliases (alchemist-utils-prepare-aliases-for-elixir + (alchemist-scope-aliases))) + (function (alchemist-scope-extract-function expr)) + (modules (alchemist-utils-prepare-modules-for-elixir + (alchemist-scope-all-modules)))) + (ring-insert find-tag-marker-ring (point-marker)) + (cond + ((and (null module) + (alchemist-goto--symbol-definition-p function) + (not (string= (buffer-name) alchemist-help-buffer-name))) + (alchemist-goto--goto-symbol function)) + (t + (setq alchemist-goto-callback (lambda (file) + (cond ((alchemist-utils-empty-string-p file) + (message "Don't know how to find: %s" expr)) + ((file-exists-p file) + (alchemist-goto--open-file file module function)) + ((alchemist-goto-elixir-file-p file) + (let* ((elixir-source-file (alchemist-goto--build-elixir-ex-core-file file))) + (if (file-exists-p elixir-source-file) + (alchemist-goto--open-file elixir-source-file module function) + (message "Don't know how to find: %s" expr)))) + ((alchemist-goto-erlang-file-p file) + (let* ((elixir-source-file (alchemist-goto--build-elixir-erl-core-file file)) + (erlang-source-file (alchemist-goto--build-erlang-core-file file))) + (cond ((file-exists-p elixir-source-file) + (alchemist-goto--open-file elixir-source-file module function)) + ((file-exists-p erlang-source-file) + (alchemist-goto--open-file erlang-source-file module function)) + (t + (message "Don't know how to find: %s" expr))))) + (t + (pop-tag-mark) + (message "Don't know how to find: %s" expr))))) + (alchemist-server-goto (format "{ \"%s,%s\", [ context: Elixir, imports: %s, aliases: %s ] }" module function modules aliases) + #'alchemist-goto-filter))))) + +(defun alchemist-goto--open-file (file module function) + (let ((buf (find-file-noselect file))) + (switch-to-buffer buf) + (goto-char (point-min)) + (cond ((alchemist-goto-elixir-file-p file) + (alchemist-goto--jump-to-elixir-source module function)) + ((alchemist-goto-erlang-file-p file) + (alchemist-goto--jump-to-erlang-source module function))))) + +(defun alchemist-goto--jump-to-elixir-source (module function) + (cond + (function + (alchemist-goto--fetch-symbol-definitions) + (alchemist-goto--goto-symbol function)) + (t + (when (re-search-forward (format "\\(defmodule\\|defimpl\\|defprotocol\\)\s+%s\s+do" module) nil t) + (goto-char (match-beginning 0)))))) + +(defun alchemist-goto--jump-to-erlang-source (module function) + (when (re-search-forward (format "\\(^%s\(\\)" function) nil t) + (goto-char (match-beginning 0))) + (when (re-search-forward (format "\\(^-module\(%s\)\\)" (substring module 1)) nil t) + (goto-char (match-beginning 0)))) + +(defun alchemist-goto-filter (_process output) + (with-local-quit + (setq alchemist-goto-filter-output (cons output alchemist-goto-filter-output)) + (if (alchemist-server-contains-end-marker-p output) + (let* ((output (alchemist-server-prepare-filter-output alchemist-goto-filter-output)) + (file output)) + (setq alchemist-goto-filter-output nil) + (funcall alchemist-goto-callback file))))) + +;; Public functions + +(defun alchemist-goto-definition-at-point () + "Jump to the elixir expression definition at point." + (interactive) + (alchemist-goto--open-definition (alchemist-scope-expression))) + +(defalias 'alchemist-goto-jump-back 'pop-tag-mark) + +(provide 'alchemist-goto) + +;;; alchemist-goto.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-help.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-help.el new file mode 100644 index 0000000..c96be2f --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-help.el @@ -0,0 +1,266 @@ +;;; alchemist-help.el --- Functionality for Elixir documentation lookup -*- lexical-binding: t -*- + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Functionality for Elixir documentation lookup. + +;;; Code: + +(require 'dash) +(require 'ansi-color) +(require 'alchemist-utils) +(require 'alchemist-project) +(require 'alchemist-server) +(require 'alchemist-scope) +(require 'alchemist-goto) + +(defgroup alchemist-help nil + "Functionality for Elixir documentation lookup." + :prefix "alchemist-help-" + :group 'alchemist) + +(defcustom alchemist-help-buffer-name "*alchemist help*" + "Name of the Elixir help buffer." + :type 'string + :group 'alchemist-help) + +(defvar alchemist-help-search-history '() + "Storage for the search history.") + +(defvar alchemist-help-current-search-text '() + "Stores the current search.") + +(defvar alchemist-help-filter-output nil) + +(defface alchemist-help-key-face + '((t (:inherit font-lock-variable-name-face :bold t :foreground "red"))) + "Face for the letter keys in the summary." + :group 'alchemist-help) + +(defun alchemist-help-lookup-doc (search) + "Lookup Elixir documentation for SEARCH." + (setq alchemist-help-current-search-text search) + (setq alchemist-help-filter-output nil) + (if (not (alchemist-utils-empty-string-p search)) + (alchemist-server-complete-candidates + (alchemist-help--completion-server-arguments search) + #'alchemist-help-complete-filter-output) + (message "No documentation for [%s] found." search))) + +(defun alchemist-help-no-doc-available-p (string) + "Return non-nil if STRING contains Elixir no documentation message." + (or (string-match-p "No documentation for" string) + (string-match-p "Could not load module" string) + (string-match-p "it does not have Elixir-style docs" string) + (alchemist-utils-empty-string-p string))) + +(defun alchemist-help-store-search-in-history () + "Store the last `alchemist-help-current-search-text' in `alchemist-help-search-history'." + (unless (memq 'alchemist-help-current-search-text alchemist-help-search-history) + (add-to-list 'alchemist-help-search-history alchemist-help-current-search-text))) + +(defun alchemist-help-display-doc (content) + "Initialize the `alchemist-help-buffer-name' and insert CONTENT." + (let ((default-directory (alchemist-project-root-or-default-dir)) + (buffer (get-buffer-create alchemist-help-buffer-name))) + (cond + ((alchemist-help-no-doc-available-p content) + (message (format "No documentation for [%s] found." + alchemist-help-current-search-text))) + (t + (alchemist-help-store-search-in-history) + (with-current-buffer buffer + (let ((inhibit-read-only t)) + (goto-char (point-min)) + (erase-buffer) + (insert content) + (goto-char (point-min)) + (ansi-color-apply-on-region (point-min) (point-max)) + (alchemist-help-minor-mode))) + (pop-to-buffer buffer))))) + +(defun alchemist-help--search-at-point () + "Search through `alchemist-help' with the expression under the cursor" + (let* ((expr (alchemist-scope-expression))) + (alchemist-help-lookup-doc (alchemist-help--prepare-search-expr expr)))) + +(defun alchemist-help--search-marked-region (begin end) + "Run `alchemist-help' with the marked region. +Argument BEGIN where the mark starts. +Argument END where the mark ends." + (let ((expr (buffer-substring-no-properties begin end))) + (alchemist-help-lookup-doc (alchemist-help--prepare-search-expr expr)))) + +(defun alchemist-help--prepare-search-expr (expr) + (let* ((module (alchemist-scope-extract-module expr)) + (module (alchemist-scope-alias-full-path module)) + (module (if module module "")) + (function (alchemist-scope-extract-function expr)) + (function (if function function "")) + (expr (cond + ((and (not (alchemist-utils-empty-string-p module)) + (not (alchemist-utils-empty-string-p function))) + (format "%s.%s" module function)) + ((not (alchemist-utils-empty-string-p module)) + module) + (t + expr)))) + expr)) + +(defun alchemist-help--elixir-modules-to-list (str) + (let* ((str (replace-regexp-in-string "^Elixir\\." "" str)) + (modules (split-string str)) + (modules (delete nil modules)) + (modules (cl-sort modules 'string-lessp :key 'downcase)) + (modules (-distinct modules))) + modules)) + +(defun alchemist-help-minor-mode-key-binding-summary () + (interactive) + (message + (concat "[" (propertize "q" 'face 'alchemist-help-key-face) + "]-quit [" + (propertize "e" 'face 'alchemist-help-key-face) + "]-search-at-point [" + (propertize "s" 'face 'alchemist-help-key-face) + "]-search [" + (propertize "h" 'face 'alchemist-help-key-face) + "]-history [" + (propertize "?" 'face 'alchemist-help-key-face) + "]-keys"))) + +(defun alchemist-help--server-arguments (args) + (if (and (not (equal major-mode 'alchemist-iex-mode)) + (not (bound-and-true-p alchemist-help-minor-mode))) + (let* ((modules (alchemist-utils-prepare-modules-for-elixir + (alchemist-scope-all-modules)))) + (format "{ \"%s\", [ context: Elixir, imports: %s, aliases: [] ] }" args modules)) + (format "{ \"%s\", [ context: Elixir, imports: [], aliases: [] ] }" args))) + +(defun alchemist-help--completion-server-arguments (args) + "Build informations about the current context." + (if (and (not (equal major-mode 'alchemist-iex-mode)) + (not (bound-and-true-p alchemist-help-minor-mode))) + (let* ((modules (alchemist-utils-prepare-modules-for-elixir + (alchemist-scope-all-modules))) + (aliases (alchemist-utils-prepare-aliases-for-elixir + (alchemist-scope-aliases)))) + (format "{ \"%s\", [ context: Elixir, imports: %s, aliases: %s ] }" args modules aliases)) + (format "{ \"%s\", [ context: Elixir, imports: [], aliases: [] ] }" args))) + +(defun alchemist-help-complete-filter-output (_process output) + (with-local-quit + (setq alchemist-help-filter-output (cons output alchemist-help-filter-output)) + (if (alchemist-server-contains-end-marker-p output) + (let* ((string (alchemist-server-prepare-filter-output alchemist-help-filter-output)) + (candidates (alchemist-complete--output-to-list + (ansi-color-filter-apply string))) + (candidates (if (= (length candidates) 2) + nil + candidates))) + (setq alchemist-help-filter-output nil) + (if candidates + (let* ((search (alchemist-complete--completing-prompt alchemist-help-current-search-text candidates))) + (setq alchemist-help-current-search-text search) + (alchemist-server-help (alchemist-help--server-arguments search) #'alchemist-help-filter-output)) + (alchemist-server-help (alchemist-help--server-arguments alchemist-help-current-search-text) #'alchemist-help-filter-output)))))) + +(defun alchemist-help-filter-output (_process output) + (setq alchemist-help-filter-output (cons output alchemist-help-filter-output)) + (if (alchemist-server-contains-end-marker-p output) + (let ((string (alchemist-server-prepare-filter-output alchemist-help-filter-output))) + (alchemist-help-display-doc string) + (setq alchemist-help-current-search-text nil) + (setq alchemist-help-filter-output nil)))) + +(defun alchemist-help-modules-filter (_process output) + (with-local-quit + (setq alchemist-help-filter-output (cons output alchemist-help-filter-output)) + (if (alchemist-server-contains-end-marker-p output) + (let* ((output (alchemist-server-prepare-filter-output alchemist-help-filter-output)) + (modules (alchemist-help--elixir-modules-to-list output)) + (search (completing-read + "Elixir help: " + modules + nil + nil + nil)) + (module (alchemist-scope-extract-module search)) + (function (alchemist-scope-extract-function search)) + (search (cond + ((and module function) + search) + ((and module + (not (string-match-p "[\/0-9]+$" module))) + (concat module ".")) + (t + search)))) + (alchemist-help-lookup-doc (alchemist-utils-remove-dot-at-the-end search)))))) + +;; Public functions + +(defun alchemist-help-search-at-point () + "Search through `alchemist-help' with the expression under the cursor. + +If the buffer local variable `mark-active' is non-nil, +the actively marked region will be used for passing to `alchemist-help'." + (interactive) + (if mark-active + (alchemist-help--search-marked-region (region-beginning) (region-end)) + (alchemist-help--search-at-point))) + +(defvar alchemist-help-minor-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "q") #'quit-window) + (define-key map (kbd "e") #'alchemist-help-search-at-point) + (define-key map (kbd "s") #'alchemist-help) + (define-key map (kbd "h") #'alchemist-help-history) + (define-key map (kbd "M-.") #'alchemist-goto-definition-at-point) + (define-key map (kbd "?") #'alchemist-help-minor-mode-key-binding-summary) + map) + "Keymap for `alchemist-help-minor-mode'.") + +(define-minor-mode alchemist-help-minor-mode + "Minor mode for displaying elixir help." + :group 'alchemist-help + :keymap alchemist-help-minor-mode-map + (cond (alchemist-help-minor-mode + (setq buffer-read-only t)) + (t + (setq buffer-read-only nil)))) + +(defun alchemist-help () + "Load Elixir documentation for SEARCH." + (interactive) + (setq alchemist-help-filter-output nil) + (alchemist-server-info "{ :type, :modules }" #'alchemist-help-modules-filter)) + +(defun alchemist-help-history (search) + "Load Elixir from the documentation history for SEARCH." + (interactive + (list + (completing-read "Elixir help history: " alchemist-help-search-history nil nil ""))) + (alchemist-help-lookup-doc search)) + +(provide 'alchemist-help) + +;;; alchemist-help.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-hooks.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-hooks.el new file mode 100644 index 0000000..5418054 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-hooks.el @@ -0,0 +1,60 @@ +;;; alchemist-hooks.el --- Hooks functionality + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini + +;; This file is not part of GNU Emacs. + +;; 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 . + +;;; Commentary: + +;; Hooks functionality + +;;; Code: + +(require 'alchemist-project) +(require 'alchemist-mix) +(require 'alchemist-report) +(require 'alchemist-test-mode) + +(defgroup alchemist-hooks nil + "Hooks" + :prefix "alchemist-hooks-" + :group 'alchemist) + +(defcustom alchemist-hooks-test-on-save nil + "If t, run `alchemist-mix-test' on save." + :type 'boolean + :group 'alchemist-hooks) + +(defun alchemist-hooks-test-on-save () + (when (and alchemist-hooks-test-on-save + (alchemist-project-p)) + (alchemist-report-run "mix test" + alchemist-test-report-process-name + alchemist-test-report-buffer-name + #'alchemist-test-report-mode + #'alchemist-test--handle-exit + t))) + +(eval-after-load 'elixir-mode + '(progn + (add-hook 'after-save-hook 'alchemist-hooks-test-on-save nil nil))) + +(provide 'alchemist-hooks) + +;;; alchemist-hooks.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-iex.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-iex.el new file mode 100644 index 0000000..e5dc498 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-iex.el @@ -0,0 +1,229 @@ +;;; alchemist-help.el --- Interaction with an Elixir IEx process + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Interaction with an Elixir IEx process + +;;; Code: + +(require 'comint) +(require 'company) +(require 'alchemist-key) +(require 'alchemist-scope) +(require 'alchemist-project) + +(defgroup alchemist-iex nil + "Interaction with an Elixir IEx process." + :prefix "alchemist-iex-" + :group 'alchemist) + +(defcustom alchemist-iex-program-name "iex" + "The shell command for iex." + :type 'string + :group 'alchemist-iex) + +(defcustom alchemist-iex-prompt-read-only t + "If non-nil, the prompt will be read-only." + :type 'boolean + :group 'alchemist-iex) + +(defvar alchemist-iex-buffer nil + "The buffer in which the Elixir IEx process is running.") + +(defvar alchemist-iex-mode-hook nil + "Hook for customizing `alchemist-iex-mode'.") + +(defvar alchemist-iex-mode-map + (let ((map (nconc (make-sparse-keymap) comint-mode-map))) + (define-key map "\t" 'completion-at-point) + (define-key map (kbd (format "%s i r" alchemist-key-command-prefix)) 'alchemist-iex-open-input-ring) + (define-key map (kbd (format "%s i c" alchemist-key-command-prefix)) 'alchemist-iex-clear-buffer) + (define-key map (kbd (format "%s h e" alchemist-key-command-prefix)) 'alchemist-help-search-at-point) + (define-key map (kbd "M-.") 'alchemist-goto-definition-at-point) + map)) + +(eval-after-load 'company + '(progn + (defun alchemist-iex--set-company-as-completion-at-point-function () + (setq completion-at-point-functions '(company-complete))) + (add-hook 'alchemist-iex-mode-hook 'alchemist-iex--set-company-as-completion-at-point-function))) + +(define-derived-mode alchemist-iex-mode comint-mode "Alchemist-IEx" + "Major mode for interacting with an Elixir IEx process. + +\\" + nil "Alchemist-IEx" + (set (make-local-variable 'comint-prompt-regexp) "^\\(iex\\|\.\.\.\\)\(.+\)>") + (set (make-local-variable 'comint-prompt-read-only) alchemist-iex-prompt-read-only) + (set (make-local-variable 'comint-input-autoexpand) nil) + (set (make-local-variable 'comint-input-sender) 'alchemist-iex--send-command) + (add-hook 'comint-output-filter-functions 'alchemist-iex-spot-prompt nil t)) + +(defun alchemist-iex-command (arg) + (split-string-and-unquote + (if (null arg) alchemist-iex-program-name + (read-string "Command to run Elixir IEx: " (concat alchemist-iex-program-name arg))))) + +(defun alchemist-iex-start-process (command) + "Start an IEX process. +With universal prefix \\[universal-argument], prompts for a COMMAND, +otherwise uses `alchemist-iex-program-name'. +It runs the hook `alchemist-iex-mode-hook' after starting the process and +setting up the IEx buffer." + (interactive (list (alchemist-iex-command current-prefix-arg))) + (setq alchemist-iex-buffer + (apply 'make-comint "Alchemist-IEx" (car command) nil (cdr command))) + (with-current-buffer alchemist-iex-buffer + (alchemist-iex-mode) + (run-hooks 'alchemist-iex-mode-hook))) + +(defun alchemist-iex-process (&optional arg) + (or (if (buffer-live-p alchemist-iex-buffer) + (get-buffer-process alchemist-iex-buffer)) + (progn + (let ((current-prefix-arg arg)) + (call-interactively 'alchemist-iex-start-process)) + (alchemist-iex-process arg)))) + +(defun alchemist-iex--remove-newlines (string) + (replace-regexp-in-string "\n" " " string)) + +(defun alchemist-iex-send-last-sexp () + "Send the previous sexp to the inferior IEx process." + (interactive) + (alchemist-iex-send-region (save-excursion (backward-sexp) (point)) (point))) + +(defun alchemist-iex-send-current-line () + "Sends the current line to the IEx process." + (interactive) + (let ((str (thing-at-point 'line))) + (alchemist-iex--send-command (alchemist-iex-process) str))) + +(defun alchemist-iex-send-current-line-and-go () + "Sends the current line to the inferior IEx process +and jump to the buffer." + (interactive) + (call-interactively 'alchemist-iex-send-current-line) + (pop-to-buffer (process-buffer (alchemist-iex-process)))) + +(defun alchemist-iex-send-region-and-go () + "Sends the marked region to the inferior IEx process +and jump to the buffer." + (interactive) + (call-interactively 'alchemist-iex-send-region) + (pop-to-buffer (process-buffer (alchemist-iex-process)))) + +(defun alchemist-iex-send-region (beg end) + "Sends the marked region to the IEx process." + (interactive (list (point) (mark))) + (unless (and beg end) + (error "The mark is not set now, so there is no region")) + (let* ((region (buffer-substring-no-properties beg end))) + (alchemist-iex--send-command (alchemist-iex-process) region))) + +(defun alchemist-iex-compile-this-buffer () + "Compiles the current buffer in the IEx process." + (interactive) + (let ((str (format "c(\"%s\")" (buffer-file-name)))) + (alchemist-iex--send-command (alchemist-iex-process) str))) + +(defun alchemist-iex-reload-module () + "Recompiles and reloads the current module in the IEx process." + (interactive) + (let ((str (format "r(%s)" (alchemist-scope-module)))) + (alchemist-iex--send-command (alchemist-iex-process) str))) + +(defun alchemist-iex--send-command (proc str) + (let ((lines (split-string str "\n" nil))) + (with-current-buffer (process-buffer proc) + (-map (lambda (line) + (alchemist-iex-wait-for-prompt proc) + (goto-char (process-mark proc)) + (insert-before-markers (concat line "\n")) + (move-marker comint-last-input-end (point)) + (comint-send-string proc (concat line "\n"))) lines)))) + +(defvar alchemist-iex-seen-prompt nil) +(make-variable-buffer-local 'alchemist-iex-seen-prompt) + +(defun alchemist-iex-spot-prompt (_string) + (let ((proc (get-buffer-process (current-buffer)))) + (when proc + (save-excursion + (goto-char (process-mark proc)) + (if (re-search-backward comint-prompt-regexp + (line-beginning-position) t) + (setq alchemist-iex-seen-prompt t)))))) + +(defun alchemist-iex-wait-for-prompt (proc &optional timeout) + "Wait until PROC sends us a prompt. +The process PROC should be associated to a comint buffer." + (with-current-buffer (process-buffer proc) + (while (progn + (goto-char comint-last-input-end) + (not (or alchemist-iex-seen-prompt + (setq alchemist-iex-seen-prompt + (re-search-forward comint-prompt-regexp nil t)) + (not (accept-process-output proc timeout)))))) + (unless alchemist-iex-seen-prompt + (error "Can't find the IEx prompt")) + (setq alchemist-iex-seen-prompt nil))) + +(defun alchemist-iex-clear-buffer () + "Clear the current iex process buffer." + (interactive) + (let ((comint-buffer-maximum-size 0)) + (comint-truncate-buffer))) + +(defun alchemist-iex-open-input-ring () + "Open the buffer containing the input history." + (interactive) + (progn + (comint-dynamic-list-input-ring) + (other-window 1))) + +;;;###autoload +(defalias 'run-elixir 'alchemist-iex-run) +(defalias 'inferior-elixir 'alchemist-iex-run) + +;;;###autoload +(defun alchemist-iex-run (&optional arg) + "Start an IEx process. +Show the IEx buffer if an IEx process is already run." + (interactive "P") + (let ((proc (alchemist-iex-process arg))) + (pop-to-buffer (process-buffer proc)))) + +;;;###autoload +(defun alchemist-iex-project-run () + "Start an IEx process with mix 'iex -S mix' in the +context of an Elixir project. +Show the IEx buffer if an IEx process is already run." + (interactive) + (if (alchemist-project-p) + (let ((default-directory (alchemist-project-root))) + (pop-to-buffer (process-buffer (alchemist-iex-process " -S mix")))) + (message "No mix.exs file available. Please use `alchemist-iex-run' instead."))) + +(provide 'alchemist-iex) + +;;; alchemist-iex.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-info.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-info.el new file mode 100644 index 0000000..8fdf79b --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-info.el @@ -0,0 +1,95 @@ +;;; alchemist-info.el --- Getting informations from the server. -*- lexical-binding: t -*- + +;; Copyright © 2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Getting informations from the server. + +;;; Code: + +(require 'ansi-color) + +(defgroup alchemist-info nil + "Getting informations from the server." + :prefix "alchemist-info-" + :group 'alchemist) + +(defconst alchemist-info-buffer-name "*alchemist-info-mode*" + "Name of the Elixir info buffer.") + +(defvar alchemist-info-filter-output nil) + +(defvar alchemist-info-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "q") #'quit-window) + map) + "Keymap for `alchemist-info-mode'.") + +(defun alchemist-info-datatype-filter (_process output) + (setq alchemist-info-filter-output (cons output alchemist-info-filter-output)) + (when (alchemist-server-contains-end-marker-p output) + (alchemist-interact-create-popup alchemist-info-buffer-name + (alchemist-server-prepare-filter-output alchemist-info-filter-output) + #'(lambda () + (alchemist-info-mode) + (ansi-color-apply-on-region (point-min) (point-max)))) + (setq alchemist-info-filter-output nil))) + +(defun alchemist-info-expression-at-point () + "Return the expression under the cursor." + (let (p1 p2) + (save-excursion + (skip-chars-backward "-_A-Za-z0-9.?!:@\'\"") + (setq p1 (point)) + (skip-chars-forward "-_A-Za-z0-9.?!:@\'\"") + (setq p2 (point)) + (buffer-substring-no-properties p1 p2)))) + +(defun alchemist-info-datatype-at-point () + "Return information about any datatype under the cursor." + (interactive) + (let ((expr (if mark-active + (buffer-substring-no-properties (region-beginning) (region-end)) + (alchemist-info-expression-at-point)))) + (alchemist-server-info (format "{ :type, :info, '%s' }" expr) #'alchemist-info-datatype-filter))) + +(defun alchemist-info-types-at-point () + "Return information of types under the cursor." + (interactive) + (let ((expr (alchemist-info-expression-at-point))) + (alchemist-server-info (format "{ :type, :types, '%s' }" expr) #'alchemist-info-datatype-filter))) + +(defun alchemist-info-close-popup () + "Quit the information buffer window." + (interactive) + (quit-windows-on alchemist-info-buffer-name)) + +(define-minor-mode alchemist-info-mode + "Minor mode for Alchemist server information. + +\\{alchemist-info-mode-map}" + nil + " Alchemist-Info" + alchemist-info-mode-map) + +(provide 'alchemist-info) + +;;; alchemist-info.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-interact.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-interact.el new file mode 100644 index 0000000..2188dd5 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-interact.el @@ -0,0 +1,64 @@ +;;; alchemist-interact.el --- Interaction interface -*- lexical-binding: t -*- + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Interaction interface. + +;;; Code: + +(defgroup alchemist-interact nil + "Interaction interface." + :prefix "alchemist-interact-" + :group 'alchemist) + +(defun alchemist-interact-insert-as-comment (string) + "Insert STRING at point as comment." + (let ((lines (split-string string "\n"))) + (if (> (length lines) 1) + (save-excursion + (end-of-line) + (mapc (lambda (s) + (newline) + (insert (format "# => %s" s)) + (indent-according-to-mode)) + lines)) + (save-excursion + (end-of-line) + (insert (format " # => %s" string)))))) + +(defun alchemist-interact-create-popup (name content mode) + "Create a NAME buffer and insert CONTENT. +Call the MODE afterwards." + (let ((buffer (get-buffer-create name))) + (with-current-buffer buffer + (with-current-buffer-window + buffer (cons 'display-buffer-below-selected + '((window-height . fit-window-to-buffer))) + (lambda (_window _buffer)) + (let ((inhibit-read-only t)) + (insert content) + (goto-char (point-min)) + (funcall mode)))))) + +(provide 'alchemist-interact) + +;;; alchemist-interact.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-key.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-key.el new file mode 100644 index 0000000..2a58f9a --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-key.el @@ -0,0 +1,40 @@ +;;; alchemist-key.el --- Key prefix setup for Alchemist related key commands + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Key prefix setup for Alchemist related key commands. + +;;; Code: + +(defgroup alchemist-key nil + "Key prefix setup for Alchemist related key commands." + :prefix "alchemist-key-" + :group 'alchemist) + +(defcustom alchemist-key-command-prefix (kbd "C-c a") + "The prefix for Alchemist related key commands." + :type 'string + :group 'alchemist) + +(provide 'alchemist-key) + +;;; alchemist-key.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-macroexpand.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-macroexpand.el new file mode 100644 index 0000000..7513372 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-macroexpand.el @@ -0,0 +1,156 @@ +;;; alchemist-macroexpand.el --- Macro expansion support -*- lexical-binding: t -*- + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Macro expansion support + +;;; Code: + +(require 'alchemist-server) +(require 'alchemist-interact) + +(defgroup alchemist-macroexpand nil + "Macro expansion support." + :prefix "alchemist-macroexpand-" + :group 'alchemist) + +(defvar alchemist-macroexpand-filter-output nil) + +(defconst alchemist-macroexpand-buffer-name "*alchemist macroexpand*" + "Name of the Elixir Macro expand buffer.") + +(defun alchemist-macroexpand-filter (_process output) + (setq alchemist-macroexpand-filter-output (cons output alchemist-macroexpand-filter-output)) + (when (alchemist-server-contains-end-marker-p output) + (alchemist-interact-create-popup alchemist-macroexpand-buffer-name + (alchemist-server-prepare-filter-output alchemist-macroexpand-filter-output) + #'(lambda () + (elixir-mode) + (alchemist-macroexpand-mode))) + (setq alchemist-macroexpand-filter-output nil))) + +(defun alchemist-macroexpand-insert-filter (_process output) + (setq alchemist-macroexpand-filter-output (cons output alchemist-macroexpand-filter-output)) + (when (alchemist-server-contains-end-marker-p output) + (alchemist-interact-insert-as-comment + (alchemist-server-prepare-filter-output alchemist-macroexpand-filter-output)) + (setq alchemist-macroexpand-filter-output nil))) + +(defun alchemist-macroexpand-expand-request (expr) + (let ((file (make-temp-file "alchemist-expand" nil ".exs"))) + (with-temp-file file + (insert expr)) + (alchemist-server-eval (format "{ :expand, '%s' }" file) #'alchemist-macroexpand-filter))) + +(defun alchemist-macroexpand-expand-and-print-request (expr) + (let ((file (make-temp-file "alchemist-expand" nil ".exs"))) + (with-temp-file file + (insert expr)) + (alchemist-server-eval (format "{ :expand, '%s' }" file) #'alchemist-macroexpand-insert-filter))) + +(defun alchemist-macroexpand-expand-once-request (expr) + (let ((file (make-temp-file "alchemist-expand-once" nil ".exs"))) + (with-temp-file file + (insert expr)) + (alchemist-server-eval (format "{ :expand_once, '%s' }" file) #'alchemist-macroexpand-filter))) + +(defun alchemist-macroexpand-expand-once-and-print-request (expr) + (let ((file (make-temp-file "alchemist-expand-once" nil ".exs"))) + (with-temp-file file + (insert expr)) + (alchemist-server-eval (format "{ :expand_once, '%s' }" file) #'alchemist-macroexpand-insert-filter))) + +(defun alchemist-macroexpand-current-line () + "Macro expand the Elixir code on the current line." + (interactive) + (alchemist-macroexpand-expand-request (thing-at-point 'line))) + +(defun alchemist-macroexpand-print-current-line () + "Macro expand the Elixir code on the current line and insert the result." + (interactive) + (alchemist-macroexpand-expand-and-print-request (thing-at-point 'line))) + +(defun alchemist-macroexpand-once-current-line () + "Macro expand the Elixir code on the current line." + (interactive) + (alchemist-macroexpand-expand-once-request (thing-at-point 'line))) + +(defun alchemist-macroexpand-once-print-current-line () + "Macro expand the Elixir code on the current line and insert the result." + (interactive) + (alchemist-macroexpand-expand-once-and-print-request (thing-at-point 'line))) + +(defun alchemist-macroexpand-print-region (beg end) + "Macro expand the Elixir code on marked region and insert the result." + (interactive (list (point) (mark))) + (unless (and beg end) + (error "The mark is not set now, so there is no region")) + (let ((string (buffer-substring-no-properties beg end))) + (when (> end beg) + (exchange-point-and-mark)) + (alchemist-macroexpand-expand-and-print-request string))) + +(defun alchemist-macroexpand-region (beg end) + "Macro expand the Elixir code on marked region." + (interactive (list (point) (mark))) + (unless (and beg end) + (error "The mark is not set now, so there is no region")) + (let ((string (buffer-substring-no-properties beg end))) + (alchemist-macroexpand-expand-request string))) + +(defun alchemist-macroexpand-once-print-region (beg end) + "Macro expand the Elixir code on marked region once and insert the result." + (interactive "r") + (let ((string (buffer-substring-no-properties beg end))) + (when (> end beg) + (exchange-point-and-mark)) + (alchemist-macroexpand-expand-once-and-print-request string))) + +(defun alchemist-macroexpand-once-region (beg end) + "Macro expand the Elixir code on marked region once." + (interactive (list (point) (mark))) + (unless (and beg end) + (error "The mark is not set now, so there is no region")) + (let ((string (buffer-substring-no-properties beg end))) + (alchemist-macroexpand-expand-once-request string))) + +(defun alchemist-macroexpand-close-popup () + "Quit the macroexpand buffer window." + (interactive) + (quit-windows-on alchemist-macroexpand-buffer-name)) + +(defvar alchemist-macroexpand-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "q") #'quit-window) + map) + "Keymap for `alchemist-macroexpand-mode'.") + +(define-minor-mode alchemist-macroexpand-mode + "Minor mode for Alchemist Elixir macroexpand functionality. + +\\{alchemist-macroexpand-mode-map}" + nil + alchemist-macroexpand-mode-map) + +(provide 'alchemist-macroexpand) + +;;; alchemist-macroexpand.el ends here diff --git a/emacs.d/elpa/alchemist-20150624.159/alchemist-message.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-message.el similarity index 100% rename from emacs.d/elpa/alchemist-20150624.159/alchemist-message.el rename to emacs.d/elpa/alchemist-20160111.2340/alchemist-message.el diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-mix.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-mix.el new file mode 100644 index 0000000..5585bd4 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-mix.el @@ -0,0 +1,227 @@ +;;; alchemist-mix.el --- Interface to run Elixir mix tasks inside Emacs + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Interface to run Elixir mix tasks inside Emacs. + +;;; Code: + +(require 'alchemist-utils) +(require 'alchemist-project) +(require 'alchemist-test-mode) +(require 'alchemist-server) + +(defgroup alchemist-mix nil + "Emacs integration for Elixir's mix." + :prefix "alchemist-mix-" + :group 'alchemist) + +;; Variables + +(defvar alchemist-last-run-test nil) +(defvar alchemist-mix-filter-output nil) + +(defcustom alchemist-mix-command "mix" + "The shell command for mix." + :type 'string + :group 'alchemist-mix) + +(defcustom alchemist-mix-test-task "test" + "Default task to run tests." + :type 'string + :group 'alchemist-mix) + +(defcustom alchemist-mix-test-default-options '() + "Default options for alchemist test command." + :type '(repeat string) + :group 'alchemist-mix) + +(defcustom alchemist-mix-env nil + "The default mix env to run mix commands with. If nil, the mix env is +not set explicitly." + :type '(string boolean) + :group 'alchemist-mix) + +(defvar alchemist-mix-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "q" #'quit-window) + (define-key map "i" #'alchemist-mix-send-input-to-mix-process) + map)) + +(defvar alchemist-mix-buffer-name "*alchemist mix*" + "Name of the mix output buffer.") + +(defvar alchemist-mix--envs '("dev" "prod" "test") + "The list of mix envs to use as defaults.") + +;; Private functions + +(defun alchemist-mix--completing-read (prompt cmdlist) + (completing-read prompt cmdlist nil t nil nil (car cmdlist))) + +(defun alchemist-mix--execute-test (&optional what) + "Execute 'mix test' on the given `WHAT'. + +`WHAT' could be a filename, a filename:line string or the empty string (meaning +run all tests)." + (if what + (setq alchemist-last-run-test what) + (setq alchemist-last-run-test "")) + (alchemist-test-execute (list "mix" + alchemist-mix-test-task + what + alchemist-mix-test-default-options))) + +(defun alchemist-mix--test-file (filename) + "Run a specific FILENAME as argument for the mix command test." + (when (not (file-exists-p filename)) + (error "The given file doesn't exist")) + (alchemist-mix--execute-test (expand-file-name filename))) + +;; Public functions + +(defun alchemist-mix () + "Prompt for a specific mix task to run. + +If the command `universal-argument' is called before `alchemist-mix', +a prompt for a specific mix environment in which the task will be +executed, gets called." + (interactive) + (alchemist-server-info "{ :type, :mixtasks }" #'alchemist-mix-filter)) + +(defun alchemist-mix-display-mix-buffer () + "Display the mix buffer when exists." + (interactive) + (when (get-buffer alchemist-mix-buffer-name) + (display-buffer alchemist-mix-buffer-name))) + +(defun alchemist-mix-test () + "Run the whole elixir test suite." + (interactive) + (alchemist-mix--execute-test)) + +(defun alchemist-mix-test-this-buffer () + "Run the current buffer through mix test." + (interactive) + (alchemist-mix--test-file buffer-file-name)) + +(defun alchemist-mix-test-file (filename) + "Run `alchemist-mix--test-file' with the FILENAME." + (interactive "Fmix test: ") + (alchemist-mix--test-file (expand-file-name filename))) + +(defun alchemist-mix-test-at-point () + "Run the test at point." + (interactive) + (let* ((line (line-number-at-pos (point))) + (file-and-line (format "%s:%s" buffer-file-name line))) + (alchemist-mix--execute-test file-and-line))) + +(defun alchemist-mix-rerun-last-test () + "Rerun the last test that was run by alchemist. + +When no tests had been run before calling this function, do nothing." + (interactive) + (if alchemist-last-run-test + (alchemist-mix--execute-test alchemist-last-run-test) + (message "No tests have been run yet"))) + +(defun alchemist-mix-compile (command &optional prefix) + "Compile the whole elixir project. Prompt for the mix env if the prefix +arg is set." + (interactive "Mmix compile: \nP") + (alchemist-mix-execute (list "compile" command) prefix)) + +(defun alchemist-mix-run (command &optional prefix) + "Runs the given file or expression in the context of the application." + (interactive "Mmix run: \nP") + (alchemist-mix-execute (list "run" command) prefix)) + +(defun alchemist-mix-send-input-to-mix-process (input) + "Send INPUT to the current running mix task process." + (interactive "MSend to running mix task: ") + (let* ((buffer (get-buffer alchemist-mix-buffer-name)) + (process (get-buffer-process buffer))) + (if (and process (eq (process-status process) 'run)) + (with-current-buffer buffer + (let ((inhibit-read-only t)) + (goto-char (point-max)) + (insert (concat input "\n\n")) + (set-marker (process-mark process) (point))) + (comint-send-string process (concat input "\n"))) + (error "No %s process is running" alchemist-mix-buffer-name)))) + +(defun alchemist-mix-help () (interactive) + (alchemist-utils-deprecated-message "alchemist-mix-help" "alchemist-mix")) +(defun alchemist-mix-new () (interactive) + (alchemist-utils-deprecated-message "alchemist-mix-new" "alchemist-mix")) +(defun alchemist-mix-deps () (interactive) + (alchemist-utils-deprecated-message "alchemist-mix-deps" "alchemist-mix")) +(defun alchemist-mix-deps-with-prompt () (interactive) + (alchemist-utils-deprecated-message "alchemist-mix-deps-with-prompt" "alchemist-mix")) +(defun alchemist-mix-local-with-prompt () (interactive) + (alchemist-utils-deprecated-message "alchemist-mix-local-with-prompt" "alchemist-mix")) +(defun alchemist-mix-local () (interactive) + (alchemist-utils-deprecated-message "alchemist-mix-local" "alchemist-mix")) +(defun alchemist-mix-local-install () (interactive) + (alchemist-utils-deprecated-message "alchemist-mix-local-install" "alchemist-mix")) +(defun alchemist-mix-local-with-url () (interactive) + (alchemist-utils-deprecated-message "alchemist-mix-local-with-url" "alchemist-mix")) +(defun alchemist-mix-local-with-path () (interactive) + (alchemist-utils-deprecated-message "alchemist-mix-local-with-path" "alchemist-mix")) +(defun alchemist-mix-hex-search () (interactive) + (alchemist-utils-deprecated-message "alchemist-mix-local-hex-search" "alchemist-mix")) + +(defun alchemist-mix-filter (_process output) + (with-local-quit + (setq alchemist-mix-filter-output (cons output alchemist-mix-filter-output)) + (when (alchemist-server-contains-end-marker-p output) + (let* ((output (alchemist-server-prepare-filter-output alchemist-mix-filter-output)) + (tasks (split-string output "\n")) + (selected-task (alchemist-mix--completing-read "mix: " tasks)) + (command (read-shell-command "mix " (concat selected-task " ")))) + (setq alchemist-mix-filter-output nil) + (alchemist-mix-execute (list command) current-prefix-arg))))) + +(define-derived-mode alchemist-mix-mode fundamental-mode "Mix Mode" + "Major mode for presenting Mix tasks. + +\\{alchemist-mix-mode-map}" + (setq buffer-read-only t) + (setq-local truncate-lines t) + (setq-local electric-indent-chars nil)) + +(defun alchemist-mix-execute (command-list &optional prefix) + "Run a mix task specified by COMMAND-LIST. + +If PREFIX is non-nil, prompt for a mix environment variable." + (let* ((mix-env (if prefix + (completing-read "mix env: " alchemist-mix--envs nil nil alchemist-mix-env) + alchemist-mix-env)) + (command (alchemist-utils-build-command + (list (when mix-env (concat "MIX_ENV=" mix-env)) + alchemist-mix-command command-list)))) + (alchemist-report-run command "alchemist-mix-report" alchemist-mix-buffer-name 'alchemist-mix-mode))) + +(provide 'alchemist-mix) + +;;; alchemist-mix.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-phoenix.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-phoenix.el new file mode 100644 index 0000000..1d06004 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-phoenix.el @@ -0,0 +1,145 @@ +;;; alchemist-phoenix.el --- Minor mode for the Phoenix web framework + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Minor mode for the Phoenix web framework + +;;; Code: + +(require 'alchemist-key) +(require 'alchemist-project) + +(defgroup alchemist-phoenix nil + "Minor mode for the Phoenix web framework." + :prefix "alchemist-phoenix-" + :group 'alchemist) + +;;;###autoload +(defun alchemist-phoenix-project-p () + "Return non-nil if `default-directory' is inside an Phoenix project." + (and (alchemist-project-p) + (file-directory-p (concat (alchemist-project-root) "web")))) + +(defun alchemist-phoenix-find-dir (directory) + (unless (alchemist-phoenix-project-p) + (error "Could not find an Phoenix Mix project root.")) + (alchemist-file-find-files (alchemist-project-root) directory)) + +(defun alchemist-phoenix-find-web () + (interactive) + (alchemist-phoenix-find-dir "web")) + +(defun alchemist-phoenix-find-views () + (interactive) + (alchemist-phoenix-find-dir "web/views")) + +(defun alchemist-phoenix-find-controllers () + (interactive) + (alchemist-phoenix-find-dir "web/controllers")) + +(defun alchemist-phoenix-find-channels () + (interactive) + (alchemist-phoenix-find-dir "web/channels")) + +(defun alchemist-phoenix-find-templates () + (interactive) + (alchemist-phoenix-find-dir "web/templates")) + +(defun alchemist-phoenix-find-models () + (interactive) + (alchemist-phoenix-find-dir "web/models")) + +(defun alchemist-phoenix-find-static () + (interactive) + (alchemist-phoenix-find-dir "web/static")) + +(defun alchemist-phoenix-routes (&optional prefix) + (interactive) + "Run the Mix task 'phoenix.routes' and list all available Phoenix routes." + (alchemist-mix-execute '("phoenix.routes") prefix)) + +(defun alchemist-phoenix-router () + "Open the 'router.ex' file from 'web' directory." + (interactive) + (unless (alchemist-phoenix-project-p) + (error "Could not find an Phoenix Mix project root.")) + (find-file (concat (alchemist-project-root) "web/router.ex"))) + +(defvar alchemist-phoenix-command-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "n w") #'alchemist-phoenix-find-web) + (define-key map (kbd "n v") #'alchemist-phoenix-find-views) + (define-key map (kbd "n c") #'alchemist-phoenix-find-controllers) + (define-key map (kbd "n l") #'alchemist-phoenix-find-channels) + (define-key map (kbd "n t") #'alchemist-phoenix-find-templates) + (define-key map (kbd "n m") #'alchemist-phoenix-find-models) + (define-key map (kbd "n s") #'alchemist-phoenix-find-static) + (define-key map (kbd "n r") #'alchemist-phoenix-router) + (define-key map (kbd "n R") #'alchemist-phoenix-routes) + map) + "Keymap for Alchemist Phoenix commands after `alchemist-key-command-prefix'.") +(fset 'alchemist-phoenix-command-map alchemist-phoenix-command-map) + +(defvar alchemist-phoenix-mode-map + (let ((map (make-sparse-keymap))) + (define-key map alchemist-key-command-prefix 'alchemist-phoenix-command-map) + map) + "Keymap for Alchemist Phoenix minor mode.") + +(easy-menu-define alchemist-mode-menu alchemist-phoenix-mode-map + "Menu for Alchemist-Phoenix mode." + '("Phoenix" + ("Directory lookup" + ["Lookup 'web' " alchemist-phoenix-find-web] + ["Lookup 'web/views' " alchemist-phoenix-find-views] + ["Lookup 'web/controllers' " alchemist-phoenix-find-controllers] + ["Lookup 'web/channels' " alchemist-phoenix-find-channels] + ["Lookup 'web/templates' " alchemist-phoenix-find-templates] + ["Lookup 'web/models' " alchemist-phoenix-find-models] + ["Lookup 'web/static'" alchemist-phoenix-find-static]) + ("Mix tasks" + ["Run 'phoenix.routes'" alchemist-phoenix-routes]) + ["Open the 'router.ex' file" alchemist-phoenix-router])) + +;;;###autoload +(define-minor-mode alchemist-phoenix-mode + "Minor mode for Elixir Phoenix web framework projects. + +The following commands are available: + +\\{alchemist-phoenix-mode-map}" + :lighter " alchemist-phoenix" + :keymap alchemist-phoenix-mode-map + :group 'alchemist) + +;;;###autoload +(defun alchemist-phoenix-enable-mode () + (when (alchemist-phoenix-project-p) + (alchemist-phoenix-mode))) + +;;;###autoload +(dolist (hook '(alchemist-mode-hook)) + (add-hook hook 'alchemist-phoenix-enable-mode)) + +(provide 'alchemist-phoenix) + +;;; alchemist-phoenix.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-pkg.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-pkg.el new file mode 100644 index 0000000..c155e2d --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-pkg.el @@ -0,0 +1,11 @@ +(define-package "alchemist" "20160111.2340" "Elixir tooling integration into Emacs" + '((elixir-mode "2.2.5") + (dash "2.11.0") + (emacs "24.4") + (company "0.8.0") + (pkg-info "0.4")) + :url "http://www.github.com/tonini/alchemist.el" :keywords + '("languages" "elixir" "elixirc" "mix" "hex" "alchemist")) +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-project.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-project.el new file mode 100644 index 0000000..0aa19c5 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-project.el @@ -0,0 +1,222 @@ +;;; alchemist-project.el --- API to identify Elixir mix projects. + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; API to identify Elixir mix projects. + +;;; Code: + +(require 'cl-lib) +(require 'dash) +(require 'alchemist-utils) +(require 'alchemist-file) + +(defgroup alchemist-project nil + "API to identify Elixir mix projects." + :prefix "alchemist-help-" + :group 'alchemist) + +(defconst alchemist-project-mix-project-indicator "mix.exs" + "File which indicates the root directory of an Elixir Mix project.") + +(defconst alchemist-project-hex-pkg-indicator ".hex" + "File which indicates the root directory of an Elixir Hex package.") + +(defun alchemist-project-elixir-p () + "Return non-nil if `default-directory' is inside the Elixir source codebase." + (stringp (alchemist-project-elixir-root))) + +(defun alchemist-project-elixir-root (&optional dir) + "Return root directory of the Elixir source." + (let* ((dir (file-name-as-directory (or dir (expand-file-name default-directory)))) + (present-files (directory-files dir))) + (cond ((alchemist-project-top-level-dir-p dir) + nil) + ((and (-contains-p present-files "eex") + (-contains-p present-files "elixir") + (-contains-p present-files "logger") + (-contains-p present-files "mix") + (-contains-p present-files "iex") + (-contains-p present-files "ex_unit")) + (file-name-directory (directory-file-name dir))) + (t (alchemist-project-elixir-root (file-name-directory (directory-file-name dir))))))) + +(defun alchemist-project-p () + "Return non-nil if `default-directory' is inside an Elixir Mix project." + (stringp (alchemist-project-root))) + +(defun alchemist-project-top-level-dir-p (dir) + "Return non-nil if DIR is the top level directory." + (equal dir (file-name-directory (directory-file-name dir)))) + +(defun alchemist-project-root (&optional dir) + "Return root directory of the current Elixir Mix project. + +It starts walking the directory tree to find the Elixir Mix root directory +from `default-directory'. If DIR is non-nil it starts walking the +directory from there instead." + (let* ((dir (file-name-as-directory (or dir (expand-file-name default-directory)))) + (present-files (directory-files dir))) + (cond ((alchemist-project-top-level-dir-p dir) + nil) + ((-contains-p present-files alchemist-project-hex-pkg-indicator) + (alchemist-project-root (file-name-directory (directory-file-name dir)))) + ((-contains-p present-files alchemist-project-mix-project-indicator) + dir) + (t + (alchemist-project-root (file-name-directory (directory-file-name dir))))))) + +(defun alchemist-project-root-or-default-dir () + "Return the current Elixir mix project root or `default-directory'." + (let* ((project-root (alchemist-project-root)) + (dir (if project-root + project-root + default-directory))) + dir)) + +(defun alchemist-project-toggle-file-and-tests-other-window () + "Toggle between a file and its tests in other window." + (interactive) + (if (alchemist-utils-test-file-p) + (alchemist-project-open-file-for-current-tests 'find-file-other-window) + (alchemist-project-open-tests-for-current-file 'find-file-other-window))) + +(defun alchemist-project-toggle-file-and-tests () + "Toggle between a file and its tests in the current window." + (interactive) + (if (alchemist-utils-test-file-p) + (alchemist-project-open-file-for-current-tests 'find-file) + (alchemist-project-open-tests-for-current-file 'find-file))) + +(defun alchemist-project-file-under-test (file directory) + "Return the file which are tested by FILE. +DIRECTORY is the place where the file under test is located." + (let* ((filename (file-relative-name file (alchemist-project-root))) + (filename (replace-regexp-in-string "^test" directory filename)) + (filename (replace-regexp-in-string "_test\.exs$" "\.ex" filename))) + (concat (alchemist-project-root) filename))) + +(defun alchemist-project-open-file-for-current-tests (opener) + "Visit the implementation file for the current buffer with OPENER." + (let* ((filename (alchemist-project-file-under-test (buffer-file-name) "web")) + (filename (if (file-exists-p filename) + filename + (alchemist-project-file-under-test (buffer-file-name) "lib")))) + (funcall opener filename))) + +(defun alchemist-project-open-tests-for-current-file (opener) + "Visit the test file for the current buffer with OPENER." + (let* ((filename (file-relative-name (buffer-file-name) (alchemist-project-root))) + (filename (replace-regexp-in-string "^lib/" "test/" filename)) + (filename (replace-regexp-in-string "^web/" "test/" filename)) + (filename (replace-regexp-in-string "\.ex$" "_test\.exs" filename)) + (filename (format "%s/%s" (alchemist-project-root) filename))) + (if (file-exists-p filename) + (funcall opener filename) + (if (y-or-n-p "No test file found; create one now?") + (alchemist-project--create-test-for-current-file + filename (current-buffer)) + (message "No test file found."))))) + +(defun alchemist-project--create-test-for-current-file (filename buffer) + "Creates and populates a test module, FILENAME, for the code in BUFFER. +The module name given to the test module is determined from the name of the +first module defined in BUFFER." + (let* ((directory-name (file-name-directory filename)) + (module-name (alchemist-project--grok-module-name buffer)) + (test-module-name (concat module-name "Test"))) + (unless (file-exists-p directory-name) + (make-directory (file-name-directory filename) t)) + (alchemist-project--insert-test-boilerplate + (find-file-other-window filename) test-module-name))) + +(defun alchemist-project--grok-module-name (buffer) + "Determines the name of the first module defined in BUFFER." + (save-excursion + (with-current-buffer buffer + (goto-char (point-min)) + (re-search-forward "defmodule\\s-\\(.+?\\)\\s-?,?\\s-do") + (match-string 1)))) + +(defun alchemist-project--insert-test-boilerplate (buffer module) + "Inserts ExUnit boilerplate for MODULE in BUFFER. +Point is left in a convenient location." + (with-current-buffer buffer + (insert (concat "defmodule " module " do\n" + " use ExUnit.Case\n\n\n" + "end\n")) + (goto-char (point-min)) + (beginning-of-line 4) + (indent-according-to-mode))) + +(defun alchemist-project-run-tests-for-current-file () + "Run the tests related to the current file." + (interactive) + (alchemist-project-open-tests-for-current-file 'alchemist-mix-test-file)) + +(defun alchemist-project-create-file () + "Create a file under lib/ in the current project. + +The newly created buffer is filled with a module definition based on the file name." + (interactive) + (let ((root (alchemist-project-root))) + (if (not root) + (message "You're not in a Mix project") + (let* ((lib-path (concat root "lib/")) + (abs-path (read-file-name "New file in lib/: " lib-path)) + (abs-path (alchemist-utils-add-ext-to-path-if-not-present abs-path ".ex")) + (relative-path (file-relative-name abs-path lib-path))) + (if (file-readable-p abs-path) + (message "%s already exists" relative-path) + (make-directory (file-name-directory abs-path) t) + (find-file abs-path) + (insert (concat "defmodule " + (alchemist-utils-path-to-module-name relative-path) + " do\n" + " \n" + "end\n")) + (goto-char (point-min)) + (beginning-of-line 2) + (back-to-indentation)))))) + +(defun alchemist-project-name () + "Return the name of the current Elixir Mix project." + (if (alchemist-project-p) + (car (cdr (reverse (split-string (alchemist-project-root) "/")))) + "")) + +(defun alchemist-project-find-dir (directory) + (unless (alchemist-project-p) + (error "Could not find an Elixir Mix project root.")) + (alchemist-file-find-files (alchemist-project-root) directory)) + +(defun alchemist-project-find-lib () + (interactive) + (alchemist-project-find-dir "lib")) + +(defun alchemist-project-find-test () + (interactive) + (alchemist-project-find-dir "test")) + +(provide 'alchemist-project) + +;;; alchemist-project.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-refcard.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-refcard.el new file mode 100644 index 0000000..1ca791f --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-refcard.el @@ -0,0 +1,201 @@ +;;; alchemist-refcard.el --- Generates a refcard of alchemist functionality + +;; Copyright © 2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Generates a refcard of alchemist functionality + +;;; Code: + +(require 'cl-lib) +(require 'dash) +(require 'tabulated-list) + +;; Tell the byte compiler about autoloaded functions from packages +(eval-when-compile + (declare-function alchemist-mode "alchemist.el") + (declare-function alchemist-version "alchemist.el")) + +(defgroup alchemist-refcard nil + "Generate a refcard of alchemist functionality." + :prefix "alchemist-" + :group 'applications) + +(defconst alchemist-refcard--buffer-name "*alchemist-refcard*" + "Name of Alchemist-Refcard mode buffer.") + +(defconst alchemist-refcard-list-format + [("" 55 t) + ("" 35 t)] + "List format.") + +(defvar alchemist-refcard-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "i") 'alchemist-refcard--describe-funtion-at-point) + (define-key map (kbd "q") 'quit-window) + map) + "Keymap for `alchemist-refcard-mode'.") + +(defun alchemist-refcard--get-keybinding (function-name) + (let* ((keys (where-is-internal (intern function-name))) + (keys (-map (lambda (k) + (let ((key (format "%s" k))) + (if (string-match-p "menu-bar" key) + nil + k))) keys)) + (keys (-remove 'null keys))) + (if keys + (progn + (mapconcat (lambda (k) (key-description k)) keys " , ")) + ""))) + +(defun alchemist-refcard--tabulated-list-entries () + (alchemist-mode +1) ;; needs to be enabled for fetching current keybindings + (let ((rows (list (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-refcard-title-row (format "Alchemist Refcard v%s" (alchemist-version))) + (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-title-row "Mix") + (alchemist-refcard--build-tabulated-row "alchemist-mix") + (alchemist-refcard--build-tabulated-row "alchemist-mix-compile") + (alchemist-refcard--build-tabulated-row "alchemist-mix-run") + (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-title-row "Testing") + (alchemist-refcard--build-tabulated-row "alchemist-mix-test") + (alchemist-refcard--build-tabulated-row "alchemist-mix-rerun-last-test") + (alchemist-refcard--build-tabulated-row "alchemist-mix-test-file") + (alchemist-refcard--build-tabulated-row "alchemist-mix-test-this-buffer") + (alchemist-refcard--build-tabulated-row "alchemist-mix-test-at-point") + (alchemist-refcard--build-tabulated-row "alchemist-test-toggle-test-report-display") + (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-title-row "Compilation") + (alchemist-refcard--build-tabulated-row "alchemist-compile") + (alchemist-refcard--build-tabulated-row "alchemist-compile-file") + (alchemist-refcard--build-tabulated-row "alchemist-compile-this-buffer") + (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-title-row "Execution") + (alchemist-refcard--build-tabulated-row "alchemist-execute") + (alchemist-refcard--build-tabulated-row "alchemist-execute-file") + (alchemist-refcard--build-tabulated-row "alchemist-execute-this-buffer") + (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-title-row "Documentation Lookup") + (alchemist-refcard--build-tabulated-row "alchemist-help") + (alchemist-refcard--build-tabulated-row "alchemist-help-history") + (alchemist-refcard--build-tabulated-row "alchemist-help-search-at-point") + (alchemist-refcard--build-tabulated-row "alchemist-refcard") + (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-title-row "Definition Lookup") + (alchemist-refcard--build-tabulated-row "alchemist-goto-definition-at-point") + (alchemist-refcard--build-tabulated-row "alchemist-goto-jump-back") + (alchemist-refcard--build-tabulated-row "alchemist-goto-jump-to-previous-def-symbol") + (alchemist-refcard--build-tabulated-row "alchemist-goto-jump-to-next-def-symbol") + (alchemist-refcard--build-tabulated-row "alchemist-goto-list-symbol-definitions") + (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-title-row "Project") + (alchemist-refcard--build-tabulated-row "alchemist-project-find-test") + (alchemist-refcard--build-tabulated-row "alchemist-project-toggle-file-and-tests") + (alchemist-refcard--build-tabulated-row "alchemist-project-toggle-file-and-tests-other-window") + (alchemist-refcard--build-tabulated-row "alchemist-project-run-tests-for-current-file") + (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-title-row "IEx") + (alchemist-refcard--build-tabulated-row "alchemist-iex-run") + (alchemist-refcard--build-tabulated-row "alchemist-iex-project-run") + (alchemist-refcard--build-tabulated-row "alchemist-iex-send-current-line") + (alchemist-refcard--build-tabulated-row "alchemist-iex-send-current-line-and-go") + (alchemist-refcard--build-tabulated-row "alchemist-iex-send-region") + (alchemist-refcard--build-tabulated-row "alchemist-iex-send-region-and-go") + (alchemist-refcard--build-tabulated-row "alchemist-iex-compile-this-buffer") + (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-title-row "Eval") + (alchemist-refcard--build-tabulated-row "alchemist-eval-current-line") + (alchemist-refcard--build-tabulated-row "alchemist-eval-print-current-line") + (alchemist-refcard--build-tabulated-row "alchemist-eval-quoted-current-line") + (alchemist-refcard--build-tabulated-row "alchemist-eval-print-quoted-current-line") + (alchemist-refcard--build-tabulated-row "alchemist-eval-region") + (alchemist-refcard--build-tabulated-row "alchemist-eval-print-region") + (alchemist-refcard--build-tabulated-row "alchemist-eval-quoted-region") + (alchemist-refcard--build-tabulated-row "alchemist-eval-print-quoted-region") + (alchemist-refcard--build-tabulated-row "alchemist-eval-buffer") + (alchemist-refcard--build-tabulated-row "alchemist-eval-print-buffer") + (alchemist-refcard--build-tabulated-row "alchemist-eval-quoted-buffer") + (alchemist-refcard--build-tabulated-row "alchemist-eval-print-quoted-buffer") + (alchemist-refcard--build-tabulated-row "alchemist-eval-close-popup") + (alchemist-refcard--build-empty-tabulated-row) + (alchemist-refcard--build-tabulated-title-row "Macroexpand") + (alchemist-refcard--build-tabulated-row "alchemist-macroexpand-once-current-line") + (alchemist-refcard--build-tabulated-row "alchemist-macroexpand-once-print-current-line") + (alchemist-refcard--build-tabulated-row "alchemist-macroexpand-current-line") + (alchemist-refcard--build-tabulated-row "alchemist-macroexpand-print-current-line") + (alchemist-refcard--build-tabulated-row "alchemist-macroexpand-once-region") + (alchemist-refcard--build-tabulated-row "alchemist-macroexpand-once-print-region") + (alchemist-refcard--build-tabulated-row "alchemist-macroexpand-region") + (alchemist-refcard--build-tabulated-row "alchemist-macroexpand-print-region") + (alchemist-refcard--build-tabulated-row "alchemist-macroexpand-close-popup")))) + (alchemist-mode -1) ;; disable it after getting the current keybindings + rows)) + +(defun alchemist-refcard--build-empty-tabulated-row () + (list "" `[,"" ""])) + +(defun alchemist-refcard--build-tabulated-row (function-name) + (list function-name `[,function-name + ,(propertize (alchemist-refcard--get-keybinding function-name) 'face font-lock-builtin-face)])) + +(defun alchemist-refcard--build-tabulated-refcard-title-row (title) + (list "" `[,(propertize title 'face font-lock-variable-name-face) ""])) + +(defun alchemist-refcard--build-tabulated-title-row (title) + (list "" `[,(propertize title 'face font-lock-constant-face) ""])) + +(defun alchemist-refcard--describe-funtion-at-point () + (interactive) + (let ((function-name (get-text-property (point) 'tabulated-list-id))) + (when (not (alchemist-utils-empty-string-p function-name)) + (describe-function (intern function-name))))) + +(defun alchemist-refcard--buffer () + "Return alchemist-refcard buffer if it exists." + (get-buffer alchemist-refcard--buffer-name)) + +(define-derived-mode alchemist-refcard-mode tabulated-list-mode "Alchemist" + "Alchemist refcard mode." + (buffer-disable-undo) + (kill-all-local-variables) + (setq truncate-lines t) + (setq mode-name "Alchemist-Refcard") + (setq-local alchemist-test-status-modeline nil) + (use-local-map alchemist-refcard-mode-map) + (setq tabulated-list-format alchemist-refcard-list-format) + (setq tabulated-list-entries 'alchemist-refcard--tabulated-list-entries) + (tabulated-list-print)) + +;;;###autoload +(defun alchemist-refcard () + "Generate an Alchemist refcard of all the features." + (interactive) + (let ((buffer-p (alchemist-refcard--buffer)) + (buffer (get-buffer-create alchemist-refcard--buffer-name))) + (pop-to-buffer buffer) + (unless buffer-p + (alchemist-refcard-mode)))) + +(provide 'alchemist-refcard) + +;;; alchemist-refcard.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-report.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-report.el new file mode 100644 index 0000000..d5f4023 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-report.el @@ -0,0 +1,167 @@ +;;; alchemist-report.el --- Run command in a process and handles buffer of it + +;; Copyright © 2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Run command in a process and handles buffer output and display + +;;; Code: + +(require 'ansi-color) +(require 'alchemist-project) + +(defgroup alchemist-report nil + "Run command in a process and handles buffer output and display" + :prefix "alchemist-report-" + :group 'alchemist) + +(defvar alchemist-report-on-exit nil) +(defvar alchemist-report-on-exit-function nil) +(defvar alchemist-report-on-render nil) +(defvar alchemist-report-on-render-function nil) +(defvar alchemist-report--last-run-status nil) +(defvar alchemist-report-mode-name nil) + +(defun alchemist-report--kill-process (process) + "Interrupt and kill the running report PROCESS." + (when process + (let ((mode-name (replace-regexp-in-string ":.+$" "" mode-name))) + (if (or (not (eq (process-status process) 'run)) + (eq (process-query-on-exit-flag process) nil) + (yes-or-no-p + (format "A %s process already running; kill it? " + mode-name))) + (condition-case () + (progn + (interrupt-process process) + (sit-for 1) + (delete-process process)) + (error nil)) + (error "Cannot have two processes in `%s' at once" + (buffer-name)))))) + +(defun alchemist-report--sentinel (process status) + "Sentinel for test report buffer." + (if (memq (process-status process) '(exit signal)) + (let ((buffer (process-buffer process))) + (if (null (buffer-name buffer)) + (set-process-buffer process nil) + (progn + (alchemist-report--render-report buffer) + (alchemist-report--handle-exit status buffer) + (alchemist-report-update-mode-name process) + (delete-process process)))))) + +(defun alchemist-report--render-report (buffer) + "Call the defined render functions for the BUFFER." + (when alchemist-report-on-render-function + (funcall alchemist-report-on-render-function buffer))) + +(defun alchemist-report--handle-exit (status buffer) + "Call the defined exit function specified in `alchemist-report-on-exit-function'. +Argument for the exit function is the STATUS and BUFFER of the finished process." + (alchemist-report--store-process-status status) + (when alchemist-report-on-exit-function + (funcall alchemist-report-on-exit-function status buffer))) + +(defun alchemist-report--store-process-status (status) + "Store STATUS of the last finished process." + (setq alchemist-report--last-run-status status)) + +(defun alchemist-report--last-run-successful-p () + "Return non-nil if the last process successfully finished." + (when (string-prefix-p "finished" alchemist-report--last-run-status) t)) + +(defun alchemist-report-filter (process output) + "Process filter for report buffers." + (with-current-buffer (process-buffer process) + (let* ((buffer-read-only nil) + (output (if (string= (process-name process) alchemist-test-report-process-name) + (alchemist-test-clean-compilation-output output) + output)) + (moving (= (point) (process-mark process)))) + (save-excursion + (goto-char (process-mark process)) + (insert output) + (set-marker (process-mark process) (point)) + (ansi-color-apply-on-region (point-min) (point-max))) + (if moving (goto-char (process-mark process)))))) + +(defun alchemist-report-update-mode-name (process) + "Update the `mode-name' with the status of PROCESS." + (with-current-buffer (process-buffer process) + (setq-local mode-name (format "%s:%s" + (replace-regexp-in-string ":.+$" "" mode-name) + (process-status process))))) + +(defun alchemist-report-interrupt-current-process () + "Interrupt the current running report process." + (interactive) + (let ((buffer (current-buffer)) + (name (replace-regexp-in-string ":.+" "" mode-name))) + (if (get-buffer-process buffer) + (interrupt-process (get-buffer-process buffer)) + (error "The [%s] process is not running" (downcase name))))) + +(defun alchemist-report-cleanup-process-buffer (buffer) + "Clean the content BUFFER of process. +If there is already a running process, ask for interrupting it." + (with-current-buffer buffer + (let ((inhibit-read-only t) + (process (get-buffer-process buffer))) + (erase-buffer)))) + +(defun alchemist-report-display-buffer (buffer) + "Display the BUFFER." + (display-buffer buffer)) + +(defun alchemist-report-activate-mode (mode buffer) + "Enable MODE inside BUFFER." + (with-current-buffer buffer + (funcall mode) + (setq-local truncate-lines t) ;; Do not display continuation lines. + (setq-local window-point-insertion-type t))) + +(defun alchemist-report-run (command process-name buffer-name mode &optional on-exit hidden) + "Run COMMAND in a new process called PROCESS-NAME. +The output of PROCESS-NAME will be displayed in BUFFER-NAME. +After displaying BUFFER-NAME, the MODE function will be called within. + +Optional ON-EXIT and HIDDEN functions could be defined. +The function ON-EXIT will be called when PROCESS-NAME is finished. +The HIDDEN variable defines if PROCESS-NAME should run in the background." + (let* ((buffer (get-buffer-create buffer-name)) + (default-directory (alchemist-project-root-or-default-dir))) + (alchemist-report-cleanup-process-buffer buffer) + (alchemist-report--kill-process (get-buffer-process buffer)) + (start-process-shell-command process-name buffer command) + (when on-exit + (setq alchemist-report-on-exit-function on-exit)) + (set-process-sentinel (get-buffer-process buffer) 'alchemist-report--sentinel) + (set-process-filter (get-buffer-process buffer) 'alchemist-report-filter) + (alchemist-report-activate-mode mode buffer) + (if (not hidden) + (alchemist-report-display-buffer buffer)) + (alchemist-report-update-mode-name (get-buffer-process buffer)))) + +(provide 'alchemist-report) + +;;; alchemist-report.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-scope.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-scope.el new file mode 100644 index 0000000..c1fafa3 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-scope.el @@ -0,0 +1,205 @@ +;;; alchemist-scope.el --- Provides information about Elixir source code context -*- lexical-binding: t -*- + +;; Copyright © 2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Provides information about the Elixir source code context. + +;;; Code: + +(require 'dash) + +(defgroup alchemist-scope nil + "Provides information about the Elixir source code context." + :prefix "alchemist-scope-" + :group 'alchemist) + +(defconst alchemist-scope-defmodule-regex "defmodule \\([A-Za-z\._]+\\)\s+" + "The regex for matching Elixir defmodule macro.") + +(defconst alchemist-scope-alias-regex + "^\s+alias\s+\\([-:_A-Za-z0-9,\.\?!\]+\\)\\(\s*,\s*as:\s*\\)?\\([-_A-Za-z0-9,\.\?!\]+\\)?\n" + "The regex for matching Elixir alias definitions. + Example: + alias Phoenix.Router.Resource, as: Special") + +(defconst alchemist-scope-alias-regex-two + "^\s+alias\s+\\([-:_A-Za-z0-9,\.\?!\]+\\)\.{\\([-:_A-Za-z0-9\s,\.\?!\]+\\)}\n" + "The regex for matching Elixir alias definitions. + Example: + alias List.Chars.{Atom, Float}") + +(defconst alchemist-scope-use-regex + "^\s+use\s+\\([A-Za-z0-9\.]+\\)" + "The regex for matching Elixir use definitions.") + +(defconst alchemist-scope-import-regex + "^\s+import\s+\\([A-Za-z0-9\.]+\\)" + "The regex for matching Elixir import definitions.") + +(defun alchemist-scope-inside-string-p () + "Return non-nil if `point' is inside a string or heredoc." + (let* ((pos (point)) + (parse-info (syntax-ppss pos))) + (or (and (nth 3 parse-info) + (nth 8 parse-info)) + (and (looking-at "\"\"\"\\|'''\\|\"\\|\'") + (match-beginning 0))))) + +(defun alchemist-scope-inside-module-p () + "Return non-nil if `point' is currently inside a module." + (save-excursion + (end-of-line) + (let ((found-flag-p nil) + (found-p nil)) + (while (and (not found-flag-p) + (re-search-backward alchemist-scope-defmodule-regex nil t)) + (when (not (alchemist-scope-inside-string-p)) + (setq found-flag-p t) + (setq found-p t))) + found-p))) + +(defun alchemist-scope-module () + "Return name from the current defmodule." + (save-excursion + (let ((found-flag-p nil) + (module-name "")) + (save-match-data + (while (and (not found-flag-p) + (re-search-backward alchemist-scope-defmodule-regex nil t)) + (when (not (alchemist-scope-inside-string-p)) + (setq module-name (match-string 1)) + (setq found-flag-p t)) + (when (equal 1 (line-number-at-pos (point))) + (setq found-flag-p t))) + module-name)))) + +(defun alchemist-scope-aliases () + "Return aliases from the current module." + (let* ((aliases '()) + (context (alchemist-scope-module))) + (save-excursion + (when (alchemist-scope-inside-module-p) + (end-of-line) + ;; alias definition like: + ;; + ;; alias Phoenix.Router.Resource, as: Special + (while (re-search-backward alchemist-scope-alias-regex nil t) + (when (and + (not (alchemist-scope-inside-string-p)) + (equal context (alchemist-scope-module))) + (let* ((alias (match-string 1)) + (as (if (match-string 3) (match-string 3) nil)) + (as (if as as (car (last (split-string alias "\\.")))))) + (setq aliases (append aliases (list (list (alchemist-utils-remove-dot-at-the-end alias) + (alchemist-utils-remove-dot-at-the-end as)))))))) + ;; alias definition like: + ;; + ;; alias List.Chars.{Atom, Float} + (while (re-search-backward alchemist-scope-alias-regex-two nil t) + (when (and + (not (alchemist-scope-inside-string-p)) + (equal context (alchemist-scope-module))) + (let* ((prefix (match-string 1)) + (alias-collection (if (match-string 2) (split-string (match-string 2) ",") nil))) + (-map (lambda (alias) + (let* ((alias (replace-regexp-in-string "\s+" "" alias)) + (namespace (format "%s.%s" prefix alias))) + (setq aliases (append aliases (list (list (alchemist-utils-remove-dot-at-the-end namespace) + (alchemist-utils-remove-dot-at-the-end alias))))))) + alias-collection)))))) + aliases)) + +(defun alchemist-scope--modules (regex) + (let ((modules '()) + (context (alchemist-scope-module))) + (save-excursion + (when (not (alchemist-utils-empty-string-p context)) + (while (re-search-backward regex nil t) + (when (and (match-string 1) + (not (alchemist-scope-inside-string-p)) + (equal context (alchemist-scope-module))) + (cl-pushnew (substring-no-properties (match-string 1)) modules)))) + modules))) + +(defun alchemist-scope-use-modules () + "Return `use' introduced module names from the current module." + (alchemist-scope--modules alchemist-scope-use-regex)) + +(defun alchemist-scope-import-modules () + "Return `import' introduced module names from the current module." + (alchemist-scope--modules alchemist-scope-import-regex)) + +(defun alchemist-scope-all-modules () + "Return `use' and `import' introduced modules from the current module." + (let ((current (alchemist-scope-module)) + (use (alchemist-scope-use-modules)) + (import (alchemist-scope-import-modules)) + (modules '())) + (push current modules) + (push use modules) + (push import modules) + (-flatten modules))) + +(defun alchemist-scope-extract-module (expr) + "Extract module from EXPR." + (let* ((parts (split-string expr "\\.")) + (function (car (last parts))) + (case-fold-search nil)) + (when (string-match-p "^[a-z_\?!]+" function) + (delete function parts)) + (unless (string-match-p "^[a-z_\?!]+" (car parts)) + (alchemist-utils-remove-dot-at-the-end (mapconcat 'concat parts "."))))) + +(defun alchemist-scope-extract-function (expr) + "Extract function from EXPR." + (let* ((parts (split-string expr "\\.")) + (function (car (last parts))) + (case-fold-search nil)) + (when (and function + (string-match-p "^[a-z_\?!]+" function)) + function))) + +(defun alchemist-scope-alias-full-path (module) + "Solve the full path for the MODULE alias." + (if (not (alchemist-utils-empty-string-p module)) + (let* ((aliases (-map (lambda (m) + (when (string-match-p (format "^%s" (car (cdr m))) module) + (replace-regexp-in-string (format "^%s" (car (cdr m))) (car m) module t))) + (alchemist-scope-aliases))) + (aliases (delete nil aliases))) + (if aliases + (car aliases) + module)))) + +(defun alchemist-scope-expression () + "Return the expression under the cursor." + (let (p1 p2) + (save-excursion + (skip-chars-backward "-_A-Za-z0-9.?!:@") + (setq p1 (point)) + (skip-chars-forward "-_A-Za-z0-9.?!:@") + (setq p2 (point)) + (buffer-substring-no-properties p1 p2)))) + +(provide 'alchemist-scope) + +;;; alchemist-scope.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server.el new file mode 100644 index 0000000..1f5fd45 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server.el @@ -0,0 +1,211 @@ +;;; alchemist-server.el --- Interface to the Alchemist Elixir server. -*- lexical-binding: t -*- + +;; Copyright © 2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Interface to the Alchemist Elixir server. + +;;; Code: + +(require 'alchemist-execute) + +(defgroup alchemist-server nil + "Interface to the Alchemist Elixir server." + :prefix "alchemist-server-" + :group 'alchemist) + +(defvar alchemist-server-processes '() + "Store running Alchemist server processes.") + +(defvar alchemist-server-env "dev" + "Default environment in for the Alchemist server.") + +(defvar alchemist-server-envs '("dev" "prod" "test" "shared") + "List of available Alchemist server environments.") + +(defconst alchemist-server + (concat (file-name-directory load-file-name) "alchemist-server/run.exs") + "Path to the Alchemist server file.") + +(defconst alchemist-server-command + (format "%s %s %s" + alchemist-execute-command + alchemist-server + alchemist-server-env) + "Alchemist server command.") + +(defconst alchemist-server-codes '((server-eval "EVAL") + (server-defl "DEFL") + (server-info "INFO") + (server-docl "DOCL") + (server-comp "COMP")) + "Alchemist server API codes.") + +(defun alchemist-server-start (env) + "Start alchemist server for the current mix project in specific ENV. + +If a server already running, the current one will be killed and new one +will be started instead." + (interactive (list + (completing-read (format "(Alchemist-Server) run in environment: (default: %s) " alchemist-server-env) + alchemist-server-envs nil nil nil))) + (when (alchemist-server-process-p) + (kill-process (alchemist-server-process))) + (alchemist-server-start-in-env env)) + +(defun alchemist-server-start-if-not-running () + "Start a new Alchemist server if not already running. + +An Alchemist server will be started for the current Elixir mix project." + (unless (alchemist-server-process-p) + (alchemist-server-start-in-env alchemist-server-env))) + +(defun alchemist-server-start-in-env (env) + "Start an Alchemist server with the ENV." + (let* ((process-name (alchemist-server-process-name)) + (default-directory (if (string= process-name "alchemist-server") + default-directory + process-name)) + (server-command (format "elixir %s %s" alchemist-server env)) + (process (start-process-shell-command process-name "*alchemist-server*" server-command))) + (set-process-query-on-exit-flag process nil) + (alchemist-server--store-process process))) + +(defun alchemist-server--store-process (process) + "Store PROCESS in `alchemist-server-processes'." + (let ((process-name (alchemist-server-process-name))) + (if (cdr (assoc process-name alchemist-server-processes)) + (setq alchemist-server-processes + (delq (assoc process-name alchemist-server-processes) alchemist-server-processes))) + (add-to-list 'alchemist-server-processes (cons process-name process)))) + +(defun alchemist-server-process-p () + "Return non-nil if a process for the current +Elixir mix project is live." + (process-live-p (alchemist-server-process))) + +(defun alchemist-server-process () + "Return process for the current Elixir mix project." + (cdr (assoc (alchemist-server-process-name) alchemist-server-processes))) + +(defun alchemist-server-process-name () + "Return process name for the current Elixir mix project." + (let* ((process-name (if (alchemist-project-elixir-p) + "alchemist-server" + (alchemist-project-root))) + (process-name (if process-name + process-name + "alchemist-server"))) + process-name)) + +(defun alchemist-server-api-code (symbol) + "Return Alchemist server API code for SYMBOL." + (car (cdr (assoc symbol alchemist-server-codes)))) + +(defconst alchemist-server-code-end-marker-regex + (format "END-OF-\\(%s\\|%s\\|%s\\|%s\\|%s\\)$" + (alchemist-server-api-code 'server-eval) + (alchemist-server-api-code 'server-defl) + (alchemist-server-api-code 'server-info) + (alchemist-server-api-code 'server-docl) + (alchemist-server-api-code 'server-comp)) + "Regular expression to identify Alchemist server API end markers.") + +(defun alchemist-server-contains-end-marker-p (string) + "Return non-nil if STRING contain an Alchemist server API end marker." + (string-match-p alchemist-server-code-end-marker-regex string)) + +(defun alchemist-server-build-request-string (code &optional args) + "Build Alchemist server request string for CODE. + +If ARGS available add them to the request string." + (let* ((code (car (cdr (assoc code alchemist-server-codes))))) + (if args + (format "%s %s\n" code args) + (format "%s\n" code)))) + +(defun alchemist-server-prepare-filter-output (output) + "Clean OUTPUT by remove Alchemist server API end markes." + (let* ((output (apply #'concat (reverse output))) + (output (replace-regexp-in-string alchemist-server-code-end-marker-regex "" output)) + (output (replace-regexp-in-string "\n+$" "" output))) + output)) + +(defun alchemist-server-send-request (string filter) + "Send STRING to Alchemist server API and set FILTER to process." + (alchemist-server-start-if-not-running) + (set-process-filter (alchemist-server-process) filter) + (process-send-string (alchemist-server-process) string)) + +(defun alchemist-server-goto (args filter) + "Make an Alchemist server source request with ARGS. + +Process server respond with FILTER." + (alchemist-server-start-if-not-running) + (alchemist-server-send-request (alchemist-server-build-request-string 'server-defl args) filter)) + +(defun alchemist-server-info (args filter) + "Make an Alchemist server mix request. + +Process server respond with FILTER." + (alchemist-server-start-if-not-running) + (alchemist-server-send-request (alchemist-server-build-request-string 'server-info args) filter)) + +(defun alchemist-server-help-with-modules (filter) + "Make an Alchemist server modules request. + +Process server respond with FILTER." + (alchemist-server-start-if-not-running) + (alchemist-server-send-request (alchemist-server-build-request-string 'server-info) filter)) + +(defun alchemist-server-help (args filter) + "Make an Alchemist server doc request with ARGS. + +Process server respond with FILTER." + (alchemist-server-start-if-not-running) + (alchemist-server-send-request (alchemist-server-build-request-string 'server-docl args) filter)) + +(defun alchemist-server-eval (args filter) + "Make an Alchemist server evaluate request with FILE. + +Process server respond with FILTER." + (alchemist-server-start-if-not-running) + (alchemist-server-send-request (alchemist-server-build-request-string 'server-eval args) filter)) + +(defun alchemist-server-complete-candidates (args filter) + "Make an Alchemist server complete request with ARGS. + +Process server respond with FILTER." + (alchemist-server-start-if-not-running) + (alchemist-server-send-request (alchemist-server-build-request-string 'server-comp args) filter)) + +(defun alchemist-server-status () + "Report the server status for the current Elixir project." + (interactive) + (message "Alchemist-Server-Status: [Project: %s Status: %s]" + (alchemist-server-process-name) + (if (alchemist-server-process-p) + "Connected" + "Not Connected"))) + +(provide 'alchemist-server) + +;;; alchemist-server.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/.gitignore b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/.gitignore new file mode 100644 index 0000000..5663f4d --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/.gitignore @@ -0,0 +1,2 @@ +test/sandbox +.cask \ No newline at end of file diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/.travis.yml b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/.travis.yml new file mode 100644 index 0000000..7839941 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/.travis.yml @@ -0,0 +1,12 @@ +language: elixir +elixir: + - 1.1.1 + - 1.2.0-rc.0 +otp_release: + - 18.0 +sudo: false +install: mix local.hex --force +script: + - make +notifications: + irc: "irc.freenode.org#emacs-elixir" \ No newline at end of file diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/Makefile b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/Makefile new file mode 100644 index 0000000..6e02908 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/Makefile @@ -0,0 +1,35 @@ +ELIXIR = elixir + +VERSION = $(shell git describe --tags --abbrev=0 | sed 's/^v//') + +NO_COLOR=\033[0m +INFO_COLOR=\033[2;32m +STAT_COLOR=\033[2;33m + +all: test + +test: test_server + ${MAKE} test_helpers + ${MAKE} test_api + +test_server: + @ echo "\n$(INFO_COLOR)Run server tests: $(NO_COLOR)\n" + $(ELIXIR) test/server_test.exs + +test_helpers: + @ echo "\n$(INFO_COLOR)Run helper tests: $(NO_COLOR)\n" + $(ELIXIR) test/helpers/module_info_test.exs + $(ELIXIR) test/helpers/complete_test.exs + +test_api: + @ echo "\n$(INFO_COLOR)Run api tests: $(NO_COLOR)\n" + $(ELIXIR) test/api/docl_test.exs + $(ELIXIR) test/api/comp_test.exs + $(ELIXIR) test/api/defl_test.exs + +api_completer: + @ echo "\n$(INFO_COLOR)Run api tests: $(NO_COLOR)\n" + $(ELIXIR) test/api_test.exs + + +.PHONY: test test_server test_helpers test_api diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/README.md b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/README.md new file mode 100644 index 0000000..cbc2a1a --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/README.md @@ -0,0 +1,161 @@ +[![License GPL 3](https://img.shields.io/badge/license-GPL_3-green.svg)](http://www.gnu.org/licenses/gpl-3.0.txt) +[![Build Status](https://img.shields.io/travis/tonini/alchemist-server.svg)](https://travis-ci.org/tonini/alchemist-server) + +**INFO:** The Alchemist-Server is in Beta status and the API will most likey change until the first release. Feedback and critic are highly appreciated though. + +# Alchemist Server + +The Alchemist-Server operates as an informant for a specific desired +Elixir Mix project and serves with informations as the following: + +* Completion for Modules and functions. +* Documentation lookup for Modules and functions. +* Code evaluation and quoted representation of code. +* Definition lookup of code. +* Listing of all available Mix tasks. +* Listing of all available Modules with documentation. + +# Usage + +The server needs to be started inside an Elixir mix project like below: + +``` +$ cd elixir_project +$ elixir path/to/alchemist-server/run.exs dev +``` + +The Alchemist-Server API is `STDIN/STDOUT` based, when input sent to a +running server process it responds by sending information back to the `STDOUT`. + +A request consisting of two parts, the request type and the request arguments. + +Example for a completion request: + +``` +[type] [arguments] + +COMP { "def", [ context: Elixir, imports: [Enum], aliases: [{MyList, List}] ] } +``` + +# API + +## Completion + +Return a completion list of all the available candidates. + +``` +COMP +COMP { "def", [ context: Elixir, imports: [], aliases: [] ] } +COMP { "List.fla", [ context: Elixir, imports: [], aliases: [] ] } +``` + +## Documentation lookup + +Return the documentation. + +``` +DOCL { "defmodule", [ context: Elixir, imports: [], aliases: [] ] } +DOCL { "List.flatten/1", [ context: Elixir, imports: [], aliases: [] ] } +``` + +## Evaluation, Quoted & Macro expand + +### Evaluation + +Return the evaluation result of the code from the file. + +``` +EVAL { :eval, 'path/to/file/which/holds/content/to/eval.tmp' } +``` + +### Quoted + +Return the code from the file quoted. + +``` +EVAL { :quote, 'path/to/file/which/holds/content/to/quote.tmp' } +``` + +### Macro expand + +Return the code from the file expanded. + +``` +EVAL { :expand, 'path/to/file/which/holds/content/to/expand.tmp' } +``` + +Return the code from the file expanded once. + +``` +EVAL { :expand_once, 'path/to/file/which/holds/content/to/expand_once.tmp' } +``` + +## Definition lookup + +Return the path to the source file which holds the definition. + +``` +DEFL { "List,flatten", [ context: Elixir, imports: [], aliases: [] ] } +DEFL { "nil,defmacro", [ context: Elixir, imports: [], aliases: [] ] } +DEFL { "nil,create_file", [ context: Elixir, imports: [Mix.Generator], aliases: [] ] } +DEFL { "MyList,nil", [ context: Elixir, imports: [], aliases: [{MyList, List}] ] } +``` + +## Informations + +### Mix tasks + +Return a list of all available mix tasks. + +``` +INFO { :type, :mixtasks } +``` + +### Modules + +Return a list of all available modules which has documentation. + +``` +INFO { :type, :modules } +``` + +### Datatype Information + +Return information about any datatype. + +``` +INFO { :type, :info, List } +``` + +### Module Or Function/Arity Types Information + +Return types for a module or function/arity pair. + +``` +INFO { :type, :types, 'List' } +INFO { :type, :types, 'Enum.t' } +INFO { :type, :types, 'Agent.on_start/0' } +``` + +## End Markers + +Each request type ends with a specific end marker tag to notify that the request is done. + +An end tag looks like the following: + +``` +END-OF- +``` + +For example, after the following request an end tag would look like this: + +``` +INFO { :type, :modules } +List +String +Enum +. +... +.... +END-OF-INFO +``` diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/comp.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/comp.exs new file mode 100644 index 0000000..2740f68 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/comp.exs @@ -0,0 +1,41 @@ +Code.require_file "../helpers/complete.exs", __DIR__ + +defmodule Alchemist.API.Comp do + + @moduledoc false + + alias Alchemist.Helpers.Complete + + def request(args) do + args + |> normalize + |> process + end + + def process([nil, _, imports, _]) do + Complete.run('', imports) ++ Complete.run('') + |> print + end + + def process([hint, _context, imports, aliases]) do + Application.put_env(:"alchemist.el", :aliases, aliases) + + Complete.run(hint, imports) ++ Complete.run(hint) + |> print + end + + defp normalize(request) do + {{hint, [ context: context, + imports: imports, + aliases: aliases ]}, _} = Code.eval_string(request) + [hint, context, imports, aliases] + end + + defp print(result) do + result + |> Enum.uniq + |> Enum.map(&IO.puts/1) + + IO.puts "END-OF-COMP" + end +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/defl.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/defl.exs new file mode 100644 index 0000000..db7e8f8 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/defl.exs @@ -0,0 +1,80 @@ +Code.require_file "../helpers/module_info.exs", __DIR__ + +defmodule Alchemist.API.Defl do + + @moduledoc false + + alias Alchemist.Helpers.ModuleInfo + + def request(args) do + args + |> normalize + |> process + |> IO.puts + + IO.puts "END-OF-DEFL" + end + + def process([nil, function, [context: _, imports: [], aliases: _]]) do + look_for_kernel_functions(function) + end + + def process([nil, function, [context: _, imports: imports, aliases: _ ]]) do + module = Enum.filter(imports, &ModuleInfo.has_function?(&1, function)) + |> List.first + + case module do + nil -> look_for_kernel_functions(function) + _ -> source(module) + end + end + + def process([module, _function, [context: _, imports: _, aliases: aliases]]) do + if elixir_module?(module) do + module + |> Module.split + |> ModuleInfo.expand_alias(aliases) + else + module + end |> source + end + + defp elixir_module?(module) do + module == Module.concat(Elixir, module) + end + + defp look_for_kernel_functions(function) do + cond do + ModuleInfo.docs?(Kernel, function) -> + source(Kernel) + ModuleInfo.docs?(Kernel.SpecialForms, function) -> + source(Kernel.SpecialForms) + true -> "" + end + end + + defp source([]), do: nil + defp source(module) when is_list(module) do + module + |> Module.concat + |> do_source + end + defp source(module), do: do_source(module) + + defp do_source(module) do + if Code.ensure_loaded? module do + case module.module_info(:compile)[:source] do + nil -> nil + source -> List.to_string(source) + end + end + end + + defp normalize(request) do + {{expr, context_info}, _} = Code.eval_string(request) + [module, function] = String.split(expr, ",", parts: 2) + {module, _} = Code.eval_string(module) + function = String.to_atom function + [module, function, context_info] + end +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/docl.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/docl.exs new file mode 100644 index 0000000..5467030 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/docl.exs @@ -0,0 +1,78 @@ +Code.require_file "../helpers/module_info.exs", __DIR__ + +defmodule Alchemist.API.Docl do + + @moduledoc false + + import IEx.Helpers, warn: false + + alias Alchemist.Helpers.ModuleInfo + + def request(args) do + Application.put_env(:iex, :colors, [enabled: true]) + + args + |> normalize + |> process + + IO.puts "END-OF-DOCL" + end + + def process([expr, modules, aliases]) do + search(expr, modules, aliases) + end + + def search(nil), do: true + def search(expr) do + try do + Code.eval_string("h(#{expr})", [], __ENV__) + rescue + _e -> nil + end + end + + def search(expr, modules, []) do + expr = to_string expr + unless function?(expr) do + search(expr) + else + search_with_context(modules, expr) + end + end + + def search(expr, modules, aliases) do + unless function?(expr) do + String.split(expr, ".") + |> ModuleInfo.expand_alias(aliases) + |> search + else + search_with_context(modules, expr) + end + end + + defp search_with_context(modules, expr) do + modules ++ [Kernel, Kernel.SpecialForms] + |> build_search(expr) + |> search + end + + defp build_search(modules, search) do + function = Regex.replace(~r/\/[0-9]$/, search, "") + function = String.to_atom(function) + for module <- modules, + ModuleInfo.docs?(module, function) do + "#{module}.#{search}" + end |> List.first + end + + defp function?(expr) do + Regex.match?(~r/^[a-z_]/, expr) + end + + defp normalize(request) do + {{expr, [ context: _, + imports: imports, + aliases: aliases]}, _} = Code.eval_string(request) + [expr, imports, aliases] + end +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/eval.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/eval.exs new file mode 100644 index 0000000..9269be1 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/eval.exs @@ -0,0 +1,63 @@ +defmodule Alchemist.API.Eval do + + @moduledoc false + + def request(args) do + args + |> normalize + |> process + + IO.puts "END-OF-EVAL" + end + + def process({:eval, file}) do + try do + File.read!("#{file}") + |> Code.eval_string + |> Tuple.to_list + |> List.first + |> IO.inspect + rescue + e -> IO.inspect e + end + end + + def process({:quote, file}) do + try do + File.read!("#{file}") + |> Code.string_to_quoted + |> Tuple.to_list + |> List.last + |> IO.inspect + rescue + e -> IO.inspect e + end + end + + def process({:expand, file}) do + try do + {_, expr} = File.read!("#{file}") + |> Code.string_to_quoted + res = Macro.expand(expr, __ENV__) + IO.puts Macro.to_string(res) + rescue + e -> IO.inspect e + end + end + + def process({:expand_once, file}) do + try do + {_, expr} = File.read!("#{file}") + |> Code.string_to_quoted + res = Macro.expand_once(expr, __ENV__) + IO.puts Macro.to_string(res) + rescue + e -> IO.inspect e + end + end + + def normalize(request) do + {expr , _} = Code.eval_string(request) + expr + end +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/info.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/info.exs new file mode 100644 index 0000000..13d7c2c --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/api/info.exs @@ -0,0 +1,86 @@ +Code.require_file "../helpers/module_info.exs", __DIR__ +Code.require_file "../helpers/complete.exs", __DIR__ + +defmodule Alchemist.API.Info do + + @moduledoc false + + import IEx.Helpers, warn: false + + alias Alchemist.Helpers.ModuleInfo + alias Alchemist.Helpers.Complete + + def request(args) do + args + |> normalize + |> process + end + + def process(:modules) do + modules = ModuleInfo.all_applications_modules + |> Enum.uniq + |> Enum.reject(&is_nil/1) + |> Enum.filter(&ModuleInfo.moduledoc?/1) + + functions = Complete.run('') + + modules ++ functions + |> Enum.uniq + |> Enum.map(&IO.puts/1) + + IO.puts "END-OF-INFO" + end + + def process(:mixtasks) do + # append things like hex or phoenix archives to the load_path + Mix.Local.append_archives + + :code.get_path + |> Mix.Task.load_tasks + |> Enum.map(&Mix.Task.task_name/1) + |> Enum.sort + |> Enum.map(&IO.puts/1) + + IO.puts "END-OF-INFO" + end + + def process({:info, arg}) do + try do + Code.eval_string("i(#{arg})", [], __ENV__) + rescue + _e -> nil + end + + IO.puts "END-OF-INFO" + end + + def process({:types, arg}) do + try do + Code.eval_string("t(#{arg})", [], __ENV__) + rescue + _e -> nil + end + + IO.puts "END-OF-INFO" + end + + def process(nil) do + IO.puts "END-OF-INFO" + end + + def normalize(request) do + try do + Code.eval_string(request) + rescue + _e -> nil + else + {{_, type }, _} -> type + {{_, type, arg}, _} -> + if Version.match?(System.version, ">=1.2.0-rc") do + {type, arg} + else + nil + end + end + end +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/helpers/complete.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/helpers/complete.exs new file mode 100644 index 0000000..3ca1586 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/helpers/complete.exs @@ -0,0 +1,351 @@ +Code.require_file "module_info.exs", __DIR__ + +defmodule Alchemist.Helpers.Complete do + + alias Alchemist.Helpers.ModuleInfo + + @moduledoc """ + This Alchemist.Completer holds a codebase copy of the + IEx.Autocomplete because for the use of context specific + aliases. + + With the release of Elixir v1.1 the IEx.Autocomplete will + look for aliases in a certain environment variable + `Application.get_env(:iex, :autocomplete_server)` and until + then we'll use our own autocomplete codebase. + """ + + def run(exp) do + code = case is_bitstring(exp) do + true -> exp |> String.to_char_list + _ -> exp + end + + {status, result, list } = expand(code |> Enum.reverse) + + case { status, result, list } do + { :no, _, _ } -> '' + { :yes, [], _ } -> List.insert_at(list, 0, exp) + { :yes, _, _ } -> run(code ++ result) + end + end + + def run(hint, modules) do + for module <- modules do + ModuleInfo.get_functions(module, hint) + end |> List.flatten + end + + def expand('') do + expand_import("") + end + + def expand([h|t]=expr) do + cond do + h === ?. and t != []-> + expand_dot(reduce(t)) + h === ?: -> + expand_erlang_modules() + identifier?(h) -> + expand_expr(reduce(expr)) + (h == ?/) and t != [] and identifier?(hd(t)) -> + expand_expr(reduce(t)) + h in '([{' -> + expand('') + true -> + no() + end + end + + defp identifier?(h) do + (h in ?a..?z) or (h in ?A..?Z) or (h in ?0..?9) or h in [?_, ??, ?!] + end + + defp expand_dot(expr) do + case Code.string_to_quoted expr do + {:ok, atom} when is_atom(atom) -> + expand_call(atom, "") + {:ok, {:__aliases__, _, list}} -> + expand_elixir_modules(list, "") + _ -> + no() + end + end + + defp expand_expr(expr) do + case Code.string_to_quoted expr do + {:ok, atom} when is_atom(atom) -> + expand_erlang_modules(Atom.to_string(atom)) + {:ok, {atom, _, nil}} when is_atom(atom) -> + expand_import(Atom.to_string(atom)) + {:ok, {:__aliases__, _, [root]}} -> + expand_elixir_modules([], Atom.to_string(root)) + {:ok, {:__aliases__, _, [h|_] = list}} when is_atom(h) -> + hint = Atom.to_string(List.last(list)) + list = Enum.take(list, length(list) - 1) + expand_elixir_modules(list, hint) + {:ok, {{:., _, [mod, fun]}, _, []}} when is_atom(fun) -> + expand_call(mod, Atom.to_string(fun)) + _ -> + no() + end + end + + defp reduce(expr) do + Enum.reverse Enum.reduce ' ([{', expr, fn token, acc -> + hd(:string.tokens(acc, [token])) + end + end + + defp yes(hint, entries) do + {:yes, String.to_char_list(hint), Enum.map(entries, &String.to_char_list/1)} + end + + defp no do + {:no, '', []} + end + + ## Formatting + + defp format_expansion([], _) do + no() + end + + defp format_expansion([uniq], hint) do + case to_hint(uniq, hint) do + "" -> yes("", to_uniq_entries(uniq)) + hint -> yes(hint, []) + end + end + + defp format_expansion([first|_]=entries, hint) do + binary = Enum.map(entries, &(&1.name)) + length = byte_size(hint) + prefix = :binary.longest_common_prefix(binary) + if prefix in [0, length] do + yes("", Enum.flat_map(entries, &to_entries/1)) + else + yes(:binary.part(first.name, prefix, length-prefix), []) + end + end + + ## Expand calls + + # :atom.fun + defp expand_call(mod, hint) when is_atom(mod) do + expand_require(mod, hint) + end + + # Elixir.fun + defp expand_call({:__aliases__, _, list}, hint) do + expand_alias(list) + |> normalize_module + |> expand_require(hint) + end + + defp expand_call(_, _) do + no() + end + + defp expand_require(mod, hint) do + format_expansion match_module_funs(mod, hint), hint + end + + defp expand_import(hint) do + funs = match_module_funs(IEx.Helpers, hint) ++ + match_module_funs(Kernel, hint) ++ + match_module_funs(Kernel.SpecialForms, hint) + format_expansion funs, hint + end + + ## Erlang modules + + defp expand_erlang_modules(hint \\ "") do + format_expansion match_erlang_modules(hint), hint + end + + defp match_erlang_modules(hint) do + for mod <- match_modules(hint, true) do + %{kind: :module, name: mod, type: :erlang} + end + end + + ## Elixir modules + + defp expand_elixir_modules([], hint) do + expand_elixir_modules(Elixir, hint, match_aliases(hint)) + end + + defp expand_elixir_modules(list, hint) do + expand_alias(list) + |> normalize_module + |> expand_elixir_modules(hint, []) + end + + defp expand_elixir_modules(mod, hint, aliases) do + aliases + |> Kernel.++(match_elixir_modules(mod, hint)) + |> Kernel.++(match_module_funs(mod, hint)) + |> format_expansion(hint) + end + + defp expand_alias([name | rest] = list) do + module = Module.concat(Elixir, name) + Enum.find_value env_aliases(), list, fn {alias, mod} -> + if alias === module do + case Atom.to_string(mod) do + "Elixir." <> mod -> + Module.concat [mod|rest] + _ -> + mod + end + end + end + end + + defp env_aliases() do + Application.get_env(:"alchemist.el", :aliases) + |> format_aliases + end + + defp format_aliases(nil), do: [] + defp format_aliases(list), do: list + + defp match_aliases(hint) do + for {alias, _mod} <- env_aliases(), + [name] = Module.split(alias), + starts_with?(name, hint) do + %{kind: :module, type: :alias, name: name} + end + end + + defp match_elixir_modules(module, hint) do + name = Atom.to_string(module) + depth = length(String.split(name, ".")) + 1 + base = name <> "." <> hint + + for mod <- match_modules(base, module === Elixir), + parts = String.split(mod, "."), + depth <= length(parts) do + %{kind: :module, type: :elixir, name: Enum.at(parts, depth-1)} + end + |> Enum.uniq + end + + ## Helpers + + defp normalize_module(mod) do + if is_list(mod) do + Module.concat(mod) + else + mod + end + end + + defp match_modules(hint, root) do + get_modules(root) + |> :lists.usort() + |> Enum.drop_while(& not starts_with?(&1, hint)) + |> Enum.take_while(& starts_with?(&1, hint)) + end + + defp get_modules(true) do + ["Elixir.Elixir"] ++ get_modules(false) + end + + defp get_modules(false) do + modules = Enum.map(:code.all_loaded(), &Atom.to_string(elem(&1, 0))) + case :code.get_mode() do + :interactive -> modules ++ get_modules_from_applications() + _otherwise -> modules + end + end + + defp get_modules_from_applications do + for [app] <- loaded_applications(), + {:ok, modules} = :application.get_key(app, :modules), + module <- modules do + Atom.to_string(module) + end + end + + defp loaded_applications do + # If we invoke :application.loaded_applications/0, + # it can error if we don't call safe_fixtable before. + # Since in both cases we are reaching over the + # application controller internals, we choose to match + # for performance. + :ets.match(:ac_tab, {{:loaded, :"$1"}, :_}) + end + + defp match_module_funs(mod, hint) do + case ensure_loaded(mod) do + {:module, _} -> + falist = get_module_funs(mod) + + list = Enum.reduce falist, [], fn {f, a}, acc -> + case :lists.keyfind(f, 1, acc) do + {f, aa} -> :lists.keyreplace(f, 1, acc, {f, [a|aa]}) + false -> [{f, [a]}|acc] + end + end + + for {fun, arities} <- list, + name = Atom.to_string(fun), + starts_with?(name, hint) do + %{kind: :function, name: name, arities: arities} + end |> :lists.sort() + + _otherwise -> [] + end + end + + defp get_module_funs(mod) do + if function_exported?(mod, :__info__, 1) do + if docs = Code.get_docs(mod, :docs) do + for {tuple, _line, _kind, _sign, doc} <- docs, doc != false, do: tuple + else + mod.__info__(:macros) ++ (mod.__info__(:functions) -- [__info__: 1]) + end + else + mod.module_info(:exports) + end + end + + defp ensure_loaded(Elixir), do: {:error, :nofile} + defp ensure_loaded(mod), do: Code.ensure_compiled(mod) + + defp starts_with?(_string, ""), do: true + defp starts_with?(string, hint), do: String.starts_with?(string, hint) + + ## Ad-hoc conversions + + defp to_entries(%{kind: :module, name: name}) do + [name] + end + + defp to_entries(%{kind: :function, name: name, arities: arities}) do + for a <- :lists.sort(arities), do: "#{name}/#{a}" + end + + defp to_uniq_entries(%{kind: :module}) do + [] + end + + defp to_uniq_entries(%{kind: :function} = fun) do + to_entries(fun) + end + + defp to_hint(%{kind: :module, name: name}, hint) do + format_hint(name, hint) <> "." + end + + defp to_hint(%{kind: :function, name: name}, hint) do + format_hint(name, hint) + end + + defp format_hint(name, hint) do + hint_size = byte_size(hint) + :binary.part(name, hint_size, byte_size(name) - hint_size) + end +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/helpers/module_info.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/helpers/module_info.exs new file mode 100644 index 0000000..c8de52e --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/helpers/module_info.exs @@ -0,0 +1,117 @@ +defmodule Alchemist.Helpers.ModuleInfo do + + @moduledoc false + + def moduledoc?(module) do + case Code.get_docs module, :moduledoc do + {_, doc} -> is_binary doc + _ -> false + end + end + + def docs?(module, function) do + docs = Code.get_docs module, :docs + do_docs?(docs, function) + end + + def expand_alias([name | rest] = list, aliases) do + module = Module.concat(Elixir, name) + Enum.find_value(aliases, list, fn {alias, mod} -> + if alias === module do + case Atom.to_string(mod) do + "Elixir." <> mod -> + Module.concat [mod|rest] + _ -> + mod + end + end + end) |> normalize_module + end + + def get_functions(module, hint) do + hint = to_string hint + {module, _} = Code.eval_string(module) + functions = get_module_funs(module) + + list = Enum.reduce functions, [], fn({f, a}, acc) -> + case :lists.keyfind(f, 1, acc) do + {f, aa} -> :lists.keyreplace(f, 1, acc, {f, [a|aa]}) + false -> [{f, [a]}|acc] + end + end + + do_get_functions(list, hint) |> :lists.sort() + end + + def has_function?(module, function) do + List.keymember? get_module_funs(module), function, 0 + end + + defp do_get_functions(list, "") do + all_functions(list) + end + + defp do_get_functions(list, hint) do + all_functions(list, hint) + end + + defp get_module_funs(module) do + case Code.ensure_loaded(module) do + {:module, _} -> + module.module_info(:functions) ++ module.__info__(:macros) + _otherwise -> + [] + end + end + + defp all_functions(list) do + for {fun, arities} <- list, name = Atom.to_string(fun) do + "#{name}/#{List.first(arities)}" + end + end + + defp all_functions(list, hint) do + for {fun, arities} <- list, + name = Atom.to_string(fun), + String.starts_with?(name, hint) do + "#{name}/#{List.first(arities)}" + end + end + + def all_applications_modules do + for [app] <- loaded_applications(), + {:ok, modules} = :application.get_key(app, :modules), + module <- modules do + module + end + end + + defp do_docs?([head|tail], function) do + {{func, _}, _, _, _, doc} = head + if func == function and is_binary(doc) do + true + else + do_docs?(tail, function) + end + end + defp do_docs?([], _function), do: false + defp do_docs?(nil, _function), do: false + + defp loaded_applications do + # If we invoke :application.loaded_applications/0, + # it can error if we don't call safe_fixtable before. + # Since in both cases we are reaching over the + # application controller internals, we choose to match + # for performance. + :ets.match(:ac_tab, {{:loaded, :"$1"}, :_}) + end + + defp normalize_module(mod) do + if is_list(mod) do + Module.concat(mod) + else + mod + end + end + +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/server.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/server.exs new file mode 100644 index 0000000..09ae6de --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/lib/server.exs @@ -0,0 +1,93 @@ +Code.require_file "api/comp.exs", __DIR__ +Code.require_file "api/docl.exs", __DIR__ +Code.require_file "api/defl.exs", __DIR__ +Code.require_file "api/eval.exs", __DIR__ +Code.require_file "api/info.exs", __DIR__ + +defmodule Alchemist.Server do + + @version "0.1.0-beta" + + @moduledoc """ + The Alchemist-Server operates as an informant for a specific desired + Elixir Mix project and serves with informations as the following: + + * Completion for Modules and functions. + * Documentation lookup for Modules and functions. + * Code evaluation and quoted representation of code. + * Definition lookup of code. + * Listing of all available Mix tasks. + * Listing of all available Modules with documentation. + """ + + alias Alchemist.API + + def start([env]) do + loop(all_loaded(), env) + end + + def loop(loaded, env) do + line = IO.gets("") |> String.rstrip() + paths = load_paths(env) + apps = load_apps(env) + + read_input(line) + + purge_modules(loaded) + purge_paths(paths) + purge_apps(apps) + + loop(loaded, env) + end + + def read_input(line) do + case line |> String.split(" ", parts: 2) do + ["COMP", args] -> + API.Comp.request(args) + ["DOCL", args] -> + API.Docl.request(args) + ["INFO", args] -> + API.Info.request(args) + ["EVAL", args] -> + API.Eval.request(args) + ["DEFL", args] -> + API.Defl.request(args) + _ -> + nil + end + end + + defp all_loaded() do + for {m,_} <- :code.all_loaded, do: m + end + + defp load_paths(env) do + for path <- Path.wildcard("_build/#{env}/lib/*/ebin") do + Code.prepend_path(path) + path + end + end + + defp load_apps(env) do + for path <- Path.wildcard("_build/#{env}/lib/*/ebin/*.app") do + app = path |> Path.basename() |> Path.rootname() |> String.to_atom + Application.load(app) + app + end + end + + defp purge_modules(loaded) do + for m <- (all_loaded() -- loaded) do + :code.delete(m) + :code.purge(m) + end + end + + defp purge_paths(paths) do + for p <- paths, do: Code.delete_path(p) + end + + defp purge_apps(apps) do + for a <- apps, do: Application.unload(a) + end +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/run.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/run.exs new file mode 100644 index 0000000..4616198 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/run.exs @@ -0,0 +1,3 @@ +Code.require_file "lib/server.exs", __DIR__ + +Alchemist.Server.start([System.argv]) diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api/comp_test.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api/comp_test.exs new file mode 100644 index 0000000..e9d0c8a --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api/comp_test.exs @@ -0,0 +1,57 @@ +Code.require_file "../test_helper.exs", __DIR__ +Code.require_file "../../lib/api/comp.exs", __DIR__ + +defmodule Alchemist.API.CompTest do + + use ExUnit.Case, async: true + import ExUnit.CaptureIO + + alias Alchemist.API.Comp + + test "COMP request with empty hint" do + assert capture_io(fn -> + Comp.process([nil, Elixir, [], [] ]) + end) =~ """ + import/2 + quote/2 + require/2 + END-OF-COMP + """ + end + + test "COMP request without empty hint" do + assert capture_io(fn -> + Comp.process(['is_b', Elixir, [], []]) + end) =~ """ + is_b + is_binary/1 + is_bitstring/1 + is_boolean/1 + END-OF-COMP + """ + end + + test "COMP request with an alias" do + assert capture_io(fn -> + Comp.process(['MyList.flat', Elixir, [], [{MyList, List}]]) + end) =~ """ + MyList.flatten + flatten/1 + flatten/2 + END-OF-COMP + """ + end + + test "COMP request with a module hint" do + assert capture_io(fn -> + Comp.process(['Str', Elixir, [], []]) + end) =~ """ + Str + Stream + String + StringIO + END-OF-COMP + """ + end + +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api/defl_test.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api/defl_test.exs new file mode 100644 index 0000000..d0ead2f --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api/defl_test.exs @@ -0,0 +1,45 @@ +Code.require_file "../test_helper.exs", __DIR__ +Code.require_file "../../lib/api/defl.exs", __DIR__ + +defmodule Alchemist.API.DeflTest do + + use ExUnit.Case + + alias Alchemist.API.Defl + + test "DEFL request call for defmodule" do + context = [context: Elixir, imports: [], aliases: []] + assert Defl.process([nil, :defmodule, context]) =~ "lib/elixir/lib/kernel.ex" + end + + test "DEFL request call for import" do + context = [context: Elixir, imports: [], aliases: []] + assert Defl.process([nil, :import, context]) =~ "lib/elixir/lib/kernel/special_forms.ex" + end + + test "DEFL request call for create_file with available import" do + context = [context: Elixir, imports: [Mix.Generator], aliases: []] + assert Defl.process([nil, :create_file, context]) =~ "lib/mix/lib/mix/generator.ex" + end + + test "DEFL request call for MyList.flatten with available aliases" do + context = [context: Elixir, imports: [], aliases: [{MyList, List}]] + assert Defl.process([MyList, :flatten, context]) =~ "lib/elixir/lib/list.ex" + end + + test "DEFL request call for String module" do + context = [context: Elixir, imports: [], aliases: []] + assert Defl.process([String, nil, context]) =~ "lib/elixir/lib/string.ex" + end + + test "DEFL request call for erlang module" do + context = [ context: Elixir, imports: [], aliases: [] ] + assert Defl.process([:lists, :duplicate, context]) =~ "lib/stdlib/src/lists.erl" + end + + test "DEFL request call for none existing module" do + context = [ context: Elixir, imports: [], aliases: [] ] + assert Defl.process([Rock, :duplicate, context]) == nil + end + +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api/docl_test.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api/docl_test.exs new file mode 100644 index 0000000..fc1eaa5 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api/docl_test.exs @@ -0,0 +1,73 @@ +Code.require_file "../test_helper.exs", __DIR__ +Code.require_file "../../lib/api/comp.exs", __DIR__ +Code.require_file "../../lib/api/docl.exs", __DIR__ + +defmodule Alchemist.API.DoclTest do + + use ExUnit.Case, async: true + import ExUnit.CaptureIO + + alias Alchemist.API.Docl + + test "DOCL request" do + assert capture_io(fn -> + Docl.process(['defmodule', [], []]) + end) =~ """ + Defines a module given by name with the given contents. + """ + end + + test "DOCL request for List.flatten" do + assert capture_io(fn -> + Docl.process(["List.flatten", [], []]) + end) =~ """ + Flattens the given \e[36mlist\e[0m of nested lists. + \e[0m + \e[33mExamples\e[0m + \e[0m + \e[36m\e[1m┃ iex> List.flatten([1, [[2], 3]]) + """ + end + + test "DOCL request for MyCustomList.flatten with alias" do + assert capture_io(fn -> + Docl.process(["MyCustomList.flatten", [], [{MyCustomList, List}]]) + end) =~ """ + Flattens the given \e[36mlist\e[0m of nested lists. + \e[0m + \e[33mExamples\e[0m + \e[0m + \e[36m\e[1m┃ iex> List.flatten([1, [[2], 3]]) + """ + end + + test "DOCL request for search create_file with import" do + assert capture_io(fn -> + Docl.process(["create_file", [Mix.Generator], []]) + end) =~ """ + def create_file(path, contents, opts \\\\ []) \e[0m + \e[0m + Creates a file with the given contents. If the file already exists, asks for + user confirmation. + \e[0m + """ + end + + test "DOCL request for defmacro" do + assert capture_io(fn -> + Docl.process(["defmacro", [], []]) + end) =~ """ + \e[7m\e[33m defmacro defmacro(call, expr \\\\ nil) \e[0m + """ + end + + test "DOCL request for Path.basename/1" do + assert capture_io(fn -> + Docl.process(["Path.basename/1", [], []]) + end) =~ """ + Returns the last component of the path or the path itself if it does not + contain any directory separators. + """ + end + +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api_test.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api_test.exs new file mode 100644 index 0000000..7928920 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/api_test.exs @@ -0,0 +1,19 @@ +Code.require_file "test_helper.exs", __DIR__ +Code.require_file "../lib/api/comp.exs", __DIR__ +Code.require_file "../lib/api/docl.exs", __DIR__ + +defmodule APITest do + use ExUnit.Case, async: true + import ExUnit.CaptureIO + + alias Alchemist.API + + test "DOCL request" do + assert capture_io(fn -> + API.Docl.process(['defmodule', [], []]) + end) =~ """ + Defines a module given by name with the given contents. + """ + end + +end diff --git a/emacs.d/elpa/yasnippet-20150415.244/snippets/enh-ruby-mode b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/fixtures/.gitkeep old mode 100755 new mode 100644 similarity index 100% rename from emacs.d/elpa/yasnippet-20150415.244/snippets/enh-ruby-mode rename to emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/fixtures/.gitkeep diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/helpers/complete_test.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/helpers/complete_test.exs new file mode 100644 index 0000000..1c10e12 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/helpers/complete_test.exs @@ -0,0 +1,41 @@ +Code.require_file "../test_helper.exs", __DIR__ +Code.require_file "../../lib/helpers/complete.exs", __DIR__ + +defmodule CompleteTest do + use ExUnit.Case, async: true + + import Alchemist.Helpers.Complete + + defmodule MyModule do + def say_hi, do: true + end + + test "return completion candidates for 'List'" do + assert run('List') == ['List.', 'Chars', 'first/1', 'last/1', 'to_atom/1', + 'to_existing_atom/1', 'to_float/1', 'to_string/1', 'to_tuple/1', + 'wrap/1', 'zip/1', 'delete/2', 'delete_at/2', 'duplicate/2', + 'keysort/2', 'flatten/1', 'flatten/2', 'to_integer/1', + 'to_integer/2', 'foldl/3', 'foldr/3', 'insert_at/3', 'keydelete/3', + 'keymember?/3', 'keytake/3', 'replace_at/3', 'update_at/3', + 'keyfind/4', 'keyreplace/4', 'keystore/4'] + end + + test "return completion candidates for 'Str'" do + assert run('Str') == ['Str', 'Stream', 'String', 'StringIO'] + end + + test "return completion candidates for 'List.del'" do + assert run('List.del') == ['List.delete', 'delete/2', 'delete_at/2'] + end + + test "return completion candidates for module with alias" do + Application.put_env(:"alchemist.el", :aliases, [{MyList, List}]) + + assert run('MyList.del') == ['MyList.delete', 'delete/2', 'delete_at/2'] + end + + test "return completion candidates for functions from import" do + imports = [MyModule] + assert run('say', imports) == ["say_hi/0"] + end +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/helpers/module_info_test.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/helpers/module_info_test.exs new file mode 100644 index 0000000..4bbf645 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/helpers/module_info_test.exs @@ -0,0 +1,45 @@ +Code.require_file "../test_helper.exs", __DIR__ +Code.require_file "../../lib/helpers/module_info.exs", __DIR__ + +defmodule Alchemist.Helpers.ModuleTest do + + use ExUnit.Case + + alias Alchemist.Helpers.ModuleInfo + + test "moduledoc? returns true" do + assert ModuleInfo.moduledoc?(List) == true + end + + test "moduledoc? returns false" do + assert ModuleInfo.moduledoc?(List.Chars.Atom) == false + end + + test "docs? returns true" do + assert ModuleInfo.docs?(List, :flatten) == true + assert ModuleInfo.docs?(Kernel, :def) == true + end + + test "docs? returns false" do + assert ModuleInfo.docs?(List, :dance) == false + assert ModuleInfo.docs?(nil, :dance) == false + end + + test "expand_alias return expanded module alias" do + aliases = [{MyList, List}, {MyGenServer, :gen_server}] + + assert ModuleInfo.expand_alias([MyList], aliases) == List + assert ModuleInfo.expand_alias([MyGenServer], aliases) == :gen_server + assert ModuleInfo.expand_alias([MyList], aliases) == List + end + + test "has_function? return true" do + assert ModuleInfo.has_function?(List, :flatten) == true + assert ModuleInfo.has_function?(List, :to_string) == true + end + + test "has_function? return false" do + assert ModuleInfo.has_function?(List, :split) == false + assert ModuleInfo.has_function?(List, :map) == false + end +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/server_test.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/server_test.exs new file mode 100644 index 0000000..0f09f76 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/server_test.exs @@ -0,0 +1,126 @@ +Code.require_file "test_helper.exs", __DIR__ +Code.require_file "../lib/server.exs", __DIR__ + +defmodule ServerTest do + use ExUnit.Case + import ExUnit.CaptureIO + + setup_all do + on_exit fn -> + {_status, files} = File.ls Path.expand("fixtures", __DIR__) + files |> Enum.each(fn(file) -> + unless file == ".gitkeep" do + File.rm Path.expand("fixtures/#{file}", __DIR__) + end + end) + end + end + + test "Expression completion" do + assert send_signal("COMP { 'def', [context: Elixir, imports: [], aliases: []]}") =~ """ + defoverridable/1 + """ + end + + test "Documentation lookup" do + assert send_signal("DOCL { 'List', [context: Elixir, imports: [], aliases: []]}") =~ """ + \e[0m\n\e[7m\e[33m List \e[0m\n\e[0m + """ + end + + test "Getting the definition source file information of code" do + assert send_signal("DEFL {\"List,delete\", [context: Elixir, imports: [], aliases: []]}") =~ "/lib/elixir/lib/list.ex" + end + + test "Evaluate the content of a file" do + filename = Path.expand("fixtures/eval_fixture.exs", __DIR__) + File.write(filename, "1+1") + assert send_signal("EVAL { :eval, '#{filename}' }") =~ "2" + end + + test "Evaluate and quote the content of a file" do + filename = Path.expand("fixtures/eval_and_quote_fixture.exs", __DIR__) + File.write(filename, "[4,2,1,3] |> Enum.sort") + assert send_signal("EVAL { :quote, '#{filename}' }") =~ """ + {{:., [line: 1], [{:__aliases__, [counter: 0, line: 1], [:Enum]}, :sort]},\n [line: 1], []}]} + """ + end + + test "Expand macro once" do + filename = Path.expand("fixtures/macro_expand_once_fixture.exs", __DIR__) + File.write(filename, "unless true, do: IO.puts \"this should never be printed\"") + assert send_signal("EVAL { :expand_once, '#{filename}' }") =~ """ + if(true) do + nil + else + IO.puts("this should never be printed") + end + """ + end + + test "Expand macro" do + filename = Path.expand("fixtures/macro_expand_fixture.exs", __DIR__) + File.write(filename, "unless true, do: IO.puts \"this should never be printed\"") + assert send_signal("EVAL { :expand, '#{filename}' }") =~ """ + case(true) do + x when x in [false, nil] -> + IO.puts("this should never be printed") + _ -> + nil + end + """ + end + + test "Get all available application modules" do + assert send_signal("INFO { :type, :modules }") =~ """ + Elixir.Logger + Elixir.Logger.Formatter + Elixir.Logger.Translator + """ + end + + test "Get all available mix tasks by name" do + assert send_signal("INFO { :type, :mixtasks }") =~ """ + app.start + archive + archive.build + archive.install + archive.uninstall + clean + cmd + compile + """ + end + + # The IEx.Helpers.t and IEx.Helpers.i are functionality which come with + # Elixir version 1.2.0 + if Version.match?(System.version, ">=1.2.0-rc") do + test "Get information from data type" do + assert send_signal("INFO { :type, :info, List}") =~ """ + Reference modules\e[0m\n\e[22m Module, Atom\e[0m\nEND-OF-INFO + """ + end + + test "Don't crash server if data type argument is faulty" do + assert send_signal("INFO { :type, :info, whatever}") =~ """ + END-OF-INFO + """ + end + + test "Prints the types for the given module or for the given function/arity pair" do + assert send_signal("INFO { :type, :types, 'Agent'}") =~ """ + @type agent() :: pid() | {atom(), node()} | name()\e[0m\n\e[22m@type state() :: term()\e[0m\nEND-OF-INFO + """ + + assert send_signal("INFO { :type, :types, 'Agent.on_start/0'}") =~ """ + @type on_start() :: {:ok, pid()} | {:error, {:already_started, pid()} | term()}\e[0m + """ + end + end + + defp send_signal(signal) do + capture_io(fn -> + Alchemist.Server.read_input(signal) + end) + end +end diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/test_helper.exs b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-server/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start() diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-test-mode.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-test-mode.el new file mode 100644 index 0000000..f9bd0fd --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-test-mode.el @@ -0,0 +1,373 @@ +;;; alchemist-test-mode.el --- Minor mode for Elixir test files. + +;; Copyright © 2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Minor mode for Elixir test files. + +;;; Code: + +(require 'dash) +(require 'alchemist-project) + +(defgroup alchemist-test-mode nil + "Minor mode for Elixir ExUnit files." + :prefix "alchemist-test-mode-" + :group 'alchemist) + +;; Variables + +(defcustom alchemist-test-mode-highlight-tests t + "Non-nil means that specific functions for testing will +be highlighted with more significant font faces." + :type 'boolean + :group 'alchemist-test-mode) + +(defcustom alchemist-test-display-compilation-output nil + "if Non-nil, compilation informations will be displayed +in the test report buffer." + :type 'boolean + :group 'alchemist-test-mode) + +(defcustom alchemist-test-status-modeline t + "if Non-nil, the face of local `mode-name' variable will change with test run status. + +For example, when `alchemist-mix-test' fails, the `mode-name' will be +formatted with the `alchemist-test--failed-face' face, to symbolize failing tests." + :type 'boolean + :group 'alchemist-test) + +(defcustom alchemist-test-ask-about-save t + "Non-nil means 'alchemist-test-excute` asks which buffers to save before running. +Otherwise, it saves all modified buffers without asking." + :type 'boolean + :group 'alchemist-test) + +(defvar alchemist-test--last-run-status "") + +(defconst alchemist-test-report-buffer-name "*alchemist test report*" + "Name of the test report buffer.") + +(defconst alchemist-test-report-process-name "alchemist-test-process" + "Name of the test report process.") + +(defconst alchemist-test--failing-files-regex + "\\( [0-9]+).+\n\s+\\)\\([-A-Za-z0-9./_]+:[0-9]+\\)$") +(defconst alchemist-test--stacktrace-files-regex + "\\( \\)\\([-A-Za-z0-9./_]+:[0-9]+\\).*") + +;; Faces + +(defface alchemist-test--test-file-and-location-face + '((t (:inherit font-lock-variable-name-face :weight bold))) + "Face for the file where the failed test are." + :group 'alchemist-test) + +(defface alchemist-test--stacktrace-file-and-location-face + '((t (:inherit font-lock-keyword-face :weight bold))) + "Face for the stacktrace files." + :group 'alchemist-test) + +(defface alchemist-test--success-face + '((t (:inherit font-lock-variable-name-face :bold t :background "darkgreen" :foreground "white"))) + "Face for successful compilation run." + :group 'alchemist-test) + +(defface alchemist-test--failed-face + '((t (:inherit font-lock-variable-name-face :bold t :background "red" :foreground "white"))) + "Face for failed compilation run." + :group 'alchemist-test) + +(defvar alchemist-test--mode-name-face 'mode-line) + +(defvar alchemist-test-at-point #'alchemist-mix-test-at-point) +(defvar alchemist-test-this-buffer #'alchemist-mix-test-this-buffer) +(defvar alchemist-test #'alchemist-mix-test) +(defvar alchemist-test-file #'alchemist-mix-test-file) +(defvar alchemist-test-jump-to-previous-test #'alchemist-test-mode-jump-to-previous-test) +(defvar alchemist-test-jump-to-next-test #'alchemist-test-mode-jump-to-next-test) +(defvar alchemist-test-list-tests #'alchemist-test-mode-list-tests) + +(defvar alchemist-test-report-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "q" #'quit-window) + (define-key map "t" #'toggle-truncate-lines) + (define-key map "r" #'alchemist-mix-rerun-last-test) + (define-key map (kbd "M-n") #'alchemist-test-next-result) + (define-key map (kbd "M-p") #'alchemist-test-previous-result) + (define-key map (kbd "M-N") #'alchemist-test-next-stacktrace-file) + (define-key map (kbd "M-P") #'alchemist-test-previous-stacktrace-file) + (define-key map (kbd "C-c C-k") #'alchemist-report-interrupt-current-process) + map)) + +(defvar alchemist-test-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-c , s") alchemist-test-at-point) + (define-key map (kbd "C-c , v") alchemist-test-this-buffer) + (define-key map (kbd "C-c , a") alchemist-test) + (define-key map (kbd "C-c , f") alchemist-test-file) + (define-key map (kbd "C-c , p") alchemist-test-jump-to-previous-test) + (define-key map (kbd "C-c , n") alchemist-test-jump-to-next-test) + (define-key map (kbd "C-c , l") alchemist-test-list-tests) + map) + "Keymap for `alchemist-test-mode'.") + +(defconst alchemist-test-mode--test-regex + (let ((whitespace-opt "[[:space:]]*") + (whitespace "[[:space:]]+")) + (concat "\\(^" whitespace-opt "test" whitespace "\\(?10:.+\\)" whitespace "do" whitespace-opt "$" + "\\|" + whitespace " [0-9]+) test .+\\)"))) + +;; Private functions + +(defun alchemist-test--set-modeline-color (status) + (setq alchemist-test--mode-name-face + (if (string-prefix-p "finished" status) + 'alchemist-test--success-face + 'alchemist-test--failed-face))) + +(defun alchemist-test--render-report (buffer) + (with-current-buffer buffer + (let ((inhibit-read-only t)) + (alchemist-test--render-files)))) + +(defun alchemist-test--render-files () + (alchemist-test--render-test-failing-files) + (alchemist-test--render-stacktrace-files)) + +(defun alchemist-test--render-test-failing-files () + (alchemist-test--render-file alchemist-test--failing-files-regex + 'alchemist-test--test-file-and-location-face)) + +(defun alchemist-test--render-stacktrace-files () + (alchemist-test--render-file alchemist-test--stacktrace-files-regex + 'alchemist-test--stacktrace-file-and-location-face)) + +(defun alchemist-test--render-file (regex face) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward regex nil t) + (let ((file (buffer-substring-no-properties (match-beginning 2) (match-end 2)))) + (goto-char (match-beginning 2)) + (replace-match "" nil nil nil 2) + (insert-text-button file + 'face face + 'file file + 'follow-link t + 'action #'alchemist-test--open-file + 'help-echo "visit the source location"))))) + +(defun alchemist-test--open-file (button) + (save-match-data + (string-match "\\([-A-Za-z0-9./_]+\\):\\([0-9]+\\)" (button-get button 'file)) + (let* ((file-with-line (button-get button 'file)) + (file (substring-no-properties file-with-line (match-beginning 1) (match-end 1))) + (line (string-to-number (substring-no-properties file-with-line (match-beginning 2) (match-end 2)))) + (file-path (if (file-exists-p file) + file + (expand-file-name (concat (alchemist-project-root) file))))) + (with-current-buffer (find-file-other-window file-path) + (goto-char (point-min)) + (forward-line (- line 1)))))) + +(defun alchemist-test--handle-exit (status buffer) + (when alchemist-test-status-modeline + (alchemist-test--set-modeline-color status)) + (with-current-buffer buffer + (let ((inhibit-read-only t)) + (alchemist-test--render-files)))) + +(defun alchemist-test-mode--buffer-contains-tests-p () + "Return nil if the current buffer contains no tests, non-nil if it does." + (alchemist-utils-occur-in-buffer-p (current-buffer) alchemist-test-mode--test-regex)) + +(defun alchemist-test-mode--tests-in-buffer () + "Return an alist of tests in this buffer. + +The keys in the list are the test names (e.g., the string passed to the test/2 +macro) while the values are the position at which the test matched." + (save-match-data + (save-excursion + (goto-char (point-min)) + (let ((tests '())) + (while (re-search-forward alchemist-test-mode--test-regex nil t) + (let* ((position (car (match-data))) + (matched-string (match-string 10))) + (set-text-properties 0 (length matched-string) nil matched-string) + (add-to-list 'tests (cons matched-string position) t))) + tests)))) + +(defun alchemist-test-mode--highlight-syntax () + (if alchemist-test-mode-highlight-tests + (font-lock-add-keywords nil + '(("^\s+\\(test\\)\s+" 1 + font-lock-variable-name-face t) + ("^\s+\\(assert[_a-z]*\\|refute[_a-z]*\\|flunk\\)\s+" 1 + font-lock-type-face t) + ("^\s+\\(assert[_a-z]*\\|refute[_a-z]*\\|flunk\\)\(" 1 + font-lock-type-face t))))) + +;; Public functions + +(define-derived-mode alchemist-test-report-mode fundamental-mode "Alchemist Test Report" + "Major mode for presenting Elixir test results. + +\\{alchemist-test-report-mode-map}" + (setq buffer-read-only t) + (setq-local truncate-lines t) + (setq-local electric-indent-chars nil)) + +(defun alchemist-test-save-buffers () + "Save some modified file-visiting buffers." + (save-some-buffers (not alchemist-test-ask-about-save) nil)) + +(defun alchemist-test-clean-compilation-output (output) + (if (not alchemist-test-display-compilation-output) + (with-temp-buffer + (insert output) + (delete-matching-lines "^Compiled .+" (point-min) (point-max)) + (delete-matching-lines "^Generated .+" (point-min) (point-max)) + (buffer-substring-no-properties (point-min) (point-max))) + output)) + +(defun alchemist-test-execute (command-list) + (message "Testing...") + (let* ((command (mapconcat 'concat (-flatten command-list) " "))) + (alchemist-test-save-buffers) + (alchemist-report-run command + alchemist-test-report-process-name + alchemist-test-report-buffer-name + 'alchemist-test-report-mode + #'alchemist-test--handle-exit))) + +(defun alchemist-test-initialize-modeline () + "Initialize the mode-line face." + (when alchemist-test-status-modeline + (setq mode-name + '(:eval (propertize "Elixir" 'face alchemist-test--mode-name-face))))) + +(defun alchemist-test-reset-modeline () + "Reset the current mode-line face to default." + (setq mode-name "Elixir")) + +(defun alchemist-test-mode-jump-to-next-test () + "Jump to the next ExUnit test. If there are no tests after the current +position, jump to the first test in the buffer. Do nothing if there are no tests +in this buffer." + (interactive) + (alchemist-utils-jump-to-next-matching-line alchemist-test-mode--test-regex 'back-to-indentation)) + +(defun alchemist-test-mode-jump-to-previous-test () + "Jump to the previous ExUnit test. If there are no tests before the current +position, jump to the last test in the buffer. Do nothing if there are no tests +in this buffer." + (interactive) + (alchemist-utils-jump-to-previous-matching-line alchemist-test-mode--test-regex 'back-to-indentation)) + +(defun alchemist-test-next-result () + "Jump to the next error in the test report. + +If there are no error after the current position, +jump to the first error in the test report. +Do nothing if there are no error in this test report." + (interactive) + (alchemist-utils-jump-to-next-matching-line alchemist-test--failing-files-regex + 'back-to-indentation)) + +(defun alchemist-test-previous-result () + "Jump to the previous error in the test report. + +If there are no error before the current position, +jump to the first error in the test report. +Do nothing if there are no error in this test report." + (interactive) + (alchemist-utils-jump-to-previous-matching-line alchemist-test--failing-files-regex + #'(lambda () + (forward-line 1) + (back-to-indentation)))) + +(defun alchemist-test-next-stacktrace-file () + "Jump to the next stacktrace file in the test report. + +If there are no stacktrace file after the current position, +jump to the first stacktrace file in the test report. +Do nothing if there are no stacktrace file in this test report." + (interactive) + (alchemist-utils-jump-to-next-matching-line alchemist-test--stacktrace-files-regex + 'back-to-indentation)) + +(defun alchemist-test-previous-stacktrace-file () + "Jump to the previous stacktrace file in the test report. + +If there are no stacktrace file before the current position, +jump to the first stacktrace file in the test report. +Do nothing if there are no stacktrace file in this test report." + (interactive) + (alchemist-utils-jump-to-previous-matching-line alchemist-test--stacktrace-files-regex + 'back-to-indentation)) + +(defun alchemist-test-mode-list-tests () + "List ExUnit tests (calls to the test/2 macro) in the current buffer and jump +to the selected one." + (interactive) + (let* ((tests (alchemist-test-mode--tests-in-buffer)) + (selected (completing-read "Test: " tests)) + (position (cdr (assoc selected tests)))) + (goto-char position) + (back-to-indentation))) + +(defun alchemist-test-toggle-test-report-display () + "Toggle between display or hidding `alchemist-test-report-buffer-name' buffer." + (interactive) + (let* ((buffer (get-buffer alchemist-test-report-buffer-name)) + (window (get-buffer-window buffer))) + (if buffer + (if window + (quit-window nil window) + (display-buffer buffer)) + (message "No Alchemist test report buffer exists.")))) + +;;;###autoload +(define-minor-mode alchemist-test-mode + "Minor mode for Elixir ExUnit files. + +The following commands are available: + +\\{alchemist-test-mode-map}" + :lighter "" + :keymap alchemist-test-mode-map + :group 'alchemist + (when alchemist-test-mode + (alchemist-test-mode--highlight-syntax))) + +;;;###autoload +(defun alchemist-test-enable-mode () + (if (alchemist-utils-test-file-p) + (alchemist-test-mode))) + +;;;###autoload +(dolist (hook '(alchemist-mode-hook)) + (add-hook hook 'alchemist-test-enable-mode)) + +(provide 'alchemist-test-mode) + +;;; alchemist-test-mode.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist-utils.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist-utils.el new file mode 100644 index 0000000..3c16bc5 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist-utils.el @@ -0,0 +1,162 @@ +;;; alchemist-utils.el --- Common utility functions that don't belong anywhere else -*- lexical-binding: t -*- + +;; Copyright © 2014-2015 Samuel Tonini + +;; Author: Samuel Tonini . + +;;; Commentary: + +;; Common utility functions that don't belong anywhere else + +;;; Code: + +(require 'cl-lib) +(require 'dash) + +(defface alchemist-utils--deprecated-face + '((t (:inherit font-lock-variable-name-face :bold t :foreground "red"))) + "Face for 'deprecated' word inside deprecated message." + :group 'alchemist) + +(defun alchemist-utils-deprecated-message (function new-function) + (message "'%s is %s in favor of '%s" + function (propertize "deprecated" + 'face 'alchemist-utils--deprecated-face) + new-function)) + +(defun alchemist-utils-build-command (command-list) + "Build the commands list for the runner." + (let* ((command-list (-flatten (if (stringp command-list) + (split-string command-list) + command-list))) + (command (-remove (lambda (e) (equal e "")) command-list))) + (mapconcat 'concat command " "))) + +(defun alchemist-utils-count-char-occurence (regexp str) + "Count occurrence of char with REGEXP inside STR." + (cl-loop with start = 0 + for count from 0 + while (string-match regexp str start) + do (setq start (match-end 0)) + finally return count)) + +(defun alchemist-utils-test-file-p () + "Return non-nil `current-buffer' holds an Elixir test file." + (string-match "_test\\.exs$" (or (buffer-file-name) ""))) + +(defun alchemist-utils-remove-dot-at-the-end (string) + "Remove dot character at the end of STRING." + (replace-regexp-in-string "\\.$" "" string)) + +(defun alchemist-utils-empty-string-p (string) + "Return non-nil if STRING is null, blank or whitespace only." + (or (null string) + (string= string "") + (if (string-match-p "^\s+$" string) t))) + +(defun alchemist-utils-prepare-aliases-for-elixir (aliases) + (let* ((aliases (-map (lambda (a) + (let ((module (alchemist-utils-remove-dot-at-the-end (car a))) + (alias (alchemist-utils-remove-dot-at-the-end (car (cdr a))))) + (if (not (or (alchemist-utils-empty-string-p alias) + (string= alias module))) + (format "{%s, %s}" + (if (alchemist-utils-empty-string-p alias) + module + alias) + module)))) aliases)) + (aliases (mapconcat #'identity aliases ","))) + (format "[%s]" aliases))) + +(defun alchemist-utils-prepare-modules-for-elixir (modules) + (let* ((modules (mapconcat #'identity modules ","))) + (format "[%s]" modules))) + +(defun alchemist-utils--snakecase-to-camelcase (str) + "Convert a snake_case string STR to a CamelCase string. + +This function is useful for converting file names like my_module to Elixir +module names (MyModule)." + (mapconcat 'capitalize (split-string str "_") "")) + +(defun alchemist-utils-add-ext-to-path-if-not-present (path ext) + "Add EXT to PATH if PATH doesn't already ends with EXT." + (if (string-suffix-p ext path) + path + (concat path ext))) + +(defun alchemist-utils-path-to-module-name (path) + "Convert PATH to its Elixir module name equivalent. + +For example, convert 'my_app/my_module.ex' to 'MyApp.MyModule'." + (let* ((path (file-name-sans-extension path)) + (path (split-string path "/")) + (path (-remove (lambda (str) (equal str "")) path))) + (mapconcat #'alchemist-utils--snakecase-to-camelcase path "."))) + +(defun alchemist-utils-add-trailing-slash (path) + "Add trailing slash to PATH if not already contain." + (if (not (string-match-p "/$" path)) + (format "%s/" path) + path)) + +(defun alchemist-utils-occur-in-buffer-p (buffer regex) + "Return non-nil if BUFFER contains at least one occurrence of REGEX." + (with-current-buffer buffer + (save-excursion + (save-match-data + (goto-char (point-min)) + (re-search-forward regex nil t))))) + +(defun alchemist-utils-jump-to-regex (regex before-fn after-fn search-fn reset-fn) + "Jump to REGEX using SEARCH-FN to search for it. +A common use case would be to use `re-search-forward' as the SEARCH-FN. +Call RESET-FN if the regex isn't found at the first try. BEFORE-FN is called +before performing the search while AFTER-FN after." + (when (alchemist-utils-occur-in-buffer-p (current-buffer) regex) + (save-match-data + (funcall before-fn) + (unless (funcall search-fn regex nil t) + (funcall reset-fn) + (funcall search-fn regex nil t)) + (funcall after-fn)))) + +(defun alchemist-utils-jump-to-next-matching-line (regex after-fn) + "Jump to the next line matching REGEX. +Call AFTER-FN after performing the search." + (alchemist-utils-jump-to-regex regex 'end-of-line after-fn 're-search-forward 'beginning-of-buffer)) + +(defun alchemist-utils-jump-to-previous-matching-line (regex after-fn) + "Jump to the previous line matching REGEX. + +Call AFTER-FN after performing the search." + (alchemist-utils-jump-to-regex regex 'beginning-of-line after-fn 're-search-backward 'end-of-buffer)) + +(defun alchemist-utils-elixir-version () + "Return the current Elixir version on the system." + (let* ((output (shell-command-to-string (format "%s --version" alchemist-execute-command))) + (output (split-string output "\n")) + (output (-remove (lambda (string) (alchemist-utils-empty-string-p string)) + output)) + (version (-last-item output)) + (version (replace-regexp-in-string "Elixir " "" version))) + version)) + +(provide 'alchemist-utils) + +;;; alchemist-utils.el ends here diff --git a/emacs.d/elpa/alchemist-20160111.2340/alchemist.el b/emacs.d/elpa/alchemist-20160111.2340/alchemist.el new file mode 100644 index 0000000..28342b8 --- /dev/null +++ b/emacs.d/elpa/alchemist-20160111.2340/alchemist.el @@ -0,0 +1,282 @@ +;;; alchemist.el --- Elixir tooling integration into Emacs + +;; Copyright © 2014-2015 Samuel Tonini +;; +;; Author: Samuel Tonini +;; Maintainer: Samuel Tonini +;; URL: http://www.github.com/tonini/alchemist.el +;; Version: 1.7.0 +;; Package-Requires: ((elixir-mode "2.2.5") (dash "2.11.0") (emacs "24.4") (company "0.8.0") (pkg-info "0.4")) +;; Keywords: languages, elixir, elixirc, mix, hex, alchemist + +;; This file is not part of GNU Emacs. + +;; 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 . + +;;; Commentary: +;; +;; What Does Alchemist Do For You? +;; +;; Alchemist brings you all the Elixir tooling and power inside your Emacs editor. +;; +;; Alchemist comes with a bunch of features, which are: +;; +;; * Mix integration +;; * Compile & Execution of Elixir code +;; * Inline code evaluation +;; * Inline macro expanding +;; * Documentation lookup +;; * Definition lookup +;; * Powerful IEx integration +;; * Smart code completion +;; * Elixir project management +;; * Phoenix support + +;;; Code: + +;; Tell the byte compiler about autoloaded functions from packages +(declare-function pkg-info-version-info "pkg-info" (package)) + +(defgroup alchemist nil + "Elixir Tooling Integration Into Emacs." + :prefix "alchemist-" + :group 'applications + :link '(url-link :tag "Website" "http://www.alchemist-elixir.org") + :link '(url-link :tag "Github" "https://github.com/tonini/alchemist.el") + :link '(emacs-commentary-link :tag "Commentary" "alchemist")) + +(defvar alchemist-mode-keymap nil) + +(require 'easymenu) +(require 'company) +(require 'elixir-mode) +(require 'alchemist-utils) +(require 'alchemist-key) +(require 'alchemist-eval) +(require 'alchemist-goto) +(require 'alchemist-info) +(require 'alchemist-report) +(require 'alchemist-mix) +(require 'alchemist-hooks) +(require 'alchemist-message) +(require 'alchemist-iex) +(require 'alchemist-compile) +(require 'alchemist-refcard) +(require 'alchemist-complete) +(require 'alchemist-company) +(require 'alchemist-macroexpand) +(require 'alchemist-phoenix) + +(defun alchemist-mode-hook () + "Hook which enables `alchemist-mode'" + (alchemist-mode 1)) + +(defun alchemist-version (&optional show-version) + "Get the Alchemist version as string. + +If called interactively or if SHOW-VERSION is non-nil, show the +version in the echo area and the messages buffer. + +The returned string includes both, the version from package.el +and the library version, if both a present and different. + +If the version number could not be determined, signal an error, +if called interactively, or if SHOW-VERSION is non-nil, otherwise +just return nil." + (interactive (list t)) + (let ((version (pkg-info-version-info 'alchemist))) + (when show-version + (message "Alchemist version: %s" version)) + version)) + +(defun alchemist-elixir-version () + "Display the current Elixir version on the system." + (interactive) + (message "Elixir %s" (alchemist-utils-elixir-version))) + +(define-prefix-command 'alchemist-mode-keymap) + +;;;###autoload +(define-minor-mode alchemist-mode + "Toggle alchemist mode. + +Key bindings: +\\{alchemist-mode-map}" + nil + ;; The indicator for the mode line. + " alchemist" + :group 'alchemist + :global nil + :keymap `((,alchemist-key-command-prefix . alchemist-mode-keymap)) + (cond (alchemist-mode + (alchemist-server-start-if-not-running) + (alchemist-test-initialize-modeline)) + (t + (alchemist-test-reset-modeline)))) + +(let ((map alchemist-mode-keymap)) + (define-key map (kbd "x") 'alchemist-mix) + (define-key map (kbd "t") 'alchemist-mix-test) + (define-key map (kbd "r") 'alchemist-mix-rerun-last-test) + + (define-key map (kbd "m c") 'alchemist-mix-compile) + (define-key map (kbd "m r") 'alchemist-mix-run) + (define-key map (kbd "m t f") 'alchemist-mix-test-file) + (define-key map (kbd "m t b") 'alchemist-mix-test-this-buffer) + (define-key map (kbd "m t .") 'alchemist-mix-test-at-point) + + (define-key map (kbd "c c") 'alchemist-compile) + (define-key map (kbd "c f") 'alchemist-compile-file) + (define-key map (kbd "c b") 'alchemist-compile-this-buffer) + + (define-key map (kbd "e e") 'alchemist-execute) + (define-key map (kbd "e f") 'alchemist-execute-file) + (define-key map (kbd "e b") 'alchemist-execute-this-buffer) + + (define-key map (kbd "h h") 'alchemist-help) + (define-key map (kbd "h i") 'alchemist-help-history) + (define-key map (kbd "h e") 'alchemist-help-search-at-point) + (define-key map (kbd "h r") 'alchemist-refcard) + + (define-key map (kbd "p s") 'alchemist-project-toggle-file-and-tests) + (define-key map (kbd "p o") 'alchemist-project-toggle-file-and-tests-other-window) + (define-key map (kbd "p t") 'alchemist-project-run-tests-for-current-file) + (define-key map (kbd "p l") 'alchemist-project-find-lib) + (define-key map (kbd "p f") 'alchemist-project-find-test) + + (define-key map (kbd "i i") 'alchemist-iex-run) + (define-key map (kbd "i p") 'alchemist-iex-project-run) + (define-key map (kbd "i l") 'alchemist-iex-send-current-line) + (define-key map (kbd "i c") 'alchemist-iex-send-current-line-and-go) + (define-key map (kbd "i r") 'alchemist-iex-send-region) + (define-key map (kbd "i m") 'alchemist-iex-send-region-and-go) + (define-key map (kbd "i b") 'alchemist-iex-compile-this-buffer) + (define-key map (kbd "i R") 'alchemist-iex-reload-module) + + (define-key map (kbd "v l") 'alchemist-eval-current-line) + (define-key map (kbd "v k") 'alchemist-eval-print-current-line) + (define-key map (kbd "v j") 'alchemist-eval-quoted-current-line) + (define-key map (kbd "v h") 'alchemist-eval-print-quoted-current-line) + (define-key map (kbd "v o") 'alchemist-eval-region) + (define-key map (kbd "v i") 'alchemist-eval-print-region) + (define-key map (kbd "v u") 'alchemist-eval-quoted-region) + (define-key map (kbd "v y") 'alchemist-eval-print-quoted-region) + (define-key map (kbd "v q") 'alchemist-eval-buffer) + (define-key map (kbd "v w") 'alchemist-eval-print-buffer) + (define-key map (kbd "v e") 'alchemist-eval-quoted-buffer) + (define-key map (kbd "v r") 'alchemist-eval-print-quoted-buffer) + (define-key map (kbd "v !") 'alchemist-eval-close-popup) + + (define-key map (kbd "o l") 'alchemist-macroexpand-once-current-line) + (define-key map (kbd "o L") 'alchemist-macroexpand-once-print-current-line) + (define-key map (kbd "o k") 'alchemist-macroexpand-current-line) + (define-key map (kbd "o K") 'alchemist-macroexpand-print-current-line) + (define-key map (kbd "o i") 'alchemist-macroexpand-once-region) + (define-key map (kbd "o I") 'alchemist-macroexpand-once-print-region) + (define-key map (kbd "o r") 'alchemist-macroexpand-region) + (define-key map (kbd "o R") 'alchemist-macroexpand-print-region) + (define-key map (kbd "o !") 'alchemist-macroexpand-close-popup) + + (define-key map (kbd "n i") 'alchemist-info-datatype-at-point) + (define-key map (kbd "n t") 'alchemist-info-types-at-point)) + +(define-key alchemist-mode-map (kbd "M-.") 'alchemist-goto-definition-at-point) +(define-key alchemist-mode-map (kbd "M-,") 'alchemist-goto-jump-back) +(define-key alchemist-mode-map (kbd "C-c , .") 'alchemist-goto-list-symbol-definitions) +(define-key alchemist-mode-map (kbd "M-P") 'alchemist-goto-jump-to-previous-def-symbol) +(define-key alchemist-mode-map (kbd "M-N") 'alchemist-goto-jump-to-next-def-symbol) +(define-key alchemist-mode-map (kbd "C-c M-r") 'alchemist-test-toggle-test-report-display) + +(easy-menu-define alchemist-mode-menu alchemist-mode-map + "Alchemist mode menu." + '("Alchemist" + ("Goto" + ["Jump to definition at point" alchemist-goto-definition-at-point] + ["Jump back" alchemist-goto-jump-back]) + ("Evaluate" + ["Evaluate current line" alchemist-eval-current-line] + ["Evaluate current line and print" alchemist-eval-print-current-line] + ["Evaluate quoted current line" alchemist-eval-quoted-current-line] + ["Evaluate quoted current line and print" alchemist-eval-print-quoted-current-line] + "---" + ["Evaluate region" alchemist-eval-region] + ["Evaluate region and print" alchemist-eval-print-region] + ["Evaluate quoted region" alchemist-eval-quoted-region] + ["Evaluate quoted region and print" alchemist-eval-print-quoted-region] + "---" + ["Evaluate buffer" alchemist-eval-buffer] + ["Evaluate buffer and print" alchemist-eval-print-buffer] + ["Evaluate quoted buffer" alchemist-eval-quoted-buffer] + ["Evaluate quoted buffer and print" alchemist-eval-print-quoted-buffer]) + ("Macroexpand" + ["Macro expand once current line" alchemist-macroexpand-once-current-line] + ["Macro expand once current line and print" alchemist-macroexpand-print-current-line] + ["Macro expand current line" alchemist-macroexpand-current-line] + ["Macro expand current line and print" alchemist-macroexpand-print-current-line] + "---" + ["Macro expand once region" alchemist-macroexpand-once-region] + ["Macro expand once region and print" alchemist-macroexpand-print-region] + ["Macro expand region" alchemist-macroexpand-region] + ["Macro expand region and print" alchemist-macroexpand-print-region]) + ("Compile" + ["Compile..." alchemist-compile] + ["Compile this buffer" alchemist-compile-this-buffer] + ["Compile file" alchemist-compile-file]) + ("Execute" + ["Execute..." alchemist-compile] + ["Execute this buffer" alchemist-execute-this-buffer] + ["Execute file" alchemist-execute-file]) + ("Mix" + ["Mix compile..." alchemist-mix-compile] + ["Mix run..." alchemist-mix-run] + "---" + ["Mix test this buffer" alchemist-mix-test-this-buffer] + ["Mix test file..." alchemist-mix-test-file] + ["Mix test at point" alchemist-mix-test-at-point] + "---" + ["Mix..." alchemist-mix] + "---" + ["Display mix buffer" alchemist-mix-display-mix-buffer] + "---" + ["Mix help..." alchemist-mix-help]) + ("IEx" + ["IEx send current line" alchemist-iex-send-current-line] + ["IEx send current line and go" alchemist-iex-send-current-line-and-go] + "---" + ["IEx send last region" alchemist-iex-send-last-sexp] + ["IEx send region" alchemist-iex-send-region] + ["IEx send region and go" alchemist-iex-send-region-and-go] + "---" + ["IEx compile this buffer" alchemist-iex-compile-this-buffer] + ["IEx recompile this buffer" alchemist-iex-recompile-this-buffer] + "---" + ["IEx run" alchemist-iex-run]) + ("Project" + ["Project list all files inside test directory" alchemist-project-find-test] + ["Project list all files inside lib directory" alchemist-project-find-lib] + ["Project toggle between file and test" alchemist-project-toggle-file-and-tests] + ["Project toggle between file and test in other window" alchemist-project-toggle-file-and-tests-other-window]) + ("Documentation" + ["Documentation search..." alchemist-help] + ["Documentation search history..." alchemist-help-history] + "---" + ["Documentation search at point..." alchemist-help-search-at-point]) + ("About" + ["Show Alchemist version" alchemist-version t]))) + +(add-hook 'elixir-mode-hook 'alchemist-mode-hook) + +(provide 'alchemist) + +;;; alchemist.el ends here diff --git a/emacs.d/elpa/async-20150529.529/async-autoloads.el b/emacs.d/elpa/async-20150529.529/async-autoloads.el deleted file mode 100644 index b0268d2..0000000 --- a/emacs.d/elpa/async-20150529.529/async-autoloads.el +++ /dev/null @@ -1,129 +0,0 @@ -;;; async-autoloads.el --- automatically extracted autoloads -;; -;;; Code: -(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) - -;;;### (autoloads nil "async" "async.el" (21898 47984 0 0)) -;;; Generated autoloads from async.el - -(autoload 'async-start-process "async" "\ -Start the executable PROGRAM asynchronously. See `async-start'. -PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the -process object when done. If FINISH-FUNC is nil, the future -object will return the process object when the program is -finished. Set DEFAULT-DIRECTORY to change PROGRAM's current -working directory. - -\(fn NAME PROGRAM FINISH-FUNC &rest PROGRAM-ARGS)" nil nil) - -(autoload 'async-start "async" "\ -Execute START-FUNC (often a lambda) in a subordinate Emacs process. -When done, the return value is passed to FINISH-FUNC. Example: - - (async-start - ;; What to do in the child process - (lambda () - (message \"This is a test\") - (sleep-for 3) - 222) - - ;; What to do when it finishes - (lambda (result) - (message \"Async process done, result should be 222: %s\" - result))) - -If FINISH-FUNC is nil or missing, a future is returned that can -be inspected using `async-get', blocking until the value is -ready. Example: - - (let ((proc (async-start - ;; What to do in the child process - (lambda () - (message \"This is a test\") - (sleep-for 3) - 222)))) - - (message \"I'm going to do some work here\") ;; .... - - (message \"Waiting on async process, result should be 222: %s\" - (async-get proc))) - -If you don't want to use a callback, and you don't care about any -return value form the child process, pass the `ignore' symbol as -the second argument (if you don't, and never call `async-get', it -will leave *emacs* process buffers hanging around): - - (async-start - (lambda () - (delete-file \"a remote file on a slow link\" nil)) - 'ignore) - -Note: Even when FINISH-FUNC is present, a future is still -returned except that it yields no value (since the value is -passed to FINISH-FUNC). Call `async-get' on such a future always -returns nil. It can still be useful, however, as an argument to -`async-ready' or `async-wait'. - -\(fn START-FUNC &optional FINISH-FUNC)" nil t) - -;;;*** - -;;;### (autoloads nil "async-bytecomp" "async-bytecomp.el" (21898 -;;;;;; 47984 0 0)) -;;; Generated autoloads from async-bytecomp.el - -(autoload 'async-byte-recompile-directory "async-bytecomp" "\ -Compile all *.el files in DIRECTORY asynchronously. -All *.elc files are systematically deleted before proceeding. - -\(fn DIRECTORY &optional QUIET)" nil nil) - -(defvar async-bytecomp-package-mode nil "\ -Non-nil if Async-Bytecomp-Package mode is enabled. -See the command `async-bytecomp-package-mode' for a description of this minor mode. -Setting this variable directly does not take effect; -either customize it (see the info node `Easy Customization') -or call the function `async-bytecomp-package-mode'.") - -(custom-autoload 'async-bytecomp-package-mode "async-bytecomp" nil) - -(autoload 'async-bytecomp-package-mode "async-bytecomp" "\ -Byte compile asynchronously packages installed with package.el. -Async compilation of packages can be controlled by -`async-bytecomp-allowed-packages'. - -\(fn &optional ARG)" t nil) - -;;;*** - -;;;### (autoloads nil "dired-async" "dired-async.el" (21898 47984 -;;;;;; 0 0)) -;;; Generated autoloads from dired-async.el - -(defvar dired-async-mode nil "\ -Non-nil if Dired-Async mode is enabled. -See the command `dired-async-mode' for a description of this minor mode. -Setting this variable directly does not take effect; -either customize it (see the info node `Easy Customization') -or call the function `dired-async-mode'.") - -(custom-autoload 'dired-async-mode "dired-async" nil) - -(autoload 'dired-async-mode "dired-async" "\ -Do dired actions asynchronously. - -\(fn &optional ARG)" t nil) - -;;;*** - -;;;### (autoloads nil nil ("async-pkg.el" "smtpmail-async.el") (21898 -;;;;;; 47984 290337 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; async-autoloads.el ends here diff --git a/emacs.d/elpa/async-20150529.529/async-bytecomp.el b/emacs.d/elpa/async-20150529.529/async-bytecomp.el deleted file mode 100644 index 0004347..0000000 --- a/emacs.d/elpa/async-20150529.529/async-bytecomp.el +++ /dev/null @@ -1,160 +0,0 @@ -;;; async-bytecomp.el --- Async functions to compile elisp files async - -;; Copyright (C) 2014 John Wiegley -;; Copyright (C) 2014 Thierry Volpiatto - -;; Authors: John Wiegley -;; Thierry Volpiatto - -;; Keywords: dired async byte-compile -;; X-URL: https://github.com/jwiegley/dired-async - -;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: -;; -;; This package provide the `async-byte-recompile-directory' function -;; which allows, as the name says to recompile a directory outside of -;; your running emacs. -;; The benefit is your files will be compiled in a clean environment without -;; the old *.el files loaded. -;; Among other things, this fix a bug in package.el which recompile -;; the new files in the current environment with the old files loaded, creating -;; errors in most packages after upgrades. -;; -;; NB: This package is advicing the function `package--compile'. - -;;; Code: - -(require 'cl-lib) -(require 'async) - -(defcustom async-bytecomp-allowed-packages '(async helm) - "Packages in this list will be compiled asynchronously by `package--compile'. -All the dependencies of these packages will be compiled async too, -so no need to add dependencies to this list. -The value of this variable can also be a list with a single element, -the symbol `all', in this case packages are always compiled asynchronously." - :group 'async - :type '(repeat (choice symbol))) - -(defvar async-byte-compile-log-file "~/.emacs.d/async-bytecomp.log") - -;;;###autoload -(defun async-byte-recompile-directory (directory &optional quiet) - "Compile all *.el files in DIRECTORY asynchronously. -All *.elc files are systematically deleted before proceeding." - (cl-loop with dir = (directory-files directory t "\\.elc\\'") - unless dir return nil - for f in dir - when (file-exists-p f) do (delete-file f)) - ;; Ensure async is reloaded when async.elc is deleted. - ;; This happen when recompiling its own directory. - (load "async") - (let ((call-back - `(lambda (&optional ignore) - (if (file-exists-p async-byte-compile-log-file) - (let ((buf (get-buffer-create byte-compile-log-buffer)) - (n 0)) - (with-current-buffer buf - (goto-char (point-max)) - (let ((inhibit-read-only t)) - (insert-file-contents async-byte-compile-log-file) - (compilation-mode)) - (display-buffer buf) - (delete-file async-byte-compile-log-file) - (unless ,quiet - (save-excursion - (goto-char (point-min)) - (while (re-search-forward "^.*:Error:" nil t) - (cl-incf n))) - (if (> n 0) - (message "Failed to compile %d files in directory `%s'" n ,directory) - (message "Directory `%s' compiled asynchronously with warnings" ,directory))))) - (unless ,quiet - (message "Directory `%s' compiled asynchronously with success" ,directory)))))) - (async-start - `(lambda () - (require 'bytecomp) - ,(async-inject-variables "\\`\\(load-path\\)\\|byte\\'") - (let ((default-directory (file-name-as-directory ,directory)) - error-data) - (add-to-list 'load-path default-directory) - (byte-recompile-directory ,directory 0 t) - (when (get-buffer byte-compile-log-buffer) - (setq error-data (with-current-buffer byte-compile-log-buffer - (buffer-substring-no-properties (point-min) (point-max)))) - (unless (string= error-data "") - (with-temp-file ,async-byte-compile-log-file - (erase-buffer) - (insert error-data)))))) - call-back) - (unless quiet (message "Started compiling asynchronously directory %s" directory)))) - -(defvar package-archive-contents) -(declare-function package-desc-reqs "package.el" (cl-x)) - -(defun async-bytecomp--get-package-deps (pkg &optional only) - (let* ((pkg-desc (cadr (assq pkg package-archive-contents))) - (direct-deps (cl-loop for p in (package-desc-reqs pkg-desc) - for name = (car p) - when (assq name package-archive-contents) - collect name)) - (indirect-deps (unless (eq only 'direct) - (delete-dups - (cl-loop for p in direct-deps append - (async-bytecomp--get-package-deps p)))))) - (cl-case only - (direct direct-deps) - (separate (list direct-deps indirect-deps)) - (indirect indirect-deps) - (t (delete-dups (append direct-deps indirect-deps)))))) - -(defun async-bytecomp-get-allowed-pkgs () - (when (and async-bytecomp-allowed-packages - (listp async-bytecomp-allowed-packages)) - (cl-loop for p in async-bytecomp-allowed-packages - append (async-bytecomp--get-package-deps p) into reqs - finally return - (delete-dups - (append async-bytecomp-allowed-packages reqs))))) - -(defadvice package--compile (around byte-compile-async) - (let ((cur-package (package-desc-name pkg-desc))) - (if (or (equal async-bytecomp-allowed-packages '(all)) - (memq cur-package (async-bytecomp-get-allowed-pkgs))) - (progn - (when (eq cur-package 'async) - (fmakunbound 'async-byte-recompile-directory)) - (package-activate-1 pkg-desc) - (load "async-bytecomp") ; emacs-24.3 don't reload new files. - (async-byte-recompile-directory (package-desc-dir pkg-desc) t)) - ad-do-it))) - -;;;###autoload -(define-minor-mode async-bytecomp-package-mode - "Byte compile asynchronously packages installed with package.el. -Async compilation of packages can be controlled by -`async-bytecomp-allowed-packages'." - :group 'async - :global t - (if async-bytecomp-package-mode - (ad-activate 'package--compile) - (ad-deactivate 'package--compile))) - -(provide 'async-bytecomp) - -;;; async-bytecomp.el ends here diff --git a/emacs.d/elpa/async-20150529.529/async-pkg.el b/emacs.d/elpa/async-20150529.529/async-pkg.el deleted file mode 100644 index da89a15..0000000 --- a/emacs.d/elpa/async-20150529.529/async-pkg.el +++ /dev/null @@ -1,4 +0,0 @@ -(define-package "async" "20150529.529" "Asynchronous processing in Emacs" 'nil) -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/emacs.d/elpa/async-20150529.529/async.el b/emacs.d/elpa/async-20150529.529/async.el deleted file mode 100644 index be9c04e..0000000 --- a/emacs.d/elpa/async-20150529.529/async.el +++ /dev/null @@ -1,292 +0,0 @@ -;;; async --- Asynchronous processing in Emacs - -;; Copyright (C) 2012~2014 John Wiegley - -;; Author: John Wiegley -;; Created: 18 Jun 2012 - -;; Keywords: async -;; X-URL: https://github.com/jwiegley/emacs-async - -;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; Adds the ability to call asynchronous functions and process with ease. See -;; the documentation for `async-start' and `async-start-process'. - -;;; Code: - -(defgroup async nil - "Simple asynchronous processing in Emacs" - :group 'emacs) - -(defvar async-debug nil) -(defvar async-send-over-pipe t) -(defvar async-in-child-emacs nil) -(defvar async-callback nil) -(defvar async-callback-for-process nil) -(defvar async-callback-value nil) -(defvar async-callback-value-set nil) -(defvar async-current-process nil) - -(defun async-inject-variables - (include-regexp &optional predicate exclude-regexp) - "Return a `setq' form that replicates part of the calling environment. -It sets the value for every variable matching INCLUDE-REGEXP and -also PREDICATE. It will not perform injection for any variable -matching EXCLUDE-REGEXP (if present). It is intended to be used -as follows: - - (async-start - `(lambda () - (require 'smtpmail) - (with-temp-buffer - (insert ,(buffer-substring-no-properties (point-min) (point-max))) - ;; Pass in the variable environment for smtpmail - ,(async-inject-variables \"\\`\\(smtpmail\\|\\(user-\\)?mail\\)-\") - (smtpmail-send-it))) - 'ignore)" - `(setq - ,@(let (bindings) - (mapatoms - (lambda (sym) - (if (and (boundp sym) - (or (null include-regexp) - (string-match include-regexp (symbol-name sym))) - (not (string-match - (or exclude-regexp "-syntax-table\\'") - (symbol-name sym)))) - (let ((value (symbol-value sym))) - (when (or (null predicate) - (funcall predicate sym)) - (setq bindings (cons `(quote ,value) bindings) - bindings (cons sym bindings))))))) - bindings))) - -(defalias 'async-inject-environment 'async-inject-variables) - -(defun async-handle-result (func result buf) - (if (null func) - (progn - (set (make-local-variable 'async-callback-value) result) - (set (make-local-variable 'async-callback-value-set) t)) - (unwind-protect - (if (and (listp result) - (eq 'async-signal (nth 0 result))) - (signal (car (nth 1 result)) - (cdr (nth 1 result))) - (funcall func result)) - (unless async-debug - (kill-buffer buf))))) - -(defun async-when-done (proc &optional change) - "Process sentinal used to retrieve the value from the child process." - (when (eq 'exit (process-status proc)) - (with-current-buffer (process-buffer proc) - (let ((async-current-process proc)) - (if (= 0 (process-exit-status proc)) - (if async-callback-for-process - (if async-callback - (prog1 - (funcall async-callback proc) - (unless async-debug - (kill-buffer (current-buffer)))) - (set (make-local-variable 'async-callback-value) proc) - (set (make-local-variable 'async-callback-value-set) t)) - (goto-char (point-max)) - (backward-sexp) - (async-handle-result async-callback (read (current-buffer)) - (current-buffer))) - (set (make-local-variable 'async-callback-value) - (list 'error - (format "Async process '%s' failed with exit code %d" - (process-name proc) (process-exit-status proc)))) - (set (make-local-variable 'async-callback-value-set) t)))))) - -(defun async--receive-sexp (&optional stream) - (let ((sexp (decode-coding-string (base64-decode-string - (read stream)) 'utf-8-unix))) - (if async-debug - (message "Received sexp {{{%s}}}" (pp-to-string sexp))) - (setq sexp (read sexp)) - (if async-debug - (message "Read sexp {{{%s}}}" (pp-to-string sexp))) - (eval sexp))) - -(defun async--insert-sexp (sexp) - (prin1 sexp (current-buffer)) - ;; Just in case the string we're sending might contain EOF - (encode-coding-region (point-min) (point-max) 'utf-8-unix) - (base64-encode-region (point-min) (point-max) t) - (goto-char (point-min)) (insert ?\") - (goto-char (point-max)) (insert ?\" ?\n)) - -(defun async--transmit-sexp (process sexp) - (with-temp-buffer - (if async-debug - (message "Transmitting sexp {{{%s}}}" (pp-to-string sexp))) - (async--insert-sexp sexp) - (process-send-region process (point-min) (point-max)))) - -(defun async-batch-invoke () - "Called from the child Emacs process' command-line." - (setq async-in-child-emacs t - debug-on-error async-debug) - (if debug-on-error - (prin1 (funcall - (async--receive-sexp (unless async-send-over-pipe - command-line-args-left)))) - (condition-case err - (prin1 (funcall - (async--receive-sexp (unless async-send-over-pipe - command-line-args-left)))) - (error - (prin1 (list 'async-signal err)))))) - -(defun async-ready (future) - "Query a FUTURE to see if the ready is ready -- i.e., if no blocking -would result from a call to `async-get' on that FUTURE." - (and (memq (process-status future) '(exit signal)) - (with-current-buffer (process-buffer future) - async-callback-value-set))) - -(defun async-wait (future) - "Wait for FUTURE to become ready." - (while (not (async-ready future)) - (sit-for 0.05))) - -(defun async-get (future) - "Get the value from an asynchronously function when it is ready. -FUTURE is returned by `async-start' or `async-start-process' when -its FINISH-FUNC is nil." - (async-wait future) - (with-current-buffer (process-buffer future) - (async-handle-result #'identity async-callback-value (current-buffer)))) - -(defun async-message-p (value) - "Return true of VALUE is an async.el message packet." - (and (listp value) - (plist-get value :async-message))) - -(defun async-send (&rest args) - "Send the given messages to the asychronous Emacs PROCESS." - (let ((args (append args '(:async-message t)))) - (if async-in-child-emacs - (if async-callback - (funcall async-callback args)) - (async--transmit-sexp (car args) (list 'quote (cdr args)))))) - -(defun async-receive (&rest args) - "Send the given messages to the asychronous Emacs PROCESS." - (async--receive-sexp)) - -;;;###autoload -(defun async-start-process (name program finish-func &rest program-args) - "Start the executable PROGRAM asynchronously. See `async-start'. -PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the -process object when done. If FINISH-FUNC is nil, the future -object will return the process object when the program is -finished. Set DEFAULT-DIRECTORY to change PROGRAM's current -working directory." - (let* ((buf (generate-new-buffer (concat "*" name "*"))) - (proc (let ((process-connection-type nil)) - (apply #'start-process name buf program program-args)))) - (with-current-buffer buf - (set (make-local-variable 'async-callback) finish-func) - (set-process-sentinel proc #'async-when-done) - (unless (string= name "emacs") - (set (make-local-variable 'async-callback-for-process) t)) - proc))) - -;;;###autoload -(defmacro async-start (start-func &optional finish-func) - "Execute START-FUNC (often a lambda) in a subordinate Emacs process. -When done, the return value is passed to FINISH-FUNC. Example: - - (async-start - ;; What to do in the child process - (lambda () - (message \"This is a test\") - (sleep-for 3) - 222) - - ;; What to do when it finishes - (lambda (result) - (message \"Async process done, result should be 222: %s\" - result))) - -If FINISH-FUNC is nil or missing, a future is returned that can -be inspected using `async-get', blocking until the value is -ready. Example: - - (let ((proc (async-start - ;; What to do in the child process - (lambda () - (message \"This is a test\") - (sleep-for 3) - 222)))) - - (message \"I'm going to do some work here\") ;; .... - - (message \"Waiting on async process, result should be 222: %s\" - (async-get proc))) - -If you don't want to use a callback, and you don't care about any -return value form the child process, pass the `ignore' symbol as -the second argument (if you don't, and never call `async-get', it -will leave *emacs* process buffers hanging around): - - (async-start - (lambda () - (delete-file \"a remote file on a slow link\" nil)) - 'ignore) - -Note: Even when FINISH-FUNC is present, a future is still -returned except that it yields no value (since the value is -passed to FINISH-FUNC). Call `async-get' on such a future always -returns nil. It can still be useful, however, as an argument to -`async-ready' or `async-wait'." - (require 'find-func) - (let ((procvar (make-symbol "proc"))) - `(let* ((sexp ,start-func) - (,procvar - (async-start-process - "emacs" (file-truename - (expand-file-name invocation-name - invocation-directory)) - ,finish-func - "-Q" "-l" - ;; Using `locate-library' ensure we use the right file - ;; when the .elc have been deleted. - ,(locate-library "async") - "-batch" "-f" "async-batch-invoke" - (if async-send-over-pipe - "" - (with-temp-buffer - (async--insert-sexp (list 'quote sexp)) - (buffer-string)))))) - (if async-send-over-pipe - (async--transmit-sexp ,procvar (list 'quote sexp))) - ,procvar))) - -(defmacro async-sandbox(func) - "Evaluate FUNC in a separate Emacs process, synchronously." - `(async-get (async-start ,func))) - -(provide 'async) - -;;; async.el ends here diff --git a/emacs.d/elpa/async-20150529.529/dired-async.el b/emacs.d/elpa/async-20150529.529/dired-async.el deleted file mode 100644 index d37c5cb..0000000 --- a/emacs.d/elpa/async-20150529.529/dired-async.el +++ /dev/null @@ -1,282 +0,0 @@ -;;; dired-async.el --- Copy/move/delete asynchronously in dired. - -;; Copyright (C) 2012~2014 John Wiegley -;; Copyright (C) 2012~2014 Thierry Volpiatto - -;; Authors: John Wiegley -;; Thierry Volpiatto - -;; Keywords: dired async network -;; X-URL: https://github.com/jwiegley/dired-async - -;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; This file provide a redefinition of `dired-create-file' function, -;; which must be loaded *after* dired-aux.el, performs copies, -;; moves and all what is handled by `dired-create-file' in the background -;; using a slave Emacs process, by means of the async.el module. -;; To use it, put this in your .emacs: -;; -;; (eval-after-load "dired-aux" -;; '(require 'dired-async)) -;; -;; - -;;; Code: - -(require 'cl-lib) -(require 'dired-aux) -(require 'async) - -(eval-when-compile - (defvar async-callback)) -(defvar dired-async-operation nil) - -(defgroup dired-async nil - "Copy rename files asynchronously from dired." - :group 'dired) - -(defcustom dired-async-env-variables-regexp - "\\`\\(tramp-\\(default\\|connection\\|remote\\)\\|ange-ftp\\)-.*" - "Variables matching this regexp will be loaded on Child Emacs." - :type 'regexp - :group 'dired-async) - -(defcustom dired-async-message-function 'dired-async-mode-line-message - "Function to use to notify result when operation finish. -Should take same args as `message'." - :group 'dired-async - :type 'function) - -(defcustom dired-async-log-file "/tmp/dired-async.log" - "File use to communicate errors from Child Emacs to host Emacs." - :group 'dired-async - :type 'string) - -(defface dired-async-message - '((t (:foreground "yellow"))) - "Face used for mode-line message." - :group 'dired-async) - -(defface dired-async-mode-message - '((t (:background "Firebrick1"))) - "Face used for `dired-async--modeline-mode' lighter." - :group 'dired-async) - -(define-minor-mode dired-async--modeline-mode - "Notify mode-line that an async process run." - :group 'dired-async - :global t - :lighter (:eval (propertize (format " [%s Async job(s) running]" - (length (dired-async-processes))) - 'face 'dired-async-mode-message)) - (unless dired-async--modeline-mode - (let ((visible-bell t)) (ding)))) - -(defun dired-async-mode-line-message (text &rest args) - "Notify end of operation in `mode-line'." - (message nil) - (let ((mode-line-format (concat - " " (propertize - (if args - (apply #'format text args) - text) - 'face 'dired-async-message)))) - (force-mode-line-update) - (sit-for 3) - (force-mode-line-update))) - -(defun dired-async-processes () - (cl-loop for p in (process-list) - when (cl-loop for c in (process-command p) thereis - (string= "async-batch-invoke" c)) - collect p)) - -(defun dired-async-kill-process () - (interactive) - (let* ((processes (dired-async-processes)) - (proc (car (last processes)))) - (delete-process proc) - (unless (> (length processes) 1) - (dired-async--modeline-mode -1)))) - -(defun dired-async-after-file-create (len-flist) - "Callback function used for operation handled by `dired-create-file'." - (unless (dired-async-processes) - ;; Turn off mode-line notification - ;; only when last process end. - (dired-async--modeline-mode -1)) - (when dired-async-operation - (if (file-exists-p dired-async-log-file) - (progn - (pop-to-buffer (get-buffer-create "*dired async*")) - (erase-buffer) - (insert "Error: ") - (insert-file-contents dired-async-log-file) - (delete-file dired-async-log-file)) - (run-with-timer - 0.1 nil - dired-async-message-function "Asynchronous %s of %s file(s) on %s file(s) done" - (car dired-async-operation) (cadr dired-async-operation) len-flist)))) - -(defun dired-async-maybe-kill-ftp () - "Return a form to kill ftp process in child emacs." - (quote - (progn - (require 'cl-lib) - (let ((buf (cl-loop for b in (buffer-list) - thereis (and (string-match - "\\`\\*ftp.*" - (buffer-name b)) b)))) - (when buf (kill-buffer buf)))))) - -(defun dired-async-create-files (file-creator operation fn-list name-constructor - &optional marker-char) - "Same as `dired-create-files' but asynchronous. - -See `dired-create-files' for the behavior of arguments." - (setq dired-async-operation nil) - (let (dired-create-files-failures failures async-fn-list - skipped (success-count 0) (total (length fn-list)) - (callback `(lambda (&optional ignore) - (dired-async-after-file-create ,(length fn-list))))) - (let (to overwrite-query - overwrite-backup-query) ; for dired-handle-overwrite - (dolist (from fn-list) - (setq to (funcall name-constructor from)) - (if (equal to from) - (progn - (setq to nil) - (dired-log "Cannot %s to same file: %s\n" - (downcase operation) from))) - (if (not to) - (setq skipped (cons (dired-make-relative from) skipped)) - (let* ((overwrite (file-exists-p to)) - (dired-overwrite-confirmed ; for dired-handle-overwrite - (and overwrite - (let ((help-form '(format "\ -Type SPC or `y' to overwrite file `%s', -DEL or `n' to skip to next, -ESC or `q' to not overwrite any of the remaining files, -`!' to overwrite all remaining files with no more questions." to))) - (dired-query 'overwrite-query - "Overwrite `%s'?" to)))) - ;; must determine if FROM is marked before file-creator - ;; gets a chance to delete it (in case of a move). - (actual-marker-char - (cond ((integerp marker-char) marker-char) - (marker-char (dired-file-marker from)) ; slow - (t nil)))) - ;; Handle the `dired-copy-file' file-creator specially - ;; When copying a directory to another directory or - ;; possibly to itself or one of its subdirectories. - ;; e.g "~/foo/" => "~/test/" - ;; or "~/foo/" =>"~/foo/" - ;; or "~/foo/ => ~/foo/bar/") - ;; In this case the 'name-constructor' have set the destination - ;; TO to "~/test/foo" because the old emacs23 behavior - ;; of `copy-directory' was to not create the subdirectory - ;; and instead copy the contents. - ;; With the new behavior of `copy-directory' - ;; (similar to the `cp' shell command) we don't - ;; need such a construction of the target directory, - ;; so modify the destination TO to "~/test/" instead of "~/test/foo/". - (let ((destname (file-name-directory to))) - (when (and (file-directory-p from) - (file-directory-p to) - (eq file-creator 'dired-copy-file)) - (setq to destname)) - ;; If DESTNAME is a subdirectory of FROM, not a symlink, - ;; and the method in use is copying, signal an error. - (and (eq t (car (file-attributes destname))) - (eq file-creator 'dired-copy-file) - (file-in-directory-p destname from) - (error "Cannot copy `%s' into its subdirectory `%s'" - from to))) - (if overwrite - (or (and dired-overwrite-confirmed - (push (cons from to) async-fn-list)) - (progn - (push (dired-make-relative from) failures) - (dired-log "%s `%s' to `%s' failed" - operation from to))) - (push (cons from to) async-fn-list)))))) - ;; Handle error happening in host emacs. - (cond - (dired-create-files-failures - (setq failures (nconc failures dired-create-files-failures)) - (dired-log-summary - (format "%s failed for %d file%s in %d requests" - operation (length failures) - (dired-plural-s (length failures)) - total) - failures)) - (failures - (dired-log-summary - (format "%s failed for %d of %d file%s" - operation (length failures) - total (dired-plural-s total)) - failures)) - (skipped - (dired-log-summary - (format "%s: %d of %d file%s skipped" - operation (length skipped) total - (dired-plural-s total)) - skipped)) - (t (message "%s: %s file%s" - operation success-count (dired-plural-s success-count)))) - ;; Start async process. - (when async-fn-list - (async-start `(lambda () - (require 'cl-lib) (require 'dired-aux) (require 'dired-x) - ,(async-inject-variables dired-async-env-variables-regexp) - (condition-case err - (let ((dired-recursive-copies (quote always))) - (cl-loop for (f . d) in (quote ,async-fn-list) - do (funcall (quote ,file-creator) f d t))) - (file-error - (with-temp-file ,dired-async-log-file - (insert (format "%S" err))))) - ,(dired-async-maybe-kill-ftp)) - callback) - ;; Run mode-line notifications while process running. - (dired-async--modeline-mode 1) - (setq dired-async-operation (list operation (length async-fn-list))) - (message "%s proceeding asynchronously..." operation)))) - -(defadvice dired-create-files (around dired-async) - (dired-async-create-files file-creator operation fn-list - name-constructor marker-char)) - -;;;###autoload -(define-minor-mode dired-async-mode - "Do dired actions asynchronously." - :group 'dired-async - :global t - (if dired-async-mode - (if (fboundp 'advice-add) - (advice-add 'dired-create-files :override #'dired-async-create-files) - (ad-activate 'dired-create-files)) - (if (fboundp 'advice-remove) - (advice-remove 'dired-create-files #'dired-async-create-files) - (ad-deactivate 'dired-create-files)))) - - -(provide 'dired-async) - -;;; dired-async.el ends here diff --git a/emacs.d/elpa/async-20150529.529/smtpmail-async.el b/emacs.d/elpa/async-20150529.529/smtpmail-async.el deleted file mode 100644 index d487f93..0000000 --- a/emacs.d/elpa/async-20150529.529/smtpmail-async.el +++ /dev/null @@ -1,73 +0,0 @@ -;;; smtpmail-async --- Send e-mail with smtpmail.el asynchronously - -;; Copyright (C) 2012~2014 John Wiegley - -;; Author: John Wiegley -;; Created: 18 Jun 2012 - -;; Keywords: email async -;; X-URL: https://github.com/jwiegley/emacs-async - -;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; Send e-mail with smtpmail.el asynchronously. To use: -;; -;; (require 'smtpmail-async) -;; -;; (setq send-mail-function 'async-smtpmail-send-it -;; message-send-mail-function 'async-smtpmail-send-it) -;; -;; This assumes you already have smtpmail.el working. - -;;; Code: - -(defgroup smtpmail-async nil - "Send e-mail with smtpmail.el asynchronously" - :group 'smptmail) - -(require 'async) -(require 'smtpmail) -(require 'message) - -(defvar async-smtpmail-before-send-hook nil - "Hook running in the child emacs in `async-smtpmail-send-it'. -It is called just before calling `smtpmail-send-it'.") - -(defun async-smtpmail-send-it () - (let ((to (message-field-value "To")) - (buf-content (buffer-substring-no-properties - (point-min) (point-max)))) - (message "Delivering message to %s..." to) - (async-start - `(lambda () - (require 'smtpmail) - (with-temp-buffer - (insert ,buf-content) - (set-buffer-multibyte nil) - ;; Pass in the variable environment for smtpmail - ,(async-inject-variables - "\\`\\(smtpmail\\|async-smtpmail\\|\\(user-\\)?mail\\)-\\|auth-sources" - nil "\\`\\(mail-header-format-function\\|smtpmail-address-buffer\\|mail-mode-abbrev-table\\)") - (run-hooks 'async-smtpmail-before-send-hook) - (smtpmail-send-it))) - `(lambda (&optional ignore) - (message "Delivering message to %s...done" ,to))))) - -(provide 'smtpmail-async) - -;;; smtpmail-async.el ends here diff --git a/emacs.d/elpa/async-20160108.1249/async-autoloads.el b/emacs.d/elpa/async-20160108.1249/async-autoloads.el new file mode 100644 index 0000000..dd498c3 --- /dev/null +++ b/emacs.d/elpa/async-20160108.1249/async-autoloads.el @@ -0,0 +1,129 @@ +;;; async-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) + +;;;### (autoloads nil "async" "async.el" (22171 46585 0 0)) +;;; Generated autoloads from async.el + +(autoload 'async-start-process "async" "\ +Start the executable PROGRAM asynchronously. See `async-start'. +PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the +process object when done. If FINISH-FUNC is nil, the future +object will return the process object when the program is +finished. Set DEFAULT-DIRECTORY to change PROGRAM's current +working directory. + +\(fn NAME PROGRAM FINISH-FUNC &rest PROGRAM-ARGS)" nil nil) + +(autoload 'async-start "async" "\ +Execute START-FUNC (often a lambda) in a subordinate Emacs process. +When done, the return value is passed to FINISH-FUNC. Example: + + (async-start + ;; What to do in the child process + (lambda () + (message \"This is a test\") + (sleep-for 3) + 222) + + ;; What to do when it finishes + (lambda (result) + (message \"Async process done, result should be 222: %s\" + result))) + +If FINISH-FUNC is nil or missing, a future is returned that can +be inspected using `async-get', blocking until the value is +ready. Example: + + (let ((proc (async-start + ;; What to do in the child process + (lambda () + (message \"This is a test\") + (sleep-for 3) + 222)))) + + (message \"I'm going to do some work here\") ;; .... + + (message \"Waiting on async process, result should be 222: %s\" + (async-get proc))) + +If you don't want to use a callback, and you don't care about any +return value form the child process, pass the `ignore' symbol as +the second argument (if you don't, and never call `async-get', it +will leave *emacs* process buffers hanging around): + + (async-start + (lambda () + (delete-file \"a remote file on a slow link\" nil)) + 'ignore) + +Note: Even when FINISH-FUNC is present, a future is still +returned except that it yields no value (since the value is +passed to FINISH-FUNC). Call `async-get' on such a future always +returns nil. It can still be useful, however, as an argument to +`async-ready' or `async-wait'. + +\(fn START-FUNC &optional FINISH-FUNC)" nil nil) + +;;;*** + +;;;### (autoloads nil "async-bytecomp" "async-bytecomp.el" (22171 +;;;;;; 46585 0 0)) +;;; Generated autoloads from async-bytecomp.el + +(autoload 'async-byte-recompile-directory "async-bytecomp" "\ +Compile all *.el files in DIRECTORY asynchronously. +All *.elc files are systematically deleted before proceeding. + +\(fn DIRECTORY &optional QUIET)" nil nil) + +(defvar async-bytecomp-package-mode nil "\ +Non-nil if Async-Bytecomp-Package mode is enabled. +See the command `async-bytecomp-package-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `async-bytecomp-package-mode'.") + +(custom-autoload 'async-bytecomp-package-mode "async-bytecomp" nil) + +(autoload 'async-bytecomp-package-mode "async-bytecomp" "\ +Byte compile asynchronously packages installed with package.el. +Async compilation of packages can be controlled by +`async-bytecomp-allowed-packages'. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads nil "dired-async" "dired-async.el" (22171 46585 +;;;;;; 0 0)) +;;; Generated autoloads from dired-async.el + +(defvar dired-async-mode nil "\ +Non-nil if Dired-Async mode is enabled. +See the command `dired-async-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `dired-async-mode'.") + +(custom-autoload 'dired-async-mode "dired-async" nil) + +(autoload 'dired-async-mode "dired-async" "\ +Do dired actions asynchronously. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads nil nil ("async-pkg.el" "smtpmail-async.el") (22171 +;;;;;; 46585 642069 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; async-autoloads.el ends here diff --git a/emacs.d/elpa/async-20160108.1249/async-bytecomp.el b/emacs.d/elpa/async-20160108.1249/async-bytecomp.el new file mode 100644 index 0000000..54313c0 --- /dev/null +++ b/emacs.d/elpa/async-20160108.1249/async-bytecomp.el @@ -0,0 +1,177 @@ +;;; async-bytecomp.el --- Async functions to compile elisp files async + +;; Copyright (C) 2014-2016 Free Software Foundation, Inc. + +;; Authors: John Wiegley +;; Thierry Volpiatto + +;; Keywords: dired async byte-compile +;; X-URL: https://github.com/jwiegley/dired-async + +;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: +;; +;; This package provide the `async-byte-recompile-directory' function +;; which allows, as the name says to recompile a directory outside of +;; your running emacs. +;; The benefit is your files will be compiled in a clean environment without +;; the old *.el files loaded. +;; Among other things, this fix a bug in package.el which recompile +;; the new files in the current environment with the old files loaded, creating +;; errors in most packages after upgrades. +;; +;; NB: This package is advicing the function `package--compile'. + +;;; Code: + +(require 'cl-lib) +(require 'async) + +(defcustom async-bytecomp-allowed-packages + '(async helm helm-core helm-ls-git helm-ls-hg magit) + "Packages in this list will be compiled asynchronously by `package--compile'. +All the dependencies of these packages will be compiled async too, +so no need to add dependencies to this list. +The value of this variable can also be a list with a single element, +the symbol `all', in this case packages are always compiled asynchronously." + :group 'async + :type '(repeat (choice symbol))) + +(defvar async-byte-compile-log-file "~/.emacs.d/async-bytecomp.log") + +;;;###autoload +(defun async-byte-recompile-directory (directory &optional quiet) + "Compile all *.el files in DIRECTORY asynchronously. +All *.elc files are systematically deleted before proceeding." + (cl-loop with dir = (directory-files directory t "\\.elc\\'") + unless dir return nil + for f in dir + when (file-exists-p f) do (delete-file f)) + ;; Ensure async is reloaded when async.elc is deleted. + ;; This happen when recompiling its own directory. + (load "async") + (let ((call-back + `(lambda (&optional ignore) + (if (file-exists-p async-byte-compile-log-file) + (let ((buf (get-buffer-create byte-compile-log-buffer)) + (n 0)) + (with-current-buffer buf + (goto-char (point-max)) + (let ((inhibit-read-only t)) + (insert-file-contents async-byte-compile-log-file) + (compilation-mode)) + (display-buffer buf) + (delete-file async-byte-compile-log-file) + (unless ,quiet + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^.*:Error:" nil t) + (cl-incf n))) + (if (> n 0) + (message "Failed to compile %d files in directory `%s'" n ,directory) + (message "Directory `%s' compiled asynchronously with warnings" ,directory))))) + (unless ,quiet + (message "Directory `%s' compiled asynchronously with success" ,directory)))))) + (async-start + `(lambda () + (require 'bytecomp) + ,(async-inject-variables "\\`\\(load-path\\)\\|byte\\'") + (let ((default-directory (file-name-as-directory ,directory)) + error-data) + (add-to-list 'load-path default-directory) + (byte-recompile-directory ,directory 0 t) + (when (get-buffer byte-compile-log-buffer) + (setq error-data (with-current-buffer byte-compile-log-buffer + (buffer-substring-no-properties (point-min) (point-max)))) + (unless (string= error-data "") + (with-temp-file ,async-byte-compile-log-file + (erase-buffer) + (insert error-data)))))) + call-back) + (unless quiet (message "Started compiling asynchronously directory %s" directory)))) + +(defvar package-archive-contents) +(defvar package-alist) +(declare-function package-desc-reqs "package.el" (cl-x)) + +(defun async-bytecomp--get-package-deps (pkg &optional only) + ;; Same as `package--get-deps' but parse instead `package-archive-contents' + ;; because PKG is not already installed and not present in `package-alist'. + ;; However fallback to `package-alist' in case PKG no more present + ;; in `package-archive-contents' due to modification to `package-archives'. + ;; See issue #58. + (let* ((pkg-desc (cadr (or (assq pkg package-archive-contents) + (assq pkg package-alist)))) + (direct-deps (cl-loop for p in (package-desc-reqs pkg-desc) + for name = (car p) + when (or (assq name package-archive-contents) + (assq name package-alist)) + collect name)) + (indirect-deps (unless (eq only 'direct) + (delete-dups + (cl-loop for p in direct-deps append + (async-bytecomp--get-package-deps p)))))) + (cl-case only + (direct direct-deps) + (separate (list direct-deps indirect-deps)) + (indirect indirect-deps) + (t (delete-dups (append direct-deps indirect-deps)))))) + +(defun async-bytecomp-get-allowed-pkgs () + (when (and async-bytecomp-allowed-packages + (listp async-bytecomp-allowed-packages)) + (if package-archive-contents + (cl-loop for p in async-bytecomp-allowed-packages + when (assq p package-archive-contents) + append (async-bytecomp--get-package-deps p) into reqs + finally return + (delete-dups + (append async-bytecomp-allowed-packages reqs))) + async-bytecomp-allowed-packages))) + +(defadvice package--compile (around byte-compile-async) + (let ((cur-package (package-desc-name pkg-desc)) + (pkg-dir (package-desc-dir pkg-desc))) + (if (or (equal async-bytecomp-allowed-packages '(all)) + (memq cur-package (async-bytecomp-get-allowed-pkgs))) + (progn + (when (eq cur-package 'async) + (fmakunbound 'async-byte-recompile-directory)) + ;; Add to `load-path' the latest version of async and + ;; reload it when reinstalling async. + (when (string= cur-package "async") + (cl-pushnew pkg-dir load-path) + (load "async-bytecomp")) + ;; `async-byte-recompile-directory' will add directory + ;; as needed to `load-path'. + (async-byte-recompile-directory (package-desc-dir pkg-desc) t)) + ad-do-it))) + +;;;###autoload +(define-minor-mode async-bytecomp-package-mode + "Byte compile asynchronously packages installed with package.el. +Async compilation of packages can be controlled by +`async-bytecomp-allowed-packages'." + :group 'async + :global t + (if async-bytecomp-package-mode + (ad-activate 'package--compile) + (ad-deactivate 'package--compile))) + +(provide 'async-bytecomp) + +;;; async-bytecomp.el ends here diff --git a/emacs.d/elpa/async-20160108.1249/async-pkg.el b/emacs.d/elpa/async-20160108.1249/async-pkg.el new file mode 100644 index 0000000..b042040 --- /dev/null +++ b/emacs.d/elpa/async-20160108.1249/async-pkg.el @@ -0,0 +1,6 @@ +(define-package "async" "20160108.1249" "Asynchronous processing in Emacs" 'nil :keywords + '("async") + :url "http://elpa.gnu.org/packages/async.html") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/emacs.d/elpa/async-20160108.1249/async.el b/emacs.d/elpa/async-20160108.1249/async.el new file mode 100644 index 0000000..24db2a1 --- /dev/null +++ b/emacs.d/elpa/async-20160108.1249/async.el @@ -0,0 +1,303 @@ +;;; async.el --- Asynchronous processing in Emacs + +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. + +;; Author: John Wiegley +;; Created: 18 Jun 2012 +;; Version: 1.6 + +;; Keywords: async +;; X-URL: https://github.com/jwiegley/emacs-async + +;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Adds the ability to call asynchronous functions and process with ease. See +;; the documentation for `async-start' and `async-start-process'. + +;;; Code: + +(defgroup async nil + "Simple asynchronous processing in Emacs" + :group 'emacs) + +(defvar async-debug nil) +(defvar async-send-over-pipe t) +(defvar async-in-child-emacs nil) +(defvar async-callback nil) +(defvar async-callback-for-process nil) +(defvar async-callback-value nil) +(defvar async-callback-value-set nil) +(defvar async-current-process nil) +(defvar async--procvar nil) + +(defun async-inject-variables + (include-regexp &optional predicate exclude-regexp) + "Return a `setq' form that replicates part of the calling environment. +It sets the value for every variable matching INCLUDE-REGEXP and +also PREDICATE. It will not perform injection for any variable +matching EXCLUDE-REGEXP (if present). It is intended to be used +as follows: + + (async-start + `(lambda () + (require 'smtpmail) + (with-temp-buffer + (insert ,(buffer-substring-no-properties (point-min) (point-max))) + ;; Pass in the variable environment for smtpmail + ,(async-inject-variables \"\\`\\(smtpmail\\|\\(user-\\)?mail\\)-\") + (smtpmail-send-it))) + 'ignore)" + `(setq + ,@(let (bindings) + (mapatoms + (lambda (sym) + (if (and (boundp sym) + (or (null include-regexp) + (string-match include-regexp (symbol-name sym))) + (not (string-match + (or exclude-regexp "-syntax-table\\'") + (symbol-name sym)))) + (let ((value (symbol-value sym))) + (when (or (null predicate) + (funcall predicate sym)) + (setq bindings (cons `(quote ,value) bindings) + bindings (cons sym bindings))))))) + bindings))) + +(defalias 'async-inject-environment 'async-inject-variables) + +(defun async-handle-result (func result buf) + (if (null func) + (progn + (set (make-local-variable 'async-callback-value) result) + (set (make-local-variable 'async-callback-value-set) t)) + (unwind-protect + (if (and (listp result) + (eq 'async-signal (nth 0 result))) + (signal (car (nth 1 result)) + (cdr (nth 1 result))) + (funcall func result)) + (unless async-debug + (kill-buffer buf))))) + +(defun async-when-done (proc &optional change) + "Process sentinal used to retrieve the value from the child process." + (when (eq 'exit (process-status proc)) + (with-current-buffer (process-buffer proc) + (let ((async-current-process proc)) + (if (= 0 (process-exit-status proc)) + (if async-callback-for-process + (if async-callback + (prog1 + (funcall async-callback proc) + (unless async-debug + (kill-buffer (current-buffer)))) + (set (make-local-variable 'async-callback-value) proc) + (set (make-local-variable 'async-callback-value-set) t)) + (goto-char (point-max)) + (backward-sexp) + (async-handle-result async-callback (read (current-buffer)) + (current-buffer))) + (set (make-local-variable 'async-callback-value) + (list 'error + (format "Async process '%s' failed with exit code %d" + (process-name proc) (process-exit-status proc)))) + (set (make-local-variable 'async-callback-value-set) t)))))) + +(defun async--receive-sexp (&optional stream) + (let ((sexp (decode-coding-string (base64-decode-string + (read stream)) 'utf-8-unix)) + ;; Parent expects UTF-8 encoded text. + (coding-system-for-write 'utf-8-unix)) + (if async-debug + (message "Received sexp {{{%s}}}" (pp-to-string sexp))) + (setq sexp (read sexp)) + (if async-debug + (message "Read sexp {{{%s}}}" (pp-to-string sexp))) + (eval sexp))) + +(defun async--insert-sexp (sexp) + (let (print-level + print-length + (print-escape-nonascii t) + (print-circle t)) + (prin1 sexp (current-buffer)) + ;; Just in case the string we're sending might contain EOF + (encode-coding-region (point-min) (point-max) 'utf-8-unix) + (base64-encode-region (point-min) (point-max) t) + (goto-char (point-min)) (insert ?\") + (goto-char (point-max)) (insert ?\" ?\n))) + +(defun async--transmit-sexp (process sexp) + (with-temp-buffer + (if async-debug + (message "Transmitting sexp {{{%s}}}" (pp-to-string sexp))) + (async--insert-sexp sexp) + (process-send-region process (point-min) (point-max)))) + +(defun async-batch-invoke () + "Called from the child Emacs process' command-line." + ;; Make sure 'message' and 'prin1' encode stuff in UTF-8, as parent + ;; process expects. + (let ((coding-system-for-write 'utf-8-unix)) + (setq async-in-child-emacs t + debug-on-error async-debug) + (if debug-on-error + (prin1 (funcall + (async--receive-sexp (unless async-send-over-pipe + command-line-args-left)))) + (condition-case err + (prin1 (funcall + (async--receive-sexp (unless async-send-over-pipe + command-line-args-left)))) + (error + (prin1 (list 'async-signal err))))))) + +(defun async-ready (future) + "Query a FUTURE to see if the ready is ready -- i.e., if no blocking +would result from a call to `async-get' on that FUTURE." + (and (memq (process-status future) '(exit signal)) + (with-current-buffer (process-buffer future) + async-callback-value-set))) + +(defun async-wait (future) + "Wait for FUTURE to become ready." + (while (not (async-ready future)) + (sit-for 0.05))) + +(defun async-get (future) + "Get the value from an asynchronously function when it is ready. +FUTURE is returned by `async-start' or `async-start-process' when +its FINISH-FUNC is nil." + (async-wait future) + (with-current-buffer (process-buffer future) + (async-handle-result #'identity async-callback-value (current-buffer)))) + +(defun async-message-p (value) + "Return true of VALUE is an async.el message packet." + (and (listp value) + (plist-get value :async-message))) + +(defun async-send (&rest args) + "Send the given messages to the asychronous Emacs PROCESS." + (let ((args (append args '(:async-message t)))) + (if async-in-child-emacs + (if async-callback + (funcall async-callback args)) + (async--transmit-sexp (car args) (list 'quote (cdr args)))))) + +(defun async-receive (&rest args) + "Send the given messages to the asychronous Emacs PROCESS." + (async--receive-sexp)) + +;;;###autoload +(defun async-start-process (name program finish-func &rest program-args) + "Start the executable PROGRAM asynchronously. See `async-start'. +PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the +process object when done. If FINISH-FUNC is nil, the future +object will return the process object when the program is +finished. Set DEFAULT-DIRECTORY to change PROGRAM's current +working directory." + (let* ((buf (generate-new-buffer (concat "*" name "*"))) + (proc (let ((process-connection-type nil)) + (apply #'start-process name buf program program-args)))) + (with-current-buffer buf + (set (make-local-variable 'async-callback) finish-func) + (set-process-sentinel proc #'async-when-done) + (unless (string= name "emacs") + (set (make-local-variable 'async-callback-for-process) t)) + proc))) + +;;;###autoload +(defun async-start (start-func &optional finish-func) + "Execute START-FUNC (often a lambda) in a subordinate Emacs process. +When done, the return value is passed to FINISH-FUNC. Example: + + (async-start + ;; What to do in the child process + (lambda () + (message \"This is a test\") + (sleep-for 3) + 222) + + ;; What to do when it finishes + (lambda (result) + (message \"Async process done, result should be 222: %s\" + result))) + +If FINISH-FUNC is nil or missing, a future is returned that can +be inspected using `async-get', blocking until the value is +ready. Example: + + (let ((proc (async-start + ;; What to do in the child process + (lambda () + (message \"This is a test\") + (sleep-for 3) + 222)))) + + (message \"I'm going to do some work here\") ;; .... + + (message \"Waiting on async process, result should be 222: %s\" + (async-get proc))) + +If you don't want to use a callback, and you don't care about any +return value form the child process, pass the `ignore' symbol as +the second argument (if you don't, and never call `async-get', it +will leave *emacs* process buffers hanging around): + + (async-start + (lambda () + (delete-file \"a remote file on a slow link\" nil)) + 'ignore) + +Note: Even when FINISH-FUNC is present, a future is still +returned except that it yields no value (since the value is +passed to FINISH-FUNC). Call `async-get' on such a future always +returns nil. It can still be useful, however, as an argument to +`async-ready' or `async-wait'." + (let ((sexp start-func) + ;; Subordinate Emacs will send text encoded in UTF-8. + (coding-system-for-read 'utf-8-unix)) + (setq async--procvar + (async-start-process + "emacs" (file-truename + (expand-file-name invocation-name + invocation-directory)) + finish-func + "-Q" "-l" + ;; Using `locate-library' ensure we use the right file + ;; when the .elc have been deleted. + (locate-library "async") + "-batch" "-f" "async-batch-invoke" + (if async-send-over-pipe + "" + (with-temp-buffer + (async--insert-sexp (list 'quote sexp)) + (buffer-string))))) + (if async-send-over-pipe + (async--transmit-sexp async--procvar (list 'quote sexp))) + async--procvar)) + +(defmacro async-sandbox(func) + "Evaluate FUNC in a separate Emacs process, synchronously." + `(async-get (async-start ,func))) + +(provide 'async) + +;;; async.el ends here diff --git a/emacs.d/elpa/async-20160108.1249/dired-async.el b/emacs.d/elpa/async-20160108.1249/dired-async.el new file mode 100644 index 0000000..ecab9cb --- /dev/null +++ b/emacs.d/elpa/async-20160108.1249/dired-async.el @@ -0,0 +1,290 @@ +;;; dired-async.el --- Copy/move/delete asynchronously in dired. + +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. + +;; Authors: John Wiegley +;; Thierry Volpiatto + +;; Keywords: dired async network +;; X-URL: https://github.com/jwiegley/dired-async + +;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This file provide a redefinition of `dired-create-file' function, +;; performs copies, moves and all what is handled by `dired-create-file' +;; in the background using a slave Emacs process, +;; by means of the async.el module. +;; To use it, put this in your .emacs: + +;; (dired-async-mode 1) + +;; This will enable async copy/rename etc... +;; in dired and helm. + +;;; Code: + +(require 'cl-lib) +(require 'dired-aux) +(require 'async) + +(eval-when-compile + (defvar async-callback)) +(defvar dired-async-operation nil) + +(defgroup dired-async nil + "Copy rename files asynchronously from dired." + :group 'dired) + +(defcustom dired-async-env-variables-regexp + "\\`\\(tramp-\\(default\\|connection\\|remote\\)\\|ange-ftp\\)-.*" + "Variables matching this regexp will be loaded on Child Emacs." + :type 'regexp + :group 'dired-async) + +(defcustom dired-async-message-function 'dired-async-mode-line-message + "Function to use to notify result when operation finish. +Should take same args as `message'." + :group 'dired-async + :type 'function) + +(defcustom dired-async-log-file "/tmp/dired-async.log" + "File use to communicate errors from Child Emacs to host Emacs." + :group 'dired-async + :type 'string) + +(defface dired-async-message + '((t (:foreground "yellow"))) + "Face used for mode-line message." + :group 'dired-async) + +(defface dired-async-mode-message + '((t (:foreground "Gold"))) + "Face used for `dired-async--modeline-mode' lighter." + :group 'dired-async) + +(define-minor-mode dired-async--modeline-mode + "Notify mode-line that an async process run." + :group 'dired-async + :global t + :lighter (:eval (propertize (format " [%s Async job(s) running]" + (length (dired-async-processes))) + 'face 'dired-async-mode-message)) + (unless dired-async--modeline-mode + (let ((visible-bell t)) (ding)))) + +(defun dired-async-mode-line-message (text &rest args) + "Notify end of operation in `mode-line'." + (message nil) + (let ((mode-line-format (concat + " " (propertize + (if args + (apply #'format text args) + text) + 'face 'dired-async-message)))) + (force-mode-line-update) + (sit-for 3) + (force-mode-line-update))) + +(defun dired-async-processes () + (cl-loop for p in (process-list) + when (cl-loop for c in (process-command p) thereis + (string= "async-batch-invoke" c)) + collect p)) + +(defun dired-async-kill-process () + (interactive) + (let* ((processes (dired-async-processes)) + (proc (car (last processes)))) + (delete-process proc) + (unless (> (length processes) 1) + (dired-async--modeline-mode -1)))) + +(defun dired-async-after-file-create (len-flist) + "Callback function used for operation handled by `dired-create-file'." + (unless (dired-async-processes) + ;; Turn off mode-line notification + ;; only when last process end. + (dired-async--modeline-mode -1)) + (when dired-async-operation + (if (file-exists-p dired-async-log-file) + (progn + (pop-to-buffer (get-buffer-create "*dired async*")) + (erase-buffer) + (insert "Error: ") + (insert-file-contents dired-async-log-file) + (delete-file dired-async-log-file)) + (run-with-timer + 0.1 nil + dired-async-message-function "Asynchronous %s of %s file(s) on %s file(s) done" + (car dired-async-operation) (cadr dired-async-operation) len-flist)))) + +(defun dired-async-maybe-kill-ftp () + "Return a form to kill ftp process in child emacs." + (quote + (progn + (require 'cl-lib) + (let ((buf (cl-loop for b in (buffer-list) + thereis (and (string-match + "\\`\\*ftp.*" + (buffer-name b)) b)))) + (when buf (kill-buffer buf)))))) + +(defun dired-async-create-files (file-creator operation fn-list name-constructor + &optional marker-char) + "Same as `dired-create-files' but asynchronous. + +See `dired-create-files' for the behavior of arguments." + (setq dired-async-operation nil) + (let (dired-create-files-failures + failures async-fn-list + skipped (success-count 0) + (total (length fn-list)) + callback) + (let (to overwrite-query + overwrite-backup-query) ; for dired-handle-overwrite + (dolist (from fn-list) + (setq to (funcall name-constructor from)) + (if (equal to from) + (progn + (setq to nil) + (dired-log "Cannot %s to same file: %s\n" + (downcase operation) from))) + (if (not to) + (setq skipped (cons (dired-make-relative from) skipped)) + (let* ((overwrite (file-exists-p to)) + (dired-overwrite-confirmed ; for dired-handle-overwrite + (and overwrite + (let ((help-form '(format "\ +Type SPC or `y' to overwrite file `%s', +DEL or `n' to skip to next, +ESC or `q' to not overwrite any of the remaining files, +`!' to overwrite all remaining files with no more questions." to))) + (dired-query 'overwrite-query + "Overwrite `%s'?" to)))) + ;; must determine if FROM is marked before file-creator + ;; gets a chance to delete it (in case of a move). + (actual-marker-char + (cond ((integerp marker-char) marker-char) + (marker-char (dired-file-marker from)) ; slow + (t nil)))) + ;; Handle the `dired-copy-file' file-creator specially + ;; When copying a directory to another directory or + ;; possibly to itself or one of its subdirectories. + ;; e.g "~/foo/" => "~/test/" + ;; or "~/foo/" =>"~/foo/" + ;; or "~/foo/ => ~/foo/bar/") + ;; In this case the 'name-constructor' have set the destination + ;; TO to "~/test/foo" because the old emacs23 behavior + ;; of `copy-directory' was to not create the subdirectory + ;; and instead copy the contents. + ;; With the new behavior of `copy-directory' + ;; (similar to the `cp' shell command) we don't + ;; need such a construction of the target directory, + ;; so modify the destination TO to "~/test/" instead of "~/test/foo/". + (let ((destname (file-name-directory to))) + (when (and (file-directory-p from) + (file-directory-p to) + (eq file-creator 'dired-copy-file)) + (setq to destname)) + ;; If DESTNAME is a subdirectory of FROM, not a symlink, + ;; and the method in use is copying, signal an error. + (and (eq t (car (file-attributes destname))) + (eq file-creator 'dired-copy-file) + (file-in-directory-p destname from) + (error "Cannot copy `%s' into its subdirectory `%s'" + from to))) + (if overwrite + (or (and dired-overwrite-confirmed + (push (cons from to) async-fn-list)) + (progn + (push (dired-make-relative from) failures) + (dired-log "%s `%s' to `%s' failed" + operation from to))) + (push (cons from to) async-fn-list))))) + (setq callback + `(lambda (&optional ignore) + (dired-async-after-file-create ,total) + (when (string= ,(downcase operation) "rename") + (cl-loop for (file . to) in ',async-fn-list + do (and (get-file-buffer file) + (with-current-buffer (get-file-buffer file) + (set-visited-file-name to nil t)))))))) + ;; Handle error happening in host emacs. + (cond + (dired-create-files-failures + (setq failures (nconc failures dired-create-files-failures)) + (dired-log-summary + (format "%s failed for %d file%s in %d requests" + operation (length failures) + (dired-plural-s (length failures)) + total) + failures)) + (failures + (dired-log-summary + (format "%s failed for %d of %d file%s" + operation (length failures) + total (dired-plural-s total)) + failures)) + (skipped + (dired-log-summary + (format "%s: %d of %d file%s skipped" + operation (length skipped) total + (dired-plural-s total)) + skipped)) + (t (message "%s: %s file%s" + operation success-count (dired-plural-s success-count)))) + ;; Start async process. + (when async-fn-list + (async-start `(lambda () + (require 'cl-lib) (require 'dired-aux) (require 'dired-x) + ,(async-inject-variables dired-async-env-variables-regexp) + (condition-case err + (let ((dired-recursive-copies (quote always))) + (cl-loop for (f . d) in (quote ,async-fn-list) + do (funcall (quote ,file-creator) f d t))) + (file-error + (with-temp-file ,dired-async-log-file + (insert (format "%S" err))))) + ,(dired-async-maybe-kill-ftp)) + callback) + ;; Run mode-line notifications while process running. + (dired-async--modeline-mode 1) + (setq dired-async-operation (list operation (length async-fn-list))) + (message "%s proceeding asynchronously..." operation)))) + +(defadvice dired-create-files (around dired-async) + (dired-async-create-files file-creator operation fn-list + name-constructor marker-char)) + +;;;###autoload +(define-minor-mode dired-async-mode + "Do dired actions asynchronously." + :group 'dired-async + :global t + (if dired-async-mode + (if (fboundp 'advice-add) + (advice-add 'dired-create-files :override #'dired-async-create-files) + (ad-activate 'dired-create-files)) + (if (fboundp 'advice-remove) + (advice-remove 'dired-create-files #'dired-async-create-files) + (ad-deactivate 'dired-create-files)))) + + +(provide 'dired-async) + +;;; dired-async.el ends here diff --git a/emacs.d/elpa/async-20160108.1249/smtpmail-async.el b/emacs.d/elpa/async-20160108.1249/smtpmail-async.el new file mode 100644 index 0000000..5ac426d --- /dev/null +++ b/emacs.d/elpa/async-20160108.1249/smtpmail-async.el @@ -0,0 +1,73 @@ +;;; smtpmail-async.el --- Send e-mail with smtpmail.el asynchronously + +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. + +;; Author: John Wiegley +;; Created: 18 Jun 2012 + +;; Keywords: email async +;; X-URL: https://github.com/jwiegley/emacs-async + +;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Send e-mail with smtpmail.el asynchronously. To use: +;; +;; (require 'smtpmail-async) +;; +;; (setq send-mail-function 'async-smtpmail-send-it +;; message-send-mail-function 'async-smtpmail-send-it) +;; +;; This assumes you already have smtpmail.el working. + +;;; Code: + +(defgroup smtpmail-async nil + "Send e-mail with smtpmail.el asynchronously" + :group 'smptmail) + +(require 'async) +(require 'smtpmail) +(require 'message) + +(defvar async-smtpmail-before-send-hook nil + "Hook running in the child emacs in `async-smtpmail-send-it'. +It is called just before calling `smtpmail-send-it'.") + +(defun async-smtpmail-send-it () + (let ((to (message-field-value "To")) + (buf-content (buffer-substring-no-properties + (point-min) (point-max)))) + (message "Delivering message to %s..." to) + (async-start + `(lambda () + (require 'smtpmail) + (with-temp-buffer + (insert ,buf-content) + (set-buffer-multibyte nil) + ;; Pass in the variable environment for smtpmail + ,(async-inject-variables + "\\`\\(smtpmail\\|async-smtpmail\\|\\(user-\\)?mail\\)-\\|auth-sources\\|epg" + nil "\\`\\(mail-header-format-function\\|smtpmail-address-buffer\\|mail-mode-abbrev-table\\)") + (run-hooks 'async-smtpmail-before-send-hook) + (smtpmail-send-it))) + `(lambda (&optional ignore) + (message "Delivering message to %s...done" ,to))))) + +(provide 'smtpmail-async) + +;;; smtpmail-async.el ends here diff --git a/emacs.d/elpa/auto-complete-20150618.1949/auto-complete-autoloads.el b/emacs.d/elpa/auto-complete-20150618.1949/auto-complete-autoloads.el deleted file mode 100644 index 66046c4..0000000 --- a/emacs.d/elpa/auto-complete-20150618.1949/auto-complete-autoloads.el +++ /dev/null @@ -1,64 +0,0 @@ -;;; auto-complete-autoloads.el --- automatically extracted autoloads -;; -;;; Code: -(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) - -;;;### (autoloads nil "auto-complete" "auto-complete.el" (21898 47983 -;;;;;; 0 0)) -;;; Generated autoloads from auto-complete.el - -(autoload 'auto-complete "auto-complete" "\ -Start auto-completion at current point. - -\(fn &optional SOURCES)" t nil) - -(autoload 'auto-complete-mode "auto-complete" "\ -AutoComplete mode - -\(fn &optional ARG)" t nil) - -(defvar global-auto-complete-mode nil "\ -Non-nil if Global-Auto-Complete mode is enabled. -See the command `global-auto-complete-mode' for a description of this minor mode. -Setting this variable directly does not take effect; -either customize it (see the info node `Easy Customization') -or call the function `global-auto-complete-mode'.") - -(custom-autoload 'global-auto-complete-mode "auto-complete" nil) - -(autoload 'global-auto-complete-mode "auto-complete" "\ -Toggle Auto-Complete mode in all buffers. -With prefix ARG, enable Global-Auto-Complete mode if ARG is positive; -otherwise, disable it. If called from Lisp, enable the mode if -ARG is omitted or nil. - -Auto-Complete mode is enabled in all buffers where -`auto-complete-mode-maybe' would do it. -See `auto-complete-mode' for more information on Auto-Complete mode. - -\(fn &optional ARG)" t nil) - -;;;*** - -;;;### (autoloads nil "auto-complete-config" "auto-complete-config.el" -;;;;;; (21898 47983 0 0)) -;;; Generated autoloads from auto-complete-config.el - -(autoload 'ac-config-default "auto-complete-config" "\ - - -\(fn)" nil nil) - -;;;*** - -;;;### (autoloads nil nil ("auto-complete-pkg.el") (21898 47983 747280 -;;;;;; 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; auto-complete-autoloads.el ends here diff --git a/emacs.d/elpa/auto-complete-20150618.1949/auto-complete-pkg.el b/emacs.d/elpa/auto-complete-20150618.1949/auto-complete-pkg.el deleted file mode 100644 index 1b402b0..0000000 --- a/emacs.d/elpa/auto-complete-20150618.1949/auto-complete-pkg.el +++ /dev/null @@ -1,6 +0,0 @@ -(define-package "auto-complete" "20150618.1949" "Auto Completion for GNU Emacs" - '((popup "0.5.0") - (cl-lib "0.5"))) -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/emacs.d/elpa/auto-complete-20150618.1949/auto-complete.el b/emacs.d/elpa/auto-complete-20150618.1949/auto-complete.el deleted file mode 100644 index 380ac6a..0000000 --- a/emacs.d/elpa/auto-complete-20150618.1949/auto-complete.el +++ /dev/null @@ -1,2162 +0,0 @@ -;;; auto-complete.el --- Auto Completion for GNU Emacs - -;; Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Tomohiro Matsuyama - -;; Author: Tomohiro Matsuyama -;; URL: https://github.com/auto-complete/auto-complete -;; Keywords: completion, convenience -;; Version: 1.5.0 - -;; 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 . - -;;; Commentary: -;; -;; This extension provides a way to complete with popup menu like: -;; -;; def-!- -;; +-----------------+ -;; |defun::::::::::::| -;; |defvar | -;; |defmacro | -;; | ... | -;; +-----------------+ -;; -;; You can complete by typing and selecting menu. -;; -;; Entire documents are located in doc/ directory. -;; Take a look for information. -;; -;; Enjoy! - -;;; Code: - - - -(defconst ac-version "1.5.0" - "Version of auto-complete in string format. -Use `version-to-list' to get version component.") - -(defconst ac-version-major (car (version-to-list ac-version)) - "Major version number of auto-complete") - -(defconst ac-version-minor (cadr (version-to-list ac-version)) - "Minor version number of auto-complete") - -(require 'cl-lib) -(require 'popup) - -;;;; Global stuff - -(defun ac-error (&optional var) - "Report an error and disable `auto-complete-mode'." - (ignore-errors - (message "auto-complete error: %s" var) - (auto-complete-mode -1) - var)) - - - -;;;; Customization - -(defgroup auto-complete nil - "Auto completion." - :group 'completion - :prefix "ac-") - -(defcustom ac-delay 0.1 - "Delay to completions will be available." - :type 'float - :group 'auto-complete) - -(defcustom ac-auto-show-menu 0.8 - "Non-nil means completion menu will be automatically shown." - :type '(choice (const :tag "Yes" t) - (const :tag "Never" nil) - (float :tag "Timer")) - :group 'auto-complete) - -(defcustom ac-show-menu-immediately-on-auto-complete t - "Non-nil means menu will be showed immediately on `auto-complete'." - :type 'boolean - :group 'auto-complete) - -(defcustom ac-expand-on-auto-complete t - "Non-nil means expand whole common part on first time `auto-complete'." - :type 'boolean - :group 'auto-complete) - -(defcustom ac-disable-faces '(font-lock-comment-face font-lock-string-face font-lock-doc-face) - "Non-nil means disable automatic completion on specified faces." - :type '(repeat symbol) - :group 'auto-complete) - -(defcustom ac-stop-flymake-on-completing t - "Non-nil means disble flymake temporarily on completing." - :type 'boolean - :group 'auto-complete) - -(defcustom ac-flycheck-poll-completion-end-interval 0.5 - "Polling interval to restart automatically flycheck's checking after completion is end." - :type 'float - :group 'auto-complete) - -(defcustom ac-use-fuzzy (and (locate-library "fuzzy") t) - "Non-nil means use fuzzy matching." - :type 'boolean - :group 'auto-complete) - -(defcustom ac-fuzzy-cursor-color "red" - "Cursor color in fuzzy mode." - :type 'string - :group 'auto-complete) - -(defcustom ac-use-comphist t - "Non-nil means use intelligent completion history." - :type 'boolean - :group 'auto-complete) - -(defcustom ac-comphist-threshold 0.7 - "Percentage of ignoring low scored candidates." - :type 'float - :group 'auto-complete) - -(defcustom ac-comphist-file - (expand-file-name (concat (if (boundp 'user-emacs-directory) - user-emacs-directory - "~/.emacs.d/") - "/ac-comphist.dat")) - "Completion history file name." - :type 'string - :group 'auto-complete) - -(defcustom ac-user-dictionary nil - "User defined dictionary" - :type '(repeat string) - :group 'auto-complete) - -(defcustom ac-dictionary-files '("~/.dict") - "Dictionary files." - :type '(repeat string) - :group 'auto-complete) -(defvaralias 'ac-user-dictionary-files 'ac-dictionary-files) - -(defcustom ac-dictionary-directories - (ignore-errors - (when load-file-name - (let ((installed-dir (file-name-directory load-file-name))) - (cl-loop for name in '("ac-dict" "dict") - for dir = (concat installed-dir name) - if (file-directory-p dir) - collect dir)))) - "Dictionary directories." - :type '(repeat string) - :group 'auto-complete) - -(defcustom ac-use-quick-help t - "Non-nil means use quick help." - :type 'boolean - :group 'auto-complete) - -(defcustom ac-quick-help-delay 1.5 - "Delay to show quick help." - :type 'float - :group 'auto-complete) - -(defcustom ac-menu-height 10 - "Max height of candidate menu." - :type 'integer - :group 'auto-complete) -(defvaralias 'ac-candidate-menu-height 'ac-menu-height) - -(defcustom ac-quick-help-height 20 - "Max height of quick help." - :type 'integer - :group 'auto-complete) - -(defcustom ac-quick-help-prefer-pos-tip t - "Prefer native tooltip with pos-tip than overlay popup for displaying quick help." - :type 'boolean - :group 'auto-complete) -(defvaralias 'ac-quick-help-prefer-x 'ac-quick-help-prefer-pos-tip) - -(defcustom ac-candidate-limit nil - "Limit number of candidates. Non-integer means no limit." - :type 'integer - :group 'auto-complete) -(defvaralias 'ac-candidate-max 'ac-candidate-limit) - -(defcustom ac-modes - '(emacs-lisp-mode lisp-mode lisp-interaction-mode - slime-repl-mode - c-mode cc-mode c++-mode go-mode - java-mode malabar-mode clojure-mode clojurescript-mode scala-mode - scheme-mode - ocaml-mode tuareg-mode coq-mode haskell-mode agda-mode agda2-mode - perl-mode cperl-mode python-mode ruby-mode lua-mode tcl-mode - ecmascript-mode javascript-mode js-mode js2-mode php-mode css-mode scss-mode less-css-mode - makefile-mode sh-mode fortran-mode f90-mode ada-mode - xml-mode sgml-mode web-mode - ts-mode - sclang-mode - verilog-mode - qml-mode) - "Major modes `auto-complete-mode' can run on." - :type '(repeat symbol) - :group 'auto-complete) - -(defcustom ac-compatible-packages-regexp - "^ac-" - "Regexp to indicate what packages can work with auto-complete." - :type 'string - :group 'auto-complete) - -(defcustom ac-non-trigger-commands - '(*table--cell-self-insert-command - electric-buffer-list) - "Commands that can't be used as triggers of `auto-complete'." - :type '(repeat symbol) - :group 'auto-complete) - -(defcustom ac-trigger-commands - '(self-insert-command) - "Trigger commands that specify whether `auto-complete' should start or not." - :type '(repeat symbol) - :group 'auto-complete) - -(defcustom ac-trigger-commands-on-completing - '(delete-backward-char - backward-delete-char - backward-delete-char-untabify - ;; autopair - autopair-backspace - ;; paredit - paredit-backward-delete - paredit-backward-delete-word) - "Trigger commands that specify whether `auto-complete' should continue or not." - :type '(repeat symbol) - :group 'auto-complete) - -(defcustom ac-trigger-key nil - "Non-nil means `auto-complete' will start by typing this key. -If you specify this TAB, for example, `auto-complete' will start by typing TAB, -and if there is no completions, an original command will be fallbacked." - :type '(choice (const :tag "None" nil) - (string :tag "Key")) - :group 'auto-complete - :set (lambda (symbol value) - (set-default symbol value) - (when (and value - (fboundp 'ac-set-trigger-key)) - (ac-set-trigger-key value)))) - -(defcustom ac-auto-start 2 - "Non-nil means completion will be started automatically. -Positive integer means if a length of a word you entered is larger than the value, -completion will be started automatically. -If you specify `nil', never be started automatically." - :type '(choice (const :tag "Yes" t) - (const :tag "Never" nil) - (integer :tag "Require")) - :group 'auto-complete) - -(defcustom ac-stop-words nil - "List of string to stop completion." - :type '(repeat string) - :group 'auto-complete) -(defvaralias 'ac-ignores 'ac-stop-words) - -(defcustom ac-use-dictionary-as-stop-words t - "Non-nil means a buffer related dictionary will be thought of as stop words." - :type 'boolean - :group 'auto-complete) - -(defcustom ac-ignore-case 'smart - "Non-nil means auto-complete ignores case. -If this value is `smart', auto-complete ignores case only when -a prefix doesn't contain any upper case letters." - :type '(choice (const :tag "Yes" t) - (const :tag "Smart" smart) - (const :tag "No" nil)) - :group 'auto-complete) - -(defcustom ac-dwim t - "Non-nil means `auto-complete' works based on Do What I Mean." - :type 'boolean - :group 'auto-complete) - -(defcustom ac-use-menu-map nil - "Non-nil means a special keymap `ac-menu-map' on completing menu will be used." - :type 'boolean - :group 'auto-complete) - -(defcustom ac-use-overriding-local-map nil - "Non-nil means `overriding-local-map' will be used to hack for overriding key events on auto-completion." - :type 'boolean - :group 'auto-complete) - -(defcustom ac-disable-inline nil - "Non-nil disable inline completion visibility" - :type 'boolean - :group 'auto-complete) - -(defcustom ac-candidate-menu-min 1 - "Number of candidates required to display menu" - :type 'integer - :group 'auto-complete) - -(defcustom ac-max-width nil - "Maximum width for auto-complete menu to have" - :type '(choice (const :tag "No limit" nil) - (const :tag "Character Limit" 25) - (const :tag "Window Ratio Limit" 0.5)) - :group 'auto-complete) - -(defface ac-completion-face - '((t (:foreground "darkgray" :underline t))) - "Face for inline completion" - :group 'auto-complete) - -(defface ac-candidate-face - '((t (:inherit popup-face))) - "Face for candidate." - :group 'auto-complete) - -(defface ac-candidate-mouse-face - '((t (:inherit popup-menu-mouse-face))) - "Mouse face for candidate." - :group 'auto-complete) - -(defface ac-selection-face - '((t (:inherit popup-menu-selection-face))) - "Face for selected candidate." - :group 'auto-complete) - -(defvar auto-complete-mode-hook nil - "Hook for `auto-complete-mode'.") - - - -;;;; Internal variables - -(defvar auto-complete-mode nil - "Dummy variable to suppress compiler warnings.") - -(defvar ac-cursor-color nil - "Old cursor color.") - -(defvar ac-inline nil - "Inline completion instance.") - -(defvar ac-menu nil - "Menu instance.") - -(defvar ac-show-menu nil - "Flag to show menu on timer tick.") - -(defvar ac-last-completion nil - "Cons of prefix marker and selected item of last completion.") - -(defvar ac-quick-help nil - "Quick help instance") - -(defvar ac-completing nil - "Non-nil means `auto-complete-mode' is now working on completion.") - -(defvar ac-buffer nil - "Buffer where auto-complete is started.") - -(defvar ac-point nil - "Start point of prefix.") - -(defvar ac-last-point nil - "Last point of updating pattern.") - -(defvar ac-prefix nil - "Prefix string.") -(defvaralias 'ac-target 'ac-prefix) - -(defvar ac-selected-candidate nil - "Last selected candidate.") - -(defvar ac-common-part nil - "Common part string of meaningful candidates. -If there is no common part, this will be nil.") - -(defvar ac-whole-common-part nil - "Common part string of whole candidates. -If there is no common part, this will be nil.") - -(defvar ac-prefix-overlay nil - "Overlay for prefix string.") - -(defvar ac-timer nil - "Completion idle timer.") - -(defvar ac-show-menu-timer nil - "Show menu idle timer.") - -(defvar ac-quick-help-timer nil - "Quick help idle timer.") - -(defvar ac-triggered nil - "Flag to update.") - -(defvar ac-limit nil - "Limit number of candidates for each sources.") - -(defvar ac-candidates nil - "Current candidates.") - -(defvar ac-candidates-cache nil - "Candidates cache for individual sources.") - -(defvar ac-fuzzy-enable nil - "Non-nil means fuzzy matching is enabled.") - -(defvar ac-dwim-enable nil - "Non-nil means DWIM completion will be allowed.") - -(defvar ac-mode-map (make-sparse-keymap) - "Auto-complete mode map. It is also used for trigger key command. See also `ac-trigger-key'.") - -(defvar ac-completing-map - (let ((map (make-sparse-keymap))) - (define-key map "\t" 'ac-expand) - (define-key map [tab] 'ac-expand) - (define-key map "\r" 'ac-complete) - (define-key map (kbd "M-TAB") 'auto-complete) - - (define-key map "\M-n" 'ac-next) - (define-key map "\M-p" 'ac-previous) - (define-key map [down] 'ac-next) - (define-key map [up] 'ac-previous) - - (define-key map [f1] 'ac-help) - (define-key map [M-f1] 'ac-persist-help) - (define-key map (kbd "C-?") 'ac-help) - (define-key map (kbd "C-M-?") 'ac-persist-help) - - (define-key map [C-down] 'ac-quick-help-scroll-down) - (define-key map [C-up] 'ac-quick-help-scroll-up) - (define-key map "\C-\M-n" 'ac-quick-help-scroll-down) - (define-key map "\C-\M-p" 'ac-quick-help-scroll-up) - - (dotimes (i 9) - (let ((symbol (intern (format "ac-complete-select-%d" (1+ i))))) - (fset symbol - `(lambda () - (interactive) - (when (and (ac-menu-live-p) (popup-select ac-menu ,i)) - (ac-complete)))) - (define-key map (read-kbd-macro (format "M-%s" (1+ i))) symbol))) - - map) - "Keymap for completion.") -(defvaralias 'ac-complete-mode-map 'ac-completing-map) - -(defvar ac-menu-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map ac-completing-map) - (define-key map (kbd "RET") 'ac-complete) - (define-key map "\C-n" 'ac-next) - (define-key map "\C-p" 'ac-previous) - (define-key map "\C-s" 'ac-isearch) - (define-key map [mouse-1] 'ac-mouse-1) - (define-key map [down-mouse-1] 'ac-ignore) - (define-key map [mouse-4] 'ac-mouse-4) - (define-key map [mouse-5] 'ac-mouse-5) - map) - "Keymap for completion on completing menu.") - -(defvar ac-current-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map ac-completing-map) - map)) - -(defvar ac-match-function 'all-completions - "Default match function.") - -(defvar ac-prefix-definitions - '((symbol . ac-prefix-symbol) - (file . ac-prefix-file) - (valid-file . ac-prefix-valid-file) - (c-dot . ac-prefix-c-dot) - (c-dot-ref . ac-prefix-c-dot-ref) - (cc-member . ac-prefix-cc-member)) - "Prefix definitions for common use.") - -(defvar ac-sources '(ac-source-words-in-same-mode-buffers) - "Sources for completion.") -(make-variable-buffer-local 'ac-sources) - -(defvar ac-compiled-sources nil - "Compiled source of `ac-sources'.") - -(defvar ac-current-sources nil - "Current working sources. This is sublist of `ac-compiled-sources'.") - -(defvar ac-omni-completion-sources nil - "Do not use this anymore.") - -(defvar ac-current-prefix-def nil) - -(defvar ac-ignoring-prefix-def nil) - - - -;;;; Intelligent completion history - -(defvar ac-comphist nil - "Database of completion history.") - -(defsubst ac-comphist-make-tab () - (make-hash-table :test 'equal)) - -(defsubst ac-comphist-tab (db) - (nth 0 db)) - -(defsubst ac-comphist-cache (db) - (nth 1 db)) - -(defun ac-comphist-make (&optional tab) - (list (or tab (ac-comphist-make-tab)) (make-hash-table :test 'equal :weakness t))) - -(defun ac-comphist-get (db string &optional create) - (let* ((tab (ac-comphist-tab db)) - (index (gethash string tab))) - (when (and create (null index)) - (setq index (make-vector (length string) 0)) - (puthash string index tab)) - index)) - -(defun ac-comphist-add (db string prefix) - (setq prefix (min prefix (1- (length string)))) - (when (<= 0 prefix) - (setq string (substring-no-properties string)) - (let ((stat (ac-comphist-get db string t))) - (cl-incf (aref stat prefix)) - (remhash string (ac-comphist-cache db))))) - -(defun ac-comphist-score (db string prefix) - (setq prefix (min prefix (1- (length string)))) - (if (<= 0 prefix) - (let ((cache (gethash string (ac-comphist-cache db)))) - (or (and cache (aref cache prefix)) - (let ((stat (ac-comphist-get db string)) - (score 0.0)) - (when stat - (cl-loop for p from 0 below (length string) - ;; sigmoid function - with a = 5 - with b = (/ 700.0 a) ; bounds for avoiding range error in `exp' - with d = (/ 6.0 a) - for x = (max (- b) (min b (- d (abs (- prefix p))))) - for r = (/ 1.0 (1+ (exp (* (- a) x)))) - do - (cl-incf score (* (aref stat p) r)))) - ;; Weight by distance - (cl-incf score (max 0.0 (- 0.3 (/ (- (length string) prefix) 100.0)))) - (unless cache - (setq cache (make-vector (length string) nil)) - (puthash string cache (ac-comphist-cache db))) - (aset cache prefix score) - score))) - 0.0)) - -(defun ac-comphist-sort (db collection prefix &optional threshold) - (let (result - (n 0) - (total 0) - (cur 0)) - (setq result (mapcar (lambda (a) - (when (and cur threshold) - (if (>= cur (* total threshold)) - (setq cur nil) - (cl-incf n) - (cl-incf cur (cdr a)))) - (car a)) - (sort (mapcar (lambda (string) - (let ((score (ac-comphist-score db string prefix))) - (cl-incf total score) - (cons string score))) - collection) - (lambda (a b) (< (cdr b) (cdr a)))))) - (if threshold - (cons n result) - result))) - -(defun ac-comphist-serialize (db) - (let (alist) - (maphash (lambda (k v) - (push (cons k v) alist)) - (ac-comphist-tab db)) - (list alist))) - -(defun ac-comphist-deserialize (sexp) - (condition-case nil - (ac-comphist-make (let ((tab (ac-comphist-make-tab))) - (mapc (lambda (cons) - (puthash (car cons) (cdr cons) tab)) - (nth 0 sexp)) - tab)) - (error (message "Invalid comphist db.") nil))) - -(defun ac-comphist-init () - (ac-comphist-load) - (add-hook 'kill-emacs-hook 'ac-comphist-save)) - -(defun ac-comphist-load () - (interactive) - (let ((db (if (file-exists-p ac-comphist-file) - (ignore-errors - (with-temp-buffer - (insert-file-contents ac-comphist-file) - (goto-char (point-min)) - (ac-comphist-deserialize (read (current-buffer)))))))) - (setq ac-comphist (or db (ac-comphist-make))))) - -(defun ac-comphist-save () - (interactive) - (require 'pp) - (ignore-errors - (with-temp-buffer - (pp (ac-comphist-serialize ac-comphist) (current-buffer)) - (write-region (point-min) (point-max) ac-comphist-file)))) - - - -;;;; Dictionary -(defvar ac-buffer-dictionary nil) -(defvar ac-file-dictionary (make-hash-table :test 'equal)) - -(defun ac-clear-dictionary-cache () - (interactive) - (dolist (buffer (buffer-list)) - (with-current-buffer buffer - (if (local-variable-p 'ac-buffer-dictionary) - (kill-local-variable 'ac-buffer-dictionary)))) - (clrhash ac-file-dictionary)) - -(defun ac-file-dictionary (filename) - (let ((cache (gethash filename ac-file-dictionary 'none))) - (if (and cache (not (eq cache 'none))) - cache - (let (result) - (ignore-errors - (with-temp-buffer - (insert-file-contents filename) - (setq result (split-string (buffer-string) "\n" t)))) - (puthash filename result ac-file-dictionary) - result)))) - -(defun ac-mode-dictionary (mode) - (cl-loop for name in (cons (symbol-name mode) - (ignore-errors (list (file-name-extension (buffer-file-name))))) - append (cl-loop for dir in ac-dictionary-directories - for file = (concat dir "/" name) - if (file-exists-p file) - append (ac-file-dictionary file)))) - -(defun ac-buffer-dictionary (&optional buffer) - (with-current-buffer (or buffer (current-buffer)) - (if (local-variable-p 'ac-buffer-dictionary) - ac-buffer-dictionary - (make-local-variable 'ac-buffer-dictionary) - (setq ac-buffer-dictionary - (apply 'append - ac-user-dictionary - (ac-mode-dictionary major-mode) - (mapcar 'ac-file-dictionary ac-dictionary-files)))))) - - - -;;;; Auto completion internals - -(defun ac-menu-at-wrapper-line-p () - "Return non-nil if current line is long and wrapped to next visual line." - (and (not truncate-lines) - (eq (line-beginning-position) - (save-excursion - (vertical-motion 1) - (line-beginning-position))))) - -(defun ac-stop-word-p (word) - (or (member word ac-stop-words) - (if ac-use-dictionary-as-stop-words - (member word (ac-buffer-dictionary))))) - -(defun ac-prefix-default () - "Same as `ac-prefix-symbol' but ignore a number prefix." - (let ((start (ac-prefix-symbol))) - (when start - (cl-loop with end = (point) - for pos from start below end - for c = (char-after pos) - if (not (and (<= ?0 c) (<= c ?9))) - return start)))) - -(defun ac-prefix-symbol () - "Default prefix definition function." - (require 'thingatpt) - (car-safe (bounds-of-thing-at-point 'symbol))) - -(defun ac-prefix-file () - "File prefix." - (let ((point (re-search-backward "[\"<>' \t\r\n]" nil t))) - (if point (1+ point)))) - -(defsubst ac-windows-remote-file-p (file) - (and (memq system-type '(ms-dos windows-nt cygwin)) - (string-match-p "\\`\\(?://\\|\\\\\\\\\\)" file))) - -(defun ac-prefix-valid-file () - "Existed (or to be existed) file prefix." - (let* ((line-beg (line-beginning-position)) - (end (point)) - (start (or (let ((point (re-search-backward "[\"<>'= \t\r\n]" line-beg t))) - (if point (1+ point))) - line-beg)) - (file (buffer-substring start end))) - (if (and file (or (string-match "^/" file) - (and (setq file (and (string-match "^[^/]*/" file) - (match-string 0 file))) - (file-directory-p file)))) - (unless (ac-windows-remote-file-p file) - start)))) - -(defun ac-prefix-c-dot () - "C-like languages dot(.) prefix." - (if (re-search-backward "\\.\\(\\(?:[a-zA-Z0-9][_a-zA-Z0-9]*\\)?\\)\\=" nil t) - (match-beginning 1))) - -(defun ac-prefix-c-dot-ref () - "C-like languages dot(.) and reference(->) prefix." - (if (re-search-backward "\\(?:\\.\\|->\\)\\(\\(?:[a-zA-Z0-9][_a-zA-Z0-9]*\\)?\\)\\=" nil t) - (match-beginning 1))) - -(defun ac-prefix-cc-member () - "C-like languages member(.)(->)(::) prefix." - (when (re-search-backward "\\(?:\\.\\|->\\|::\\)\\(\\(?:[a-zA-Z0-9][_a-zA-Z0-9]*\\)?\\)\\=" nil t) - (match-beginning 1))) - -(defun ac-define-prefix (name prefix) - "Define new prefix definition. -You can not use it in source definition like (prefix . `NAME')." - (push (cons name prefix) ac-prefix-definitions)) - -(defun ac-match-substring (prefix candidates) - (cl-loop with regexp = (regexp-quote prefix) - for candidate in candidates - if (string-match regexp candidate) - collect candidate)) - -(defsubst ac-source-entity (source) - (if (symbolp source) - (symbol-value source) - source)) - -(defun ac-source-available-p (source) - (if (and (symbolp source) - (get source 'available)) - (eq (get source 'available) t) - (let* ((src (ac-source-entity source)) - (avail-pair (assq 'available src)) - (avail-cond (cdr avail-pair)) - (available (and (if avail-pair - (cond - ((symbolp avail-cond) - (funcall avail-cond)) - ((listp avail-cond) - (eval avail-cond))) - t) - (cl-loop for feature in (assoc-default 'depends src) - unless (require feature nil t) return nil - finally return t)))) - (if (symbolp source) - (put source 'available (if available t 'no))) - available))) - -(defun ac-compile-sources (sources) - "Compiled `SOURCES' into expanded sources style." - (cl-loop for source in sources - if (ac-source-available-p source) - do - (setq source (ac-source-entity source)) - ;; prefix - (let* ((prefix (assoc 'prefix source)) - (real (assoc-default (cdr prefix) ac-prefix-definitions))) - (cond - (real - (add-to-list 'source (cons 'prefix real))) - ((null prefix) - (add-to-list 'source (cons 'prefix 'ac-prefix-default))))) - ;; match - (let ((match (assq 'match source))) - (cond - ((eq (cdr match) 'substring) - (setcdr match 'ac-match-substring)))) - and collect source)) - -(defun ac-compiled-sources () - (or ac-compiled-sources - (setq ac-compiled-sources - (ac-compile-sources ac-sources)))) - -(defsubst ac-menu-live-p () - (popup-live-p ac-menu)) - -(defun ac-menu-create (point width height) - (setq ac-menu - (popup-create point width height - :around t - :face 'ac-candidate-face - :max-width ac-max-width - :mouse-face 'ac-candidate-mouse-face - :selection-face 'ac-selection-face - :symbol t - :scroll-bar t - :margin-left 1 - :keymap ac-menu-map - ))) - -(defun ac-menu-delete () - (when ac-menu - (popup-delete ac-menu) - (setq ac-menu))) - -(defsubst ac-inline-overlay () - (nth 0 ac-inline)) - -(defsubst ac-inline-live-p () - (and ac-inline (ac-inline-overlay) t)) - -(defun ac-inline-show (point string) - (unless ac-inline - (setq ac-inline (list nil))) - (save-excursion - (let ((overlay (ac-inline-overlay)) - (width 0) - (string-width (string-width string)) - (length 0) - (original-string string)) - ;; Calculate string space to show completion - (goto-char point) - (let (c) - (while (and (not (eolp)) - (< width string-width) - (setq c (char-after)) - (not (eq c ?\t))) ; special case for tab - (cl-incf width (char-width c)) - (cl-incf length) - (forward-char))) - - ;; Show completion - (goto-char point) - (cond - ((= width 0) - ;; End-of-line - ;; Do nothing - ) - ((<= width string-width) - ;; No space to show - ;; Do nothing - ) - ((> width string-width) - ;; Need to fill space - (setq string (concat string (make-string (- width string-width) ? ))))) - (setq string (propertize string 'face 'ac-completion-face)) - (if overlay - (progn - (move-overlay overlay point (+ point length)) - (overlay-put overlay 'invisible nil)) - (setq overlay (make-overlay point (+ point length))) - (setf (nth 0 ac-inline) overlay) - (overlay-put overlay 'priority 9999) - ;; Help prefix-overlay in some cases - (overlay-put overlay 'keymap ac-current-map)) - ;; TODO no width but char - (if (eq length 0) - ;; Case: End-of-line - (progn - (put-text-property 0 1 'cursor t string) - (overlay-put overlay 'after-string string)) - (let ((display (substring string 0 1)) - (after-string (substring string 1))) - (overlay-put overlay 'display display) - (overlay-put overlay 'after-string after-string))) - (overlay-put overlay 'string original-string)))) - -(defun ac-inline-delete () - (when (ac-inline-live-p) - (ac-inline-hide) - (delete-overlay (ac-inline-overlay)) - (setq ac-inline nil))) - -(defun ac-inline-hide () - (when (ac-inline-live-p) - (let ((overlay (ac-inline-overlay)) - (buffer-undo-list t)) - (when overlay - (move-overlay overlay (point-min) (point-min)) - (overlay-put overlay 'invisible t) - (overlay-put overlay 'display nil) - (overlay-put overlay 'after-string nil))))) - -(defun ac-inline-update () - (if (and ac-completing ac-prefix (stringp ac-common-part)) - (let ((common-part-length (length ac-common-part)) - (prefix-length (length ac-prefix))) - (if (> common-part-length prefix-length) - (progn - (ac-inline-hide) - (ac-inline-show (point) (substring ac-common-part prefix-length))) - (ac-inline-delete))) - (ac-inline-delete))) - -(defun ac-put-prefix-overlay () - (unless ac-prefix-overlay - (let (newline) - ;; Insert newline to make sure that cursor always on the overlay - (when (eobp) - (popup-save-buffer-state - (insert "\n")) - (setq newline t)) - (setq ac-prefix-overlay (make-overlay ac-point (1+ (point)) nil t t)) - (overlay-put ac-prefix-overlay 'priority 9999) - (overlay-put ac-prefix-overlay 'keymap (make-sparse-keymap)) - (overlay-put ac-prefix-overlay 'newline newline)))) - -(defun ac-remove-prefix-overlay () - (when ac-prefix-overlay - (when (overlay-get ac-prefix-overlay 'newline) - ;; Remove inserted newline - (popup-save-buffer-state - (goto-char (point-max)) - (if (eq (char-before) ?\n) - (delete-char -1)))) - (delete-overlay ac-prefix-overlay))) - -(defun ac-activate-completing-map () - (if (and ac-show-menu ac-use-menu-map) - (set-keymap-parent ac-current-map ac-menu-map)) - (when (and ac-use-overriding-local-map - (null overriding-terminal-local-map)) - (setq overriding-terminal-local-map ac-current-map)) - (when ac-prefix-overlay - (set-keymap-parent (overlay-get ac-prefix-overlay 'keymap) ac-current-map))) - -(defun ac-deactivate-completing-map () - (set-keymap-parent ac-current-map ac-completing-map) - (when (and ac-use-overriding-local-map - (eq overriding-terminal-local-map ac-current-map)) - (setq overriding-terminal-local-map nil)) - (when ac-prefix-overlay - (set-keymap-parent (overlay-get ac-prefix-overlay 'keymap) nil))) - -(defsubst ac-selected-candidate () - (if ac-menu - (popup-selected-item ac-menu))) - -(defun ac-prefix (requires ignore-list) - (cl-loop with current = (point) - with point - with point-def - with prefix-def - with sources - for source in (ac-compiled-sources) - for prefix = (assoc-default 'prefix source) - for req = (or (assoc-default 'requires source) requires 1) - - do - (unless (member prefix ignore-list) - (save-excursion - (setq point (cond - ((symbolp prefix) - (funcall prefix)) - ((stringp prefix) - (and (re-search-backward (concat prefix "\\=") nil t) - (or (match-beginning 1) (match-beginning 0)))) - ((stringp (car-safe prefix)) - (let ((regexp (nth 0 prefix)) - (end (nth 1 prefix)) - (group (nth 2 prefix))) - (and (re-search-backward (concat regexp "\\=") nil t) - (funcall (if end 'match-end 'match-beginning) - (or group 0))))) - (t - (eval prefix)))) - (if (and point - (integerp req) - (< (- current point) req)) - (setq point nil)) - (when point - (if (null prefix-def) - (setq prefix-def prefix - point-def point)) - (if (equal point point-def) - (push source sources))))) - - finally return - (and point-def (list prefix-def point-def (nreverse sources))))) - -(defun ac-init () - "Initialize current sources to start completion." - (setq ac-candidates-cache nil) - (cl-loop for source in ac-current-sources - for function = (assoc-default 'init source) - if function do - (save-excursion - (cond - ((functionp function) - (funcall function)) - (t - (eval function)))))) - -(defun ac-candidates-1 (source) - (let* ((do-cache (assq 'cache source)) - (function (assoc-default 'candidates source)) - (action (assoc-default 'action source)) - (document (assoc-default 'document source)) - (symbol (assoc-default 'symbol source)) - (ac-limit (or (assoc-default 'limit source) ac-limit)) - (face (or (assoc-default 'face source) (assoc-default 'candidate-face source))) - (selection-face (assoc-default 'selection-face source)) - (cache (and do-cache (assq source ac-candidates-cache))) - (candidates (cdr cache))) - (unless cache - (setq candidates (save-excursion - (cond - ((functionp function) - (funcall function)) - (t - (eval function))))) - ;; Convert (name value) format candidates into name with text properties. - (setq candidates (mapcar (lambda (candidate) - (if (consp candidate) - (propertize (car candidate) 'value (cdr candidate)) - candidate)) - candidates)) - (when do-cache - (push (cons source candidates) ac-candidates-cache))) - (setq candidates (funcall (or (assoc-default 'match source) - ac-match-function) - ac-prefix candidates)) - ;; Remove extra items regarding to ac-limit - (if (and (integerp ac-limit) (> ac-limit 1) (> (length candidates) ac-limit)) - (setcdr (nthcdr (1- ac-limit) candidates) nil)) - ;; Put candidate properties - (setq candidates (mapcar (lambda (candidate) - (popup-item-propertize candidate - 'action action - 'symbol symbol - 'document document - 'popup-face face - 'selection-face selection-face)) - candidates)) - candidates)) - -(defun ac-delete-duplicated-candidates (candidates) - (cl-delete-duplicates - candidates - :test (lambda (x y) - ;; We assume two candidates are same if their titles are - ;; equal and their actions are equal. - (and (equal x y) - (eq (popup-item-property x 'action) - (popup-item-property y 'action)))) - :from-end t)) - -(defun ac-reduce-candidates (candidates) - ;; Call `ac-delete-duplicated-candidates' on first portion of - ;; candidate list for speed. - (let ((size 20)) - (if (< (length candidates) size) - (ac-delete-duplicated-candidates candidates) - (cl-loop for c on candidates by 'cdr - repeat (1- size) - finally return - (let ((rest (cdr c))) - (setcdr c nil) - (append (ac-delete-duplicated-candidates candidates) (copy-sequence rest))))))) - -(defun ac-candidates () - "Produce candidates for current sources." - (cl-loop with completion-ignore-case = (or (eq ac-ignore-case t) - (and (eq ac-ignore-case 'smart) - (let ((case-fold-search nil)) (not (string-match "[[:upper:]]" ac-prefix))))) - with case-fold-search = completion-ignore-case - with prefix-len = (length ac-prefix) - for source in ac-current-sources - append (ac-candidates-1 source) into candidates - finally return - (progn - (if (and ac-use-comphist ac-comphist) - (if ac-show-menu - (let* ((pair (ac-comphist-sort ac-comphist candidates prefix-len ac-comphist-threshold)) - (n (car pair)) - (result (ac-reduce-candidates (cdr pair))) - (cons (if (> n 0) (nthcdr (1- n) result))) - (cdr (cdr cons))) - ;; XXX ugly - (if cons (setcdr cons nil)) - (setq ac-common-part (try-completion ac-prefix result)) - (setq ac-whole-common-part (try-completion ac-prefix candidates)) - (if cons (setcdr cons cdr)) - result) - (setq candidates (ac-comphist-sort ac-comphist candidates prefix-len)) - (setq ac-common-part (if candidates (popup-x-to-string (car candidates)))) - (setq ac-whole-common-part (try-completion ac-prefix candidates)) - candidates) - (when ac-show-menu - (setq candidates (ac-reduce-candidates candidates))) - (setq ac-common-part (try-completion ac-prefix candidates)) - (setq ac-whole-common-part ac-common-part) - candidates)))) - -(defun ac-update-candidates (cursor scroll-top) - "Update candidates of menu to `ac-candidates' and redraw it." - (setf (popup-cursor ac-menu) cursor - (popup-scroll-top ac-menu) scroll-top) - (setq ac-dwim-enable (= (length ac-candidates) 1)) - (if ac-candidates - (progn - (setq ac-completing t) - (ac-activate-completing-map)) - (setq ac-completing nil) - (ac-deactivate-completing-map)) - (unless ac-disable-inline - (ac-inline-update)) - (popup-set-list ac-menu ac-candidates) - (if (and (not ac-fuzzy-enable) - (<= (length ac-candidates) ac-candidate-menu-min)) - (popup-hide ac-menu) - (if ac-show-menu - (popup-draw ac-menu)))) - -(defun ac-reposition () - "Force to redraw candidate menu with current `ac-candidates'." - (let ((cursor (popup-cursor ac-menu)) - (scroll-top (popup-scroll-top ac-menu)) - (height (popup-height ac-menu))) - (ac-menu-delete) - (ac-menu-create ac-point (popup-preferred-width ac-candidates) height) - (ac-update-candidates cursor scroll-top))) - -(defun ac-cleanup () - "Cleanup auto completion." - (if ac-cursor-color - (set-cursor-color ac-cursor-color)) - (when (and ac-use-comphist ac-comphist) - (when (and (null ac-selected-candidate) - (member ac-prefix ac-candidates)) - ;; Assume candidate is selected by just typing - (setq ac-selected-candidate ac-prefix) - (setq ac-last-point ac-point)) - (when ac-selected-candidate - (ac-comphist-add ac-comphist - ac-selected-candidate - (if ac-last-point - (- ac-last-point ac-point) - (length ac-prefix))))) - (ac-deactivate-completing-map) - (ac-remove-prefix-overlay) - (ac-remove-quick-help) - (ac-inline-delete) - (ac-menu-delete) - (ac-cancel-timer) - (ac-cancel-show-menu-timer) - (ac-cancel-quick-help-timer) - (setq ac-cursor-color nil - ac-inline nil - ac-show-menu nil - ac-menu nil - ac-completing nil - ac-point nil - ac-last-point nil - ac-prefix nil - ac-prefix-overlay nil - ac-selected-candidate nil - ac-common-part nil - ac-whole-common-part nil - ac-triggered nil - ac-limit nil - ac-candidates nil - ac-candidates-cache nil - ac-fuzzy-enable nil - ac-dwim-enable nil - ac-compiled-sources nil - ac-current-sources nil - ac-current-prefix-def nil - ac-ignoring-prefix-def nil)) - -(defsubst ac-abort () - "Abort completion." - (ac-cleanup)) - -(defun ac-extend-region-to-delete (string) - "Determine the boundary of the region to delete before -inserting the completed string. This will be either the position -of current point, or the end of the symbol at point, if the text -from point to end of symbol is the right part of the completed -string." - (let* ((end-of-symbol (or (cdr-safe (bounds-of-thing-at-point 'symbol)) - (point))) - (remaindar (buffer-substring-no-properties (point) end-of-symbol)) - (remaindar-length (length remaindar))) - (if (and (>= (length string) remaindar-length) - (string= (substring-no-properties string (- remaindar-length)) - remaindar)) - end-of-symbol - (point)))) - -(defun ac-expand-string (string &optional remove-undo-boundary) - "Expand `STRING' into the buffer and update `ac-prefix' to `STRING'. -This function records deletion and insertion sequences by `undo-boundary'. -If `remove-undo-boundary' is non-nil, this function also removes `undo-boundary' -that have been made before in this function. When `buffer-undo-list' is -`t', `remove-undo-boundary' has no effect." - (when (eq buffer-undo-list t) - (setq remove-undo-boundary nil)) - (when (not (equal string (buffer-substring ac-point (point)))) - (undo-boundary) - ;; We can't use primitive-undo since it undoes by - ;; groups, divided by boundaries. - ;; We don't want boundary between deletion and insertion. - ;; So do it manually. - ;; Delete region silently for undo: - (if remove-undo-boundary - (progn - (let (buffer-undo-list) - (save-excursion - (delete-region ac-point (ac-extend-region-to-delete string)))) - (setq buffer-undo-list - (nthcdr 2 buffer-undo-list))) - (delete-region ac-point (ac-extend-region-to-delete string))) - (insert (substring-no-properties string)) - ;; Sometimes, possible when omni-completion used, (insert) added - ;; to buffer-undo-list strange record about position changes. - ;; Delete it here: - (when (and remove-undo-boundary - (integerp (cadr buffer-undo-list))) - (setcdr buffer-undo-list (nthcdr 2 buffer-undo-list))) - (undo-boundary) - (setq ac-selected-candidate string) - (setq ac-prefix string))) - -(defun ac-set-trigger-key (key) - "Set `ac-trigger-key' to `KEY'. It is recommemded to use this function instead of calling `setq'." - ;; Remove old mapping - (when ac-trigger-key - (define-key ac-mode-map (read-kbd-macro ac-trigger-key) nil)) - - ;; Make new mapping - (setq ac-trigger-key key) - (when key - (define-key ac-mode-map (read-kbd-macro key) 'ac-trigger-key-command))) - -(defun ac-set-timer () - (unless ac-timer - (setq ac-timer (run-with-idle-timer ac-delay ac-delay 'ac-update-greedy)))) - -(defun ac-cancel-timer () - (when (timerp ac-timer) - (cancel-timer ac-timer) - (setq ac-timer nil))) - -(defun ac-update (&optional force) - (when (and auto-complete-mode - ac-prefix - (or ac-triggered - force) - (not isearch-mode)) - (ac-put-prefix-overlay) - (setq ac-candidates (ac-candidates)) - (let ((preferred-width (popup-preferred-width ac-candidates))) - ;; Reposition if needed - (when (or (null ac-menu) - (>= (popup-width ac-menu) preferred-width) - (<= (popup-width ac-menu) (- preferred-width 10)) - (and (> (popup-direction ac-menu) 0) - (ac-menu-at-wrapper-line-p))) - (ac-inline-hide) ; Hide overlay to calculate correct column - (ac-remove-quick-help) - (ac-menu-delete) - (ac-menu-create ac-point preferred-width ac-menu-height))) - (ac-update-candidates 0 0) - t)) - -(defun ac-update-greedy (&optional force) - (let (result) - (while (when (and (setq result (ac-update force)) - (null ac-candidates)) - (add-to-list 'ac-ignoring-prefix-def ac-current-prefix-def) - (ac-start :force-init t) - ac-current-prefix-def)) - result)) - -(defun ac-set-show-menu-timer () - (when (and (or (integerp ac-auto-show-menu) (floatp ac-auto-show-menu)) - (null ac-show-menu-timer)) - (setq ac-show-menu-timer (run-with-idle-timer ac-auto-show-menu ac-auto-show-menu 'ac-show-menu)))) - -(defun ac-cancel-show-menu-timer () - (when (timerp ac-show-menu-timer) - (cancel-timer ac-show-menu-timer) - (setq ac-show-menu-timer nil))) - -(defun ac-show-menu () - (when (not (eq ac-show-menu t)) - (setq ac-show-menu t) - (ac-inline-hide) - (ac-remove-quick-help) - (ac-update t))) - -(defun ac-help (&optional persist) - (interactive "P") - (when ac-menu - (popup-menu-show-help ac-menu persist))) - -(defun ac-persist-help () - (interactive) - (ac-help t)) - -(defun ac-last-help (&optional persist) - (interactive "P") - (when ac-last-completion - (popup-item-show-help (cdr ac-last-completion) persist))) - -(defun ac-last-persist-help () - (interactive) - (ac-last-help t)) - -(defun ac-set-quick-help-timer () - (when (and ac-use-quick-help - (null ac-quick-help-timer)) - (setq ac-quick-help-timer (run-with-idle-timer ac-quick-help-delay ac-quick-help-delay 'ac-quick-help)))) - -(defun ac-cancel-quick-help-timer () - (when (timerp ac-quick-help-timer) - (cancel-timer ac-quick-help-timer) - (setq ac-quick-help-timer nil))) - -(defun ac-pos-tip-show-quick-help (menu &optional item &rest args) - (let* ((point (plist-get args :point)) - (around nil) - (parent-offset (popup-offset menu)) - (doc (popup-menu-documentation menu item))) - (when (stringp doc) - (if (popup-hidden-p menu) - (setq around t) - (setq point nil)) - (with-no-warnings - (pos-tip-show doc - 'popup-tip-face - (or point - (and menu - (popup-child-point menu parent-offset)) - (point)) - nil 300 - popup-tip-max-width - nil nil - (and (not around) 0)) - (unless (plist-get args :nowait) - (clear-this-command-keys) - (unwind-protect - (push (read-event (plist-get args :prompt)) unread-command-events) - (pos-tip-hide)) - t))))) - -(defun ac-quick-help-use-pos-tip-p () - (and ac-quick-help-prefer-pos-tip - window-system - (featurep 'pos-tip))) - -(defun ac-quick-help (&optional force) - (interactive) - ;; TODO don't use FORCE - (when (and (or force - (with-no-warnings - ;; called-interactively-p can take no args - (called-interactively-p)) - ;; ac-isearch'ing - (null this-command)) - (ac-menu-live-p) - (null ac-quick-help)) - (setq ac-quick-help - (funcall (if (ac-quick-help-use-pos-tip-p) - 'ac-pos-tip-show-quick-help - 'popup-menu-show-quick-help) - ac-menu nil - :point ac-point - :height ac-quick-help-height - :nowait t)))) - -(defun ac-remove-quick-help () - (when (ac-quick-help-use-pos-tip-p) - (with-no-warnings - (pos-tip-hide))) - (when ac-quick-help - (popup-delete ac-quick-help) - (setq ac-quick-help nil))) - -(defun ac-last-quick-help () - (interactive) - (when (and ac-last-completion - (eq (marker-buffer (car ac-last-completion)) - (current-buffer))) - (let ((doc (popup-item-documentation (cdr ac-last-completion))) - (point (marker-position (car ac-last-completion)))) - (when (stringp doc) - (if (ac-quick-help-use-pos-tip-p) - (with-no-warnings (pos-tip-show doc nil point nil 300)) - (popup-tip doc - :point point - :around t - :scroll-bar t - :margin t)))))) - -(defmacro ac-define-quick-help-command (name arglist &rest body) - (declare (indent 2)) - `(progn - (defun ,name ,arglist ,@body) - (put ',name 'ac-quick-help-command t))) - -(ac-define-quick-help-command ac-quick-help-scroll-down () - (interactive) - (when ac-quick-help - (popup-scroll-down ac-quick-help))) - -(ac-define-quick-help-command ac-quick-help-scroll-up () - (interactive) - (when ac-quick-help - (popup-scroll-up ac-quick-help))) - - - -;;;; Auto completion isearch - -(defun ac-isearch-callback (list) - (setq ac-dwim-enable (eq (length list) 1))) - -(defun ac-isearch () - (interactive) - (when (ac-menu-live-p) - (ac-cancel-show-menu-timer) - (ac-show-menu) - (if ac-use-quick-help - (let ((popup-menu-show-quick-help-function - (if (ac-quick-help-use-pos-tip-p) - 'ac-pos-tip-show-quick-help - 'popup-menu-show-quick-help))) - (popup-isearch ac-menu - :callback 'ac-isearch-callback - :help-delay ac-quick-help-delay)) - (popup-isearch ac-menu :callback 'ac-isearch-callback)))) - - - -;;;; Auto completion commands - -(cl-defun auto-complete-1 (&key sources (triggered 'command)) - (let ((menu-live (ac-menu-live-p)) - (inline-live (ac-inline-live-p)) - started) - (ac-abort) - (let ((ac-sources (or sources ac-sources))) - (if (or ac-show-menu-immediately-on-auto-complete - inline-live) - (setq ac-show-menu t)) - (setq started (ac-start :triggered triggered))) - (when (ac-update-greedy t) - ;; TODO Not to cause inline completion to be disrupted. - (if (ac-inline-live-p) - (ac-inline-hide)) - ;; Not to expand when it is first time to complete - (when (and (or (and (not ac-expand-on-auto-complete) - (> (length ac-candidates) 1) - (not menu-live)) - (not (let ((ac-common-part ac-whole-common-part)) - (ac-expand-common)))) - ac-use-fuzzy - (null ac-candidates)) - (ac-fuzzy-complete))) - started)) - -;;;###autoload -(defun auto-complete (&optional sources) - "Start auto-completion at current point." - (interactive) - (auto-complete-1 :sources sources)) - -(defun ac-fuzzy-complete () - "Start fuzzy completion at current point." - (interactive) - (if (not (require 'fuzzy nil t)) - (message "Please install fuzzy.el if you use fuzzy completion") - (unless (ac-menu-live-p) - (ac-start)) - (let ((ac-match-function 'fuzzy-all-completions)) - (when ac-fuzzy-cursor-color - (unless ac-cursor-color - (setq ac-cursor-color (frame-parameter (selected-frame) 'cursor-color))) - (set-cursor-color ac-fuzzy-cursor-color)) - (setq ac-show-menu t) - (setq ac-fuzzy-enable t) - (setq ac-triggered nil) - (ac-update t))) - t) - -(defun ac-next () - "Select next candidate." - (interactive) - (when (ac-menu-live-p) - (when (popup-hidden-p ac-menu) - (ac-show-menu)) - (popup-next ac-menu) - (if (eq this-command 'ac-next) - (setq ac-dwim-enable t)))) - -(defun ac-previous () - "Select previous candidate." - (interactive) - (when (ac-menu-live-p) - (when (popup-hidden-p ac-menu) - (ac-show-menu)) - (popup-previous ac-menu) - (if (eq this-command 'ac-previous) - (setq ac-dwim-enable t)))) - -(defun ac-expand (arg) - "Try expand, and if expanded twice, select next candidate. -If given a prefix argument, select the previous candidate." - (interactive "P") - (unless (ac-expand-common) - (let ((string (ac-selected-candidate))) - (when string - (when (equal ac-prefix string) - (if (not arg) - (ac-next) - (ac-previous)) - (setq string (ac-selected-candidate))) - (ac-expand-string string - (or (eq last-command 'ac-expand) - (eq last-command 'ac-expand-previous))) - ;; Do reposition if menu at long line - (if (and (> (popup-direction ac-menu) 0) - (ac-menu-at-wrapper-line-p)) - (ac-reposition)) - (setq ac-show-menu t) - string)))) - -(defun ac-expand-previous (arg) - "Like `ac-expand', but select previous candidate." - (interactive "P") - (ac-expand (not arg))) - -(defun ac-expand-common () - "Try to expand meaningful common part." - (interactive) - (if (and ac-dwim ac-dwim-enable) - (ac-complete) - (when (and (ac-inline-live-p) - ac-common-part) - (ac-inline-hide) - (ac-expand-string ac-common-part (eq last-command this-command)) - (setq ac-common-part nil) - t))) - -(defun ac-complete-1 (candidate) - (let ((action (popup-item-property candidate 'action)) - (fallback nil)) - (when candidate - (unless (ac-expand-string candidate) - (setq fallback t)) - ;; Remember to show help later - (when (and ac-point candidate) - (unless ac-last-completion - (setq ac-last-completion (cons (make-marker) nil))) - (set-marker (car ac-last-completion) ac-point ac-buffer) - (setcdr ac-last-completion candidate))) - (ac-abort) - (cond - (action - (funcall action)) - (fallback - (ac-fallback-command))) - candidate)) - -(defun ac-complete () - "Try complete." - (interactive) - (ac-complete-1 (ac-selected-candidate))) - -(cl-defun ac-start (&key - requires - force-init - (triggered (or ac-triggered t))) - "Start completion." - (interactive) - (if (not auto-complete-mode) - (message "auto-complete-mode is not enabled") - (let* ((info (ac-prefix requires ac-ignoring-prefix-def)) - (prefix-def (nth 0 info)) - (point (nth 1 info)) - (sources (nth 2 info)) - prefix - (init (or force-init (not (eq ac-point point))))) - (if (or (null point) - (progn - (setq prefix (buffer-substring-no-properties point (point))) - (and (not (eq triggered 'command)) - (ac-stop-word-p prefix)))) - (prog1 nil - (ac-abort)) - (when (and ac-use-fuzzy ac-fuzzy-cursor-color) - (unless ac-cursor-color - (setq ac-cursor-color (frame-parameter (selected-frame) 'cursor-color)))) - (setq ac-show-menu (or ac-show-menu (if (eq ac-auto-show-menu t) t)) - ac-current-sources sources - ac-buffer (current-buffer) - ac-point point - ac-prefix prefix - ac-limit ac-candidate-limit - ac-triggered triggered - ac-current-prefix-def prefix-def) - (when (or init (null ac-prefix-overlay)) - (ac-init)) - (ac-set-timer) - (ac-set-show-menu-timer) - (ac-set-quick-help-timer) - (ac-put-prefix-overlay) - t)))) - -(defun ac-stop () - "Stop completiong." - (interactive) - (setq ac-selected-candidate nil) - (ac-abort)) - -(defun ac-ignore (&rest ignore) - "Same as `ignore'." - (interactive)) - -(defun ac-mouse-1 (event) - (interactive "e") - (popup-awhen (popup-menu-item-of-mouse-event event) - (ac-complete-1 it))) - -(defun ac-mouse-4 (event) - (interactive "e") - (ac-previous)) - -(defun ac-mouse-5 (event) - (interactive "e") - (ac-next)) - -(defun ac-trigger-key-command (&optional force) - (interactive "P") - (let (started) - (when (or force (ac-trigger-command-p last-command)) - (setq started (auto-complete-1 :triggered 'trigger-key))) - (unless started - (ac-fallback-command 'ac-trigger-key-command)))) - - - -;;;; Basic cache facility - -(defvar ac-clear-variables-every-minute-timer nil) -(defvar ac-clear-variables-after-save nil) -(defvar ac-clear-variables-every-minute nil) -(defvar ac-minutes-counter 0) - -(defun ac-clear-variable-after-save (variable &optional pred) - (add-to-list 'ac-clear-variables-after-save (cons variable pred))) - -(defun ac-clear-variables-after-save () - (dolist (pair ac-clear-variables-after-save) - (if (or (null (cdr pair)) - (funcall (cdr pair))) - (set (car pair) nil)))) - -(defun ac-clear-variable-every-minutes (variable minutes) - (add-to-list 'ac-clear-variables-every-minute (cons variable minutes))) - -(defun ac-clear-variable-every-minute (variable) - (ac-clear-variable-every-minutes variable 1)) - -(defun ac-clear-variable-every-10-minutes (variable) - (ac-clear-variable-every-minutes variable 10)) - -(defun ac-clear-variables-every-minute () - (cl-incf ac-minutes-counter) - (dolist (pair ac-clear-variables-every-minute) - (if (eq (% ac-minutes-counter (cdr pair)) 0) - (set (car pair) nil)))) - - - -;;;; Auto complete mode - -(defun ac-cursor-on-diable-face-p (&optional point) - (memq (get-text-property (or point (point)) 'face) ac-disable-faces)) - -(defun ac-trigger-command-p (command) - "Return non-nil if `COMMAND' is a trigger command." - (and (symbolp command) - (not (memq command ac-non-trigger-commands)) - (or (memq command ac-trigger-commands) - (string-match "self-insert-command" (symbol-name command)) - (string-match "electric" (symbol-name command))))) - -(defun ac-fallback-key-sequence () - (setq unread-command-events - (append (this-single-command-raw-keys) - unread-command-events)) - (read-key-sequence-vector "")) - -(defun ac-fallback-command (&optional except-command) - (let* ((auto-complete-mode nil) - (keys (ac-fallback-key-sequence)) - (command (and keys (key-binding keys)))) - (when (and (commandp command) - (not (eq command except-command))) - (setq this-command command) - (call-interactively command)))) - -(defun ac-compatible-package-command-p (command) - "Return non-nil if `COMMAND' is compatible with auto-complete." - (and (symbolp command) - (string-match ac-compatible-packages-regexp (symbol-name command)))) - -(defun ac-handle-pre-command () - (condition-case var - (if (or (setq ac-triggered (and (not ac-fuzzy-enable) ; ignore key storkes in fuzzy mode - (or (eq this-command 'auto-complete) ; special case - (ac-trigger-command-p this-command) - (and ac-completing - (memq this-command ac-trigger-commands-on-completing))) - (not (ac-cursor-on-diable-face-p)) - (or ac-triggered t))) - (ac-compatible-package-command-p this-command)) - (progn - (if (or (not (symbolp this-command)) - (not (get this-command 'ac-quick-help-command))) - (ac-remove-quick-help)) - ;; Not to cause inline completion to be disrupted. - (ac-inline-hide)) - (ac-abort)) - (error (ac-error var)))) - -(defun ac-handle-post-command () - (condition-case var - (when (and ac-triggered - (or ac-auto-start - ac-completing) - (not isearch-mode)) - (setq ac-last-point (point)) - (ac-start :requires (unless ac-completing ac-auto-start)) - (unless ac-disable-inline - (ac-inline-update))) - (error (ac-error var)))) - -(defvar ac-flycheck-poll-completion-end-timer nil - "Timer to poll end of completion.") - -(defun ac-syntax-checker-workaround () - (if ac-stop-flymake-on-completing - (progn - (make-local-variable 'ac-flycheck-poll-completion-end-timer) - (when (require 'flymake nil t) - (defadvice flymake-on-timer-event (around ac-flymake-stop-advice activate) - (unless ac-completing - ad-do-it))) - (when (require 'flycheck nil t) - (defadvice flycheck-handle-idle-change (around ac-flycheck-stop-advice activate) - (if ac-completing - (setq ac-flycheck-poll-completion-end-timer - (run-at-time ac-flycheck-poll-completion-end-interval - nil - #'flycheck-handle-idle-change)) - ad-do-it)))) - (when (featurep 'flymake) - (ad-disable-advice 'flymake-on-timer-event 'around 'ac-flymake-stop-advice)) - (when (featurep 'flycheck) - (ad-disable-advice 'flycheck-handle-idle-change 'around 'ac-flycheck-stop-advice)))) - -(defun ac-setup () - (if ac-trigger-key - (ac-set-trigger-key ac-trigger-key)) - (if ac-use-comphist - (ac-comphist-init)) - (unless ac-clear-variables-every-minute-timer - (setq ac-clear-variables-every-minute-timer (run-with-timer 60 60 'ac-clear-variables-every-minute))) - (ac-syntax-checker-workaround)) - -;;;###autoload -(define-minor-mode auto-complete-mode - "AutoComplete mode" - :lighter " AC" - :keymap ac-mode-map - :group 'auto-complete - (if auto-complete-mode - (progn - (ac-setup) - (add-hook 'pre-command-hook 'ac-handle-pre-command nil t) - (add-hook 'post-command-hook 'ac-handle-post-command nil t) - (add-hook 'after-save-hook 'ac-clear-variables-after-save nil t) - (run-hooks 'auto-complete-mode-hook)) - (remove-hook 'pre-command-hook 'ac-handle-pre-command t) - (remove-hook 'post-command-hook 'ac-handle-post-command t) - (remove-hook 'after-save-hook 'ac-clear-variables-after-save t) - (ac-abort))) - -(defun auto-complete-mode-maybe () - "What buffer `auto-complete-mode' prefers." - (if (and (not (minibufferp (current-buffer))) - (memq major-mode ac-modes)) - (auto-complete-mode 1))) - -;;;###autoload -(define-global-minor-mode global-auto-complete-mode - auto-complete-mode auto-complete-mode-maybe - :group 'auto-complete) - - - -;;;; Compatibilities with other extensions - -(defun ac-flyspell-workaround () - "Flyspell uses `sit-for' for delaying its process. Unfortunatelly, -it stops auto completion which is trigger with `run-with-idle-timer'. -This workaround avoid flyspell processes when auto completion is being started." - (interactive) - (defadvice flyspell-post-command-hook (around ac-flyspell-workaround activate) - (unless ac-triggered - ad-do-it))) - -(defun ac-linum-workaround () - "linum-mode tries to display the line numbers even for the -completion menu. This workaround stops that annoying behavior." - (interactive) - (defadvice linum-update (around ac-linum-update-workaround activate) - (unless ac-completing - ad-do-it))) - - - -;;;; Standard sources - -(defmacro ac-define-source (name source) - "Source definition macro. It defines a complete command also." - (declare (indent 1)) - `(progn - (defvar ,(intern (format "ac-source-%s" name))) - ;; Use `setq' to reset ac-source-NAME every time - ;; `ac-define-source' is called. This is useful, for example - ;; when evaluating `ac-define-source' using C-M-x (`eval-defun'). - (setq ,(intern (format "ac-source-%s" name)) ,source) - (defun ,(intern (format "ac-complete-%s" name)) () - (interactive) - (auto-complete '(,(intern (format "ac-source-%s" name))))))) - -;; Words in buffer source -(defvar ac-word-index nil) - -(defun ac-candidate-words-in-buffer (point prefix limit) - (let ((i 0) - candidate - candidates - (regexp (concat "\\_<" (regexp-quote prefix) "\\(\\sw\\|\\s_\\)+\\_>"))) - (save-excursion - ;; Search backward - (goto-char point) - (while (and (or (not (integerp limit)) (< i limit)) - (re-search-backward regexp nil t)) - (setq candidate (match-string-no-properties 0)) - (unless (member candidate candidates) - (push candidate candidates) - (cl-incf i))) - ;; Search backward - (goto-char (+ point (length prefix))) - (while (and (or (not (integerp limit)) (< i limit)) - (re-search-forward regexp nil t)) - (setq candidate (match-string-no-properties 0)) - (unless (member candidate candidates) - (push candidate candidates) - (cl-incf i))) - (nreverse candidates)))) - -(defun ac-incremental-update-word-index () - (unless (local-variable-p 'ac-word-index) - (make-local-variable 'ac-word-index)) - (if (null ac-word-index) - (setq ac-word-index (cons nil nil))) - ;; Mark incomplete - (if (car ac-word-index) - (setcar ac-word-index nil)) - (let ((index (cdr ac-word-index)) - (words (ac-candidate-words-in-buffer ac-point ac-prefix (or (and (integerp ac-limit) ac-limit) 10)))) - (dolist (word words) - (unless (member word index) - (push word index) - (setcdr ac-word-index index))))) - -(defun ac-update-word-index-1 () - (unless (local-variable-p 'ac-word-index) - (make-local-variable 'ac-word-index)) - (when (and (not (car ac-word-index)) - (< (buffer-size) 1048576)) - ;; Complete index - (setq ac-word-index - (cons t - (split-string (buffer-substring-no-properties (point-min) (point-max)) - "\\(?:^\\|\\_>\\).*?\\(?:\\_<\\|$\\)"))))) - -(defun ac-update-word-index () - (dolist (buffer (buffer-list)) - (when (or ac-fuzzy-enable - (not (eq buffer (current-buffer)))) - (with-current-buffer buffer - (ac-update-word-index-1))))) - -(defun ac-word-candidates (&optional buffer-pred) - (cl-loop initially (unless ac-fuzzy-enable (ac-incremental-update-word-index)) - for buffer in (buffer-list) - if (and (or (not (integerp ac-limit)) (< (length candidates) ac-limit)) - (if buffer-pred (funcall buffer-pred buffer) t)) - append (funcall ac-match-function - ac-prefix - (and (local-variable-p 'ac-word-index buffer) - (cdr (buffer-local-value 'ac-word-index buffer)))) - into candidates - finally return (delete-dups candidates))) - -(ac-define-source words-in-buffer - '((candidates . ac-word-candidates))) - -(ac-define-source words-in-all-buffer - '((init . ac-update-word-index) - (candidates . ac-word-candidates))) - -(ac-define-source words-in-same-mode-buffers - '((init . ac-update-word-index) - (candidates . (ac-word-candidates - (lambda (buffer) - (derived-mode-p (buffer-local-value 'major-mode buffer))))))) - -;; Lisp symbols source -(defvar ac-symbols-cache nil) -(ac-clear-variable-every-10-minutes 'ac-symbols-cache) - -(defun ac-symbol-file (symbol type) - (if (fboundp 'find-lisp-object-file-name) - (find-lisp-object-file-name symbol type) - (let ((file-name (with-no-warnings - (describe-simplify-lib-file-name - (symbol-file symbol type))))) - (when (equal file-name "loaddefs.el") - ;; Find the real def site of the preloaded object. - (let ((location (condition-case nil - (if (eq type 'defun) - (find-function-search-for-symbol symbol nil - "loaddefs.el") - (find-variable-noselect symbol file-name)) - (error nil)))) - (when location - (with-current-buffer (car location) - (when (cdr location) - (goto-char (cdr location))) - (when (re-search-backward - "^;;; Generated autoloads from \\(.*\\)" nil t) - (setq file-name (match-string 1))))))) - (if (and (null file-name) - (or (eq type 'defun) - (integerp (get symbol 'variable-documentation)))) - ;; It's a object not defined in Elisp but in C. - (if (get-buffer " *DOC*") - (if (eq type 'defun) - (help-C-file-name (symbol-function symbol) 'subr) - (help-C-file-name symbol 'var)) - 'C-source) - file-name)))) - -(defun ac-symbol-documentation (symbol) - (if (stringp symbol) - (setq symbol (intern-soft symbol))) - (ignore-errors - (with-temp-buffer - (let ((standard-output (current-buffer))) - (prin1 symbol) - (princ " is ") - (cond - ((fboundp symbol) - ;; import help-xref-following - (require 'help-mode) - (let ((help-xref-following t) - (major-mode 'help-mode)) ; avoid error in Emacs 24 - (describe-function-1 symbol)) - (buffer-string)) - ((boundp symbol) - (let ((file-name (ac-symbol-file symbol 'defvar))) - (princ "a variable") - (when file-name - (princ " defined in `") - (princ (if (eq file-name 'C-source) - "C source code" - (file-name-nondirectory file-name)))) - (princ "'.\n\n") - (princ (or (documentation-property symbol 'variable-documentation t) - "Not documented.")) - (buffer-string))) - ((facep symbol) - (let ((file-name (ac-symbol-file symbol 'defface))) - (princ "a face") - (when file-name - (princ " defined in `") - (princ (if (eq file-name 'C-source) - "C source code" - (file-name-nondirectory file-name)))) - (princ "'.\n\n") - (princ (or (documentation-property symbol 'face-documentation t) - "Not documented.")) - (buffer-string))) - (t - (let ((doc (documentation-property symbol 'group-documentation t))) - (when doc - (princ "a group.\n\n") - (princ doc) - (buffer-string))))))))) - -(defun ac-symbol-candidates () - (or ac-symbols-cache - (setq ac-symbols-cache - (cl-loop for x being the symbols - if (or (fboundp x) - (boundp x) - (symbol-plist x)) - collect (symbol-name x))))) - -(ac-define-source symbols - '((candidates . ac-symbol-candidates) - (document . ac-symbol-documentation) - (symbol . "s") - (cache))) - -;; Lisp functions source -(defvar ac-functions-cache nil) -(ac-clear-variable-every-10-minutes 'ac-functions-cache) - -(defun ac-function-candidates () - (or ac-functions-cache - (setq ac-functions-cache - (cl-loop for x being the symbols - if (fboundp x) - collect (symbol-name x))))) - -(ac-define-source functions - '((candidates . ac-function-candidates) - (document . ac-symbol-documentation) - (symbol . "f") - (prefix . "(\\(\\(?:\\sw\\|\\s_\\)+\\)") - (cache))) - -;; Lisp variables source -(defvar ac-variables-cache nil) -(ac-clear-variable-every-10-minutes 'ac-variables-cache) - -(defun ac-variable-candidates () - (or ac-variables-cache - (setq ac-variables-cache - (cl-loop for x being the symbols - if (boundp x) - collect (symbol-name x))))) - -(ac-define-source variables - '((candidates . ac-variable-candidates) - (document . ac-symbol-documentation) - (symbol . "v") - (cache))) - -;; Lisp features source -(defvar ac-emacs-lisp-features nil) -(ac-clear-variable-every-10-minutes 'ac-emacs-lisp-features) - -(defun ac-emacs-lisp-feature-candidates () - (or ac-emacs-lisp-features - (if (fboundp 'find-library-suffixes) - (let ((suffix (concat (regexp-opt (find-library-suffixes) t) "\\'"))) - (setq ac-emacs-lisp-features - (append (mapcar 'prin1-to-string features) - (cl-loop for dir in load-path - if (file-directory-p dir) - append (cl-loop for file in (directory-files dir) - if (string-match suffix file) - collect (substring file 0 (match-beginning 0)))))))))) - -(ac-define-source features - '((depends find-func) - (candidates . ac-emacs-lisp-feature-candidates) - (prefix . "require +'\\(\\(?:\\sw\\|\\s_\\)*\\)") - (requires . 0))) - -(defvaralias 'ac-source-emacs-lisp-features 'ac-source-features) - -;; Abbrev source -(ac-define-source abbrev - '((candidates . (mapcar 'popup-x-to-string (append (vconcat local-abbrev-table global-abbrev-table) nil))) - (action . expand-abbrev) - (symbol . "a") - (cache))) - -;; Files in current directory source -(ac-define-source files-in-current-dir - '((candidates . (directory-files default-directory)) - (cache))) - -;; Filename source -(defvar ac-filename-cache nil) - -(defun ac-filename-candidate () - (let (file-name-handler-alist) - (unless (or (and comment-start-skip - (string-match comment-start-skip ac-prefix)) - (file-regular-p ac-prefix)) - (ignore-errors - (cl-loop with dir = (file-name-directory ac-prefix) - with files = (or (assoc-default dir ac-filename-cache) - (let ((files (directory-files dir nil "^[^.]"))) - (push (cons dir files) ac-filename-cache) - files)) - for file in files - for path = (concat dir file) - collect (if (file-directory-p path) - (concat path "/") - path)))))) - -(ac-define-source filename - '((init . (setq ac-filename-cache nil)) - (candidates . ac-filename-candidate) - (prefix . valid-file) - (requires . 0) - (action . ac-start) - (limit . nil))) - -;; Dictionary source -(ac-define-source dictionary - '((candidates . ac-buffer-dictionary) - (symbol . "d"))) - -(provide 'auto-complete) -;;; auto-complete.el ends here diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/python-mode b/emacs.d/elpa/auto-complete-20150618.1949/dict/python-mode deleted file mode 100644 index 4d7b706..0000000 --- a/emacs.d/elpa/auto-complete-20150618.1949/dict/python-mode +++ /dev/null @@ -1,380 +0,0 @@ -ArithmeticError -AssertionError -AttributeError -BaseException -BufferError -BytesWarning -DeprecationWarning -EOFError -Ellipsis -EnvironmentError -Exception -False -FloatingPointError -FutureWarning -GeneratorExit -IOError -ImportError -ImportWarning -IndentationError -IndexError -KeyError -KeyboardInterrupt -LookupError -MemoryError -NameError -None -NotImplemented -NotImplementedError -OSError -OverflowError -PendingDeprecationWarning -ReferenceError -RuntimeError -RuntimeWarning -StandardError -StopIteration -SyntaxError -SyntaxWarning -SystemError -SystemExit -TabError -True -TypeError -UnboundLocalError -UnicodeDecodeError -UnicodeEncodeError -UnicodeError -UnicodeTranslateError -UnicodeWarning -UserWarning -ValueError -Warning -ZeroDivisionError -__builtins__ -__debug__ -__doc__ -__file__ -__future__ -__import__ -__init__ -__main__ -__name__ -__package__ -_dummy_thread -_thread -abc -abs -aifc -all -and -any -apply -argparse -array -as -assert -ast -asynchat -asyncio -asyncore -atexit -audioop -base64 -basestring -bdb -bin -binascii -binhex -bisect -bool -break -buffer -builtins -bytearray -bytes -bz2 -calendar -callable -cgi -cgitb -chr -chuck -class -classmethod -cmath -cmd -cmp -code -codecs -codeop -coerce -collections -colorsys -compile -compileall -complex -concurrent -configparser -contextlib -continue -copy -copyreg -copyright -credits -crypt -csv -ctypes -curses -datetime -dbm -decimal -def -del -delattr -dict -difflib -dir -dis -distutils -divmod -doctest -dummy_threading -elif -else -email -enumerate -ensurepip -enum -enumerat -errno -eval -except -exec -execfile -exit -faulthandler -fcntl -file -filecmp -fileinput -filter -finally -float -fnmatch -for -format -formatter -fpectl -fractions -from -frozenset -ftplib -functools -gc -getattr -getopt -getpass -gettext -glob -global -globals -grp -gzip -hasattr -hash -hashlib -heapq -help -hex -hmac -html -http -id -if -imghdr -imp -impalib -import -importlib -in -input -inspect -int -intern -io -ipaddress -is -isinstance -issubclass -iter -itertools -json -keyword -lambda -len -license -linecache -list -locale -locals -logging -long -lzma -macpath -mailbox -mailcap -map -marshal -math -max -memoryview -mimetypes -min -mmap -modulefinder -msilib -msvcrt -multiprocessing -netrc -next -nis -nntplib -not -numbers -object -oct -open -operator -optparse -or -ord -os -ossaudiodev -parser -pass -pathlib -pdb -pickle -pickletools -pipes -pkgutil -platform -plistlib -poplib -posix -pow -pprint -print -profile -property -pty -pwd -py_compiler -pyclbr -pydoc -queue -quit -quopri -raise -random -range -raw_input -re -readline -reduce -reload -repr -reprlib -resource -return -reversed -rlcompleter -round -runpy -sched -select -selectors -self -set -setattr -shelve -shlex -shutil -signal -site -slice -smtpd -smtplib -sndhdr -socket -socketserver -sorted -spwd -sqlite3 -ssl -stat -staticmethod -statistics -str -string -stringprep -struct -subprocess -sum -sunau -super -symbol -symtable -sys -sysconfig -syslog -tabnanny -tarfile -telnetlib -tempfile -termios -test -textwrap -threading -time -timeit -tkinter -token -tokenize -trace -traceback -tracemalloc -try -tty -tuple -turtle -type -types -unichr -unicode -unicodedata -unittest -urllib -uu -uuid -vars -venv -warnings -wave -weakref -webbrowser -while -winsound -winreg -with -wsgiref -xdrlib -xml -xmlrpc -xrange -yield -zip -zipfile -zipimport -zlib diff --git a/emacs.d/elpa/auto-complete-20160107.8/auto-complete-autoloads.el b/emacs.d/elpa/auto-complete-20160107.8/auto-complete-autoloads.el new file mode 100644 index 0000000..963e0f2 --- /dev/null +++ b/emacs.d/elpa/auto-complete-20160107.8/auto-complete-autoloads.el @@ -0,0 +1,64 @@ +;;; auto-complete-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) + +;;;### (autoloads nil "auto-complete" "auto-complete.el" (22171 46584 +;;;;;; 0 0)) +;;; Generated autoloads from auto-complete.el + +(autoload 'auto-complete "auto-complete" "\ +Start auto-completion at current point. + +\(fn &optional SOURCES)" t nil) + +(autoload 'auto-complete-mode "auto-complete" "\ +AutoComplete mode + +\(fn &optional ARG)" t nil) + +(defvar global-auto-complete-mode nil "\ +Non-nil if Global-Auto-Complete mode is enabled. +See the command `global-auto-complete-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `global-auto-complete-mode'.") + +(custom-autoload 'global-auto-complete-mode "auto-complete" nil) + +(autoload 'global-auto-complete-mode "auto-complete" "\ +Toggle Auto-Complete mode in all buffers. +With prefix ARG, enable Global-Auto-Complete mode if ARG is positive; +otherwise, disable it. If called from Lisp, enable the mode if +ARG is omitted or nil. + +Auto-Complete mode is enabled in all buffers where +`auto-complete-mode-maybe' would do it. +See `auto-complete-mode' for more information on Auto-Complete mode. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads nil "auto-complete-config" "auto-complete-config.el" +;;;;;; (22171 46584 0 0)) +;;; Generated autoloads from auto-complete-config.el + +(autoload 'ac-config-default "auto-complete-config" "\ + + +\(fn)" nil nil) + +;;;*** + +;;;### (autoloads nil nil ("auto-complete-pkg.el") (22171 46584 590372 +;;;;;; 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; auto-complete-autoloads.el ends here diff --git a/emacs.d/elpa/auto-complete-20150618.1949/auto-complete-config.el b/emacs.d/elpa/auto-complete-20160107.8/auto-complete-config.el similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/auto-complete-config.el rename to emacs.d/elpa/auto-complete-20160107.8/auto-complete-config.el diff --git a/emacs.d/elpa/auto-complete-20160107.8/auto-complete-pkg.el b/emacs.d/elpa/auto-complete-20160107.8/auto-complete-pkg.el new file mode 100644 index 0000000..797a9e9 --- /dev/null +++ b/emacs.d/elpa/auto-complete-20160107.8/auto-complete-pkg.el @@ -0,0 +1,6 @@ +(define-package "auto-complete" "20160107.8" "Auto Completion for GNU Emacs" + '((popup "0.5.0") + (cl-lib "0.5"))) +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/emacs.d/elpa/auto-complete-20160107.8/auto-complete.el b/emacs.d/elpa/auto-complete-20160107.8/auto-complete.el new file mode 100644 index 0000000..f497e29 --- /dev/null +++ b/emacs.d/elpa/auto-complete-20160107.8/auto-complete.el @@ -0,0 +1,2163 @@ +;;; auto-complete.el --- Auto Completion for GNU Emacs + +;; Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Tomohiro Matsuyama + +;; Author: Tomohiro Matsuyama +;; URL: https://github.com/auto-complete/auto-complete +;; Keywords: completion, convenience +;; Version: 1.5.0 + +;; 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 . + +;;; Commentary: +;; +;; This extension provides a way to complete with popup menu like: +;; +;; def-!- +;; +-----------------+ +;; |defun::::::::::::| +;; |defvar | +;; |defmacro | +;; | ... | +;; +-----------------+ +;; +;; You can complete by typing and selecting menu. +;; +;; Entire documents are located in doc/ directory. +;; Take a look for information. +;; +;; Enjoy! + +;;; Code: + + + +(defconst ac-version "1.5.0" + "Version of auto-complete in string format. +Use `version-to-list' to get version component.") + +(defconst ac-version-major (car (version-to-list ac-version)) + "Major version number of auto-complete") + +(defconst ac-version-minor (cadr (version-to-list ac-version)) + "Minor version number of auto-complete") + +(require 'cl-lib) +(require 'popup) + +;;;; Global stuff + +(defun ac-error (&optional var) + "Report an error and disable `auto-complete-mode'." + (ignore-errors + (message "auto-complete error: %s" var) + (auto-complete-mode -1) + var)) + + + +;;;; Customization + +(defgroup auto-complete nil + "Auto completion." + :group 'completion + :prefix "ac-") + +(defcustom ac-delay 0.1 + "Delay to completions will be available." + :type 'float + :group 'auto-complete) + +(defcustom ac-auto-show-menu 0.8 + "Non-nil means completion menu will be automatically shown." + :type '(choice (const :tag "Yes" t) + (const :tag "Never" nil) + (float :tag "Timer")) + :group 'auto-complete) + +(defcustom ac-show-menu-immediately-on-auto-complete t + "Non-nil means menu will be showed immediately on `auto-complete'." + :type 'boolean + :group 'auto-complete) + +(defcustom ac-expand-on-auto-complete t + "Non-nil means expand whole common part on first time `auto-complete'." + :type 'boolean + :group 'auto-complete) + +(defcustom ac-disable-faces '(font-lock-comment-face font-lock-string-face font-lock-doc-face) + "Non-nil means disable automatic completion on specified faces." + :type '(repeat symbol) + :group 'auto-complete) + +(defcustom ac-stop-flymake-on-completing t + "Non-nil means disble flymake temporarily on completing." + :type 'boolean + :group 'auto-complete) + +(defcustom ac-flycheck-poll-completion-end-interval 0.5 + "Polling interval to restart automatically flycheck's checking after completion is end." + :type 'float + :group 'auto-complete) + +(defcustom ac-use-fuzzy (and (locate-library "fuzzy") t) + "Non-nil means use fuzzy matching." + :type 'boolean + :group 'auto-complete) + +(defcustom ac-fuzzy-cursor-color "red" + "Cursor color in fuzzy mode." + :type 'string + :group 'auto-complete) + +(defcustom ac-use-comphist t + "Non-nil means use intelligent completion history." + :type 'boolean + :group 'auto-complete) + +(defcustom ac-comphist-threshold 0.7 + "Percentage of ignoring low scored candidates." + :type 'float + :group 'auto-complete) + +(defcustom ac-comphist-file + (expand-file-name (concat (if (boundp 'user-emacs-directory) + user-emacs-directory + "~/.emacs.d/") + "/ac-comphist.dat")) + "Completion history file name." + :type 'string + :group 'auto-complete) + +(defcustom ac-user-dictionary nil + "User defined dictionary" + :type '(repeat string) + :group 'auto-complete) + +(defcustom ac-dictionary-files '("~/.dict") + "Dictionary files." + :type '(repeat string) + :group 'auto-complete) +(defvaralias 'ac-user-dictionary-files 'ac-dictionary-files) + +(defcustom ac-dictionary-directories + (ignore-errors + (when load-file-name + (let ((installed-dir (file-name-directory load-file-name))) + (cl-loop for name in '("ac-dict" "dict") + for dir = (concat installed-dir name) + if (file-directory-p dir) + collect dir)))) + "Dictionary directories." + :type '(repeat string) + :group 'auto-complete) + +(defcustom ac-use-quick-help t + "Non-nil means use quick help." + :type 'boolean + :group 'auto-complete) + +(defcustom ac-quick-help-delay 1.5 + "Delay to show quick help." + :type 'float + :group 'auto-complete) + +(defcustom ac-menu-height 10 + "Max height of candidate menu." + :type 'integer + :group 'auto-complete) +(defvaralias 'ac-candidate-menu-height 'ac-menu-height) + +(defcustom ac-quick-help-height 20 + "Max height of quick help." + :type 'integer + :group 'auto-complete) + +(defcustom ac-quick-help-prefer-pos-tip t + "Prefer native tooltip with pos-tip than overlay popup for displaying quick help." + :type 'boolean + :group 'auto-complete) +(defvaralias 'ac-quick-help-prefer-x 'ac-quick-help-prefer-pos-tip) + +(defcustom ac-candidate-limit nil + "Limit number of candidates. Non-integer means no limit." + :type 'integer + :group 'auto-complete) +(defvaralias 'ac-candidate-max 'ac-candidate-limit) + +(defcustom ac-modes + '(emacs-lisp-mode lisp-mode lisp-interaction-mode + slime-repl-mode + c-mode cc-mode c++-mode go-mode + java-mode malabar-mode clojure-mode clojurescript-mode scala-mode + scheme-mode + ocaml-mode tuareg-mode coq-mode haskell-mode agda-mode agda2-mode + perl-mode cperl-mode python-mode ruby-mode lua-mode tcl-mode + ecmascript-mode javascript-mode js-mode js2-mode php-mode css-mode scss-mode less-css-mode + makefile-mode sh-mode fortran-mode f90-mode ada-mode + xml-mode sgml-mode web-mode + ts-mode + sclang-mode + verilog-mode + qml-mode + apples-mode) + "Major modes `auto-complete-mode' can run on." + :type '(repeat symbol) + :group 'auto-complete) + +(defcustom ac-compatible-packages-regexp + "^ac-" + "Regexp to indicate what packages can work with auto-complete." + :type 'string + :group 'auto-complete) + +(defcustom ac-non-trigger-commands + '(*table--cell-self-insert-command + electric-buffer-list) + "Commands that can't be used as triggers of `auto-complete'." + :type '(repeat symbol) + :group 'auto-complete) + +(defcustom ac-trigger-commands + '(self-insert-command) + "Trigger commands that specify whether `auto-complete' should start or not." + :type '(repeat symbol) + :group 'auto-complete) + +(defcustom ac-trigger-commands-on-completing + '(delete-backward-char + backward-delete-char + backward-delete-char-untabify + ;; autopair + autopair-backspace + ;; paredit + paredit-backward-delete + paredit-backward-delete-word) + "Trigger commands that specify whether `auto-complete' should continue or not." + :type '(repeat symbol) + :group 'auto-complete) + +(defcustom ac-trigger-key nil + "Non-nil means `auto-complete' will start by typing this key. +If you specify this TAB, for example, `auto-complete' will start by typing TAB, +and if there is no completions, an original command will be fallbacked." + :type '(choice (const :tag "None" nil) + (string :tag "Key")) + :group 'auto-complete + :set (lambda (symbol value) + (set-default symbol value) + (when (and value + (fboundp 'ac-set-trigger-key)) + (ac-set-trigger-key value)))) + +(defcustom ac-auto-start 2 + "Non-nil means completion will be started automatically. +Positive integer means if a length of a word you entered is larger than the value, +completion will be started automatically. +If you specify `nil', never be started automatically." + :type '(choice (const :tag "Yes" t) + (const :tag "Never" nil) + (integer :tag "Require")) + :group 'auto-complete) + +(defcustom ac-stop-words nil + "List of string to stop completion." + :type '(repeat string) + :group 'auto-complete) +(defvaralias 'ac-ignores 'ac-stop-words) + +(defcustom ac-use-dictionary-as-stop-words t + "Non-nil means a buffer related dictionary will be thought of as stop words." + :type 'boolean + :group 'auto-complete) + +(defcustom ac-ignore-case 'smart + "Non-nil means auto-complete ignores case. +If this value is `smart', auto-complete ignores case only when +a prefix doesn't contain any upper case letters." + :type '(choice (const :tag "Yes" t) + (const :tag "Smart" smart) + (const :tag "No" nil)) + :group 'auto-complete) + +(defcustom ac-dwim t + "Non-nil means `auto-complete' works based on Do What I Mean." + :type 'boolean + :group 'auto-complete) + +(defcustom ac-use-menu-map nil + "Non-nil means a special keymap `ac-menu-map' on completing menu will be used." + :type 'boolean + :group 'auto-complete) + +(defcustom ac-use-overriding-local-map nil + "Non-nil means `overriding-local-map' will be used to hack for overriding key events on auto-completion." + :type 'boolean + :group 'auto-complete) + +(defcustom ac-disable-inline nil + "Non-nil disable inline completion visibility" + :type 'boolean + :group 'auto-complete) + +(defcustom ac-candidate-menu-min 1 + "Number of candidates required to display menu" + :type 'integer + :group 'auto-complete) + +(defcustom ac-max-width nil + "Maximum width for auto-complete menu to have" + :type '(choice (const :tag "No limit" nil) + (const :tag "Character Limit" 25) + (const :tag "Window Ratio Limit" 0.5)) + :group 'auto-complete) + +(defface ac-completion-face + '((t (:foreground "darkgray" :underline t))) + "Face for inline completion" + :group 'auto-complete) + +(defface ac-candidate-face + '((t (:inherit popup-face))) + "Face for candidate." + :group 'auto-complete) + +(defface ac-candidate-mouse-face + '((t (:inherit popup-menu-mouse-face))) + "Mouse face for candidate." + :group 'auto-complete) + +(defface ac-selection-face + '((t (:inherit popup-menu-selection-face))) + "Face for selected candidate." + :group 'auto-complete) + +(defvar auto-complete-mode-hook nil + "Hook for `auto-complete-mode'.") + + + +;;;; Internal variables + +(defvar auto-complete-mode nil + "Dummy variable to suppress compiler warnings.") + +(defvar ac-cursor-color nil + "Old cursor color.") + +(defvar ac-inline nil + "Inline completion instance.") + +(defvar ac-menu nil + "Menu instance.") + +(defvar ac-show-menu nil + "Flag to show menu on timer tick.") + +(defvar ac-last-completion nil + "Cons of prefix marker and selected item of last completion.") + +(defvar ac-quick-help nil + "Quick help instance") + +(defvar ac-completing nil + "Non-nil means `auto-complete-mode' is now working on completion.") + +(defvar ac-buffer nil + "Buffer where auto-complete is started.") + +(defvar ac-point nil + "Start point of prefix.") + +(defvar ac-last-point nil + "Last point of updating pattern.") + +(defvar ac-prefix nil + "Prefix string.") +(defvaralias 'ac-target 'ac-prefix) + +(defvar ac-selected-candidate nil + "Last selected candidate.") + +(defvar ac-common-part nil + "Common part string of meaningful candidates. +If there is no common part, this will be nil.") + +(defvar ac-whole-common-part nil + "Common part string of whole candidates. +If there is no common part, this will be nil.") + +(defvar ac-prefix-overlay nil + "Overlay for prefix string.") + +(defvar ac-timer nil + "Completion idle timer.") + +(defvar ac-show-menu-timer nil + "Show menu idle timer.") + +(defvar ac-quick-help-timer nil + "Quick help idle timer.") + +(defvar ac-triggered nil + "Flag to update.") + +(defvar ac-limit nil + "Limit number of candidates for each sources.") + +(defvar ac-candidates nil + "Current candidates.") + +(defvar ac-candidates-cache nil + "Candidates cache for individual sources.") + +(defvar ac-fuzzy-enable nil + "Non-nil means fuzzy matching is enabled.") + +(defvar ac-dwim-enable nil + "Non-nil means DWIM completion will be allowed.") + +(defvar ac-mode-map (make-sparse-keymap) + "Auto-complete mode map. It is also used for trigger key command. See also `ac-trigger-key'.") + +(defvar ac-completing-map + (let ((map (make-sparse-keymap))) + (define-key map "\t" 'ac-expand) + (define-key map [tab] 'ac-expand) + (define-key map "\r" 'ac-complete) + (define-key map (kbd "M-TAB") 'auto-complete) + + (define-key map "\M-n" 'ac-next) + (define-key map "\M-p" 'ac-previous) + (define-key map [down] 'ac-next) + (define-key map [up] 'ac-previous) + + (define-key map [f1] 'ac-help) + (define-key map [M-f1] 'ac-persist-help) + (define-key map (kbd "C-?") 'ac-help) + (define-key map (kbd "C-M-?") 'ac-persist-help) + + (define-key map [C-down] 'ac-quick-help-scroll-down) + (define-key map [C-up] 'ac-quick-help-scroll-up) + (define-key map "\C-\M-n" 'ac-quick-help-scroll-down) + (define-key map "\C-\M-p" 'ac-quick-help-scroll-up) + + (dotimes (i 9) + (let ((symbol (intern (format "ac-complete-select-%d" (1+ i))))) + (fset symbol + `(lambda () + (interactive) + (when (and (ac-menu-live-p) (popup-select ac-menu ,i)) + (ac-complete)))) + (define-key map (read-kbd-macro (format "M-%s" (1+ i))) symbol))) + + map) + "Keymap for completion.") +(defvaralias 'ac-complete-mode-map 'ac-completing-map) + +(defvar ac-menu-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map ac-completing-map) + (define-key map (kbd "RET") 'ac-complete) + (define-key map "\C-n" 'ac-next) + (define-key map "\C-p" 'ac-previous) + (define-key map "\C-s" 'ac-isearch) + (define-key map [mouse-1] 'ac-mouse-1) + (define-key map [down-mouse-1] 'ac-ignore) + (define-key map [mouse-4] 'ac-mouse-4) + (define-key map [mouse-5] 'ac-mouse-5) + map) + "Keymap for completion on completing menu.") + +(defvar ac-current-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map ac-completing-map) + map)) + +(defvar ac-match-function 'all-completions + "Default match function.") + +(defvar ac-prefix-definitions + '((symbol . ac-prefix-symbol) + (file . ac-prefix-file) + (valid-file . ac-prefix-valid-file) + (c-dot . ac-prefix-c-dot) + (c-dot-ref . ac-prefix-c-dot-ref) + (cc-member . ac-prefix-cc-member)) + "Prefix definitions for common use.") + +(defvar ac-sources '(ac-source-words-in-same-mode-buffers) + "Sources for completion.") +(make-variable-buffer-local 'ac-sources) + +(defvar ac-compiled-sources nil + "Compiled source of `ac-sources'.") + +(defvar ac-current-sources nil + "Current working sources. This is sublist of `ac-compiled-sources'.") + +(defvar ac-omni-completion-sources nil + "Do not use this anymore.") + +(defvar ac-current-prefix-def nil) + +(defvar ac-ignoring-prefix-def nil) + + + +;;;; Intelligent completion history + +(defvar ac-comphist nil + "Database of completion history.") + +(defsubst ac-comphist-make-tab () + (make-hash-table :test 'equal)) + +(defsubst ac-comphist-tab (db) + (nth 0 db)) + +(defsubst ac-comphist-cache (db) + (nth 1 db)) + +(defun ac-comphist-make (&optional tab) + (list (or tab (ac-comphist-make-tab)) (make-hash-table :test 'equal :weakness t))) + +(defun ac-comphist-get (db string &optional create) + (let* ((tab (ac-comphist-tab db)) + (index (gethash string tab))) + (when (and create (null index)) + (setq index (make-vector (length string) 0)) + (puthash string index tab)) + index)) + +(defun ac-comphist-add (db string prefix) + (setq prefix (min prefix (1- (length string)))) + (when (<= 0 prefix) + (setq string (substring-no-properties string)) + (let ((stat (ac-comphist-get db string t))) + (cl-incf (aref stat prefix)) + (remhash string (ac-comphist-cache db))))) + +(defun ac-comphist-score (db string prefix) + (setq prefix (min prefix (1- (length string)))) + (if (<= 0 prefix) + (let ((cache (gethash string (ac-comphist-cache db)))) + (or (and cache (aref cache prefix)) + (let ((stat (ac-comphist-get db string)) + (score 0.0)) + (when stat + (cl-loop for p from 0 below (length string) + ;; sigmoid function + with a = 5 + with b = (/ 700.0 a) ; bounds for avoiding range error in `exp' + with d = (/ 6.0 a) + for x = (max (- b) (min b (- d (abs (- prefix p))))) + for r = (/ 1.0 (1+ (exp (* (- a) x)))) + do + (cl-incf score (* (aref stat p) r)))) + ;; Weight by distance + (cl-incf score (max 0.0 (- 0.3 (/ (- (length string) prefix) 100.0)))) + (unless cache + (setq cache (make-vector (length string) nil)) + (puthash string cache (ac-comphist-cache db))) + (aset cache prefix score) + score))) + 0.0)) + +(defun ac-comphist-sort (db collection prefix &optional threshold) + (let (result + (n 0) + (total 0) + (cur 0)) + (setq result (mapcar (lambda (a) + (when (and cur threshold) + (if (>= cur (* total threshold)) + (setq cur nil) + (cl-incf n) + (cl-incf cur (cdr a)))) + (car a)) + (sort (mapcar (lambda (string) + (let ((score (ac-comphist-score db string prefix))) + (cl-incf total score) + (cons string score))) + collection) + (lambda (a b) (< (cdr b) (cdr a)))))) + (if threshold + (cons n result) + result))) + +(defun ac-comphist-serialize (db) + (let (alist) + (maphash (lambda (k v) + (push (cons k v) alist)) + (ac-comphist-tab db)) + (list alist))) + +(defun ac-comphist-deserialize (sexp) + (condition-case nil + (ac-comphist-make (let ((tab (ac-comphist-make-tab))) + (mapc (lambda (cons) + (puthash (car cons) (cdr cons) tab)) + (nth 0 sexp)) + tab)) + (error (message "Invalid comphist db.") nil))) + +(defun ac-comphist-init () + (ac-comphist-load) + (add-hook 'kill-emacs-hook 'ac-comphist-save)) + +(defun ac-comphist-load () + (interactive) + (let ((db (if (file-exists-p ac-comphist-file) + (ignore-errors + (with-temp-buffer + (insert-file-contents ac-comphist-file) + (goto-char (point-min)) + (ac-comphist-deserialize (read (current-buffer)))))))) + (setq ac-comphist (or db (ac-comphist-make))))) + +(defun ac-comphist-save () + (interactive) + (require 'pp) + (ignore-errors + (with-temp-buffer + (pp (ac-comphist-serialize ac-comphist) (current-buffer)) + (write-region (point-min) (point-max) ac-comphist-file)))) + + + +;;;; Dictionary +(defvar ac-buffer-dictionary nil) +(defvar ac-file-dictionary (make-hash-table :test 'equal)) + +(defun ac-clear-dictionary-cache () + (interactive) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (if (local-variable-p 'ac-buffer-dictionary) + (kill-local-variable 'ac-buffer-dictionary)))) + (clrhash ac-file-dictionary)) + +(defun ac-file-dictionary (filename) + (let ((cache (gethash filename ac-file-dictionary 'none))) + (if (and cache (not (eq cache 'none))) + cache + (let (result) + (ignore-errors + (with-temp-buffer + (insert-file-contents filename) + (setq result (split-string (buffer-string) "\n" t)))) + (puthash filename result ac-file-dictionary) + result)))) + +(defun ac-mode-dictionary (mode) + (cl-loop for name in (cons (symbol-name mode) + (ignore-errors (list (file-name-extension (buffer-file-name))))) + append (cl-loop for dir in ac-dictionary-directories + for file = (concat dir "/" name) + if (file-exists-p file) + append (ac-file-dictionary file)))) + +(defun ac-buffer-dictionary (&optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (if (local-variable-p 'ac-buffer-dictionary) + ac-buffer-dictionary + (make-local-variable 'ac-buffer-dictionary) + (setq ac-buffer-dictionary + (apply 'append + ac-user-dictionary + (ac-mode-dictionary major-mode) + (mapcar 'ac-file-dictionary ac-dictionary-files)))))) + + + +;;;; Auto completion internals + +(defun ac-menu-at-wrapper-line-p () + "Return non-nil if current line is long and wrapped to next visual line." + (and (not truncate-lines) + (eq (line-beginning-position) + (save-excursion + (vertical-motion 1) + (line-beginning-position))))) + +(defun ac-stop-word-p (word) + (or (member word ac-stop-words) + (if ac-use-dictionary-as-stop-words + (member word (ac-buffer-dictionary))))) + +(defun ac-prefix-default () + "Same as `ac-prefix-symbol' but ignore a number prefix." + (let ((start (ac-prefix-symbol))) + (when start + (cl-loop with end = (point) + for pos from start below end + for c = (char-after pos) + if (not (and (<= ?0 c) (<= c ?9))) + return start)))) + +(defun ac-prefix-symbol () + "Default prefix definition function." + (require 'thingatpt) + (car-safe (bounds-of-thing-at-point 'symbol))) + +(defun ac-prefix-file () + "File prefix." + (let ((point (re-search-backward "[\"<>' \t\r\n]" nil t))) + (if point (1+ point)))) + +(defsubst ac-windows-remote-file-p (file) + (and (memq system-type '(ms-dos windows-nt cygwin)) + (string-match-p "\\`\\(?://\\|\\\\\\\\\\)" file))) + +(defun ac-prefix-valid-file () + "Existed (or to be existed) file prefix." + (let* ((line-beg (line-beginning-position)) + (end (point)) + (start (or (let ((point (re-search-backward "[\"<>'= \t\r\n]" line-beg t))) + (if point (1+ point))) + line-beg)) + (file (buffer-substring start end))) + (if (and file (or (string-match "^/" file) + (and (setq file (and (string-match "^[^/]*/" file) + (match-string 0 file))) + (file-directory-p file)))) + (unless (ac-windows-remote-file-p file) + start)))) + +(defun ac-prefix-c-dot () + "C-like languages dot(.) prefix." + (if (re-search-backward "\\.\\(\\(?:[a-zA-Z0-9][_a-zA-Z0-9]*\\)?\\)\\=" nil t) + (match-beginning 1))) + +(defun ac-prefix-c-dot-ref () + "C-like languages dot(.) and reference(->) prefix." + (if (re-search-backward "\\(?:\\.\\|->\\)\\(\\(?:[a-zA-Z0-9][_a-zA-Z0-9]*\\)?\\)\\=" nil t) + (match-beginning 1))) + +(defun ac-prefix-cc-member () + "C-like languages member(.)(->)(::) prefix." + (when (re-search-backward "\\(?:\\.\\|->\\|::\\)\\(\\(?:[a-zA-Z0-9][_a-zA-Z0-9]*\\)?\\)\\=" nil t) + (match-beginning 1))) + +(defun ac-define-prefix (name prefix) + "Define new prefix definition. +You can not use it in source definition like (prefix . `NAME')." + (push (cons name prefix) ac-prefix-definitions)) + +(defun ac-match-substring (prefix candidates) + (cl-loop with regexp = (regexp-quote prefix) + for candidate in candidates + if (string-match regexp candidate) + collect candidate)) + +(defsubst ac-source-entity (source) + (if (symbolp source) + (symbol-value source) + source)) + +(defun ac-source-available-p (source) + (if (and (symbolp source) + (get source 'available)) + (eq (get source 'available) t) + (let* ((src (ac-source-entity source)) + (avail-pair (assq 'available src)) + (avail-cond (cdr avail-pair)) + (available (and (if avail-pair + (cond + ((symbolp avail-cond) + (funcall avail-cond)) + ((listp avail-cond) + (eval avail-cond))) + t) + (cl-loop for feature in (assoc-default 'depends src) + unless (require feature nil t) return nil + finally return t)))) + (if (symbolp source) + (put source 'available (if available t 'no))) + available))) + +(defun ac-compile-sources (sources) + "Compiled `SOURCES' into expanded sources style." + (cl-loop for source in sources + if (ac-source-available-p source) + do + (setq source (ac-source-entity source)) + ;; prefix + (let* ((prefix (assoc 'prefix source)) + (real (assoc-default (cdr prefix) ac-prefix-definitions))) + (cond + (real + (add-to-list 'source (cons 'prefix real))) + ((null prefix) + (add-to-list 'source (cons 'prefix 'ac-prefix-default))))) + ;; match + (let ((match (assq 'match source))) + (cond + ((eq (cdr match) 'substring) + (setcdr match 'ac-match-substring)))) + and collect source)) + +(defun ac-compiled-sources () + (or ac-compiled-sources + (setq ac-compiled-sources + (ac-compile-sources ac-sources)))) + +(defsubst ac-menu-live-p () + (popup-live-p ac-menu)) + +(defun ac-menu-create (point width height) + (setq ac-menu + (popup-create point width height + :around t + :face 'ac-candidate-face + :max-width ac-max-width + :mouse-face 'ac-candidate-mouse-face + :selection-face 'ac-selection-face + :symbol t + :scroll-bar t + :margin-left 1 + :keymap ac-menu-map + ))) + +(defun ac-menu-delete () + (when ac-menu + (popup-delete ac-menu) + (setq ac-menu nil))) + +(defsubst ac-inline-overlay () + (nth 0 ac-inline)) + +(defsubst ac-inline-live-p () + (and ac-inline (ac-inline-overlay) t)) + +(defun ac-inline-show (point string) + (unless ac-inline + (setq ac-inline (list nil))) + (save-excursion + (let ((overlay (ac-inline-overlay)) + (width 0) + (string-width (string-width string)) + (length 0) + (original-string string)) + ;; Calculate string space to show completion + (goto-char point) + (let (c) + (while (and (not (eolp)) + (< width string-width) + (setq c (char-after)) + (not (eq c ?\t))) ; special case for tab + (cl-incf width (char-width c)) + (cl-incf length) + (forward-char))) + + ;; Show completion + (goto-char point) + (cond + ((= width 0) + ;; End-of-line + ;; Do nothing + ) + ((<= width string-width) + ;; No space to show + ;; Do nothing + ) + ((> width string-width) + ;; Need to fill space + (setq string (concat string (make-string (- width string-width) ? ))))) + (setq string (propertize string 'face 'ac-completion-face)) + (if overlay + (progn + (move-overlay overlay point (+ point length)) + (overlay-put overlay 'invisible nil)) + (setq overlay (make-overlay point (+ point length))) + (setf (nth 0 ac-inline) overlay) + (overlay-put overlay 'priority 9999) + ;; Help prefix-overlay in some cases + (overlay-put overlay 'keymap ac-current-map)) + ;; TODO no width but char + (if (eq length 0) + ;; Case: End-of-line + (progn + (put-text-property 0 1 'cursor t string) + (overlay-put overlay 'after-string string)) + (let ((display (substring string 0 1)) + (after-string (substring string 1))) + (overlay-put overlay 'display display) + (overlay-put overlay 'after-string after-string))) + (overlay-put overlay 'string original-string)))) + +(defun ac-inline-delete () + (when (ac-inline-live-p) + (ac-inline-hide) + (delete-overlay (ac-inline-overlay)) + (setq ac-inline nil))) + +(defun ac-inline-hide () + (when (ac-inline-live-p) + (let ((overlay (ac-inline-overlay)) + (buffer-undo-list t)) + (when overlay + (move-overlay overlay (point-min) (point-min)) + (overlay-put overlay 'invisible t) + (overlay-put overlay 'display nil) + (overlay-put overlay 'after-string nil))))) + +(defun ac-inline-update () + (if (and ac-completing ac-prefix (stringp ac-common-part)) + (let ((common-part-length (length ac-common-part)) + (prefix-length (length ac-prefix))) + (if (> common-part-length prefix-length) + (progn + (ac-inline-hide) + (ac-inline-show (point) (substring ac-common-part prefix-length))) + (ac-inline-delete))) + (ac-inline-delete))) + +(defun ac-put-prefix-overlay () + (unless ac-prefix-overlay + (let (newline) + ;; Insert newline to make sure that cursor always on the overlay + (when (eobp) + (popup-save-buffer-state + (insert "\n")) + (setq newline t)) + (setq ac-prefix-overlay (make-overlay ac-point (1+ (point)) nil t t)) + (overlay-put ac-prefix-overlay 'priority 9999) + (overlay-put ac-prefix-overlay 'keymap (make-sparse-keymap)) + (overlay-put ac-prefix-overlay 'newline newline)))) + +(defun ac-remove-prefix-overlay () + (when ac-prefix-overlay + (when (overlay-get ac-prefix-overlay 'newline) + ;; Remove inserted newline + (popup-save-buffer-state + (goto-char (point-max)) + (if (eq (char-before) ?\n) + (delete-char -1)))) + (delete-overlay ac-prefix-overlay))) + +(defun ac-activate-completing-map () + (if (and ac-show-menu ac-use-menu-map) + (set-keymap-parent ac-current-map ac-menu-map)) + (when (and ac-use-overriding-local-map + (null overriding-terminal-local-map)) + (setq overriding-terminal-local-map ac-current-map)) + (when ac-prefix-overlay + (set-keymap-parent (overlay-get ac-prefix-overlay 'keymap) ac-current-map))) + +(defun ac-deactivate-completing-map () + (set-keymap-parent ac-current-map ac-completing-map) + (when (and ac-use-overriding-local-map + (eq overriding-terminal-local-map ac-current-map)) + (setq overriding-terminal-local-map nil)) + (when ac-prefix-overlay + (set-keymap-parent (overlay-get ac-prefix-overlay 'keymap) nil))) + +(defsubst ac-selected-candidate () + (if ac-menu + (popup-selected-item ac-menu))) + +(defun ac-prefix (requires ignore-list) + (cl-loop with current = (point) + with point + with point-def + with prefix-def + with sources + for source in (ac-compiled-sources) + for prefix = (assoc-default 'prefix source) + for req = (or (assoc-default 'requires source) requires 1) + + do + (unless (member prefix ignore-list) + (save-excursion + (setq point (cond + ((symbolp prefix) + (funcall prefix)) + ((stringp prefix) + (and (re-search-backward (concat prefix "\\=") nil t) + (or (match-beginning 1) (match-beginning 0)))) + ((stringp (car-safe prefix)) + (let ((regexp (nth 0 prefix)) + (end (nth 1 prefix)) + (group (nth 2 prefix))) + (and (re-search-backward (concat regexp "\\=") nil t) + (funcall (if end 'match-end 'match-beginning) + (or group 0))))) + (t + (eval prefix)))) + (if (and point + (integerp req) + (< (- current point) req)) + (setq point nil)) + (when point + (if (null prefix-def) + (setq prefix-def prefix + point-def point)) + (if (equal point point-def) + (push source sources))))) + + finally return + (and point-def (list prefix-def point-def (nreverse sources))))) + +(defun ac-init () + "Initialize current sources to start completion." + (setq ac-candidates-cache nil) + (cl-loop for source in ac-current-sources + for function = (assoc-default 'init source) + if function do + (save-excursion + (cond + ((functionp function) + (funcall function)) + (t + (eval function)))))) + +(defun ac-candidates-1 (source) + (let* ((do-cache (assq 'cache source)) + (function (assoc-default 'candidates source)) + (action (assoc-default 'action source)) + (document (assoc-default 'document source)) + (symbol (assoc-default 'symbol source)) + (ac-limit (or (assoc-default 'limit source) ac-limit)) + (face (or (assoc-default 'face source) (assoc-default 'candidate-face source))) + (selection-face (assoc-default 'selection-face source)) + (cache (and do-cache (assq source ac-candidates-cache))) + (candidates (cdr cache))) + (unless cache + (setq candidates (save-excursion + (cond + ((functionp function) + (funcall function)) + (t + (eval function))))) + ;; Convert (name value) format candidates into name with text properties. + (setq candidates (mapcar (lambda (candidate) + (if (consp candidate) + (propertize (car candidate) 'value (cdr candidate)) + candidate)) + candidates)) + (when do-cache + (push (cons source candidates) ac-candidates-cache))) + (setq candidates (funcall (or (assoc-default 'match source) + ac-match-function) + ac-prefix candidates)) + ;; Remove extra items regarding to ac-limit + (if (and (integerp ac-limit) (> ac-limit 1) (> (length candidates) ac-limit)) + (setcdr (nthcdr (1- ac-limit) candidates) nil)) + ;; Put candidate properties + (setq candidates (mapcar (lambda (candidate) + (popup-item-propertize candidate + 'action action + 'symbol symbol + 'document document + 'popup-face face + 'selection-face selection-face)) + candidates)) + candidates)) + +(defun ac-delete-duplicated-candidates (candidates) + (cl-delete-duplicates + candidates + :test (lambda (x y) + ;; We assume two candidates are same if their titles are + ;; equal and their actions are equal. + (and (equal x y) + (eq (popup-item-property x 'action) + (popup-item-property y 'action)))) + :from-end t)) + +(defun ac-reduce-candidates (candidates) + ;; Call `ac-delete-duplicated-candidates' on first portion of + ;; candidate list for speed. + (let ((size 20)) + (if (< (length candidates) size) + (ac-delete-duplicated-candidates candidates) + (cl-loop for c on candidates by 'cdr + repeat (1- size) + finally return + (let ((rest (cdr c))) + (setcdr c nil) + (append (ac-delete-duplicated-candidates candidates) (copy-sequence rest))))))) + +(defun ac-candidates () + "Produce candidates for current sources." + (cl-loop with completion-ignore-case = (or (eq ac-ignore-case t) + (and (eq ac-ignore-case 'smart) + (let ((case-fold-search nil)) (not (string-match "[[:upper:]]" ac-prefix))))) + with case-fold-search = completion-ignore-case + with prefix-len = (length ac-prefix) + for source in ac-current-sources + append (ac-candidates-1 source) into candidates + finally return + (progn + (if (and ac-use-comphist ac-comphist) + (if ac-show-menu + (let* ((pair (ac-comphist-sort ac-comphist candidates prefix-len ac-comphist-threshold)) + (n (car pair)) + (result (ac-reduce-candidates (cdr pair))) + (cons (if (> n 0) (nthcdr (1- n) result))) + (cdr (cdr cons))) + ;; XXX ugly + (if cons (setcdr cons nil)) + (setq ac-common-part (try-completion ac-prefix result)) + (setq ac-whole-common-part (try-completion ac-prefix candidates)) + (if cons (setcdr cons cdr)) + result) + (setq candidates (ac-comphist-sort ac-comphist candidates prefix-len)) + (setq ac-common-part (if candidates (popup-x-to-string (car candidates)))) + (setq ac-whole-common-part (try-completion ac-prefix candidates)) + candidates) + (when ac-show-menu + (setq candidates (ac-reduce-candidates candidates))) + (setq ac-common-part (try-completion ac-prefix candidates)) + (setq ac-whole-common-part ac-common-part) + candidates)))) + +(defun ac-update-candidates (cursor scroll-top) + "Update candidates of menu to `ac-candidates' and redraw it." + (setf (popup-cursor ac-menu) cursor + (popup-scroll-top ac-menu) scroll-top) + (setq ac-dwim-enable (= (length ac-candidates) 1)) + (if ac-candidates + (progn + (setq ac-completing t) + (ac-activate-completing-map)) + (setq ac-completing nil) + (ac-deactivate-completing-map)) + (unless ac-disable-inline + (ac-inline-update)) + (popup-set-list ac-menu ac-candidates) + (if (and (not ac-fuzzy-enable) + (<= (length ac-candidates) ac-candidate-menu-min)) + (popup-hide ac-menu) + (if ac-show-menu + (popup-draw ac-menu)))) + +(defun ac-reposition () + "Force to redraw candidate menu with current `ac-candidates'." + (let ((cursor (popup-cursor ac-menu)) + (scroll-top (popup-scroll-top ac-menu)) + (height (popup-height ac-menu))) + (ac-menu-delete) + (ac-menu-create ac-point (popup-preferred-width ac-candidates) height) + (ac-update-candidates cursor scroll-top))) + +(defun ac-cleanup () + "Cleanup auto completion." + (if ac-cursor-color + (set-cursor-color ac-cursor-color)) + (when (and ac-use-comphist ac-comphist) + (when (and (null ac-selected-candidate) + (member ac-prefix ac-candidates)) + ;; Assume candidate is selected by just typing + (setq ac-selected-candidate ac-prefix) + (setq ac-last-point ac-point)) + (when ac-selected-candidate + (ac-comphist-add ac-comphist + ac-selected-candidate + (if ac-last-point + (- ac-last-point ac-point) + (length ac-prefix))))) + (ac-deactivate-completing-map) + (ac-remove-prefix-overlay) + (ac-remove-quick-help) + (ac-inline-delete) + (ac-menu-delete) + (ac-cancel-timer) + (ac-cancel-show-menu-timer) + (ac-cancel-quick-help-timer) + (setq ac-cursor-color nil + ac-inline nil + ac-show-menu nil + ac-menu nil + ac-completing nil + ac-point nil + ac-last-point nil + ac-prefix nil + ac-prefix-overlay nil + ac-selected-candidate nil + ac-common-part nil + ac-whole-common-part nil + ac-triggered nil + ac-limit nil + ac-candidates nil + ac-candidates-cache nil + ac-fuzzy-enable nil + ac-dwim-enable nil + ac-compiled-sources nil + ac-current-sources nil + ac-current-prefix-def nil + ac-ignoring-prefix-def nil)) + +(defsubst ac-abort () + "Abort completion." + (ac-cleanup)) + +(defun ac-extend-region-to-delete (string) + "Determine the boundary of the region to delete before +inserting the completed string. This will be either the position +of current point, or the end of the symbol at point, if the text +from point to end of symbol is the right part of the completed +string." + (let* ((end-of-symbol (or (cdr-safe (bounds-of-thing-at-point 'symbol)) + (point))) + (remaindar (buffer-substring-no-properties (point) end-of-symbol)) + (remaindar-length (length remaindar))) + (if (and (>= (length string) remaindar-length) + (string= (substring-no-properties string (- remaindar-length)) + remaindar)) + end-of-symbol + (point)))) + +(defun ac-expand-string (string &optional remove-undo-boundary) + "Expand `STRING' into the buffer and update `ac-prefix' to `STRING'. +This function records deletion and insertion sequences by `undo-boundary'. +If `remove-undo-boundary' is non-nil, this function also removes `undo-boundary' +that have been made before in this function. When `buffer-undo-list' is +`t', `remove-undo-boundary' has no effect." + (when (eq buffer-undo-list t) + (setq remove-undo-boundary nil)) + (when (not (equal string (buffer-substring ac-point (point)))) + (undo-boundary) + ;; We can't use primitive-undo since it undoes by + ;; groups, divided by boundaries. + ;; We don't want boundary between deletion and insertion. + ;; So do it manually. + ;; Delete region silently for undo: + (if remove-undo-boundary + (progn + (let (buffer-undo-list) + (save-excursion + (delete-region ac-point (ac-extend-region-to-delete string)))) + (setq buffer-undo-list + (nthcdr 2 buffer-undo-list))) + (delete-region ac-point (ac-extend-region-to-delete string))) + (insert (substring-no-properties string)) + ;; Sometimes, possible when omni-completion used, (insert) added + ;; to buffer-undo-list strange record about position changes. + ;; Delete it here: + (when (and remove-undo-boundary + (integerp (cadr buffer-undo-list))) + (setcdr buffer-undo-list (nthcdr 2 buffer-undo-list))) + (undo-boundary) + (setq ac-selected-candidate string) + (setq ac-prefix string))) + +(defun ac-set-trigger-key (key) + "Set `ac-trigger-key' to `KEY'. It is recommemded to use this function instead of calling `setq'." + ;; Remove old mapping + (when ac-trigger-key + (define-key ac-mode-map (read-kbd-macro ac-trigger-key) nil)) + + ;; Make new mapping + (setq ac-trigger-key key) + (when key + (define-key ac-mode-map (read-kbd-macro key) 'ac-trigger-key-command))) + +(defun ac-set-timer () + (unless ac-timer + (setq ac-timer (run-with-idle-timer ac-delay ac-delay 'ac-update-greedy)))) + +(defun ac-cancel-timer () + (when (timerp ac-timer) + (cancel-timer ac-timer) + (setq ac-timer nil))) + +(defun ac-update (&optional force) + (when (and auto-complete-mode + ac-prefix + (or ac-triggered + force) + (not isearch-mode)) + (ac-put-prefix-overlay) + (setq ac-candidates (ac-candidates)) + (let ((preferred-width (popup-preferred-width ac-candidates))) + ;; Reposition if needed + (when (or (null ac-menu) + (>= (popup-width ac-menu) preferred-width) + (<= (popup-width ac-menu) (- preferred-width 10)) + (and (> (popup-direction ac-menu) 0) + (ac-menu-at-wrapper-line-p))) + (ac-inline-hide) ; Hide overlay to calculate correct column + (ac-remove-quick-help) + (ac-menu-delete) + (ac-menu-create ac-point preferred-width ac-menu-height))) + (ac-update-candidates 0 0) + t)) + +(defun ac-update-greedy (&optional force) + (let (result) + (while (when (and (setq result (ac-update force)) + (null ac-candidates)) + (add-to-list 'ac-ignoring-prefix-def ac-current-prefix-def) + (ac-start :force-init t) + ac-current-prefix-def)) + result)) + +(defun ac-set-show-menu-timer () + (when (and (or (integerp ac-auto-show-menu) (floatp ac-auto-show-menu)) + (null ac-show-menu-timer)) + (setq ac-show-menu-timer (run-with-idle-timer ac-auto-show-menu ac-auto-show-menu 'ac-show-menu)))) + +(defun ac-cancel-show-menu-timer () + (when (timerp ac-show-menu-timer) + (cancel-timer ac-show-menu-timer) + (setq ac-show-menu-timer nil))) + +(defun ac-show-menu () + (when (not (eq ac-show-menu t)) + (setq ac-show-menu t) + (ac-inline-hide) + (ac-remove-quick-help) + (ac-update t))) + +(defun ac-help (&optional persist) + (interactive "P") + (when ac-menu + (popup-menu-show-help ac-menu persist))) + +(defun ac-persist-help () + (interactive) + (ac-help t)) + +(defun ac-last-help (&optional persist) + (interactive "P") + (when ac-last-completion + (popup-item-show-help (cdr ac-last-completion) persist))) + +(defun ac-last-persist-help () + (interactive) + (ac-last-help t)) + +(defun ac-set-quick-help-timer () + (when (and ac-use-quick-help + (null ac-quick-help-timer)) + (setq ac-quick-help-timer (run-with-idle-timer ac-quick-help-delay ac-quick-help-delay 'ac-quick-help)))) + +(defun ac-cancel-quick-help-timer () + (when (timerp ac-quick-help-timer) + (cancel-timer ac-quick-help-timer) + (setq ac-quick-help-timer nil))) + +(defun ac-pos-tip-show-quick-help (menu &optional item &rest args) + (let* ((point (plist-get args :point)) + (around nil) + (parent-offset (popup-offset menu)) + (doc (popup-menu-documentation menu item))) + (when (stringp doc) + (if (popup-hidden-p menu) + (setq around t) + (setq point nil)) + (with-no-warnings + (pos-tip-show doc + 'popup-tip-face + (or point + (and menu + (popup-child-point menu parent-offset)) + (point)) + nil 300 + popup-tip-max-width + nil nil + (and (not around) 0)) + (unless (plist-get args :nowait) + (clear-this-command-keys) + (unwind-protect + (push (read-event (plist-get args :prompt)) unread-command-events) + (pos-tip-hide)) + t))))) + +(defun ac-quick-help-use-pos-tip-p () + (and ac-quick-help-prefer-pos-tip + window-system + (featurep 'pos-tip))) + +(defun ac-quick-help (&optional force) + (interactive) + ;; TODO don't use FORCE + (when (and (or force + (with-no-warnings + ;; called-interactively-p can take no args + (called-interactively-p)) + ;; ac-isearch'ing + (null this-command)) + (ac-menu-live-p) + (null ac-quick-help)) + (setq ac-quick-help + (funcall (if (ac-quick-help-use-pos-tip-p) + 'ac-pos-tip-show-quick-help + 'popup-menu-show-quick-help) + ac-menu nil + :point ac-point + :height ac-quick-help-height + :nowait t)))) + +(defun ac-remove-quick-help () + (when (ac-quick-help-use-pos-tip-p) + (with-no-warnings + (pos-tip-hide))) + (when ac-quick-help + (popup-delete ac-quick-help) + (setq ac-quick-help nil))) + +(defun ac-last-quick-help () + (interactive) + (when (and ac-last-completion + (eq (marker-buffer (car ac-last-completion)) + (current-buffer))) + (let ((doc (popup-item-documentation (cdr ac-last-completion))) + (point (marker-position (car ac-last-completion)))) + (when (stringp doc) + (if (ac-quick-help-use-pos-tip-p) + (with-no-warnings (pos-tip-show doc nil point nil 300)) + (popup-tip doc + :point point + :around t + :scroll-bar t + :margin t)))))) + +(defmacro ac-define-quick-help-command (name arglist &rest body) + (declare (indent 2)) + `(progn + (defun ,name ,arglist ,@body) + (put ',name 'ac-quick-help-command t))) + +(ac-define-quick-help-command ac-quick-help-scroll-down () + (interactive) + (when ac-quick-help + (popup-scroll-down ac-quick-help))) + +(ac-define-quick-help-command ac-quick-help-scroll-up () + (interactive) + (when ac-quick-help + (popup-scroll-up ac-quick-help))) + + + +;;;; Auto completion isearch + +(defun ac-isearch-callback (list) + (setq ac-dwim-enable (eq (length list) 1))) + +(defun ac-isearch () + (interactive) + (when (ac-menu-live-p) + (ac-cancel-show-menu-timer) + (ac-show-menu) + (if ac-use-quick-help + (let ((popup-menu-show-quick-help-function + (if (ac-quick-help-use-pos-tip-p) + 'ac-pos-tip-show-quick-help + 'popup-menu-show-quick-help))) + (popup-isearch ac-menu + :callback 'ac-isearch-callback + :help-delay ac-quick-help-delay)) + (popup-isearch ac-menu :callback 'ac-isearch-callback)))) + + + +;;;; Auto completion commands + +(cl-defun auto-complete-1 (&key sources (triggered 'command)) + (let ((menu-live (ac-menu-live-p)) + (inline-live (ac-inline-live-p)) + started) + (ac-abort) + (let ((ac-sources (or sources ac-sources))) + (if (or ac-show-menu-immediately-on-auto-complete + inline-live) + (setq ac-show-menu t)) + (setq started (ac-start :triggered triggered))) + (when (ac-update-greedy t) + ;; TODO Not to cause inline completion to be disrupted. + (if (ac-inline-live-p) + (ac-inline-hide)) + ;; Not to expand when it is first time to complete + (when (and (or (and (not ac-expand-on-auto-complete) + (> (length ac-candidates) 1) + (not menu-live)) + (not (let ((ac-common-part ac-whole-common-part)) + (ac-expand-common)))) + ac-use-fuzzy + (null ac-candidates)) + (ac-fuzzy-complete))) + started)) + +;;;###autoload +(defun auto-complete (&optional sources) + "Start auto-completion at current point." + (interactive) + (auto-complete-1 :sources sources)) + +(defun ac-fuzzy-complete () + "Start fuzzy completion at current point." + (interactive) + (if (not (require 'fuzzy nil t)) + (message "Please install fuzzy.el if you use fuzzy completion") + (unless (ac-menu-live-p) + (ac-start)) + (let ((ac-match-function 'fuzzy-all-completions)) + (when ac-fuzzy-cursor-color + (unless ac-cursor-color + (setq ac-cursor-color (frame-parameter (selected-frame) 'cursor-color))) + (set-cursor-color ac-fuzzy-cursor-color)) + (setq ac-show-menu t) + (setq ac-fuzzy-enable t) + (setq ac-triggered nil) + (ac-update t))) + t) + +(defun ac-next () + "Select next candidate." + (interactive) + (when (ac-menu-live-p) + (when (popup-hidden-p ac-menu) + (ac-show-menu)) + (popup-next ac-menu) + (if (eq this-command 'ac-next) + (setq ac-dwim-enable t)))) + +(defun ac-previous () + "Select previous candidate." + (interactive) + (when (ac-menu-live-p) + (when (popup-hidden-p ac-menu) + (ac-show-menu)) + (popup-previous ac-menu) + (if (eq this-command 'ac-previous) + (setq ac-dwim-enable t)))) + +(defun ac-expand (arg) + "Try expand, and if expanded twice, select next candidate. +If given a prefix argument, select the previous candidate." + (interactive "P") + (unless (ac-expand-common) + (let ((string (ac-selected-candidate))) + (when string + (when (equal ac-prefix string) + (if (not arg) + (ac-next) + (ac-previous)) + (setq string (ac-selected-candidate))) + (ac-expand-string string + (or (eq last-command 'ac-expand) + (eq last-command 'ac-expand-previous))) + ;; Do reposition if menu at long line + (if (and (> (popup-direction ac-menu) 0) + (ac-menu-at-wrapper-line-p)) + (ac-reposition)) + (setq ac-show-menu t) + string)))) + +(defun ac-expand-previous (arg) + "Like `ac-expand', but select previous candidate." + (interactive "P") + (ac-expand (not arg))) + +(defun ac-expand-common () + "Try to expand meaningful common part." + (interactive) + (if (and ac-dwim ac-dwim-enable) + (ac-complete) + (when (and (ac-inline-live-p) + ac-common-part) + (ac-inline-hide) + (ac-expand-string ac-common-part (eq last-command this-command)) + (setq ac-common-part nil) + t))) + +(defun ac-complete-1 (candidate) + (let ((action (popup-item-property candidate 'action)) + (fallback nil)) + (when candidate + (unless (ac-expand-string candidate) + (setq fallback t)) + ;; Remember to show help later + (when (and ac-point candidate) + (unless ac-last-completion + (setq ac-last-completion (cons (make-marker) nil))) + (set-marker (car ac-last-completion) ac-point ac-buffer) + (setcdr ac-last-completion candidate))) + (ac-abort) + (cond + (action + (funcall action)) + (fallback + (ac-fallback-command))) + candidate)) + +(defun ac-complete () + "Try complete." + (interactive) + (ac-complete-1 (ac-selected-candidate))) + +(cl-defun ac-start (&key + requires + force-init + (triggered (or ac-triggered t))) + "Start completion." + (interactive) + (if (not auto-complete-mode) + (message "auto-complete-mode is not enabled") + (let* ((info (ac-prefix requires ac-ignoring-prefix-def)) + (prefix-def (nth 0 info)) + (point (nth 1 info)) + (sources (nth 2 info)) + prefix + (init (or force-init (not (eq ac-point point))))) + (if (or (null point) + (progn + (setq prefix (buffer-substring-no-properties point (point))) + (and (not (eq triggered 'command)) + (ac-stop-word-p prefix)))) + (prog1 nil + (ac-abort)) + (when (and ac-use-fuzzy ac-fuzzy-cursor-color) + (unless ac-cursor-color + (setq ac-cursor-color (frame-parameter (selected-frame) 'cursor-color)))) + (setq ac-show-menu (or ac-show-menu (if (eq ac-auto-show-menu t) t)) + ac-current-sources sources + ac-buffer (current-buffer) + ac-point point + ac-prefix prefix + ac-limit ac-candidate-limit + ac-triggered triggered + ac-current-prefix-def prefix-def) + (when (or init (null ac-prefix-overlay)) + (ac-init)) + (ac-set-timer) + (ac-set-show-menu-timer) + (ac-set-quick-help-timer) + (ac-put-prefix-overlay) + t)))) + +(defun ac-stop () + "Stop completing." + (interactive) + (setq ac-selected-candidate nil) + (ac-abort)) + +(defun ac-ignore (&rest ignore) + "Same as `ignore'." + (interactive)) + +(defun ac-mouse-1 (event) + (interactive "e") + (popup-awhen (popup-menu-item-of-mouse-event event) + (ac-complete-1 it))) + +(defun ac-mouse-4 (event) + (interactive "e") + (ac-previous)) + +(defun ac-mouse-5 (event) + (interactive "e") + (ac-next)) + +(defun ac-trigger-key-command (&optional force) + (interactive "P") + (let (started) + (when (or force (ac-trigger-command-p last-command)) + (setq started (auto-complete-1 :triggered 'trigger-key))) + (unless started + (ac-fallback-command 'ac-trigger-key-command)))) + + + +;;;; Basic cache facility + +(defvar ac-clear-variables-every-minute-timer nil) +(defvar ac-clear-variables-after-save nil) +(defvar ac-clear-variables-every-minute nil) +(defvar ac-minutes-counter 0) + +(defun ac-clear-variable-after-save (variable &optional pred) + (add-to-list 'ac-clear-variables-after-save (cons variable pred))) + +(defun ac-clear-variables-after-save () + (dolist (pair ac-clear-variables-after-save) + (if (or (null (cdr pair)) + (funcall (cdr pair))) + (set (car pair) nil)))) + +(defun ac-clear-variable-every-minutes (variable minutes) + (add-to-list 'ac-clear-variables-every-minute (cons variable minutes))) + +(defun ac-clear-variable-every-minute (variable) + (ac-clear-variable-every-minutes variable 1)) + +(defun ac-clear-variable-every-10-minutes (variable) + (ac-clear-variable-every-minutes variable 10)) + +(defun ac-clear-variables-every-minute () + (cl-incf ac-minutes-counter) + (dolist (pair ac-clear-variables-every-minute) + (if (eq (% ac-minutes-counter (cdr pair)) 0) + (set (car pair) nil)))) + + + +;;;; Auto complete mode + +(defun ac-cursor-on-diable-face-p (&optional point) + (memq (get-text-property (or point (point)) 'face) ac-disable-faces)) + +(defun ac-trigger-command-p (command) + "Return non-nil if `COMMAND' is a trigger command." + (and (symbolp command) + (not (memq command ac-non-trigger-commands)) + (or (memq command ac-trigger-commands) + (string-match "self-insert-command" (symbol-name command)) + (string-match "electric" (symbol-name command))))) + +(defun ac-fallback-key-sequence () + (setq unread-command-events + (append (this-single-command-raw-keys) + unread-command-events)) + (read-key-sequence-vector "")) + +(defun ac-fallback-command (&optional except-command) + (let* ((auto-complete-mode nil) + (keys (ac-fallback-key-sequence)) + (command (and keys (key-binding keys)))) + (when (and (commandp command) + (not (eq command except-command))) + (setq this-command command) + (call-interactively command)))) + +(defun ac-compatible-package-command-p (command) + "Return non-nil if `COMMAND' is compatible with auto-complete." + (and (symbolp command) + (string-match ac-compatible-packages-regexp (symbol-name command)))) + +(defun ac-handle-pre-command () + (condition-case var + (if (or (setq ac-triggered (and (not ac-fuzzy-enable) ; ignore key storkes in fuzzy mode + (or (eq this-command 'auto-complete) ; special case + (ac-trigger-command-p this-command) + (and ac-completing + (memq this-command ac-trigger-commands-on-completing))) + (not (ac-cursor-on-diable-face-p)) + (or ac-triggered t))) + (ac-compatible-package-command-p this-command)) + (progn + (if (or (not (symbolp this-command)) + (not (get this-command 'ac-quick-help-command))) + (ac-remove-quick-help)) + ;; Not to cause inline completion to be disrupted. + (ac-inline-hide)) + (ac-abort)) + (error (ac-error var)))) + +(defun ac-handle-post-command () + (condition-case var + (when (and ac-triggered + (or ac-auto-start + ac-completing) + (not isearch-mode)) + (setq ac-last-point (point)) + (ac-start :requires (unless ac-completing ac-auto-start)) + (unless ac-disable-inline + (ac-inline-update))) + (error (ac-error var)))) + +(defvar ac-flycheck-poll-completion-end-timer nil + "Timer to poll end of completion.") + +(defun ac-syntax-checker-workaround () + (if ac-stop-flymake-on-completing + (progn + (make-local-variable 'ac-flycheck-poll-completion-end-timer) + (when (require 'flymake nil t) + (defadvice flymake-on-timer-event (around ac-flymake-stop-advice activate) + (unless ac-completing + ad-do-it))) + (when (require 'flycheck nil t) + (defadvice flycheck-handle-idle-change (around ac-flycheck-stop-advice activate) + (if ac-completing + (setq ac-flycheck-poll-completion-end-timer + (run-at-time ac-flycheck-poll-completion-end-interval + nil + #'flycheck-handle-idle-change)) + ad-do-it)))) + (when (featurep 'flymake) + (ad-disable-advice 'flymake-on-timer-event 'around 'ac-flymake-stop-advice)) + (when (featurep 'flycheck) + (ad-disable-advice 'flycheck-handle-idle-change 'around 'ac-flycheck-stop-advice)))) + +(defun ac-setup () + (if ac-trigger-key + (ac-set-trigger-key ac-trigger-key)) + (if ac-use-comphist + (ac-comphist-init)) + (unless ac-clear-variables-every-minute-timer + (setq ac-clear-variables-every-minute-timer (run-with-timer 60 60 'ac-clear-variables-every-minute))) + (ac-syntax-checker-workaround)) + +;;;###autoload +(define-minor-mode auto-complete-mode + "AutoComplete mode" + :lighter " AC" + :keymap ac-mode-map + :group 'auto-complete + (if auto-complete-mode + (progn + (ac-setup) + (add-hook 'pre-command-hook 'ac-handle-pre-command nil t) + (add-hook 'post-command-hook 'ac-handle-post-command nil t) + (add-hook 'after-save-hook 'ac-clear-variables-after-save nil t) + (run-hooks 'auto-complete-mode-hook)) + (remove-hook 'pre-command-hook 'ac-handle-pre-command t) + (remove-hook 'post-command-hook 'ac-handle-post-command t) + (remove-hook 'after-save-hook 'ac-clear-variables-after-save t) + (ac-abort))) + +(defun auto-complete-mode-maybe () + "What buffer `auto-complete-mode' prefers." + (if (and (not (minibufferp (current-buffer))) + (memq major-mode ac-modes)) + (auto-complete-mode 1))) + +;;;###autoload +(define-global-minor-mode global-auto-complete-mode + auto-complete-mode auto-complete-mode-maybe + :group 'auto-complete) + + + +;;;; Compatibilities with other extensions + +(defun ac-flyspell-workaround () + "Flyspell uses `sit-for' for delaying its process. Unfortunatelly, +it stops auto completion which is trigger with `run-with-idle-timer'. +This workaround avoid flyspell processes when auto completion is being started." + (interactive) + (defadvice flyspell-post-command-hook (around ac-flyspell-workaround activate) + (unless ac-triggered + ad-do-it))) + +(defun ac-linum-workaround () + "linum-mode tries to display the line numbers even for the +completion menu. This workaround stops that annoying behavior." + (interactive) + (defadvice linum-update (around ac-linum-update-workaround activate) + (unless ac-completing + ad-do-it))) + + + +;;;; Standard sources + +(defmacro ac-define-source (name source) + "Source definition macro. It defines a complete command also." + (declare (indent 1)) + `(progn + (defvar ,(intern (format "ac-source-%s" name))) + ;; Use `setq' to reset ac-source-NAME every time + ;; `ac-define-source' is called. This is useful, for example + ;; when evaluating `ac-define-source' using C-M-x (`eval-defun'). + (setq ,(intern (format "ac-source-%s" name)) ,source) + (defun ,(intern (format "ac-complete-%s" name)) () + (interactive) + (auto-complete '(,(intern (format "ac-source-%s" name))))))) + +;; Words in buffer source +(defvar ac-word-index nil) + +(defun ac-candidate-words-in-buffer (point prefix limit) + (let ((i 0) + candidate + candidates + (regexp (concat "\\_<" (regexp-quote prefix) "\\(\\sw\\|\\s_\\)+\\_>"))) + (save-excursion + ;; Search backward + (goto-char point) + (while (and (or (not (integerp limit)) (< i limit)) + (re-search-backward regexp nil t)) + (setq candidate (match-string-no-properties 0)) + (unless (member candidate candidates) + (push candidate candidates) + (cl-incf i))) + ;; Search backward + (goto-char (+ point (length prefix))) + (while (and (or (not (integerp limit)) (< i limit)) + (re-search-forward regexp nil t)) + (setq candidate (match-string-no-properties 0)) + (unless (member candidate candidates) + (push candidate candidates) + (cl-incf i))) + (nreverse candidates)))) + +(defun ac-incremental-update-word-index () + (unless (local-variable-p 'ac-word-index) + (make-local-variable 'ac-word-index)) + (if (null ac-word-index) + (setq ac-word-index (cons nil nil))) + ;; Mark incomplete + (if (car ac-word-index) + (setcar ac-word-index nil)) + (let ((index (cdr ac-word-index)) + (words (ac-candidate-words-in-buffer ac-point ac-prefix (or (and (integerp ac-limit) ac-limit) 10)))) + (dolist (word words) + (unless (member word index) + (push word index) + (setcdr ac-word-index index))))) + +(defun ac-update-word-index-1 () + (unless (local-variable-p 'ac-word-index) + (make-local-variable 'ac-word-index)) + (when (and (not (car ac-word-index)) + (< (buffer-size) 1048576)) + ;; Complete index + (setq ac-word-index + (cons t + (split-string (buffer-substring-no-properties (point-min) (point-max)) + "\\(?:^\\|\\_>\\).*?\\(?:\\_<\\|$\\)"))))) + +(defun ac-update-word-index () + (dolist (buffer (buffer-list)) + (when (or ac-fuzzy-enable + (not (eq buffer (current-buffer)))) + (with-current-buffer buffer + (ac-update-word-index-1))))) + +(defun ac-word-candidates (&optional buffer-pred) + (cl-loop initially (unless ac-fuzzy-enable (ac-incremental-update-word-index)) + for buffer in (buffer-list) + if (and (or (not (integerp ac-limit)) (< (length candidates) ac-limit)) + (if buffer-pred (funcall buffer-pred buffer) t)) + append (funcall ac-match-function + ac-prefix + (and (local-variable-p 'ac-word-index buffer) + (cdr (buffer-local-value 'ac-word-index buffer)))) + into candidates + finally return (delete-dups candidates))) + +(ac-define-source words-in-buffer + '((candidates . ac-word-candidates))) + +(ac-define-source words-in-all-buffer + '((init . ac-update-word-index) + (candidates . ac-word-candidates))) + +(ac-define-source words-in-same-mode-buffers + '((init . ac-update-word-index) + (candidates . (ac-word-candidates + (lambda (buffer) + (derived-mode-p (buffer-local-value 'major-mode buffer))))))) + +;; Lisp symbols source +(defvar ac-symbols-cache nil) +(ac-clear-variable-every-10-minutes 'ac-symbols-cache) + +(defun ac-symbol-file (symbol type) + (if (fboundp 'find-lisp-object-file-name) + (find-lisp-object-file-name symbol type) + (let ((file-name (with-no-warnings + (describe-simplify-lib-file-name + (symbol-file symbol type))))) + (when (equal file-name "loaddefs.el") + ;; Find the real def site of the preloaded object. + (let ((location (condition-case nil + (if (eq type 'defun) + (find-function-search-for-symbol symbol nil + "loaddefs.el") + (find-variable-noselect symbol file-name)) + (error nil)))) + (when location + (with-current-buffer (car location) + (when (cdr location) + (goto-char (cdr location))) + (when (re-search-backward + "^;;; Generated autoloads from \\(.*\\)" nil t) + (setq file-name (match-string 1))))))) + (if (and (null file-name) + (or (eq type 'defun) + (integerp (get symbol 'variable-documentation)))) + ;; It's a object not defined in Elisp but in C. + (if (get-buffer " *DOC*") + (if (eq type 'defun) + (help-C-file-name (symbol-function symbol) 'subr) + (help-C-file-name symbol 'var)) + 'C-source) + file-name)))) + +(defun ac-symbol-documentation (symbol) + (if (stringp symbol) + (setq symbol (intern-soft symbol))) + (ignore-errors + (with-temp-buffer + (let ((standard-output (current-buffer))) + (prin1 symbol) + (princ " is ") + (cond + ((fboundp symbol) + ;; import help-xref-following + (require 'help-mode) + (let ((help-xref-following t) + (major-mode 'help-mode)) ; avoid error in Emacs 24 + (describe-function-1 symbol)) + (buffer-string)) + ((boundp symbol) + (let ((file-name (ac-symbol-file symbol 'defvar))) + (princ "a variable") + (when file-name + (princ " defined in `") + (princ (if (eq file-name 'C-source) + "C source code" + (file-name-nondirectory file-name)))) + (princ "'.\n\n") + (princ (or (documentation-property symbol 'variable-documentation t) + "Not documented.")) + (buffer-string))) + ((facep symbol) + (let ((file-name (ac-symbol-file symbol 'defface))) + (princ "a face") + (when file-name + (princ " defined in `") + (princ (if (eq file-name 'C-source) + "C source code" + (file-name-nondirectory file-name)))) + (princ "'.\n\n") + (princ (or (documentation-property symbol 'face-documentation t) + "Not documented.")) + (buffer-string))) + (t + (let ((doc (documentation-property symbol 'group-documentation t))) + (when doc + (princ "a group.\n\n") + (princ doc) + (buffer-string))))))))) + +(defun ac-symbol-candidates () + (or ac-symbols-cache + (setq ac-symbols-cache + (cl-loop for x being the symbols + if (or (fboundp x) + (boundp x) + (symbol-plist x)) + collect (symbol-name x))))) + +(ac-define-source symbols + '((candidates . ac-symbol-candidates) + (document . ac-symbol-documentation) + (symbol . "s") + (cache))) + +;; Lisp functions source +(defvar ac-functions-cache nil) +(ac-clear-variable-every-10-minutes 'ac-functions-cache) + +(defun ac-function-candidates () + (or ac-functions-cache + (setq ac-functions-cache + (cl-loop for x being the symbols + if (fboundp x) + collect (symbol-name x))))) + +(ac-define-source functions + '((candidates . ac-function-candidates) + (document . ac-symbol-documentation) + (symbol . "f") + (prefix . "(\\(\\(?:\\sw\\|\\s_\\)+\\)") + (cache))) + +;; Lisp variables source +(defvar ac-variables-cache nil) +(ac-clear-variable-every-10-minutes 'ac-variables-cache) + +(defun ac-variable-candidates () + (or ac-variables-cache + (setq ac-variables-cache + (cl-loop for x being the symbols + if (boundp x) + collect (symbol-name x))))) + +(ac-define-source variables + '((candidates . ac-variable-candidates) + (document . ac-symbol-documentation) + (symbol . "v") + (cache))) + +;; Lisp features source +(defvar ac-emacs-lisp-features nil) +(ac-clear-variable-every-10-minutes 'ac-emacs-lisp-features) + +(defun ac-emacs-lisp-feature-candidates () + (or ac-emacs-lisp-features + (if (fboundp 'find-library-suffixes) + (let ((suffix (concat (regexp-opt (find-library-suffixes) t) "\\'"))) + (setq ac-emacs-lisp-features + (append (mapcar 'prin1-to-string features) + (cl-loop for dir in load-path + if (file-directory-p dir) + append (cl-loop for file in (directory-files dir) + if (string-match suffix file) + collect (substring file 0 (match-beginning 0)))))))))) + +(ac-define-source features + '((depends find-func) + (candidates . ac-emacs-lisp-feature-candidates) + (prefix . "require +'\\(\\(?:\\sw\\|\\s_\\)*\\)") + (requires . 0))) + +(defvaralias 'ac-source-emacs-lisp-features 'ac-source-features) + +;; Abbrev source +(ac-define-source abbrev + '((candidates . (mapcar 'popup-x-to-string (append (vconcat local-abbrev-table global-abbrev-table) nil))) + (action . expand-abbrev) + (symbol . "a") + (cache))) + +;; Files in current directory source +(ac-define-source files-in-current-dir + '((candidates . (directory-files default-directory)) + (cache))) + +;; Filename source +(defvar ac-filename-cache nil) + +(defun ac-filename-candidate () + (let (file-name-handler-alist) + (unless (or (and comment-start-skip + (string-match comment-start-skip ac-prefix)) + (file-regular-p ac-prefix)) + (ignore-errors + (cl-loop with dir = (file-name-directory ac-prefix) + with files = (or (assoc-default dir ac-filename-cache) + (let ((files (directory-files dir nil "^[^.]"))) + (push (cons dir files) ac-filename-cache) + files)) + for file in files + for path = (concat dir file) + collect (if (file-directory-p path) + (concat path "/") + path)))))) + +(ac-define-source filename + '((init . (setq ac-filename-cache nil)) + (candidates . ac-filename-candidate) + (prefix . valid-file) + (requires . 0) + (action . ac-start) + (limit . nil))) + +;; Dictionary source +(ac-define-source dictionary + '((candidates . ac-buffer-dictionary) + (symbol . "d"))) + +(provide 'auto-complete) +;;; auto-complete.el ends here diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/ada-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/ada-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/ada-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/ada-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/c++-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/c++-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/c++-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/c++-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/c-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/c-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/c-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/c-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/caml-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/caml-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/caml-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/caml-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/clojure-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/clojure-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/clojure-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/clojure-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/clojurescript-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/clojurescript-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/clojurescript-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/clojurescript-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/coq-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/coq-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/coq-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/coq-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/css-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/css-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/css-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/css-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/erlang-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/erlang-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/erlang-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/erlang-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/go-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/go-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/go-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/go-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/haskell-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/haskell-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/haskell-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/haskell-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/java-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/java-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/java-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/java-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/js-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/js-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/js-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/js-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/lua-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/lua-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/lua-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/lua-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/octave-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/octave-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/octave-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/octave-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/php-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/php-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/php-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/php-mode diff --git a/emacs.d/elpa/auto-complete-20160107.8/dict/python-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/python-mode new file mode 100644 index 0000000..09e936c --- /dev/null +++ b/emacs.d/elpa/auto-complete-20160107.8/dict/python-mode @@ -0,0 +1,379 @@ +ArithmeticError +AssertionError +AttributeError +BaseException +BufferError +BytesWarning +DeprecationWarning +EOFError +Ellipsis +EnvironmentError +Exception +False +FloatingPointError +FutureWarning +GeneratorExit +IOError +ImportError +ImportWarning +IndentationError +IndexError +KeyError +KeyboardInterrupt +LookupError +MemoryError +NameError +None +NotImplemented +NotImplementedError +OSError +OverflowError +PendingDeprecationWarning +ReferenceError +RuntimeError +RuntimeWarning +StandardError +StopIteration +SyntaxError +SyntaxWarning +SystemError +SystemExit +TabError +True +TypeError +UnboundLocalError +UnicodeDecodeError +UnicodeEncodeError +UnicodeError +UnicodeTranslateError +UnicodeWarning +UserWarning +ValueError +Warning +ZeroDivisionError +__builtins__ +__debug__ +__doc__ +__file__ +__future__ +__import__ +__init__ +__main__ +__name__ +__package__ +_dummy_thread +_thread +abc +abs +aifc +all +and +any +apply +argparse +array +as +assert +ast +asynchat +asyncio +asyncore +atexit +audioop +base64 +basestring +bdb +bin +binascii +binhex +bisect +bool +break +buffer +builtins +bytearray +bytes +bz2 +calendar +callable +cgi +cgitb +chr +chuck +class +classmethod +cmath +cmd +cmp +code +codecs +codeop +coerce +collections +colorsys +compile +compileall +complex +concurrent +configparser +contextlib +continue +copy +copyreg +copyright +credits +crypt +csv +ctypes +curses +datetime +dbm +decimal +def +del +delattr +dict +difflib +dir +dis +distutils +divmod +doctest +dummy_threading +elif +else +email +enumerate +ensurepip +enum +errno +eval +except +exec +execfile +exit +faulthandler +fcntl +file +filecmp +fileinput +filter +finally +float +fnmatch +for +format +formatter +fpectl +fractions +from +frozenset +ftplib +functools +gc +getattr +getopt +getpass +gettext +glob +global +globals +grp +gzip +hasattr +hash +hashlib +heapq +help +hex +hmac +html +http +id +if +imghdr +imp +impalib +import +importlib +in +input +inspect +int +intern +io +ipaddress +is +isinstance +issubclass +iter +itertools +json +keyword +lambda +len +license +linecache +list +locale +locals +logging +long +lzma +macpath +mailbox +mailcap +map +marshal +math +max +memoryview +mimetypes +min +mmap +modulefinder +msilib +msvcrt +multiprocessing +netrc +next +nis +nntplib +not +numbers +object +oct +open +operator +optparse +or +ord +os +ossaudiodev +parser +pass +pathlib +pdb +pickle +pickletools +pipes +pkgutil +platform +plistlib +poplib +posix +pow +pprint +print +profile +property +pty +pwd +py_compiler +pyclbr +pydoc +queue +quit +quopri +raise +random +range +raw_input +re +readline +reduce +reload +repr +reprlib +resource +return +reversed +rlcompleter +round +runpy +sched +select +selectors +self +set +setattr +shelve +shlex +shutil +signal +site +slice +smtpd +smtplib +sndhdr +socket +socketserver +sorted +spwd +sqlite3 +ssl +stat +staticmethod +statistics +str +string +stringprep +struct +subprocess +sum +sunau +super +symbol +symtable +sys +sysconfig +syslog +tabnanny +tarfile +telnetlib +tempfile +termios +test +textwrap +threading +time +timeit +tkinter +token +tokenize +trace +traceback +tracemalloc +try +tty +tuple +turtle +type +types +unichr +unicode +unicodedata +unittest +urllib +uu +uuid +vars +venv +warnings +wave +weakref +webbrowser +while +winsound +winreg +with +wsgiref +xdrlib +xml +xmlrpc +xrange +yield +zip +zipfile +zipimport +zlib diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/qml-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/qml-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/qml-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/qml-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/ruby-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/ruby-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/ruby-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/ruby-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/scala-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/scala-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/scala-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/scala-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/scheme-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/scheme-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/scheme-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/scheme-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/sclang-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/sclang-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/sclang-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/sclang-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/sh-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/sh-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/sh-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/sh-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/tcl-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/tcl-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/tcl-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/tcl-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/ts-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/ts-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/ts-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/ts-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/tuareg-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/tuareg-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/tuareg-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/tuareg-mode diff --git a/emacs.d/elpa/auto-complete-20150618.1949/dict/verilog-mode b/emacs.d/elpa/auto-complete-20160107.8/dict/verilog-mode similarity index 100% rename from emacs.d/elpa/auto-complete-20150618.1949/dict/verilog-mode rename to emacs.d/elpa/auto-complete-20160107.8/dict/verilog-mode diff --git a/emacs.d/elpa/centered-cursor-mode-20150420.1942/centered-cursor-mode-autoloads.el b/emacs.d/elpa/centered-cursor-mode-20150420.1942/centered-cursor-mode-autoloads.el deleted file mode 100644 index b2d5df0..0000000 --- a/emacs.d/elpa/centered-cursor-mode-20150420.1942/centered-cursor-mode-autoloads.el +++ /dev/null @@ -1,23 +0,0 @@ -;;; centered-cursor-mode-autoloads.el --- automatically extracted autoloads -;; -;;; Code: -(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) - -;;;### (autoloads nil "centered-cursor-mode" "centered-cursor-mode.el" -;;;;;; (21837 24217 0 0)) -;;; Generated autoloads from centered-cursor-mode.el - -(autoload 'centered-cursor-mode "centered-cursor-mode" "\ -Makes the cursor stay vertically in a defined -position (usually centered). - -\(fn &optional ARG)" t nil) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; centered-cursor-mode-autoloads.el ends here diff --git a/emacs.d/elpa/centered-cursor-mode-20150420.1942/centered-cursor-mode-pkg.el b/emacs.d/elpa/centered-cursor-mode-20150420.1942/centered-cursor-mode-pkg.el deleted file mode 100644 index 73d54db..0000000 --- a/emacs.d/elpa/centered-cursor-mode-20150420.1942/centered-cursor-mode-pkg.el +++ /dev/null @@ -1 +0,0 @@ -(define-package "centered-cursor-mode" "20150420.1942" "cursor stays vertically centered" 'nil :url "http://www.emacswiki.org/emacs/centered-cursor-mode.el" :keywords '("convenience")) diff --git a/emacs.d/elpa/centered-cursor-mode-20150420.1942/centered-cursor-mode.el b/emacs.d/elpa/centered-cursor-mode-20150420.1942/centered-cursor-mode.el deleted file mode 100644 index 0174c02..0000000 --- a/emacs.d/elpa/centered-cursor-mode-20150420.1942/centered-cursor-mode.el +++ /dev/null @@ -1,430 +0,0 @@ -;;; centered-cursor-mode.el --- cursor stays vertically centered - -;; Copyright (C) 2007 André Riemann - -;; Author: André Riemann -;; Maintainer: André Riemann -;; Created: 2007-09-14 -;; Keywords: convenience -;; Package-Version: 20150420.1942 - -;; URL: http://www.emacswiki.org/emacs/centered-cursor-mode.el -;; Compatibility: tested with GNU Emacs 23.0, 24 -;; Version: 0.5.4 -;; Last-Updated: 2015-04-20 - -;; This file 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 2, or (at your option) -;; any later version. - -;; This file 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. - -;;; Commentary: - -;; Makes the cursor stay vertically in a defined position (usually -;; centered). The vertical position can be altered, see key definition -;; below. - -;; To load put that in .emacs: -;; (require 'centered-cursor-mode) -;; To activate do: -;; M-x centered-cursor-mode -;; for buffer local or -;; M-x global-centered-cursor-mode -;; for global minor mode. -;; Also possible: put that in .emacs -;; (and -;; (require 'centered-cursor-mode) -;; (global-centered-cursor-mode +1)) -;; to always have centered-cursor-mode on in all buffers. - -;;; TODO: -;; - the code is a mess -;; - ccm-vpos-inverted doesn't work with ccm-vpos == 0, because first -;; position from top is 0 and from bottom -1 -;; - interactive first start isn't animated when calling global-... -;; because it starts the modes for each buffer and interactive-p fails -;; for that -;; - more bugs? - -;;; Change Log: -;; 2015-04-20 andre-r -;; * corrected URL in header -;; 2015-03-01 andre-r -;; * fixed bug where Emacs without X support (emacs-nox) didn't find mouse-wheel-mode -;; 2009-08-31 andre-r -;; * replaced window-body-height with window-text-height -;; (partially visible lines are not counted in window-text-height) -;; * bug fixed in ccm-vpos-recenter -;; (some parentheses where wrong after the last update) -;; 2009-02-23 andre-r -;; * some simplifications -;; 2009-02-22 andre-r -;; * some tips from Drew Adams: -;; - new local variable coding:utf-8 -;; - made recenter-sequence a defvar -;; - added groups scrolling and convenience -;; - replaced mouse-4 and mouse-5 with -;; mouse-wheel-up-event and mouse-wheel-down-event -;; - added scroll-bar-toolkit-scroll to ccm-ignored-commands -;; - made ccm-ignored-commands customisable -;; * removed a bug where it didn't work with more than one window -;; displaying the same buffer -;; * added function for page up and down scrolling -;; (standard ones didn't work well with this mode) -;; * made the animation delay customisable -;; * made the initial vertical position customisable -;; * made the behaviour at the end of the file customisable -;; 2008-02-02 andre-r -;; * fixed bug that led to wrong-type-argument -;; when opening a new buffer -;; * some other minor stuff -;; 2007-09-24 andre-r -;; * added global minor mode -;; 2007-09-21 andre-r -;; * not recentering at end of buffer -;; * defvar animate-first-start-p -;; 2007-09-14 andre-r -;; * inital release - -;; This file is *NOT* part of GNU Emacs. - -;;; Code: - - -(require 'mouse-wheel-mode nil 'noerror) - -(defgroup centered-cursor nil - "Makes the cursor stay vertically in a defined position (usually centered). -Instead the cursor the text moves around the cursor." - :group 'scrolling - :group 'convenience - :link '(emacs-library-link :tag "Source Lisp File" "centered-cursor-mode.el") - :link '(url-link "http://www.emacswiki.org/cgi-bin/wiki/centered-cursor-mode.el")) - -(defcustom ccm-step-size 2 - "Step size when animated recentering." - :group 'centered-cursor - :tag "Animation step size" - :type 'integer) - -(defcustom ccm-step-delay 0.02 - "Delay between animation steps. -If you want a different animation speed." - :group 'centered-cursor - :tag "Animation step delay" - :type 'number) - -(defcustom ccm-ignored-commands '(mouse-drag-region - mouse-set-point - widget-button-click - scroll-bar-toolkit-scroll) - "After these commands recentering is ignored. -This is to prevent unintentional jumping (especially when mouse -clicking). Following commands (except the ignored ones) will -cause an animated recentering to give a feedback and not just -jumping to the center." - :group 'centered-cursor - :tag "Ignored commands" - :type '(repeat (symbol :tag "Command"))) - -(defcustom ccm-vpos-init '(round (window-text-height) 2) - "This is the screen line position where the cursor initially stays." - :group 'centered-cursor - :tag "Vertical cursor position" - :type '(choice (const :tag "Center" (round (window-text-height) 2)) - (const :tag "Golden ratio" (round (* 21 (window-text-height)) 34)) - (integer :tag "Lines from top" :value 10))) -(make-variable-buffer-local 'ccm-vpos-init) - -(defcustom ccm-vpos-inverted 1 - "Inverted vertical cursor position. -Defines if the initial vertical position `ccm-vpos-init' is -measured from the bottom instead from the top." - :group 'centered-cursor - :tag "Inverted cursor position" - :type '(choice (const :tag "Inverted" -1) - (const :tag "Not inverted" 1))) -(make-variable-buffer-local 'ccm-vpos-inverted) - -(defcustom ccm-recenter-at-end-of-file nil - "Recenter at the end of the file. -If non-nil the end of the file is recentered. If nil the end of -the file stays at the end of the window." - :group 'centered-cursor - :tag "Recenter at EOF" - :type '(choice (const :tag "Don't recenter at the end of the file" nil) - (const :tag "Recenter at the end of the file" t))) -(make-variable-buffer-local 'ccm-recenter-end-of-file) - -(defvar ccm-vpos nil - "This is the screen line position where the cursor stays.") -(make-variable-buffer-local 'ccm-vpos) - -(defvar animate-first-start-p nil - "Whether or not to animate at first start. It is set to nil, if -centered-cursor-mode is called non-interactively.") -(make-variable-buffer-local 'animate-first-start-p) - -(defvar recenter-sequence nil - "Before animated recentering a list is generated first with positions -to successively recenter to") -(make-variable-buffer-local 'recenter-sequence) - -(defvar ccm-map - (let ((ccm-map (make-sparse-keymap))) - (define-key ccm-map [(control meta -)] 'ccm-vpos-up) - (define-key ccm-map [(control meta +)] 'ccm-vpos-down) - (define-key ccm-map [(control meta =)] 'ccm-vpos-down) - (define-key ccm-map [(control meta ?0)] 'ccm-vpos-recenter) - (when (and (boundp 'mouse-wheel-mode) mouse-wheel-mode) - (mapc (lambda (key) - (define-key ccm-map key 'ccm-mwheel-scroll)) - (list (vector mouse-wheel-up-event) - (vector mouse-wheel-down-event) - (vector (list 'control mouse-wheel-up-event)) - (vector (list 'control mouse-wheel-down-event)) - (vector (list 'shift mouse-wheel-up-event)) - (vector (list 'shift mouse-wheel-down-event))))) - (define-key ccm-map [(meta v)] 'ccm-scroll-down) - (define-key ccm-map [(control v)] 'ccm-scroll-up) - (define-key ccm-map [prior] 'ccm-scroll-down) - (define-key ccm-map [next] 'ccm-scroll-up) - ccm-map) - "Keymap used in centered-cursor-mode.") - - -(defun ccm-mwheel-scroll (event) - "Very similar to `mwheel-scroll', but does not use `scroll-down' -and `scroll-up' but `previous-line' and `next-line', that is, the -cursor is moved and thus the text in the window is scrolled -due to `recenter'. - -The customizable variable `mouse-wheel-scroll-amount' is used to -determine how much to scroll, where nil instead of a number means -the same as in mwheel-scroll, scroll by a near full screen. - -This command exists, because mwheel-scroll caused strange -behaviour with automatic recentering." -;; (interactive (list last-input-event)) - (interactive "e") - (let* ((mods (delq 'click (delq 'double (delq 'triple (event-modifiers event))))) - (amt (assoc mods mouse-wheel-scroll-amount))) - ;;(message "%S" mods) - (if amt - (setq amt (or (cdr amt) - (- (window-text-height) - next-screen-context-lines))) - (let ((list-elt mouse-wheel-scroll-amount)) - (while (consp (setq amt (pop list-elt)))))) - (if mouse-wheel-follow-mouse - (select-window (posn-window (event-start event)))) - (let ((button (mwheel-event-button event))) - (cond - ((eq button mouse-wheel-down-event) - (forward-line (- amt))) - ;;(princ amt)) - ((eq button mouse-wheel-up-event) - (forward-line amt)) - ;;(princ amt)) - (t (error "Bad binding in ccm-mwheel-scroll")))))) - -(defun ccm-scroll-down (&optional arg) - "Replaces `scroll-down' because with scroll-down -`centered-cursor-mode' sometimes doesn't reach the top of the -buffer. This version actually moves the cursor with -`previous-line'. Since with centered-cursor-mode the cursor is in -a fixed position the movement appears as page up." - (interactive "P") - (let ((amt (or arg (- (window-text-height) - next-screen-context-lines)))) - (forward-line (- amt)))) - -(defun ccm-scroll-up (&optional arg) - "Replaces `scroll-up' to be consistent with `ccm-scroll-down'. -This version actually moves the cursor with `previous-line'. -Since with centered-cursor-mode the cursor is in a fixed position -the movement appears as page up." - (interactive "P") - (let ((amt (or arg (- (window-text-height) - next-screen-context-lines)))) - (forward-line amt))) - - -(defun ccm-vpos-down (arg) - "Adjust the value of the screen line (where the cursor stays) by arg. -Negative values for arg are possible. Just the variable ccm-vpos -is set." - (interactive "p") - (or arg (setq arg 1)) - (let ((new-pos (if (< ccm-vpos 0) - (- ccm-vpos arg) - (+ ccm-vpos arg))) - ;; see pos-visible-in-window-p - (vpos-max (if (< ccm-vpos 0) - -1 - (- (window-text-height) 1))) - (vpos-min (if (< ccm-vpos 0) - (- (window-text-height)) - 0))) - (setq ccm-vpos - (cond - ((< new-pos vpos-min) - vpos-min) - ((> new-pos vpos-max) - vpos-max) - (t - new-pos))))) - -(defun ccm-vpos-up (arg) - "See `ccm-vpos-down'." - (interactive "p") - (or arg (setq arg 1)) - (ccm-vpos-down (- arg))) - -(defun ccm-vpos-recenter () - "Set the value of the screen line (where the cursor stays) in -the center. Just the variable ccm-vpos is set." - (interactive) - (if (equal (current-buffer) - (window-buffer (selected-window))) - (setq ccm-vpos (* (eval ccm-vpos-init) - ccm-vpos-inverted)))) - -(defun ccm-position-cursor () - "Do the actual recentering at the position `ccm-vpos'." - (unless (member this-command ccm-ignored-commands) - (unless ccm-vpos - (ccm-vpos-recenter)) - (unless (minibufferp (current-buffer)) - (if (equal (current-buffer) - (window-buffer (selected-window))) - (let* ((current-line - (if (< ccm-vpos 0) - ;; one-based, from bottom, negative - (- (count-lines (point) - ;; window-end is sometimes < 0 - ;; when opening a help buffer - (if (> (window-end) 0) - (window-end) - 1))) - ;; zero-based, from top, positive - (+ (count-lines (window-start) (point)) - ;; count-lines returns different value in column 0 - (if (= (current-column) 0) 0 -1)))) - (diff (- ccm-vpos current-line)) - (step-size ccm-step-size) - (step-delay ccm-step-delay) - (vpos-inverted ccm-vpos-inverted) - (recenter-at-end-of-file ccm-recenter-at-end-of-file)) - - (let* ((bottom-vpos (if (< ccm-vpos 0) - (- ccm-vpos) - (- (window-text-height) ccm-vpos))) - (correction (save-excursion - (if (or (= (point) (point-max)) - (progn - (goto-char (point-max)) - (zerop (current-column)))) - 1 0))) - ;; lines from point to end of buffer - (bottom-lines (+ (count-lines (point) (point-max)) - correction))) - - ;; only animate if the point was moved rather far away - ;; before by a mouseclick (see ccm-ignored-commands) - ;; or if minor mode is just entered interactively - (if (not (and (> (abs diff) 4) - (or (member last-command ccm-ignored-commands) - animate-first-start-p))) - - (recenter (if (and (< bottom-lines bottom-vpos) - (not recenter-at-end-of-file)) - ;; if near the bottom, recenter in the - ;; negative screen line that equals the - ;; bottom buffer line, i.e. if we are in - ;; the second last line (-2) of the - ;; buffer, the cursor will be recentered - ;; in -2 - (- bottom-lines) - ccm-vpos)) - - (setq animate-first-start-p nil) - ;; first build a list with positions to successively recenter to - (setq recenter-sequence - ;; reverse: because we build the list not FROM -> TO but - ;; TO -> FROM because if step size in number-sequence is - ;; bigger than one, TO might not included, that means the - ;; ccm-vpos would not be reached - ;; cdr: don't recenter the current-line - (if (and (< bottom-lines bottom-vpos) - (not recenter-at-end-of-file)) - ;; this one is for animation near the bottom - (cdr (reverse (number-sequence - (- bottom-lines) - (if (< ccm-vpos 0) - current-line - (- (- (window-text-height) current-line))) - (* (/ diff (abs diff)) (- step-size))))) - (cdr (reverse (number-sequence - ccm-vpos - current-line - (* (/ diff (abs diff)) (- step-size))))))) - ;; (message "%d %d %d (%d): %S" current-line ccm-vpos bottom-lines diff recenter-sequence) - (while recenter-sequence - ;; actual animation - (recenter (pop recenter-sequence)) - (if (car recenter-sequence) (sit-for step-delay t)))))))))) - -(defun ccm-first-start (animate) - "Called from centered-cursor-mode. Animate at first start, if -centered-cursor-mode is called interactively." - (let ((animate-first-start-p animate)) - (ccm-vpos-recenter) - (ccm-position-cursor))) - -;;(defalias 'ccm 'centered-cursor-mode) -;;;###autoload -(define-minor-mode centered-cursor-mode - "Makes the cursor stay vertically in a defined -position (usually centered)." - :init-value nil -;; :lighter nil - :lighter " ¢" - :keymap ccm-map - (cond - (centered-cursor-mode - (ccm-first-start (interactive-p)) - (add-hook 'post-command-hook 'ccm-position-cursor t t) - (add-hook 'window-configuration-change-hook 'ccm-vpos-recenter t t)) - (t - (remove-hook 'post-command-hook 'ccm-position-cursor t) - (remove-hook 'window-configuration-change-hook 'ccm-vpos-recenter t)))) - - -(define-global-minor-mode global-centered-cursor-mode centered-cursor-mode - centered-cursor-mode) - -(provide 'centered-cursor-mode) - -;;; Help: -;; (info "(elisp)Defining Minor Modes") -;; (info "(elisp)Screen Lines") -;; (info "(elisp)Hooks") -;; (info "(elisp)Customization") -;; (find-function 'mwheel-scroll) - -;; Local Variables: -;; coding: utf-8 -;; End: - -;;; centered-cursor-mode.el ends here diff --git a/emacs.d/elpa/centered-cursor-mode-20151001.634/centered-cursor-mode-autoloads.el b/emacs.d/elpa/centered-cursor-mode-20151001.634/centered-cursor-mode-autoloads.el new file mode 100644 index 0000000..79e2254 --- /dev/null +++ b/emacs.d/elpa/centered-cursor-mode-20151001.634/centered-cursor-mode-autoloads.el @@ -0,0 +1,23 @@ +;;; centered-cursor-mode-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) + +;;;### (autoloads nil "centered-cursor-mode" "centered-cursor-mode.el" +;;;;;; (22171 46582 0 0)) +;;; Generated autoloads from centered-cursor-mode.el + +(autoload 'centered-cursor-mode "centered-cursor-mode" "\ +Makes the cursor stay vertically in a defined +position (usually centered). + +\(fn &optional ARG)" t nil) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; centered-cursor-mode-autoloads.el ends here diff --git a/emacs.d/elpa/centered-cursor-mode-20151001.634/centered-cursor-mode-pkg.el b/emacs.d/elpa/centered-cursor-mode-20151001.634/centered-cursor-mode-pkg.el new file mode 100644 index 0000000..b899942 --- /dev/null +++ b/emacs.d/elpa/centered-cursor-mode-20151001.634/centered-cursor-mode-pkg.el @@ -0,0 +1 @@ +(define-package "centered-cursor-mode" "20151001.634" "cursor stays vertically centered" 'nil :url "http://www.emacswiki.org/cgi-bin/wiki/centered-cursor-mode.el" :keywords '("convenience")) diff --git a/emacs.d/elpa/centered-cursor-mode-20151001.634/centered-cursor-mode.el b/emacs.d/elpa/centered-cursor-mode-20151001.634/centered-cursor-mode.el new file mode 100644 index 0000000..1e2f615 --- /dev/null +++ b/emacs.d/elpa/centered-cursor-mode-20151001.634/centered-cursor-mode.el @@ -0,0 +1,436 @@ +;;; centered-cursor-mode.el --- cursor stays vertically centered + +;; Copyright (C) 2007 André Riemann + +;; Author: André Riemann +;; Maintainer: André Riemann +;; Created: 2007-09-14 +;; Keywords: convenience +;; Package-Version: 20151001.634 +;; Package-X-Original-Version: 20150302.831 + +;; URL: http://www.emacswiki.org/cgi-bin/wiki/centered-cursor-mode.el +;; Compatibility: tested with GNU Emacs 23.0, 24 +;; Version: 0.5.4 +;; Last-Updated: 2015-10-01 + +;; This file 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 2, or (at your option) +;; any later version. + +;; This file 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. + +;;; Commentary: + +;; Makes the cursor stay vertically in a defined position (usually +;; centered). The vertical position can be altered, see key definition +;; below. + +;; To load put that in .emacs: +;; (require 'centered-cursor-mode) +;; To activate do: +;; M-x centered-cursor-mode +;; for buffer local or +;; M-x global-centered-cursor-mode +;; for global minor mode. +;; Also possible: put that in .emacs +;; (and +;; (require 'centered-cursor-mode) +;; (global-centered-cursor-mode +1)) +;; to always have centered-cursor-mode on in all buffers. + +;;; TODO: +;; - the code is a mess +;; - ccm-vpos-inverted doesn't work with ccm-vpos == 0, because first +;; position from top is 0 and from bottom -1 +;; - interactive first start isn't animated when calling global-... +;; because it starts the modes for each buffer and interactive-p fails +;; for that +;; - more bugs? + +;;; Change Log: +;; 2015-10-01 Hinrik Örn Sigurðsson +;; * Avoided calling count-lines when unnecessary, which +;; fixes slow scrolling in large files +;; 2015-03-01 andre-r +;; * fixed bug where Emacs without X support (emacs-nox) didn't find mouse-wheel-mode +;; 2009-08-31 andre-r +;; * replaced window-body-height with window-text-height +;; (partially visible lines are not counted in window-text-height) +;; * bug fixed in ccm-vpos-recenter +;; (some parentheses where wrong after the last update) +;; 2009-02-23 andre-r +;; * some simplifications +;; 2009-02-22 andre-r +;; * some tips from Drew Adams: +;; - new local variable coding:utf-8 +;; - made recenter-sequence a defvar +;; - added groups scrolling and convenience +;; - replaced mouse-4 and mouse-5 with +;; mouse-wheel-up-event and mouse-wheel-down-event +;; - added scroll-bar-toolkit-scroll to ccm-ignored-commands +;; - made ccm-ignored-commands customisable +;; * removed a bug where it didn't work with more than one window +;; displaying the same buffer +;; * added function for page up and down scrolling +;; (standard ones didn't work well with this mode) +;; * made the animation delay customisable +;; * made the initial vertical position customisable +;; * made the behaviour at the end of the file customisable +;; 2008-02-02 andre-r +;; * fixed bug that led to wrong-type-argument +;; when opening a new buffer +;; * some other minor stuff +;; 2007-09-24 andre-r +;; * added global minor mode +;; 2007-09-21 andre-r +;; * not recentering at end of buffer +;; * defvar animate-first-start-p +;; 2007-09-14 andre-r +;; * inital release + +;; This file is *NOT* part of GNU Emacs. + +;;; Code: + + +(require 'mouse-wheel-mode nil 'noerror) + +(defgroup centered-cursor nil + "Makes the cursor stay vertically in a defined position (usually centered). +Instead the cursor the text moves around the cursor." + :group 'scrolling + :group 'convenience + :link '(emacs-library-link :tag "Source Lisp File" "centered-cursor-mode.el") + :link '(url-link "http://www.emacswiki.org/cgi-bin/wiki/centered-cursor-mode.el")) + +(defcustom ccm-step-size 2 + "Step size when animated recentering." + :group 'centered-cursor + :tag "Animation step size" + :type 'integer) + +(defcustom ccm-step-delay 0.02 + "Delay between animation steps. +If you want a different animation speed." + :group 'centered-cursor + :tag "Animation step delay" + :type 'number) + +(defcustom ccm-ignored-commands '(mouse-drag-region + mouse-set-point + widget-button-click + scroll-bar-toolkit-scroll) + "After these commands recentering is ignored. +This is to prevent unintentional jumping (especially when mouse +clicking). Following commands (except the ignored ones) will +cause an animated recentering to give a feedback and not just +jumping to the center." + :group 'centered-cursor + :tag "Ignored commands" + :type '(repeat (symbol :tag "Command"))) + +(defcustom ccm-vpos-init '(round (window-text-height) 2) + "This is the screen line position where the cursor initially stays." + :group 'centered-cursor + :tag "Vertical cursor position" + :type '(choice (const :tag "Center" (round (window-text-height) 2)) + (const :tag "Golden ratio" (round (* 21 (window-text-height)) 34)) + (integer :tag "Lines from top" :value 10))) +(make-variable-buffer-local 'ccm-vpos-init) + +(defcustom ccm-vpos-inverted 1 + "Inverted vertical cursor position. +Defines if the initial vertical position `ccm-vpos-init' is +measured from the bottom instead from the top." + :group 'centered-cursor + :tag "Inverted cursor position" + :type '(choice (const :tag "Inverted" -1) + (const :tag "Not inverted" 1))) +(make-variable-buffer-local 'ccm-vpos-inverted) + +(defcustom ccm-recenter-at-end-of-file nil + "Recenter at the end of the file. +If non-nil the end of the file is recentered. If nil the end of +the file stays at the end of the window." + :group 'centered-cursor + :tag "Recenter at EOF" + :type '(choice (const :tag "Don't recenter at the end of the file" nil) + (const :tag "Recenter at the end of the file" t))) +(make-variable-buffer-local 'ccm-recenter-end-of-file) + +(defvar ccm-vpos nil + "This is the screen line position where the cursor stays.") +(make-variable-buffer-local 'ccm-vpos) + +(defvar animate-first-start-p nil + "Whether or not to animate at first start. It is set to nil, if +centered-cursor-mode is called non-interactively.") +(make-variable-buffer-local 'animate-first-start-p) + +(defvar recenter-sequence nil + "Before animated recentering a list is generated first with positions +to successively recenter to") +(make-variable-buffer-local 'recenter-sequence) + +(defvar ccm-map + (let ((ccm-map (make-sparse-keymap))) + (define-key ccm-map [(control meta -)] 'ccm-vpos-up) + (define-key ccm-map [(control meta +)] 'ccm-vpos-down) + (define-key ccm-map [(control meta =)] 'ccm-vpos-down) + (define-key ccm-map [(control meta ?0)] 'ccm-vpos-recenter) + (when (and (boundp 'mouse-wheel-mode) mouse-wheel-mode) + (mapc (lambda (key) + (define-key ccm-map key 'ccm-mwheel-scroll)) + (list (vector mouse-wheel-up-event) + (vector mouse-wheel-down-event) + (vector (list 'control mouse-wheel-up-event)) + (vector (list 'control mouse-wheel-down-event)) + (vector (list 'shift mouse-wheel-up-event)) + (vector (list 'shift mouse-wheel-down-event))))) + (define-key ccm-map [(meta v)] 'ccm-scroll-down) + (define-key ccm-map [(control v)] 'ccm-scroll-up) + (define-key ccm-map [prior] 'ccm-scroll-down) + (define-key ccm-map [next] 'ccm-scroll-up) + ccm-map) + "Keymap used in centered-cursor-mode.") + + +(defun ccm-mwheel-scroll (event) + "Very similar to `mwheel-scroll', but does not use `scroll-down' +and `scroll-up' but `previous-line' and `next-line', that is, the +cursor is moved and thus the text in the window is scrolled +due to `recenter'. + +The customizable variable `mouse-wheel-scroll-amount' is used to +determine how much to scroll, where nil instead of a number means +the same as in mwheel-scroll, scroll by a near full screen. + +This command exists, because mwheel-scroll caused strange +behaviour with automatic recentering." +;; (interactive (list last-input-event)) + (interactive "e") + (let* ((mods (delq 'click (delq 'double (delq 'triple (event-modifiers event))))) + (amt (assoc mods mouse-wheel-scroll-amount))) + ;;(message "%S" mods) + (if amt + (setq amt (or (cdr amt) + (- (window-text-height) + next-screen-context-lines))) + (let ((list-elt mouse-wheel-scroll-amount)) + (while (consp (setq amt (pop list-elt)))))) + (if mouse-wheel-follow-mouse + (select-window (posn-window (event-start event)))) + (let ((button (mwheel-event-button event))) + (cond + ((eq button mouse-wheel-down-event) + (forward-line (- amt))) + ;;(princ amt)) + ((eq button mouse-wheel-up-event) + (forward-line amt)) + ;;(princ amt)) + (t (error "Bad binding in ccm-mwheel-scroll")))))) + +(defun ccm-scroll-down (&optional arg) + "Replaces `scroll-down' because with scroll-down +`centered-cursor-mode' sometimes doesn't reach the top of the +buffer. This version actually moves the cursor with +`previous-line'. Since with centered-cursor-mode the cursor is in +a fixed position the movement appears as page up." + (interactive "P") + (let ((amt (or arg (- (window-text-height) + next-screen-context-lines)))) + (forward-line (- amt)))) + +(defun ccm-scroll-up (&optional arg) + "Replaces `scroll-up' to be consistent with `ccm-scroll-down'. +This version actually moves the cursor with `previous-line'. +Since with centered-cursor-mode the cursor is in a fixed position +the movement appears as page up." + (interactive "P") + (let ((amt (or arg (- (window-text-height) + next-screen-context-lines)))) + (forward-line amt))) + + +(defun ccm-vpos-down (arg) + "Adjust the value of the screen line (where the cursor stays) by arg. +Negative values for arg are possible. Just the variable ccm-vpos +is set." + (interactive "p") + (or arg (setq arg 1)) + (let ((new-pos (if (< ccm-vpos 0) + (- ccm-vpos arg) + (+ ccm-vpos arg))) + ;; see pos-visible-in-window-p + (vpos-max (if (< ccm-vpos 0) + -1 + (- (window-text-height) 1))) + (vpos-min (if (< ccm-vpos 0) + (- (window-text-height)) + 0))) + (setq ccm-vpos + (cond + ((< new-pos vpos-min) + vpos-min) + ((> new-pos vpos-max) + vpos-max) + (t + new-pos))))) + +(defun ccm-vpos-up (arg) + "See `ccm-vpos-down'." + (interactive "p") + (or arg (setq arg 1)) + (ccm-vpos-down (- arg))) + +(defun ccm-vpos-recenter () + "Set the value of the screen line (where the cursor stays) in +the center. Just the variable ccm-vpos is set." + (interactive) + (if (equal (current-buffer) + (window-buffer (selected-window))) + (setq ccm-vpos (* (eval ccm-vpos-init) + ccm-vpos-inverted)))) + +(defun ccm-position-cursor () + "Do the actual recentering at the position `ccm-vpos'." + (unless (member this-command ccm-ignored-commands) + (unless ccm-vpos + (ccm-vpos-recenter)) + (unless (minibufferp (current-buffer)) + (if (equal (current-buffer) + (window-buffer (selected-window))) + (let* ((current-line + (if (< ccm-vpos 0) + ;; one-based, from bottom, negative + (- (count-lines (point) + ;; window-end is sometimes < 0 + ;; when opening a help buffer + (if (> (window-end) 0) + (window-end) + 1))) + ;; zero-based, from top, positive + (+ (count-lines (window-start) (point)) + ;; count-lines returns different value in column 0 + (if (= (current-column) 0) 0 -1)))) + (diff (- ccm-vpos current-line)) + (step-size ccm-step-size) + (step-delay ccm-step-delay) + (vpos-inverted ccm-vpos-inverted) + (recenter-at-end-of-file ccm-recenter-at-end-of-file)) + + (let* ((bottom-vpos (if (< ccm-vpos 0) + (- ccm-vpos) + (- (window-text-height) ccm-vpos))) + (correction (save-excursion + (if (or (= (point) (point-max)) + (progn + (goto-char (point-max)) + (zerop (current-column)))) + 1 0))) + (window-is-at-bottom (= (window-end) (point-max))) + ;; lines from point to end of buffer + (bottom-lines (if window-is-at-bottom + (+ (count-lines (point) (point-max)) + correction)))) + + ;; only animate if the point was moved rather far away + ;; before by a mouseclick (see ccm-ignored-commands) + ;; or if minor mode is just entered interactively + (if (not (and (> (abs diff) 4) + (or (member last-command ccm-ignored-commands) + animate-first-start-p))) + + (recenter (if (and window-is-at-bottom + (< bottom-lines bottom-vpos) + (not recenter-at-end-of-file)) + ;; if near the bottom, recenter in the + ;; negative screen line that equals the + ;; bottom buffer line, i.e. if we are in + ;; the second last line (-2) of the + ;; buffer, the cursor will be recentered + ;; in -2 + (- bottom-lines) + ccm-vpos)) + + (setq animate-first-start-p nil) + ;; first build a list with positions to successively recenter to + (setq recenter-sequence + ;; reverse: because we build the list not FROM -> TO but + ;; TO -> FROM because if step size in number-sequence is + ;; bigger than one, TO might not included, that means the + ;; ccm-vpos would not be reached + ;; cdr: don't recenter the current-line + (if (and window-is-at-bottom + (< bottom-lines bottom-vpos) + (not recenter-at-end-of-file)) + ;; this one is for animation near the bottom + (cdr (reverse (number-sequence + (- bottom-lines) + (if (< ccm-vpos 0) + current-line + (- (- (window-text-height) current-line))) + (* (/ diff (abs diff)) (- step-size))))) + (cdr (reverse (number-sequence + ccm-vpos + current-line + (* (/ diff (abs diff)) (- step-size))))))) + ;; (message "%d %d %d (%d): %S" current-line ccm-vpos bottom-lines diff recenter-sequence) + (while recenter-sequence + ;; actual animation + (recenter (pop recenter-sequence)) + (if (car recenter-sequence) (sit-for step-delay t)))))))))) + +(defun ccm-first-start (animate) + "Called from centered-cursor-mode. Animate at first start, if +centered-cursor-mode is called interactively." + (let ((animate-first-start-p animate)) + (ccm-vpos-recenter) + (ccm-position-cursor))) + +;;(defalias 'ccm 'centered-cursor-mode) +;;;###autoload +(define-minor-mode centered-cursor-mode + "Makes the cursor stay vertically in a defined +position (usually centered)." + :init-value nil +;; :lighter nil + :lighter " ¢" + :keymap ccm-map + (cond + (centered-cursor-mode + (ccm-first-start (interactive-p)) + (add-hook 'post-command-hook 'ccm-position-cursor t t) + (add-hook 'window-configuration-change-hook 'ccm-vpos-recenter t t)) + (t + (remove-hook 'post-command-hook 'ccm-position-cursor t) + (remove-hook 'window-configuration-change-hook 'ccm-vpos-recenter t)))) + + +(define-global-minor-mode global-centered-cursor-mode centered-cursor-mode + centered-cursor-mode) + +(provide 'centered-cursor-mode) + +;;; Help: +;; (info "(elisp)Defining Minor Modes") +;; (info "(elisp)Screen Lines") +;; (info "(elisp)Hooks") +;; (info "(elisp)Customization") +;; (find-function 'mwheel-scroll) + +;; Local Variables: +;; coding: utf-8 +;; End: + +;;; centered-cursor-mode.el ends here diff --git a/emacs.d/elpa/coffee-mode-20160111.332/coffee-mode-autoloads.el b/emacs.d/elpa/coffee-mode-20160111.332/coffee-mode-autoloads.el new file mode 100644 index 0000000..408a7f5 --- /dev/null +++ b/emacs.d/elpa/coffee-mode-20160111.332/coffee-mode-autoloads.el @@ -0,0 +1,32 @@ +;;; coffee-mode-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) + +;;;### (autoloads nil "coffee-mode" "coffee-mode.el" (22171 46582 +;;;;;; 0 0)) +;;; Generated autoloads from coffee-mode.el + +(autoload 'coffee-mode "coffee-mode" "\ +Major mode for editing CoffeeScript. + +\(fn)" t nil) + +(add-to-list 'auto-mode-alist '("\\.coffee\\'" . coffee-mode)) + +(add-to-list 'auto-mode-alist '("\\.iced\\'" . coffee-mode)) + +(add-to-list 'auto-mode-alist '("Cakefile\\'" . coffee-mode)) + +(add-to-list 'auto-mode-alist '("\\.cson\\'" . coffee-mode)) + +(add-to-list 'interpreter-mode-alist '("coffee" . coffee-mode)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; coffee-mode-autoloads.el ends here diff --git a/emacs.d/elpa/coffee-mode-20160111.332/coffee-mode-pkg.el b/emacs.d/elpa/coffee-mode-20160111.332/coffee-mode-pkg.el new file mode 100644 index 0000000..7bec4e0 --- /dev/null +++ b/emacs.d/elpa/coffee-mode-20160111.332/coffee-mode-pkg.el @@ -0,0 +1 @@ +(define-package "coffee-mode" "20160111.332" "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")) diff --git a/emacs.d/elpa/coffee-mode-20160111.332/coffee-mode.el b/emacs.d/elpa/coffee-mode-20160111.332/coffee-mode.el new file mode 100644 index 0000000..d53c5ee --- /dev/null +++ b/emacs.d/elpa/coffee-mode-20160111.332/coffee-mode.el @@ -0,0 +1,1332 @@ +;;; coffee-mode.el --- Major mode to edit CoffeeScript files in Emacs -*- lexical-binding: t; -*- + +;; Copyright (C) 2010 Chris Wanstrath + +;; Version: 0.6.2 +;; Package-Version: 20160111.332 +;; Keywords: CoffeeScript major mode +;; Author: Chris Wanstrath +;; URL: http://github.com/defunkt/coffee-mode +;; Package-Requires: ((emacs "24.1") (cl-lib "0.5")) + +;; This file is not part of GNU Emacs. + +;; 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 2, 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, write to the Free Software +;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +;;; Commentary + +;; Provides syntax highlighting, indentation support, imenu support, +;; compiling to JavaScript, REPL, a menu bar, and a few cute commands. + +;;; Code: + +(require 'comint) +(require 'easymenu) +(require 'font-lock) +(require 'rx) + +(require 'cl-lib) + +;; +;; Customizable Variables +;; + +(defconst coffee-mode-version "0.6.2" + "The version of `coffee-mode'.") + +(defgroup coffee nil + "A CoffeeScript major mode." + :group 'languages) + +(defcustom coffee-tab-width tab-width + "The tab width to use when indenting." + :type 'integer + :group 'coffee + :safe 'integerp) + +(defcustom coffee-command "coffee" + "The CoffeeScript command used for evaluating code." + :type 'string + :group 'coffee) + +(defcustom coffee-js-directory "" + "The directory for compiled JavaScript files output. This can +be an absolute path starting with a `/`, or it can be path +relative to the directory containing the coffeescript sources to +be compiled." + :type 'string + :group 'coffee) + +(defcustom js2coffee-command "js2coffee" + "The js2coffee command used for evaluating code." + :type 'string + :group 'coffee) + +(defcustom coffee-args-repl '("-i") + "The arguments to pass to `coffee-command' to start a REPL." + :type 'list + :group 'coffee) + +(defcustom coffee-args-compile '("-c" "--no-header") + "The arguments to pass to `coffee-command' to compile a file." + :type 'list + :group 'coffee) + +(defcustom coffee-compiled-buffer-name "*coffee-compiled*" + "The name of the scratch buffer used for compiled CoffeeScript." + :type 'string + :group 'coffee) + +(defcustom coffee-repl-buffer "*CoffeeREPL*" + "The name of the CoffeeREPL buffer." + :type 'string + :group 'coffee) + +(defcustom coffee-compile-jump-to-error t + "Whether to jump to the first error if compilation fails. +Since the coffee compiler does not always include a line number in +its error messages, this is not always possible." + :type 'boolean + :group 'coffee) + +(defcustom coffee-watch-buffer-name "*coffee-watch*" + "The name of the scratch buffer used when using the --watch flag +with CoffeeScript." + :type 'string + :group 'coffee) + +(defcustom coffee-mode-hook nil + "Hook called by `coffee-mode'. Examples: + + ;; Compile '.coffee' files on every save + (and (file-exists-p (buffer-file-name)) + (file-exists-p (coffee-compiled-file-name)) + (coffee-cos-mode t)))" + :type 'hook + :group 'coffee) + +(defcustom coffee-indent-tabs-mode nil + "Indentation can insert tabs if this is t." + :group 'coffee + :type 'boolean) + +(defcustom coffee-after-compile-hook nil + "Hook called after compile to Javascript" + :type 'hook + :group 'coffee) + +(defcustom coffee-indent-like-python-mode nil + "Indent like python-mode." + :type 'boolean + :group 'coffee) + +(defcustom coffee-switch-to-compile-buffer nil + "Switch to compilation buffer `coffee-compiled-buffer-name' after compiling +a buffer or region." + :type 'boolean + :group 'coffee) + +(defvar coffee-mode-map + (let ((map (make-sparse-keymap))) + ;; key bindings + (define-key map (kbd "A-r") 'coffee-compile-buffer) + (define-key map (kbd "C-c C-k") 'coffee-compile-buffer) + (define-key map (kbd "A-R") 'coffee-compile-region) + (define-key map (kbd "A-M-r") 'coffee-repl) + (define-key map (kbd "C-c C-z") 'coffee-repl) + (define-key map [remap comment-dwim] 'coffee-comment-dwim) + (define-key map [remap newline-and-indent] 'coffee-newline-and-indent) + (define-key map "\C-m" 'coffee-newline-and-indent) + (define-key map "\C-c\C-o\C-s" 'coffee-cos-mode) + (define-key map "\177" 'coffee-dedent-line-backspace) + (define-key map (kbd "C-c C-<") 'coffee-indent-shift-left) + (define-key map (kbd "C-c C->") 'coffee-indent-shift-right) + (define-key map (kbd "C-c C-l") 'coffee-send-line) + (define-key map (kbd "C-c C-r") 'coffee-send-region) + (define-key map (kbd "C-c C-b") 'coffee-send-buffer) + (define-key map (kbd "") 'coffee-indent-shift-left) + (define-key map (kbd "C-M-a") 'coffee-beginning-of-defun) + (define-key map (kbd "C-M-e") 'coffee-end-of-block) + (define-key map (kbd "C-M-h") 'coffee-mark-defun) + map) + "Keymap for CoffeeScript major mode.") + +;; +;; Commands +;; + +(defun coffee-comint-filter (string) + (ansi-color-apply + (replace-regexp-in-string + "\uFF00" "\n" + (replace-regexp-in-string "\x1b\\[.[GJK]" "" string)))) + +(defun coffee-repl () + "Launch a CoffeeScript REPL using `coffee-command' as an inferior mode." + (interactive) + + (unless (comint-check-proc coffee-repl-buffer) + (set-buffer + (apply 'make-comint "CoffeeREPL" + "env" + nil + "NODE_NO_READLINE=1" + coffee-command + coffee-args-repl)) + ;; Workaround for ansi colors + (add-hook 'comint-preoutput-filter-functions 'coffee-comint-filter nil t)) + + (pop-to-buffer coffee-repl-buffer)) + +(defun coffee-compiled-file-name (&optional filename) + ;; Returns the name of the JavaScript file compiled from a CoffeeScript file. + ;; If FILENAME is omitted, the current buffer's file name is used. + (let ((input (expand-file-name (or filename (buffer-file-name))))) + (unless (string= coffee-js-directory "") + (setq input + (expand-file-name + (concat (unless (file-name-absolute-p coffee-js-directory) + (file-name-directory input)) + (file-name-as-directory coffee-js-directory) + (file-name-nondirectory input))))) + (concat (file-name-sans-extension input) ".js"))) + +(defun coffee-revert-buffer-compiled-file (file-name) + "Revert a buffer of compiled file when the buffer exist and is not modified." + (let ((buffer (find-buffer-visiting file-name))) + (when (and buffer (not (buffer-modified-p buffer))) + (with-current-buffer buffer + (revert-buffer nil t))))) + +(defun coffee-parse-error-output (compiler-errstr) + (let* ((msg (car (split-string compiler-errstr "[\n\r]+"))) + line column) + (message msg) + (when (or (string-match "on line \\([0-9]+\\)" msg) + (string-match ":\\([0-9]+\\):\\([0-9]+\\): error:" msg)) + (setq line (string-to-number (match-string 1 msg))) + (when (match-string 2 msg) + (setq column (string-to-number (match-string 2 msg)))) + + (when coffee-compile-jump-to-error + (goto-char (point-min)) + (forward-line (1- line)) + (when column + (move-to-column (1- column))))))) + +(defun coffee-compile-file () + "Compiles and saves the current file to disk in a file of the same +base name, with extension `.js'. Subsequent runs will overwrite the +file. + +If there are compilation errors, point is moved to the first +See `coffee-compile-jump-to-error'." + (interactive) + (let* ((input (buffer-file-name)) + (basename (file-name-sans-extension input)) + (output (when (string-match-p "\\.js\\'" basename) ;; for Rails '.js.coffee' file + basename)) + (compile-cmd (coffee-command-compile input output)) + (compiler-output (shell-command-to-string compile-cmd))) + (if (string= compiler-output "") + (let ((file-name (coffee-compiled-file-name (buffer-file-name)))) + (message "Compiled and saved %s" (or output (concat basename ".js"))) + (coffee-revert-buffer-compiled-file file-name)) + (coffee-parse-error-output compiler-output)))) + +(defun coffee-compile-buffer () + "Compiles the current buffer and displays the JavaScript in a buffer +called `coffee-compiled-buffer-name'." + (interactive) + (coffee-compile-region (point-min) (point-max))) + +(defsubst coffee-generate-sourcemap-p () + (cl-find-if (lambda (opt) (member opt '("-m" "--map"))) coffee-args-compile)) + +(defun coffee--coffeescript-version () + (with-temp-buffer + (unless (zerop (process-file coffee-command nil t nil "--version")) + (error "Failed: 'coffee --version'")) + (goto-char (point-min)) + (let ((line (buffer-substring-no-properties (point) (line-end-position)))) + (when (string-match "[0-9.]+\\'" line) + (match-string-no-properties 0 line))))) + +(defun coffee--map-file-name (coffee-file) + (let* ((version (coffee--coffeescript-version)) + (extension (if (version<= "1.8" version) ".js.map" ".map"))) + ;; foo.js: foo.js.map(>= 1.8), foo.map(< 1.8) + (concat (file-name-sans-extension coffee-file) extension))) + +(defmacro coffee-save-window-if (bool &rest body) + `(if ,bool (save-selected-window ,@body) ,@body)) +(put 'coffee-save-window-if 'lisp-indent-function 1) + +(defun coffee-compile-sentinel (buffer file line column) + (lambda (proc _event) + (when (eq (process-status proc) 'exit) + (coffee-save-window-if (not coffee-switch-to-compile-buffer) + (pop-to-buffer (get-buffer coffee-compiled-buffer-name)) + (ansi-color-apply-on-region (point-min) (point-max)) + (goto-char (point-min)) + (if (not (= (process-exit-status proc) 0)) + (let ((compile-output (buffer-string))) + (with-current-buffer buffer + (coffee-parse-error-output compile-output))) + (let ((props (list :sourcemap (coffee--map-file-name file) + :line line :column column :source file))) + (let ((buffer-file-name "tmp.js")) + (setq buffer-read-only t) + (set-auto-mode) + (run-hook-with-args 'coffee-after-compile-hook props)))))))) + +(defun coffee-start-compile-process (curbuf line column) + (lambda (start end) + (let ((proc (apply 'start-file-process "coffee-mode" + (get-buffer-create coffee-compiled-buffer-name) + coffee-command (append coffee-args-compile '("-s" "-p")))) + (curfile (buffer-file-name curbuf))) + (set-process-query-on-exit-flag proc nil) + (set-process-sentinel + proc (coffee-compile-sentinel curbuf curfile line column)) + (with-current-buffer curbuf + (process-send-region proc start end)) + (process-send-eof proc)))) + +(defun coffee-start-generate-sourcemap-process (start end) + ;; so that sourcemap generation reads from the current buffer + (save-buffer) + (let* ((file (buffer-file-name)) + (sourcemap-buf (get-buffer-create "*coffee-sourcemap*")) + (proc (start-file-process "coffee-sourcemap" sourcemap-buf + coffee-command "-m" file)) + (curbuf (current-buffer)) + (line (line-number-at-pos)) + (column (current-column))) + (set-process-query-on-exit-flag proc nil) + (set-process-sentinel + proc + (lambda (proc _event) + (when (eq (process-status proc) 'exit) + (if (not (= (process-exit-status proc) 0)) + (let ((sourcemap-output + (with-current-buffer sourcemap-buf (buffer-string)))) + (with-current-buffer curbuf + (coffee-parse-error-output sourcemap-output))) + (kill-buffer sourcemap-buf) + (funcall (coffee-start-compile-process curbuf line column) start end))))))) + +(defun coffee-cleanup-compile-buffer () + (let ((buffer (get-buffer coffee-compiled-buffer-name))) + (when buffer + (with-current-buffer buffer + (setq buffer-read-only nil) + (erase-buffer))))) + +(defun coffee-compile-region (start end) + "Compiles a region and displays the JavaScript in a buffer called +`coffee-compiled-buffer-name'." + (interactive "r") + (coffee-cleanup-compile-buffer) + (if (coffee-generate-sourcemap-p) + (coffee-start-generate-sourcemap-process start end) + (funcall (coffee-start-compile-process + (current-buffer) (line-number-at-pos) (current-column)) + start end))) + +(defun coffee-get-repl-proc () + (unless (comint-check-proc coffee-repl-buffer) + (coffee-repl) + ;; see issue #332 + (sleep-for 0 100)) + (get-buffer-process coffee-repl-buffer)) + +(defun coffee-send-line () + "Send the current line to the inferior Coffee process." + (interactive) + (coffee-send-region (line-beginning-position) (line-end-position))) + +(defun coffee-send-region (start end) + "Send the current region to the inferior Coffee process." + (interactive "r") + (deactivate-mark t) + (let* ((string (buffer-substring-no-properties start end)) + (proc (coffee-get-repl-proc)) + (multiline-escaped-string + (replace-regexp-in-string "\n" "\uFF00" string))) + (comint-simple-send proc multiline-escaped-string))) + +(defun coffee-send-buffer () + "Send the current buffer to the inferior Coffee process." + (interactive) + (coffee-send-region (point-min) (point-max))) + +(defun coffee-js2coffee-replace-region (start end) + "Convert JavaScript in the region into CoffeeScript." + (interactive "r") + + (let ((buffer (get-buffer coffee-compiled-buffer-name))) + (when buffer + (kill-buffer buffer))) + + (call-process-region start end + js2coffee-command t + (current-buffer))) + +(defun coffee-version () + "Show the `coffee-mode' version in the echo area." + (interactive) + (message (concat "coffee-mode version " coffee-mode-version))) + +(defun coffee-watch (dir-or-file) + "Run `coffee-run-cmd' with the --watch flag on a directory or file." + (interactive "fDirectory or File: ") + (let ((coffee-compiled-buffer-name coffee-watch-buffer-name) + (args (mapconcat 'identity (append coffee-args-compile (list "--watch" (expand-file-name dir-or-file))) " "))) + (coffee-run-cmd args))) + +;; +;; Menubar +;; + +(easy-menu-define coffee-mode-menu coffee-mode-map + "Menu for CoffeeScript mode" + '("CoffeeScript" + ["Compile File" coffee-compile-file] + ["Compile Buffer" coffee-compile-buffer] + ["Compile Region" coffee-compile-region] + ["REPL" coffee-repl] + "---" + ["Version" coffee-version] + )) + +;; +;; Define Language Syntax +;; + +;; Instance variables (implicit this) +(defvar coffee-this-regexp "\\(?:@[_[:word:]]+\\|\\") + +;; Prototype::access +(defvar coffee-prototype-regexp "[_[:word:].$]+?::") + +;; Assignment +(defvar coffee-assign-regexp "\\(@?[_[:word:].$]+?\\)\\s-*:") + +;; Local Assignment +(defvar coffee-local-assign-regexp "\\s-*\\([_[:word:].$]+\\)\\s-*\\??=\\(?:[^>=]\\|$\\)") + +;; Lambda +(defvar coffee-lambda-regexp "\\(?:([^)]*)\\)?\\s-*\\(->\\|=>\\)") + +;; Namespaces +(defvar coffee-namespace-regexp "\\b\\(?:class\\s-+\\(\\S-+\\)\\)\\b") + +;; Booleans +(defvar coffee-boolean-regexp + (rx (or bol (not (any "."))) + (group symbol-start + (or "true" "false" "yes" "no" "on" "off" "null" "undefined") + symbol-end))) + +;; Regular expressions +(eval-and-compile + (defvar coffee-regexp-regexp "\\s/\\(\\(?:\\\\/\\|[^/\n\r]\\)*\\)\\s/")) + +;; JavaScript Keywords +(defvar coffee-js-keywords + '("if" "else" "new" "return" "try" "catch" + "finally" "throw" "break" "continue" "for" "in" "while" + "delete" "instanceof" "typeof" "switch" "super" "extends" + "class" "until" "loop" "yield")) + +;; Reserved keywords either by JS or CS. +(defvar coffee-js-reserved + '("case" "default" "do" "function" "var" "void" "with" + "const" "let" "debugger" "enum" "export" "import" "native" + "__extends" "__hasProp")) + +;; CoffeeScript keywords. +(defvar coffee-cs-keywords + '("then" "unless" "and" "or" "is" "own" + "isnt" "not" "of" "by" "when")) + +;; Iced CoffeeScript keywords +(defvar iced-coffee-cs-keywords + '("await" "defer")) + +;; Regular expression combining the above three lists. +(defvar coffee-keywords-regexp + ;; keywords can be member names. + (concat "\\(?:^\\|[^.]\\)" + (regexp-opt (append coffee-js-reserved + coffee-js-keywords + coffee-cs-keywords + iced-coffee-cs-keywords) 'symbols))) + +;; Create the list for font-lock. Each class of keyword is given a +;; particular face. +(defvar coffee-font-lock-keywords + ;; *Note*: order below matters. `coffee-keywords-regexp' goes last + ;; because otherwise the keyword "state" in the function + ;; "state_entry" would be highlighted. + `((,coffee-regexp-regexp . font-lock-constant-face) + (,coffee-this-regexp . font-lock-variable-name-face) + (,coffee-prototype-regexp . font-lock-type-face) + (,coffee-assign-regexp . font-lock-type-face) + (,coffee-local-assign-regexp 1 font-lock-variable-name-face) + (,coffee-boolean-regexp 1 font-lock-constant-face) + (,coffee-lambda-regexp 1 font-lock-function-name-face) + (,coffee-keywords-regexp 1 font-lock-keyword-face) + (,(lambda (limit) + (let ((res nil) + start) + (while (and (not res) (search-forward "#{" limit t)) + (let ((restart-pos (match-end 0))) + (setq start (match-beginning 0)) + (let (finish) + (while (and (not finish) (search-forward "}" limit t)) + (let ((end-pos (point))) + (save-excursion + (when (and (ignore-errors (backward-list 1)) + (= start (1- (point)))) + (setq res end-pos finish t))))) + (unless finish + (goto-char restart-pos))))) + (when (and res start) + (set-match-data (list start res))) + res)) + (0 font-lock-variable-name-face t)))) + +;; +;; Helper Functions +;; + +(defun coffee-comment-dwim (arg) + "Comment or uncomment current line or region in a smart way. +For details, see `comment-dwim'." + (interactive "*P") + (require 'newcomment) + (let ((deactivate-mark nil) (comment-start "#") (comment-end "")) + (comment-dwim arg) + (deactivate-mark t))) + +(defsubst coffee-command-compile-arg-as-string (output) + (mapconcat 'identity + (or (and output (append coffee-args-compile (list "-j" output))) + coffee-args-compile) + " ")) + +(defun coffee-command-compile (input &optional output) + "Run `coffee-command' to compile FILE-NAME to file with default +.js output file, or optionally to OUTPUT-FILE-NAME." + (let* ((full-file-name (expand-file-name input)) + (output-file (coffee-compiled-file-name full-file-name)) + (output-dir (file-name-directory output-file))) + (unless (file-directory-p output-dir) + (make-directory output-dir t)) + (format "%s %s -o %s %s" + (shell-quote-argument coffee-command) + (coffee-command-compile-arg-as-string output) + (shell-quote-argument output-dir) + (shell-quote-argument full-file-name)))) + +(defun coffee-run-cmd (args) + "Run `coffee-command' with the given arguments, and display the +output in a compilation buffer." + (interactive "sArguments: ") + (let ((compilation-buffer-name-function + (lambda (_this-mode) + (generate-new-buffer-name coffee-compiled-buffer-name)))) + (compile (concat coffee-command " " args)))) + +(defun coffee-toggle-fatness () + "Toggle fatness of a coffee function arrow." + (interactive) + (save-excursion + (when (re-search-backward "[-=]>" nil t) + (cond ((looking-at "=") (replace-match "-")) + ((looking-at "-") (replace-match "=")))))) + +;; +;; imenu support +;; + +(defconst coffee-imenu-index-regexp + (concat "^\\(\\s-*\\)" ; $1 + "\\(?:" + coffee-assign-regexp ; $2 + "\\s-*" + coffee-lambda-regexp + "\\|" + coffee-namespace-regexp ; $4 + "\\|" + "\\(@?[_[:word:]:.$]+\\)\\s-*=\\(?:[^>]\\|$\\)" ; $5 match prototype access too + "\\(?:" "\\s-*" "\\(" coffee-lambda-regexp "\\)" "\\)?" ; $6 + "\\)")) + +(defun coffee-imenu-create-index () + "Create an imenu index of all methods in the buffer." + (interactive) + + ;; This function is called within a `save-excursion' so we're safe. + (goto-char (point-min)) + + (let ((index-alist '()) + (ns-indent 0) + ns-name) + ;; Go through every assignment that includes -> or => on the same + ;; line or starts with `class'. + (while (re-search-forward coffee-imenu-index-regexp nil t) + (let ((current-indent (- (match-end 1) (match-beginning 1))) + (property-name (match-string-no-properties 2)) + (class-name (match-string-no-properties 4)) + (variable-name (match-string-no-properties 5)) + (func-assign (match-string-no-properties 6))) + + ;; If this is the start of a new namespace, save the namespace's + ;; indentation level and name. + (if class-name + (setq ns-name (concat class-name "::") + ns-indent current-indent) + (when (and variable-name (<= current-indent ns-indent)) + (setq ns-name (concat variable-name ".") + ns-indent current-indent))) + + (if func-assign + (push (cons variable-name (match-beginning 5)) index-alist) + (when (and ns-name property-name) + (let ((index-pos (match-beginning 2))) + (if (<= current-indent ns-indent) + ;; Clear the namespace if we're no longer indented deeper + (setq ns-name nil ns-indent nil) + ;; Register as index-name if we are within the context of a namespace + (push (cons (concat ns-name property-name) index-pos) index-alist))))))) + index-alist)) + +;; +;; Indentation +;; + +(defsubst coffee-insert-spaces (count) + (if coffee-indent-tabs-mode + (insert-char (string-to-char "\t") (floor count coffee-tab-width)) + (insert-char ? count))) + +;;; The theory is explained in the README. + +(defsubst coffee--in-string-or-comment-p () + (nth 8 (syntax-ppss))) + +(defun coffee--block-type () + (save-excursion + (back-to-indentation) + (unless (coffee--in-string-or-comment-p) + (cond ((looking-at-p "else\\(\\s-+if\\)?\\_>") 'if-else) + ((looking-at-p "\\(?:catch\\|finally\\)\\_>") 'try-catch))))) + +(defun coffee--closed-if-else-p (curindent if-indent) + (let (else-if-p else-p) + (when (looking-at "else\\(?:\\s-+\\(if\\)\\)?\\_>") + (if (string= (match-string 1) "if") + (setq else-if-p t) + (setq else-p t))) + (or (and (not (or else-p else-if-p)) (<= curindent if-indent)) + (and else-p (= curindent if-indent))))) + +(defun coffee--closed-try-catch-p (curindent if-indent) + (and (not (looking-at-p "\\(?:finally\\|catch\\)\\_>")) + (<= curindent if-indent))) + +(defun coffee--closed-block-p (type if-indent limit) + (let ((limit-line (line-number-at-pos limit)) + (closed-pred (cl-case type + (if-else 'coffee--closed-if-else-p) + (try-catch 'coffee--closed-try-catch-p))) + finish) + (save-excursion + (while (and (not finish) (< (point) limit)) + (forward-line 1) + (when (< (line-number-at-pos) limit-line) + (let ((curindent (current-indentation))) + (unless (coffee--in-string-or-comment-p) + (back-to-indentation) + (when (funcall closed-pred curindent if-indent) + (setq finish t)))))) + finish))) + +(defun coffee--find-if-else-indents (limit cmpfn) + (let (indents) + (while (re-search-forward "^\\s-*if\\_>" limit t) + (let ((indent (current-indentation))) + (unless (coffee--closed-block-p 'if-else indent limit) + (push indent indents)))) + (sort indents cmpfn))) + +(defun coffee--find-try-catch-indents (limit cmpfn) + (let (indents) + (while (re-search-forward "^\\s-*try\\_>" limit t) + (let ((indent (current-indentation))) + (unless (coffee--closed-block-p 'try-catch indent limit) + (push indent indents)))) + (sort indents cmpfn))) + +(defun coffee--find-indents (type limit cmpfn) + (save-excursion + (coffee-beginning-of-defun 1) + (cl-case type + (if-else (coffee--find-if-else-indents limit cmpfn)) + (try-catch (coffee--find-try-catch-indents limit cmpfn))))) + +(defsubst coffee--decide-indent (curindent if-indents cmpfn) + (cl-loop for if-indent in if-indents + when (funcall cmpfn if-indent curindent) + return if-indent + finally + return (car if-indents))) + +(defun coffee--indent-insert-spaces (indent-size) + (unless (= (current-indentation) indent-size) + (save-excursion + (goto-char (line-beginning-position)) + (delete-horizontal-space) + (coffee-insert-spaces indent-size))) + (when (< (current-column) (current-indentation)) + (back-to-indentation))) + +(defun coffee--indent-line-like-python-mode (prev-indent repeated) + (let ((next-indent (- (current-indentation) coffee-tab-width)) + (indent-p (coffee-line-wants-indent))) + (if repeated + (if (< next-indent 0) + (+ prev-indent (if indent-p coffee-tab-width 0)) + next-indent) + (+ prev-indent (if indent-p coffee-tab-width 0))))) + +(defun coffee-indent-line () + "Indent current line as CoffeeScript." + (interactive) + (let* ((curindent (current-indentation)) + (limit (+ (line-beginning-position) curindent)) + (type (coffee--block-type)) + indent-size + begin-indents) + (if (and type (setq begin-indents (coffee--find-indents type limit '<))) + (setq indent-size (coffee--decide-indent curindent begin-indents '>)) + (if coffee-indent-like-python-mode + (setq indent-size + (coffee--indent-line-like-python-mode + (coffee-previous-indent) (eq last-command this-command))) + (let ((prev-indent (coffee-previous-indent)) + (next-indent-size (+ curindent coffee-tab-width))) + (if (> (- next-indent-size prev-indent) coffee-tab-width) + (setq indent-size 0) + (setq indent-size (+ curindent coffee-tab-width)))))) + (coffee--indent-insert-spaces indent-size))) + +(defun coffee-previous-indent () + "Return the indentation level of the previous non-blank line." + (save-excursion + (forward-line -1) + (while (and (looking-at "^[ \t]*$") (not (bobp))) + (forward-line -1)) + (current-indentation))) + +(defun coffee-newline-and-indent () + "Insert a newline and indent it to the same level as the previous line." + (interactive) + + ;; Remember the current line indentation level, + ;; insert a newline, and indent the newline to the same + ;; level as the previous line. + (let ((prev-indent (current-indentation))) + (when (< (current-column) (current-indentation)) + (move-to-column (current-indentation))) + (delete-horizontal-space t) + (newline) + + (if (coffee-line-wants-indent) + ;; We need to insert an additional tab because the last line was special. + (coffee-insert-spaces (+ (coffee-previous-indent) coffee-tab-width)) + ;; otherwise keep at the same indentation level + (coffee-insert-spaces prev-indent)) + + ;; Last line was a comment so this one should probably be, + ;; too. Makes it easy to write multi-line comments (like the one I'm + ;; writing right now). + (unless (and auto-fill-function comment-auto-fill-only-comments) + (when (coffee-previous-line-is-single-line-comment) + (insert "# "))))) + +(defun coffee-dedent-line-backspace (arg) + "Unindent to increment of `coffee-tab-width' with ARG==1 when +called from first non-blank char of line. + +Delete ARG spaces if ARG!=1." + (interactive "*p") + (if (use-region-p) + (delete-region (region-beginning) (region-end)) + (if (and (= 1 arg) + (= (point) (save-excursion + (back-to-indentation) + (point))) + (not (bolp))) + (let* ((extra-space-count (% (current-column) coffee-tab-width)) + (deleted-chars (if (zerop extra-space-count) + coffee-tab-width + extra-space-count))) + (backward-delete-char-untabify deleted-chars)) + (backward-delete-char-untabify arg)))) + +;; Indenters help determine whether the current line should be +;; indented further based on the content of the previous line. If a +;; line starts with `class', for instance, you're probably going to +;; want to indent the next line. + +(defvar coffee-indenters-bol '("class" "for" "if" "else" "unless" "while" "until" + "try" "catch" "finally" "switch") + "Keywords or syntax whose presence at the start of a line means the +next line should probably be indented.") + +(defun coffee-indenters-bol-regexp () + "Builds a regexp out of `coffee-indenters-bol' words." + (regexp-opt coffee-indenters-bol 'words)) + +(defvar coffee-indenters-eol '(?> ?{ ?\[) + "Single characters at the end of a line that mean the next line +should probably be indented.") + +(defun coffee-line-wants-indent () + "Return t if the current line should be indented relative to the +previous line." + (save-excursion + (back-to-indentation) + (skip-chars-backward "\r\n\t ") + (let ((char-of-eol (char-before (line-end-position)))) + (or (and char-of-eol (memq char-of-eol coffee-indenters-eol)) + (progn + (back-to-indentation) + (looking-at (coffee-indenters-bol-regexp))))))) + +(defun coffee-previous-line-is-single-line-comment () + "Return t if the previous line is a CoffeeScript single line comment." + (save-excursion + (forward-line -1) + (back-to-indentation) + (and (looking-at "#") + (not (looking-at "###\\(?:\\s-+.*\\)?$")) + (progn + (goto-char (line-end-position)) + (nth 4 (syntax-ppss)))))) + +(defun coffee-indent-shift-amount (start end dir) + "Compute distance to the closest increment of `coffee-tab-width'." + (let ((min most-positive-fixnum)) + (save-excursion + (goto-char start) + (while (< (point) end) + (let ((current (current-indentation))) + (when (< current min) + (setq min current))) + (forward-line)) + (let ((rem (% min coffee-tab-width))) + (if (zerop rem) + coffee-tab-width + (cond ((eq dir 'left) rem) + ((eq dir 'right) (- coffee-tab-width rem)) + (t 0))))))) + +(defun coffee-indent-shift-left (start end &optional count) + "Shift lines contained in region START END by COUNT columns to the left. +If COUNT is not given, indents to the closest increment of +`coffee-tab-width'. If region isn't active, the current line is +shifted. The shifted region includes the lines in which START and +END lie. An error is signaled if any lines in the region are +indented less than COUNT columns." + (interactive + (if (use-region-p) + (list (region-beginning) (region-end) current-prefix-arg) + (list (line-beginning-position) (line-end-position) current-prefix-arg))) + (let ((amount (if count (* coffee-tab-width (prefix-numeric-value count)) + (coffee-indent-shift-amount start end 'left)))) + (when (> amount 0) + (let (deactivate-mark) + (save-excursion + (goto-char start) + ;; Check that all lines can be shifted enough + (while (< (point) end) + (if (and (< (current-indentation) amount) + (not (looking-at "[ \t]*$"))) + (error "Can't shift all lines enough")) + (forward-line)) + (indent-rigidly start end (- amount))))))) + +(add-to-list 'debug-ignored-errors "^Can't shift all lines enough") + +(defun coffee-indent-shift-right (start end &optional count) + "Shift lines contained in region START END by COUNT columns to the right. +if COUNT is not given, indents to the closest increment of +`coffee-tab-width'. If region isn't active, the current line is +shifted. The shifted region includes the lines in which START and +END lie." + (interactive + (if (use-region-p) + (list (region-beginning) (region-end) current-prefix-arg) + (list (line-beginning-position) (line-end-position) current-prefix-arg))) + (let (deactivate-mark + (amount (if count (* coffee-tab-width (prefix-numeric-value count)) + (coffee-indent-shift-amount start end 'right)))) + (indent-rigidly start end amount))) + +(defun coffee-indent-region (start end) + (interactive "r") + (save-excursion + (goto-char start) + (forward-line 1) + (while (and (not (eobp)) (< (point) end)) + (let ((prev-indent (coffee-previous-indent)) + (curindent (current-indentation)) + indent-size) + (if (coffee-line-wants-indent) + (let ((expected (+ prev-indent coffee-tab-width))) + (when (/= curindent expected) + (setq indent-size expected))) + (when (> curindent prev-indent) + (setq indent-size prev-indent))) + (when indent-size + (save-excursion + (goto-char (line-beginning-position)) + (delete-horizontal-space) + (coffee-insert-spaces indent-size)))) + (forward-line 1)))) + +;; +;; Fill +;; + +(defun coffee-fill-forward-paragraph-function (&optional count) + "`fill-forward-paragraph-function' which correctly handles block +comments such as the following: + + class Klass + method: -> + ### + This is a method doc comment that spans multiple lines. + If `fill-paragraph' is applied to this paragraph, the comment + should preserve its format, with the delimiters on separate lines. + ### + ..." + (let ((ret (forward-paragraph count))) + (when (and (= count -1) + (looking-at "[[:space:]]*###[[:space:]]*$")) + (forward-line)) + ret)) + +;; +;; Define navigation functions +;; + +(defconst coffee-defun-regexp + (concat "^\\s-*\\(?:" + coffee-assign-regexp + "\\s-*" + coffee-lambda-regexp + "\\|" + coffee-namespace-regexp + "\\|" + "@?[_[:word:]:.$]+\\s-*=\\(?:[^>]\\|$\\)" + "\\s-*" + coffee-lambda-regexp + "\\)")) + +(defun coffee-in-comment-p () + (unless (eobp) + (save-excursion + (back-to-indentation) + (when (eq (char-after) ?#) + (forward-char 1)) + (nth 4 (syntax-ppss))))) + +(defsubst coffee-current-line-empty-p () + (let ((line (buffer-substring-no-properties + (line-beginning-position) (line-end-position)))) + (string-match-p "^\\s-*$" line))) + +(defun coffee-current-line-is-defun () + (save-excursion + (goto-char (line-end-position)) + (re-search-backward coffee-defun-regexp (line-beginning-position) t))) + +(defun coffee-current-line-is-assignment () + (save-excursion + (goto-char (line-end-position)) + (re-search-backward "^[_[:word:].$]+\\s-*=\\(?:[^>]\\|$\\)" + (line-beginning-position) t))) + +(defun coffee-curline-defun-type (parent-indent start-is-defun) + (save-excursion + (goto-char (line-end-position)) + (if (not (re-search-backward coffee-defun-regexp (line-beginning-position) t)) + (when (and (zerop parent-indent) (coffee-current-line-is-assignment)) + 'other) + (if (not start-is-defun) + 'other + (if (< parent-indent (current-indentation)) + 'child + 'other))))) + +(defun coffee-same-block-p (block-indent start-is-defun) + (let ((type (coffee-curline-defun-type block-indent start-is-defun))) + (cond ((eq type 'child) t) + ((eq type 'other) nil) + (t (>= (current-indentation) block-indent))))) + +(defsubst coffee-skip-line-p () + (or (coffee-in-comment-p) (coffee-current-line-empty-p))) + +(defun coffee-skip-forward-lines (arg) + (let ((pred (if (> arg 0) + (lambda () (not (eobp))) + (lambda () (not (bobp)))))) + (while (and (funcall pred) (coffee-skip-line-p)) + (forward-line arg)))) + +(defun coffee-beginning-of-defun (&optional count) + (interactive "p") + (unless count + (setq count 1)) + (let ((next-indent nil)) + (when (coffee-skip-line-p) + (save-excursion + (coffee-skip-forward-lines +1) + (setq next-indent (current-indentation)))) + (coffee-skip-forward-lines -1) + (let ((start-indent (or next-indent (current-indentation)))) + (when (and (not (eq this-command 'coffee-mark-defun)) (looking-back "^\\s-*" (line-beginning-position))) + (forward-line -1)) + (let ((finish nil)) + (goto-char (line-end-position)) + (while (and (not finish) (re-search-backward coffee-defun-regexp nil 'move)) + (let ((cur-indent (current-indentation))) + (when (<= cur-indent start-indent) + (setq start-indent cur-indent) + (cl-decf count))) + (when (<= count 0) + (back-to-indentation) + (setq finish t))))))) + +(defun coffee-end-of-block (&optional count) + "Move point to the end of the block." + (interactive "p") + (unless count + (setq count 1)) + (dotimes (_i count) + (let* ((curline-is-defun (coffee-current-line-is-defun)) + start-indent) + (coffee-skip-forward-lines 1) + (setq start-indent (current-indentation)) + (when (and (zerop start-indent) (not curline-is-defun)) + (when (re-search-forward coffee-defun-regexp nil 'move) + (back-to-indentation) + (setq curline-is-defun t))) + (let ((finish nil)) + (while (not finish) + (forward-line 1) + (coffee-skip-forward-lines 1) + (when (or (not (coffee-same-block-p start-indent curline-is-defun)) + (eobp)) + (setq finish t))) + (forward-line -1) + (coffee-skip-forward-lines -1) + (forward-line 1))))) + +(defun coffee-mark-defun () + (interactive) + (let ((be-actived transient-mark-mode)) + (push-mark (point)) + (let ((cur-indent (current-indentation))) + (coffee-beginning-of-defun) + (push-mark (point)) + (coffee-end-of-block) + (push-mark (point) nil be-actived) + (let ((next-indent nil)) + (when (coffee-skip-line-p) + (save-excursion + (coffee-skip-forward-lines +1) + (setq next-indent (current-indentation)))) + (when (and next-indent (< next-indent cur-indent)) + (coffee-skip-forward-lines -1)) + (coffee-beginning-of-defun))))) + +;; +;; hs-minor-mode +;; + +;; support for hs-minor-mode +(add-to-list 'hs-special-modes-alist + '(coffee-mode "\\s-*\\(?:class\\|.+[-=]>$\\)" nil "#" + coffee-end-of-block nil)) + +;; +;; Based on triple quote of python.el +;; +(eval-and-compile + (defconst coffee-block-strings-delimiter + (rx (and + ;; Match even number of backslashes. + (or (not (any ?\\ ?\' ?\" ?/)) + point + ;; Quotes might be preceded by a escaped quote. + (and (or (not (any ?\\)) point) + ?\\ + (* ?\\ ?\\) + (any ?\' ?\" ?/))) + (* ?\\ ?\\) + ;; Match single or triple quotes of any kind. + (group (or "'''" "\"\"\"" "///")))))) + +(defsubst coffee-syntax-count-quotes (quote-char start-point limit) + (let ((i 0)) + (while (and (< i 3) + (< (+ start-point i) limit) + (eq (char-after (+ start-point i)) quote-char)) + (cl-incf i)) + i)) + +(defun coffee-syntax-block-strings-stringify () + (let* ((ppss (prog2 + (backward-char 3) + (syntax-ppss) + (forward-char 3))) + (string-start (and (not (nth 4 ppss)) (nth 8 ppss))) + (quote-starting-pos (- (point) 3)) + (quote-ending-pos (point)) + (num-closing-quotes + (and string-start + (coffee-syntax-count-quotes + (char-before) string-start quote-starting-pos)))) + (cond ((and string-start (= num-closing-quotes 0)) + ;; This set of quotes doesn't match the string starting + ;; kind. Do nothing. + nil) + ((not string-start) + ;; This set of quotes delimit the start of a string. + (put-text-property quote-starting-pos (1+ quote-starting-pos) + 'syntax-table (string-to-syntax "|"))) + ((= num-closing-quotes 3) + ;; This set of quotes delimit the end of a string. + (put-text-property (1- quote-ending-pos) quote-ending-pos + 'syntax-table (string-to-syntax "|")))))) + +(defun coffee-syntax-propertize-block-comment () + (let ((curpoint (point)) + (inhibit-changing-match-data t)) + (let* ((valid-comment-start nil) + (valid-comment-end (looking-at-p "#\\{0,2\\}\\s-*$")) + (ppss (prog2 + (backward-char 3) + (syntax-ppss) + (setq valid-comment-start (looking-back "^\\s-*" (line-beginning-position))) + (forward-char 3))) + (in-comment (nth 4 ppss)) + (in-string (nth 3 ppss))) + (when (or (and (not in-comment) (not in-string) valid-comment-start) + (and in-comment valid-comment-end)) + (put-text-property (- curpoint 3) curpoint + 'syntax-table (string-to-syntax "!")))))) + +(defsubst coffee--in-string-p () + (nth 3 (syntax-ppss))) + +(defun coffee-syntax-string-interpolation () + (let ((start (match-beginning 0)) + (end (point))) + (if (not (coffee--in-string-p)) + (put-text-property start (1+ start) + 'syntax-table (string-to-syntax "< b")) + (goto-char start) + (let (finish res) + (while (and (not finish) (search-forward "}" nil t)) + (let ((end-pos (match-end 0))) + (save-excursion + (when (and (ignore-errors (backward-list 1)) + (= start (1- (point)))) + (setq res end-pos finish t))))) + (goto-char end) + (when res + (while (re-search-forward "[\"'#]" res t) + (put-text-property (match-beginning 0) (match-end 0) + 'syntax-table (string-to-syntax "_"))) + (goto-char (1- res))))))) + +(defun coffee-syntax-propertize-function (start end) + (goto-char start) + (funcall + (syntax-propertize-rules + (coffee-block-strings-delimiter + (0 (ignore (coffee-syntax-block-strings-stringify)))) + ("/" + (0 (ignore + (let ((curpoint (point)) + (start (match-beginning 0)) + (end (match-end 0))) + (goto-char start) + (let ((ppss (syntax-ppss))) + (cond ((nth 8 ppss) + (put-text-property start end + 'syntax-table (string-to-syntax "_")) + (goto-char curpoint)) + ((looking-at coffee-regexp-regexp) + (put-text-property (match-beginning 1) (match-end 1) + 'syntax-table (string-to-syntax "_")) + (goto-char (match-end 0))) + (t (goto-char curpoint)))))))) + ("#{" (0 (ignore (coffee-syntax-string-interpolation)))) + ("###" + (0 (ignore (coffee-syntax-propertize-block-comment))))) + (point) end)) + +(defun coffee-get-comment-info () + (let* ((syntax (syntax-ppss)) + (commentp (nth 4 syntax)) + (comment-start-kinda (nth 8 syntax))) + (when commentp + (save-excursion + (if (and + (> comment-start-kinda 2) (< comment-start-kinda (point-max)) + (string= + "###" (buffer-substring + (- comment-start-kinda 2) (1+ comment-start-kinda)))) + 'multiple-line + 'single-line))))) + +(defun coffee-comment-line-break-fn (&optional _) + (let ((comment-type (coffee-get-comment-info)) + (coffee-indent-like-python-mode t)) + (comment-indent-new-line) + (cond ((eq comment-type 'multiple-line) + (save-excursion + (beginning-of-line) + (when (looking-at "[[:space:]]*\\(#\\)") + (replace-match "" nil nil nil 1)))) + ((eq comment-type 'single-line) + (coffee-indent-line))))) + +(defun coffee-auto-fill-fn () + (let ((comment-type (coffee-get-comment-info)) + (fill-result (do-auto-fill)) + (coffee-indent-like-python-mode t)) + (when (and fill-result (eq comment-type 'single-line)) + (save-excursion + (beginning-of-line) + (when (looking-at "[[:space:]]*#") + (replace-match "#"))) + (coffee-indent-line)))) + +;; +;; Define Major Mode +;; + +;;;###autoload +(define-derived-mode coffee-mode prog-mode "Coffee" + "Major mode for editing CoffeeScript." + + ;; code for syntax highlighting + (setq font-lock-defaults '((coffee-font-lock-keywords))) + + ;; fix comment filling function + (set (make-local-variable 'comment-line-break-function) + #'coffee-comment-line-break-fn) + (set (make-local-variable 'auto-fill-function) #'coffee-auto-fill-fn) + ;; perl style comment: "# ..." + (modify-syntax-entry ?# "< b" coffee-mode-syntax-table) + (modify-syntax-entry ?\n "> b" coffee-mode-syntax-table) + + ;; Treat slashes as paired delimiters; useful for finding regexps. + (modify-syntax-entry ?/ "/" coffee-mode-syntax-table) + + (set (make-local-variable 'comment-start) "#") + + ;; single quote strings + (modify-syntax-entry ?' "\"" coffee-mode-syntax-table) + + ;; indentation + (make-local-variable 'coffee-tab-width) + (make-local-variable 'coffee-indent-tabs-mode) + (set (make-local-variable 'indent-line-function) 'coffee-indent-line) + (set (make-local-variable 'indent-region-function) 'coffee-indent-region) + (set (make-local-variable 'tab-width) coffee-tab-width) + + (set (make-local-variable 'syntax-propertize-function) + 'coffee-syntax-propertize-function) + + ;; fill + (set (make-local-variable 'fill-forward-paragraph-function) + 'coffee-fill-forward-paragraph-function) + + (set (make-local-variable 'beginning-of-defun-function) + 'coffee-beginning-of-defun) + (set (make-local-variable 'end-of-defun-function) + 'coffee-end-of-block) + + ;; imenu + (set (make-local-variable 'imenu-create-index-function) + 'coffee-imenu-create-index) + + ;; Don't let electric-indent-mode break coffee-mode. + (set (make-local-variable 'electric-indent-functions) + (list (lambda (_arg) 'no-indent))) + + ;; no tabs + (setq indent-tabs-mode coffee-indent-tabs-mode)) + +;; +;; Compile-on-Save minor mode +;; + +(defcustom coffee-cos-mode-line " CoS" + "Lighter of `coffee-cos-mode'" + :type 'string + :group 'coffee) + +(define-minor-mode coffee-cos-mode + "Toggle compile-on-save for coffee-mode. + +Add `'(lambda () (coffee-cos-mode t))' to `coffee-mode-hook' to turn +it on by default." + :group 'coffee :lighter coffee-cos-mode-line + (if coffee-cos-mode + (add-hook 'after-save-hook 'coffee-compile-file nil t) + (remove-hook 'after-save-hook 'coffee-compile-file t))) + +(provide 'coffee-mode) + +;; +;; On Load +;; + +;; Run coffee-mode for files ending in .coffee. +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.coffee\\'" . coffee-mode)) +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.iced\\'" . coffee-mode)) +;;;###autoload +(add-to-list 'auto-mode-alist '("Cakefile\\'" . coffee-mode)) +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.cson\\'" . coffee-mode)) +;;;###autoload +(add-to-list 'interpreter-mode-alist '("coffee" . coffee-mode)) + +;;; coffee-mode.el ends here diff --git a/emacs.d/elpa/company-20150624.334/company-abbrev.el b/emacs.d/elpa/company-20150624.334/company-abbrev.el deleted file mode 100644 index 0a849ad..0000000 --- a/emacs.d/elpa/company-20150624.334/company-abbrev.el +++ /dev/null @@ -1,50 +0,0 @@ -;;; company-abbrev.el --- company-mode completion back-end for abbrev - -;; Copyright (C) 2009-2011, 2015 Free Software Foundation, Inc. - -;; Author: Nikolaj Schumacher - -;; This file is part of GNU Emacs. - -;; 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 of the License, 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. If not, see . - - -;;; Commentary: -;; - -;;; Code: - -(require 'company) -(require 'cl-lib) -(require 'abbrev) - -(defun company-abbrev-insert (match) - "Replace MATCH with the expanded abbrev." - (expand-abbrev)) - -;;;###autoload -(defun company-abbrev (command &optional arg &rest ignored) - "`company-mode' completion back-end for abbrev." - (interactive (list 'interactive)) - (cl-case command - (interactive (company-begin-backend 'company-abbrev - 'company-abbrev-insert)) - (prefix (company-grab-symbol)) - (candidates (nconc - (delete "" (all-completions arg global-abbrev-table)) - (delete "" (all-completions arg local-abbrev-table)))) - (meta (abbrev-expansion arg)))) - -(provide 'company-abbrev) -;;; company-abbrev.el ends here diff --git a/emacs.d/elpa/company-20150624.334/company-autoloads.el b/emacs.d/elpa/company-20150624.334/company-autoloads.el deleted file mode 100644 index 57c4e2f..0000000 --- a/emacs.d/elpa/company-20150624.334/company-autoloads.el +++ /dev/null @@ -1,284 +0,0 @@ -;;; company-autoloads.el --- automatically extracted autoloads -;; -;;; Code: -(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) - -;;;### (autoloads nil "company" "company.el" (21898 47982 0 0)) -;;; Generated autoloads from company.el - -(autoload 'company-mode "company" "\ -\"complete anything\"; is an in-buffer completion framework. -Completion starts automatically, depending on the values -`company-idle-delay' and `company-minimum-prefix-length'. - -Completion can be controlled with the commands: -`company-complete-common', `company-complete-selection', `company-complete', -`company-select-next', `company-select-previous'. If these commands are -called before `company-idle-delay', completion will also start. - -Completions can be searched with `company-search-candidates' or -`company-filter-candidates'. These can be used while completion is -inactive, as well. - -The completion data is retrieved using `company-backends' and displayed -using `company-frontends'. If you want to start a specific back-end, call -it interactively or use `company-begin-backend'. - -By default, the completions list is sorted alphabetically, unless the -backend chooses otherwise, or `company-transformers' changes it later. - -regular keymap (`company-mode-map'): - -\\{company-mode-map} -keymap during active completions (`company-active-map'): - -\\{company-active-map} - -\(fn &optional ARG)" t nil) - -(defvar global-company-mode nil "\ -Non-nil if Global-Company mode is enabled. -See the command `global-company-mode' for a description of this minor mode. -Setting this variable directly does not take effect; -either customize it (see the info node `Easy Customization') -or call the function `global-company-mode'.") - -(custom-autoload 'global-company-mode "company" nil) - -(autoload 'global-company-mode "company" "\ -Toggle Company mode in all buffers. -With prefix ARG, enable Global-Company mode if ARG is positive; -otherwise, disable it. If called from Lisp, enable the mode if -ARG is omitted or nil. - -Company mode is enabled in all buffers where -`company-mode-on' would do it. -See `company-mode' for more information on Company mode. - -\(fn &optional ARG)" t nil) - -;;;*** - -;;;### (autoloads nil "company-abbrev" "company-abbrev.el" (21898 -;;;;;; 47982 0 0)) -;;; Generated autoloads from company-abbrev.el - -(autoload 'company-abbrev "company-abbrev" "\ -`company-mode' completion back-end for abbrev. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-bbdb" "company-bbdb.el" (21898 47982 -;;;;;; 0 0)) -;;; Generated autoloads from company-bbdb.el - -(autoload 'company-bbdb "company-bbdb" "\ -`company-mode' completion back-end for BBDB. - -\(fn COMMAND &optional ARG &rest IGNORE)" t nil) - -;;;*** - -;;;### (autoloads nil "company-css" "company-css.el" (21898 47982 -;;;;;; 0 0)) -;;; Generated autoloads from company-css.el - -(autoload 'company-css "company-css" "\ -`company-mode' completion back-end for `css-mode'. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-dabbrev" "company-dabbrev.el" (21898 -;;;;;; 47982 0 0)) -;;; Generated autoloads from company-dabbrev.el - -(autoload 'company-dabbrev "company-dabbrev" "\ -dabbrev-like `company-mode' completion back-end. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-dabbrev-code" "company-dabbrev-code.el" -;;;;;; (21898 47982 0 0)) -;;; Generated autoloads from company-dabbrev-code.el - -(autoload 'company-dabbrev-code "company-dabbrev-code" "\ -dabbrev-like `company-mode' back-end for code. -The back-end looks for all symbols in the current buffer that aren't in -comments or strings. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-elisp" "company-elisp.el" (21898 47982 -;;;;;; 0 0)) -;;; Generated autoloads from company-elisp.el - -(autoload 'company-elisp "company-elisp" "\ -`company-mode' completion back-end for Emacs Lisp. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-etags" "company-etags.el" (21898 47982 -;;;;;; 0 0)) -;;; Generated autoloads from company-etags.el - -(autoload 'company-etags "company-etags" "\ -`company-mode' completion back-end for etags. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-files" "company-files.el" (21898 47982 -;;;;;; 0 0)) -;;; Generated autoloads from company-files.el - -(autoload 'company-files "company-files" "\ -`company-mode' completion back-end existing file names. -Completions works for proper absolute and relative files paths. -File paths with spaces are only supported inside strings. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-gtags" "company-gtags.el" (21898 47982 -;;;;;; 0 0)) -;;; Generated autoloads from company-gtags.el - -(autoload 'company-gtags "company-gtags" "\ -`company-mode' completion back-end for GNU Global. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-ispell" "company-ispell.el" (21898 -;;;;;; 47982 0 0)) -;;; Generated autoloads from company-ispell.el - -(autoload 'company-ispell "company-ispell" "\ -`company-mode' completion back-end using Ispell. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-keywords" "company-keywords.el" (21898 -;;;;;; 47982 0 0)) -;;; Generated autoloads from company-keywords.el - -(autoload 'company-keywords "company-keywords" "\ -`company-mode' back-end for programming language keywords. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-nxml" "company-nxml.el" (21898 47982 -;;;;;; 0 0)) -;;; Generated autoloads from company-nxml.el - -(autoload 'company-nxml "company-nxml" "\ -`company-mode' completion back-end for `nxml-mode'. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-oddmuse" "company-oddmuse.el" (21898 -;;;;;; 47982 0 0)) -;;; Generated autoloads from company-oddmuse.el - -(autoload 'company-oddmuse "company-oddmuse" "\ -`company-mode' completion back-end for `oddmuse-mode'. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-semantic" "company-semantic.el" (21898 -;;;;;; 47982 0 0)) -;;; Generated autoloads from company-semantic.el - -(autoload 'company-semantic "company-semantic" "\ -`company-mode' completion back-end using CEDET Semantic. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-tempo" "company-tempo.el" (21898 47982 -;;;;;; 0 0)) -;;; Generated autoloads from company-tempo.el - -(autoload 'company-tempo "company-tempo" "\ -`company-mode' completion back-end for tempo. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-xcode" "company-xcode.el" (21898 47982 -;;;;;; 0 0)) -;;; Generated autoloads from company-xcode.el - -(autoload 'company-xcode "company-xcode" "\ -`company-mode' completion back-end for Xcode projects. - -\(fn COMMAND &optional ARG &rest IGNORED)" t nil) - -;;;*** - -;;;### (autoloads nil "company-yasnippet" "company-yasnippet.el" -;;;;;; (21898 47982 0 0)) -;;; Generated autoloads from company-yasnippet.el - -(autoload 'company-yasnippet "company-yasnippet" "\ -`company-mode' back-end for `yasnippet'. - -This back-end should be used with care, because as long as there are -snippets defined for the current major mode, this back-end will always -shadow back-ends that come after it. Recommended usages: - -* In a buffer-local value of `company-backends', grouped with a back-end or - several that provide actual text completions. - - (add-hook 'js-mode-hook - (lambda () - (set (make-local-variable 'company-backends) - '((company-dabbrev-code company-yasnippet))))) - -* After keyword `:with', grouped with other back-ends. - - (push '(company-semantic :with company-yasnippet) company-backends) - -* Not in `company-backends', just bound to a key. - - (global-set-key (kbd \"C-c y\") 'company-yasnippet) - -\(fn COMMAND &optional ARG &rest IGNORE)" t nil) - -;;;*** - -;;;### (autoloads nil nil ("company-capf.el" "company-clang.el" "company-cmake.el" -;;;;;; "company-eclim.el" "company-pkg.el" "company-template.el") -;;;;;; (21898 47982 27553 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; company-autoloads.el ends here diff --git a/emacs.d/elpa/company-20150624.334/company-bbdb.el b/emacs.d/elpa/company-20150624.334/company-bbdb.el deleted file mode 100644 index 58be84c..0000000 --- a/emacs.d/elpa/company-20150624.334/company-bbdb.el +++ /dev/null @@ -1,61 +0,0 @@ -;;; company-bbdb.el --- company-mode completion back-end for BBDB in message-mode - -;; Copyright (C) 2013-2014 Free Software Foundation, Inc. - -;; Author: Jan Tatarik - -;; This file is part of GNU Emacs. - -;; 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 of the License, 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. If not, see . - -(require 'company) -(require 'cl-lib) - -(declare-function bbdb-record-get-field "bbdb") -(declare-function bbdb-records "bbdb") -(declare-function bbdb-dwim-mail "bbdb-com") -(declare-function bbdb-search "bbdb-com") - -(defgroup company-bbdb nil - "Completion back-end for BBDB." - :group 'company) - -(defcustom company-bbdb-modes '(message-mode) - "Major modes in which `company-bbdb' may complete." - :type '(repeat (symbol :tag "Major mode")) - :package-version '(company . "0.8.8")) - -(defun company-bbdb--candidates (arg) - (cl-mapcan (lambda (record) - (mapcar (lambda (mail) (bbdb-dwim-mail record mail)) - (bbdb-record-get-field record 'mail))) - (eval '(bbdb-search (bbdb-records) arg nil arg)))) - -;;;###autoload -(defun company-bbdb (command &optional arg &rest ignore) - "`company-mode' completion back-end for BBDB." - (interactive (list 'interactive)) - (cl-case command - (interactive (company-begin-backend 'company-bbdb)) - (prefix (and (memq major-mode company-bbdb-modes) - (featurep 'bbdb-com) - (looking-back "^\\(To\\|Cc\\|Bcc\\): *\\(.*\\)" - (line-beginning-position)) - (match-string-no-properties 2))) - (candidates (company-bbdb--candidates arg)) - (sorted t) - (no-cache t))) - -(provide 'company-bbdb) -;;; company-bbdb.el ends here diff --git a/emacs.d/elpa/company-20150624.334/company-capf.el b/emacs.d/elpa/company-20150624.334/company-capf.el deleted file mode 100644 index 17b739b..0000000 --- a/emacs.d/elpa/company-20150624.334/company-capf.el +++ /dev/null @@ -1,153 +0,0 @@ -;;; company-capf.el --- company-mode completion-at-point-functions back-end -*- lexical-binding: t -*- - -;; Copyright (C) 2013-2015 Free Software Foundation, Inc. - -;; Author: Stefan Monnier - -;; This file is part of GNU Emacs. - -;; 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 of the License, 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. If not, see . - - -;;; Commentary: -;; - -;;; Code: - -(require 'company) -(require 'cl-lib) - -(defvar company--capf-cache nil) - -(defun company--capf-data () - (let ((cache company--capf-cache)) - (if (and (equal (current-buffer) (car cache)) - (equal (point) (car (setq cache (cdr cache)))) - (equal (buffer-chars-modified-tick) (car (setq cache (cdr cache))))) - (cadr cache) - (let ((data (company--capf-data-real))) - (setq company--capf-cache - (list (current-buffer) (point) (buffer-chars-modified-tick) data)) - data)))) - -(defun company--capf-data-real () - (cl-letf* (((default-value 'completion-at-point-functions) - ;; Ignore tags-completion-at-point-function because it subverts - ;; company-etags in the default value of company-backends, where - ;; the latter comes later. - (remove 'tags-completion-at-point-function - (default-value 'completion-at-point-functions))) - (data (run-hook-wrapped 'completion-at-point-functions - ;; Ignore misbehaving functions. - #'completion--capf-wrapper 'optimist))) - (when (and (consp (cdr data)) (integer-or-marker-p (nth 1 data))) data))) - -(defun company-capf (command &optional arg &rest _args) - "`company-mode' back-end using `completion-at-point-functions'." - (interactive (list 'interactive)) - (pcase command - (`interactive (company-begin-backend 'company-capf)) - (`prefix - (let ((res (company--capf-data))) - (when res - (if (> (nth 2 res) (point)) - 'stop - (buffer-substring-no-properties (nth 1 res) (point)))))) - (`candidates - (let ((res (company--capf-data))) - (when res - (let* ((table (nth 3 res)) - (pred (plist-get (nthcdr 4 res) :predicate)) - (meta (completion-metadata - (buffer-substring (nth 1 res) (nth 2 res)) - table pred)) - (sortfun (cdr (assq 'display-sort-function meta))) - (candidates (completion-all-completions arg table pred (length arg))) - (last (last candidates)) - (base-size (and (numberp (cdr last)) (cdr last)))) - (when base-size - (setcdr last nil)) - (when sortfun - (setq candidates (funcall sortfun candidates))) - (if (not (zerop (or base-size 0))) - (let ((before (substring arg 0 base-size))) - (mapcar (lambda (candidate) - (concat before candidate)) - candidates)) - candidates))))) - (`sorted - (let ((res (company--capf-data))) - (when res - (let ((meta (completion-metadata - (buffer-substring (nth 1 res) (nth 2 res)) - (nth 3 res) (plist-get (nthcdr 4 res) :predicate)))) - (cdr (assq 'display-sort-function meta)))))) - (`match - ;; Can't just use 0 when base-size (see above) is non-zero. - (let ((start (if (get-text-property 0 'font-lock-face arg) - 0 - (next-single-property-change 0 'font-lock-face arg)))) - (when start - ;; completions-common-part comes first, but we can't just look for this - ;; value because it can be in a list. - (or - (let ((value (get-text-property start 'font-lock-face arg))) - (text-property-not-all start (length arg) - 'font-lock-face value arg)) - (length arg))))) - (`duplicates t) - (`no-cache t) ;Not much can be done here, as long as we handle - ;non-prefix matches. - (`meta - (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-docsig))) - (when f (funcall f arg)))) - (`doc-buffer - (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-doc-buffer))) - (when f (funcall f arg)))) - (`location - (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-location))) - (when f (funcall f arg)))) - (`annotation - (save-excursion - ;; FIXME: `company-begin' sets `company-point' after calling - ;; `company--begin-new'. We shouldn't rely on `company-point' here, - ;; better to cache the capf-data value instead. However: we can't just - ;; save the last capf-data value in `prefix', because that command can - ;; get called more often than `candidates', and at any point in the - ;; buffer (https://github.com/company-mode/company-mode/issues/153). - ;; We could try propertizing the returned prefix string, but it's not - ;; passed to `annotation', and `company-prefix' is set only after - ;; `company--strip-duplicates' is called. - (when company-point - (goto-char company-point)) - (let ((f (plist-get (nthcdr 4 (company--capf-data)) :annotation-function))) - (when f (funcall f arg))))) - (`require-match - (plist-get (nthcdr 4 (company--capf-data)) :company-require-match)) - (`init nil) ;Don't bother: plenty of other ways to initialize the code. - (`post-completion - (let* ((res (company--capf-data)) - (exit-function (plist-get (nthcdr 4 res) :exit-function)) - (table (nth 3 res)) - (pred (plist-get (nthcdr 4 res) :predicate))) - (if exit-function - ;; Follow the example of `completion--done'. - (funcall exit-function arg - (if (eq (try-completion arg table pred) t) - 'finished 'sole))))) - )) - -(provide 'company-capf) - -;;; company-capf.el ends here diff --git a/emacs.d/elpa/company-20150624.334/company-clang.el b/emacs.d/elpa/company-20150624.334/company-clang.el deleted file mode 100644 index 369f4a9..0000000 --- a/emacs.d/elpa/company-20150624.334/company-clang.el +++ /dev/null @@ -1,331 +0,0 @@ -;;; company-clang.el --- company-mode completion back-end for Clang -*- lexical-binding: t -*- - -;; Copyright (C) 2009, 2011, 2013-2015 Free Software Foundation, Inc. - -;; Author: Nikolaj Schumacher - -;; This file is part of GNU Emacs. - -;; 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 of the License, 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. If not, see . - - -;;; Commentary: -;; - -;;; Code: - -(require 'company) -(require 'company-template) -(require 'cl-lib) - -(defgroup company-clang nil - "Completion back-end for Clang." - :group 'company) - -(defcustom company-clang-executable - (executable-find "clang") - "Location of clang executable." - :type 'file) - -(defcustom company-clang-begin-after-member-access t - "When non-nil, automatic completion will start whenever the current -symbol is preceded by \".\", \"->\" or \"::\", ignoring -`company-minimum-prefix-length'. - -If `company-begin-commands' is a list, it should include `c-electric-lt-gt' -and `c-electric-colon', for automatic completion right after \">\" and -\":\".") - -(defcustom company-clang-arguments nil - "Additional arguments to pass to clang when completing. -Prefix files (-include ...) can be selected with `company-clang-set-prefix' -or automatically through a custom `company-clang-prefix-guesser'." - :type '(repeat (string :tag "Argument"))) - -(defcustom company-clang-prefix-guesser 'company-clang-guess-prefix - "A function to determine the prefix file for the current buffer." - :type '(function :tag "Guesser function" nil)) - -(defvar company-clang-modes '(c-mode c++-mode objc-mode) - "Major modes which clang may complete.") - -(defcustom company-clang-insert-arguments t - "When non-nil, insert function arguments as a template after completion." - :type 'boolean - :package-version '(company . "0.8.0")) - -;; prefix ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defvar company-clang--prefix nil) - -(defsubst company-clang--guess-pch-file (file) - (let ((dir (directory-file-name (file-name-directory file)))) - (when (equal (file-name-nondirectory dir) "Classes") - (setq dir (file-name-directory dir))) - (car (directory-files dir t "\\([^.]h\\|[^h]\\).pch\\'" t)))) - -(defsubst company-clang--file-substring (file beg end) - (with-temp-buffer - (insert-file-contents-literally file nil beg end) - (buffer-string))) - -(defun company-clang-guess-prefix () - "Try to guess the prefix file for the current buffer." - ;; Prefixes seem to be called .pch. Pre-compiled headers do, too. - ;; So we look at the magic number to rule them out. - (let* ((file (company-clang--guess-pch-file buffer-file-name)) - (magic-number (and file (company-clang--file-substring file 0 4)))) - (unless (member magic-number '("CPCH" "gpch")) - file))) - -(defun company-clang-set-prefix (&optional prefix) - "Use PREFIX as a prefix (-include ...) file for clang completion." - (interactive (let ((def (funcall company-clang-prefix-guesser))) - (unless (stringp def) - (setq def default-directory)) - (list (read-file-name "Prefix file: " - (when def (file-name-directory def)) - def t (when def (file-name-nondirectory def)))))) - ;; TODO: pre-compile? - (setq company-clang--prefix (and (stringp prefix) - (file-regular-p prefix) - prefix))) - -;; Clean-up on exit. -(add-hook 'kill-emacs-hook 'company-clang-set-prefix) - -;; parsing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; TODO: Handle Pattern (syntactic hints would be neat). -;; Do we ever see OVERLOAD (or OVERRIDE)? -(defconst company-clang--completion-pattern - "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)\\(?: : \\(.*\\)$\\)?$") - -(defconst company-clang--error-buffer-name "*clang-error*") - -(defun company-clang--lang-option () - (if (eq major-mode 'objc-mode) - (if (string= "m" (file-name-extension buffer-file-name)) - "objective-c" "objective-c++") - (substring (symbol-name major-mode) 0 -5))) - -(defun company-clang--parse-output (prefix _objc) - (goto-char (point-min)) - (let ((pattern (format company-clang--completion-pattern - (regexp-quote prefix))) - (case-fold-search nil) - lines match) - (while (re-search-forward pattern nil t) - (setq match (match-string-no-properties 1)) - (unless (equal match "Pattern") - (save-match-data - (when (string-match ":" match) - (setq match (substring match 0 (match-beginning 0))))) - (let ((meta (match-string-no-properties 2))) - (when (and meta (not (string= match meta))) - (put-text-property 0 1 'meta - (company-clang--strip-formatting meta) - match))) - (push match lines))) - lines)) - -(defun company-clang--meta (candidate) - (get-text-property 0 'meta candidate)) - -(defun company-clang--annotation (candidate) - (let ((ann (company-clang--annotation-1 candidate))) - (if (not (and ann (string-prefix-p "(*)" ann))) - ann - (with-temp-buffer - (insert ann) - (search-backward ")") - (let ((pt (1+ (point)))) - (re-search-forward ".\\_>" nil t) - (delete-region pt (point))) - (buffer-string))))) - -(defun company-clang--annotation-1 (candidate) - (let ((meta (company-clang--meta candidate))) - (cond - ((null meta) nil) - ((string-match "[^:]:[^:]" meta) - (substring meta (1+ (match-beginning 0)))) - ((string-match "\\((.*)[ a-z]*\\'\\)" meta) - (let ((paren (match-beginning 1))) - (if (not (eq (aref meta (1- paren)) ?>)) - (match-string 1 meta) - (with-temp-buffer - (insert meta) - (goto-char paren) - (substring meta (1- (search-backward "<")))))))))) - -(defun company-clang--strip-formatting (text) - (replace-regexp-in-string - "#]" " " - (replace-regexp-in-string "[<{[]#\\|#[>}]" "" text t) - t)) - -(defun company-clang--handle-error (res args) - (goto-char (point-min)) - (let* ((buf (get-buffer-create company-clang--error-buffer-name)) - (cmd (concat company-clang-executable " " (mapconcat 'identity args " "))) - (pattern (format company-clang--completion-pattern "")) - (err (if (re-search-forward pattern nil t) - (buffer-substring-no-properties (point-min) - (1- (match-beginning 0))) - ;; Warn the user more aggressively if no match was found. - (message "clang failed with error %d:\n%s" res cmd) - (buffer-string)))) - - (with-current-buffer buf - (let ((inhibit-read-only t)) - (erase-buffer) - (insert (current-time-string) - (format "\nclang failed with error %d:\n" res) - cmd "\n\n") - (insert err) - (setq buffer-read-only t) - (goto-char (point-min)))))) - -(defun company-clang--start-process (prefix callback &rest args) - (let ((objc (derived-mode-p 'objc-mode)) - (buf (get-buffer-create "*clang-output*")) - ;; Looks unnecessary in Emacs 25.1 and later. - (process-adaptive-read-buffering nil)) - (if (get-buffer-process buf) - (funcall callback nil) - (with-current-buffer buf - (erase-buffer) - (setq buffer-undo-list t)) - (let ((process (apply #'start-process "company-clang" buf - company-clang-executable args))) - (set-process-sentinel - process - (lambda (proc status) - (unless (string-match-p "hangup" status) - (funcall - callback - (let ((res (process-exit-status proc))) - (with-current-buffer buf - (unless (eq 0 res) - (company-clang--handle-error res args)) - ;; Still try to get any useful input. - (company-clang--parse-output prefix objc))))))) - (unless (company-clang--auto-save-p) - (send-region process (point-min) (point-max)) - (send-string process "\n") - (process-send-eof process)))))) - -(defsubst company-clang--build-location (pos) - (save-excursion - (goto-char pos) - (format "%s:%d:%d" - (if (company-clang--auto-save-p) buffer-file-name "-") - (line-number-at-pos) - (1+ (length - (encode-coding-region - (line-beginning-position) - (point) - 'utf-8 - t)))))) - -(defsubst company-clang--build-complete-args (pos) - (append '("-fsyntax-only" "-Xclang" "-code-completion-macros") - (unless (company-clang--auto-save-p) - (list "-x" (company-clang--lang-option))) - company-clang-arguments - (when (stringp company-clang--prefix) - (list "-include" (expand-file-name company-clang--prefix))) - (list "-Xclang" (format "-code-completion-at=%s" - (company-clang--build-location pos))) - (list (if (company-clang--auto-save-p) buffer-file-name "-")))) - -(defun company-clang--candidates (prefix callback) - (and (company-clang--auto-save-p) - (buffer-modified-p) - (basic-save-buffer)) - (when (null company-clang--prefix) - (company-clang-set-prefix (or (funcall company-clang-prefix-guesser) - 'none))) - (apply 'company-clang--start-process - prefix - callback - (company-clang--build-complete-args (- (point) (length prefix))))) - -(defun company-clang--prefix () - (if company-clang-begin-after-member-access - (company-grab-symbol-cons "\\.\\|->\\|::" 2) - (company-grab-symbol))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defconst company-clang-required-version 1.1) - -(defvar company-clang--version nil) - -(defun company-clang--auto-save-p () - (< company-clang--version 2.9)) - -(defsubst company-clang-version () - "Return the version of `company-clang-executable'." - (with-temp-buffer - (call-process company-clang-executable nil t nil "--version") - (goto-char (point-min)) - (if (re-search-forward "clang\\(?: version \\|-\\)\\([0-9.]+\\)" nil t) - (let ((ver (string-to-number (match-string-no-properties 1)))) - (if (> ver 100) - (/ ver 100) - ver)) - 0))) - -(defun company-clang (command &optional arg &rest ignored) - "`company-mode' completion back-end for Clang. -Clang is a parser for C and ObjC. Clang version 1.1 or newer is required. - -Additional command line arguments can be specified in -`company-clang-arguments'. Prefix files (-include ...) can be selected -with `company-clang-set-prefix' or automatically through a custom -`company-clang-prefix-guesser'. - -With Clang versions before 2.9, we have to save the buffer before -performing completion. With Clang 2.9 and later, buffer contents are -passed via standard input." - (interactive (list 'interactive)) - (cl-case command - (interactive (company-begin-backend 'company-clang)) - (init (when (memq major-mode company-clang-modes) - (unless company-clang-executable - (error "Company found no clang executable")) - (setq company-clang--version (company-clang-version)) - (when (< company-clang--version company-clang-required-version) - (error "Company requires clang version 1.1")))) - (prefix (and (memq major-mode company-clang-modes) - buffer-file-name - company-clang-executable - (not (company-in-string-or-comment)) - (or (company-clang--prefix) 'stop))) - (candidates (cons :async - (lambda (cb) (company-clang--candidates arg cb)))) - (meta (company-clang--meta arg)) - (annotation (company-clang--annotation arg)) - (post-completion (let ((anno (company-clang--annotation arg))) - (when (and company-clang-insert-arguments anno) - (insert anno) - (if (string-match "\\`:[^:]" anno) - (company-clang-objc-templatify anno) - (company-template-c-like-templatify - (concat arg anno)))))))) - -(provide 'company-clang) -;;; company-clang.el ends here diff --git a/emacs.d/elpa/company-20150624.334/company-cmake.el b/emacs.d/elpa/company-20150624.334/company-cmake.el deleted file mode 100644 index e2962f5..0000000 --- a/emacs.d/elpa/company-20150624.334/company-cmake.el +++ /dev/null @@ -1,198 +0,0 @@ -;;; company-cmake.el --- company-mode completion back-end for CMake - -;; Copyright (C) 2013-2014 Free Software Foundation, Inc. - -;; Author: Chen Bin -;; Version: 0.2 - -;; 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 . - -;;; Commentary: -;; -;; company-cmake offers completions for module names, variable names and -;; commands used by CMake. And their descriptions. - -;;; Code: - -(require 'company) -(require 'cl-lib) - -(defgroup company-cmake nil - "Completion back-end for CMake." - :group 'company) - -(defcustom company-cmake-executable - (executable-find "cmake") - "Location of cmake executable." - :type 'file) - -(defvar company-cmake-executable-arguments - '("--help-command-list" - "--help-module-list" - "--help-variable-list") - "The arguments we pass to cmake, separately. -They affect which types of symbols we get completion candidates for.") - -(defvar company-cmake--completion-pattern - "^\\(%s[a-zA-Z0-9_<>]%s\\)$" - "Regexp to match the candidates.") - -(defvar company-cmake-modes '(cmake-mode) - "Major modes in which cmake may complete.") - -(defvar company-cmake--candidates-cache nil - "Cache for the raw candidates.") - -(defvar company-cmake--meta-command-cache nil - "Cache for command arguments to retrieve descriptions for the candidates.") - -(defun company-cmake--replace-tags (rlt) - (setq rlt (replace-regexp-in-string - "\\(.*?\\(IS_GNU\\)?\\)\\(.*\\)" - (lambda (_match) - (mapconcat 'identity - (if (match-beginning 2) - '("\\1CXX\\3" "\\1C\\3" "\\1G77\\3") - '("\\1CXX\\3" "\\1C\\3" "\\1Fortran\\3")) - "\n")) - rlt t)) - (setq rlt (replace-regexp-in-string - "\\(.*\\)\\(.*\\)" - (mapconcat 'identity '("\\1DEBUG\\2" "\\1RELEASE\\2" - "\\1RELWITHDEBINFO\\2" "\\1MINSIZEREL\\2") - "\n") - rlt)) - rlt) - -(defun company-cmake--fill-candidates-cache (arg) - "Fill candidates cache if needed." - (let (rlt) - (unless company-cmake--candidates-cache - (setq company-cmake--candidates-cache (make-hash-table :test 'equal))) - - ;; If hash is empty, fill it. - (unless (gethash arg company-cmake--candidates-cache) - (with-temp-buffer - (let ((res (call-process company-cmake-executable nil t nil arg))) - (unless (zerop res) - (message "cmake executable exited with error=%d" res))) - (setq rlt (buffer-string))) - (setq rlt (company-cmake--replace-tags rlt)) - (puthash arg rlt company-cmake--candidates-cache)) - )) - -(defun company-cmake--parse (prefix content cmd) - (let ((start 0) - (pattern (format company-cmake--completion-pattern - (regexp-quote prefix) - (if (zerop (length prefix)) "+" "*"))) - (lines (split-string content "\n")) - match - rlt) - (dolist (line lines) - (when (string-match pattern line) - (let ((match (match-string 1 line))) - (when match - (puthash match cmd company-cmake--meta-command-cache) - (push match rlt))))) - rlt)) - -(defun company-cmake--candidates (prefix) - (let (results - cmd-opts - str) - - (unless company-cmake--meta-command-cache - (setq company-cmake--meta-command-cache (make-hash-table :test 'equal))) - - (dolist (arg company-cmake-executable-arguments) - (company-cmake--fill-candidates-cache arg) - (setq cmd-opts (replace-regexp-in-string "-list$" "" arg) ) - - (setq str (gethash arg company-cmake--candidates-cache)) - (when str - (setq results (nconc results - (company-cmake--parse prefix str cmd-opts))))) - results)) - -(defun company-cmake--unexpand-candidate (candidate) - (cond - ((string-match "^CMAKE_\\(C\\|CXX\\|Fortran\\)\\(_.*\\)$" candidate) - (setq candidate (concat "CMAKE_" (match-string 2 candidate)))) - - ;; C flags - ((string-match "^\\(.*_\\)IS_GNU\\(C\\|CXX\\|G77\\)$" candidate) - (setq candidate (concat (match-string 1 candidate) "IS_GNU"))) - - ;; C flags - ((string-match "^\\(.*_\\)OVERRIDE_\\(C\\|CXX\\|Fortran\\)$" candidate) - (setq candidate (concat (match-string 1 candidate) "OVERRIDE_"))) - - ((string-match "^\\(.*\\)\\(_DEBUG\\|_RELEASE\\|_RELWITHDEBINFO\\|_MINSIZEREL\\)\\(.*\\)$" candidate) - (setq candidate (concat (match-string 1 candidate) - "_" - (match-string 3 candidate))))) - candidate) - -(defun company-cmake--meta (candidate) - (let ((cmd-opts (gethash candidate company-cmake--meta-command-cache)) - result) - (setq candidate (company-cmake--unexpand-candidate candidate)) - - ;; Don't cache the documentation of every candidate (command) - ;; Cache in this case will cost too much memory. - (with-temp-buffer - (call-process company-cmake-executable nil t nil cmd-opts candidate) - ;; Go to the third line, trim it and return the result. - ;; Tested with cmake 2.8.9. - (goto-char (point-min)) - (forward-line 2) - (setq result (buffer-substring-no-properties (line-beginning-position) - (line-end-position))) - (setq result (replace-regexp-in-string "^[ \t\n\r]+" "" result)) - result))) - -(defun company-cmake--doc-buffer (candidate) - (let ((cmd-opts (gethash candidate company-cmake--meta-command-cache))) - - (setq candidate (company-cmake--unexpand-candidate candidate)) - (with-temp-buffer - (call-process company-cmake-executable nil t nil cmd-opts candidate) - ;; Go to the third line, trim it and return the doc buffer. - ;; Tested with cmake 2.8.9. - (goto-char (point-min)) - (forward-line 2) - (company-doc-buffer - (buffer-substring-no-properties (line-beginning-position) - (point-max)))))) - -(defun company-cmake (command &optional arg &rest ignored) - "`company-mode' completion back-end for CMake. -CMake is a cross-platform, open-source make system." - (interactive (list 'interactive)) - (cl-case command - (interactive (company-begin-backend 'company-cmake)) - (init (when (memq major-mode company-cmake-modes) - (unless company-cmake-executable - (error "Company found no cmake executable")))) - (prefix (and (memq major-mode company-cmake-modes) - (not (company-in-string-or-comment)) - (company-grab-symbol))) - (candidates (company-cmake--candidates arg)) - (meta (company-cmake--meta arg)) - (doc-buffer (company-cmake--doc-buffer arg)) - )) - -(provide 'company-cmake) -;;; company-cmake.el ends here diff --git a/emacs.d/elpa/company-20150624.334/company-css.el b/emacs.d/elpa/company-20150624.334/company-css.el deleted file mode 100644 index 28f6c2d..0000000 --- a/emacs.d/elpa/company-20150624.334/company-css.el +++ /dev/null @@ -1,442 +0,0 @@ -;;; company-css.el --- company-mode completion back-end for css-mode -*- lexical-binding: t -*- - -;; Copyright (C) 2009, 2011, 2014 Free Software Foundation, Inc. - -;; Author: Nikolaj Schumacher - -;; This file is part of GNU Emacs. - -;; 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 of the License, 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. If not, see . - -;;; Commentary: - -;;; Code: - -(require 'company) -(require 'cl-lib) - -(declare-function web-mode-language-at-pos "web-mode" (&optional pos)) - -(defconst company-css-property-alist - ;; see http://www.w3.org/TR/CSS21/propidx.html - '(("azimuth" angle "left-side" "far-left" "left" "center-left" "center" - "center-right" "right" "far-right" "right-side" "behind" "leftwards" - "rightwards") - ("background" background-color background-image background-repeat - background-attachment background-position - background-clip background-origin background-size) - ("background-attachment" "scroll" "fixed") - ("background-color" color "transparent") - ("background-image" uri "none") - ("background-position" percentage length "left" "center" "right" percentage - length "top" "center" "bottom" "left" "center" "right" "top" "center" - "bottom") - ("background-repeat" "repeat" "repeat-x" "repeat-y" "no-repeat") - ("border" border-width border-style border-color) - ("border-bottom" border) - ("border-bottom-color" border-color) - ("border-bottom-style" border-style) - ("border-bottom-width" border-width) - ("border-collapse" "collapse" "separate") - ("border-color" color "transparent") - ("border-left" border) - ("border-left-color" border-color) - ("border-left-style" border-style) - ("border-left-width" border-width) - ("border-right" border) - ("border-right-color" border-color) - ("border-right-style" border-style) - ("border-right-width" border-width) - ("border-spacing" length length) - ("border-style" border-style) - ("border-top" border) - ("border-top-color" border-color) - ("border-top-style" border-style) - ("border-top-width" border-width) - ("border-width" border-width) - ("bottom" length percentage "auto") - ("caption-side" "top" "bottom") - ("clear" "none" "left" "right" "both") - ("clip" shape "auto") - ("color" color) - ("content" "normal" "none" string uri counter "attr()" "open-quote" - "close-quote" "no-open-quote" "no-close-quote") - ("counter-increment" identifier integer "none") - ("counter-reset" identifier integer "none") - ("cue" cue-before cue-after) - ("cue-after" uri "none") - ("cue-before" uri "none") - ("cursor" uri "*" "auto" "crosshair" "default" "pointer" "move" "e-resize" - "ne-resize" "nw-resize" "n-resize" "se-resize" "sw-resize" "s-resize" - "w-resize" "text" "wait" "help" "progress") - ("direction" "ltr" "rtl") - ("display" "inline" "block" "list-item" "run-in" "inline-block" "table" - "inline-table" "table-row-group" "table-header-group" "table-footer-group" - "table-row" "table-column-group" "table-column" "table-cell" - "table-caption" "none") - ("elevation" angle "below" "level" "above" "higher" "lower") - ("empty-cells" "show" "hide") - ("float" "left" "right" "none") - ("font" font-style font-weight font-size "/" line-height - font-family "caption" "icon" "menu" "message-box" "small-caption" - "status-bar" "normal" "small-caps" - ;; CSS3 - font-stretch) - ("font-family" family-name generic-family) - ("font-size" absolute-size relative-size length percentage) - ("font-style" "normal" "italic" "oblique") - ("font-weight" "normal" "bold" "bolder" "lighter" "100" "200" "300" "400" - "500" "600" "700" "800" "900") - ("height" length percentage "auto") - ("left" length percentage "auto") - ("letter-spacing" "normal" length) - ("line-height" "normal" number length percentage) - ("list-style" list-style-type list-style-position list-style-image) - ("list-style-image" uri "none") - ("list-style-position" "inside" "outside") - ("list-style-type" "disc" "circle" "square" "decimal" "decimal-leading-zero" - "lower-roman" "upper-roman" "lower-greek" "lower-latin" "upper-latin" - "armenian" "georgian" "lower-alpha" "upper-alpha" "none") - ("margin" margin-width) - ("margin-bottom" margin-width) - ("margin-left" margin-width) - ("margin-right" margin-width) - ("margin-top" margin-width) - ("max-height" length percentage "none") - ("max-width" length percentage "none") - ("min-height" length percentage) - ("min-width" length percentage) - ("orphans" integer) - ("outline" outline-color outline-style outline-width) - ("outline-color" color "invert") - ("outline-style" border-style) - ("outline-width" border-width) - ("overflow" "visible" "hidden" "scroll" "auto" - ;; CSS3: - "no-display" "no-content") - ("padding" padding-width) - ("padding-bottom" padding-width) - ("padding-left" padding-width) - ("padding-right" padding-width) - ("padding-top" padding-width) - ("page-break-after" "auto" "always" "avoid" "left" "right") - ("page-break-before" "auto" "always" "avoid" "left" "right") - ("page-break-inside" "avoid" "auto") - ("pause" time percentage) - ("pause-after" time percentage) - ("pause-before" time percentage) - ("pitch" frequency "x-low" "low" "medium" "high" "x-high") - ("pitch-range" number) - ("play-during" uri "mix" "repeat" "auto" "none") - ("position" "static" "relative" "absolute" "fixed") - ("quotes" string string "none") - ("richness" number) - ("right" length percentage "auto") - ("speak" "normal" "none" "spell-out") - ("speak-header" "once" "always") - ("speak-numeral" "digits" "continuous") - ("speak-punctuation" "code" "none") - ("speech-rate" number "x-slow" "slow" "medium" "fast" "x-fast" "faster" - "slower") - ("stress" number) - ("table-layout" "auto" "fixed") - ("text-align" "left" "right" "center" "justify") - ("text-indent" length percentage) - ("text-transform" "capitalize" "uppercase" "lowercase" "none") - ("top" length percentage "auto") - ("unicode-bidi" "normal" "embed" "bidi-override") - ("vertical-align" "baseline" "sub" "super" "top" "text-top" "middle" - "bottom" "text-bottom" percentage length) - ("visibility" "visible" "hidden" "collapse") - ("voice-family" specific-voice generic-voice "*" specific-voice - generic-voice) - ("volume" number percentage "silent" "x-soft" "soft" "medium" "loud" - "x-loud") - ("white-space" "normal" "pre" "nowrap" "pre-wrap" "pre-line") - ("widows" integer) - ("width" length percentage "auto") - ("word-spacing" "normal" length) - ("z-index" "auto" integer) - ;; CSS3 - ("align-content" align-stretch "space-between" "space-around") - ("align-items" align-stretch "baseline") - ("align-self" align-items "auto") - ("animation" animation-name animation-duration animation-timing-function - animation-delay animation-iteration-count animation-direction - animation-fill-mode) - ("animation-delay" time) - ("animation-direction" "normal" "reverse" "alternate" "alternate-reverse") - ("animation-duration" time) - ("animation-fill-mode" "none" "forwards" "backwards" "both") - ("animation-iteration-count" integer "infinite") - ("animation-name" "none") - ("animation-play-state" "paused" "running") - ("animation-timing-function" transition-timing-function - "step-start" "step-end" "steps(,)") - ("backface-visibility" "visible" "hidden") - ("background-clip" background-origin) - ("background-origin" "border-box" "padding-box" "content-box") - ("background-size" length percentage "auto" "cover" "contain") - ("border-image" border-image-outset border-image-repeat border-image-source - border-image-slice border-image-width) - ("border-image-outset" length) - ("border-image-repeat" "stretch" "repeat" "round" "space") - ("border-image-source" uri "none") - ("border-image-slice" length) - ("border-image-width" length percentage) - ("border-radius" length) - ("border-top-left-radius" length) - ("border-top-right-radius" length) - ("border-bottom-left-radius" length) - ("border-bottom-right-radius" length) - ("box-decoration-break" "slice" "clone") - ("box-shadow" length color) - ("box-sizing" "content-box" "border-box") - ("break-after" "auto" "always" "avoid" "left" "right" "page" "column" - "avoid-page" "avoid-column") - ("break-before" break-after) - ("break-inside" "avoid" "auto") - ("columns" column-width column-count) - ("column-count" integer) - ("column-fill" "auto" "balance") - ("column-gap" length "normal") - ("column-rule" column-rule-width column-rule-style column-rule-color) - ("column-rule-color" color) - ("column-rule-style" border-style) - ("column-rule-width" border-width) - ("column-span" "all" "none") - ("column-width" length "auto") - ("filter" url "blur()" "brightness()" "contrast()" "drop-shadow()" - "grayscale()" "hue-rotate()" "invert()" "opacity()" "saturate()" "sepia()") - ("flex" flex-grow flex-shrink flex-basis) - ("flex-basis" percentage length "auto") - ("flex-direction" "row" "row-reverse" "column" "column-reverse") - ("flex-flow" flex-direction flex-wrap) - ("flex-grow" number) - ("flex-shrink" number) - ("flex-wrap" "nowrap" "wrap" "wrap-reverse") - ("font-feature-setting" normal string number) - ("font-kerning" "auto" "normal" "none") - ("font-language-override" "normal" string) - ("font-size-adjust" "none" number) - ("font-stretch" "normal" "ultra-condensed" "extra-condensed" "condensed" - "semi-condensed" "semi-expanded" "expanded" "extra-expanded" "ultra-expanded") - ("font-synthesis" "none" "weight" "style") - ("font-variant" font-variant-alternates font-variant-caps - font-variant-east-asian font-variant-ligatures font-variant-numeric - font-variant-position) - ("font-variant-alternates" "normal" "historical-forms" "stylistic()" - "styleset()" "character-variant()" "swash()" "ornaments()" "annotation()") - ("font-variant-caps" "normal" "small-caps" "all-small-caps" "petite-caps" - "all-petite-caps" "unicase" "titling-caps") - ("font-variant-east-asian" "jis78" "jis83" "jis90" "jis04" "simplified" - "traditional" "full-width" "proportional-width" "ruby") - ("font-variant-ligatures" "normal" "none" "common-ligatures" - "no-common-ligatures" "discretionary-ligatures" "no-discretionary-ligatures" - "historical-ligatures" "no-historical-ligatures" "contextual" "no-contextual") - ("font-variant-numeric" "normal" "ordinal" "slashed-zero" - "lining-nums" "oldstyle-nums" "proportional-nums" "tabular-nums" - "diagonal-fractions" "stacked-fractions") - ("font-variant-position" "normal" "sub" "super") - ("hyphens" "none" "manual" "auto") - ("justify-content" align-common "space-between" "space-around") - ("line-break" "auto" "loose" "normal" "strict") - ("marquee-direction" "forward" "reverse") - ("marquee-play-count" integer "infinite") - ("marquee-speed" "slow" "normal" "fast") - ("marquee-style" "scroll" "slide" "alternate") - ("opacity" number) - ("order" number) - ("outline-offset" length) - ("overflow-x" overflow) - ("overflow-y" overflow) - ("overflow-style" "auto" "marquee-line" "marquee-block") - ("overflow-wrap" "normal" "break-word") - ("perspective" "none" length) - ("perspective-origin" percentage length "left" "center" "right" "top" "bottom") - ("resize" "none" "both" "horizontal" "vertical") - ("tab-size" integer length) - ("text-align-last" "auto" "start" "end" "left" "right" "center" "justify") - ("text-decoration" text-decoration-color text-decoration-line text-decoration-style) - ("text-decoration-color" color) - ("text-decoration-line" "none" "underline" "overline" "line-through" "blink") - ("text-decoration-style" "solid" "double" "dotted" "dashed" "wavy") - ("text-overflow" "clip" "ellipsis") - ("text-shadow" color length) - ("text-underline-position" "auto" "under" "left" "right") - ("transform" "matrix(,,,,,)" "translate(,)" "translateX()" "translateY()" - "scale()" "scaleX()" "scaleY()" "rotate()" "skewX()" "skewY()" "none") - ("transform-origin" perspective-origin) - ("transform-style" "flat" "preserve-3d") - ("transition" transition-property transition-duration - transition-timing-function transition-delay) - ("transition-delay" time) - ("transition-duration" time) - ("transition-timing-function" - "ease" "linear" "ease-in" "ease-out" "ease-in-out" "cubic-bezier(,,,)") - ("transition-property" "none" "all" identifier) - ("word-wrap" overflow-wrap) - ("word-break" "normal" "break-all" "keep-all")) - "A list of CSS properties and their possible values.") - -(defconst company-css-value-classes - '((absolute-size "xx-small" "x-small" "small" "medium" "large" "x-large" - "xx-large") - (align-common "flex-start" "flex-end" "center") - (align-stretch align-common "stretch") - (border-style "none" "hidden" "dotted" "dashed" "solid" "double" "groove" - "ridge" "inset" "outset") - (border-width "thick" "medium" "thin") - (color "aqua" "black" "blue" "fuchsia" "gray" "green" "lime" "maroon" "navy" - "olive" "orange" "purple" "red" "silver" "teal" "white" "yellow") - (counter "counter(,)") - (family-name "Courier" "Helvetica" "Times") - (generic-family "serif" "sans-serif" "cursive" "fantasy" "monospace") - (generic-voice "male" "female" "child") - (margin-width "auto") ;; length percentage - (relative-size "larger" "smaller") - (shape "rect(,,,)") - (uri "url()")) - "A list of CSS property value classes and their contents.") -;; missing, because not completable -;; -;;