2019-11-23 09:10:03 +01:00
|
|
|
;;; racket-mode.el --- Major mode for Racket language.
|
|
|
|
|
2020-03-24 18:20:37 +01:00
|
|
|
;; Copyright (c) 2013-2020 by Greg Hendershott.
|
2019-11-23 09:10:03 +01:00
|
|
|
|
|
|
|
;; Package: racket-mode
|
2020-03-24 18:20:37 +01:00
|
|
|
;; Package-Requires: ((emacs "25.1") (faceup "0.0.2") (pos-tip "20191127.1028"))
|
2019-11-23 09:10:03 +01:00
|
|
|
;; Author: Greg Hendershott
|
|
|
|
;; URL: https://www.racket-mode.com/
|
|
|
|
|
|
|
|
;; License:
|
|
|
|
;; This 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, or (at your option)
|
|
|
|
;; any later version. This 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. See
|
|
|
|
;; http://www.gnu.org/licenses/ for details.
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
;; Goals:
|
|
|
|
;; - Focus on Racket lang.
|
|
|
|
;; - Follow DrRacket concepts where applicable.
|
|
|
|
;; - Thorough font-lock and indent.
|
2020-03-28 22:53:25 +01:00
|
|
|
;; - Compatible with Emacs 25.1+ and Racket 6.9+.
|
2019-11-23 09:10:03 +01:00
|
|
|
;;
|
|
|
|
;; Details: https://github.com/greghendershott/racket-mode
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
(require 'racket-edit)
|
2020-03-24 18:20:37 +01:00
|
|
|
(require 'racket-xp)
|
|
|
|
(require 'racket-custom)
|
|
|
|
(require 'racket-smart-open)
|
2019-11-23 09:10:03 +01:00
|
|
|
(require 'racket-imenu)
|
|
|
|
(require 'racket-profile)
|
|
|
|
(require 'racket-logger)
|
|
|
|
(require 'racket-stepper)
|
|
|
|
(require 'racket-repl)
|
2020-03-24 18:20:37 +01:00
|
|
|
(require 'racket-repl-buffer-name)
|
2019-11-23 09:10:03 +01:00
|
|
|
(require 'racket-collection)
|
|
|
|
(require 'racket-bug-report)
|
|
|
|
(require 'racket-util)
|
|
|
|
(require 'easymenu)
|
|
|
|
|
|
|
|
(defvar racket-mode-map
|
|
|
|
(racket--easy-keymap-define
|
|
|
|
'((("C-c C-c"
|
2020-03-24 18:20:37 +01:00
|
|
|
"C-c C-k") racket-run-module-at-point)
|
2019-11-23 09:10:03 +01:00
|
|
|
("C-c C-z" racket-repl)
|
|
|
|
("<f5>" racket-run-and-switch-to-repl)
|
|
|
|
("M-C-<f5>" racket-racket)
|
|
|
|
("C-<f5>" racket-test)
|
|
|
|
("C-c C-t" racket-test)
|
|
|
|
("C-c C-l" racket-logger)
|
|
|
|
("C-c C-o" racket-profile)
|
|
|
|
("M-C-x" racket-send-definition)
|
|
|
|
("C-x C-e" racket-send-last-sexp)
|
|
|
|
("C-c C-r" racket-send-region)
|
|
|
|
("C-c C-e f" racket-expand-file)
|
|
|
|
("C-c C-e x" racket-expand-definition)
|
|
|
|
("C-c C-e e" racket-expand-last-sexp)
|
|
|
|
("C-c C-e r" racket-expand-region)
|
|
|
|
("C-c C-x C-f" racket-open-require-path)
|
|
|
|
("TAB" indent-for-tab-command)
|
|
|
|
("M-C-u" racket-backward-up-list)
|
|
|
|
("C-c C-p" racket-cycle-paren-shapes)
|
|
|
|
("M-C-y" racket-insert-lambda)
|
|
|
|
("M-C-." racket-visit-module)
|
|
|
|
("M-," racket-unvisit)
|
|
|
|
("C-c C-f" racket-fold-all-tests)
|
|
|
|
("C-c C-u" racket-unfold-all-tests)
|
|
|
|
((")" "]" "}") racket-insert-closing)))
|
|
|
|
"Keymap for Racket mode.")
|
|
|
|
|
|
|
|
(easy-menu-define racket-mode-menu racket-mode-map
|
|
|
|
"Menu for Racket mode."
|
|
|
|
'("Racket"
|
|
|
|
("Run"
|
|
|
|
["in REPL" racket-run]
|
|
|
|
["in REPL and switch to REPL" racket-run-and-switch-to-repl]
|
|
|
|
["in *shell* using `racket`" racket-racket])
|
|
|
|
("Tests"
|
|
|
|
["in REPL" racket-test]
|
|
|
|
["in *shell* using `raco test`" racket-raco-test]
|
|
|
|
"---"
|
|
|
|
["Fold All" racket-fold-all-tests]
|
|
|
|
["Unfold All" racket-unfold-all-tests])
|
|
|
|
("Eval"
|
|
|
|
["Region" racket-send-region :active (region-active-p)]
|
|
|
|
["Definition" racket-send-definition]
|
|
|
|
["Last S-Expression" racket-send-last-sexp])
|
|
|
|
("Macro Expand"
|
|
|
|
["File" racket-expand-file]
|
|
|
|
["Region" racket-expand-region :active (region-active-p)]
|
|
|
|
["Definition" racket-expand-definition]
|
|
|
|
["Last S-Expression" racket-expand-last-sexp])
|
|
|
|
["Switch to REPL" racket-repl]
|
|
|
|
("Tools"
|
|
|
|
["Profile" racket-profile]
|
|
|
|
["Error Trace" racket-run-with-errortrace]
|
2020-03-24 18:20:37 +01:00
|
|
|
["Step Debug" racket-run-with-debugging]
|
|
|
|
["Toggle XP Mode" racket-xp-mode])
|
2019-11-23 09:10:03 +01:00
|
|
|
"---"
|
|
|
|
["Comment" comment-dwim]
|
|
|
|
["Insert λ" racket-insert-lambda]
|
|
|
|
["Indent Region" indent-region]
|
|
|
|
["Cycle Paren Shapes" racket-cycle-paren-shapes]
|
|
|
|
["Align" racket-align]
|
|
|
|
["Unalign" racket-unalign]
|
|
|
|
"---"
|
|
|
|
["Visit Module" racket-visit-module]
|
|
|
|
["Return from Visit" racket-unvisit]
|
|
|
|
"---"
|
|
|
|
["Open Require Path" racket-open-require-path]
|
|
|
|
["Find Collection" racket-find-collection]
|
|
|
|
"---"
|
|
|
|
["Next Error or Link" next-error]
|
|
|
|
["Previous Error" previous-error]
|
|
|
|
"---"
|
|
|
|
["Tidy Requires" racket-tidy-requires]
|
|
|
|
["Trim Requires" racket-trim-requires]
|
|
|
|
["Use #lang racket/base" racket-base-requires]
|
|
|
|
"---"
|
|
|
|
["Start Faster" racket-mode-optimize-startup]
|
|
|
|
["Customize..." customize-mode]))
|
|
|
|
|
|
|
|
(defun racket--variables-imenu ()
|
|
|
|
(setq-local imenu-case-fold-search t)
|
|
|
|
(setq-local imenu-create-index-function #'racket--imenu-create-index-function))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(define-derived-mode racket-mode prog-mode
|
|
|
|
"Racket"
|
|
|
|
"Major mode for editing Racket.
|
|
|
|
\\{racket-mode-map}"
|
|
|
|
(racket--common-variables)
|
|
|
|
(racket--variables-imenu)
|
2020-03-24 18:20:37 +01:00
|
|
|
(hs-minor-mode t)
|
|
|
|
(setq-local completion-at-point-functions (list #'racket-complete-at-point))
|
|
|
|
(setq-local eldoc-documentation-function nil)
|
|
|
|
(funcall (or (and (functionp racket-repl-buffer-name-function)
|
|
|
|
racket-repl-buffer-name-function)
|
|
|
|
#'racket-repl-buffer-name-shared))
|
|
|
|
(add-hook 'kill-buffer-hook
|
|
|
|
#'racket-mode-maybe-offer-to-kill-repl-buffer))
|
2019-11-23 09:10:03 +01:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(progn
|
|
|
|
(add-to-list 'auto-mode-alist '("\\.rkt[dl]?\\'" . racket-mode))
|
|
|
|
(modify-coding-system-alist 'file "\\.rkt[dl]?\\'" 'utf-8)
|
|
|
|
(add-to-list 'interpreter-mode-alist '("racket" . racket-mode)))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun racket-mode-start-faster ()
|
|
|
|
"Compile Racket Mode's .rkt files for faster startup.
|
|
|
|
|
|
|
|
Racket Mode is implemented as an Emacs Lisp \"front end\" that
|
|
|
|
talks to a Racket process \"back end\". Because Racket Mode is
|
|
|
|
delivered as an Emacs package instead of a Racket package,
|
|
|
|
installing it does not do the `raco setup` that is normally done
|
|
|
|
for Racket packages.
|
|
|
|
|
|
|
|
This command will do a `raco make` of Racket Mode's .rkt files,
|
|
|
|
creating bytecode files in `compiled/` subdirectories. As a
|
|
|
|
result, when a `racket-run' or `racket-repl' command must start
|
|
|
|
the Racket process, it will start faster.
|
|
|
|
|
|
|
|
If you run this command, ever, you should run it again after:
|
|
|
|
|
|
|
|
- Installing an updated version of Racket Mode. Otherwise, you
|
|
|
|
might lose some of the speed-up.
|
|
|
|
|
|
|
|
- Installing a new version of Racket and/or changing the value of
|
|
|
|
the variable `racket-program'. Otherwise, you might get an
|
|
|
|
error message due to the bytecode being different versions."
|
|
|
|
(interactive)
|
|
|
|
(let* ((racket (executable-find racket-program))
|
|
|
|
(rkts0 (expand-file-name "*.rkt" racket--rkt-source-dir) )
|
|
|
|
(rkts1 (expand-file-name "commands/*.rkt" racket--rkt-source-dir))
|
|
|
|
(command (format "%s -l raco make -v %s %s"
|
|
|
|
(shell-quote-wildcard-pattern racket)
|
|
|
|
(shell-quote-wildcard-pattern rkts0)
|
|
|
|
(shell-quote-wildcard-pattern rkts1)))
|
|
|
|
(prompt (format "Do `%s` " command)))
|
|
|
|
(when (y-or-n-p prompt)
|
|
|
|
(async-shell-command command))))
|
|
|
|
|
2020-04-09 09:23:58 +02:00
|
|
|
;;; Commands that predate `racket-xp-mode'
|
|
|
|
|
|
|
|
(defun racket-doc ()
|
|
|
|
"Instead please use `racket-xp-documentation' or `racket-repl-documentation'.
|
|
|
|
See: <https://github.com/greghendershott/racket-mode/issues/439>"
|
|
|
|
(interactive)
|
|
|
|
(describe-function 'racket-doc))
|
|
|
|
|
|
|
|
(defun racket-describe ()
|
|
|
|
"Instead please use `racket-xp-describe' or `racket-repl-describe'.
|
|
|
|
See: <https://github.com/greghendershott/racket-mode/issues/439>"
|
|
|
|
(interactive)
|
|
|
|
(describe-function 'racket-describe))
|
|
|
|
|
|
|
|
(defun racket-visit-definition ()
|
|
|
|
"Instead please use `racket-xp-visit-definition' or `racket-repl-visit-definition'.
|
|
|
|
See: <https://github.com/greghendershott/racket-mode/issues/439>"
|
|
|
|
(interactive)
|
|
|
|
(describe-function 'racket-visit-definition))
|
|
|
|
|
2019-11-23 09:10:03 +01:00
|
|
|
(provide 'racket-mode)
|
|
|
|
|
|
|
|
;;; racket-mode.el ends here
|