nim-lang / nim-mode

An emacs major mode for the Nim programming language
137 stars 46 forks source link

Nim-mode doesn't highlight functions as font-lock-function-name-face #217

Open ogdenwebb opened 5 years ago

ogdenwebb commented 5 years ago

An example of nim-mode highlighting.

emacs-nim-mode

Go-mode behaviour in Emacs, also I notice VS Code has similar highlighting in nim files.

emacs-go-mode

krux02 commented 5 years ago

In many languages it is pretty easy to determine what a function is with a regular expression. In Nim this is not the case. For example in a.b a could be a package and b a function. a could be an object and b a member or a could be an object and b a function.

In a(b), a could be a function, a template or a macro.

Since highlighting is based on regular expressions, do you want every identifier before an open brace highlighted as a function name?

ogdenwebb commented 5 years ago

do you want every identifier before an open brace highlighted as a function name?

Probably we can do this, because there's nimsuggest-show-doc to describe a kind of object.

Since highlighting is based on regular expressions, do you want every identifier before an open brace highlighted as a function name?

Well, I don't know enough about Emacs syntax highlighting, but emacs-lisp has the same syntax for macros and functions, i.e. (identifier [args]), but Emacs treat a macro as keyword and a function as functions(in terms of the font-lock faces).

js2-mode treats identifier.x without brackets as js2-object-property and identifier.x() as js2-function-call. Ugh, I know that won't fit well into nim uniform function call syntax.

krux02 commented 5 years ago

syntax highlighting in emacs works search based. Search can be a regular expression or a custom search function written in elisp. And everything the function/re matches on is highlighted in the given theme. Emacs lisp has the advantage that identifiers of functions are global names with unique names, and the emacs lisp vm is right there. So whenever the search encours an identifier, emacs can just ask the vm: "what does this function symbol hold? Is it a marco?". The name is enough here. This does not work in Nim. An indentifier is almost never enough to even ask what that symbol means. This is very context dependent here. And communication between nimsuggest and Nim is often the cause for emacs to freeze (there is a lot of potential for optimizations).

yuutayamada commented 5 years ago

I think js2-mode has own js parser of emacs-lisp and that's why they can highlight like that. I don't think we can mimic that unless someone contributes super hard. I think nimsuggest way might work (there is highlight option to query to nimsuggest, and there is a way to highlight like flycheck or flymake), but nimsuggest doesn't work if the file is too big due to that EPC (message protocol for current nimsuggest-emacs) has limit to send the data even if someone made the package for emacs.

zetashift commented 4 years ago

Is there anyway this is still doable? A nimsuggest way would not be possible 'cause that slows Emacs down no?

krux02 commented 4 years ago

@zetashift sorry for the late reply, I just get way too many notifications and sometimes they bury deep. I would not rule out a nimsuggest solution entirely, I think it can work. Emacs can handle multiple layers of highlighting with some attributes overriding others. So regular expression highlighting would be the initial fast highlighting and nimsuggest is called later to generate the correct but slow highlighting. But it should be implemented in non blocking way. The problem is, I don't know how to guarantee non blocking nimsuggest integration. Current nimsuggest integration is far from non-blocking, that is the reason I have it permanently disabled.

zetashift commented 4 years ago

@krux02 no problem! I kinda figured you'd be busy a lot anyway and a lot of people I know have notification floods. I have nimsuggest disabled too because of: https://github.com/nim-lang/nim-mode/issues/227 Simple regex-based highlighting might be ideal for now. I've been wondering if it might be better to improve nimlsp and hook it up to lsp-mode or eglot.

krux02 commented 4 years ago

Maybe LSP is the better approach. On the other hand. I don't understand why the nimsuggest integration is so horribly complicated. I think it should be thrown away and written from scratch, but in a simpler more maintanable codebase. Unfortunately I can't do that right now.

zetashift commented 4 years ago

Would rewriting nimsuggest integration be better than contributing to nimlsp? I feel like rewriting nim-suggest.el might be a bit too big of a hurdle.

Also yeah time is limited :)

krux02 commented 4 years ago

Honestly I don't know what the better plan is. From the theoretical complexity, both emacs-nimsuggest and lsp-nimsuggest should be equal amount of complexity. And don't take current implementation as a reference for complexity. I think it is totally over engineered and over complicated. Throwing it away and writing it from scratch should be faster and simpler than trying to figure out what the current implementation does.