Skip to content

Instantly share code, notes, and snippets.

@sogaiu
Last active March 21, 2021 06:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sogaiu/e89145fb3385efbb7d3923fe2cdd0697 to your computer and use it in GitHub Desktop.
Save sogaiu/e89145fb3385efbb7d3923fe2cdd0697 to your computer and use it in GitHub Desktop.
in emacs, fix one missing delimiter with some help from janet
;;; a-janet-fix-one.el --- Fixing One Delimiter -*- lexical-binding: t; -*-
;; Author: sogaiu
;; Version: 0.1.0
;; Package-Requires: ((emacs "25.2"))
;; 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/>.
;;; Commentary:
;;; Acknowledgments:
;; Saikyun
;;; Code:
(require 'a-janet-utils)
(defvar a-janet-fix-one-temp-output
'()
"List to accumulate output from janet process.")
(defun a-janet-fix-one-filter (process output)
"Filter for processing janet PROCESS command OUTPUT."
(setq a-janet-fix-one-temp-output
(cons output a-janet-fix-one-temp-output)))
(defun a-janet-fix-one-reset-temp-output ()
"Reset the temporary holding area for process output."
(setq a-janet-fix-one-temp-output '()))
;; handles processing complete output from janet process
(defun a-janet-fix-one-sentinel (process event)
"Sentinel for janet PROCESS receiving EVENT."
(when (equal "finished\n" event)
(let* ((output-str (apply 'concat a-janet-fix-one-temp-output)))
(cond ((string-equal output-str "0")
(message "No closing delimiter determined."))
((memq output-str '(")" "]" "}" "\""))
(insert output-str))
((string-equal "`" (substring output-str 0 1))
(insert output-str))
((string-equal "?" (substring output-str 0 1))
(message "Unexpected character encountered: %s"
(substring output-str 1 2)))
((message "Unknown character received: %S" result-str))))
(a-janet-fix-one-reset-temp-output)))
(defvar a-janet-fix-one-prog
(with-temp-buffer
(insert-file-contents (concat (a-janet-package-path)
"find-missing-delim.janet"))
(buffer-string)))
(defun a-janet-fix-one ()
"Close one of the delimiters (, [, or { appropriately."
(interactive "")
(condition-case err
(let* ((text-to-here (buffer-substring-no-properties
(point-min) (point)))
(a-janet-fix-one-proc
(make-process :name "janet"
:buffer nil
:command (list "janet"
"-s"
"-q"
"-e"
a-janet-fix-one-prog)
:connection-type 'pipe
:filter 'a-janet-fix-one-filter
:sentinel 'a-janet-fix-one-sentinel)))
(when a-janet-fix-one-proc
;; XXX: is this sufficient?
(a-janet-fix-one-reset-temp-output)
(process-send-string a-janet-fix-one-proc text-to-here)
(process-send-eof a-janet-fix-one-proc)))
(error
(message "Error: %s %s" (car err) (cdr err)))))
(provide 'a-janet-fix-one)
;;; a-janet-fix-one.el ends here
;;; a-janet-utils.el --- utils for a-janet-mode -*- lexical-binding: t; -*-
;; Author: sogaiu
;; Version: 0.1.0
;; URL: https://codeberg.org/sogaiu/a-janet-mode
;; Package-Requires: ((emacs "25.2") (tree-sitter "0.13.0"))
;; 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/>.
;;; Commentary:
;;; Code:
;; XXX: hack for helping `a-janet-package-path'
(defvar a-janet-utils-thing nil)
;; XXX: may be there's a better way to do this
(defun a-janet-package-path ()
"Determine path to containing directory of a-janet package."
(locate-dominating-file (symbol-file 'a-janet-utils-thing)
"a-janet-mode.el"))
(provide 'a-janet-utils)
;;; a-janet-util.el ends here
# input: janet source code fragment on stdin
# output: first missing delimiter or report of attempt on stdout
(var res 0)
(try
(do
(def buf (file/read stdin :all))
(def p (parser/new))
(parser/consume p buf)
(parser/eof p)
(when-let [delims ((parser/state p) :delimiters)]
(when (pos? (length delims))
(let [last-char (string/slice delims -2)]
(set res
(cond
(= "(" last-char)
")"
#
(= "[" last-char)
"]"
#
(= "{" last-char)
"}"
#
(= `"` last-char)
`"`
#
(= "`" last-char)
(let [backtick-count (->> (string/reverse delims)
(peg/match ~(sequence (some "`")
(position)))
first)]
(string/repeat "`" backtick-count))
# XXX: unexpected character
(string "?" last-char)))))))
([err]
(set res
(string "!" err))))
(prin res)
(flush)
(os/exit 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment