I have been using Emacs at work for whole week

Syntax Highlighting isn’t something I find particularly useful personally, I prefer adhoc highlighting. But I will say trying to “parse” syntax with a regexp is a losing proposition. It will always break, at some point I would like to dig into the math of it – but I think the only way to highlight properly is with a real parser. I think at best regexp highlighting is a good “fallback”. I would to see lsp-style parsers emitting syntax highlighting to become the norm.

Syntax Indentation, same problems as above, and something I am simply becoming less worried about as autoformatters rule the day – computers are good at formatting humans aren’t.

Documentation… your point about docstring, declare-option and define-function is really an important one… I wonder if we could make them the primary source of documentation for user commands. Maybe if there was the idea of a so a brief blurb could be displayed with a way to dig into and see more (also would be useful for documentation overlays for code bits). I think this is actually a really great idea, how much of the whole documentation for kakoune could be re-imagined as docstrings? It seems it is already the primary source for many users.

Modes, Packages, Plugins, Extensions, here is where I get concerned. The more complex and integrated the plugins are – the more breakable everything becomes. This is an increasing issue in the Vim world and is already a critical issue in Emacs. Feeling like your editor is unreliable or fickle is scary. I want the opposite of deeper integration, I want more stuff like @alexherbo2’s :connect and light and reasonable integration. Reliable being the core word.

Configuring Emacs, org mode and friends. I definitely do not ever want to pay the org mode tax in my day to day life, I am not personally a fan of org mode. It is indeed a technical marvel (as is Magit) but it isn’t my cup and tea so any motivation derived from it falls on deaf ears with me. Basically, I want brutal simplicity, that is what brought me to Kakoune.

On unloading… you hit on this repeatedly, and I think it really is a fair point and something to nip in the bud before it becomes a more pervasive problem as it did with Vim.

On context… I don’t know about Emacs, but the implementation of contexts in Vim is… inelegant. I can see the value of it, but the complexity cost feels very high to me, I will have to investigate the Emacs way of doing it.

On narrowing, I know myself and @eraserhd want it enough we both have made sort of homebrew implementations of it, but never something that was released (unless I missed it!). Narrowing and better code-oriented navigation is absolutely something I think would be terrific.

On autocomplete… I don’t mind the fact that LSP has to be used to get good semantic autocomplete, I don’t want something that complex to be baked in I don’t think. That said, I understand the reasoning, as my LSP configuration recently has broken a bit and I haven’t put together enough info on it to report it to @ulis – just turned it off!

3 Likes

@robertmeta I think what you mean is composability over extensibility.

1 Like

Indeed, that is a concise way to say it.


I loathe fragility in my editor.

Great additions. I’ll put here some thought on your thoughts that I don’t particularly agree with.

Well, sure, a parser will do the job better, but my old point still valid. There’s no parsers for many languages and may never be. Writing parser is a hard task. Tree sitter is capable to create parsers based on grammar, but afaik it isn’t general enough, and for some languages with obscure syntax it needs to be modified in order to provide a parser.

Regular expression highlighting can be really hard to do, and it can be wrong in some sithuations, but it doesn’t mean we do not have to improve it and work on it. It is the most general way to create a highlighting as of today. Grammars are good, but are the same convoluted as the regexps and can be incorrect too.

Again, a real parser is better, but we may do not have one. And providing some simple mechanics to create indentation rules may significantly improve initial support of the languages. Current situation is really bad and must be improved.

I don’t know what is a critical issue with Emacs, but in my experience there was literally no problems with many packages. About 4 month ago my private configuration of Emacs (that doesn’t go to the github) had around 180 packages and everything was working at its finest.

Vim on the other hand had troubles with 20 packages. Vim is actually the most unpleasant editor to make packages.

That’s what I never felt with Emacs or Kakoune.

I didn’t knew there was a context feature in Vim.

I use spacemacs along with kakoune. If we compare number of open issues, it is:


Though those are completely different editors, but it is very good sign, at least for me, that kakoune’s contributors handle issues with steady pace. When I first started using spacemacs about two years ago, it was roughly the same amount of open issues as it is now.

Yeah, and this is given that fact that spacemacs is 1 year younger than Kakoune (It was started in 2012), mind you! But I’m afraid that spacemacs simply far more popular than kakoune, that’s why there are so many issues. Sure, Kakoune is simpler in design, so may be there will not be such issues like in spacemacs, but still I think if Kakoune will get this kind of popularity, @mawww wouldn’t be able to maintain fill list of issues all by himself.

Regarding minor modes, I still plan to implement them as shared scopes. Currently we have global/buffer/window scopes, I would like to add support for declaring scopes, in which we can put everything a scope can contain (aliases, option values, highlighters…), so that we can just group-up language support/plugins inside a scope, and enable/disable it by “linking” it into one of global/buffer/window scope.

That would generalize the current “shared” highlighter support, and make enabling disabling those modes/scopes uniform (:link-scope window cpp, :unlink-scope window lsp…).

This would also remove the need for cleanup commands (like the ones removing the hook groups from the window), as that would be taken care of automatically by unlinking the scope.

12 Likes

@andreyorst Thanks for this post.

Well, I came across this post because I am like you, I am trying to move from emacs to kakoune. However, the syntax highlight is making things difficult for me. Actually, I am C/C++ developer, and I am trying to get the same highlight in kakoune as I have it in emacs.
I have noticed that you have started several pull request in github for this issue, I do not know if they all merged to kakoune yet or not but nice work.
Also I have noticed your langauges.kak file to improve the highlighting, it is a great work but still not like emacs. Have you managed to get the same highlight in kakoune for C++ as it is in emacs??

Except I’ve used Kakoune before Emacs :smiley:

No. I’ve gave up on writing regular expressions for various type castings in C++, and I’m actually C programmer, and write C++ occasionally. I have high hopes for tree-sitter, and I wish someone wrote a plugin for Kakoune that uses tree-sitter for highlighting.

I’ve gave up on writing regular expressions for various type castings

That’s actually why I’ve stopped contributing to language highlighters, since I’m incapable of writing such complex highlighter. There’s always some quirks in C++ syntax that drive me crazy. In comparison, highlighting Rust with regular expressions is easy, because syntax forms more or less are have single meaning.

I guess one might port Emacs regular expressions used to highlight C++ to Kakoune regular expressions, but that might violate some license bits though i’m not sure.

IMHO – a plugin that did that would be up there with kak-lsp in terms of very high value.

1 Like

I actually wish Kakoune could use grammars instead of regular expressions.

1 Like

Kakoune is not limited to regular expressions, regions highlighters do provide already some ways to define complex grammars (although not as expressive as EBNFs). There is a fine balance between correctness, ease of use (especially in ad-hoc cases), tolerance to invalid states, and performance. grammars are the best for correctness, but are not great for all the others.

can we update multiple region highlighters on every keypress without noticeable lag?

It should be mostly fine except in pathological cases, region highlighters apply their regexes by-line so that they can just re-parse the modified lines when needed. This means in the most common case (1 line modified every keypress), region highlighters are very quick (I think they run in log-n time with n the number of matches for the delimieters).

They do use a lot of memory though, as they store all the candidate delimiter positions.

I’m asking because tools like tree sitter provide coordinates. This code:

fn foo(x: i32) {
    println!("x is {}", x);
}

Produces such tree in tree-sitter’s playground:

source_file [0, 0] - [3, 0])
  function_item [0, 0] - [2, 1])
    name: identifier [0, 3] - [0, 6])
    parameters: parameters [0, 6] - [0, 14])
      parameter [0, 7] - [0, 13])
        pattern: identifier [0, 7] - [0, 8])
        type: primitive_type [0, 10] - [0, 13])
    body: block [0, 15] - [2, 1])
      macro_invocation [1, 4] - [1, 26])
        macro: identifier [1, 4] - [1, 11])
        token_tree [1, 12] - [1, 26])
          string_literal [1, 13] - [1, 22])
          identifier [1, 24] - [1, 25])

On every keypress code is being reparsed by tree-sitter down the tree from modified leaf and coordinates change. We should update all changed region highlighters. If we could do so on every keypress we could have very nice highlighter with tree-sitter. There’s plugin already that uses tree-sitter to provide structural selections by @ulis, but I believe it doesn’t re-parse on every keypress, am I right?

It doesn’t on every keypress but it does on every tree-* command invocation. This plugin is stateless and doesn’t leverage incremental parsing.

However I use it to highlight scopes which means it’s called and does re-parse on NormalIdle and I didn’t notice any problems with it, tree-sitter is fast enough even in non-incremental mode for my case.

Here is interesting talk about Xi editor design. Its author mentions that syntax highlighter is regex based and acknowledges that it’s probably not the best technique.

This is a nice talk. What stood out for me is JSON RPC syntax highlighters, which might be something we could use.

I think that ultimate goal should be not just syntax higlighting, but editor understanding the code. Indentation, folding, and syntax are close friends. Local variable highlighting can be based on syntax tree as well, and so forth. Emacs does this for several languages and I find it super convenient.

We do have tree based highlighting using the region and group system, I am conflicted about exposing this outside of highlighting. It would solve some issues but greatly complexify the mental model of Kakoune commands (if we decide that text objects need to start/end in the same region type).

Improving the design of the region system to make it easier to express grammars would be worthwhile though.

3 Likes