Welcome to Aisu, a package manager for Howl! (こんにちは、アイス)¶
Aisu (アイス) is a package manager for the Howl text editor, built on top of Git and Mercurial.
If you like Aisu, you can star it on GitHub! Stars make me happy. :D
Installing Aisu¶
Ironically enough, you can’t use Aisu to install itself (yet!) like most package managers. Instead, you have to do things the old-fashioned way:
$ mkdir ~/.howl/bundles
$ cd ~/.howl/bundles
$ git clone https://github.com/kirbyfan64/aisu.git
The console¶
Aisu is used within Howl. Whenever a command is referenced in these docs, you can
run it by using Alt+X (to open up the Howl command line) and then entering the
command name (e.g. aisu-query
).
Upon running a command, a new buffer will be opened up containing various prompts pertaining to the command. This is called the Aisu console. It behaves a lot like a terminal would...except it’s inside of Howl! While packages are being installed, for instance, you can go and continue working inside of Howl, doing other things in other buffers.
Whenever Aisu asks for package paths or names, you can specify multiple ones by
separating them by spaces. For instance, when aisu-uninstall
asks for a
package name, you can specify multiple ones like
my-first-package my-second-package
.
Installing and querying for packages¶
Aisu was designed to be really easy to use. To query information about and
install different packages, you can use the aisu-query
and aisu-install
commands. They will both ask for the path/repo of the package to install. This
can be a path to a local Git/Mercurial repository (/home/my_user/my_repo
) or
a URL (https://github.com/my_user/my_repo.git
). In addition, for packages on
GitHub, you can just use username/repo
; my_user/my_repo
is shorthand for
https://github.com/my_user/my_repo.git
.
If you’re using aisu-query
, Aisu will download the package to a temporary
folder and print information about it (like author and description).
aisu-install
will do the same thing, followed by a confirmation message
verifying that you want to install the package.
Just like mentioned above, you can install multiple packages by separating their paths with spaces.
Updating packages¶
To update packages, you can just run aisu-update
. This will ask for the
packages to update. If you want to update all your packages, you can just enter
an asterisk (*
). In addition, you can use Ctrl+Space to auto-complete with a
list of installed packages.
Uninstalling packages¶
aisu-uninstall
will uninstall any given packages. Just like aisu-update
,
you can press Ctrl+Space in order to auto-complete with a list of packages.
Creating packages¶
By default, Aisu looks for a file called aisu.moon
. It looks kind of like
this:
{
meta:
author: 'Author name here'
description: 'Description here'
license: 'License here'
version: 'Version here'
build: (buffer) ->
-- This function will be run whenever the package is installed/updated.
}
Any of the fields can be ommited.
You can also use Lua with aisu.lua
, like this:
return {
meta = {
author = 'Author name here',
description = 'Description here',
license = 'License here',
version = 'Version here'
},
build = function (buffer)
-- This function will be run whenever the package is installed/updated.
end
}
If neither aisu.moon
nor aisu.lua
is present, Aisu will attempt to
parse init.moon
to find the metadata. If that also fails, then Aisu will
ask you if it can run init.moon
or init.lua
to get the metadata.
Failing that, it bails and assumes all the metadata is unknown.
The most interesting part here is the build
function. It is passed the Aisu
ControlBuffer and is supposed to setup anything required for the package to
function correctly. An example is:
build: (buffer, dir) ->
-- Run make. dir is the directory holding the package.
aisu.spawn_in_buffer buffer,
cmd: {'make'}
working_directory: dir
A full example of an aisu.moon
can be seen in the howl-autoclang
bundle:
{
-- Metadata
meta:
author: 'Ryan Gonzalez'
description: 'Clang-based autocompletion for C/C++'
license: 'MIT'
version: '0.1'
-- The build function: runs each command.
build: (buf, dir) ->
cmds = {
{'git', 'submodule', 'init'}
{'git', 'submodule', 'update'}
{'make', '-C', 'ljclang', 'libljclang.so'}
}
for cmd in *cmds
aisu.spawn_in_buffer buf,
:cmd
working_directory: dir
}
Reducing duplication¶
If you haven’t noticed, aisu.moon
‘s meta
field is largely the same as
init.moon
‘s info
. Since that’s a bit of a chore to maintain, you can
just do this in init.moon
:
-- ... normal code here ...
{
-- The magic is here:
info: bundle_load('aisu').meta
-- ...
}
This just loads up aisu.moon
and grabs the meta
field.
FAQ¶
Since Aisu is new, there haven’t really been any questions asked yet, so this mostly came off the top of my head. Which explains why it makes almost no sense...
Does Aisu have dependency management?¶
Not yet. This isn’t that high of a priority at the moment, since packages
designed for text editors (like Howl!) usually aren’t as dependency-happy as
NodeJS packages (a.k.a. left-pad
).
Is Aisu self-updating?¶
Again, not yet. Eventually, Aisu will be a valid package of its own, and you’ll just run a quick bootstrap script to install it.
Why the hell did you name this Aisu?¶
Aisu (アイス) is Japanese for ice. Wolves can live in cold weather. Howling is what wolves do. Get it? Get it?
(To top it off, I didn’t realize it at first, but the Sphinx theme I used for these docs was made by Japanese people. Kind of a weird coincidence...)
API documentation¶
The core¶
aisu.setup()
Initializes Aisu.
aisu.packages
A table of installed packages. Each value is a table containing two fields:
path
(the package location) andvcs
(the version control that the package uses; eithergit
orhg
).aisu.save_packages()
Writes the package list to
~/.howl/aisu.lua
.aisu.yield()
Like
coroutine.yield
, but discards the first return value. Useful forControlBuffer.open_prompt
, since it also returns the buffer, which you probably already have if you were callingopen_prompt
!
Utilities¶
aisu.bind(f, ...)
Does a function partial with the given function and arguments. Google it.
aisu.upper(s)
Returns the given string with the first letter capitalized.
aisu.spawn_in_buffer(buf, args)
Creates a new instance of
howl.io.Process
with the given arguments and writes the process output to the buffer. Returns the completed process.
VCS utilities¶
aisu.Vcs
An abstract class representing a version control system. Subclasses of
Vcs
have four methods:exec(cmd, dir)
- Execute the command inside of the given directory.clone(url, dir)
- Clones the URL into the given directory.update(dir)
- Updates the repository inside the given directory.revid(dir)
- Retrieves the latest commit hash from the repository.
aisu.Git
aisu.Mercurial
Two subclasses of
aisu.Vcs
that implement the corresponding version control system support.aisu.get_vcs(vcs)
Given one of
'git'
or'hg'
, return the corresponding version control class (NOT an instance).aisu.vcs_info()
Returns a table containing two keys,
git
andhg
. If the value of the key isfalse
, then the corresponding version control program isn’t present; otherwise, it was present.aisu.read_url(url)
If the URL is actually the GitHub repository shorthand, it returns the expanded version (e.g.
my_user/my_repo
->https://github.com/my_user/my_repo.git
). Otherwise, it just returns the original argument.aisu.identify_repo(url)
Returns the version control class corresponding to the given URL. If the URL points to a Git repo, then the function returns
aisu.Git
, and, if it’s a Mercurial repo,aisu.Mercurial
. If neither, thennil
is returned.
ControlBuffer
¶
aisu.ControlBuffer.prompt_begins
If a prompt is currently open, this is the buffer offset at which the prompt begins. Otherwise, it is
nil
.aisu.ControlBuffer.write(text, flair)
Writes the given text to the buffer, highlighted using the given flair.
aisu.ControlBuffer.writeln(text, flair)
Same as
write
, but appends a newline to text.aisu.ControlBuffer.info(text)
Writes some informative text to the buffer.
aisu.ControlBuffer.warn(text)
Writes a warning to the buffer.
aisu.ControlBuffer.error(text)
Writes an error to the buffer.
aisu.ControlBuffer.open_prompt()
Opens up a prompt for user input. The result can be obtained by calling
aisu.yield!
.aisu.ControlBuffer.ask(text, flair)
Writes the text followed by a newline with the given flair, followed by opening the prompt. The text will be written until the user enters either
y
orn
. Ify
was entered,true
will be returned; otherwise,false
will be returned.aisu.ControlBuffer.call(f, ...)
Calls the given function with the variadic arguments. If an error occurs, then the traceback will be written to the buffer, and the error will be re-raised.
Commands¶
aisu.map_packages(buffer, packages, fn, ...)
Splits the string
packages
by spaces. For each resulting package, callsfn(buffer, package, ...)
.aisu.query_info_from_repo(dir)
Search for
aisu.moon
andinit.moon
and return the Aisu config table. It’s formatted like this:{ meta: author: '...' description: '...' license: '...' build: build_function_here }
Any of the fields may be missing/
nil
.aisu.perform_query(buffer, package, after)
Queries for information on the given package. After the query is complete, calls after(buffer, package_url, temporary_directory_holding_repo, version_control_class, package_information_like_query_info_from_repo).
aisu.show_query(buffer, url, dir, vcs, info)
Writes the package information to the buffer. Designed to be called by
aisu.perform_query
.aisu.build_package(buffer, build_function, dir)
Calls the given build function.
dir
is the directory holding the package.aisu.show_query(buffer, url, dir, vcs, info)
Installs the given package. Designed to be called by
aisu.perform_query
.aisu.uninstall_package(package)
Uninstalls the given package.
aisu.update_package(package)
Updates the given package.