Ocelot File Manager

All pages

JavaScript plugins

A JavaScript plugin is a main.js that the app runs in a JavaScript context of its own, on one serial queue. The script's top level runs once, lazily, at the first command or column call, often during a folder load and with no folder of its own: it registers handlers and nothing else. notify, openURL, openInApp, invalidateColumn and spawn throw at the top level.

ocelot.onCommand("my.command", function (ctx) {
  // ctx = { selectionPaths: [String], directoryPath: String, paneID: String,
  //         surface: "selection" | "tab" }
  var out = ocelot.spawn("git", ["status", "--short"], ctx.directoryPath);
  if (out.status !== 0) { ocelot.notify("Git", out.stderr || out.error); return; }
  ocelot.notify("Git status", out.stdout);
});

ocelot.provideColumn("my.column", function (paths, ctx) {
  var values = {};
  paths.forEach(function (path) { values[path] = path.length; });
  return values;
});

The ocelot object

ocelot.onCommand(id, handler) registers the handler for a command the manifest declares. ctx.surface is "tab" when the command came from a tab's menu: directoryPath is then the tab's folder and selectionPaths is empty. A command has 10 seconds.

ocelot.provideColumn(id, provider) registers the provider of a declared column: provider(paths, ctx) returns an object from path to value for the paths asked about. See Columns and badges.

ocelot.spawn(tool, args, cwd) runs a tool the manifest allows with process.spawn:<tool> and returns {status, stdout, stderr, truncated, error}. cwd must be the shown folder or one of the selected paths. At most 256 string arguments. The tool has 8 seconds (inside a column provider, three quarters of the column's budget) and 1 MB of output per stream; past either limit it is stopped, with truncated: true or an error saying it timed out. The tool runs in the plugin's sandbox (see Permissions), with a minimal environment: a fixed PATH, HOME, USER, LANG, LC_ALL, SHELL, TMPDIR and OCELOT_PLUGIN_DATA.

ocelot.readText(path) returns the contents of a UTF-8 text file in the current selection, up to 1 MB. Regular files only. Needs file.readText.

ocelot.openURL(url) hands an http, https or mailto URL of at most 2 048 characters to the system. Needs openURL. A command may open one link or app; a second call throws.

ocelot.openInApp(bundleID, folder) opens the shown folder or a selected folder in that app and returns whether it could. Needs app.open:<bundle id>. Folders only, never packages or files. Tools you spawn cannot open apps themselves; this is the way.

ocelot.notify(title, body) shows a toast in the app. Title and body are cut at 4 096 characters; at most 10 toasts a minute per plugin. Not from a column provider.

ocelot.log(level, message) and console.log write to the plugin's log in Settings ▸ Plugins. Levels: debug, info, warning, error; anything else is info. Lines are cut at 4 096 characters, at most 100 a second; past that the rest is dropped and the next line says how many were.

ocelot.storage is a small key–value store of the plugin's own; see Storage.

ocelot.invalidateColumn(id, paths) tells the app that the values of one of the plugin's columns changed although the files did not; see Columns and badges.

Rules the app enforces