Skip to content

Commit

Permalink
Add configuration layer for Gleam language
Browse files Browse the repository at this point in the history
  • Loading branch information
2ynn authored and smile13241324 committed Jun 29, 2024
1 parent 7bce0c7 commit 36b52f1
Show file tree
Hide file tree
Showing 7 changed files with 331 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.develop
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ the [[file:CHANGELOG.org][CHANGELOG.org]] file.
* Release 0.300.x
** 0.300.0
*** Hot new feature
- Add configuration layer for gleam-lang (thanks to Qynn Schwaab)
- Highlight ruby debugger lines appropriately
- Add support for Android emacs.
- Extensive use of lazy loading of packages and other tricks to reduce Spacemacs
Expand Down
97 changes: 97 additions & 0 deletions layers/+lang/gleam/README.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#+TITLE: Gleam layer

#+TAGS: general|layer|programming|pure

[[file:img/gleam.png]]

* Table of Contents :TOC_4_gh:noexport:
- [[#description][Description]]
- [[#features][Features:]]
- [[#install][Install]]
- [[#configuration][Configuration]]
- [[#lsp][LSP]]
- [[#formatting][Formatting]]
- [[#execution][Execution]]
- [[#key-bindings][Key bindings]]
- [[#lsp-1][LSP]]
- [[#formatting-1][Formatting]]
- [[#execution-1][Execution]]

* Description
This layers adds support for [[https://gleam.run/][Gleam]]. It relies on the official [[https://github.com/gleam-lang/gleam-mode][gleam-mode]] package and [[https://github.com/emacsmirror/tree-sitter-indent][tree-sitter-indent]].

** Features:
- [[https://gleam.run/news/v0.21-introducing-the-gleam-language-server/][Gleam language server]] integration
- Formatting (=gleam format=)
- Execution (=gleam build=, =gleam run=, =gleam test=)

* Install

To use this configuration layer, add ~gleam~ to the existing =dotspacemacs-configuration-layers= list in your =~/.spacemacs= file.

You also need to [[https://gleam.run/getting-started/installing/][install Gleam]] and make sure the =gleam= command was properly added to you =PATH=.

* Configuration
** LSP
=lsp-gleam= is the official implementation of the Gleam language server that comes pre-installed with the built-in =gleam lsp= command.

If the =lsp= layer was already added to your dotfile, the LSP backend will be enabled by default. To explicitly disable it for the =gleam= layer, set the following:
#+BEGIN_SRC elisp
(gleam :variables gleam-enable-lsp nil)
#+END_SRC

If the =lsp= layer is not already installed, the LSP backend must be explicitely enabled for =lsp-mode= to start automatically when visiting a gleam file:
#+BEGIN_SRC elisp
(gleam :variables gleam-enable-lsp nil)
#+END_SRC

When enabled, the =gleam-lsp= server will be automatically initialized when visiting a gleam file.

More details can be found in the [[https://github.com/syl20bnr/spacemacs/tree/develop/layers/%2Btools/lsp#configuration][lsp layer configuration section]].

** Formatting
=gleam-mode= provides the ~gleam-format~ command (~SPC m = =~) to format source code in the official Gleam style.

To automatically apply formatting files before saving:
#+BEGIN_SRC elisp
(gleam :variables gleam-format-on-save t)
#+END_SRC

If the LSP backend is enabled, automatic formatting will use the =lsp-format-buffer= command (~SPC m = b~) instead.

** Execution
The platform to target during compilation is set to =erlang= by default. To select =javascript= instead:
#+BEGIN_SRC elisp
(gleam :variables gleam-target 'javascript)
#+END_SRC

The default runtime for the =javascript= target is =nodejs=. To select a different runtime:
#+BEGIN_SRC elisp
(gleam :variables gleam-target 'javascript
gleam-runtime 'bun)
#+END_SRC

By default, the ~spacemacs//gleam-run~ command (~SPC m c c~) is set up to execute =gleam run= inside the project root directory. To run the module associated with the current instead:
#+BEGIN_SRC elisp
(gleam :variables gleam-run-scope 'module)
#+END_SRC


* Key bindings
** LSP
Detailed keybindings can be found in the [[https://github.com/syl20bnr/spacemacs/tree/develop/layers/%2Btools/lsp#key-bindings][lsp layer keybindings section]]

** Formatting
| Key Binding | Description |
|-------------+-------------------------------------------------|
| ~SPC m = =~ | Run =gleam-format= |
| ~SPC m T =~ | Toggle =gleam-format-on-save= in current buffer |

** Execution
| Key Binding | Description |
|-------------+------------------------------------------------|
| ~SPC m c b~ | Build project (run =gleam build=) |
| ~SPC m c a~ | Run project (run =gleam run= in project root) |
| ~SPC m c m~ | Run module (run =gleam run --module <module>=) |
| ~SPC m c c~ | Run project or module (see ~gleam-run-scope~) |
| ~SPC m t a~ | Test project (run =gleam test=) |
51 changes: 51 additions & 0 deletions layers/+lang/gleam/config.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
;;; config.el --- Gleam layer config file for Spacemacs
;;
;; Copyright (c) 2012-2024 Sylvain Benner & Contributors
;;
;; Author: Qynn Schwaab <[email protected]>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;; 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 3 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/>.


(spacemacs|define-jump-handlers gleam-mode)

(defvar gleam-format-on-save nil
"If non-nil, automatically run gleam-format before save. Default is nil.")

(defvar gleam-enable-lsp (not (null (configuration-layer/layer-used-p 'lsp)))
"Whether to enable gleam-lsp. Default is nil unless `lsp' layer is used.")

(defvar gleam-target 'erlang
"The platform to target for `gleam-run-command'.
Possible values are `erlang' or `javascript'. Default is `erlang'.")

(defvar gleam-run-scope 'project
"The scope for `gleam-run-command'.
Possible values are `project', `module' or `nil'. Default is `project'.")

(defvar gleam-runtime 'nodejs
"The runtime to target when `gleam-run-target' is set to `javascript'.
Possible values are `nodejs', `deno' or `bun'. Default is `nodejs'.")

(defvar gleam-build-command "gleam build"
"Gleam build command. Default is \"gleam build\".")

(defvar gleam-run-command "gleam run"
"Gleam run command. Default is \"gleam run\".")

(defvar gleam-test-command "gleam test"
"Gleam test command. Default is \"gleam test\".")
101 changes: 101 additions & 0 deletions layers/+lang/gleam/funcs.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
;;; funcs.el --- Gleam layer functions file for Spacemacs
;;
;; Copyright (c) 2012-2024 Sylvain Benner & Contributors
;;
;; Author: Qynn Schwaab <[email protected]>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;; 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 3 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/>.


;; lsp

(defun spacemacs//gleam-setup-lsp ()
"Conditionally setup lsp."
(when gleam-enable-lsp (lsp-deferred)))


;; formatting

(defun spacemacs//gleam-format ()
"Ran before saving a file when `gleam-format-on-save' is non-nil.
Either `lsp-format-buffer' when `lsp-mode' is active, `gleam-format' otherwise."
(if lsp-mode
(lsp-format-buffer)
(gleam-format)))

(defun spacemacs//gleam-setup-format-on-save ()
"Conditionally setup format on save."
(funcall (if gleam-format-on-save 'add-hook 'remove-hook) 'gleam-mode-hook
(lambda () (add-hook 'before-save-hook 'spacemacs//gleam-format nil t))))

(defun spacemacs//gleam-toggle-format-on-save ()
"Toggle gleam-format-on-save."
(interactive)
(setq gleam-format-on-save (not gleam-format-on-save))
(message "gleam-format-on-save set to %s" gleam-format-on-save)
(if gleam-format-on-save
(add-hook 'before-save-hook 'spacemacs//gleam-format nil t)
(remove-hook 'before-save-hook 'spacemacs//gleam-format t))
(spacemacs//gleam-setup-format-on-save))


;; execution

(defun spacemacs//gleam-shell-command (command &optional scope target runtime)
"Execute gleam shell command.
CMD is a string, the command to execute.
SCOPE is a quoted symbol corresponding to `gleam-run-scope'
TARGET is a quoted symbol corresponding to `gleam-target'
RUNTIME is a quoted symbol corresponding to `gleam-runtime'."
(setq cmd (concat
(if (eq scope 'project)
(format "cd %s; %s" (projectile-project-root) command)
command)
(concat
(format " --target %s" (symbol-name target))
(when (and runtime (eq gleam-target 'javascript))
(format " --runtime %s" (symbol-name runtime)))
(when (eq scope 'module)
(format " --module %s" (file-name-base (buffer-file-name)))))))
(message "Running `%s'" cmd)
(shell-command cmd))


(defun spacemacs//gleam-build ()
"Build project. Execute \"gleam run\" inside current directory."
(interactive)
(spacemacs//gleam-shell-command gleam-build-command nil gleam-target nil))

(defun spacemacs//gleam-test-project ()
"Test project. Execute \"gleam test --target <gleam-target>\" inside project root directory."
(interactive)
(spacemacs//gleam-shell-command gleam-test-command (intern "project") gleam-target gleam-runtime))

(defun spacemacs//gleam-run-project ()
"Run project. Execute \"gleam run --target <gleam-target> [--runtime <gleam-runtime>]\" inside project root directory."
(interactive)
(spacemacs//gleam-shell-command gleam-run-command (intern "project") gleam-target gleam-runtime))

(defun spacemacs//gleam-run-module ()
"Run module. Execute \"gleam run --module <module> --target <gleam-target> [--runtime <gleam-runtime>]\"."
(interactive)
(spacemacs//gleam-shell-command gleam-run-command (intern "module") gleam-target gleam-runtime))

(defun spacemacs//gleam-run ()
"Run project or module depending on the value of `gleam-run-scope'."
(interactive)
(spacemacs//gleam-shell-command gleam-run-command gleam-run-scope gleam-target gleam-runtime))
Binary file added layers/+lang/gleam/img/gleam.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions layers/+lang/gleam/layers.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
;;; layers.el --- Gleam layer layers file for Spacemacs.
;;
;; Copyright (c) 2012-2024 Sylvain Benner & Contributors
;;
;; Author: Qynn Schwaab <[email protected]>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;; 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 3 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/>.


(configuration-layer/declare-layer-dependencies
(append '(tree-sitter)
(if (and (boundp 'gleam-enable-lsp) gleam-enable-lsp) '(lsp) '())))
55 changes: 55 additions & 0 deletions layers/+lang/gleam/packages.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
;;; packages.el --- Gleam layer packages file for Spacemacs.
;;
;; Copyright (c) 2012-2024 Sylvain Benner & Contributors
;;
;; Author: Qynn Schwaab <[email protected]>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;; 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 3 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/>.


(defconst gleam-packages
'((tree-sitter-indent)
(gleam-mode :location (recipe
:fetcher github
:repo "gleam-lang/gleam-mode"
:files ("*.el" "tree-sitter-gleam")))))

(defun gleam/post-init-tree-sitter-indent ()
"Initialize tree-sitter-indent"
(use-package tree-sitter-indent
:defer t))

(defun gleam/init-gleam-mode ()
"Initialize gleam-mode"
(use-package gleam-mode
:mode ("\\.gleam\\'" . gleam-mode)
:hook ((gleam-mode . spacemacs//gleam-setup-format-on-save)
(gleam-mode . spacemacs//gleam-setup-lsp))
:config
(spacemacs/declare-prefix-for-mode 'gleam-mode "m=" "format")
(spacemacs/declare-prefix-for-mode 'gleam-mode "mc" "compile")
(spacemacs/declare-prefix-for-mode 'gleam-mode "mg" "goto")
(spacemacs/declare-prefix-for-mode 'gleam-mode "mt" "tests")
(spacemacs/declare-prefix-for-mode 'gleam-mode "mT" "toggle")
(spacemacs/set-leader-keys-for-major-mode 'gleam-mode
"==" 'gleam-format
"cb" 'spacemacs//gleam-build
"cc" 'spacemacs//gleam-run
"cm" 'spacemacs//gleam-run-module
"ca" 'spacemacs//gleam-run-project
"ta" 'spacemacs//gleam-test-project
"T=" 'spacemacs//gleam-toggle-format-on-save)))

0 comments on commit 36b52f1

Please sign in to comment.