Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
4.6 KiB

  1. ;;; -*- mode: emacs-lisp; lexical-binding: t; -*-
  2. ;;; ein-company.el --- Support for completion using company back-end.
  3. ;; Copyright (C) 2017 - John Miller
  4. ;; Author: John Miller <millejoh at mac.com>
  5. ;; This file is NOT part of GNU Emacs.
  6. ;; ein-company.el is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; ein-company.el is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with ein-company.el. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;;
  18. ;;; Code:
  19. (require 'deferred)
  20. (require 'ein-completer)
  21. (require 'company nil t)
  22. (autoload 'company-begin-backend "company")
  23. (autoload 'company-doc-buffer "company")
  24. (defun ein:company--deferred-complete ()
  25. (let ((d (deferred:new #'identity)))
  26. (ein:completer-complete
  27. (ein:get-kernel)
  28. (list :complete_reply
  29. (cons (lambda (d* &rest args) (deferred:callback-post d* args))
  30. d))
  31. (apply-partially (lambda (d* err) (deferred:callback-post d* err)) d))
  32. d))
  33. (defun ein:company--complete (prefix fetcher)
  34. (deferred:$
  35. (deferred:next
  36. (lambda ()
  37. (ein:company--deferred-complete)))
  38. (deferred:nextc it
  39. (lambda (replies)
  40. (unless (stringp replies) ;; if not an error
  41. (ein:completions--prepare-matches prefix fetcher replies))))))
  42. (defun ein:completions--prepare-matches (prefix fetcher replies)
  43. (cl-destructuring-bind
  44. ((&key matches cursor_start cursor_end &allow-other-keys) ; :complete_reply
  45. _metadata)
  46. replies
  47. (let ((nix (- cursor_end cursor_start))
  48. prefixed-matches)
  49. (dolist (match matches)
  50. (setq prefixed-matches
  51. (nconc prefixed-matches (list (concat prefix (substring match nix))))))
  52. (ein:completions--build-oinfo-cache prefixed-matches)
  53. (funcall fetcher prefixed-matches))))
  54. ;;;###autoload
  55. (defun ein:company-backend (command &optional arg &rest _)
  56. (interactive (list 'interactive))
  57. (cl-case command
  58. (interactive (company-begin-backend 'ein:company-backend))
  59. (prefix (and (eq ein:completion-backend 'ein:use-company-backend)
  60. (or (ein:worksheet-at-codecell-p) ein:connect-mode)
  61. (ein:get-kernel)
  62. (ein:object-prefix-at-point)))
  63. (annotation (let ((kernel (ein:get-kernel)))
  64. (ein:aif (gethash arg (ein:$kernel-oinfo-cache kernel))
  65. (plist-get it :definition))))
  66. (doc-buffer (cons :async
  67. (lambda (cb)
  68. (ein:company-handle-doc-buffer arg cb))))
  69. (location (cons :async
  70. (lambda (cb)
  71. (ein:pytools-find-source (ein:get-kernel-or-error)
  72. arg
  73. cb))))
  74. (candidates
  75. (let* ((kernel (ein:get-kernel-or-error))
  76. (cached (ein:completions-get-cached arg (ein:$kernel-oinfo-cache kernel))))
  77. (ein:aif cached it
  78. (unless (ein:company--punctuation-check (thing-at-point 'line)
  79. (current-column))
  80. (cl-case ein:completion-backend
  81. (t
  82. (cons :async
  83. (lambda (cb)
  84. (ein:company--complete arg cb)))))))))))
  85. (defun ein:company--punctuation-check (thing col)
  86. (or (string-match "[[:nonascii:]]" thing)
  87. (let ((query (ein:trim-right (cl-subseq thing 0 col) "[\n]")))
  88. (string-match "[]()\",[{}'=: ]$" query (- col 2)))))
  89. (defun ein:company-handle-doc-buffer-finish (packed content _metadata-not-used_)
  90. (when (plist-get content :found)
  91. (funcall (plist-get packed :callback) (company-doc-buffer
  92. (ansi-color-apply (cadr (plist-get content :data)))))))
  93. (defun ein:company-handle-doc-buffer (object cb)
  94. (ein:kernel-object-info-request (ein:get-kernel-or-error)
  95. object
  96. (list :inspect_reply
  97. (cons #'ein:company-handle-doc-buffer-finish
  98. (list :object object
  99. :callback cb)))))
  100. (when (boundp 'company-backends)
  101. (add-to-list 'company-backends 'ein:company-backend))
  102. (provide 'ein-company)