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
    Commented 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(). Commented 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). Commented 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! Commented 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
    Commented 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()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.