Skip to content

Commit a3aa268

Browse files
committed
Make gc work everywhere, add docs for extensions
1 parent f2321d5 commit a3aa268

File tree

3 files changed

+62
-13
lines changed

3 files changed

+62
-13
lines changed

assets/keymaps/vim.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,8 @@
370370
"bindings": {
371371
"escape": "vim::ClearOperators",
372372
"ctrl-c": "vim::ClearOperators",
373-
"ctrl-[": "vim::ClearOperators"
373+
"ctrl-[": "vim::ClearOperators",
374+
"g c": "vim::Comment"
374375
}
375376
},
376377
{
@@ -401,8 +402,7 @@
401402
"i": "vim::IndentObj",
402403
"shift-i": ["vim::IndentObj", { "includeBelow": true }],
403404
"m": "vim::Method",
404-
"c": "vim::Class",
405-
"g c": "vim::Comment"
405+
"c": "vim::Class"
406406
}
407407
},
408408
{

crates/vim/src/object.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use std::ops::Range;
22

3-
use crate::{motion::right, state::Mode, Vim};
3+
use crate::{
4+
motion::right,
5+
state::{Mode, Operator},
6+
Vim,
7+
};
48
use editor::{
59
display_map::{DisplaySnapshot, ToDisplayPoint},
610
movement::{self, FindRange},
@@ -120,6 +124,9 @@ pub fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
120124
vim.object(Object::Class, cx)
121125
});
122126
Vim::action(editor, cx, |vim, _: &Comment, cx| {
127+
if !matches!(vim.active_operator(), Some(Operator::Object { .. })) {
128+
vim.push_operator(Operator::Object { around: true }, cx);
129+
}
123130
vim.object(Object::Comment, cx)
124131
});
125132
Vim::action(
@@ -276,15 +283,7 @@ impl Object {
276283
TextObject::InsideFunction
277284
},
278285
),
279-
Object::Comment => text_object(
280-
map,
281-
relative_to,
282-
if around {
283-
TextObject::AroundComment
284-
} else {
285-
TextObject::InsideComment
286-
},
287-
),
286+
Object::Comment => comment_object(map, relative_to),
288287
Object::Class => text_object(
289288
map,
290289
relative_to,
@@ -497,6 +496,16 @@ fn around_next_word(
497496
Some(start..end)
498497
}
499498

499+
fn comment_object(
500+
map: &DisplaySnapshot,
501+
relative_to: DisplayPoint,
502+
target: TextObject,
503+
) -> Option<Range<DisplayPoint>> {
504+
let snapshot = &map.buffer_snapshot;
505+
let offset = relative_to.to_offset(map, Bias::Left);
506+
snapshot.range_for_syntax_ancestor(range)
507+
}
508+
500509
fn text_object(
501510
map: &DisplaySnapshot,
502511
relative_to: DisplayPoint,

docs/src/extensions/languages.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ several features:
6969
- Syntax overrides
7070
- Text redactions
7171
- Runnable code detection
72+
- Selecting classes, functions, etc.
7273

7374
The following sections elaborate on how [Tree-sitter queries](https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax) enable these
7475
features in Zed, using [JSON syntax](https://www.json.org/json-en.html) as a guiding example.
@@ -259,6 +260,45 @@ For example, in JavaScript, we also disable auto-closing of single quotes within
259260
(comment) @comment.inclusive
260261
```
261262

263+
### Text objects
264+
265+
The `textobjects.scm` file defines rules for navigating by text objects. This was added in Zed v0.165 and is currently used only in Vim mode.
266+
267+
Vim provides two levels of granularity for navigating around files. Section-by-section with `[]` etc., and method-by-method with `]m` etc. Even languages that don't support functions and classes can work well by defining similar concepts. For example CSS defines a rule-set as a method, and a media-query as a class.
268+
269+
When there's only one level, use the function matchers instead of class as the `[[` family of motions will fall-back to methods if there are no classes defined. For example, Markdown defines a section as a method so that you can use `[[` to jump to the next heading.
270+
271+
For languages with closures, these typically should not count as functions in Zed. This is best-effort however, as languages like Javascript do not syntactically differentiate syntactically between closures and top-level function declarations.
272+
273+
For languages with declarations like C, provide queries that match `@class.around` or `@function.around`. The `im` and `ic` text objects will default to these if there is no inside.
274+
275+
If you are not sure what to put in textobjects.scm, both [nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects), and the [Helix editor](https://github.com/helix-editor/helix) have queries for many langauges. You can refer to the Zed [built-in languages](https://github.com/zed-industries/zed/tree/main/crates/languages/src) to see how to adapt these.
276+
277+
| Capture | Description | Vim mode |
278+
|------------------|-------------|----------|
279+
| @function.around | An entire function definition or equivalent small section of a file. | `[m`, `]m`, `[M`,`]M` motions. `am` text object |
280+
| @function.inside | The function body (the stuff within the braces). | `im` text object |
281+
| @class.around | An entire class definition or equivalent large section of a file. | `[[`, `]]`, `[]`, `][` motions. `ac` text object |
282+
| @class.inside | The contents of a class definition. | `ic` text object |
283+
| @comment.around | An entire comment (e.g. all adjacent line comments, or a block comment) | `gc` text object |
284+
| @comment.inside | The contents of a comment | `igc` text object (rarely supported) |
285+
286+
For example:
287+
```scheme
288+
; include only the content of the method in the function
289+
(method_definition
290+
body: (_
291+
"{"
292+
(_)* @function.inside
293+
"}")) @function.around
294+
295+
; match function.around for declarations with no body
296+
(function_signature_item) @function.around
297+
298+
; join all adjacent comments into one
299+
(comment)+ @comment.around
300+
```
301+
262302
### Text redactions
263303

264304
The `redactions.scm` file defines text redaction rules. When collaborating and sharing your screen, it makes sure that certain syntax nodes are rendered in a redacted mode to avoid them from leaking.

0 commit comments

Comments
 (0)