Klimi's new dotfiles with stow.
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.

168 lines
6.7 KiB

пре 4 година
  1. ;;; company-semantic.el --- company-mode completion backend using Semantic
  2. ;; Copyright (C) 2009-2011, 2013-2016 Free Software Foundation, Inc.
  3. ;; Author: Nikolaj Schumacher
  4. ;; This file is part of GNU Emacs.
  5. ;; GNU Emacs is free software: you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; GNU Emacs is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;;
  17. ;;; Code:
  18. (require 'company)
  19. (require 'company-template)
  20. (require 'cl-lib)
  21. (defvar semantic-idle-summary-function)
  22. (declare-function semantic-documentation-for-tag "semantic/doc" )
  23. (declare-function semantic-analyze-current-context "semantic/analyze")
  24. (declare-function semantic-analyze-possible-completions "semantic/complete")
  25. (declare-function semantic-analyze-find-tags-by-prefix "semantic/analyze/fcn")
  26. (declare-function semantic-tag-class "semantic/tag")
  27. (declare-function semantic-tag-name "semantic/tag")
  28. (declare-function semantic-tag-start "semantic/tag")
  29. (declare-function semantic-tag-buffer "semantic/tag")
  30. (declare-function semantic-active-p "semantic")
  31. (declare-function semantic-format-tag-prototype "semantic/format")
  32. (defgroup company-semantic nil
  33. "Completion backend using Semantic."
  34. :group 'company)
  35. (defcustom company-semantic-metadata-function 'company-semantic-summary-and-doc
  36. "The function turning a semantic tag into doc information."
  37. :type 'function)
  38. (defcustom company-semantic-begin-after-member-access t
  39. "When non-nil, automatic completion will start whenever the current
  40. symbol is preceded by \".\", \"->\" or \"::\", ignoring
  41. `company-minimum-prefix-length'.
  42. If `company-begin-commands' is a list, it should include `c-electric-lt-gt'
  43. and `c-electric-colon', for automatic completion right after \">\" and
  44. \":\"."
  45. :type 'boolean)
  46. (defcustom company-semantic-insert-arguments t
  47. "When non-nil, insert function arguments as a template after completion."
  48. :type 'boolean
  49. :package-version '(company . "0.9.0"))
  50. (defvar company-semantic-modes '(c-mode c++-mode jde-mode java-mode))
  51. (defvar-local company-semantic--current-tags nil
  52. "Tags for the current context.")
  53. (defun company-semantic-documentation-for-tag (tag)
  54. (when (semantic-tag-buffer tag)
  55. ;; When TAG's buffer is unknown, the function below raises an error.
  56. (semantic-documentation-for-tag tag)))
  57. (defun company-semantic-doc-or-summary (tag)
  58. (or (company-semantic-documentation-for-tag tag)
  59. (and (require 'semantic-idle nil t)
  60. (require 'semantic/idle nil t)
  61. (funcall semantic-idle-summary-function tag nil t))))
  62. (defun company-semantic-summary-and-doc (tag)
  63. (let ((doc (company-semantic-documentation-for-tag tag))
  64. (summary (funcall semantic-idle-summary-function tag nil t)))
  65. (and (stringp doc)
  66. (string-match "\n*\\(.*\\)$" doc)
  67. (setq doc (match-string 1 doc)))
  68. (concat summary
  69. (when doc
  70. (if (< (+ (length doc) (length summary) 4) (window-width))
  71. " -- "
  72. "\n"))
  73. doc)))
  74. (defun company-semantic-doc-buffer (tag)
  75. (let ((doc (company-semantic-documentation-for-tag tag)))
  76. (when doc
  77. (company-doc-buffer
  78. (concat (funcall semantic-idle-summary-function tag nil t)
  79. "\n"
  80. doc)))))
  81. (defsubst company-semantic-completions (prefix)
  82. (ignore-errors
  83. (let ((completion-ignore-case nil)
  84. (context (semantic-analyze-current-context)))
  85. (setq company-semantic--current-tags
  86. (semantic-analyze-possible-completions context 'no-unique))
  87. (all-completions prefix company-semantic--current-tags))))
  88. (defun company-semantic-completions-raw (prefix)
  89. (setq company-semantic--current-tags nil)
  90. (dolist (tag (semantic-analyze-find-tags-by-prefix prefix))
  91. (unless (eq (semantic-tag-class tag) 'include)
  92. (push tag company-semantic--current-tags)))
  93. (delete "" (mapcar 'semantic-tag-name company-semantic--current-tags)))
  94. (defun company-semantic-annotation (argument tags)
  95. (let* ((tag (assq argument tags))
  96. (kind (when tag (elt tag 1))))
  97. (cl-case kind
  98. (function (let* ((prototype (semantic-format-tag-prototype tag nil nil))
  99. (par-pos (string-match "(" prototype)))
  100. (when par-pos (substring prototype par-pos)))))))
  101. (defun company-semantic--prefix ()
  102. (if company-semantic-begin-after-member-access
  103. (company-grab-symbol-cons "\\.\\|->\\|::" 2)
  104. (company-grab-symbol)))
  105. ;;;###autoload
  106. (defun company-semantic (command &optional arg &rest ignored)
  107. "`company-mode' completion backend using CEDET Semantic."
  108. (interactive (list 'interactive))
  109. (cl-case command
  110. (interactive (company-begin-backend 'company-semantic))
  111. (prefix (and (featurep 'semantic)
  112. (semantic-active-p)
  113. (memq major-mode company-semantic-modes)
  114. (not (company-in-string-or-comment))
  115. (or (company-semantic--prefix) 'stop)))
  116. (candidates (if (and (equal arg "")
  117. (not (looking-back "->\\|\\.\\|::" (- (point) 2))))
  118. (company-semantic-completions-raw arg)
  119. (company-semantic-completions arg)))
  120. (meta (funcall company-semantic-metadata-function
  121. (assoc arg company-semantic--current-tags)))
  122. (annotation (company-semantic-annotation arg
  123. company-semantic--current-tags))
  124. (doc-buffer (company-semantic-doc-buffer
  125. (assoc arg company-semantic--current-tags)))
  126. ;; Because "" is an empty context and doesn't return local variables.
  127. (no-cache (equal arg ""))
  128. (duplicates t)
  129. (location (let ((tag (assoc arg company-semantic--current-tags)))
  130. (when (buffer-live-p (semantic-tag-buffer tag))
  131. (cons (semantic-tag-buffer tag)
  132. (semantic-tag-start tag)))))
  133. (post-completion (let ((anno (company-semantic-annotation
  134. arg company-semantic--current-tags)))
  135. (when (and company-semantic-insert-arguments anno)
  136. (insert anno)
  137. (company-template-c-like-templatify (concat arg anno)))
  138. ))))
  139. (provide 'company-semantic)
  140. ;;; company-semantic.el ends here