From f23e059ac1dbc663aa03b764bbdbce6b4e8e9cbc Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Fri, 9 Aug 2013 17:09:29 +0300 Subject: [PATCH] Bundle company-cmake Fixes #13 --- NEWS.md | 1 + company-cmake.el | 130 +++++++++++++++++++++++++++++++++++++++++++++++ company.el | 3 +- 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 company-cmake.el diff --git a/NEWS.md b/NEWS.md index bbbd830db..1bc150ffe 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ ## Next +* `company-cmake` is now bundled. * Better `linum` compatibility in Emacs <= 24.2. * `company-global-modes`: New option. diff --git a/company-cmake.el b/company-cmake.el new file mode 100644 index 000000000..d4f557788 --- /dev/null +++ b/company-cmake.el @@ -0,0 +1,130 @@ +;;; company-cmake.el --- company-mode completion back-end for CMake + +;; Copyright (C) 2013 Chen Bin + +;; Author: Chen Bin +;; Version: 0.1 + +;; This file is NOT 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 . + +;;; Commentary: +;; +;; company-cmake offers completions for module names, variable names and +;; commands used by CMake. And their descriptions. + +;;; Code: +(require 'company) + +(defgroup company-cmake nil + "Completion back-end for CMake." + :group 'company) + +(defcustom company-cmake-executable + (executable-find "cmake") + "Location of cmake executable." + :type 'file) + +(defvar company-cmake-executable-arguments + '("--help-command-list" + "--help-module-list" + "--help-variable-list") + "The arguments we pass to cmake, separately. +They affect which types of symbols we get completion candidates for.") + +(defvar company-cmake--completion-pattern + "^\\(%s[a-zA-Z0-9_]%s\\)$" + "Regexp to match the candidates.") + +(defvar company-cmake-modes '(cmake-mode) + "Major modes in which cmake may complete.") + +(defvar company-cmake--meta-command-cache nil + "Cache for command arguments to retrieve descriptions for the candidates.") + +(defun company-cmake--parse-output (prefix cmd) + "Analyze the temp buffer and collect lines." + (goto-char (point-min)) + (let ((pattern (format company-cmake--completion-pattern + (regexp-quote prefix) + (if (zerop (length prefix)) "+" "*"))) + (case-fold-search nil) + lines match) + (while (re-search-forward pattern nil t) + (setq match (match-string-no-properties 1)) + (puthash match cmd company-cmake--meta-command-cache) + (push match lines)) + lines)) + +(defun company-cmake--candidates (prefix) + (let ((res 0) + results + cmd) + (setq company-cmake--meta-command-cache (make-hash-table :test 'equal)) + (dolist (arg company-cmake-executable-arguments) + (with-temp-buffer + (setq res (call-process company-cmake-executable nil t nil arg)) + (unless (eq 0 res) + (message "cmake executable exited with error=%d" res)) + (setq cmd (replace-regexp-in-string "-list$" "" arg) ) + (setq results (nconc results (company-cmake--parse-output prefix cmd))))) + results)) + +(defun company-cmake--meta (prefix) + (let ((cmd-opts (gethash prefix company-cmake--meta-command-cache)) + result) + (with-temp-buffer + (call-process company-cmake-executable nil t nil cmd-opts prefix) + ;; Go to the third line, trim it and return the result. + ;; Tested with cmake 2.8.9. + (goto-char (point-min)) + (forward-line 2) + (setq result (buffer-substring-no-properties (line-beginning-position) + (line-end-position))) + (setq result (replace-regexp-in-string "^[ \t\n\r]+" "" result)) + result))) + +(defun company-cmake-doc-buffer (candidates) + (let ((cmd-opts (gethash prefix company-cmake--meta-command-cache)) + result) + (with-temp-buffer + (call-process company-cmake-executable nil t nil cmd-opts prefix) + ;; Go to the third line, trim it and return the result. + ;; Tested with cmake 2.8.9. + (goto-char (point-min)) + (forward-line 2) + (setq result (buffer-substring-no-properties (line-beginning-position) + (point-max))) + result))) + +(defun company-cmake (command &optional arg &rest ignored) + "`company-mode' completion back-end for CMake. +CMake is a cross-platform, open-source make system." + (interactive (list 'interactive)) + (case command + (interactive (company-begin-backend 'company-cmake)) + (init (when (memq major-mode company-cmake-modes) + (unless company-cmake-executable + (error "Company found no cmake executable")))) + (prefix (and (memq major-mode company-cmake-modes) + (not (company-in-string-or-comment)) + (company-grab-symbol))) + (candidates (company-cmake--candidates arg)) + (meta (company-cmake--meta arg)) + (doc-buffer (company-cmake-doc-buffer arg)) + )) + +(provide 'company-cmake) +;;; company-cmake.el ends here diff --git a/company.el b/company.el index f8d4a46f1..cd45c0883 100644 --- a/company.el +++ b/company.el @@ -215,6 +215,7 @@ If this many lines are not available, prefer to display the tooltip above." '((company-abbrev . "Abbrev") (company-capf . "completion-at-point-functions") (company-clang . "Clang") + (company-cmake . "CMake") (company-css . "CSS") (company-dabbrev . "dabbrev for plain text") (company-dabbrev-code . "dabbrev for code") @@ -244,7 +245,7 @@ If this many lines are not available, prefer to display the tooltip above." (defcustom company-backends '(company-elisp company-nxml company-css company-semantic company-clang company-eclim - company-xcode company-ropemacs + company-xcode company-ropemacs company-cmake (company-gtags company-etags company-dabbrev-code company-keywords) company-oddmuse company-files company-dabbrev) -- 2.39.2