diff options
author | Thierry Volpiatto <thierry.volpiatto@gmail.com> | 2012-03-22 12:58:42 +0100 |
---|---|---|
committer | Thierry Volpiatto <thierry.volpiatto@gmail.com> | 2012-03-22 12:58:42 +0100 |
commit | 00184513fe985b05965ce51ebf4156c6815e783e (patch) | |
tree | 9d9a2682d26270df10c3834893e6976b3a545ec2 /helm-eshell.el | |
parent | 7946b64e3319eb666db7e6b5304d38365c67bf45 (diff) |
* helm-config.el: Move pcomplete and eshell hist to helm-eshell.el
* helm-eshell.el: new file.
Diffstat (limited to 'helm-eshell.el')
-rw-r--r-- | helm-eshell.el | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/helm-eshell.el b/helm-eshell.el new file mode 100644 index 00000000..bd38781f --- /dev/null +++ b/helm-eshell.el @@ -0,0 +1,128 @@ +;;; helm-eshell.el --- pcomplete and eshell completion for helm. + +;; Copyright (C) 2012 Thierry Volpiatto <thierry.volpiatto@gmail.com> + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: +(eval-when-compile (require 'cl)) +(require 'helm) +(require 'helm-elisp) +(require 'helm-regexp) + +;; Enable like this in .emacs: +;; +;; (add-hook 'eshell-mode-hook +;; #'(lambda () +;; (define-key eshell-mode-map [remap pcomplete] 'helm-esh-pcomplete))) +;; + +(defvar helm-eshell-history-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "M-p") 'helm-next-line) + map) + "Keymap for `helm-eshell-history'.") + +(defvar helm-c-source-esh + '((name . "Eshell completions") + (init . (lambda () + (setq pcomplete-current-completions nil + pcomplete-last-completion-raw nil) + ;; Eshell-command add this hook in all minibuffers + ;; Remove it for the helm one. (Fixed in Emacs24) + (remove-hook 'minibuffer-setup-hook 'eshell-mode))) + (candidates . helm-esh-get-candidates) + (action . helm-ec-insert)) + "Helm source for Eshell completion.") + +;; Internal. +(defvar helm-ec-target "") +(defun helm-ec-insert (candidate) + "Replace text at point with CANDIDATE. +The function that call this should set `helm-ec-target' to thing at point." + (let ((pt (point))) + (when (and helm-ec-target + (search-backward helm-ec-target nil t) + (string= (buffer-substring (point) pt) helm-ec-target)) + (delete-region (point) pt))) + (insert (helm-quote-whitespace candidate))) + +(defun helm-esh-get-candidates () + "Get candidates for eshell completion using `pcomplete'." + (catch 'pcompleted + (let* ((pcomplete-stub) + pcomplete-seen pcomplete-norm-func + pcomplete-args pcomplete-last pcomplete-index + (pcomplete-autolist pcomplete-autolist) + (pcomplete-suffix-list pcomplete-suffix-list)) + (with-helm-current-buffer + (loop with table = (pcomplete-completions) + with entry = (condition-case nil + ;; On Emacs24 `try-completion' return + ;; pattern when more than one result. + ;; Otherwise Emacs23 return nil, which + ;; is wrong, in this case use pattern + ;; to behave like Emacs24. + (or (try-completion helm-pattern + (pcomplete-entries)) + helm-pattern) + ;; In Emacs23 `pcomplete-entries' may fail + ;; with error, so try this instead. + (error + nil + (let ((fc (car (last + (pcomplete-parse-arguments))))) + ;; Check if last arg require fname completion. + (and (file-name-directory fc) fc)))) + for i in (all-completions pcomplete-stub table) + for file-cand = (and entry + (if (file-remote-p i) i + (expand-file-name + i (file-name-directory entry)))) + if (and file-cand (or (file-remote-p file-cand) + (file-exists-p file-cand))) + collect file-cand into ls + else collect i into ls + finally return + (if (and entry (not (string= entry "")) (file-exists-p entry)) + (append (list (expand-file-name entry default-directory)) ls) + ls)))))) + +;;; Eshell history. +;; +;; +(defvar helm-c-source-eshell-history + `((name . "Eshell history") + (init . (lambda () + (let (eshell-hist-ignoredups) + ;; Write the content's of ring to file. + (eshell-write-history eshell-history-file-name t) + (with-current-buffer (helm-candidate-buffer 'global) + (insert-file-contents eshell-history-file-name))) + ;; Same comment as in `helm-c-source-esh' + (remove-hook 'minibuffer-setup-hook 'eshell-mode))) + (candidates-in-buffer) + (keymap . ,helm-eshell-history-map) + (filtered-candidate-transformer . (lambda (candidates sources) + (reverse candidates))) + (candidate-number-limit . 9999) + (action . (lambda (candidate) + (eshell-kill-input) + (insert candidate)))) + "Helm source for Eshell history.") + +(provide 'helm-eshell) + +;;; helm-eshell ends here |