Here is a representative example of asynchronous list update, and fuzzy searching on the items using scope.vim.
This example spawns a job to obtain a list of files using fd
command. Output of fd
command is checked every 100ms.
import autoload 'scope/task.vim'
import autoload 'scope/popup.vim'
# Helper function: Filter a list of files using fuzzy matching on typed string
# 'lst' represents a list of all files where each list entry is a dict of
# the form {text: filename}
# 'prompt' string is what the user typed so far
def FilterItems(lst: list<dict<any>>, prompt: string): list<any>
if prompt->empty()
# when nothing is typed display all files in the popup window
return [lst, [lst]]
else
var pat = prompt->trim()
var matches = lst->matchfuzzypos(pat, {key: "text", limit: 1000})
# return both the original list and filtered list
return [lst, matches]
endif
enddef
def FindFile()
# create the popup object
var menu: popup.FilterMenu
menu = popup.FilterMenu.new("File", [],
(res, key) => {
exe $"e {res.text}"
},
null_function,
FilterItems)
# create async job object
var job: task.AsyncCmd
job = task.AsyncCmd.new('fd -tf --follow'->split(),
(items: list<string>) => {
# this function is called periodically as new file names are received
if menu.Closed()
job.Stop()
endif
var items_dict: list<dict<any>> = items->mapnew((_, v) => {
return {text: v}
})
if !menu.SetText(items_dict, FilterItems, 10000) # stop after 10000 files (for example)
job.Stop()
endif
})
enddef