Skip to content

Commit

Permalink
Merge branch dev into published
Browse files Browse the repository at this point in the history
  • Loading branch information
PEZ committed Jan 7, 2023
2 parents e8d68ee + ed2736a commit 8cc6337
Show file tree
Hide file tree
Showing 14 changed files with 206 additions and 68 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Changes to Calva.

## [Unreleased]

## [2.0.323] - 2023-01-07

- Fix: [Provider completions not handling errors gracefully](https://github.com/BetterThanTomorrow/calva/issues/2006)
- Partly fix (indenter): [Indenter and formatter fails while typing out body of deftype method](https://github.com/BetterThanTomorrow/calva/issues/1957)

## [2.0.322] - 2022-12-14

- Fix: [Clojure notebooks don't seem to work on MS-Windows](https://github.com/BetterThanTomorrow/calva/issues/1994)
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "Calva: Clojure & ClojureScript Interactive Programming",
"description": "Integrated REPL, formatter, Paredit, and more. Powered by cider-nrepl and clojure-lsp.",
"icon": "assets/calva.png",
"version": "2.0.322",
"version": "2.0.323",
"publisher": "betterthantomorrow",
"author": {
"name": "Better Than Tomorrow",
Expand All @@ -14,6 +14,9 @@
"url": "https://github.com/BetterThanTomorrow/calva.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/BetterThanTomorrow/calva/issues"
},
"engines": {
"node": ">=16",
"vscode": "^1.67.0"
Expand Down
49 changes: 35 additions & 14 deletions publish.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
;; Note: The shell commands may need to be modified if you're using Windows.
;; At the time of this writing, both people who push use Unix-based machines.

(require '[clojure.string :as str]
'[cheshire.core :as json]
'[clojure.java.shell :as shell])
(ns publish
(:require [clojure.string :as str]
[cheshire.core :as json]
[clojure.java.shell :as shell]))

(def changelog-filename "CHANGELOG.md")
(def changelog-text (slurp changelog-filename))
Expand Down Expand Up @@ -37,11 +38,12 @@
(format "[Unreleased]\n\n%s\n\n" new-header))]
new-text))

(defn throw-if-error [{:keys [exit out err]}]
(when-not (= exit 0)
(defn throw-if-error [{:keys [exit out err] :as result}]
(if-not (= exit 0)
(throw (Exception. (if (empty? out)
err
out)))))
out)))
result))

(defn commit-changelog [file-name message]
(println "Committing")
Expand All @@ -60,6 +62,18 @@
(println "Pushing")
(throw-if-error (shell/sh "git" "push" "--follow-tags")))

(defn git-status []
(println "Checking git status")
(let [result (throw-if-error (shell/sh "git" "status"))
out (:out result)
[_ branch] (re-find #"^On branch (\S+)\n" out)
up-to-date (re-find #"Your branch is up to date" out)
clean (re-find #"nothing to commit, working tree clean" out)]
(cond-> #{}
(not= "dev" branch) (conj :not-on-dev)
(not up-to-date) (conj :not-up-to-date)
(not clean) (conj :branch-not-clean))))

(defn publish []
(tag calva-version)
(push)
Expand All @@ -69,15 +83,22 @@
(when (= *file* (System/getProperty "babashka.file"))
(let [unreleased-changelog-text (get-unreleased-changelog-text
changelog-text
unreleased-header-re)]
unreleased-header-re)
status (git-status)]
(when (or (seq status)
(empty? unreleased-changelog-text))
(when (seq status)
(println "Git status issues: " status))
(when (empty? unreleased-changelog-text)
(print "There are no unreleased changes in the changelog."))
(println "Release anyway? YES/NO: ")
(flush)
(let [answer (read)]
(when-not (= "YES" answer)
(println "Aborting publish.")
(System/exit 0))))
(if (empty? unreleased-changelog-text)
(do
(print "There are no unreleased changes in the changelog. Release anyway? y/n: ")
(flush)
(let [answer (read)]
(if (= (str answer) "y")
(publish)
(println "Aborting publish."))))
(publish)
(let [updated-changelog-text (new-changelog-text changelog-text
unreleased-header-re
calva-version)]
Expand Down
12 changes: 11 additions & 1 deletion src/calva-fmt/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,24 @@ const defaultCljfmtContent =
const LSP_CONFIG_KEY = 'CLOJURE-LSP';
let lspFormatConfig: string | undefined;

function cljfmtOptionsFromString(cljfmt: string) {
const options = cljsLib.cljfmtOptionsFromString(cljfmt);
return {
...options,
// because we can't correctly pass ordered map from cljs
// but we need it to determine the order of applying indent rules
indents: Object.fromEntries(options['indents']),
};
}

function configuration(workspaceConfig: vscode.WorkspaceConfiguration, cljfmt: string) {
return {
'format-as-you-type': !!formatOnTypeEnabled(),
'keep-comment-forms-trail-paren-on-own-line?': !!workspaceConfig.get<boolean>(
'keepCommentTrailParenOnOwnLine'
),
'cljfmt-options-string': cljfmt,
'cljfmt-options': cljsLib.cljfmtOptionsFromString(cljfmt),
'cljfmt-options': cljfmtOptionsFromString(cljfmt),
};
}

Expand Down
10 changes: 9 additions & 1 deletion src/cljs-lib/src/calva/fmt/formatter.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
indents
(merge cljfmt/default-indents indents)))

(defn- sort-indents
"Sorts rules in order to prevent default rule application
before specific one"
[indents]
#_{:clj-kondo/ignore [:private-call]}
(sort-by cljfmt/indent-order indents))

(def ^:private default-fmt
{:remove-surrounding-whitespace? true
:remove-trailing-whitespace? true
Expand All @@ -27,6 +34,7 @@
[fmt]
(as-> fmt $
(update $ :indents merge-default-indents)
(update $ :indents sort-indents)
(merge default-fmt $)))

(defn- read-cljfmt
Expand Down Expand Up @@ -259,7 +267,7 @@
(remove-indent-token-if-empty-current-line)
(remove-trail-symbol-if-comment range)))
(comment

:rcf)
(defn format-text-at-idx-on-type
"Relax formating some when used as an on-type handler"
Expand Down
22 changes: 13 additions & 9 deletions src/cljs-lib/test/calva/fmt/formatter_test.cljs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(ns calva.fmt.formatter-test
(:require [cljs.test :include-macros true :refer [deftest is testing]]
[cljfmt.core :as cljfmt]
[calva.fmt.formatter :as sut]))
(:require [calva.fmt.formatter :as sut]
[cljfmt.core :as cljfmt :refer [includes?]]
[cljs.test :include-macros true :refer [deftest is testing]]))

(deftest format-text-at-range
(is (= "(foo)\n(defn bar\n [x]\n baz)"
Expand Down Expand Up @@ -51,7 +51,7 @@ ccc {:a b :aa bb :ccc ccc}]
:config {:align-associative? true}
:range [0 56]
:idx 0})))))

(testing "Does not align associative structures when `:align-associative` is not `true`"
(is (= "(def foo
(let [a b
Expand All @@ -73,7 +73,7 @@ ccc {:a b :aa bb :ccc ccc}]
:config {:remove-multiple-non-indenting-spaces? true}
:range [0 56]
:idx 0})))))

(testing "Does not trim space between forms when `:remove-multiple-non-indenting-spaces?` is missing"
(is (= "(def foo
(let [a b
Expand Down Expand Up @@ -314,7 +314,7 @@ bar))" :range [22 25]})))
(is (= (+ 2 (count cljfmt/default-indents))
(count (:indents (sut/read-cljfmt "{:indents {foo [[:inner 0]] bar [[:block 1]]}}"))))
"merges indents on top of cljfmt indent rules")
(is (= {'a [[:inner 0]]}
(is (= '([a [[:inner 0]]])
(:indents (sut/read-cljfmt "{:indents ^:replace {a [[:inner 0]]}}")))
"with :replace metadata hint overrides default indents")
(is (= false
Expand All @@ -330,7 +330,11 @@ bar))" :range [22 25]})))
(:remove-surrounding-whitespace? (sut/read-cljfmt "{:remove-surrounding-whitespace? false}")))
"including keys in cljfmt such as :remove-surrounding-whitespace? will override defaults.")
(is (nil? (:foo (sut/read-cljfmt "{:bar false}")))
"most keys don't have any defaults."))
"most keys don't have any defaults.")
(is (empty? (let [indents (map (comp str first) (:indents (sut/read-cljfmt "{}")))
indents-after-default (drop-while #(not= (str #"^def(?!ault)(?!late)(?!er)") %) indents)]
(filter (partial re-find #"^def") indents-after-default)))
"places default rule '^def(?!ault)(?!late)(?!er)' after all specific def rules"))

(deftest cljfmt-options
(is (= (count cljfmt/default-indents)
Expand All @@ -339,12 +343,12 @@ bar))" :range [22 25]})))
(is (= (+ 2 (count cljfmt/default-indents))
(count (:indents (sut/merge-cljfmt '{:indents {foo [[:inner 0]] bar [[:block 1]]}}))))
"merges indents on top of cljfmt indent rules")
(is (= {'a [[:inner 0]]}
(is (= '([a [[:inner 0]]])
(:indents (sut/merge-cljfmt '{:indents ^:replace {a [[:inner 0]]}})))
"with :replace metadata hint overrides default indents")
(is (= true
(:align-associative? (sut/merge-cljfmt {:align-associative? true
:cljfmt-string "{:align-associative? false}"})))
:cljfmt-string "{:align-associative? false}"})))
"cljfmt :align-associative? has lower priority than config's option")
(is (= false
(:align-associative? (sut/merge-cljfmt {:cljfmt-string "{}"})))
Expand Down
106 changes: 68 additions & 38 deletions src/cursor-doc/indent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,54 +143,84 @@ const testCljRe = (re, str) => {
return matches && RegExp(matches[1]).test(str.replace(/^.*\//, ''));
};

const calculateDefaultIndent = (indentInfo: IndentInformation) =>
indentInfo.exprsOnLine > 0 ? indentInfo.firstItemIdent : indentInfo.startIndent;

const calculateInnerIndent = (
currentIndent: number,
rule: IndentRule,
indentInfo: IndentInformation
) => {
if (rule.length !== 3 || rule[2] > indentInfo.argPos) {
return indentInfo.startIndent + 1;
}

return currentIndent;
};

const calculateBlockIndent = (
currentIndent: number,
rule: IndentRule,
indentInfo: IndentInformation
) => {
if (indentInfo.exprsOnLine > rule[1]) {
return indentInfo.firstItemIdent;
}

if (indentInfo.argPos >= rule[1]) {
return indentInfo.startIndent + 1;
}

return currentIndent;
};

const calculateIndent = (
currentIndent: number,
rule: IndentRule,
indentInfo: IndentInformation,
stateSize: number,
pos: number
) => {
if (rule[0] === 'inner' && pos + rule[1] === stateSize) {
return calculateInnerIndent(currentIndent, rule, indentInfo);
}

if (rule[0] === 'block' && pos === stateSize) {
return calculateBlockIndent(currentIndent, rule, indentInfo);
}

return currentIndent;
};

/** Returns the expected newline indent for the given position, in characters. */
export function getIndent(document: EditableModel, offset: number, config?: any): number {
if (!config) {
config = {
'cljfmt-options': {
indents: indentRules,
},
};
export function getIndent(
document: EditableModel,
offset: number,
config: any = {
'cljfmt-options': {
indents: indentRules,
},
}
): number {
const state = collectIndents(document, offset, config);
// now find applicable indent rules
let indent = -1;
const thisBlock = state[state.length - 1];
if (!state.length) {
return 0;
}

for (let pos = state.length - 1; pos >= 0; pos--) {
for (const rule of state[pos].rules) {
if (rule[0] == 'inner') {
if (pos + rule[1] == state.length - 1) {
if (rule.length == 3) {
if (rule[2] > thisBlock.argPos) {
indent = thisBlock.startIndent + 1;
}
} else {
indent = thisBlock.startIndent + 1;
}
}
} else if (rule[0] == 'block' && pos == state.length - 1) {
if (thisBlock.exprsOnLine <= rule[1]) {
if (thisBlock.argPos >= rule[1]) {
indent = thisBlock.startIndent + 1;
}
} else {
indent = thisBlock.firstItemIdent;
}
}
}
// now find applicable indent rules
let indent = -1;
const stateSize = state.length - 1;
const thisBlock = state.at(-1);
for (let pos = stateSize; pos >= 0; pos--) {
indent = state[pos].rules.reduce(
(currentIndent, rule) => calculateIndent(currentIndent, rule, thisBlock, stateSize, pos),
indent
);
}

if (indent == -1) {
// no indentation styles applied, so use default style.
if (thisBlock.exprsOnLine > 0) {
indent = thisBlock.firstItemIdent;
} else {
indent = thisBlock.startIndent;
}
return calculateDefaultIndent(thisBlock);
}

return indent;
}
Loading

0 comments on commit 8cc6337

Please sign in to comment.