Skip to content

Commit 39e5d8c

Browse files
Merge branch 'dev' into wip/test-runner-stacktrace
2 parents e0f4471 + ba172de commit 39e5d8c

7 files changed

+97
-26
lines changed

CHANGELOG.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Changes to Calva.
44

55
## [Unreleased]
66

7+
- [A more flexible evaluate-to-cursor command](https://github.com/BetterThanTomorrow/calva/
8+
issues/1901)
79
- [Test runner does not show stacktrace on error](https://github.com/BetterThanTomorrow/calva/issues/424)
810

911
## [2.0.307] - 2022-10-11
@@ -32,7 +34,7 @@ Changes to Calva.
3234
## [2.0.302] - 2022-09-18
3335

3436
- [Show error message if loading file results in an error](https://github.com/BetterThanTomorrow/calva/issues/1767)
35-
- Document workaround for: [Allow sending a different project-root-uri during LSP initialize request](https://github.com/BetterThanTomorrow/calva/issues/1866)
37+
- Document workaround for: [Allow sending a different project-root-uri during LSP initialize request](https://github.com/BetterThanTomorrow/calva/issues/1866)
3638

3739
## [2.0.301] - 2022-09-16
3840

@@ -139,7 +141,7 @@ Changes to Calva.
139141
## [2.0.280] - 2022-05-31
140142

141143
- Fix: [Debugger decorations are not working properly](https://github.com/BetterThanTomorrow/calva/issues/1165)
142-
- Add some logging when Calva starts and finishes activating
144+
- Add some logging when Calva starts and finishes activating
143145

144146
## [2.0.279] - 2022-05-30
145147

docs/site/evaluation.md

+49-12
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,22 @@ An ”exception” is introduced by the `comment` form. It will create a new top
6666

6767
At the top level the selection of which form is the current top level form follows the same rules as those for [the current form](#current-form).
6868

69+
### Evaluate Enclosing Form
70+
71+
The default keyboard shortcut for evaluating the current enclosing form (the list the cursor is in) is `ctrl+shift+enter`.
72+
73+
```clojure
74+
(let [foo :bar]
75+
(when false (str| foo))) ; => ":bar"
76+
```
77+
6978
### Evaluate to Cursor
7079

71-
There is also a command for evaluating the text from the start of the current list to where the cursor is. Convenient for checking intermediate results in thread or `doto`, or similar pipelines. The cursor is right behind `:d` in this form:
80+
There are several commands for evaluating a piece of code, closing brackets. It's good, especially in threads, but can also come in handy in other situations, for instance when you want to evaluate something that depends on bindings, such as in a `let` form.
81+
82+
### Evaluate From Start of List to Cursor, Closing Brackets
83+
84+
This command evaluates the text from the start of the current enclosing list to where the cursor is, and it adds the missing closing bracket for you. Convenient for checking intermediate results in thread or `doto`, or similar pipelines. The cursor is right behind `:d` in this form:
7285

7386
```clojure
7487
(->> [1 1 2 3 5 8 13 21]
@@ -79,11 +92,40 @@ There is also a command for evaluating the text from the start of the current li
7992
(Math/abs))
8093
```
8194

82-
The default shortcut for this command is `ctrl+alt+enter`.
95+
The default shortcut for this command is <kbd>ctrl+alt+enter</kbd>.
96+
97+
### Evaluate Selection, Closing Brackets
98+
99+
This is the most versatile of the ”evaluation, closing brackets” commands. It will do what it says. 😄 It's extra handy in combination with the command **Paredit: Select Backward Up Sexp/Form** (<kbd>shift+ctrl+up</kbd>). Consider this contrieved form (buggy code, because it was supposed to result in `42`, not `-42`):
100+
101+
```clojure
102+
(defn fortytwo-from-thirty
103+
[]
104+
(let [thirty 30]
105+
(-> thirty
106+
inc ;1
107+
(send-off)
108+
(+ 1 2 3)
109+
(->>
110+
(+ 2 2) ;2
111+
(+))
112+
list
113+
(->>
114+
(into [1])
115+
(reduce + 1))
116+
(- 1) ;3
117+
(* -1))))
118+
```
119+
120+
At `;1`, you can do **backward up sexp** (<kbd>shift+ctrl+up</kbd>) twice to select up to the `(let ..)`, then issue **Evaluate Selection, Closing Brackets**. It has the same default keybinding as the command for [evaluating the current list up to the cursor](#evaluate-from-start-of-list-to-cursor-closing-brackets): <kbd>ctrl+alt+enter</kbd>.
83121

84-
### Evaluate Top Level Form to Cursor
122+
At `;2` you need select backwards up three times.
85123

86-
This command has a default shortcut keybinding of `shift+alt+enter`. It will create a form from the start of the current top level form, up to the cursor, then fold the form, closing all brackets, and this will then be evaluated. Good for examining code blocks up to a certain point.
124+
`;3` is included because it is close to the bug. (Which was introduced when the thread-last, `->>` was added to make this example.) Please practice the **Evaluate Selection, Closing Brackets** command to fix the bug.
125+
126+
### Evaluate From Start of Top Level Form to Cursor, Closing Brackets
127+
128+
This command has a default shortcut keybinding of `shift+alt+enter`. It will create a form from the start of the current top level form, up to the cursor, close all brackets, and this will then be evaluated. Good for examining code blocks up to a certain point. Often comes in handy in Rich comments (`(comment ...)`).
87129

88130
Take this example and paste it in a file loaded into the REPL, then place the cursor in front of each line comment and try the command.
89131

@@ -116,16 +158,11 @@ Take this example and paste it in a file loaded into the REPL, then place the cu
116158
))))
117159
```
118160

119-
### Evaluate Enclosing Form
161+
### Evaluate From Start of File to Cursor, Closing Brackets
120162

121-
The default keyboard shortcut for evaluating the current enclosing form (the list the cursor is in) is `ctrl+shift+enter`.
122-
123-
```clojure
124-
(let [foo :bar]
125-
(when false (str| foo))) ; => ":bar"
126-
```
163+
Yup, that command also exists. 😄
127164

128-
### Copying the inline results
165+
## Copying the inline results
129166

130167
There is a command called **Copy last evaluation results**, `ctrl+alt+c ctrl+c`.
131168

package.json

+16-5
Original file line numberDiff line numberDiff line change
@@ -1133,19 +1133,25 @@
11331133
},
11341134
{
11351135
"command": "calva.evaluateToCursor",
1136-
"title": "Evaluate From Start of List to Cursor",
1137-
"enablement": "calva:connected",
1136+
"title": "Evaluate From Start of List to Cursor, Closing Brackets",
1137+
"enablement": "calva:connected && !editorHasSelection",
1138+
"category": "Calva"
1139+
},
1140+
{
1141+
"command": "calva.evaluateSelectionToSelectionEnd",
1142+
"title": "Evaluate Selection, Closing Brackets",
1143+
"enablement": "calva:connected && editorHasSelection",
11381144
"category": "Calva"
11391145
},
11401146
{
11411147
"command": "calva.evaluateTopLevelFormToCursor",
1142-
"title": "Evaluate From Start of Top Level Form to Cursor",
1148+
"title": "Evaluate From Start of Top Level Form to Cursor, Closing Brackets",
11431149
"enablement": "calva:connected",
11441150
"category": "Calva"
11451151
},
11461152
{
11471153
"command": "calva.evaluateStartOfFileToCursor",
1148-
"title": "Evaluate From Start of File to Cursor",
1154+
"title": "Evaluate From Start of File to Cursor, Closing Brackets",
11491155
"enablement": "calva:connected",
11501156
"category": "Calva"
11511157
},
@@ -1889,7 +1895,12 @@
18891895
{
18901896
"command": "calva.evaluateToCursor",
18911897
"key": "ctrl+alt+enter",
1892-
"when": "calva:keybindingsEnabled && editorLangId == clojure && editorTextFocus"
1898+
"when": "calva:keybindingsEnabled && editorLangId == clojure && editorTextFocus && !editorHasSelection"
1899+
},
1900+
{
1901+
"command": "calva.evaluateSelectionToSelectionEnd",
1902+
"key": "ctrl+alt+enter",
1903+
"when": "calva:keybindingsEnabled && editorLangId == clojure && editorTextFocus && editorHasSelection"
18931904
},
18941905
{
18951906
"command": "calva.evaluateTopLevelFormToCursor",

src/evaluate.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,9 @@ function evaluateUsingTextAndSelectionGetter(
377377

378378
function evaluateToCursor(document = {}, options = {}) {
379379
evaluateUsingTextAndSelectionGetter(
380-
getText.currentEnclosingFormToCursor,
380+
vscode.window.activeTextEditor.selection.isEmpty
381+
? getText.currentEnclosingFormToCursor
382+
: getText.selectionAddingBrackets,
381383
(code) => `${code}`,
382384
document,
383385
options

src/extension.ts

+3
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ async function activate(context: vscode.ExtensionContext) {
267267
context.subscriptions.push(
268268
vscode.commands.registerCommand('calva.evaluateToCursor', eval.evaluateToCursor)
269269
);
270+
context.subscriptions.push(
271+
vscode.commands.registerCommand('calva.evaluateSelectionToSelectionEnd', eval.evaluateToCursor)
272+
);
270273
context.subscriptions.push(
271274
vscode.commands.registerCommand(
272275
'calva.evaluateTopLevelFormToCursor',

src/util/cursor-get-text.ts

+15-6
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,15 @@ export function currentTopLevelForm(doc: EditableDocument): RangeAndText {
3939
return defunRange ? [defunRange, doc.model.getText(...defunRange)] : [undefined, ''];
4040
}
4141

42-
function rangeOrStartOfFileToCursor(
42+
function rangeToCursor(
4343
doc: EditableDocument,
4444
foldRange: [number, number],
45-
startFrom: number
45+
startFrom: number,
46+
active: number
4647
): RangeAndText {
4748
if (foldRange) {
4849
const closeBrackets: string[] = [];
49-
const bracketCursor = doc.getTokenCursor(doc.selection.active);
50+
const bracketCursor = doc.getTokenCursor(active);
5051
bracketCursor.backwardWhitespace(true);
5152
const rangeEnd = bracketCursor.offsetStart;
5253
while (
@@ -65,17 +66,25 @@ function rangeOrStartOfFileToCursor(
6566
export function currentEnclosingFormToCursor(doc: EditableDocument): RangeAndText {
6667
const cursor = doc.getTokenCursor(doc.selection.active);
6768
const enclosingRange = cursor.rangeForList(1);
68-
return rangeOrStartOfFileToCursor(doc, enclosingRange, enclosingRange[0]);
69+
return rangeToCursor(doc, enclosingRange, enclosingRange[0], doc.selection.active);
6970
}
7071

7172
export function currentTopLevelFormToCursor(doc: EditableDocument): RangeAndText {
7273
const cursor = doc.getTokenCursor(doc.selection.active);
7374
const defunRange = cursor.rangeForDefun(doc.selection.active);
74-
return rangeOrStartOfFileToCursor(doc, defunRange, defunRange[0]);
75+
return rangeToCursor(doc, defunRange, defunRange[0], doc.selection.active);
7576
}
7677

7778
export function startOfFileToCursor(doc: EditableDocument): RangeAndText {
7879
const cursor = doc.getTokenCursor(doc.selection.active);
7980
const defunRange = cursor.rangeForDefun(doc.selection.active, false);
80-
return rangeOrStartOfFileToCursor(doc, defunRange, 0);
81+
return rangeToCursor(doc, defunRange, 0, doc.selection.active);
82+
}
83+
84+
export function selectionAddingBrackets(doc: EditableDocument): RangeAndText {
85+
const [left, right] = [doc.selection.anchor, doc.selection.active].sort();
86+
const cursor = doc.getTokenCursor(left);
87+
cursor.forwardSexp(true, true, true);
88+
const rangeEnd = cursor.offsetStart;
89+
return rangeToCursor(doc, [left, rangeEnd], left, right);
8190
}

src/util/get-text.ts

+7
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@ export function currentTopLevelFormToCursor(
105105
return selectionAndText(doc, cursorTextGetter.currentTopLevelFormToCursor, pos);
106106
}
107107

108+
export function selectionAddingBrackets(
109+
doc: vscode.TextDocument,
110+
pos: vscode.Position
111+
): SelectionAndText {
112+
return selectionAndText(doc, cursorTextGetter.selectionAddingBrackets, pos);
113+
}
114+
108115
export function startOFileToCursor(
109116
doc: vscode.TextDocument,
110117
pos: vscode.Position

0 commit comments

Comments
 (0)