nixos/pkgsets/emacs/company.nix

171 lines
7.5 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
# Source: https://github.com/Henry/dot-emacs/blob/master/my-lisp/company-pcomplete.el
company-pcomplete = pkgs.writeText "company-pcomplete.el" ''
;;; company-pcomplete.el --- company-mode pcomplete backend -*- lexical-binding: t -*-
;; Copyright (C) 2016 Free Software Foundation, Inc.
;; Author: Henry G. Weller
;; 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 <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; Based on `ac-pcomplete', see https://www.emacswiki.org/emacs/EshellCompletion
;; and `pcomplete`, see pcomplete.el.
;;; Code:
(require 'company)
(require 'cl-lib)
(require 'pcomplete)
(defgroup company-pcomplete nil
"Completion backend using pcomplete."
:group 'company)
(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)))
(provide 'company-pcomplete)
'';
in mkIf (elem "emacs::company" config.machine.pkgs) {
programs.emacs.init.usePackage = {
company = {
enable = true;
package = epkgs: [ epkgs.company epkgs.company-web ];
diminish = [ "company-mode" ];
hook = [ "(after-init . global-company-mode)" ]
++ optional (elem "emacs::rust" config.machine.pkgs)
''(rust-mode . (lambda () (setq company-backends '((company-capf :with company-yasnippet)))))''
++ optional (elem "emacs::web-mode" config.machine.pkgs)
''(web-mode . (lambda () (set (make-local-variable 'company-backends) '(company-web-html company-css))
(company-mode t)))'';
bind = { "\t" = "'company-complete-common"; };
init = ''(require 'ffap)'';
config = ''
;; (setq company-tooltip-align-annotations t)
(setq company-idle-delay 0.3
company-show-numbers t)
${optionalString
(elem "emacs::org" config.machine.pkgs) ''
(load-file "${company-pcomplete}")''
}
'';
extraConfig = ''
:bind (:map company-mode-map
([remap completion-at-point] . company-complete-common)
([remap complete-symbol] . company-complete-common))
'';
};
company-box = {
enable = true;
hook = [ "(company-mode . (lambda () (company-box-mode)))" ];
config = ''
(setq company-box-icons-alist 'company-box-icons-all-the-icons)
(setq company-box-icons-lsp
`(( 1 . ,(all-the-icons-faicon "file-text-o" :v-adjust -0.0575)) ; Text
( 2 . ,(all-the-icons-faicon "cube" :v-adjust -0.0575)) ; Method
( 3 . ,(all-the-icons-faicon "cube" :v-adjust -0.0575)) ; Function
( 4 . ,(all-the-icons-faicon "cube" :v-adjust -0.0575)) ; Constructor
( 5 . ,(all-the-icons-faicon "tag" :v-adjust -0.0575)) ; Field
( 6 . ,(all-the-icons-faicon "tag" :v-adjust -0.0575)) ; Variable
( 7 . ,(all-the-icons-faicon "cog" :v-adjust -0.0575)) ; Class
( 8 . ,(all-the-icons-faicon "cogs" :v-adjust -0.0575)) ; Interface
( 9 . ,(all-the-icons-alltheicon "less")) ; Module
(10 . ,(all-the-icons-faicon "wrench" :v-adjust -0.0575)) ; Property
(11 . ,(all-the-icons-faicon "tag" :v-adjust -0.0575)) ; Unit
(12 . ,(all-the-icons-faicon "tag" :v-adjust -0.0575)) ; Value
(13 . ,(all-the-icons-material "content_copy" :v-adjust -0.2)) ; Enum
(14 . ,(all-the-icons-faicon "tag" :v-adjust -0.0575)) ; Keyword
(15 . ,(all-the-icons-material "content_paste" :v-adjust -0.2)) ; Snippet
(16 . ,(all-the-icons-material "palette" :v-adjust -0.2)) ; Color
(17 . ,(all-the-icons-faicon "file" :v-adjust -0.0575)) ; File
(18 . ,(all-the-icons-faicon "tag" :v-adjust -0.0575)) ; Reference
(19 . ,(all-the-icons-faicon "folder" :v-adjust -0.0575)) ; Folder
(20 . ,(all-the-icons-faicon "tag" :v-adjust -0.0575)) ; EnumMember
(21 . ,(all-the-icons-faicon "tag" :v-adjust -0.0575)) ; Constant
(22 . ,(all-the-icons-faicon "cog" :v-adjust -0.0575)) ; Struct
(23 . ,(all-the-icons-faicon "bolt" :v-adjust -0.0575)) ; Event
(24 . ,(all-the-icons-faicon "tag" :v-adjust -0.0575)) ; Operator
(25 . ,(all-the-icons-faicon "cog" :v-adjust -0.0575)) ; TypeParameter
))
'';
};
all-the-icons = { enable = true; };
company-jedi = {
enable = (elem "emacs::elpy" config.machine.pkgs);
};
};
fonts.packages = pkgs.emacs-all-the-icons-fonts.all;
}