neodev.nvim icon indicating copy to clipboard operation
neodev.nvim copied to clipboard

`vim.fn.getline()` does not accept strings

Open chrisgrieser opened this issue 2 years ago • 6 comments

get line currently only seems to accept a number as parameter, even though certain strings should also be accepted.

Pasted image 2022-11-27 21 38 29

chrisgrieser avatar Nov 27 '22 20:11 chrisgrieser

also, getline() should return a string (or list), not any. This cursor string methods such as ":find()" to also be marked as problems by the lsp Pasted image 2022-11-27 21 41 45

chrisgrieser avatar Nov 27 '22 20:11 chrisgrieser

The same seems to apply to append(), indent(), and setline().

line(), however, seems to correctly accept strings like "."

chrisgrieser avatar Nov 27 '22 20:11 chrisgrieser

The annotation are automatically generated based on available info. There's just no correct info available for those methods

folke avatar Nov 28 '22 15:11 folke

The annotation are automatically generated based on available info. There's just no correct info available for those methods

How is the info extracted? Directly from nvim docs? as far as I can see, those doesn't have any annotation info, so are you extracting it from some other place?

danielo515 avatar Dec 19 '22 08:12 danielo515

multiple sources. check the code.

folke avatar Dec 19 '22 08:12 folke

Okay, I have looked into this. If I understand neodev correctly, it guesses argument types of vim functions by the argument name. vim.fn.getline and many more functions take an argument called lnum (a line number). neodev assigns the number type to all lnum arguments.

Neodev gets the function list from :h builtin-function-list. In this list, there are 26 functions, that have an lnum argument:

append appendbufline cindent cursor diff_filler diff_hlID foldclosed foldclosedend foldlevel foldtextresult getbufline
getbufoneline getline getline indent line2byte lispindent nextnonblank prevnonblank screenpos setbufline setline synID
synconcealed synstack virtcol2col

I have checked the vimdocs for all of them. The getline function accepts strings for lnum (as is mentioned in the original issue). These functions refer to getline for the usage of the lnum argument:

append cindent cursor diff_filler diff_hlID foldclosed foldclosedend foldlevel foldtextresult indent line2byte
lispindent nextnonblank prevnonblank setbufline setline synID synconcealed synstack

These ones don't refer to getline, but they mention, that they accept "$" as lnum.

appendbufline getbufline getbufoneline

getbufline also accepts a "$" in its end argument, but I'm not sure whether end can be a string elsewhere.

These ones don't accept a string as an lnum argument at all:

screenpos virtcol2col

So, the point is that it's not that there isn't correct info available, it's just not possible to know the type of lnum just by looking at :h builtin-function-list.

Looking through code, I found out that the detailed documentation is already being parsed, so it is possible to detect, whether the doc contains information about how the lnum arg can be used. I have prepared a patch as a POC: https://github.com/syyyr/neodev.nvim/tree/detect-lnum-string The detection algorithm is very simple, and could use a lot of improvements.

I have enabled the CI job, that updates the types on my fork. With the updated types, these functions now take strings for lnum arguments:

append appendbufline cindent diff_filler diff_hlID foldclosed foldclosedend foldlevel foldtextresult getline indent
line2byte lispindent nextnonblank prevnonblank setbufline setline synID synconcealed

Some functions like cursor were unfortunately not recognized. It seems that it's because neodev doesn't find the overload with the lnum argument. This isn't a problem of course, since lnum was never recognized.

The second type of lnum functions are a little bit harder to detect, and I couldn't think of a simple way to do it.

The third type functions' signatures are unchanged.

syyyr avatar Dec 23 '22 04:12 syyyr