diff options
| -rw-r--r-- | README | 11 | ||||
| -rw-r--r-- | elisp/Makefile.am | 1 | ||||
| -rw-r--r-- | elisp/geiser-autodoc.el | 6 | ||||
| -rw-r--r-- | elisp/geiser-company.el | 111 | ||||
| -rw-r--r-- | elisp/geiser-completion.el | 8 | ||||
| -rw-r--r-- | elisp/geiser-edit.el | 11 | ||||
| -rw-r--r-- | elisp/geiser-mode.el | 7 | ||||
| -rw-r--r-- | elisp/geiser-reload.el | 1 | ||||
| -rw-r--r-- | elisp/geiser-repl.el | 7 | 
9 files changed, 153 insertions, 10 deletions
| @@ -81,6 +81,17 @@    To start a REPL, M-x geiser. +*** Completion with company-mode +    Geiser offers identifier and module name completion, bound to +    M-TAB and M-` respectively. Only names visible in the current +    module are offered. + +    While that is cool and all, things are even better: if you have +    [[http://nschum.de/src/emacs/company-mode/][company-mode]] installed, Geiser's completion will use it. Just +    require company-mode and, from then on, any new scheme buffer or +    REPL will use it. If you didn't know about Nikolaj Schumacher's +    awesome mode, check [[http://www.screentoaster.com/watch/stU0lSRERIR1pYRFVdXVlRVFFV/company_mode_for_gnu_emacs][this screencast]]. +  * Quick key reference  *** In Scheme buffers: diff --git a/elisp/Makefile.am b/elisp/Makefile.am index a6ff248..9f93e64 100644 --- a/elisp/Makefile.am +++ b/elisp/Makefile.am @@ -3,6 +3,7 @@ EXTRA_DIST = geiser-install.el.in  dist_lisp_LISP = \     geiser-autodoc.el \     geiser-base.el \ +   geiser-company.el \     geiser-compile.el \     geiser-completion.el	\     geiser-connection.el	\ diff --git a/elisp/geiser-autodoc.el b/elisp/geiser-autodoc.el index 26abd8d..5aa6691 100644 --- a/elisp/geiser-autodoc.el +++ b/elisp/geiser-autodoc.el @@ -153,9 +153,13 @@ when `geiser-autodoc-display-module-p' is on."  ;;; Autodoc function: +(make-variable-buffer-local + (defvar geiser-autodoc--inhibit-flag nil)) +  (defun geiser-autodoc--eldoc-function ()    (condition-case e -      (geiser-autodoc--autodoc (geiser-syntax--scan-sexps)) +      (and (not geiser-autodoc--inhibit-flag) +           (geiser-autodoc--autodoc (geiser-syntax--scan-sexps)))      (error (format "Autodoc not available (%s)" (error-message-string e))))) diff --git a/elisp/geiser-company.el b/elisp/geiser-company.el new file mode 100644 index 0000000..8ae8969 --- /dev/null +++ b/elisp/geiser-company.el @@ -0,0 +1,111 @@ +;; geiser-company.el -- integration with company-mode + +;; Copyright (C) 2009 Jose Antonio Ortega Ruiz + +;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org> +;; Start date: Mon Aug 24, 2009 12:44 + +;; This file 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. + +;; This file 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/>. + +;;; Code: + +(require 'geiser-autodoc) +(require 'geiser-completion) +(require 'geiser-edit) +(require 'geiser-base) + + +;;; Helpers: + +(make-variable-buffer-local + (defvar geiser-company--enabled-flag nil)) + +(defsubst geiser-company--candidates (prefix module) +  (car (geiser-completion--complete prefix module))) + +(defsubst geiser-company--doc (id module) +  (ignore-errors +    (if module +	(format "%s [module]" id) +      (geiser-autodoc--autodoc (list (list (intern id) 0)))))) + +(defsubst geiser-company--doc-buffer (id module) +  nil) + +(defun geiser-company--location (id module) +  (ignore-errors +    (let ((id (intern id))) +      (save-current-buffer +	(if module (geiser-edit-module id) (geiser-edit-symbol id)) +	(cons (current-buffer) (point)))))) + +(defsubst geiser-company--prefix-at-point (module) +  (and geiser-company--enabled-flag +       (looking-at-p "\\_>") +       (not (nth 8 (syntax-ppss))) +       (geiser-completion--prefix module))) + + +;;; Activation + +(defun geiser-company--setup (enable) +  (setq geiser-company--enabled-flag enable) +  (when (fboundp 'company-mode) +    (company-mode nil) +    (when enable (company-mode enable))) +  (when (boundp 'company-lighter) +    (setq company-lighter "/C"))) + +(defun geiser-company--inhibit-autodoc (ignored) +  (setq geiser-autodoc--inhibit-flag t)) + +(defun geiser-company--restore-autodoc (&optional ignored) +  (setq geiser-autodoc--inhibit-flag nil)) + + +;;; Backends: +(defmacro geiser-company--make-backend (name mod) +  `(defun ,name (command &optional arg &rest ignored) +     "A `company-mode' completion back-end for `geiser-mode'." +     (interactive (list 'interactive)) +     (case command +       ('interactive (company-begin-backend ',name)) +       ('prefix (geiser-company--prefix-at-point ,mod)) +       ('candidates (geiser-company--candidates arg ,mod)) +       ('meta (geiser-company--doc arg ,mod)) +       ('doc-buffer (geiser-company--doc-buffer arg ,mod)) +       ('location (geiser-company--location arg ,mod)) +       ('sorted t)))) + +(defvar geiser-company--backend '(company-geiser-ids company-geiser-modules)) + +(eval-after-load "company" +  '(progn +     (geiser-company--make-backend company-geiser-ids nil) +     (geiser-company--make-backend company-geiser-modules t) +     (add-to-list 'company-backends geiser-company--backend) +     (add-hook 'company-completion-finished-hook 'geiser-company--restore-autodoc) +     (add-hook 'company-completion-cancelled-hook 'geiser-company--restore-autodoc) +     (add-hook 'company-completion-started-hook 'geiser-company--inhibit-autodoc))) + + +;;; Reload support: + +(defun geiser-company-unload-function () +  (when (boundp 'company-backends) +    (setq company-backends (remove geiser-company--backend company-backends)))) + + +(provide 'geiser-company) +;;; geiser-company.el ends here diff --git a/elisp/geiser-completion.el b/elisp/geiser-completion.el index cd03cae..e3bd74b 100644 --- a/elisp/geiser-completion.el +++ b/elisp/geiser-completion.el @@ -204,14 +204,16 @@ terminates a current completion."             (funcall geiser-completion--symbol-begin-function module))        (save-excursion (skip-syntax-backward "^-()>") (point)))) +(defsubst geiser-completion--prefix (module) +  (buffer-substring-no-properties (point) +                                  (geiser-completion--symbol-begin module))) +  (defun geiser-completion--complete-symbol (&optional arg)    "Complete the symbol at point.  Perform completion similar to Emacs' complete-symbol.  With prefix, complete module name."    (interactive "P") -  (let* ((end (point)) -         (beg (geiser-completion--symbol-begin arg)) -         (prefix (buffer-substring-no-properties beg end)) +  (let* ((prefix (geiser-completion--prefix arg))           (result (geiser-completion--complete prefix arg))           (completions (car result))           (partial (cdr result))) diff --git a/elisp/geiser-edit.el b/elisp/geiser-edit.el index ad2c11e..418b6e3 100644 --- a/elisp/geiser-edit.el +++ b/elisp/geiser-edit.el @@ -155,13 +155,12 @@ or following links in error buffers.")  (defvar geiser-edit--symbol-history nil) -(defun geiser-edit-symbol () +(defun geiser-edit-symbol (symbol)    "Asks for a symbol to edit, with completion." -  (interactive) -  (let* ((symbol (geiser-completion--read-symbol "Edit symbol: " -                                                nil -                                                geiser-edit--symbol-history)) -         (cmd `(:eval ((:ge symbol-location) ',symbol)))) +  (interactive (list (geiser-completion--read-symbol "Edit symbol: " +                                                     nil +                                                     geiser-edit--symbol-history))) +  (let ((cmd `(:eval ((:ge symbol-location) ',symbol))))      (geiser-edit--try-edit symbol (geiser-eval--send/wait cmd))))  (defun geiser-edit-symbol-at-point (&optional arg) diff --git a/elisp/geiser-mode.el b/elisp/geiser-mode.el index cc5a00f..fa686ec 100644 --- a/elisp/geiser-mode.el +++ b/elisp/geiser-mode.el @@ -28,6 +28,7 @@  (require 'geiser-doc)  (require 'geiser-compile)  (require 'geiser-completion) +(require 'geiser-company)  (require 'geiser-xref)  (require 'geiser-edit)  (require 'geiser-autodoc) @@ -52,6 +53,11 @@    :group 'geiser-autodoc    :type 'boolean) +(defcustom geiser-mode-company-p t +  "Whether to use company-mode for completion, if available." +  :group 'geiser-mode +  :type 'boolean) +  (defcustom geiser-mode-smart-tab-p nil    "Whether `geiser-smart-tab-mode' gets enabled by default in Scheme buffers."    :group 'geiser-mode @@ -188,6 +194,7 @@ interacting with the Geiser REPL is at your disposal.    (when geiser-mode (geiser-impl--set-buffer-implementation))    (setq geiser-autodoc-mode-string "/A")    (setq geiser-smart-tab-mode-string "/T") +  (geiser-company--setup (and geiser-mode geiser-mode-company-p))    (when geiser-mode-autodoc-p (geiser-autodoc-mode geiser-mode))    (when geiser-mode-smart-tab-p (geiser-smart-tab-mode geiser-mode))) diff --git a/elisp/geiser-reload.el b/elisp/geiser-reload.el index 97b398d..5a30e1f 100644 --- a/elisp/geiser-reload.el +++ b/elisp/geiser-reload.el @@ -38,6 +38,7 @@             geiser-doc             geiser-debug             geiser-impl +           geiser-company             geiser-completion             geiser-autodoc             geiser-compile diff --git a/elisp/geiser-repl.el b/elisp/geiser-repl.el index bed653f..4ea1bb7 100644 --- a/elisp/geiser-repl.el +++ b/elisp/geiser-repl.el @@ -24,6 +24,7 @@  ;;; Code: +(require 'geiser-company)  (require 'geiser-autodoc)  (require 'geiser-edit)  (require 'geiser-impl) @@ -70,6 +71,11 @@ implementation name gets appended to it."    :type 'boolean    :group 'geiser-repl) +(defcustom geiser-repl-company-p t +  "Whether to use company-mode for completion, if available." +  :group 'geiser-mode +  :type 'boolean) +  (defcustom geiser-repl-read-only-prompt-p t    "Whether the REPL's prompt should be read-only."    :type 'boolean @@ -293,6 +299,7 @@ If no REPL is running, execute `run-geiser' to start a fresh one."    (set-syntax-table scheme-mode-syntax-table)    (setq geiser-eval--get-module-function 'geiser-repl--module-function)    (when geiser-repl-autodoc-p (geiser-autodoc-mode 1)) +  (geiser-company--setup geiser-repl-company-p)    (compilation-shell-minor-mode 1))  (define-key geiser-repl-mode-map "\C-d" 'delete-char) | 
