Skip to content

Instantly share code, notes, and snippets.

@gfanton
Last active August 9, 2023 07:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gfanton/6e233656dfeabd7a46f21f7507b6b311 to your computer and use it in GitHub Desktop.
Save gfanton/6e233656dfeabd7a46f21f7507b6b311 to your computer and use it in GitHub Desktop.
gno mode starter
;;; gno-mode.el --- Major mode for editing GNO files, based on go-mode -*- lexical-binding: t -*-
;; Author: Guilhem Fanton <guilhem.fanton@gmail.com>
;; Version: 0.1
;; Package-Requires: ((emacs "24.3") (go-mode "1.5.0"))
;; Keywords: languages, gno
;; URL: https://gist.github.com/gfanton/6e233656dfeabd7a46f21f7507b6b311
;;; Commentary:
;;
;; gno-mode is a work-in-progress major mode for editing GNO files.
;; It is based on go-mode with only minor differences for now.
;;
;; Current differences from go-mode include:
;; 1. Adaptation for formatting GNO code using gofumpt.
;; 2. Temporary disabling of the Language Server Protocol (LSP) for GNO files, as it creates conflicts and doesn't work with GNO files.
;;
;; This package provides:
;; - `gno-mode` for editing GNO files, similar to `go-mode`.
;; - `gno-dot-mod-mode` for editing GNO module files.
;;
;; See the "Code" section below for more details.
;;
;;; Code:
(require 'go-mode)
(defcustom gno-tab-width 8
"Width of a tab for GNO mode."
:type 'integer
:group 'gno)
;;;###autoload
(define-derived-mode gno-mode go-mode "GNO"
"Major mode for GNO files, an alias for go-mode."
(setq-local tab-width gno-tab-width) ;; Use the custom gno-tab-width variable
(when (fboundp 'lsp-disconnect) ;; Check if the lsp-disconnect function is available
(lsp-disconnect)) ;; lsp doesn't work with gno yet, so we disconnect it
(gno-mode-setup))
;;;###autoload
(add-to-list 'auto-mode-alist '("gno\\.mod\\'" . go-dot-mod-mode))
(defun gno-mode-setup ()
"Hook for setting up gno-mode."
(add-hook 'before-save-hook 'gno-format-buffer nil t))
(defun gno-format-buffer ()
"Format the current buffer using gofumpt. This is an adapted version from go-mode gofmt."
(interactive)
(let ((tmpfile (make-nearby-temp-file "gofumpt" nil ".gno"))
(patchbuf (get-buffer-create "*Gofumpt patch*"))
(errbuf (get-buffer-create "*Gofumpt Errors*"))
(coding-system-for-read 'utf-8)
(coding-system-for-write 'utf-8))
(unwind-protect
(save-restriction
(widen)
(with-current-buffer errbuf
(setq buffer-read-only nil)
(erase-buffer))
(with-current-buffer patchbuf
(erase-buffer))
(write-region nil nil tmpfile)
(message "Calling gofumpt: %s" tmpfile)
(if (zerop (call-process "gofumpt" nil errbuf nil "-w" (file-local-name tmpfile)))
(progn
(if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile))
(message "Buffer is already gofumpted")
(go--apply-rcs-patch patchbuf)
(message "Applied gofumpt"))
(gofmt--kill-error-buffer errbuf))
(message "Could not apply gofumpt")
(gofmt--process-errors (buffer-file-name) tmpfile errbuf)))
(kill-buffer patchbuf)
(delete-file tmpfile))))
;;;###autoload
(define-derived-mode gno-dot-mod-mode go-dot-mod-mode "GNO Mod"
"Major mode for GNO mod files, an alias for go-dot-mod-mode."
)
;;;###autoload
(add-to-list 'auto-mode-alist '("gno\\.mod\\'" . gno-dot-mod-mode))
(provide 'gno-mode)
;;; gno-mode.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment