Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite and refactor all documentation #5534

Merged
merged 39 commits into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
421b5eb
Rewrite and refactor all documentation
David-Else Jan 14, 2023
dc6a0e3
Rewrite and refactor the guides
David-Else Jan 14, 2023
d3dfb29
update runtime directory instructions for windows
CptPotato Jan 14, 2023
4224da6
Merge pull request #1 from CptPotato/win-build-docs
David-Else Jan 15, 2023
a6894a1
Update the Ubuntu 3rd party repo section with 22.10
David-Else Jan 16, 2023
227ed34
Merge remote-tracking branch 'upstream/master' into rewrite-and-refac…
David-Else Jan 16, 2023
07cbc54
Merge from upstream
David-Else Jan 16, 2023
3901d60
Rewrite and refactor all documentation
David-Else Jan 28, 2023
d932969
Apply suggestions from code review
David-Else Jan 29, 2023
7c84042
Merge branch 'rewrite-and-refactor-all-documentation' of github.com:D…
David-Else Jan 29, 2023
550273c
Add Windows themes folder
David-Else Feb 1, 2023
0fa91ee
Merge branch 'rewrite-and-refactor-all-documentation' of github.com:D…
David-Else Feb 2, 2023
498be1b
Apply the rest of the suggestions from the code review
David-Else Feb 2, 2023
7cfdd9c
Revert "Apply the rest of the suggestions from the code review"
David-Else Feb 2, 2023
1480e19
Revert "Merge branch 'rewrite-and-refactor-all-documentation' of gith…
the-mikedavis Feb 2, 2023
f5eeac6
Merge branch 'master' into rewrite-and-refactor-all-documentation
the-mikedavis Feb 2, 2023
f92d580
Apply code review suggestions
David-Else Feb 3, 2023
f7ed274
Changes after re-reading all documents
David-Else Feb 3, 2023
a5567a9
Missed a full stop
David-Else Feb 3, 2023
192e891
Code review suggestions and remove macOS and Windows specific sections
David-Else Feb 7, 2023
e01032e
Add OpenBSD to heading
David-Else Feb 7, 2023
445314c
Add back macOS and Windows sections and further simplify and improve
David-Else Feb 8, 2023
47fca79
Change wording to nightly
David-Else Feb 8, 2023
6674a08
Remove README installation section and turn into a link
David-Else Feb 8, 2023
3bd1b23
Simplify building from source and follow code review suggestions
David-Else Feb 8, 2023
99eec65
Code review revisions
David-Else Feb 8, 2023
6b30103
Fix copy paste mistake
David-Else Feb 8, 2023
24fc54a
Apply the latest code review suggestions
David-Else Feb 9, 2023
b3c551e
More small code review items
David-Else Feb 9, 2023
81a95f8
Change minor modes for code review
David-Else Feb 9, 2023
81f9e1b
Fix link and typos
David-Else Feb 9, 2023
b5bd559
Add note that you need a c++ compiler to install the tree-sitter gram…
David-Else Feb 11, 2023
b1372a7
Add pacman example
David-Else Feb 12, 2023
fbaa5d5
Make sure all headings are lower case
David-Else Feb 17, 2023
aa45dc7
Revert to the original passage adding a reference to Windows that was…
David-Else Feb 17, 2023
a5784ed
Merge branch 'master' into rewrite-and-refactor-all-documentation
the-mikedavis Feb 28, 2023
b1d63ea
Update book/src/guides/adding_languages.md
David-Else Mar 1, 2023
07be576
Update book/src/install.md
David-Else Mar 1, 2023
826f470
Remove TOC links to main heading
David-Else Mar 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion book/src/commands.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Commands

Command mode can be activated by pressing `:`, similar to Vim. Built-in commands:
Command mode, similar to Vim, can be activated by pressing `:`. The built-in
commands are:

{{#include ./generated/typable-cmd.md}}
197 changes: 101 additions & 96 deletions book/src/configuration.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion book/src/guides/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Guides

This section contains guides for adding new language server configurations,
tree-sitter grammars, textobject queries, etc.
tree-sitter grammars, textobject queries, and other similar items.
78 changes: 46 additions & 32 deletions book/src/guides/adding_languages.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,59 @@
# Adding languages
# Adding new languages to Helix

In order to add a new language to Helix, you will need to follow the steps
below.

## Language configuration

To add a new language, you need to add a `[[language]]` entry to the
`languages.toml` (see the [language configuration section]).
1. Add a new `[[language]]` entry in the `languages.toml` file and provide the
necessary configuration for the new language. For more information on
language configuration, refer to the
[language configuration section](../languages.md) of the documentation.
2. If you are adding a new language or updating an existing language server
configuration, run the command `cargo xtask docgen` to update the
[Language Support](../lang-support.md) documentation.

When adding a new language or Language Server configuration for an existing
language, run `cargo xtask docgen` to add the new configuration to the
[Language Support][lang-support] docs before creating a pull request.
When adding a Language Server configuration, be sure to update the
[Language Server Wiki][install-lsp-wiki] with installation notes.
> 💡 If you are adding a new Language Server configuration, make sure to update
> the
> [Language Server Wiki](https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers)
David-Else marked this conversation as resolved.
Show resolved Hide resolved
> with the installation instructions.

## Grammar configuration

If a tree-sitter grammar is available for the language, add a new `[[grammar]]`
entry to `languages.toml`.

You may use the `source.path` key rather than `source.git` with an absolute path
to a locally available grammar for testing, but switch to `source.git` before
submitting a pull request.
1. If a tree-sitter grammar is available for the new language, add a new
`[[grammar]]` entry to the `languages.toml` file.
2. If you are testing the grammar locally, you can use the `source.path` key
with an absolute path to the grammar. However, before submitting a pull
request, make sure to switch to using `source.git`.

## Queries

For a language to have syntax-highlighting and indentation among
other things, you have to add queries. Add a directory for your
language with the path `runtime/queries/<name>/`. The tree-sitter
[website](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#queries)
gives more info on how to write queries.

> NOTE: When evaluating queries, the first matching query takes
precedence, which is different from other editors like Neovim where
the last matching query supersedes the ones before it. See
[this issue][neovim-query-precedence] for an example.

## Common Issues

- If you get errors when running after switching branches, you may have to update the tree-sitter grammars. Run `hx --grammar fetch` to fetch the grammars and `hx --grammar build` to build any out-of-date grammars.

- If a parser is segfaulting or you want to remove the parser, make sure to remove the compiled parser in `runtime/grammar/<name>.so`
1. In order to provide syntax highlighting and indentation for the new language,
you will need to add queries.
2. Create a new directory for the language with the path
`runtime/queries/<name>/`.
3. Refer to the
[tree-sitter website](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#queries)
for more information on writing queries.

> 💡 In Helix, the first matching query takes precedence when evaluating
> queries, which is different from other editors such as Neovim where the last
> matching query supersedes the ones before it. See
> [this issue](https://github.com/helix-editor/helix/pull/1170#issuecomment-997294090)
> for an example.

## Common issues

- If you encounter errors when running Helix after switching branches, you may
need to update the tree-sitter grammars. Run the command `hx --grammar fetch`
to fetch the grammars and `hx --grammar build` to build any out-of-date
grammars.
- If a parser is causing a segfault or you want to remove it, make sure to
remove the compiled parser located at `runtime/grammar/<name>.so`.
David-Else marked this conversation as resolved.
Show resolved Hide resolved

[language configuration section]: ../languages.md
[neovim-query-precedence]: https://github.com/helix-editor/helix/pull/1170#issuecomment-997294090
[install-lsp-wiki]: https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers
[neovim-query-precedence]:
https://github.com/helix-editor/helix/pull/1170#issuecomment-997294090
[install-lsp-wiki]:
https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers
[lang-support]: ../lang-support.md
114 changes: 55 additions & 59 deletions book/src/guides/indent.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@
# Adding Indent Queries

Helix uses tree-sitter to correctly indent new lines. This requires
a tree-sitter grammar and an `indent.scm` query file placed in
`runtime/queries/{language}/indents.scm`. The indentation for a line
is calculated by traversing the syntax tree from the lowest node at the
beginning of the new line. Each of these nodes contributes to the total
indent when it is captured by the query (in what way depends on the name
of the capture).

Note that it matters where these added indents begin. For example,
multiple indent level increases that start on the same line only increase
the total indent level by 1.
Helix uses tree-sitter to correctly indent new lines. This requires a
tree-sitter grammar and an `indent.scm` query file placed in
`runtime/queries/{language}/indents.scm`. The indentation for a line is
calculated by traversing the syntax tree from the lowest node at the beginning
of the new line. Each of these nodes contributes to the total indent when it is
captured by the query (in what way depends on the name of the capture).

Note that it matters where these added indents begin. For example, multiple
indent level increases that start on the same line only increase the total
indent level by 1.

## Scopes

Added indents don't always apply to the whole node. For example, in most
cases when a node should be indented, we actually only want everything
except for its first line to be indented. For this, there are several
scopes (more scopes may be added in the future if required):
Added indents don't always apply to the whole node. For example, in most cases
David-Else marked this conversation as resolved.
Show resolved Hide resolved
when a node should be indented, we actually only want everything except for its
first line to be indented. For this, there are several scopes (more scopes may
be added in the future if required):

- `all`: This scope applies to the whole captured node. This is only different
from `tail` when the captured node is the first node on its line.

- `all`:
This scope applies to the whole captured node. This is only different from
`tail` when the captured node is the first node on its line.
- `tail`: This scope applies to everything except for the first line of the
captured node.

- `tail`:
This scope applies to everything except for the first line of the
captured node.
Every capture type has a default scope which should do the right thing in most
situations. When a different scope is required, this can be changed by using a
`#set!` declaration anywhere in the pattern:

Every capture type has a default scope which should do the right thing
in most situations. When a different scope is required, this can be
changed by using a `#set!` declaration anywhere in the pattern:
```scm
(assignment_expression
right: (_) @indent
Expand All @@ -38,56 +36,54 @@ changed by using a `#set!` declaration anywhere in the pattern:

## Capture Types

- `@indent` (default scope `tail`):
Increase the indent level by 1. Multiple occurrences in the same line
don't stack. If there is at least one `@indent` and one `@outdent`
capture on the same line, the indent level isn't changed at all.

- `@outdent` (default scope `all`):
Decrease the indent level by 1. The same rules as for `@indent` apply.
- `@indent` (default scope `tail`): Increase the indent level by 1. Multiple
occurrences in the same line don't stack. If there is at least one `@indent`
and one `@outdent` capture on the same line, the indent level isn't changed at
all.

- `@extend`:
Extend the range of this node to the end of the line and to lines that
are indented more than the line that this node starts on. This is useful
for languages like Python, where for the purpose of indentation some nodes
(like functions or classes) should also contain indented lines that follow them.
- `@outdent` (default scope `all`): Decrease the indent level by 1. The same
rules as for `@indent` apply.

- `@extend.prevent-once`:
Prevents the first extension of an ancestor of this node. For example, in Python
a return expression always ends the block that it is in. Note that this only stops the
extension of the next `@extend` capture. If multiple ancestors are captured,
only the extension of the innermost one is prevented. All other ancestors are unaffected
(regardless of whether the innermost ancestor would actually have been extended).
- `@extend`: Extend the range of this node to the end of the line and to lines
that are indented more than the line that this node starts on. This is useful
for languages like Python, where for the purpose of indentation some nodes
(like functions or classes) should also contain indented lines that follow
them.

- `@extend.prevent-once`: Prevents the first extension of an ancestor of this
node. For example, in Python a return expression always ends the block that it
is in. Note that this only stops the extension of the next `@extend` capture.
If multiple ancestors are captured, only the extension of the innermost one is
prevented. All other ancestors are unaffected (regardless of whether the
innermost ancestor would actually have been extended).

## Predicates

In some cases, an S-expression cannot express exactly what pattern should be matched.
For that, tree-sitter allows for predicates to appear anywhere within a pattern,
similar to how `#set!` declarations work:
In some cases, an S-expression cannot express exactly what pattern should be
matched. For that, tree-sitter allows for predicates to appear anywhere within a
pattern, similar to how `#set!` declarations work:

```scm
(some_kind
(child_kind) @indent
(#predicate? arg1 arg2 ...)
)
```
The number of arguments depends on the predicate that's used.
Each argument is either a capture (`@name`) or a string (`"some string"`).
The following predicates are supported by tree-sitter:

- `#eq?`/`#not-eq?`:
The first argument (a capture) must/must not be equal to the second argument
(a capture or a string).
The number of arguments depends on the predicate that's used. Each argument is
either a capture (`@name`) or a string (`"some string"`). The following
predicates are supported by tree-sitter:

- `#eq?`/`#not-eq?`: The first argument (a capture) must/must not be equal to
the second argument (a capture or a string).

- `#match?`/`#not-match?`:
The first argument (a capture) must/must not match the regex given in the
second argument (a string).
- `#match?`/`#not-match?`: The first argument (a capture) must/must not match
the regex given in the second argument (a string).

Additionally, we support some custom predicates for indent queries:

- `#not-kind-eq?`:
The kind of the first argument (a capture) must not be equal to the second
argument (a string).
- `#not-kind-eq?`: The kind of the first argument (a capture) must not be equal
to the second argument (a string).

- `#same-line?`/`#not-same-line?`:
The captures given by the 2 arguments must/must not start on the same line.
- `#same-line?`/`#not-same-line?`: The captures given by the 2 arguments
must/must not start on the same line.
42 changes: 23 additions & 19 deletions book/src/guides/textobject.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# Adding Textobject Queries

Textobjects that are language specific ([like functions, classes, etc][textobjects])
require an accompanying tree-sitter grammar and a `textobjects.scm` query file
to work properly. Tree-sitter allows us to query the source code syntax tree
and capture specific parts of it. The queries are written in a lisp dialect.
More information on how to write queries can be found in the [official tree-sitter
documentation][tree-sitter-queries].
Helix supports textobjects that are language specific, such as functions,
classes, etc. These textobjects require an accompanying tree-sitter grammar and
a `textobjects.scm` query file to work properly. Tree-sitter allows us to query
the source code syntax tree and capture specific parts of it. The queries are
written in a lisp dialect. More information on how to write queries can be found
in the [official tree-sitter documentation][tree-sitter-queries].

Query files should be placed in `runtime/queries/{language}/textobjects.scm`
when contributing. Note that to test the query files locally you should put
them under your local runtime directory (`~/.config/helix/runtime` on Linux
when contributing to Helix. Note that to test the query files locally you should
put them under your local runtime directory (`~/.config/helix/runtime` on Linux
for example).

The following [captures][tree-sitter-captures] are recognized:

| Capture Name |
| --- |
| ------------------ |
| `function.inside` |
| `function.around` |
| `class.inside` |
Expand All @@ -26,24 +26,28 @@ The following [captures][tree-sitter-captures] are recognized:
| `comment.inside` |
| `comment.around` |

[Example query files][textobject-examples] can be found in the helix GitHub repository.
[Example query files][textobject-examples] can be found in the Helix GitHub
repository.

## Queries for Textobject Based Navigation

[Tree-sitter based navigation][textobjects-nav] is done using captures in the
following order:
Tree-sitter based navigation in Helix is done using captures in the following
order:

- `object.movement`
- `object.around`
- `object.inside`

For example if a `function.around` capture has been already defined for a language
in it's `textobjects.scm` file, function navigation should also work automatically.
`function.movement` should be defined only if the node captured by `function.around`
doesn't make sense in a navigation context.
For example if a `function.around` capture has been already defined for a
language in its `textobjects.scm` file, function navigation should also work
automatically. `function.movement` should be defined only if the node captured
by `function.around` doesn't make sense in a navigation context.

[textobjects]: ../usage.md#textobjects
[textobjects-nav]: ../usage.md#tree-sitter-textobject-based-navigation
[tree-sitter-queries]: https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax
[tree-sitter-captures]: https://tree-sitter.github.io/tree-sitter/using-parsers#capturing-nodes
[textobject-examples]: https://github.com/search?q=repo%3Ahelix-editor%2Fhelix+filename%3Atextobjects.scm&type=Code&ref=advsearch&l=&l=
[tree-sitter-queries]:
https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax
[tree-sitter-captures]:
https://tree-sitter.github.io/tree-sitter/using-parsers#capturing-nodes
[textobject-examples]:
https://github.com/search?q=repo%3Ahelix-editor%2Fhelix+filename%3Atextobjects.scm&type=Code&ref=advsearch&l=&l=
Loading