Last active
May 14, 2022 07:54
-
-
Save Gavinok/250a0394e1025a0d96a8dacc9dd832a3 to your computer and use it in GitHub Desktop.
The basis of porting yasnippets to tempel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defvar *snippet-funcs* | |
'((any . (tabstop placeholder choice variable ;; text | |
)) | |
(tabstop . (("$" int) ("${" int "}"))) | |
(placeholder . (("${" int ":" any "}"))) | |
(choice . ("${" int "|" text ("," text)* "|}")) | |
(variable . (("$" var) ("${" var "}") | |
("${" var ":" any "}") | |
("${" var "/" regex "/" (format | text)+ "/" options "}"))) | |
(format . (("$" int) ("${" int "}") | |
("${" int ":" "/upcase") "/downcase"( "/capitalize" "}") | |
("${" int ":+" if "}") | |
("${" int ":?" if ":" else "}") | |
("${" int ":-" else "}") ("${" int ":" else "}"))) | |
(regex . (JavaScript Regular Expression value (ctor-string))) | |
(options . (JavaScript Regular Expression option (ctor-options))) | |
(var . "[_a-zA-Z] [_a-zA-Z0-9]*") | |
(int . "[0-9]+") | |
(text . ".*"))) | |
(defun parse-this (test-string remaining-string) | |
"Treats a given string TEST-STRING and compairs it to | |
REMAINING-STRING returns the matched substring starting at the 0th index and nil | |
if it failed to find a match. | |
Parse-this assumes the TEST-STRING passed was regex if it starts with a [ or ." | |
;; Regex Needed | |
(let ((start-of-sexp (aref test-string 0))) | |
(if (cl-some (lambda (x) (equal start-of-sexp x)) '(?\[ ?.)) | |
(progn | |
(string-match (concat "\\(" test-string "\\)") remaining-string) | |
(match-string 1 remaining-string)) | |
;; No regex needed | |
(let ((matched-string (cl-loop for i in (string-to-list test-string) | |
for j in (string-to-list remaining-string) | |
;; counter to determin the last index matched | |
for counter from 0 | |
if (char-equal i j) | |
collect j | |
else | |
return nil))) | |
(if matched-string | |
(seq-concatenate 'string matched-string) | |
matched-string))))) | |
;; TODO implement this | |
(defun try-different-variations (options remaining-string) | |
"Try each option one at a time and go with the first match | |
return nil if all fail to match." | |
) | |
(defun parse-by-type (current-element remaining-element remaining-string) | |
"Parse the REMAINING-STRING against the CURRENT-ELEMENT the | |
CURRENT-ELEMENT can be a `list' of alternative formats, a | |
symbolwith a `sexp' location in the `*snippet-funcs*', and finally a | |
`string'. | |
parse-by-type returns nil if it was unable to match the | |
CURRENT-ELEMENT with the REMAINING-STRING using any of the above | |
methods." | |
(cl-check-type remaining-string string) | |
(print current-element) | |
(cl-typecase current-element | |
(null nil) | |
;; we have hit text we can match against | |
(string (print (parse-this current-element remaining-string))) | |
;; Find the definition of this symbol | |
(symbol (cons current-element | |
(parse-by-type (alist-get current-element | |
,*snippet-funcs*) | |
remaining-string))) | |
;; Fork in the road we go down one of 2 paths | |
;; first we will go down the first path | |
(cons (or | |
(handle-sexps current-element remaining-string) | |
(handle-sexps remaining-element remaining-string))) | |
(t (handle-sexps current-element remaining-string)))) | |
;; This should return the section of the string that | |
;; was matched or nil if it did not match | |
(defun handle-sexps (current-sexp remaining-string) | |
"Takes a given sexp called CURRENT-SEXP tokenizes the string | |
named REMAINING-STRING using it's contents." | |
(let* ((next-element (cdr current-sexp)) | |
(matched-result (parse-by-type | |
(car current-sexp) | |
(cdr current-sexp) | |
remaining-string)) | |
;; handle when a (key . value) is returned | |
(matched-string (if (consp matched-result) | |
(cdr matched-result) matched-result))) | |
(cons matched-result | |
(if next-element | |
(handle-sexps next-element | |
(substring remaining-string | |
(length matched-string) | |
(length remaining-string))) | |
nil)))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ert-deftest test/parse-this-no-regex () | |
(should (equal (parse-this "$" "$l") "$")) | |
(should (equal (parse-this "hel" "hello") "hel")) | |
(should (equal (parse-this "$" "$l") "$")) | |
(should (equal (parse-this "ello" "hello") nil))) | |
(ert-deftest test/parse-this-with-regex () | |
(should (equal (parse-this "[0-9]+" "10") "10")) | |
(should (equal (parse-this "[0-9]+" "$") nil))) | |
(ert-deftest test/handle-sexps-single-level-list () | |
(should (equal (handle-sexps '("[0-9]+") "10") "10")) | |
(should (equal (handle-sexps '("[0-9]") "$") nil)) | |
(should (equal (handle-sexps '("10") "10") "10"))) | |
(ert-deftest test/handle-sexps-nested-lists () | |
(should (equal (handle-sexps '("[0-9]+" "$") "10$") | |
'("10" "$"))) | |
(should (equal (handle-sexps '("[0-9]+" ("${" int "}")) "10${1}") | |
'("10" ("${" "1" "}"))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment