Skip to content

Instantly share code, notes, and snippets.

@InfiniteCoder01
Last active October 19, 2024 13:02
Show Gist options
  • Save InfiniteCoder01/e0cba8f7427fcc6719593780bd897657 to your computer and use it in GitHub Desktop.
Save InfiniteCoder01/e0cba8f7427fcc6719593780bd897657 to your computer and use it in GitHub Desktop.
Game of life in helix editor (experimental plugins in steel scheme PR)

Instructions

You will need a copy of this helix fork (works for sure in this commit, in case breaking changes happen)

Follow instructions in STEEL.md (you might need to add +stable after cargo to all commands if you get helix-term build errors, f. e. cargo xtask steel will become cargo +stable xtask steel) to install helix and steel and don't forget to run cargo xtask code-gen (or cargo +stable xtask code-gen) after you install helix to generate bindings

Copy all files in this gist into your helix config directory (game-of-life.scm into cogs subdirectory inside)

(require "helix/editor.scm")
(require (prefix-in helix. "helix/commands.scm"))
(require (prefix-in helix.static. "helix/static.scm"))
; (require "helix/misc.scm")
(provide game-of-life gol-update)
;; Utilities
(define (make-list size item) (mutable-vector->list (make-vector size item)))
(define (push-front list item) (reverse (push-back (reverse list) item)))
(define (lines->string lines) (apply string-append (map (lambda (line) (string-append line "\n")) lines)))
(define (string-set string index value) (string-append (substring string 0 index) (make-string 1 value) (substring string (+ index 1) (string-length string))))
(define (map-wi list start-index mapper)
(if (empty? list)
list
(push-front (map-wi(cdr list) (+ start-index 1) mapper) (mapper start-index (car list)))))
(define (map-nth list index mapper)
(if (= index 0)
(push-front (cdr list) (mapper (car list)))
(push-front (map-nth (cdr list) (- index 1) mapper) (car list))))
;; Board
(define (make-board width height) (make-list height (make-string width #\ )))
(define (board-ref board x y) (string-ref (list-ref board y) x))
(define (board-set board x y value)
(map-nth board y
(lambda (line)
(string-set line x value))))
(define (board-width board) (string-length (first board)))
(define (board-height board) (length board))
;; Neighbours
(define (board-count-cell board x y)
(if (char=? (board-ref board x y) #\#) 1 0))
(define (board-count-line board x y)
(+
(if (> x 0) (board-count-cell board (- x 1) y) 0)
(board-count-cell board x y)
(if (< (+ x 1) (board-width board)) (board-count-cell board (+ x 1) y) 0)))
(define (neighbours board x y)
(+
(if (> y 0) (board-count-line board x (- y 1)) 0)
(- (board-count-line board x y) (board-count-cell board x y))
(if (< (+ y 1) (board-height board)) (board-count-line board x (+ y 1)) 0)))
;; Step
(define (step board)
(map-wi board 0 (lambda (y line)
(list->string (map-wi (string->list line) 0 (lambda (x cell)
(let ((nc (neighbours board x y)))
(if (char=? cell #\#)
(if (or (= nc 2) (= nc 3)) cell #\ )
(if (= nc 3) #\# cell)))
))))))
;; Initial board
(define board-initial (make-board 80 40))
(define cx (/ (board-width board-initial) 2))
(define cy (/ (board-height board-initial) 2))
(set! board-initial (board-set board-initial cx cy #\#))
(set! board-initial (board-set board-initial cx (- cy 1) #\#))
(set! board-initial (board-set board-initial cx (+ cy 1) #\#))
(set! board-initial (board-set board-initial (- cx 1) cy #\#))
(set! board-initial (board-set board-initial (+ cx 1) (+ cy 1) #\#))
(define TITLE "[game-of-life]")
(define doc-id 'uninitialzed)
;;@doc
;;Game of life inside of helix
(define (game-of-life)
(helix.new)
(set-scratch-buffer-name! TITLE)
(set! doc-id (editor->doc-id (editor-focus)))
(helix.static.select_all)
(helix.static.delete_selection)
(helix.static.insert_string (lines->string board-initial))
(helix.static.goto_line_start))
;; Update Game of life
(define (gol-update)
(helix.static.select_all)
(define state (split-many (helix.static.current-highlighted-text!) "\n"))
(set! state (reverse (rest (reverse state))))
(define new-state (step state))
(helix.static.delete_selection)
(helix.static.insert_string (lines->string new-state))
(helix.static.goto_line_start))
(define GOL-KEYBINDINGS
(hash "normal"
(hash " " ':gol-update)))
(require (only-in "cogs/game-of-life.scm" game-of-life gol-update))
(provide game-of-life gol-update)
(require-builtin helix/core/keymaps as helix.keymaps.)
(require "helix/configuration.scm")
(define (add-global-keybinding map)
(define global-bindings (get-keybindings))
(helix.keymaps.helix-merge-keybindings
global-bindings
(~> map (value->jsexpr-string) (helix.keymaps.helix-string->keymap)))
(keybindings global-bindings) )
(add-global-keybinding (hash "normal" (hash "C-x" ":gol-update")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment