diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..4971e7e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## Unreleased + +- Fix [#45](https://github.com/nextjournal/clojure-mode/issues/45): cursor after Discard node should evaluate child diff --git a/public/squint/js/demo.mjs b/public/squint/js/demo.mjs index 85cd2ee..b5da6a7 100644 --- a/public/squint/js/demo.mjs +++ b/public/squint/js/demo.mjs @@ -2,6 +2,7 @@ import { default_extensions, complete_keymap } from '@nextjournal/clojure-mode'; import { extension as eval_ext, cursor_node_string, top_level_string } from '@nextjournal/clojure-mode/extensions/eval-region'; import { EditorView, drawSelection, keymap } from '@codemirror/view'; import { EditorState } from '@codemirror/state'; +import { history, historyKeymap } from '@codemirror/commands'; import { syntaxHighlighting, defaultHighlightStyle, foldGutter } from '@codemirror/language'; import { compileStringEx } from 'squint-cljs'; @@ -89,10 +90,11 @@ let squintExtension = ( opts ) => { }])} -let extensions = [ theme, foldGutter(), +let extensions = [ history(), theme, foldGutter(), syntaxHighlighting(defaultHighlightStyle), drawSelection(), keymap.of(complete_keymap), + keymap.of(historyKeymap), ...default_extensions, eval_ext({modifier: "Meta"}), squintExtension({modifier: "Meta"}) @@ -120,6 +122,8 @@ let doc = `(comment (+ 1 2 3)) ` ; +// doc = `(do #_#_1 (+ 1 2 3) )` + evalCode(doc); let state = EditorState.create( {doc: doc, @@ -129,6 +133,7 @@ let editorElt = document.querySelector('#editor'); let editor = new EditorView({state: state, parent: editorElt, extensions: extensions }) +globalThis.editor = editor; let keys = {"ArrowUp": "↑", "ArrowDown": "↓", diff --git a/squint-demo/index.mjs b/squint-demo/index.mjs index 1fa5ca6..1a5adad 100644 --- a/squint-demo/index.mjs +++ b/squint-demo/index.mjs @@ -4,6 +4,7 @@ import { EditorView, drawSelection, keymap } from '@codemirror/view'; import { EditorState } from '@codemirror/state'; import { syntaxHighlighting, defaultHighlightStyle, foldGutter } from '@codemirror/language'; import { javascript } from '@codemirror/lang-javascript'; +import { history, historyKeymap } from '@codemirror/commands'; let theme = EditorView.theme({ ".cm-content": {whitespace: "pre-wrap", @@ -25,12 +26,13 @@ let theme = EditorView.theme({ "&.cm-focused .cm-cursor": {visibility: "visible"} }); -let extensions = [ +let extensions = [ history(), theme, foldGutter(), syntaxHighlighting(defaultHighlightStyle), drawSelection(), keymap.of(complete_keymap), + keymap.of(historyKeymap), ...default_extensions ]; diff --git a/src-shared/nextjournal/clojure_mode/extensions/eval_region.cljc b/src-shared/nextjournal/clojure_mode/extensions/eval_region.cljc index a9602e4..62bdf7c 100644 --- a/src-shared/nextjournal/clojure_mode/extensions/eval_region.cljc +++ b/src-shared/nextjournal/clojure_mode/extensions/eval_region.cljc @@ -12,12 +12,15 @@ (defn uppermost-edge-here "Returns node or its highest ancestor that starts or ends at the cursor position." [pos node] - (or (->> (iterate n/up node) - (take-while (every-pred (complement n/top?) - #(or (= pos (n/end %) (n/end node)) - (= pos (n/start %) (n/start node))))) - (last)) - node)) + (let [node (or (->> (iterate n/up node) + (take-while (every-pred (complement n/top?) + #(or (= pos (n/end %) (n/end node)) + (= pos (n/start %) (n/start node))))) + (last)) + node)] + (if (= "Discard" (n/name node)) + (last (n/children node)) + node))) (defn main-selection [state] (-> @@ -32,9 +35,10 @@ (<= (n/start %) from) (<= (n/end %) from)) (cond-> % - (or (n/top? %) - (and (not (n/terminal-type? (n/type %))) - (< (n/start %) from (n/end %)))) + (or + (n/top? %) + (and (not (n/terminal-type? (n/type %))) + (< (n/start %) from (n/end %)))) (-> (n/children from -1) first)))) (uppermost-edge-here from) (n/balanced-range state)))) diff --git a/test/nextjournal/clojure_mode_tests.cljc b/test/nextjournal/clojure_mode_tests.cljc index 2d967f5..7c68710 100644 --- a/test/nextjournal/clojure_mode_tests.cljc +++ b/test/nextjournal/clojure_mode_tests.cljc @@ -331,7 +331,9 @@ (= (f (test-utils/make-state extensions input)) expected) "(+ |1 2 3)" eval-region/cursor-node-string "1" "(+ |(+ 1 2) 2 3)" eval-region/cursor-node-string "(+ 1 2)" - "(+ (+ 1 2)| 2 3)" eval-region/cursor-node-string "(+ 1 2)") + "(+ (+ 1 2)| 2 3)" eval-region/cursor-node-string "(+ 1 2)" + "(+ #_(+ 1 2)| 2 3)" eval-region/cursor-node-string "(+ 1 2)" + "(+ #_#_1 (+ 1 2)| 2 3)" eval-region/cursor-node-string "(+ 1 2)") (let [state (test-utils/make-state extensions ";; dude\n|{:a 1}")] (is (= "{:a 1}" (->> (eval-region/top-level-node state) (util/range-str state)))))))