0

I am trying to write a completion function which has as its source a 386k line (CSS) file.

Initially I read the file into a list with readfile() and used a for loop to iterate over each line, matching it against the base text. This worked but took about 5-7 seconds. (readfile() was very quick; the time was spent in the loop.)

I couldn't see a way to speed that up so instead I tried loading the file into a buffer and using search() to find the matches. I coded it up with a hardcoded string pattern and it was very fast - a few hundred milliseconds at most.

So then I tried using that in my completion function but ran into a problem. To search the big file I switch to its buffer, do the search stuff, then switch back to the previous buffer. But during insert-mode completion it is not allowed to switch buffers.

Is there a way to run commands or a function in a hidden buffer without switching to it?

5
  • Seeing your actual code would help but, from your description, I am wondering if using a :for loop wouldn't be the cause of your problems. Would :help filter() be better?
    – romainl
    Mar 8, 2023 at 14:32
  • The difficulty with filter() is that I want to match CSS class names and also extract the properties for those class names. That's tricky with filter(). Mar 8, 2023 at 15:57
  • I just tried pre-processing the file into a dictionary and then when autocompleting looping over they dictionary's keys looking for matches. It's fast enough (although the one-off pre-processing still takes 5-7 seconds). Mar 8, 2023 at 15:58
  • 1
    @romainl I'm now pre-converting the file to JSON and json_decode()-ing it in Vim which is very fast. For searching I'm using filter(), as you suggested, on the keys and it is fast. Thanks! Mar 9, 2023 at 15:07
  • 1
    Cool. You should consider posting your solution (or a minimal version of your solution) as an answer.
    – romainl
    Mar 9, 2023 at 15:38

1 Answer 1

1

I sped this up by pre-converting the CSS file to JSON. Vim is fast at reading and decoding JSON:

let css = readfile('myfile.json')->join('')->json_decode()

To search for keys matching a prefix, I did this:

let keys = keys(css)
        \ ->filter({_, v -> stridx(v, prefix) == 0})
        \ ->sort()

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .