company-etags.el (4043B)
1 ;;; company-etags.el --- company-mode completion backend for etags 2 3 ;; Copyright (C) 2009-2011, 2013-2015, 2018-2019 Free Software Foundation, Inc. 4 5 ;; Author: Nikolaj Schumacher 6 7 ;; This file is part of GNU Emacs. 8 9 ;; GNU Emacs is free software: you can redistribute it and/or modify 10 ;; it under the terms of the GNU General Public License as published by 11 ;; the Free Software Foundation, either version 3 of the License, or 12 ;; (at your option) any later version. 13 14 ;; GNU Emacs is distributed in the hope that it will be useful, 15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 ;; GNU General Public License for more details. 18 19 ;; You should have received a copy of the GNU General Public License 20 ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. 21 22 23 ;;; Commentary: 24 ;; 25 26 ;;; Code: 27 28 (require 'company) 29 (require 'cl-lib) 30 (require 'etags) 31 32 (defgroup company-etags nil 33 "Completion backend for etags." 34 :group 'company) 35 36 (defcustom company-etags-use-main-table-list t 37 "Always search `tags-table-list' if set. 38 If this is disabled, `company-etags' will try to find the one table for each 39 buffer automatically." 40 :type '(choice (const :tag "off" nil) 41 (const :tag "on" t))) 42 43 (defcustom company-etags-ignore-case nil 44 "Non-nil to ignore case in completion candidates." 45 :type 'boolean 46 :package-version '(company . "0.7.3")) 47 48 (defcustom company-etags-everywhere nil 49 "Non-nil to offer completions in comments and strings. 50 Set it to t or to a list of major modes." 51 :type '(choice (const :tag "Off" nil) 52 (const :tag "Any supported mode" t) 53 (repeat :tag "Some major modes" 54 (symbol :tag "Major mode"))) 55 :package-version '(company . "0.9.0")) 56 57 (defvar company-etags-modes '(prog-mode c-mode objc-mode c++-mode java-mode 58 jde-mode pascal-mode perl-mode python-mode)) 59 60 (defvar-local company-etags-buffer-table 'unknown) 61 62 (defun company-etags-find-table () 63 (let ((file (expand-file-name 64 "TAGS" 65 (locate-dominating-file (or buffer-file-name 66 default-directory) 67 "TAGS")))) 68 (when (and file (file-regular-p file)) 69 (list file)))) 70 71 (defun company-etags-buffer-table () 72 (or (and company-etags-use-main-table-list tags-table-list) 73 (if (eq company-etags-buffer-table 'unknown) 74 (setq company-etags-buffer-table (company-etags-find-table)) 75 company-etags-buffer-table))) 76 77 (defun company-etags--candidates (prefix) 78 (let ((tags-table-list (company-etags-buffer-table)) 79 (tags-file-name tags-file-name) 80 (completion-ignore-case company-etags-ignore-case)) 81 (and (or tags-file-name tags-table-list) 82 (fboundp 'tags-completion-table) 83 (save-excursion 84 (visit-tags-table-buffer) 85 (all-completions prefix (tags-completion-table)))))) 86 87 ;;;###autoload 88 (defun company-etags (command &optional arg &rest ignored) 89 "`company-mode' completion backend for etags." 90 (interactive (list 'interactive)) 91 (cl-case command 92 (interactive (company-begin-backend 'company-etags)) 93 (prefix (and (apply #'derived-mode-p company-etags-modes) 94 (or (eq t company-etags-everywhere) 95 (apply #'derived-mode-p company-etags-everywhere) 96 (not (company-in-string-or-comment))) 97 (company-etags-buffer-table) 98 (or (company-grab-symbol) 'stop))) 99 (candidates (company-etags--candidates arg)) 100 (location (let ((tags-table-list (company-etags-buffer-table))) 101 (when (fboundp 'find-tag-noselect) 102 (save-excursion 103 (let ((buffer (find-tag-noselect arg))) 104 (cons buffer (with-current-buffer buffer (point)))))))) 105 (ignore-case company-etags-ignore-case))) 106 107 (provide 'company-etags) 108 ;;; company-etags.el ends here