diff --git a/CHANGELOG.develop b/CHANGELOG.develop index 42331b544..ab9350c0f 100644 --- a/CHANGELOG.develop +++ b/CHANGELOG.develop @@ -311,6 +311,7 @@ sane way, here is the complete list of changed key bindings - perl5 (thanks to Troy Hinckley, Jinseop Kim and Michael Rohleder) - perl6 (thanks to Bahtiar Gadimov and yuhan0) - prolog (thanks to Newres Al Haider) +- reasonml (thanks to fredyr and Dave Aitken) - protobuf (thanks to Amol Mandhane) - restructuredtext (thanks to Wei-Wei Guo and Kalle Lindqvist) - semantic-web (thanks to Andreas Textor) @@ -1596,7 +1597,7 @@ Other: - Added missing prefixes for =web-mode= and =css-mode= (thanks to Uroš Perišić) - Fixed ~TAB~ indenting in =web-mode= (thanks to Christopher Eames) - Added =lsp= support for =css-mode=, =less-css-mode=, and =scss-mode= -- Added support for =prettier= formatter in HTML buffers +- Added support for =prettier= formatter in HTML buffers **** Hy - Added support for virtual envs (thanks to Danny Freeman) - Key bindings: @@ -2224,6 +2225,19 @@ Other: - Use JSX header without breaking React (thanks to Jam Risser) - Fixed React imports when using web beautify. (thanks to Ismael) - Made layer depends on node and tern layers (thanks to Sylvain Benner) +**** ReasonML +- Key bindings: + - ~SPC m g g~ Jump to definition + - ~SPC m g G~ Jump to definition (other window) + - ~SPC m g b~ Jump back + - ~SPC m h t~ Show type + - ~SPC m h h~ Show docs + - ~SPC m r d~ Merlin destruct + - ~SPC m = =~ Refmt + - ~SPC m t r~ Toggle auto-refmt on save + - ~SPC m = m r~ Refmt: convert ml syntax to re syntax + - ~SPC m = r m~ Refmt: convert re syntax to ml syntax + (thanks to Fredrik Dyrkell and Dave Aitken) **** Ruby - Added support for =org-babel= (thanks to Muneeb Shaikh) - Highlight debugger keywords (thanks to Alexander Berezovsky and Eivind Fonn) diff --git a/layers/+lang/reasonml/README.org b/layers/+lang/reasonml/README.org new file mode 100644 index 000000000..e8f51897c --- /dev/null +++ b/layers/+lang/reasonml/README.org @@ -0,0 +1,76 @@ +#+TITLE: ReasonML layer + +[[https://reasonml.github.io/img/reason.svg]] + +* Description + +Spacemacs layer for ReasonML, based around [[https://github.com/reasonml-editor/reason-mode][reason-mode]]. + +** Features: + - Syntax highlighting / indentation + - Autocomplete (via =merlin=) + - Lint / error display (via =merlin=, and =flycheck= if =syntax-checking= layer is enabled) + - REPL via =rtop= + - Auto-formatting (via =refmt=) + +* Install + +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =reasonml= to the existing =dotspacemacs-configuration-layers= list in this +file. + +This layer depends on the `ocaml` layer which should be installed automatically. + +** Merlin + +You'll need merlin (binaries =ocamlmerlin= and =ocamlmerlin-reason=) installed +on your system and on your =PATH= for errors and auto-completion. + +If you're familiar with =opam= you can +#+BEGIN_SRC sh + opam install merlin reason +#+END_SRC +to get =ocamlmerlin= and =ocamlmerlin-reason= on your current =opam= switch. + +** Refmt + +Similarly to Merlin, you'll need the =refmt= binary on your path. + +If you're familiar with =opam= you can +#+BEGIN_SRC sh + opam install reason +#+END_SRC +to get =refmt= in your current =opam switch=. + +If your project depends on a specific version of =refmt=, you can set +=refmt-command= (via =customize-mode= or =(setq refmt-command ..)=) to the path +to a particular binary. You can also use the special values ='npm= or ='opam= to +run =refmt= via =npx= or =opam exec=, which will keep you on the correct version +for your current opam switch, or the project-local of =node_modules=. + +You can toggle =refmt= on save with =SPC m r t=. To permanently enable it, add the layer variable: +#+BEGIN_SRC emacs-lisp + (reasonml :variables reason-auto-refmt t) +#+END_SRC +in your =dotspacemacs-configuration-layers=. + +* Key bindings + +The main keybindings, see =packages.el= for the main list. + +| Key binding | Description | +|---------------+---------------------------------------| +| ~SPC m g g~ | Jump to definition | +| ~SPC m g G~ | Jump to definition (other window) | +| ~SPC m g b~ | Jump back | +| ~SPC m h t~ | Show type | +| ~SPC m h h~ | Show docs | +| ~SPC m r d~ | Merlin destruct | +| ~SPC m = =~ | Refmt | +| ~SPC m t r~ | Toggle auto-refmt on save | +| ~SPC m = m r~ | Refmt: convert ml syntax to re syntax | +| ~SPC m = r m~ | Refmt: convert re syntax to ml syntax | + +* Thanks + +Special thanks to [[https://github.com/fredyr/][fredyr]] who wrote the initial verison of this layer. diff --git a/layers/+lang/reasonml/config.el b/layers/+lang/reasonml/config.el new file mode 100644 index 000000000..c7730b4c0 --- /dev/null +++ b/layers/+lang/reasonml/config.el @@ -0,0 +1,13 @@ +;;; config.el --- reasonml layer configuration file for Spacemacs +;; +;; Copyright (c) 2012-2018 Sylvain Benner & Contributors +;; +;; Author: Dave Aitken +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar-local reason-auto-refmt nil + "Whether to automatcally run refmt on save in the current reason-mode buffer.") diff --git a/layers/+lang/reasonml/funcs.el b/layers/+lang/reasonml/funcs.el new file mode 100644 index 000000000..a9de2c1aa --- /dev/null +++ b/layers/+lang/reasonml/funcs.el @@ -0,0 +1,28 @@ +;;; funcs.el --- reasonml layer functions file for Spacemacs +;; +;; Copyright (c) 2012-2018 Sylvain Benner & Contributors +;; +;; Author: Dave Aitken +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun reason/rtop-prompt () + "The rtop prompt function." + (let ((prompt (format "rtop[%d]> " utop-command-number))) + (add-text-properties 0 (length prompt) '(face utop-prompt) prompt) + prompt)) + +(defun reason/refmt-re-to-ml () + (interactive) + (if (use-region-p) + (apply-refmt (region-beginning) (region-end) "re" "ml") + (apply-refmt nil nil "re" "ml"))) + +(defun reason/refmt-ml-to-re () + (interactive) + (if (use-region-p) + (apply-refmt (region-beginning) (region-end) "ml" "re") + (apply-refmt nil nil "ml" "re"))) diff --git a/layers/+lang/reasonml/layers.el b/layers/+lang/reasonml/layers.el new file mode 100644 index 000000000..b0a7b084f --- /dev/null +++ b/layers/+lang/reasonml/layers.el @@ -0,0 +1,12 @@ +;;; layers.el --- reasonml layer layers file for Spacemacs +;; +;; Copyright (c) 2012-2018 Sylvain Benner & Contributors +;; +;; Author: Dave Aitken +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(configuration-layer/declare-layer 'ocaml) diff --git a/layers/+lang/reasonml/packages.el b/layers/+lang/reasonml/packages.el new file mode 100644 index 000000000..f3cfab4f0 --- /dev/null +++ b/layers/+lang/reasonml/packages.el @@ -0,0 +1,150 @@ +;;; packages.el --- reasonml layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Fredrik Dyrkell +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst reasonml-packages + '(company + evil-matchit + flycheck + flycheck-ocaml + merlin + popwin + reason-mode + utop)) + +(defun reasonml/post-init-company () + (when (configuration-layer/package-usedp 'merlin) + (spacemacs|add-company-backends + :backends merlin-company-backend + :modes reason-mode))) + +(defun reasonml/post-init-evil-matchit () + (evilmi-load-plugin-rules '(reason-mode) '(template simple html)) + (add-hook 'reason-mode-hook 'turn-on-evil-matchit-mode)) + +(defun flycheck-ocaml-reason-setup () + (with-eval-after-load 'merlin + (setq merlin-error-after-save nil) + + (flycheck-define-generic-checker 'reason-merlin + "A syntax checker for Reason using Merlin Mode. + See URL `https://github.com/the-lambda-church/merlin'." + :start #'flycheck-ocaml-merlin-start + :verify #'flycheck-verify-ocaml-merlin + :modes '(reason-mode) + :predicate (and merlin-mode + ;; Don't check if Merlin's own checking is + ;; enabled, to avoid duplicate overlays + (not merlin-error-after-save))) + + (interactive) + (add-to-list 'flycheck-checkers 'reason-merlin))) + +(defun reasonml/post-init-flycheck () + (when (configuration-layer/layer-used-p 'syntax-checking) + (spacemacs/enable-flycheck 'reason-mode))) + +(defun reasonml/post-init-flycheck-ocaml () + (when (configuration-layer/layer-used-p 'syntax-checking) + (flycheck-ocaml-reason-setup))) + +(defun reasonml/post-init-merlin () + (use-package merlin + :defer t + :init + (progn + (setq merlin-completion-with-doc t) + + (spacemacs/set-leader-keys-for-major-mode 'reason-mode + "cp" 'merlin-project-check + "cv" 'merlin-goto-project-file + "eC" 'merlin-error-check + "en" 'merlin-error-next + "eN" 'merlin-error-prev + "gb" 'merlin-pop-stack + "gg" 'merlin-locate + "gG" 'spacemacs/merlin-locate-other-window + "gl" 'merlin-locate-ident + "gi" 'merlin-switch-to-ml + "gI" 'merlin-switch-to-mli + "go" 'merlin-occurrences + "hh" 'merlin-document + "ht" 'merlin-type-enclosing + "hT" 'merlin-type-expr + "rd" 'merlin-destruct)))) + +(defun reasonml/pre-init-popwin () + (spacemacs|use-package-add-hook popwin + :post-config + (push '("*Refmt Errors*" :tail t :position bottom :noselect t) + popwin:special-display-config))) + +(defun reasonml/init-reason-mode () + (use-package reason-mode + :defer t + :mode ("\\.rei?\\'" . reason-mode) + :init + (progn + (add-hook 'reason-mode-hook 'merlin-mode) + (add-hook 'reason-mode-hook 'utop-minor-mode) + (when (configuration-layer/layer-used-p 'syntax-checking) + (add-hook 'reason-mode-hook 'flycheck-mode)) + + (add-hook 'reason-mode-hook + (lambda () + (when reason-auto-refmt + (add-hook 'before-save-hook 'refmt nil t)))) + + (spacemacs|add-toggle reason-auto-refmt + :documentation "Toggle automatic refmt on save." + :status reason-auto-refmt + :on (progn + (setq reason-auto-refmt t) + (add-hook 'before-save-hook 'refmt nil t)) + :off (progn + (setq reason-auto-refmt nil) + (remove-hook 'before-save-hook 'refmt t)))) + + :config + (progn + (spacemacs/declare-prefix-for-mode 'reason-mode "mc" "compile") + (spacemacs/declare-prefix-for-mode 'reason-mode "mt" "toggle") + (spacemacs/declare-prefix-for-mode 'reason-mode "me" "errors/eval") + (spacemacs/declare-prefix-for-mode 'reason-mode "mg" "goto") + (spacemacs/declare-prefix-for-mode 'reason-mode "mh" "help/show") + (spacemacs/declare-prefix-for-mode 'reason-mode "mr" "refactor") + (spacemacs/declare-prefix-for-mode 'reason-mode "m=" "refmt") + + (spacemacs/set-leader-keys-for-major-mode 'reason-mode + "cr" 'refmt + "==" 'refmt + "tr" 'spacemacs/toggle-reason-auto-refmt + "=mr" 'reason/refmt-ml-to-re + "=rm" 'reason/refmt-re-to-ml)))) + +(defun reasonml/pre-init-utop () + (spacemacs|use-package-add-hook utop + :post-init + (add-hook + 'reason-mode-hook + (lambda () + (setq utop-command "rtop -emacs") + (setq utop-edit-command nil) + (setq utop-prompt 'reason/rtop-prompt) + (setq utop-initial-command "let myVar = \"Hello Reason!\";") + (setq utop-phrase-terminator ";"))) + :post-config + (progn + (spacemacs/set-leader-keys-for-major-mode 'reason-mode + "er" 'utop-eval-region + "eb" 'utop-eval-buffer + "ee" 'utop-eval-phrase)))) + +;;; packages.el ends here