| ;===--- inferior-swift.el --------------------------------------------------===; |
| ; |
| ; This source file is part of the Swift.org open source project |
| ; |
| ; Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| ; Licensed under Apache License v2.0 with Runtime Library Exception |
| ; |
| ; See https://swift.org/LICENSE.txt for license information |
| ; See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| ; |
| ;===------------------------------------------------------------------------===; |
| |
| ;;; Load modes that we build off of. |
| (require 'cl) |
| (require 'comint) |
| (require 'swift-mode) |
| |
| ;;; Declare variables. |
| (defcustom swift-command "swift" |
| "Command to invoke `swift'." |
| :group 'swift |
| :type 'string) |
| (defcustom swift-args '() |
| "Commandline arguments to pass to `swift-command'." |
| :group 'swift |
| :type 'string) |
| (defcustom swift-prompt-regexp "^\\(swift\\) " |
| "Prompt for `run-swift'." |
| :group 'swift |
| :type 'regexp) |
| (defcustom swift-xcrun-command "xcrun" |
| "Command used to invoke `xcrun'." |
| :group 'swift |
| :type 'string) |
| (defcustom swift-xcrun-sdk "macosx" |
| "SDK to lookup from `xcrun'." |
| :group 'swift |
| :type 'string) |
| |
| (defvar swift-comint-buffer nil |
| "Swift process variable.") |
| |
| ;;; Entry point for creating the inferior-process from a swift mode buffer. |
| (defun run-swift () |
| "Run an inferior instance of `swift' inside Emacs." |
| (interactive) |
| (cl-flet ((chomp (str) |
| "Chomp leading and tailing whitespace from STR." |
| (while (string-match "\\`\n+\\|^\\s-+\\|\\s-+$\\|\n+\\'" |
| str) |
| (setq str (replace-match "" t t str))) |
| str)) |
| (let* ((swift-sdk-path (chomp |
| (shell-command-to-string |
| (format "%s --show-sdk-path -sdk %s" |
| swift-xcrun-command swift-xcrun-sdk)))) |
| (buffer (comint-check-proc "inferior-swift"))) |
| (pop-to-buffer-same-window |
| (if (or buffer (not (derived-mode-p 'inferior-swift-mode)) |
| (comint-check-proc (current-buffer))) |
| (get-buffer-create (or buffer "*inferior-swift*")) |
| (current-buffer))) |
| (unless buffer |
| (apply 'make-comint-in-buffer "inferior-swift" buffer |
| swift-xcrun-command nil (list swift-command "-sdk" swift-sdk-path)) |
| (setq swift-comint-buffer (get-buffer "*inferior-swift*")) |
| (inferior-swift-mode))))) |
| |
| (defun inferior-swift-mode--initialize () |
| "Helper function to initialize inferior-swift" |
| (setq comint-process-echoes t) |
| (setq comint-use-prompt-regexp t)) |
| |
| ;;; Define the derived mode. |
| (define-derived-mode inferior-swift-mode comint-mode "inferior-swift" |
| "Minor inferior mode for working with a swift repl." |
| nil "inferior-swift" |
| (setq comint-prompt-regexp swift-prompt-regexp) |
| (setq comint-prompt-read-only t)) |
| |
| ;;; Add initialization to the hook. |
| (add-hook 'inferior-swift-mode-hook 'inferior-swift-mode--initialize) |
| |
| ;;; Extra utility methods for sending swift definitions to repl. |
| (defun swift-eval-region (start end) |
| (interactive "r") |
| (let* ((lines (split-string (buffer-substring start end) "\n")) |
| (region-string (mapconcat 'identity (remove-if-not (lambda (x) (not (string-equal x ""))) lines) "; "))) |
| (comint-send-string swift-comint-buffer region-string)) |
| (comint-send-string swift-comint-buffer "\n")) |
| |
| (defun switch-to-swift () |
| (interactive) |
| (pop-to-buffer swift-comint-buffer)) |
| |
| ;;; Add some things to the keymap for use in inferior lisp mode. |
| (define-key swift-mode-map "\C-c\C-r" 'swift-eval-region) |
| (define-key swift-mode-map "\C-c\C-z" 'switch-to-swift) |
| |
| ;; Provide inferior-swift |
| (provide 'inferior-swift-mode) |
| |
| ;;; end inferior-swift-mode.el |