Git Product home page Git Product logo

vim-maktaba's Introduction

Maktaba is a vimscript plugin library. It is designed for plugin authors. Features include:

  • Plugin objects (for manipulating plugins in vimscript)
  • Plugin flags (used to configure plugins without global settings)
  • Universal logger interface
  • Dependency management tools
  • Real closures

Maktaba advocates a plugin structure that, when adhered to, gives the plugin access to many powerful tools such as configuration flags. Within Google, these conventions standardize behavior across a wide variety of plugins.

Also contained are many utility functions that ease the pain of working with vimscript. This includes, among other things:

  • Exception handling
  • Variable type enforcement
  • Filepath manipulation

Usage example

Maktaba plugins can be installed using any plugin manager. However, maktaba plugins make heavy use of dependency management, so it's recommended to use a plugin manager with dependency management capabilities, like VAM.

Installation of a few plugins using VAM looks something like

set runtimepath+=~/.vim/bundle/vim-addon-manager/
" Loads glaive, vtd, and their maktaba dependency.
call vam#ActivateAddons(['glaive', 'vtd'])
" Initializes all maktaba plugins.
call maktaba#plugin#Detect()

Plugins Using Maktaba

Several vim plugins are already using maktaba. As a user, you can generally expect these plugins to be configurable using Glaive and be more well-behaved in terms of things like defining unwanted global mappings and variables and avoiding annoying side-effects like moving your cursor.

Plugin authors should consider developing plugins using maktaba to simplify code, support modular plugins with hassle-free dependency management, and avoid common pitfalls. If you've written a plugin using maktaba, please add it to the list above and share feedback.

Further reading

In the vroom/ directory you'll find literate test files that walk you through maktaba features in depth. vroom/main.vroom is a good place to start.

In the examples/ directory you can find an example maktaba plugin to give you a feel for how maktaba plugins look.

In the doc/ directory you'll find helpfiles for maktaba. These are also available via :help maktaba if maktaba has been installed and helptags have been generated. The help files document the maktaba API in its entirety.

vim-maktaba's People

Contributors

ardagnir avatar artasparks avatar blueyed avatar chiphogg avatar dbarnett avatar flwyd avatar glts avatar gregorias avatar malcolmr avatar nelstrom avatar nfischer avatar okkays avatar pavoljuhas avatar rocketdonkey avatar slowki avatar snu5mumr1k avatar stgpetrovic avatar xanderman avatar yilin-yang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vim-maktaba's Issues

Symlinked plugin location results in AlreadyExists conflict

I created the plugin script ~/src/myplugin/plugin/commands.vim with contents

let [s:plugin, s:enter] = maktaba#plugin#Enter(expand('<sfile>', ':p'))
if !s:enter
  finish
endif

and then created a symlink to the plugin's top-level directory like this:

$ ln -s ~/src/myplugin ~/.vim/bundle/myplugin

Now, after starting up Vim I install the plugin using the symlink:

call maktaba#plugin#GetOrInstall('~/.vim/bundle/myplugin')
echo maktaba#plugin#Get('myplugin').location
/home/glts/.vim/bundle/myplugin/

And all is fine. But when I load the plugin call maktaba#LateLoad() I get an AlreadyExists conflict:

Error detected while processing function maktaba#plugin#Enter..maktaba#plugin#GetOrInstall:
line    8:
E605: Exception not caught: ERROR(AlreadyExists): Conflict for plugin "myplugin": /home/glts/.vim/bundle/myplugin/ and /home/glts/src/myplugin/

The reason why this happens seems to be that expand('<sfile>', ':p') in commands.vim evaluates to the actual file location, and /home/glts/.vim/bundle/myplugin/ != /home/glts/src/myplugin/. resolve() to the rescue?

Remove legacy maktaba#system API

We now have a maktaba#syscall API for making system calls using a builder pattern that deprecates the maktaba#system API (which has a messier cross product of options upfront).

We should get rid of the redundant legacy API for the next major version. Maybe we should show deprecation warnings for it for a while beforehand. Haven't decided yet if it's worth maktaba showing deprecation warnings for stuff like this.

Maktaba thinks /var/lib/vim/addons is a plugin

The heuristics in maktaba#rtp#LeafDirs do a fairly good job of detecting what's a plugin-like path and what's not, but I've noticed that it lists /var/lib/vim/addons as a LeafDir and consequently 'addons' gets registered as a plugin by maktaba#plugin#Detect and several other utility functions.

Probably not worth worrying much over (may even be correct behavior), but it feels weird. As far as I can tell, the only difference it makes is that :Glaive tab completion lists 'addons' as a configurable plugin.

Implement a hook for "filetype known"

If a plugin wants to have configuration based on a buffer's filetype, it turns out to be tricky to handle if you need to explicitly handle the case where filetype wasn't set. You can use "autocmd FileType", but that will never fire for a new buffer with no filetype, and can fire multiple times for a single new buffer if autocmds are overriding filetype on each other.

It would be useful to have a hook for code that needs to read the 'filetype' setting and expects it to already be valid even for no-filetype buffers. This hook should fire:

  • Once after all filetypedetect autocmds have fired (i.e., after the last BufRead or BufNewFile autocmd).
  • Any time the filetype changes afterwards.
    This should avoid firing multiple times for the same event if autocmds set and then override the filetype (especially for the initial filetype detection, but also for later events if possible).

Ideally, this would be implemented inside vim, and might be tricky or impossible to implement properly in maktaba, but it's worth discussing.

Plugin canonical name: drop the 'vim-'. It's cleaner.

A wide plurality of vim plugins on github (including pretty much everything from tpope) begin with the vim- prefix. The directories inherit this name by default, and maktaba gets the plugin name from the directories. This means that vtd becomes vim_vtd; unimpaired becomes vim_unimpaired; etc.

The vim- prefix makes some sense on github, but very little sense inside my ~/.vim/bundle/ directory, where it's pretty safe to assume everything is somehow vim-related. I propose that maktaba should disregard any leading vim- character sequence.

Normally, I don't like special-cased rules like this one. But in this case, I think the practical benefit would be worth it.

I'm planning to put together a pull request for this.

Plugin may be installed twice when symlinked

More trouble with symlinks, is it #18 (and #23) coming back to bite us?

Setup any Maktaba plugin as a symlink with a basename different from the target basename, then #GetOrInstall it in the vimrc.

$ git clone git://github.com/google/glaive.git ~/code/google-glaive
$ ln -s ~/code/google-glaive ~/.vim/bundle/glaive
call maktaba#plugin#GetOrInstall('~/.vim/bundle/glaive')

Now after starting Vim, the plugin is installed twice under different names:

:echo maktaba#plugin#RegisteredPlugins()
['maktaba', 'glaive', 'google_glaive']

The reason seems to be that the plugin name is determined from the basename twice, at vimrc #GetOrInstall time, and at #Enter time. The names don't match.

Add a FLAG.AddCallback variant that doesn't fire immediately

If you add a callback to a maktaba flag with FLAG.AddCallback, it will always call your callback immediately with the current value. Sometimes that's not what you want. For instance, you might want to set an initial value and then add a callback to show a warning for all subsequent value changes.

There should be a variant of FLAG.AddCallback that disables the initial call. Something like FLAG.AddCallback({F}, [fire_immediately]).

Need to ensure initial settings are applied before sourcing instant/*.vim

Plugin management code needs to do the following operations in order:

  1. Check if plugin FOO is installed on runtimepath
  2. If not: Fetch plugin, add to rtp
  3. Source instant/flags.vim
  4. Apply initial settings (e.g., !instant[somefile])
  5. Source other instant files

We currently have a problem that checking whether plugin FOO is installed on runtimepath (using maktaba#plugin#IsRegistered or similar) will automatically trigger step 5 before we've had a chance to get to step 4. This is bad because it makes it impossible to disable instant/ files before they're initially sourced.

maktaba#path#MakeRelative returns empty string for CWD

maktaba#path#MakeRelative('/foo', '/foo') returns the empty string.

Even though vim seems to accept the empty string as an alias for '.', it's an error-prone convention and we should make sure maktaba path manipulation functions return an explicit '.' for these cases.

maktaba#syscall drops empty command words

Given a system call like

call maktaba#syscall#Create(['foo', '--bar', '', 'baz']).Call()

maktaba will effectively drop the empty word and call foo --bar baz. This can cause arguments to be misparsed (foo might think "baz" is the value for --bar, not ""), and forces the caller to worry about handling the empty string specially.

We should instead recognize the empty string as not being a "simple" value and render it with literal quotes, like foo --bar "" baz.

What is vroom?

From the project README:

In the vroom/ directory you'll find literate test files that walk you through maktaba features in depth.

I'm reading through the literate test files, which all end in .vroom. I've never encountered this file format before and I'd like to know more about it. Googling 'vroom' turns up a couple of projects that seem unrelated:

  • vim-vroom - a plugin for running Ruby tests
  • Vroom - slide shows in Vim

maktaba#buffer#Overwrite() doesn't seem to validate startline, producing odd results

maktaba#buffer#Overwrite() doesn't appear to validate the startline parameter, contrary to the documentation, and produces odd results when it's out of the documented range. I suggest we add validation as documented, and also explicitly disallow a non-positive startline.

Currently: Given a buffer containing foo\nbar\nbaz, :call maktaba#buffer#Overwrite(startline, 2, ['quux']) has the following behaviour:

  • with startline=1: the first two lines are replaced, giving quux\nbaz.
  • with startline=2: the second line is replaced, giving foo\nquux\nbaz.

Those are exactly as described by the function documentation. The following are not:

  • with startline=3: the text is inserted after the first two lines, giving foo\nbar\nquux\nbaz.
  • with startline>3: the text is inserted after the first three lines, giving foo\nbar\nbaz\nquux.

According to the documentation, those should throw ERROR(BadValue), but they don't appear to do so.

  • with startline=0: the text is inserted after the first two lines, giving foo\nbar\nquux\nbaz.
  • with startline=-1: the second line is replaced, giving foo\nquux\nbaz.
  • with startline=-2: the first two lines are replaced, giving quux\nbaz.
  • with startline=-3: the first line is replaced, giving quux\nbar\nbaz.
  • with startline<-3: the text is inserted before the first line, giving quux\nfoo\nbar\nbaz.

(In case it's not obvious, non-positive startline is effectively being resolved as `line('$') + startline first, and then we're inserting text if startline>endline.)

These are all undefined, and I think should also throw ERROR(BadValue). In particular, the case for startline=0 is pretty unexpected.

(The documentation says that all the insertion cases above should be handled by append(line, ['quux']) instead, which, incidentally, silently fails if line < 0 or line > line('$'), though I could see a benefit in allowing maktaba#buffer#Overwrite(N+1, N, expr) to insert at line N+1, but that would be a change from what we currently document.)

ftplugin files with `maktaba#plugin#Enter()` aren't entered for each scratch buffer

ftplugin files using maktaba#plugin#Enter() currently don't work properly in some corner cases. After opening a scratch buffer, any subsequent scratch buffers won't have the ftplugin activated:

:enew
:setfiletype FOO
:enew
:setfiletype FOO  " <-- doesn't apply the ftplugin

The use of bufnr() in maktaba#plugin#Enter() doesn't quite work as expected, since the buffer number is -1 for any unnamed buffer.

Confusion about plugin name, canonical name, declared name

Suppose I have a plugin named 'cottidie.vim'. I have dutifully created an addon-info.json file with a "name" to match the given name, 'cottidie.vim', which is also the name registered with VAM, and the plugin name on vim.org.

Now, when doing

:echo maktaba#plugin#RegisteredPlugins()

that plugin shows up as cottidie_vim. The same name shows up with glaive autocompletion.

Is this intended?

I recall a discussion (#20) about how it would be prettier to have names without .vim there, for example :Glaive surround .... But now it looks like that would become surround_vim if it had a proper addon-info.json file.

I'll note here that the naming scheme <plugin>.vim is an age-old naming tradition in the Vim plugin community. Many early plugins use it. The upload instructions on vim.org suggest it. Some of the most popular authors keep it alive. And it is nicely parallel to the Emacs convention (I believe) with .el, as in paredit.el.

maktaba#path#GetDirectory behavior needs more thought

maktaba#path#GetDirectory treats nonexistent paths as directories:

echo maktaba#path#GetDirectory('foo/bar/NONEXISTENT')
" --> foo/bar/NONEXISTENT/

Originally we had a variant that assumed files, not directories, but that was deleted. I would argue that assuming files in ambiguous cases is the more intuitive behavior, and we should detect trailing slashes so there's a mechanism to get the alternative behavior in cases where the caller already believes the nonexistent path should refer to a directory.

"Invalid expression" error when parsing settings due to missing comma

Certain types of unparseable flag settings give a gnarly "Invalid expression" error, caused by a missing comma in setting.vim.

For example, :Glaive glaive plugin=foo::bar (note the extra ":") gives the following error:

Error detected while processing function <SNR>21_Glaive..glaive#Configure..maktaba#setting#ParseAll..maktaba#setting#Parse..<SNR>19_ValueParseError:
line    2:
E116: Invalid arguments for function maktaba#error#Message( l:type, 'Could not parse value on setting "%s": %s.' a:setting, l:msg)
E15: Invalid expression: maktaba#error#Message( l:type, 'Could not parse value on setting "%s": %s.' a:setting, l:msg)

Make examples tests run out-of-the-box

Currently, vroom files in examples/helloworld/vroom/ fail out of the box because they can't find maktaba. The standard directions are to make sure maktaba is in a sibling directory to the plugin you're testing, but here it's in a parent directory.

This is particularly annoying since if you try to run vroom on all vroom files in all of your plugins, you'll get failures on just these files.

Speed up maktaba#plugin#IsLibrary

I've noticed some performance problems with maktaba#plugin#IsLibrary and code that calls it like maktaba#library#Import and maktaba#library#Require.

In experimenting with declaring more deps explicitly in all our plugins including a maktaba dep for each, I discovered that ~70 calls to maktaba#library#Import adds ~200ms to vim startup on my system. I tracked it down to our strict library checking and saw it's doing 12 isdirectory() calls each time (checking for 6 non-library dirs and their after/ equivalents).

We should definitely be caching the IsLibrary value after we first check a plugin. Many plugins are going to be depending on maktaba and we don't want to check if it's a valid library more than once. We can probably also get better mileage using glob() to list directories and iterating through looking for non-library dirs rather than iterating through the list of non-library dirs and checking whether each exists.

Follow local-additions convention in doc

Maktaba stands out in the table of contents at :h local-additions.

This is because it doesn't follow the convention documented at :h write-local-help. The first line of the doc is magical and the proper format for it is

*someplug.txt*<Tab>Some cool plug tag line

Point of note:

  • Why is the initial tag *someplug.txt*? It is somewhat of a help idiom that "X.txt" will bring you to the top of a help page. This is what all of Vim's own help files do, and it's the purpose of the shortcuts in local-additions.

On top of that, it frees up the main tag *someplug* to be used where the meat of the doc starts.

I think tpope docs are good examples for this convention.

(doc/maktaba.txt is auto-generated so this is probably the wrong issue tracker, isn't it?)

Bogus plugin entries like "Vim/vimfiles" on Windows

On a new Maktaba installation on Windows 7 the default runtime path directories appear as registered plugins.

:echo maktaba#plugin#RegisteredPlugins()
['Vim/vimfiles', 'Vim/vimfiles/after', 'glts/vimfiles', 'glts/vimfiles/after', 'maktaba']

Apparently the paranoia expressed in this comment is unsubstantiated, forward slashes are not allowed in file names on Windows (and indeed may serve as path separators in APIs).

maktaba#system#Call should accept STDIN value

maktaba#system#Call doesn't support any way of passing STDIN to the process being launched.

Vim's system() accepts an [input] arg. We can maybe hack the foreground case to work by executing something like "echo input | cmd".

First Flag(NAME, VALUE) call always returns 0

PLUGIN.Flag(NAME, VALUE) returns VALUE if the flag already exists, but always returns 0 (vim's default return value) if the flag didn't exist before the call.

Either Flag(NAME, VALUE) should never return a value or it always should. It looks like a mistake that the behavior depends on whether the flag already existed.

Add helpers for command completion

Vim's command completion interface is fine for simple commands, but pretty awkward for more complex commands like :Glaive that can't necessarily base completion just on ArgLead (the last partial arg on the command line), and have to do complex processing on CmdLine using CursorPos and parse out the command name, leading modifiers and whatnot to handle command lines like ": ::4,'XGlaive! …".

Maktaba should include some utilities to bridge the gap between vim's completion interface and what you need to write powerful completion functions easily.

ftplugin files not entered in some buffers

I noticed a bug in maktaba#plugin#Enter where buffer numbers aren't looked up correctly causing ftplugin files to not be entered for some buffers, contrary to the behavior described in vroom/plugincontrol.vroom which says ftplugin files can be entered once per buffer. In fact, plugincontrol.vroom seems to be failing, and AFAICT has been failing since it was originally committed.

We should change the guard behavior in maktaba#plugin#Enter so it correctly guards ftplugin files to be sourced once per buffer.

Consider adding JSON support

In implementing addon-info.json introspection for maktaba, we had to pull some JSON parsing code into maktaba. We might want to move it into maktaba#json and expose it to maktaba users.

Higher precision timestamps in maktaba#log#

We should be able to add sub-second precision by using reltime() instead of localtime() in vim builds with the reltime feature eanbled.

If that turns out to add significant overhead, we could guard it with a setting or have individual log messages opt in to precise timing.

maktaba#plugin#Install('nonexistent/path/') should throw an error

Calling maktaba#plugin#Install('nonexistent/path/') to install nonexistent plugin paths actually succeeds, registering and returning a plugin object:

:echo maktaba#plugin#Install('nonexistent/path/')
{'HasDir': function('maktaba#plugin#HasDir'), 'flags': {}, …}
:echo maktaba#plugin#IsRegistered('path')
1

Seems like it should throw NotFound or something.

Update guidelines to mention vroom

Now that vroom is released, we should mention in CONTRIBUTING.md that people should run it before submitting and possibly document how in README.md or a vroom/README or something.

Add mechanism to save/restore variables

It would be handy to be able to save and restore values from a set of built-in vim variables, including &settings, &l:localsettings, g:globalvariables, $ENVVARS.

It's pretty common for vim plugins to need to save values, do something, and then restore values. This involves a few corner cases, such as unset variables needing to be "restored" back to unset, local settings needing to be reset to the global value, etc.

Should have a maktaba#plugin#Register that doesn't install

We have maktaba#plugin#Install to install a plugin on the runtimepath and register it with maktaba. But that's a fairly heavy operation that should usually be left to plugin managers, and in many cases we just want to make sure a plugin has been initialized with maktaba without affecting the runtimepath. For instance, both maktaba#plugin#Detect and maktaba#plugin#Enter potentially install the plugin on runtimepath, but in both cases we already know it's on runtimepath and #Install only adds the overhead of rtp manipulation and the potential for stomping on things (#49).

We should implement a maktaba#plugin#Register({dir}) that's a more pure maktaba registration/init utility. Instead of installing plugins on runtimepath, it could either throw an error if it detects a plugin isn't installed or just not even check runtimepath.

Better detection for already-active plugins

So far, maktaba has had the model that plugins are registered/activated/initialized through maktaba calls, and then later plugins are looked up in maktaba's master plugin list. That might not be an option anymore when we have plugins installed using a standard plugin manager. Few if any plugin managers have support for executing arbitrary code at plugin activation time.

maktaba#library#Require(), #library#Import(), and probably #plugin#Get() should have the ability to detect any plugins that are already on &runtimepath but not registered via maktaba calls.

We can probably use the presence and/or contents of addon-info.json files to detect whether a given &rtp entry is a plugin or just a miscellaneous runtime dir like ~/.vim/. Of course, we'll want to have some caching to prevent repeatedly scanning the same &rtp entries for addon-info.json files.

Implement function to manually kick off instant/ code

In a few cases, it's useful for plugins to be able to execute code as soon as possible after they're activated. We created an instant/ mechanism in maktaba for these rare cases.

But automatically triggering instant/ code becomes pretty awkward in a world where plugins are installed by a plugin manager that doesn't know about maktaba, and doesn't provide its own way for plugins to execute special instant code at activation time. We could just get rid of instant/ and replace it with setup functions in each plugin, and leave it up to users to call such functions when necessary, but that has some drawbacks:

  • Users have to learn different installation instructions for different plugins.
  • Forgetting to call the setup function can result in strange failures.
  • Updating to a new version of a plugin that suddenly needs a setup function can be a bad experience for users. OTOH, calling a bunch of empty autoload setup functions just in case they're ever needed is unnecessary overhead.

One solution would be for maktaba to continue to support instant/ code, but to expose a function for users to manually trigger any instant/ code in newly activated plugins after all plugins have been activated. This would be less aggressive than maktaba#LateLoad(): it wouldn't force plugin/ files to load, just the instant/ files intended to run at vimrc time.

It might also be useful for maktaba#plugin#Enter() to detect if a plugin has instant/ code that hasn't been triggered, and warn the user to call the maktaba setup function from their vimrc.

Provide polyfill for pyeval

pyeval was added in 7.3.569, and is a much better way of getting the result of a single python statement into a ViM data type than eval(maktaba#command#GetOutput('python print …')). We should provide something like maktaba#python#Eval or maktaba#command#PyEval. http://stackoverflow.com/a/13220941/286583 suggests it look like:

function Pyeval(expr)
    python import json
    python vim.command('return '+json.dumps(eval(vim.eval('a:expr'))))
endfunction

Trailing backslash on Maktaba plugin locations disrupts the 'runtimepath' on Windows

This one's nasty. I couldn't make Maktaba get-or-install Glaive on Windows 7.

call maktaba#plugin#GetOrInstall('~/vimfiles/maktaba/glaive')

The problem is the trailing path separator Maktaba adds before prepending the location to 'runtimepath'. Since on Windows the path separator is a backslash its effect is to escape the following comma.

:echo &rtp
C:\Users\glts/vimfiles,C:\Users\glts/vimfiles/maktaba/glaive\,C:Program Files (x86)\Vim/vimfiles,...

Obviously this results in long, concatenated nonsense paths and no sourcing of plugin files.

Symlinked plugin with addon-info.json "name" may be added to the runtimepath twice

This happens on an old MacVim 7.3, but not on newer versions of Vim.

Create a plugin with an addon-info.json file with an explicit "name", for example ~/code/vim-linked/addon-info.json:

{
    "name": "linked.vim",
    "version": "0.0.0",
    "dependencies": {
        "maktaba": {}
    }
}

Create a symlink to the plugin location, then start Vim with a vimrc that #GetOrInstalls the symlink location. (Here I used locations with different leaf dir names, but the same thing happens when the leaf dir names are the same.)

set nocompatible
source ~/.vim/maktaba/maktaba/bootstrap.vim
call maktaba#plugin#GetOrInstall('~/.vim/maktaba/linked')

Result. &rtp:

~/.vim,
~/code/vim-linked/,
~/.vim/maktaba/linked/,
/Applications/MacVim.app/Contents/Resources/vim/vimfiles,
/Applications/MacVim.app/Contents/Resources/vim/runtime,
/Applications/MacVim.app/Contents/Resources/vim/vimfiles/after,
~/.vim/after,
~/.vim/maktaba/maktaba

:echo maktaba#plugin#RegisteredPlugins():

['linked.vim', 'maktaba']

Include benchmark scripts

Maktaba includes a few performance-critical functions like maktaba#rtp#Add that we try to optimize with caching, etc., but we somehow completely broke the caching at some point and didn't notice. We should add some benchmark scripts to the repo so it's more convenient to check for performance changes.

For example, we want something to start up vim with --startuptime and do some heavy &runtimepath manipulation using maktaba#rtp#Add, maktaba#rtp#Remove and friends.

Add fluent maktaba#ensure#That API

Maktaba has a suite of maktaba#ensure# functions for throwing errors whenever certain conditions aren't satisfied. For instance:

call maktaba#ensure#IsTrue(g:foo)
call maktaba#ensure#IsEqual(5, g:foo)
call maktaba#ensure#IsIn(g:foo, [1, 2, 3])
call maktaba#ensure#Passes(g:foo, 'empty')

The order of arguments is a little arbitrary (I have to look up the order of arguments every time I use them) and is sometimes hard to understand at a glance in vroom tests.

We should consider adding a "fluent" API like the Java Truth library that makes ensure calls read more naturally:

call maktaba#ensure#That(g:foo).IsTrue()
call maktaba#ensure#That(g:foo).Equals(5)
call maktaba#ensure#That(g:foo).IsIn([1, 2, 3])
call maktaba#ensure#That(g:foo).Passes('empty')

We could add a parallel maktaba#check#That API to replace the corresponding maktaba#value# functions if the parallelism is worth the churn.

Maktaba adds itself to the runtime path twice

I used this stripped down vimrc:

source ~/path/to/maktaba/bootstrap.vim
filetype plugin indent on
syntax enable

At startup the 'runtimepath' is

runtimepath=~/.vim,/usr/local/share/vim/vimfiles,/usr/local/share/vim/vim74,/usr/local/share/vim/vimfiles/after,~/.vim/after,~/path/to/maktaba

When I run the first Maktaba command, for example :echo maktaba#VERSION, the runtime path changes to:

runtimepath=~/.vim,~/path/to/maktaba/,/usr/local/share/vim/vimfiles,/usr/local/share/vim/vim74,/usr/local/share/vim/vimfiles/after,~/.vim/after,~/path/to/maktaba

The path to maktaba is now present twice, with and without trailing slash.

At least one negative effect of this is that Maktaba now appears twice in the table of contents at :h local-additions.

This issue might be related to #7.

Messy runtime path after #42

I have been using pathogen.vim which keeps the bundles in the runtime path in glob order. Now after maktaba auto-detection the runtime path is not in order any more.

One side-effect of the random (?) order -- beside it being ugly on the eyes -- is that it makes a mess of the table of contents at :h local-additions.

I wonder if it's really necessary to force detection of plugins on the user. Isn't that a plugin manager's job? At least for me this is an unwelcome change (not that I can't adapt of course).

Curious to hear your thoughts! I'll revert to an earlier version for the time being.

Maktaba added to runtimepath twice when symlinked and installed manually

Minor issue. When using the manual installation procedure described at https://github.com/google/maktaba/blob/master/vroom/manual.vroom, and Maktaba is symlinked, then it is added to the runtimepath twice, once with the symlink location and once with the resolved symlink. See also #31.

Example vimrc:

" ~/.vim -> ~/code/dotfiles/.vim
set runtimepath+=~/.vim/maktaba

Resulting runtimepath is ...,/home/glts/code/dotfiles/.vim/maktaba,.../home/glts/.vim/maktaba.

Plugin name should match "name" from addon-info.json, if present

When we register a maktaba Plugin object for a plugin path, we make some effort to canonicalize it, stripping off any "vim-" prefix or ".vim" suffix and converting special characters to underscores. We should also check for a "name" field declared in addon-info.json and respect any canonical name declared there.

This will help us not be so sensitive to directory names, and also help resolve symlink issues like #31.

maktaba#plugin#Enter() appears not to work from subdirectories

I tried putting the standard maktaba boilerplate at the top of a file called autoload/vtd/view.vim. When I try calling a function from that autoload file, I get the following:

Error detected while processing function maktaba#plugin#Enter..<SNR>8_SplitEnteredFile:
line    3:
E605: Exception not caught: ERROR(CannotEnter): maktaba#plugin#Enter must be called from a file in
an autoload/, plugin/, ftplugin/, or instant/ directory. It was called from %s.
E605: Exception not caught: ERROR(CannotEnter): maktaba#plugin#Enter must be called from a file in
an autoload/, plugin/, ftplugin/, or instant/ directory. It was called from %s.

Looks like subdirectories don't work. Is that intentional?

Also, it would appear the %s is not getting interpolated with the filename.

maktaba#syscall doesn't support newlines properly

The makataba#syscall functions seem to garble newlines you try to pass to them. For example:

:echo maktaba#syscall#Create(['echo', "foo\nbar"]).GetCommand()
echo 'foo\
bar'

I think it will work properly if we just changed it to pass newlines through unmodified inside single-quoted strings.

Add addon-info.json functionality

We want plugin managers to support installing maktaba plugins and have a way for plugins to declare a maktaba dependency that's not itself a maktaba call.

The best way forward seems to be for maktaba plugins to follow VAM's addon-info.json standard to declare the maktaba dependency, and then we can recommend addon-info.json support to other plugin managers.

This is mostly independent of maktaba, but maktaba could offer a few related features like validating addon-info.json, providing convenient access to addon-info.json for introspection, respecting the declared plugin name, etc.

Better maktaba#ensure#Passes error messages

Currently, maktaba#ensure#Passes has no way to pass a custom message in, and can only every give you the very vague message E605: Exception not caught: ERROR(BadValue): SOMEVALUE failed to pass predicate. I'd probably never use that as-is since the error is next to worthless.

We should add support for passing in a custom message and/or change it to have a better message by default.

The ideal approach in terms of code readability and clear error message would be to just to pass a literal expression in as a string (maktaba#ensure#Passes({expr})) and eval it:

call maktaba#ensure#Passes('a:startline >= 1')

ERROR(BadValue): Condition 'a:startline >= 1' failed
But the variables won't be evaluated in the right scope. We could at least detect and optimize the common case of:

call maktaba#ensure#Passes(a:startline, maktaba#function#FromExpr('a:1 >= 1'))

to automatically report the literal expression that failed: ERROR(BadValue): Condition 'a:1 >= 1' failed. a:1 was 0. The a:1 is a little bit cryptic, but still better than ERROR(BadValue): 0 failed to pass predicate.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.