From 422c61a02a42be5a008492d4e0f76005e41e04fb Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 22 Oct 2019 03:55:13 -0400 Subject: [PATCH] term/eshell: integrate company + pcomplete --- modules/term/eshell/autoload/company.el | 57 +++++++++++++++++++++++++ modules/term/eshell/autoload/eshell.el | 8 +++- modules/term/eshell/config.el | 10 ++++- 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 modules/term/eshell/autoload/company.el diff --git a/modules/term/eshell/autoload/company.el b/modules/term/eshell/autoload/company.el new file mode 100644 index 000000000..6086f7424 --- /dev/null +++ b/modules/term/eshell/autoload/company.el @@ -0,0 +1,57 @@ +;;; term/eshell/autoload/company.el -*- lexical-binding: t; -*- +;;;###if (featurep! :completion company) + +;; REVIEW Refactor me + +(defvar company-pcomplete-available 'unknown) + +(defun company-pcomplete--prefix () + (let* ((pcomplete-stub) + pcomplete-seen + pcomplete-norm-func + pcomplete-args + pcomplete-last pcomplete-index + (pcomplete-autolist pcomplete-autolist) + (pcomplete-suffix-list pcomplete-suffix-list)) + (pcomplete-completions) + (buffer-substring (pcomplete-begin) (point)))) + +(defun company-pcomplete--candidates () + (let* ((pcomplete-stub) + (pcomplete-show-list t) + pcomplete-seen pcomplete-norm-func + pcomplete-args pcomplete-last pcomplete-index + (pcomplete-autolist pcomplete-autolist) + (pcomplete-suffix-list pcomplete-suffix-list) + (candidates (pcomplete-completions)) + (prefix (buffer-substring (pcomplete-begin) (point))) + ;; Collect all possible completions for the current stub + (cnds (all-completions pcomplete-stub candidates)) + (bnds (completion-boundaries pcomplete-stub candidates nil "")) + (skip (- (length pcomplete-stub) (car bnds)))) + ;; Replace the stub at the beginning of each candidate by the prefix + (mapcar (lambda (cand) + (concat prefix (substring cand skip))) + cnds))) + +(defun company-pcomplete-available () + (when (eq company-pcomplete-available 'unknown) + (condition-case _err + (progn + (company-pcomplete--candidates) + (setq company-pcomplete-available t)) + (error + (message "Company: pcomplete not found") + (setq company-pcomplete-available nil)))) + company-pcomplete-available) + +;;;###autoload +(defun company-pcomplete (command &optional _arg &rest ignored) + "`company-mode' completion backend using `pcomplete'." + (interactive (list 'interactive)) + (cl-case command + (interactive (company-begin-backend 'company-pcomplete)) + (prefix (when (company-pcomplete-available) + (company-pcomplete--prefix))) + (candidates (company-pcomplete--candidates)) + (sorted t))) diff --git a/modules/term/eshell/autoload/eshell.el b/modules/term/eshell/autoload/eshell.el index cadcd20dd..2468012e9 100644 --- a/modules/term/eshell/autoload/eshell.el +++ b/modules/term/eshell/autoload/eshell.el @@ -175,7 +175,13 @@ Once the eshell process is killed, the previous frame layout is restored." bottom. This ties pcomplete into ivy or helm, if they are enabled." (interactive) (require 'pcomplete) - (ignore-errors (pcomplete-std-complete))) + (if (and (bound-and-true-p company-mode) + (or company-candidates + (and (company-pcomplete-available) + (company-pcomplete--prefix) + (company-pcomplete--candidates)))) + (call-interactively #'company-pcomplete) + (ignore-errors (pcomplete-std-complete)))) ;;;###autoload (defun +eshell/quit-or-delete-char (arg) diff --git a/modules/term/eshell/config.el b/modules/term/eshell/config.el index ef9fa5185..f07a3d43a 100644 --- a/modules/term/eshell/config.el +++ b/modules/term/eshell/config.el @@ -151,7 +151,15 @@ You should use `set-eshell-alias!' to change this.") [remap doom/backward-to-bol-or-indent] #'eshell-bol [remap doom/backward-kill-to-bol-and-indent] #'eshell-kill-input [remap evil-window-split] #'+eshell/split-below - [remap evil-window-vsplit] #'+eshell/split-right)))) + [remap evil-window-vsplit] #'+eshell/split-right))) + (add-hook! 'eshell-mode-hook + (defun +eshell-init-company-h () + (when (featurep! :completion company) + (company-mode +1) + (setq-local company-backends '(company-pcomplete)) + (setq-local company-frontends (cons 'company-tng-frontend company-frontends)) + (when (bound-and-true-p evil-local-mode) + (evil-normalize-keymaps)))))) (use-package! eshell-up