Skip to content

Commit

Permalink
chore(build): auto-generate docs
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] committed Aug 3, 2024
1 parent 1f3cd5a commit b4e6163
Show file tree
Hide file tree
Showing 10 changed files with 791 additions and 10 deletions.
134 changes: 134 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
title: Source
description: Type description of care.nvim config
author:
- max397574
categories:
- docs,
- types
---

# General

The config of care is used to configure the ui and care itself.

There are two main parts to the config. The first one is the `ui` field and the second on is the
rest of the configuration which is for configuring care itself.

## UI

In the ui field the completion menu, the docs view and the format of the entries are configured.
There is also a field for configuring type icons.

## Snippet expansion

Here a function for expanding snippets is defined. By default this is the builtin
`vim.snippet.expand()`. You can also use a plugin like luasnip for this like this:

```lua
snippet_expansion = function(body)
require("luasnip").lsp_expand(body)
end
```

## Selection behavior

With the selection behavior the user can determine what happens when selecting an entry. This can
either be `"select"` or `"insert"`. Selecting will just select the entry and do nothing else. Insert
will actually insert the text of the entry (this is not necessarily the whole text).

## Keyword pattern

Pattern used to determine keywords, used to determine what to use for filtering and what to
remove if insert text is used.

## Completion events

The `completion_events` table is used to set events for completion. By default it just contains
`"TextChangedI"`. You can set it to an empty table (`{}`) to disable autocompletion.

## Sources

TODO

## Preselect

Whether items should be preselected or not

## Enabled

This function can be used to disable care in certain contexts. By default this disables
care in prompts.

# UI

The ui configuration is used to configure the whole ui of care. One of the main goals of
this is to be as extensible as possible. This is especially important for the completion entries.
Read more about that under [Configuraton of item display](./design.md#configuraton-of-item-display).

The most important part for many users will be the `menu` field. It's used to configure the
completion menu.

You can also configure the documentation view just like the main menu.

Lastly the users can also configure the icons which will be used for the different items.

## Ghost text

with this option the user can determine if ghost text should be displayed. Ghost text is just
virtual text which shows a preview of the entry.

You can use the `enabled` field to determine whether the ghost text should be enabled or not.
The `position` can either be `"inline"` or `"overlay"`. Inline will add the text inline right
where the cursor is. With the overlay position the text will overlap with existing text after the
cursor.

## Menu

This configuration should allow you to completely adapt the completion menu to your likings.

It includes some basic window properties like the border and the maximum height of the window. It
also has a field to define the character used for the scrollbar.
Set `scrollbar` to `nil` value to disable the scrollbar.

## Position

If the menu should be displayed on top, bottom or automatically

Another field is `format_entry`. This is a function which recieves an entry of the completion
menu and determines how it's formatted. For that a table with text-highlight chunks like
`:h nvim_buf_set_extmarks()` is used. You can create sections which are represented by tables
and can have a different alignment each. This is specified with another field which takes a table
with the alignment of each section.

For example you want to have the label of an entry in a red highlight and an icon in a entry-kind
specific color left aligned first and then the source of the entry right aligned in blue.
You could do that like this:

```lua
format_entry = function(entry)
return {
-- The first section with the two chunks for the label and the icon
{ { entry.label .. " ", "MyRedHlGroup" }, { entry.kind, "HighlightKind" .. entry.kind } }
-- The second section for the source
{ { entry.source, "MyBlueHlGroup" } }
}
end,
alignment = { "left", "right" }
```

Notice that there are multiple differences between having one table containing the chunks for the
label and kind and having them separately. The latter would require another entry in the `alignment`
table. It would also change the style of the menu because the left sides of the icons would be
aligned at the same column and not be next to the labels. In the example there also was some
spacing added in between the two.

## Documentation view

This configuration allows you to configure the documentation view.
It consists of some basic window properties like the border and the maximum height of the window.
It also has a field to define the character used for the scrollbar.

## Type Icons

This is a table which defines the different icons.
210 changes: 210 additions & 0 deletions docs/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
---
title: Design
description: Design of care.nvim
author:
- max397574
categories:
- docs
---

# General

There is the [care.nvim](https://github.com/max397574/care.nvim) plugin. This is
the main module of the whole completion architecture. Then there are also sources, which is where
the core gets it's completions from.

## Care.nvim

This is the core of the autocompletion. From here the sources are used to get completions which
are then displayed in the [Completion Menu](#completion-menu)

### Completion Menu

The completion menu displays the current completions.
Features that it should have:

- Completely customizable display for every entry (with **text-highlight chunks** like extmark-api)
- Customizable scrollbar
- Customizable window properties
- Border
- Max height
- Docview
- Customizable
- Try to get nicely concealed like in core or noice.nvim
- Allow to send to e.g. quickfix or copy

# Terms

## Offset

Offset always describes the distance between e.g. the start of an entry from the beginning of the
line.

# Architecture

TODO: fancy ascii diagramms

autocompletion:

1. `TextChangedI` or `CursorMovedI`
2. get the context (line before, cursor position etc)
3. Check if context changed
4. Check if character was a trigger character or completion was triggered manually
5. Depending on ^^ decide what to do _for every source_:
- Get new completions
1. get completions from source based on context
- sort completions
1. Use characters found with `keyword_pattern` to fuzzy match and sort completions
6. Collect all the completions
7. Open menu to display thing
1. if there is a selected one:
- highlight selected one
- show preview of selected completion
- show docs

When completing (e.g. `<cr>`):

1. check if menu is open
2. check if anything is selected (or autoselect option)
3. complete
1. insert text
2. additional text edits (check core functions)
3. snippet expansion (core or luasnip)
4. close menu

# Motivation

## Nvim-cmp

These days nvim-cmp is the most popular completion-engine for neovim. There are some mayor issues
me and also other people in the community have with cmp.

### Bad code/Documentation

The code of nvim-cmp is often quite unreadable. Sometimes this might be due to optimizations
and surely some of it has just grown historically. Also there are nearly no docs on how the
whole completion engine works. The api for new sources is quite unclear and far from optimal.
While this doesn't really matter to a user it definitely does to a potential contributor and
developers of sources.

### Legacy code/features

There are a lot of things which grew just historically. The author of nvim-cmp is
(understandable to a certain degree) afraid of making breaking changes and fixing them or just
doesn't think changes are necessary.

#### Configuration of item display

One such example is the configuration of how items are displayed in the menu. This works with
a function `formatting` which takes a completion item and is allowed to return an item where
the three fields `menu`, `kind` and `abbr` and three more fields for highlights for those can
be set. So apart from the background and border color of the menu you're limited to have three
different fields and colors in your menu E.g. source name, kind name, kind icon and text isn't
possible. It's also not possible to have round or half blocks around icons because you don't
have enough colors. An example of an issue can be found [here](https://github.com/hrsh7th/nvim-cmp/issues/1599).
You also can't add padding wherever you want and you can't align the fields as you want.

#### Legacy code

There is e.g. the whole "native menu" thing laying around in the codebase. Nowadays this isn't
really needed anymore. Everything of it can be accomplished with the "custom menu". There is a
lot of duplicate code because of that.

### Mapping system

The mapping system is quite confusing. It's a table in the config with keys to be mapped as keys
and a call to `cmp.mapping()` with a callback to the actual functionality as value.
Users should able to just use normal mappings or functions with `vim.keymap.set`.

### Custom solutions for builtin functionality

An example for this is the [Mapping system](#mapping-system). Another example would be the `cmp.event.on`
which could just be done with User autocmds.

### Why not contribute?

The maintainer is in general quite conservative. There were pull-requests for many features open
which were liked by the community (seen by reactions and comments). But they were abandoned
because the maintainer saw no reason to add it. There was for example a pull-request to fix the
issue with the limited fields in the configuration [here](https://github.com/hrsh7th/nvim-cmp/pull/1238).
This pull request was closed because _No specific use cases have emerged at this stage._
according to the author. Even though there was clearly a problem described and what the pr would
allow (this pr allowed custom fields which still isn't nice but fixed the obvious problems).
There were also some features (in particular the custom scrollbars) removed because there were
some issues with it which apparently weren't worth fixing for the feature.
So it's not really motivating to try to contribute new things. It's also quite hard because of
the messy code with lots of legacy code.

# Goals

## Use nvim-cmp sources

We should be able to use nvim-cmp sources. This should be possible by adding a `package.loaders`
where we can redirect calls to `cmp.register_source` (which happens in most sources auto-
matically) to our own plugin. We **don't want to adapt to cmp's apis** for this though. We won't
extend our own formats e.g. for entries or sources to match cmps. Even when it's complicated we
will just convert between the different formats.

## Native things

Use as many native things as possible. This includes setting mappings with `vim.keymap.set` or
add events as user autocmd events.

# Non-Goals

## Different views

Nvim-cmp has different views. At the moment wild-menu, native menu and custom menu. There is a
lot of code duplication because of this. We'd like to avoid having multiple views. The native
one isn't needed anyway (it likely is just in cmp for historical reasons).
In the future we'd like to allow injecting custom views via config where you just get the
entries and do things with them yourself. This is mostly to avoid code duplication in core.

## Commandline completion

At the moment no command line completion is planned. This is because the author thinks it's not
really needed because builtin completion is already quite good and there is little value added
by adding commandline completion. Also it doesn't really make sense in my opinion to combine
commandline completion and autocompletion for buffer contents in the same plugin. Especially if
you try to share things in between like nvim-cmp does.

# Types used

The types should minimally be the lsp things (for the context passed to source, for response and
for entries). Everything additionally is mostly optional.

# Code style

## Object-Orientation

Most of the modules are written object oriented. This decision was made because it's way easier
to create new instances of the things and associate data with them.

## Functions

You should always write functions in the form of `[local] function <name>(<parameters>)` as
opposed to `[local <name> = function(<parameters>)`. The first notation provides the advantage
that you can directly jump to it's definition and you won't get multiple results (the name and
the anonymous function).

## Comments and annotations

Add annotations to **every** public function of a module (e.g. with neogen) and add comments
explaining what the code does. We'd like to have code which would be understandable for outsiders.
Also try to add annotations and descriptions to local functions but this isn't as important as
public ones

### Format

For The annotations we use [LuaCATS](https://luals.github.io/wiki/annotations/) style. For types
don't use a space after the `---` marker. For comments you should. Check the annotations in
`lua/care/types/` for examples.

## Types

We have files for types which are tangled from a norg file (this one?) using lua-ls annotations.
They are prefixed with `care.`.
As often as possible we should try to use the `lsp.*` types which are in neovim core.

The types are documented in the `docs/` folder and are tangled to lua type files with [neorg](https://github.com/nvim-neorg/neorg).
So if you want to change a type annotation you should change the `.norg` file and tangle it again.
52 changes: 52 additions & 0 deletions docs/dev/context.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Index
description: Type description of context
author:
- max397574
categories:
- docs,
- types
---

This is a class representing the current state. It includes buffer number and cursor position. It
is passed to completion sources to get completions.

# Methods

## Changed

Whether the context changed in comparison to the previous one. This is used to check whether to
get new completions or not.

## New

Create a new context. This takes the previous one as argument. This one is stored to determine if
the context changed or not when completing.
The previous context of the previous one is deleted so this data structure doesn't grow really
large.

# Fields

## Previous

The previous context which is used to determine whether the context changed or not.

## Cursor

The cursor positon.

## Bufnr

Number of the buffer.

## Reason

Reason for triggering completion.

## Current line

The current line.

## Line before cursor

Part of the current line which is before the cursor.
Loading

0 comments on commit b4e6163

Please sign in to comment.