Random changes

This commit is contained in:
John Doty 2021-08-16 16:32:31 -07:00
parent f1a4519507
commit 90772c2c0b
6 changed files with 650 additions and 33 deletions

View file

@ -1,14 +1,14 @@
if status --is-login
set PATH /opt/local/bin /opt/local/sbin $PATH ~/bin
if test -d ~/.cargo/bin
set PATH ~/.cargo/bin $PATH
end
if test -d ~/devtools/buck/bin
set PATH $PATH ~/devtools/buck/bin
end
if test -d /snap/bin
set PATH $PATH /snap/bin
end
if test -d ~/.cargo/bin
set PATH $PATH ~/.cargo/bin
end
if test -d ~/.local/bin
set PATH $PATH ~/.local/bin
end

View file

@ -6,7 +6,7 @@
#: individual font faces and even specify special fonts for particular
#: characters.
# font_family monospace
font_family Input Mono Narrow
# bold_font auto
# italic_font auto
# bold_italic_font auto
@ -23,7 +23,7 @@
#: italic_font Operator Mono Book Italic
#: bold_italic_font Operator Mono Medium Italic
# font_size 11.0
font_size 14.0
#: Font size (in pts)
@ -88,7 +88,7 @@
#: The cursor shape can be one of (block, beam, underline)
# cursor_blink_interval -1
cursor_blink_interval 0
#: The interval (in seconds) at which to blink the cursor. Set to zero
#: to disable blinking. Negative values mean use system default. Note
@ -574,7 +574,7 @@
#: content of windows, etc. Note that this even works over ssh
#: connections.
# env
# env
#: Specify environment variables to set in all child processes. Note
#: that environment variables are expanded recursively, so if you
@ -643,7 +643,7 @@
#: you are probably better off just hiding the titlebar with
#: hide_window_decorations.
# macos_option_as_alt no
macos_option_as_alt both
#: Use the option key as an alt key. With this set to no, kitty will
#: use the macOS native Option+Key = unicode character behavior. This

View file

@ -22,7 +22,7 @@
'(company-minimum-prefix-length 1)
'(css-indent-offset 2)
'(custom-safe-themes
'("3dbb18bf06f41012d4525e6c64c392d6cfef06a2f8fe1bf7b565c4e020255466" "8db4b03b9ae654d4a57804286eb3e332725c84d7cdab38463cb6b97d5762ad26" default))
'("7b3ce93a17ce4fc6389bba8ecb9fee9a1e4e01027a5f3532cc47d160fe303d5a" "3dbb18bf06f41012d4525e6c64c392d6cfef06a2f8fe1bf7b565c4e020255466" "8db4b03b9ae654d4a57804286eb3e332725c84d7cdab38463cb6b97d5762ad26" default))
'(fast-lock-cache-directories '("~/flc-cache"))
'(fast-lock-minimum-size nil)
'(fill-column 77)
@ -58,7 +58,7 @@
'(org-odd-levels-only t)
'(org-todo-keywords '((sequence "TODO" "|" "DONE" "ABANDONED" "DEFERRED")))
'(package-selected-packages
'(eglot prettier-js zig-mode modus-operandi-theme esup gnu-elpa-keyring-update lsp-hack hack-mode rust-mode filladapt lsp-ui yaml-mode wgrep fsharp-mode company-lsp cquery mustache-mode clang-format projectile dash-functional mocha add-node-modules-path rjsx-mode xref-js2 js2-refactor company omnisharp geiser cider clojure-mode graphviz-dot-mode multi-term xterm-color thrift markdown-mode tuareg merlin ag use-package flycheck dockerfile-mode js2-mode web-mode tss switch-window python-mode paredit magit lua-mode go-mode go-autocomplete exec-path-from-shell csharp-mode color-theme-monokai auto-complete auto-complete-nxml flymake flyspell json-mode popup ruby-mode company-jedi tide elm-mode monky))
'(flycheck-rust eglot prettier-js zig-mode modus-operandi-theme esup gnu-elpa-keyring-update lsp-hack hack-mode rust-mode filladapt lsp-ui yaml-mode wgrep fsharp-mode company-lsp cquery mustache-mode clang-format projectile dash-functional mocha add-node-modules-path rjsx-mode xref-js2 js2-refactor company omnisharp geiser cider clojure-mode graphviz-dot-mode multi-term xterm-color thrift markdown-mode tuareg merlin ag use-package flycheck dockerfile-mode js2-mode web-mode tss switch-window python-mode paredit magit lua-mode go-mode go-autocomplete exec-path-from-shell csharp-mode color-theme-monokai auto-complete auto-complete-nxml flymake flyspell json-mode popup ruby-mode company-jedi tide elm-mode monky))
'(reb-re-syntax 'string)
'(rmail-mail-new-frame t)
'(safe-local-variable-values

View file

@ -179,18 +179,19 @@
(setq my-font-choice
(font-candidate
"Input Mono Narrow-12:weight=light"
"InputMonoNarrow Light-12:light"
"Input Mono Narrow:pixelsize=14:weight=normal"
"Consolas-10"
"Inconsolata-11"
"Monaco-14"))
;; This is just here for playing with things.
(set-frame-font my-font-choice)
;;
;; To obtain new font string, execute eval-expression, and eval this:
;;(insert(prin1-to-string(w32-select-font)))
;; (insert(prin1-to-string(w32-select-font)))
;; This will show the required string in the scratch buffer.
(setq jd-frame-height
@ -319,11 +320,18 @@
;; :config (add-hook 'lsp-mode-hook 'lsp-ui-mode)))
(use-package eglot :ensure
:commands eglot-ensure
:hook (python-mode . eglot-ensure)
:hook
(python-mode . eglot-ensure)
(rust-mode . eglot-ensure)
:config
(add-to-list 'eglot-server-programs '(python-mode . ("pyls-language-server")))
)
:init
(flycheck-mode -1))
;; NOTE: elgot defers to flymake for error information.
(use-package flymake
:bind (("C-c n" . 'flymake-goto-next-error)
("C-c p" . 'flymake-goto-prev-error)))
;; =================================================================
@ -356,8 +364,6 @@
(turn-on-auto-fill)
(flyspell-prog-mode)
(define-key c-mode-base-map "\C-m" 'c-context-line-break)
(unless is-fb-environment
(set-fill-column 120))
;; (local-set-key "}" 'indent-on-closing-bracket)
)
@ -918,6 +924,9 @@
:config
(setq rust-format-on-save t))
(use-package flycheck-rust :ensure t
:hook (rust-mode . flycheck-rust-setup))
;; =================================================================
;; Clojure
;; =================================================================
@ -960,4 +969,10 @@
:major-modes '(zig-mode)
:server-id 'zls)))
;; ================================================================
;; Pico-8
;; ================================================================
(use-package pico8-mode
:mode (("\\.p8\\'" . pico8-mode)))
;;; init.el ends here

613
site-lisp/pico8-mode.el Normal file
View file

@ -0,0 +1,613 @@
;;; pico8-mode.el --- a major-mode for editing Pico8 p8 files -*- lexical-binding: t -*-
;; Author: Väinö Järvelä <vaino@jarve.la>
;; URL: https://github.com/kaali/pico8-mode
;; Version: 20180215
;; Package-Requires: ((lua-mode "20180104"))
;;
;; This file is NOT part of Emacs.
;;
;; 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 2
;; 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, write to the Free Software
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
;; MA 02110-1301, USA.
(require 'seq)
(require 'lua-mode)
(require 'rx)
(require 'cl-lib)
(require 'xref)
(require 'subr-x)
;; TODO: Clean up and refactor
;; TODO: Highlight current argument with eldoc
;; TODO: Optimize?
;; The code is currently really really inefficient, it goes through the
;; file multiple times when doing navigation or completion. It also goes
;; through the file to find images to render, and the image scaler is
;; quite crude. But nothing really shows up in the profiler, and .p8
;; files are so small that it doesn't show up in use at all.
;; Fix Emacs 25 support by defining when-let*
(eval-when-compile
(unless (fboundp 'when-let*)
(defalias 'when-let* 'when-let)))
(defgroup pico8 nil
"pico8 major mode"
:prefix "pico8-"
:group 'languages)
;; TODO: Maybe rebuild documentation when setting this custom-var?
(defcustom pico8-documentation-file ""
"Full path to pico8 manual.
Enables documentation annotations with eldoc and company"
:type 'file
:group 'pico8)
(defcustom pico8-dim-non-code-sections t
"If enabled, then dim all sections that are not Lua code"
:type 'boolean
:group 'pico8)
(defcustom pico8-create-images t
"If enabled, then image data is rendered inline."
:type 'boolean
:group 'pico8)
(defface pico8--non-lua-overlay
'((((background light)) :foreground "grey90")
(((background dark)) :foreground "grey10"))
"Face for non-Lua sections of the p8 file"
:group 'pico8)
(defvar pico8--lua-block-start nil "")
(make-variable-buffer-local 'pico8--lua-block-start)
(defvar pico8--lua-block-end nil "")
(make-variable-buffer-local 'pico8--lua-block-end)
(defvar pico8--lua-block-end-tag nil "")
(make-variable-buffer-local 'pico8--lua-block-end-tag)
(cl-defstruct (pico8-symbol (:constructor pico8-symbol--create))
"A Lua symbol on pico8 mode."
symbol line column signature location doc doc-position arguments)
(defun pico8--make-builtin (symbol signature &optional doc)
"Constructs a built-in plist with symbol, signature and documentation."
(pico8-symbol--create
:symbol symbol
:signature (concat "function " symbol "(" signature ")")
:arguments signature
:doc doc))
(defconst pico8--builtins-list
'(("clip" "[x y w h]")
("pget" "x y")
("pset" "x y c")
("sget" "x y")
("sset" "x y c")
("fget" "n [f]")
("fset" "n [f] v")
("print" "str [x y [col]]")
("cursor" "x y")
("color" "col")
("cls" "[col]")
("camera" "[x y]")
("circ" "x y r [col]")
("circfill" "x y r [col]")
("line" "x0 y0 x1 y1 [col]")
("rect" "x0 y0 x1 y1 [col]")
("rectfill" "x0 y0 x1 y1 [col]")
("pal" "c0 c1 [p]")
("palt" "c t")
("spr" "n x y [w h] [flip_x] [flip_y]")
("sspr" "sx sy sw sh dx dy [dw dh] [flip_x] [flip_y]")
("fillp" "p")
("add" "t v")
("del" "t v")
("all" "t")
("foreach" "t f")
("pairs" "t")
("btn" "[i [p]]")
("btnp" "[i [p]]")
("sfx" "n [channel [offset [length]]]")
("music" "[n [fade_len [channel_mask]]]")
("mget" "x y")
("mset" "x y v")
("map" "cel_x cel_y sx sy cel_w cel_h [layer]")
("peek" "addr")
("poke" "addr val")
("peek4" "addr")
("poke4" "addr val")
("memcpy" "dest_addr source_addr len")
("reload" "dest_addr source_addr len [filename]")
("cstore" "dest_addr source_addr len [filename]")
("memset" "dest_addr val len")
("max" "x y" "Returns maximum value of x and y")
("min" "x y" "Returns minimum value of x and y")
("mid" "x y z" "Returns middle value of x, y and z")
("flr" "x" "Floor x")
("ceil" "x" "Ceil x")
("cos" "x" "Cosine of x")
("sin" "x" "Sine of x")
("atan2" "dx dy")
("sqrt" "x")
("abs" "x")
("rnd" "x")
("srand" "x")
("band" "x y" "Boolean and")
("bor" "x y" "Boolean or")
("bxor" "x y" "Boolean xor")
("bnot" "x" "Boolean not")
("rotl" "x y" "Rotate right")
("rotr" "x y" "Ritate left")
("shl" "x n" "Shift left")
("shr" "x n" "Shift right")
("lshr" "x n" "Logical shift right")
("menuitem" "Index [label callback]")
("sub" "s a b")
("type" "val")
("tostr" "val [hex]")
("tonum" "val")
("cartdata" "id")
("dget" "index")
("dset" "index value")
("setmetatable" "t, m" "Get metatable")
("getmetatable" "t" "Set metatable")
("cocreate" "f")
("coresume" "c [p0 p1 ..]")
("costatus" "c")
("yield" "" "Yield coroutine execution")))
(defconst pico8--palette
(concat "\"0 c #000000\",\n"
"\"1 c #1d2b53\",\n"
"\"2 c #7e2553\",\n"
"\"3 c #008751\",\n"
"\"4 c #ab5236\",\n"
"\"5 c #5f574f\",\n"
"\"6 c #c2c3c7\",\n"
"\"7 c #fff1e8\",\n"
"\"8 c #ff004d\",\n"
"\"9 c #ffa300\",\n"
"\"a c #ffec27\",\n"
"\"b c #00e436\",\n"
"\"c c #29adff\",\n"
"\"d c #83769c\",\n"
"\"e c #ff77a8\",\n"
"\"f c #ffccaa\",\n"))
(defconst pico8--builtins
(seq-map (lambda (x) (apply #'pico8--make-builtin x)) pico8--builtins-list))
(defconst pico8--builtins-symbols
(seq-map (lambda (s) (plist-get s :symbol)) pico8--builtins))
;; based on lua-mode.el
(defconst pico8--builtins-regex
(concat
"\\(?:^\\|[^:. \t]\\|[.][.]\\)[ \t]*\\(?:"
(mapconcat (lambda (x)
(concat "\\(?1:\\_<" x "\\_>\\)"))
pico8--builtins-symbols "\\|")
"\\)"))
(defun pico8--has-documentation-p ()
"Is pico8-documentation-file set and does the file exits?"
(and (> (length pico8-documentation-file) 0)
(file-exists-p pico8-documentation-file)))
(defun pico8--find-documentation (symbol arguments)
"Find a part of documentation for `symbol' with `arguments'.
Does a dumb lookup which can break if the file format changes.
Returns string and location in the documentation file."
(if (pico8--has-documentation-p)
(with-temp-buffer
(insert-file-contents pico8-documentation-file)
(save-excursion
(goto-char 1)
(when (search-forward-regexp (concat "\t" (regexp-quote symbol) " +" (regexp-quote arguments)) nil t)
(let ((fun-start (point)))
(when (search-forward-regexp "\t\t[A-Za-z]" nil t)
(let ((start (1- (point)))
(end (line-end-position)))
(cons (buffer-substring-no-properties start end) fun-start)))))))
(error "Define pico8-documentation-file to use documentation features")))
;;;###autoload
(defun pico8-build-documentation ()
"Rebuild pico8 function documentation.
Requires `pico8-documentation-file' to be set."
(interactive)
(seq-do (lambda (s)
(if (pico8-symbol-doc s)
s
(let* ((symbol (pico8-symbol-symbol s))
(arguments (pico8-symbol-arguments s))
(doc (pico8--find-documentation symbol arguments)))
(setf (pico8-symbol-doc s) (car doc))
(setf (pico8-symbol-doc-position s) (cdr doc)))))
pico8--builtins)
nil)
(defun pico8--modified-lua-font-lock ()
"Return a modified lua-font-lock.
Where lua built-ins are removed and replaced with pico8 builtins."
(let ((without-builtins
(seq-filter
(lambda (x) (not (string-match ".*loadstring.*" (car x))))
lua-font-lock-keywords)))
(append `((,pico8--builtins-regex . font-lock-builtin-face))
without-builtins)))
;; Adapted from lua-mode.el (lua-send-defun)
(defun pico8--lua-function-bounds ()
"Return Lua function bounds, or nil if not in a function."
(save-excursion
(let ((pos (point))
(start (if (save-match-data (looking-at "^function[ \t]"))
(point)
(lua-beginning-of-proc)
(point)))
(end (progn (lua-end-of-proc) (point))))
(if (and (>= pos start) (< pos end))
(cons start end)
nil))))
(defun pico8--match-column (SUBEXPR)
"Return a position of column at start of text matched by last search."
(- (match-beginning SUBEXPR) (line-beginning-position)))
;; this is copied from lua-mode.el to match its functionality
(defconst pico8--lua-function-regex
(lua-rx (or bol ";") ws (opt (seq (symbol "local") ws)) lua-funcheader))
(defconst pico8--lua-variable-regex
(lua-rx (or bol ";") ws (opt (seq (group-n 1 (symbol "local")) ws)) (group-n 2 lua-funcname) ws "="))
(defvar pico8--lua-argument-regex
(lua-rx (seq (group-n 1 lua-name))))
(defun pico8--find-all-functions ()
"Find and return all lua functions from the current buffer."
(let ((symbols))
(save-excursion
(save-restriction
(widen)
(goto-char (or pico8--lua-block-start 1))
(while (search-forward-regexp pico8--lua-function-regex
pico8--lua-block-end t 1)
(let ((symbol (pico8-symbol--create
:symbol (match-string-no-properties 1)
:line (line-number-at-pos)
:column (pico8--match-column 1)
:signature (thing-at-point 'line t)
:location (match-beginning 1))))
;; Augment with arguments
(save-excursion
(goto-char (match-beginning 0))
(when (search-forward "(" (line-end-position) t 1)
(let ((arguments '()))
(while (search-forward-regexp pico8--lua-argument-regex
(line-end-position) t 1)
(push (match-string-no-properties 1) arguments))
(setf (pico8-symbol-arguments symbol) (string-join (reverse arguments) " ")))))
(push symbol symbols)))))
symbols))
(defun pico8--find-variables ()
"Find and return lua variables.
Do some scoping with local variables."
(let ((variables))
(save-excursion
(save-restriction
(widen)
(let ((fn-bounds (pico8--lua-function-bounds)))
(goto-char (or pico8--lua-block-start 1))
(while (search-forward-regexp pico8--lua-variable-regex
pico8--lua-block-end t 1)
(let ((is-local (match-string-no-properties 1))
(variable (match-string-no-properties 2))
(line-num (line-number-at-pos)))
(when (or (not is-local)
(not fn-bounds)
(<= (car fn-bounds) (point) (cdr fn-bounds)))
(push (pico8-symbol--create
:symbol variable
:line (line-number-at-pos)
:column (pico8--match-column 2)
:location (match-beginning 2))
variables)))))))
variables))
;; TODO: Reduce code duplication in this pattern
(defun pico8--find-current-function-arguments ()
"Find and return lua arguments of the current function."
(let ((arguments))
(save-excursion
(save-restriction
(widen)
(when-let* ((fn-bounds (pico8--lua-function-bounds)))
(goto-char (car fn-bounds))
(when (search-forward "(" (cdr fn-bounds) t 1)
(while (search-forward-regexp pico8--lua-argument-regex
(line-end-position) t 1)
(push (pico8-symbol--create
:symbol (match-string-no-properties 1)
:line (line-number-at-pos)
:column (pico8--match-column 1)
:location (match-beginning 1))
arguments))))))
arguments))
(defun pico8--filter-symbol (symbol &optional symbols)
"Find all symbols named symbol."
(seq-filter (lambda (s) (string= symbol (pico8-symbol-symbol s)))
(or symbols (pico8--completion-symbols-without-builtins))))
(defun pico8--find-symbol (symbol &optional symbols)
"Find a single symbol named symbol.
Returns the first match in case of multiple matches."
(seq-find (lambda (s) (string= symbol (pico8-symbol-symbol s)))
(or symbols (pico8--find-all-functions))))
(defun pico8--make-xref-of-symbol (symbol)
"Make a xref of a symbol."
(xref-make (pico8-symbol-symbol symbol)
(xref-make-file-location buffer-file-name
(pico8-symbol-line symbol)
(pico8-symbol-column symbol))))
(cl-defmethod xref-backend-identifier-at-point
((_backend (eql xref-pico8)))
"pico8 xref identifier-at-point."
(lua-funcname-at-point))
(cl-defmethod xref-backend-definitions
((_backend (eql xref-pico8)) symbol)
"pico8 xref definitions."
(seq-map #'pico8--make-xref-of-symbol
(pico8--filter-symbol symbol)))
(cl-defmethod xref-backend-apropos
((_backend (eql xref-pico8)) symbol)
"pico8 xref apropos."
(seq-map #'pico8--make-xref-of-symbol
(pico8--filter-symbol symbol)))
(cl-defmethod xref-backend-identifier-completion-table
((_backend (eql xref-pico8)))
"pico8 xref identifier completion table."
(pico8--completion-symbols-without-builtins))
(defun xref-pico8-backend ()
"Return pico8 xref backend name."
'xref-pico8)
(defun pico8--completion-symbols ()
"Return a list of all completion symbols.
Including Lua and pico8 built-ins."
(append pico8--builtins
(pico8--find-all-functions)
(pico8--find-variables)
(pico8--find-current-function-arguments)))
(defun pico8--completion-symbols-without-builtins ()
"Return a list of all completion symbols.
Including Lua and pico8 built-ins."
(append (pico8--find-all-functions)
(pico8--find-variables)
(pico8--find-current-function-arguments)))
;; based on lua-funcname-at-point code from lua-mode.el
(defun pico8--lua-funcname-bounds-at-point ()
(with-syntax-table (copy-syntax-table)
(modify-syntax-entry ?. "_")
(bounds-of-thing-at-point 'symbol)))
(defun pico8--company-doc-buffer (symbol)
(cons
(with-current-buffer (get-buffer-create "*company-documentation*")
(erase-buffer)
(insert-file-contents pico8-documentation-file)
(current-buffer))
(pico8-symbol-doc-position symbol)))
(defun pico8--company-location (symbol)
(cons (current-buffer)
(pico8-symbol-location symbol)))
(defun pico8--completion-at-point-exit-function (arg status symbol)
(when (boundp 'company-mode)
(when-let* ((arguments (pico8-symbol-arguments symbol)))
(let* ((split-args (split-string arguments))
(args-template (concat "(" (string-join split-args ", ") ")")))
(insert args-template)
(company-template-c-like-templatify
(concat arg args-template))))))
(defun pico8--completion-at-point ()
(when-let* ((bounds (pico8--lua-funcname-bounds-at-point))
(symbols (pico8--completion-symbols))
(symbol-names (seq-map 'pico8-symbol-symbol symbols)))
(fset 'symbol (lambda (arg) (pico8--find-symbol arg symbols)))
(list (car bounds)
(cdr bounds)
symbol-names
:exclude 'no
:company-docsig (lambda (arg) (pico8-symbol-signature (symbol arg)))
:annotation-function (lambda (arg) (pico8-symbol-doc (symbol arg)))
:company-doc-buffer (lambda (arg)
(pico8--company-doc-buffer (pico8--find-symbol arg symbols)))
:company-location (lambda (arg)
(pico8--company-location (pico8--find-symbol arg symbols)))
:exit-function (lambda (arg status)
(pico8--completion-at-point-exit-function
arg status (pico8--find-symbol arg symbols))))))
(defun pico8--eldoc-documentation ()
"eldoc documentation function for pico8"
(save-excursion
(condition-case nil
(backward-up-list nil t)
(error nil))
(when-let* ((symbol (pico8--find-symbol (lua-funcname-at-point)
(pico8--completion-symbols)))
(signature (pico8-symbol-signature symbol)))
(concat signature
(when-let* ((doc (pico8-symbol-doc symbol)))
(concat ": " doc))))))
(defun pico8--put-non-lua-overlay (beg end)
"Put pico8 non-Lua overlay in region."
(overlay-put (make-overlay beg end) 'face 'pico8--non-lua-overlay))
(defun pico8--do-scan-for-lua-block-in-region (beg end)
"Actually run the scan for pico8--scan-for-lua-block-in-region"
(save-excursion
(goto-char beg)
(while (search-forward-regexp "^__\\([a-z]+\\)__$" end t 1)
(if (string= "lua" (match-string 1))
(setq pico8--lua-block-start (match-end 0))
(when (and (> (match-beginning 0) (or pico8--lua-block-start 1))
(or (not pico8--lua-block-end)
(string= (match-string-no-properties 1) pico8--lua-block-end-tag)
(< (match-beginning 0) pico8--lua-block-end)))
(setq pico8--lua-block-end-tag (match-string-no-properties 1))
(setq pico8--lua-block-end (match-beginning 0)))))))
(defun pico8--scan-for-lua-block-in-region (beg end)
"Try to find lua block in the region.
If a __lua__ line is found, then that is set as the start for a
lua block. If other __def__ lines are found, they might be chosen
as an end position for the lua block."
(when (and pico8--lua-block-start (<= beg pico8--lua-block-start end))
(setq pico8--lua-block-start nil))
(when (and pico8--lua-block-end (<= beg pico8--lua-block-end end))
(setq pico8--lua-block-end nil))
(pico8--do-scan-for-lua-block-in-region beg end)
(unless (and pico8--lua-block-start pico8--lua-block-end)
(pico8--do-scan-for-lua-block-in-region (point-min) (point-max))))
(defun pico8--line-length (point)
"Get line length at `point'"
(save-excursion
(goto-char point)
(- (line-end-position) (line-beginning-position))))
(defun pico8--get-scaled-image-data (start end)
"Get scaled pico8 image data in in the region between `start' and `end'.
Doubles the image data, otherwise it's too tiny to look at."
(string-join
(seq-map
(lambda (x)
(let ((line (concat "\"" (replace-regexp-in-string "\\([0-9a-f]\\)" "\\1\\1" x) "\"")))
(concat line ",\n" line)))
(split-string (buffer-substring-no-properties start end) "\n" t))
",\n"))
(defun pico8--generate-image (start end)
"Generate an image from pico8 data in the region between `start' and `end'."
(let ((height (number-to-string (* 2 (count-lines start end))))
(width (number-to-string (* 2 (pico8--line-length start)))))
(create-image
(concat "/* XPM */\nstatic char *xpm[] ={\n"
"\"" width " " height " 16 1\",\n"
pico8--palette
(pico8--get-scaled-image-data start end))
'xpm t)))
(defvar pico8--gfx-overlays nil '())
(make-variable-buffer-local 'pico8--gfx-overlays)
(defun pico8--put-gfx-overlay (beg end)
"Put pico8 gfx overlay in region."
(interactive "r")
(setq-local pico8--gfx-overlays
(seq-filter
(lambda (overlay)
(if (and (= beg (overlay-start overlay))
(= end (overlay-end overlay)))
(delete-overlay overlay)
t))
pico8--gfx-overlays))
(let ((overlay (make-overlay beg end)))
(overlay-put overlay 'display (pico8--generate-image beg end))
(push overlay pico8--gfx-overlays))
nil)
(defun pico8--create-image-overlays ()
"Create XPM image overlays over pico8 image data"
(save-excursion
(save-restriction
(widen)
(goto-char 1)
(while (search-forward-regexp "__\\([a-z]+\\)" nil t 1)
(forward-line 1)
(let ((start (point)))
(when (or (string= "gfx" (match-string-no-properties 1))
(string= "label" (match-string-no-properties 1)))
(save-excursion
(if (search-forward-regexp "__[a-z]+__" nil t 1)
(progn
(forward-line -1)
(end-of-line))
(forward-paragraph))
(pico8--put-gfx-overlay start (point)))))))))
(defun pico8--remove-image-overlays ()
"Remove all XPM image overlays"
(seq-do (lambda (overlay) (delete-overlay overlay)) pico8--gfx-overlays)
(setq-local pico8--gfx-overlays '()))
(defun pico8--syntax-propertize (beg end)
"pico8 syntax-table propertize function.
Sets an overlay on non-Lua code. And also keeps track of lua code
region."
(lua--propertize-multiline-bounds beg end)
(pico8--scan-for-lua-block-in-region beg end)
;; TODO: Revamp
(when pico8-dim-non-code-sections
(remove-overlays (point-min) (point-max) 'face 'pico8--non-lua-overlay)
(when pico8--lua-block-start
(pico8--put-non-lua-overlay (point-min) pico8--lua-block-start))
(when pico8--lua-block-end
(pico8--put-non-lua-overlay pico8--lua-block-end (point-max)))
))
;;;###autoload
(define-derived-mode pico8-mode lua-mode "pico8"
"pico8 major mode."
(setq-local lua-font-lock-keywords (pico8--modified-lua-font-lock))
(add-to-list 'xref-backend-functions #'xref-pico8-backend)
(add-to-list 'completion-at-point-functions #'pico8--completion-at-point)
(setq-local eldoc-documentation-function #'pico8--eldoc-documentation)
(setq-local syntax-propertize-function #'pico8--syntax-propertize)
(when (pico8--has-documentation-p)
(pico8-build-documentation))
(when (and pico8-create-images
(display-graphic-p)
(image-type-available-p 'xpm))
(add-hook 'before-revert-hook 'pico8--remove-image-overlays)
(add-hook 'after-revert-hook 'pico8--create-image-overlays)
(pico8--create-image-overlays)))
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.p8\\'" . pico8-mode))
(provide 'pico8-mode)
;;; pico8-mode.el ends here

View file

@ -57,24 +57,13 @@
"fb.ms-remote-connections.hosts": [
{
"hostname": "our.doty.sb.facebook.com",
"folders": [
"/data/users/doty/configerator/",
"/data/users/doty/configerator-dsi/",
"/data/users/doty/configerator-hg/",
"/data/users/doty/configerator-puma/",
"/data/users/doty/databee/",
"/data/users/doty/dataswarm-git/",
"/data/users/doty/dataswarm-hg/",
"/data/users/doty/fbsource/",
"/data/users/doty/jepsen/",
"/data/users/doty/mysql-schemas/",
"/data/users/doty/opsfiles-hg/",
"/data/users/doty/www-hg/",
"/data/users/doty/www/"
]
"folders": []
}
],
"terminal.integrated.shell.linux": "/usr/bin/fish",
"workbench.colorTheme": "Monokai",
"editor.suggestSelection": "first"
"editor.suggestSelection": "first",
"files.associations": {
"*.gadget": "thrift"
}
}