diff --git a/editor/imstate.fnl b/editor/imstate.fnl index 88df89d..df74d1d 100644 --- a/editor/imstate.fnl +++ b/editor/imstate.fnl @@ -1,4 +1,5 @@ (local core (require :core)) +(local config (require :core.config)) (local command (require :core.command)) (local keymap (require :core.keymap)) (local style (require :core.style)) @@ -44,7 +45,8 @@ (command.add #(not= (-?> core.active_view.imstate (. :focus)) nil) commands) (keymap.add keymaps)) -(register-keys [:backspace :delete :left :right :shift+left :shift+right :home :end :shift+home :shift+end]) +(register-keys [:backspace :delete :left :right :shift+left :shift+right :home :end :shift+home :shift+end + :ctrl+left :ctrl+right :ctrl+shift+left :ctrl+shift+right :ctrl+c :ctrl+v]) (fn cmd-predicate [p] (var p-fn p) @@ -103,19 +105,36 @@ (if (or (<= x xMid) (= s "")) i (i-from-x (s:sub 2) x (+ xLeft w) font (+ i 1)))) +(fn next-match [text i di pred] + (local imax (+ (length text) 1)) + (local inext (+ i di)) + (if (<= inext 1) 1 + (> inext imax) imax + (pred (text:sub inext inext)) (if (< di 0) i inext) + (next-match text inext di pred))) +(fn is-nonword-char [char] (config.non_word_chars:find char nil true)) +(fn next-word [text i di] + (let [iwordboundary (next-match text i di #(is-nonword-char $1))] + (next-match text iwordboundary di #(not (is-nonword-char $1))))) + (fn textnav [key i text] (local imax (+ (length text) 1)) (match key - :left (math.max 1 (- i 1)) - :right (math.min imax (+ i 1)) - :home 1 - :end imax)) + :left (math.max 1 (- i 1)) + :right (math.min imax (+ i 1)) + :ctrl+left (next-word text i -1) + :ctrl+right (next-word text i 1) + :home 1 + :end imax)) (fn selection-span [view] (let [f view.imstate.focus iStart (math.min f.i f.iAnchor) iLim (math.max f.i f.iAnchor)] (values iStart iLim))) +(fn selection-text [view text] + (local (iStart iLim) (selection-span view)) + (text:sub iStart (- iLim 1))) (fn replace-selection [view s replacement ?iStart ?iLim] (local (iStart iLim) (if ?iLim (values ?iStart ?iLim) (selection-span view))) @@ -139,20 +158,19 @@ (set textNew (replace-selection view textNew view.imstate.text))) (each [_ key (ipairs (or view.imstate.keys []))] (set view.imstate.focus.blink (love.timer.getTime)) - (if (= (key:sub 1 6) "shift+") - (set f.i (or (textnav (key:sub 7) f.i textNew) f.i)) + (if (= key :ctrl+c) (system.set_clipboard (selection-text view textNew)) + (= key :ctrl+v) (set textNew (replace-selection view textNew (system.get_clipboard))) + (key:find "shift%+") (set f.i (or (textnav (key:gsub "shift%+" "") f.i textNew) f.i)) (let [iNav (textnav key f.i textNew)] (when iNav (set f.i iNav) (set f.iAnchor iNav)) - (if (= f.i f.iAnchor) - (set textNew - (match key - :delete (replace-selection view textNew "" f.i (+ f.i 1)) - (:backspace ? (> f.i 1)) (replace-selection view textNew "" (- f.i 1) f.i) - _ textNew)) - (when (or (= key :delete) (= key :backspace)) - (set textNew (replace-selection view textNew "")))))))) + (when (or (= key :delete) (= key :backspace)) + (local (iStartDel iLimDel) + (if (not= f.i f.iAnchor) (selection-span view) + (= key :delete) (values f.i (+ f.i 1)) + (= key :backspace) (values (math.max 1 (- f.i 1)) f.i))) + (set textNew (replace-selection view textNew "" iStartDel iLimDel))))))) ; handle mouse events (when (mouse-inside x y w h) (set view.cursor :ibeam)) diff --git a/game/tiles.fnl b/game/tiles.fnl index d961e58..e279f21 100644 --- a/game/tiles.fnl +++ b/game/tiles.fnl @@ -18,8 +18,8 @@ (org:append [:bytes tile.gfx]))) (fn appendmaps [org] - (local map (: (util.readjson "game/map00001.json") :fromhex)) - (org:append :map [:bytes map])) + (local map (util.readjson "game/map00001.json")) + (org:append :map [:bytes (map.map:fromhex)])) {: loadtiles : savetiles : appendtiles : appendmaps : flags}