Instantly share code, notes, and snippets.
Save BlueDrink9/474b150c44d41b80934990c0acfb00be to your computer and use it in GitHub Desktop.
This is a drop-in adapter layer for vim-plug and lazy.nvim, allowing you to have acore set of vim plugins, configured with Plug, which will also be loadedusing lazy.nvim instead whenever you use neovim (alongside any additional set oflazy.nvim plugins you have configured.)
It works by adding a new commandPlugin
as a drop-inPlug
replacement.That calls a function that sets up lazy.nvim specs for the equivalent Plugargs, and stores them in a variable that you can then add to your lazy spec.
It also:
- Installs plug if you are in vim, lazy.nvim if you are in neovim.
- Allows these extra lazy load arguments compared to Plug:
event
,afterLoad
(if using nvim, will convertto lazy.nvim'sconfig
, i.e. runs after plugin is lazyloaded). - Adds the 'dependencies' option to Plug, for simple delcarations of additional plugins.
This script prioritises neovim in terms of performance - where converting orextra code could be added for only one or the other, vim / vim-plug isalways given the extra load.
First, find and replace all instances of "Plug '" in your config with 'Plugin'.
Ensure these lines exist in your lazy config:
require("lazy").setup({root=vim.g.pluginInstallPath,-- share plugin folder with Plugspec= {...LazyPlugSpecs, }})
Then add this to your .vimrc, around where you have your vim-plug setup.
letg:pluginInstallPath="~/.vim/plugins"" First source this gist:source"plug_lazy_adapter.vim"if!has('nvim')callplug#begin(g:pluginInstallPath)endif" uses default config function namePlugin'machakann/vim-sandwich', {'keys': ['ys','ds','cs'],\'afterLoad':v:true}function!Plug_after_vim_sandwich()runtime macros/sandwich/keymap/surround.vimendf" Custom afterLoad functionPlugin'https://github.com/benknoble/vim-auto-origami', {\'on':'AutoOrigamiFoldColumn',\'event': ["CursorHold","BufWinEnter","WinEnter"],\'afterLoad':'PluginAfterAutoOrigami'}function!PluginAfterAutoOrigami()au myPluginsCursorHold,BufWinEnter,WinEnter* AutoOrigamiFoldColumnendf" Keys will do nothing in vim, but will create lazyLoad keys for lazy.nvim.Plugin'wellle/targets.vim', {\'keys':MakeLazyKeys({\'n': ['[',']'],\'ov': ['i,','a','I','A'],\})}letg:vim_shell_plug_args= {'dependencies': ['xolox/vim-misc']}ifhas('nvim')letg:vim_shell_plug_args['event']='VeryLazy'endifPlugin'https://github.com/xolox/vim-shell',g:vim_shell_plug_argsif!has('nvim')callplug#end()elseluarequire("config.lazy")endif
Finally, copy in this adapter script to your config:
Note: The latest version of this script, if any updates haven't propagated to the gist, residesin my dotfiles (permalink)
" This command is your main interface to the plugin:" args: anything vim-plug supports in its extra options, plus:" * afterLoad: the name of a vimscript function to run after the plugin" lazy-loads." * event: list of autocmd events that the plugin should lazy-load on" * Any other lazy.nvim spec config options that don't have a Plug alternative" (Note, for `keys`, modes are only supported via the special MakeLazyKeys" function.)command!-bang -nargs=+Plugincall<sid>PluginAdapter(<args>)function!GetPluginName(pluginUrl)" Get plugin name out of a plugin spec name/url. Fairly simplistic, so" don't include .git at the end of your urls.returnsplit(a:pluginUrl,'/')[-1]endfunction" Define function to check if a plugin is added to the manager." Accepts only the last part of the plugin name (See GetPluginName())." Usage: IsPluginUsed('nvim-treesitter')ifhas('nvim')lua IsPluginUsed=function(name)returnrequire("lazy.core.config").plugins[name] ~= nilendendiffunction!IsPluginUsed(name)ifhas('nvim')returnhas_key(s:plugs,a:name)elsereturnhas_key(g:plugs,a:name)endifendfunction" To remove a Plugged repo using UnPlug 'pluginName'function!s:deregister(name)" name: See GetPluginName()tryifhas('nvim')callremove(s:plugs,a:name)returnelsecallremove(g:plugs,a:name)callremove(g:plugs_order,index(g:plugs_order,a:name))endif" strip anything after period because not legitimate variable.letl:varname=substitute(a:name,'\..*','','')letl:varname=substitute(l:varname,'vim-','','')exec'let g:loaded_' .l:varname .' = 1'catch/^Vim\%((\a\+)\)\=:E716:/echom'Unplug failed for' .a:nameendtryendfunctioncommand! -nargs=1-bar UnPlugcalls:deregister(<args>)ifhas('nvim')lua << EOF-- Allow makingakeys table with modesfor Lazy.vimin vimscript-- Expectsadictionary wherekeys areastring of modesandvalues are--alist ofkeys.-- usage:addpluginopt:--Plugin'abc/def', {'keys':MakeLazyKeys({--" \ 'n': ['[', ']'],--" \ 'ov': ['i,', 'a', 'I', 'A'],--" \ })}-- Returnsaluafunctionfor settingupa lazykeys spec. Needtoreturna--function because can'treturna mixedlist/dict tablein vimscript. MakeLazyKeys=function(args)returnfunction() localret= {}for modes,keysinpairs(args)dofor _,keyinipairs(keys)do modesT= {}fori=1, #modesdo modesT[i]= modes:sub(i,i)end table.insert(ret, {key,mode= modesT})endendreturnretendendEOFfunction!MakeLazyKeys(args)returnluaeval('MakeLazyKeys(_A[1])', [a:args])endfunctionelsefunction!MakeLazyKeys(args)return []endfunctionendif" Passes plugin to a lua function that creates a lazy.nvim spec, or to a vimscript" function to adapt the args for vim-plug.function!s:PluginAdapter(...)letl:plugin=a:1letl:args= {}ifa:0==2letl:args=a:2endififhas('nvim')" Has to be global so lua sees itletg:__plugin_args=l:argsexec'lua PlugToLazy("' .l:plugin .'", vim.g.__plugin_args)'lets:plugs[GetPluginName(l:plugin)]=1elsecallPlugPlusLazyArgs(l:plugin,l:args)endifendfunctionifhas('nvim')lets:plugs= {}lua << EOFLazyPlugSpecs= {}-- Compatibilityfunctionto convertvim-plug's Plugcommandto lazy.nvim specfunctionPlugToLazy(plugin, opts)-- Build lazyplugin spec, converting anyvim-plugoptions. local lazySpec= {}if opts then lazySpec= opts lazySpec.ft= opts["for"]-- lazySpec.for= nil lazySpec.name= opts["as"] lazySpec.as= nil lazySpec.cmd= opts["on"] lazySpec.on= nil lazySpec.version= opts["tag"]if opts['afterLoad'] then lazySpec['config']=function()-- Eithercall the default afterLoadfunction...if opts['afterLoad']== true thenvim.fn[vim.fn.PluginNameToFunc(vim.fn.GetPluginName(plugin) )]()else--...orcall the specified name.vim.fn[opts['afterLoad']]()endendendif lazySpec.cmd then-- Ensure itisalist/tableiftype(lazySpec.cmd)=="string" then lazySpec.cmd= {lazySpec.cmd}end--<plug> mappings are commands ('on')for Plug, butkeysfor Lazyfork, cmdinpairs(lazySpec.cmd)doifstring.find(string.lower(cmd),"<plug>",1,6) then lazySpec.keys= lazySpec.keysor {}-- Convertplug mappingsforall modes, not just default of'n' table.insert(lazySpec.keys, {cmd,mode={'n','v','o','l'}}) lazySpec.cmd[k]= nilendend-- Remove anyempty cmd tableto prevent lazyload (may beemptyif-- usedto forcea lazy loadin Plug)if not lazySpec.cmd then lazySpec.cmd= nilendendend lazySpec[1]=plugin table.insert(LazyPlugSpecs, lazySpec)endEOFendiffunction!PluginNameToFunc(name)" Convert a plugins name to default function name to use for afterLoad" functions." Has to be a global function so lua can access it.return'Plug_after_' .substitute(a:name,'[\\.-]','_','g')endfunctionfunction!s:installPluginManager()ifhas('nvim')letg:loaded_plug=1lua << EOF local lazypath=vim.g.pluginInstallPath .."/lazy.nvim"if notvim.loop.fs_stat(lazypath) then-- bootstrap lazy.nvim-- stylua:ignorevim.fn.system({"git","clone","--filter=blob:none","https://github.com/folke/lazy.nvim.git","--branch=stable", lazypath })endvim.opt.rtp:prepend(vim.env.LAZYor lazypath)EOFelseifhas('win32')||has ('win64')letl:vimhome=$HOME."/vimfiles"elseletl:vimhome=$HOME."/.vim"endifletl:plugin_manager_dir=expand(l:vimhome .'/autoload')letl:plugin_manager_file=l:plugin_manager_dir .'/plug.vim'lets:plugin_manager_url="https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"if!filereadable(l:plugin_manager_file)exec"silent !mkdir -p" .l:plugin_manager_dirifExecutable("curl")lets:downloader="curl -fLo"elseifExecutable("wget")lets:downloader="wget --no-check-certificate -O"elseechoerr"You have to install curl or wget, or install plugin manager yourself!"echoerr"Plugin manager not installed. No plugins will be loaded."finishendif" Continue installing...echom"Installing plugin manager..."echo""callsystem(printf('%s %s %s',s:downloader,l:plugin_manager_file,s:plugin_manager_url))if!filereadable(l:plugin_manager_file)echoerr"Plugin manager not installed. No plugins will be loaded."finishendifautocmd myPluginsVimEnter* PlugInstallendifendifendfunctioncalls:installPluginManager()" Rest is entirely plug-specificifhas('nvim')finishendiffunction!PlugPlusLazyArgs(plugin,args)letl:plugin_name=GetPluginName(a:plugin)letl:args=a:args" convert lazy args we want to keep when using plugfordepinget(l:args,'dependencies', []) Plugdependfor" Handle hook for after loadletl:func=get(l:args,'afterLoad',v:false)" If 'afterLoad' is v:true, call function based off a default name" convention (the plugin name, with _ replacing . and -). Otherwise" call the function name passed in. Only will be called for" lazy-loaded plugins, so don't use without an 'on' or 'for' mapping." ('keys' gets ignored).ifl:func==v:trueexec'au User' .l:plugin_name .' call' .PluginNameToFunc(l:plugin_name) .'()'elseifl:func!=v:falseexec'au User' .l:plugin_name .' call' .l:func .'()'endifforeventinget(l:args,'event', [])" Removes unsupported events, e.g. VeryLazy.if!exists('##' .event)continueendifcalls:loadPluginOnEvent(l:plugin_name,event)" Add empty 'on' argument to enable lazyloading.if!has_key(l:args,'on')letl:args['on']= []endifendforcalls:removeUnsupportedArgs(l:args) Pluga:plugin,l:argsendfunctionfunction!s:removeUnsupportedArgs(args)" Remove args unsupported by Plugletl:PlugOpts= [\'branch',\'tag',\'commit',\'rtp',\'dir',\'as',\'do',\'on',\'for',\'frozen',\]foroptinkeys(a:args)ifindex(l:PlugOpts,opt) <0" If item not in the list.silent!callremove(a:args,opt)endifendforendfunction" Add support for loading Plug plugins on specific event.function!s:loadPluginOnEvent(name,event)" Plug-loads function on autocmd event." Plug options should include 'on': [] to prevent load before event." name: the last part of the plugin url (See GetPluginName())." event: name of autocmd event" Example:" Plug 'ycm-core/YouCompleteMe', {'on': []}" call LoadPluginOnEvent('YouCompleteMe', 'InsertEnter')letl:plugLoad='autocmd' .a:event .' * call plug#load("'letl:plugLoadEnd='")'letl:augroupName=a:name .'_' .a:eventletl:undoAutocmd='autocmd!' .l:augroupNameexec'augroup' .l:augroupNameautocmd!execl:plugLoad .a:name .l:plugLoadEnd .' |' .l:undoAutocmdexec'augroup END'endfunction
baco commentedJan 14, 2024
Couldn't all this come as a Vim/Neovim plugin itself? I mean, is a lot of code to keep up to date by hand when updates come.
eyalk11 commentedMay 10, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
I very much like it. For some reason I can't load plugins I put in different folders, but not even in plugged.