X-Git-Url: https://git.korewanetadesu.com/?p=pico8.git;a=blobdiff_plain;f=pico8.el;h=dabe69bbb6340bebf0b6074bc1bc7214f8e11d94;hp=784cea6575d43c5a91a89622e9721861ae76ab96;hb=HEAD;hpb=823c38ce61401461f03a0b10a8e38441e69befe1 diff --git a/pico8.el b/pico8.el index 784cea6..dabe69b 100644 --- a/pico8.el +++ b/pico8.el @@ -6,16 +6,16 @@ ;; URL: https://git.korewanetadesu.com/pico8.git ;; Keywords: convenience ;; -;; 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 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. ;;; Commentary: ;; -;; This mode (ab)uses polymode to fit six modes into one buffer, one -;; of which is "real Lua" text and the other five of which have -;; diverse strict formatting requirements. +;; This mode (ab)uses polymode to fit six modes into one buffer, one of +;; which is "real Lua" text and the other five of which have diverse +;; strict formatting requirements. ;; ;; It provides keybindings and commands for inter-mode actions. @@ -25,6 +25,7 @@ (require 'lua-mode) (require 'thingatpt) (require 'dash) +(require 'calc-bin) (defgroup pico8 nil @@ -46,8 +47,8 @@ PICO-8 processes are long-lived with little surprising output, so their output buffers are killed by default when they exit. -However, this is not usual behavior in Emacs, and can be -disabled by setting this to t." +However, this is not usual behavior in Emacs, and can be disabled +by setting this to t." :group 'pico8 :tag "Preserve PICO-8 Output On Exit" :type 'boolean) @@ -55,10 +56,10 @@ disabled by setting this to t." (defcustom pico8-lua-indent-level 1 "Default indentation for PICO-8 Lua mode. -This overrides ‘lua-indent-level’ in ‘pico8-lua-mode’. ‘lua-mode’ -uses a default indentation is 3, which is both idiosyncratic and -quite large when viewed in the PICO-8 editor, where the -convention is 1." +This overrides ‘lua-indent-level’ in ‘pico8-lua-mode’. +‘lua-mode’ uses a default indentation is 3, which is both +idiosyncratic and quite large when viewed in the PICO-8 editor, +where the convention is 1." :group 'pico8 :tag "PICO-8 Lua Indent Level") @@ -244,27 +245,52 @@ Make sure it is installed, and present in ‘pico8-executable-paths’"))) (defun pico8-gff-current-position () "Calculate the flag position of the cursor." - (pm-with-narrowed-to-span (pm-get-innermost-span) + (pm-with-narrowed-to-span (pm-innermost-span) (let ((row (1- (line-number-at-pos))) (col (min 255 (current-column)))) (+ (/ col 2) (* row 128))))) (defun pico8-gff-lighter () "Calculate the flag under the cursor." - (pm-with-narrowed-to-span (pm-get-innermost-span) + (pm-with-narrowed-to-span (pm-innermost-span) (let ((row (1- (line-number-at-pos))) (col (current-column))) (+ (* 128 row) (/ col 2))))) +(defun pico8-gff-eldoc () + "Show information about the flag under the point." + (save-excursion + (when (cl-oddp (current-column)) + (backward-char)) + (when (looking-at "..") + (let* ((hex (substring-no-properties (match-string 0))) + (int (string-to-number hex 16))) + (format "%08d %3d %02x" + (let ((calc-number-radix 2)) + (string-to-number (math-format-radix int))) + int int))))) + +(defconst pico8-gff-font-lock-keywords + '(("..\n?" 0 + (prog1 nil + ;; TODO: Lots of work to do here… + (let ((pdl (or (car (overlays-at (match-beginning 0))) + (make-overlay (match-beginning 0) (match-end 0))))) + (overlay-put pdl 'after-string " ")))))) + + (define-derived-mode pico8-gff-mode pico8-data-mode '(:eval (format "Flag[%d]" (pico8-gff-lighter))) - "Major mode for editing flags in PICO-8 cartridges.") + "Major mode for editing flags in PICO-8 cartridges." + (font-lock-add-keywords nil pico8-gff-font-lock-keywords) + (setq-local eldoc-documentation-function #'pico8-gff-eldoc)) (defun pico8-gff-offset-of-flag (flag) "Calculate the offset of of flag number FLAG." (unless (<= 0 flag 255) (error "Valid flag numbers are 0 to 255, inclusive")) (+ (* 2 flag) (if (> flag 128) 1 0))) + (defface pico8-pixel '((t (:inherit pico8-data :height 100))) @@ -279,14 +305,14 @@ Make sure it is installed, and present in ‘pico8-executable-paths’"))) (-map-indexed (lambda (i c) `(,(format "%x+" i) - 0 '(:inherit pico8-pixel :foreground ,c))) + 0 '(face (:inherit pico8-pixel :foreground ,c)))) pico8-colors))) (defun pico8-gfx-current-position () "Calculate the sprite and in-sprite position of the cursor." ;; FIXME: Ensure the span we got was actually the gfx one. - (pm-with-narrowed-to-span (pm-get-innermost-span) + (pm-with-narrowed-to-span (pm-innermost-span) (let ((row (1- (line-number-at-pos))) (col (min 127 (current-column)))) (list (+ (* 16 (/ row 8)) (/ col 8)) @@ -301,7 +327,7 @@ Make sure it is installed, and present in ‘pico8-executable-paths’"))) (% (+ 256 n (nth 0 current)) 256) (nth 1 current) (nth 2 current)))) - (pm-with-narrowed-to-span (pm-get-innermost-span) + (pm-with-narrowed-to-span (pm-innermost-span) (goto-char (+ (point-min) offset))))) (defun pico8-backward-sprite (n) @@ -350,7 +376,7 @@ Make sure it is installed, and present in ‘pico8-executable-paths’"))) (defun pico8-map-lighter () "Calculate the map tile under the cursor." - (pm-with-narrowed-to-span (pm-get-innermost-span) + (pm-with-narrowed-to-span (pm-innermost-span) (let ((row (- (line-number-at-pos) 1)) (col (current-column))) ;; TODO: Show sprite number and flags value @@ -363,7 +389,7 @@ Make sure it is installed, and present in ‘pico8-executable-paths’"))) (defun pico8-sfx-lighter () "Calculate the sound effect under the cursor." - (pm-with-narrowed-to-span (pm-get-innermost-span) + (pm-with-narrowed-to-span (pm-innermost-span) (let ((row (- (line-number-at-pos) 1))) (format "%d" row)))) @@ -373,7 +399,7 @@ Make sure it is installed, and present in ‘pico8-executable-paths’"))) (defun pico8-music-lighter () "Calculate the map tile under the cursor." - (pm-with-narrowed-to-span (pm-get-innermost-span) + (pm-with-narrowed-to-span (pm-innermost-span) (let ((row (- (line-number-at-pos) 1))) (format "%d" row)))) @@ -411,8 +437,8 @@ Returns nil, not 0, if the string was not converted." "Get the sprite number relevant to the point. When editing a flag, this is the flag number. When editing a -map, this is the value at the map. When editing Lua code, -this is the numeric literal in the code." +map, this is the value at the map. When editing Lua code, this +is the numeric literal in the code." (cond ((derived-mode-p 'pico8-gff-mode) (pico8-gff-current-position)) @@ -434,8 +460,8 @@ this is the numeric literal in the code." "Go to the sprite number relevant to the text at the point. When editing a flag, this is the flag number. When editing a -map, this is the value at the map. When editing Lua code, -this is the numeric literal in the code." +map, this is the value at the map. When editing Lua code, this +is the numeric literal in the code." (interactive) (let ((sprite (pico8-sprite-relevant-to-point))) (if sprite (pico8-goto-sprite sprite) @@ -549,27 +575,28 @@ See URL ‘https://github.com/mpeterv/luacheck’." (defmacro pico8--defchunkmode (name) "Define a PICO-8 polymode chunk for section NAME." `(defconst ,(intern (concat "pico8--pm-inner-" name)) - (pm-hbtchunkmode :mode ',(intern (format "pico8-%s-mode" name)) - :head-mode 'host - :head-reg ,(format "^__%s__\n" name) - :tail-reg "^__[a-z]\\{3,5\\}__\n\\|^\n\\'"))) - -(defconst pico8--pm-poly - (pm-polymode-multi - :hostmode - (defconst pico8--pm-host - (pm-bchunkmode :mode 'pico8-cartridge-mode)) + (pm-inner-chunkmode + :name ,name + :mode ',(intern (format "pico8-%s-mode" name)) + :head-mode 'host + :head-matcher ,(format "^__%s__\n" name) + :tail-matcher "^__[a-z]\\{3,5\\}__\n\\|^\n\\'"))) + + +(defconst pico8--pm-host + (pm-host-chunkmode :name "PICO-8" :mode 'pico8-cartridge-mode)) + +(define-polymode pico8-mode + :hostmode 'pico8--pm-host :innermodes (list (pico8--defchunkmode "lua") (pico8--defchunkmode "gfx") (pico8--defchunkmode "gff") (pico8--defchunkmode "map") (pico8--defchunkmode "sfx") - (pico8--defchunkmode "music")))) - -(define-polymode pico8-mode pico8--pm-poly - :lighter "P8" - :keymap '(("\C-c\C-r" . pico8-run-cartridge) + (pico8--defchunkmode "music")) + :lighter "P8" + :keymap '(("\C-c\C-r" . pico8-run-cartridge) ("\C-c\C-e" . pico8-load-cartridge) ("\M-gs" . pico8-goto-sprite) ("\M-gS" . pico8-goto-sprite-relevant-to-point) @@ -583,3 +610,7 @@ See URL ‘https://github.com/mpeterv/luacheck’." (provide 'pico8) ;;; pico8.el ends here + +;; Local Variables: +;; sentence-end-double-space: t +;; End: