Skip to content

Instantly share code, notes, and snippets.

@jason-chandler
Last active May 22, 2025 19:55
Show Gist options
  • Select an option

  • Save jason-chandler/6332e3fd753fa87e3b1cd13582df5862 to your computer and use it in GitHub Desktop.

Select an option

Save jason-chandler/6332e3fd753fa87e3b1cd13582df5862 to your computer and use it in GitHub Desktop.
Basic .lem/init.lisp showing some ugly workarounds for getting cxxxr/valtan to work along with paredit and a few common themes
(in-package :lem-user)
(define-color-theme "zenburn" ()
(:foreground "#dcdccc")
(:background "#3f3f3f")
(cursor :foreground "#3f3f3f" :background "#cc9393")
(syntax-warning-attribute :foreground "#dca3a3" :background "#3f3f3f")
(syntax-string-attribute :foreground "#cc9393" :background "#3f3f3f")
(syntax-comment-attribute :foreground "#7f9f7f" :background "#3f3f3f")
(syntax-keyword-attribute :foreground "#f0dfaf" :background "#3f3f3f" :bold t)
(syntax-constant-attribute :foreground "#dca3a3" :background "#3f3f3f" :bold t)
(syntax-function-name-attribute :foreground "#8cd0d3" :background "#3f3f3f")
(syntax-variable-attribute :foreground "#efdcbc" :background "#3f3f3f")
(syntax-type-attribute :foreground "#dfe4cf" :background "#3f3f3f" :bold t)
(syntax-builtin-attribute :foreground "#dfdfbf" :background "#3f3f3f"))
(define-color-theme "gruvbox" ()
(:foreground "#fbf1c7")
(:background "#282828")
(cursor :foreground "#282828" :background "#fbf1c7")
(syntax-warning-attribute :foreground "#d3869b" :background "#282828")
(syntax-string-attribute :foreground "#b8bb26" :background "#282828")
(syntax-comment-attribute :foreground "#7c6f64" :background "#282828")
(syntax-keyword-attribute :foreground "#fb4934" :background "#282828" :bold t)
(syntax-constant-attribute :foreground "#fabd2f" :background "#282828" :bold t)
(syntax-function-name-attribute :foreground "#b8bb26" :background "#282828")
(syntax-variable-attribute :foreground "#83a598" :background "#282828")
(syntax-type-attribute :foreground "#fabd2f" :background "#282828" :bold t)
(syntax-builtin-attribute :foreground "#fb4934" :background "#282828"))
(define-color-theme "sourcerer" ()
(:foreground "#c2c2b0")
(:background "#222222")
(cursor :foreground "#222222" :background "#c2c2b0")
(syntax-warning-attribute :foreground "#8f6f8f" :background "#222222" :bold t)
(syntax-string-attribute :foreground "#779b70" :background "#222222")
(syntax-comment-attribute :foreground "#5c5d56" :background "#222222")
(syntax-keyword-attribute :foreground "#90b0d1" :background "#222222")
(syntax-constant-attribute :foreground "#7e8aa2" :background "#222222" :bold t)
(syntax-function-name-attribute :foreground "#7e8aa2" :background "#222222")
(syntax-variable-attribute :foreground "#9ebac2" :background "#222222")
(syntax-type-attribute :foreground "#7e8aa2" :background "#222222" :bold t)
(syntax-builtin-attribute :foreground "#9ebac2" :background "#222222"))
(load-theme "gruvbox")
#+lem-sdl2
(progn
(let ((font (lem-sdl2/font::get-resource-pathname "resources/fonts/FantasqueSansMono-Regular.ttf"))
(bold-font (lem-sdl2/font::get-resource-pathname "resources/fonts/FantasqueSansMono-Bold.ttf")))
(when (and (probe-file font) (probe-file bold-font))
(lem-sdl2/display:change-font (lem-sdl2/display:current-display)
(lem-sdl2/font:make-font-config
:latin-normal-file font
:latin-bold-file bold-font
:size 19)))))
;; use the ultralisp dist for quicklisp
(unless (member "ultralisp" (ql-dist:all-dists)
:key 'ql-dist:name
:test 'string=)
(ql-dist:install-dist "http://dist.ultralisp.org/"
:prompt nil))
(define-file-type ("system") lem-lisp-mode:lisp-mode)
;; automatically load paredit when opening a lisp file
(defun pared-hook ()
(lem-paredit-mode:paredit-mode t))
(add-hook lem-lisp-mode:*lisp-mode-hook* #'pared-hook)
#+valtan-installed
(progn
;; grab and load up individual pieces of valtan compiler
(progn
(dolist (valtan-lib '("valtan" "cl-source-map" "valtan/library/valtan-core" "lem/modes/lisp-mode" "valtan/lem"))
(let ((lib-path (concatenate 'string "~/.roswell/local-projects/cxxxr/" valtan-lib "/")))
(push lib-path asdf:*central-registry*)))
(ql:quickload :valtan)
(ql:quickload :trivial-ws)
(dolist (lem-script '("remote-eval" "valtan-mode" "main"))
(let ((script-path (concatenate 'string "~/.roswell/local-projects/cxxxr/valtan/lem/" lem-script)))
(load script-path))))
;; spin up a server and host the system in working directory as a valtan-compiled project
(define-command start-web-serve () ()
(labels ((split-/ (path) (split-sequence:split-sequence "/" path :test #'string-equal :remove-empty-subseqs t))
(concatenate-string (&rest seqs) (apply #'concatenate 'string seqs))
(get-system (dir) (concatenate-string dir (car (last (split-/ dir))) ".system"))
(concatenate-/ (target) (concatenate-string target "/"))
(up-dir (path) (butlast (butlast path))))
(let ((system-path (get-system (buffer-directory))))
(loop :while (and (not (cl-fad:file-exists-p (pathname system-path))) (string-not-equal system-path ".system"))
:do (let ((next-path (apply #'concatenate-string (mapcar #'concatenate-/ (up-dir (split-/ system-path))))))
(setf system-path (concatenate-string "/" (get-system next-path)))))
(valtan-host.build:build-application system-path :force nil)
(lem-valtan/remote-eval:start))))
(define-command stop-web-serve () ()
(lem-valtan/remote-eval:stop))
(define-command web-serve-repl () ()
(unwind-protect (lem-valtan/remote-eval:repl)
(lem-valtan/remote-eval:stop)))
(define-command valtan-paredit-mode () ()
(lem-valtan.valtan-mode::valtan-mode))
(define-command valtan-save-file () ()
(lem-core/commands/file:save-current-buffer)
(lem-valtan.valtan-mode::valtan-mode)))
(define-command lisp-paredit-mode () ()
(lem-lisp-mode:lisp-mode))
;; add some keybinds i'm used to for paredit and valtan, shift + alt + f to slurp forward etc.
;; valtan-mode allows a SLIME-like connection to a running web-hosted lisp project
(defun define-keys-in-maps (&rest keymap-pairs)
(loop :for (keymap . new-key-list) :in keymap-pairs
:do (loop :for (key . action) :in new-key-list
:do (define-key keymap key action))))
(let ((paredit-bindings '(("M-M" . lem-paredit-mode:paredit-mode)
("M-L" . lem-user::lisp-paredit-mode))))
(defparameter *new-global-keys*
#+valtan-installed
`(,lem:*global-keymap* . (,@paredit-bindings
("M-W" . lem-user::start-web-serve) ("M-R" . lem-user::web-serve-repl)
("M-Q" . lem-user::stop-web-serve)
("M-V" . lem-user::valtan-paredit-mode)))
#-valtan-installed
`(,lem:*global-keymap* . ,paredit-bindings)))
(defparameter *new-paredit-keys*
`(,lem-paredit-mode:*paredit-mode-keymap* . (("M-F" . lem-paredit-mode:paredit-slurp)
("M-B" . lem-paredit-mode:paredit-barf))))
#+valtan-installed
(progn
(defparameter *new-valtan-mode-keys*
`(,lem-valtan.valtan-mode::*valtan-mode-keymap* . (("C-x C-s" . lem-user::valtan-save-file))))
(define-keys-in-maps *new-global-keys* *new-valtan-mode-keys*)
)
(define-keys-in-maps *new-global-keys* *new-paredit-keys*)
(in-package :lem-core)
(defun marked-region-to-string ()
(points-to-string (cursor-region-beginning (current-point)) (cursor-region-end (current-point))))
(export 'marked-region-to-string)
(in-package :lem/grep)
(define-command project-selection-grep () ()
"Run grep at the project root directory for selection."
(let* ((current-buffer (current-buffer))
(cwd (buffer-directory))
(project-root (lem-core/commands/project:find-root cwd))
(root (or project-root cwd))
(query (prompt-for-string "" :initial-value (str:concat *grep-command* " " *grep-args* " " (lem-core:marked-region-to-string)) :history-symbol 'grep)))
(buffer-mark-cancel current-buffer)
(grep query root)))
(define-key *global-keymap* "C-x p w" 'project-selection-grep)
(in-package :lem-core/commands/project)
(defun ruby-class-to-file-path-string (target)
(str:downcase
(str:replace-using '(" " "_" "::" "/")
(cl-change-case::regex-replace-all
"([\\p{Ll}\\p{N}])(\\p{Lu})" target "\\1 \\2"))))
(in-package :lem-core/commands/file)
(defun prompt-for-files-recursively-with-default (default)
"Prompt for a file, listing all files under the buffer's directory recursively.
If listing all files times out, abort the process and fallback to the simple find-file."
(handler-bind ((fallback-to-find-file
;; Fallback to simple find-file.
(lambda (c)
(declare (ignore c))
(message "Time out! Finding files recursively under ~A was aborted." (buffer-directory))
(prompt-for-file
"Find File: "
:directory (buffer-directory)
:default default
:existing nil))))
(let ((candidates (get-files-recursively-with-timeout (find-program))))
(prompt-for-string
"File: "
:initial-value default
:completion-function (lambda (x) (completion-files x candidates))
:test-function (lambda (name) (member name candidates :test #'string=))))))
(in-package :lem-core/commands/project)
(define-command project-class-find-file (arg) (:universal)
"Open a file based on selected ruby class, from the list of all files in this project."
;; ARG is currently not used, use it when needed.
(declare (ignorable arg))
(let* ((current-buffer (current-buffer))
(cwd (buffer-directory))
(project-root (find-root cwd))
(root (or project-root cwd)))
(uiop:with-current-directory (root)
(let ((filename (lem-core/commands/file::prompt-for-files-recursively-with-default (lem-core/commands/project::ruby-class-to-file-path-string (lem-core:marked-region-to-string))))
buffer)
(when filename
(setf buffer (execute-find-file *find-file-executor*
(get-file-mode filename)
filename))
(when buffer
(buffer-mark-cancel current-buffer)
(switch-to-buffer buffer t nil)))))))
(define-key *global-keymap* "C-x p r" 'project-class-find-file)
(define-command paste-to-terminal () ()
"paste selection to terminal"
(let ((terminal-buffer (lem-terminal/terminal:find-terminal-buffer)))
(when terminal-buffer
(let ((terminal (lem-terminal/terminal-mode::buffer-terminal terminal-buffer)))
(loop :for c :across (lem-core::marked-region-to-string)
:do (lem-terminal/terminal:input-character terminal c))
(lem-terminal/terminal:input-character terminal #\Newline)))))
(define-key *global-keymap* "C-x C-t" 'paste-to-terminal)
(in-package :lem-core)
(lem-lsp-mode/lsp-mode::define-language-spec
(rb-spec lem-ruby-mode:ruby-mode)
:language-id "ruby"
:root-uri-patterns '(".rspec" ".env" "Rakefile" ".git")
:command (lambda () (progn
(lem-core/commands/project::change-directory (str:concat (uiop:getenv "HOME") "/projects/fieldwire_api")))
`(,(str:concat (uiop:getenv "HOME") "/" ".rbenv/shims/bundle") "exec" "--gemfile" ,(str:concat (uiop:getenv "HOME") "/" "projects/fieldwire_api/" ".ruby-lsp/Gemfile") "ruby-lsp"))
:install-command "rbenv exec gem install ruby-lsp"
;; :readme-url "https://github.com/Shopify/ruby-lsp"
:connection-mode :stdio)
(in-package :lem-lsp-mode/lsp-mode)
(define-command lsp-hover-goto-def () ()
(check-connection)
(when-let ((result (text-document/hover (current-point))))
(when-let ((file-def-path (str:replace-all "file://" "" (car (cl-ppcre:all-matches-as-strings "file://(.*)" (buffer-text result))))))
(let ((path-without-line (cl-ppcre:scan-to-strings "^[^#]*" file-def-path))
(line-number (parse-integer (str:replace-using '("#L" "" "," "") (car (cl-ppcre:all-matches-as-strings "#L[^,]*" file-def-path))))))
(find-file path-without-line)
(goto-line line-number)))))
(define-key *lsp-mode-keymap* "C-c g" 'lsp-hover-goto-def)
(in-package :lem-core)
(define-command go-init-file () ()
(lem-core/commands/file:find-file (str:concat (uiop:getenv "HOME") "/.lem/init.lisp")))
(define-key *global-keymap* "C-x C-Home" 'go-init-file)
(define-key *global-keymap* "C-x Home" 'go-init-file)
(define-command another-escape () ()
(error 'editor-abort :message nil))
(define-key *global-keymap* "C-Tab" 'another-escape)
(in-package lem-lsp-mode)
(loop for pair in '(("C-c C-q" lsp-document-symbol)
("C-c C-w" lsp-code-action)
("C-c C-e" lsp-signature-help)
("C-c C-d" lsp-implementation)
("C-c C-r" lsp-rename))
do (define-key *lsp-mode-keymap* (car pair) (cadr pair)))
@mantacid
Copy link

Thanks! That'd be a really big help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment