diff --git a/server/src/zen_lang/lsp_server/impl/autocomplete.clj b/server/src/zen_lang/lsp_server/impl/autocomplete.clj index 1804ac7..7fca0f1 100644 --- a/server/src/zen_lang/lsp_server/impl/autocomplete.clj +++ b/server/src/zen_lang/lsp_server/impl/autocomplete.clj @@ -1,5 +1,11 @@ (ns zen-lang.lsp-server.impl.autocomplete) +(defn gather-confirming-keys + [ztx confirmings] + (when (seq confirmings) + (mapcat #(concat (keys (get-in @ztx [:symbols % :keys])) + (gather-confirming-keys ztx (:confirms (get-in @ztx [:symbols %])))) + confirmings))) (defn find-completions [ztx {:keys [uri struct-path]}] (cond @@ -16,6 +22,17 @@ sort (mapv str))) + ;; :keys symbol suggestion based on :confirms key + (= :keys (last struct-path)) + (let [current-ns (get-in @ztx [:file uri :last-valid-edn 'ns]) + pos-ctx-struct (get-in @ztx (into [:file uri :last-valid-edn] (butlast struct-path))) + confirms (map #(if (nil? (namespace %)) + (symbol (str current-ns) (name %)) + %) + (:confirms pos-ctx-struct)) + confirming-keys (gather-confirming-keys ztx confirms)] + (vec (map str confirming-keys))) + ;; schema :keys keyword suggestion :else (let [pos-ctx-struct (get-in @ztx (into [:file uri :last-valid-edn] struct-path)) diff --git a/server/test-resources/test-project/zrc/qux.edn b/server/test-resources/test-project/zrc/qux.edn new file mode 100644 index 0000000..f163454 --- /dev/null +++ b/server/test-resources/test-project/zrc/qux.edn @@ -0,0 +1,25 @@ +{ns qux + import #{baz} + + grand-parent-schema + {:zen/tags #{zen/schema} + :type zen/map + :keys {:grand-parent-key {:type zen/string}} + :zen/desc "A cool schema"} + + parent-schema + {:zen/tags #{zen/schema} + :type zen/map + :confirms #{baz/schema2 grand-parent-schema} + :keys {:parent-key {:type zen/string}} + :zen/desc "A cool schema"} + + schema + {:zen/tags #{zen/schema} + :type zen/map + :confirms #{parent-schema} + :keys {:hello {:type zen/string + :confirms #{grand-parent-schema} + :keys {}} + :baz {}} + :zen/desc "A cool schema"}} \ No newline at end of file diff --git a/server/test/zen_lsp/autocomplete_test.clj b/server/test/zen_lsp/autocomplete_test.clj index 9514456..1de233f 100644 --- a/server/test/zen_lsp/autocomplete_test.clj +++ b/server/test/zen_lsp/autocomplete_test.clj @@ -10,6 +10,7 @@ (do (alter-var-root #'server/zen-ctx (constantly (server/new-context))) (server/initialize-paths {:root "test-resources/test-project"}) (server/load-document (file->message "test-resources/test-project/zrc/baz.edn")) + (server/load-document (file->message "test-resources/test-project/zrc/foo.edn")) server/zen-ctx)) (deftest find-completions-test @@ -31,5 +32,17 @@ (is (= (conj (->> @ztx :symbols keys (mapv str) set) "schema" "schema2") (let [f "test-resources/test-project/zrc/baz.edn" path ['schema2 :qux :type]] - (set (zl/find-completions ztx {:uri f :struct-path path}))))) ) + (set (zl/find-completions ztx {:uri f :struct-path path})))))) + + (testing "following hierarchy of symbols by the :confirm key gather all possible keys" + (is (= (let [parent-keys (get-in @ztx [:symbols 'qux/parent-schema :keys]) + grand-parent-keys (get-in @ztx [:symbols 'qux/grand-parent-schema :keys]) + imported-keys (get-in @ztx [:symbols 'baz/schema2 :keys])] + (->> (concat parent-keys grand-parent-keys imported-keys) + keys + set + (map str) + vec)) + (let [f "test-resources/test-project/zrc/qux.edn"] + (zl/find-completions ztx {:uri f :struct-path ['schema :keys]}))))) ))