]> code.delx.au - gnu-emacs-elpa/commitdiff
Added Xcode back-end.
authorNikolaj Schumacher <git@nschum.de>
Sat, 11 Apr 2009 20:05:28 +0000 (22:05 +0200)
committerNikolaj Schumacher <git@nschum.de>
Mon, 13 Apr 2009 17:22:15 +0000 (19:22 +0200)
company-xcode.el [new file with mode: 0644]
company.el

diff --git a/company-xcode.el b/company-xcode.el
new file mode 100644 (file)
index 0000000..1280c10
--- /dev/null
@@ -0,0 +1,113 @@
+;;; company-xcode.el --- a company-mode completion back-end for Xcode projects
+;;
+;; Copyright (C) 2009 Nikolaj Schumacher
+;;
+;; This file is part of company 0.2.1.
+;;
+;; This program 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 2
+;; of the License, or (at your option) any later version.
+;;
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'company)
+(eval-when-compile (require 'cl))
+
+(defcustom company-xcode-xcodeindex-executable (executable-find "xcodeindex")
+  "*Location of xcodeindex executable"
+  :group 'company-xcode
+  :type 'file)
+
+(defvar company-xcode-tags nil)
+
+(defun company-xcode-reset ()
+  "Reset the cached tags."
+  (interactive)
+  (setq company-xcode-tags nil))
+
+(defcustom company-xcode-types
+  '("Class" "Const" "Constant" "Enum" "Macro" "Modeled Class" "Structure"
+    "Type" "Union" "Function")
+  "*The types of symbols offered by `company-xcode'
+No context-enabled completion is available.  Types like methods will be
+offered regardless of whether the class supports them.  The defaults should be
+valid in most contexts."
+  :set (lambda (variable value)
+         (set variable value)
+         (company-xcode-reset))
+  :group 'company-xcode
+  :type '(set (const "Category") (const "Class") (const "Class Method")
+              (const "Const") (const "Constant") (const "Enum") (const "Field")
+              (const "Instance Method") (const "Instance Variables")
+              (const "Macro") (const "Modeled Class") (const "Modeled Method")
+              (const "Property") (const "Protocol") (const "Structure")
+              (const "Type") (const "Union") (const "Variable")
+              (const "Function")))
+
+(defvar company-xcode-symbol-regexp
+  "\\_<[A-Za-z_][A-Za-z_0-9]*\\_>")
+
+(defvar company-xcode-project 'unknown)
+(make-variable-buffer-local 'company-xcode-project)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-xcode-fetch (project-bundle)
+  (setq project-bundle (directory-file-name project-bundle))
+  (message "Retrieving dump from %s..." project-bundle)
+  (with-temp-buffer
+    (let ((default-directory (file-name-directory project-bundle)))
+      (call-process company-xcode-xcodeindex-executable nil (current-buffer)
+                    nil "dump" "-project"
+                    (file-name-nondirectory project-bundle) "-quiet")
+      (goto-char (point-min))
+      (let ((regexp (concat "^\\([^\t\n]*\\)\t[^\t\n]*\t"
+                            (regexp-opt company-xcode-types)
+                            "\t[^\t\n]*\t[^\t\n]*"))
+            candidates)
+        (while (re-search-forward regexp nil t)
+          (add-to-list 'candidates (match-string 1)))
+        (message "Retrieving dump from %s...done" project-bundle)
+        candidates))))
+
+(defun company-xcode-find-project ()
+  (let ((dir (if buffer-file-name
+                 (file-name-directory buffer-file-name)
+               (expand-file-name default-directory)))
+        file)
+    (while (not (or file (equal dir "/")))
+      (setq file (car (directory-files dir t ".xcodeproj\\'" t))
+            dir (file-name-directory (directory-file-name dir))))
+    file))
+
+(defun company-xcode-tags ()
+  (when (eq company-xcode-project 'unknown)
+    (setq company-xcode-project (company-xcode-find-project)))
+  (when company-xcode-project
+    (cdr (or (assoc company-xcode-project company-xcode-tags)
+             (car (push (cons company-xcode-project
+                              (company-xcode-fetch company-xcode-project))
+                        company-xcode-tags))))))
+;;;###autoload
+(defun company-xcode (command &optional arg &rest ignored)
+  "A `company-mode' completion back-end for Xcode projects."
+  (interactive (list 'interactive))
+  (case command
+    ('interactive (company-begin-backend 'company-xcode))
+    ('prefix (and company-xcode-xcodeindex-executable
+                  (not (company-in-string-or-comment))
+                  (company-xcode-tags)
+                  (or (company-grab company-xcode-symbol-regexp) "")))
+    ('candidates (let ((completion-ignore-case nil))
+                   (all-completions arg (company-xcode-tags))))))
+
+
+(provide 'company-xcode)
+;;; company-xcode.el ends here
index c7a34d5756ebf48ae78374564cd24ec1c2fed4e7..086c021c749c25080b7ca33fa031be8f1306acb5 100644 (file)
@@ -69,7 +69,7 @@
 ;;
 ;;; Change Log:
 ;;
-;;    Added abbrev and tempo back-ends.
+;;    Added abbrev, tempo and Xcode back-ends.
 ;;    Back-ends are now interactive.  You can start them with M-x backend-name.
 ;;    Added `company-begin-with' for starting company from elisp-code.
 ;;    Added hooks.
@@ -234,8 +234,9 @@ The visualized data is stored in `company-prefix', `company-candidates',
                          (function :tag "custom function" nil))))
 
 (defcustom company-backends '(company-elisp company-nxml company-css
-                              company-semantic company-gtags company-etags
-                              company-oddmuse company-files company-dabbrev)
+                              company-semantic company-xcode company-gtags
+                              company-etags company-oddmuse company-files
+                              company-dabbrev)
   "*The list of active back-ends (completion engines).
 Each back-end is a function that takes a variable number of arguments.
 The first argument is the command requested from the back-end.  It is one