Newer
Older
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
let sessiondir_completer = function (context) {
context.anchored=false;
dir = options.sessiondir;
if (/^~?\//.test(context.filter))
completion.file(context,true);
else {
completion.file(context,true,dir+context.filter);
context.keys.text = function (f) this.path.substr(dir.length);
}
}
let sessiondir_setter = function (value) {
let dir = io.File(value);
if (!dir.exists()) {
try { dir.create(1,488) } catch(e) { return dactyl.echoerr(e.message) };
} else if (!dir.isDirectory())
return dactyl.echoerr(value+' is not a directory!');
if (!/\/$/.test(value)) value+='/';
return value
}
group.options.add(['sessiondir', 'sesdir'],
'Default directory for saving sessions',
'string', options.runtimepath+'/sessions/',
setter: sessiondir_setter,
}
)
group.options.add(['sessionfile', 'sesfile'],
'Current session file',
group.options.add(['sessionoptions', 'sesop'],
"Set what will be saved with :sessionsave",
"stringlist", 'curdir,help,tabs',
{
completer: function (context) [
["blank", "Empty tabs"],
["curdir", "Current directory"],
["help", "Help tabs"],
["options", "All options and mappings"],
["runtime", "Current runtime path(s)"],
["sesdir", "Session directory as current directory"],
["tabs", "Normal tabs"]
]
}
)
group.commands.add(['sessions[ave]','mkses[sion]'],
'Save current window',
function(args) {
let filename = args[0] ? (/^~?\//.test(args[0]) ? args[0] :
options.sessiondir+args[0]) :
options.sessiondir + File(
services.directory.get("ProfD", Ci.nsIFile)).leafName
+'/'+ new Date().toLocaleString().replace(/\s/g,"_")+'.penta'
let file = io.File(filename);
dactyl.assert(!file.exists() || args.bang, _("io.exists", file.path.quote()));
let sesop = options.sessionoptions.toString();
let lines = new Array('" vim: set ft=pentadactyl:\n');
if (/sesdir/.test(sesop))
lines.push('silent cd '+options.sessiondir);
else if (/curdir/.test(sesop))
lines.push('silent cd '+io.cwd.path);
if (/runtime/.test(sesop))
lines.push('set runtimepath='+options.runtimepath);
if (/options/.test(sesop)) {
let cmds = [cmd.serialize().map(commands.commandToString, cmd) for
(cmd in commands.iterator()) if (cmd.serialize)];
cmds = array.flatten(cmds);
lines = lines.concat(cmds);
}
if (/tabs/.test(sesop)) {
tabs.getGroups( function ({ GroupItems }) {
GroupItems.groupItems.forEach( function (group, k) {
lines.push('js <<EOF');
lines.push('tabs.getGroups(function ({ GroupItems }) {');
lines.push('\tlet newGroup = GroupItems.newGroup();');
if (!(group.getTitle() === ""))
lines.push('\tnewGroup.setTitle(\''+group.getTitle()+'\');');
let children = group.getChildren();
children.forEach(function (tab, i) {
let loc = tab.tab.linkedBrowser.contentDocument.location.href;
if (/^dactyl:\/\/help\//.test(loc) && !/help/.test(sesop))
return;
if (loc == 'about:blank' && !/blank/.test(sesop))
return;
lines.push('\tex.tabopen(\''+loc+'\');');
});
lines.push('});');
lines.push('EOF');
});
file.write(lines.join('\n'));
} catch(e) {
dactyl.echoerr(_("io.notWriteable", file.path.quote()));
return;
};
options.sessionfile=file.path;
dactyl.echomsg('Saved session to '+file.path.quote());
}, {
argCount: '?',
bang: true,
completer: sessiondir_completer
group.commands.add(['sessiona[ppend]', 'sessionadd'],
'Append tab(s) to a session file',
function(args) {
let file = io.File(/^~?\//.test(args[0]) ? args[0] : options.sessiondir+args[0]);
if (!file.exists() || !file.isWritable() || file.isDirectory()) {
dactyl.echoerr(_("io.notWriteable", file.path.quote()));
return;
}
let data = '';
if (args.bang) {
tabs.visibleTabs.forEach(function (tab, i) {
data+='\ntabopen '+tab.linkedBrowser.contentDocument.location.href;
data+='\ntabopen '+gBrowser.mCurrentTab.linkedBrowser.contentDocument.location.href;
}
try {
file.write(data,'>>');
} catch(e) {
dactyl.echoerr(_("io.notWriteable", file.path.quote()));
return;
};
dactyl.echomsg('Appended tab(s) to session file '+file.path.quote());
}, {
argCount: '1',
bang: true,
completer: sessiondir_completer
group.commands.add(['sessionl[oad]'],
'Load a session file',
function(args) {
let file = io.File(/^~?\//.test(args[0]) ? args[0] : options.sessiondir+args[0]);
if (!file.exists() || !file.isReadable() || file.isDirectory()) {
dactyl.echoerr(_("io.notReadable", file.path.quote()));
return;
}
// delete inactive groups --> only vivisble tabs will remain
tabs.getGroups( function ({ GroupItems }) {
let activeGroup = GroupItems.getActiveGroupItem();
let items = GroupItems.groupItems;
for(let i in items){
if (items[i].id !== activeGroup.id)
items[i].closeAll();
}
});
if(!args.bang) tabs.keepOnly(curtab); //FIXME deletes only visible tabs
let sessionscript = io.source(file.path);
sessionscript.unload();
options.sessionfile=file.path;
if(!args.bang) tabs.remove(curtab);
dactyl.echomsg('Loaded session from '+file.path.quote());
}, {
argCount: "1",
bang: true,
completer: sessiondir_completer
}
);
group.mappings.add([modes.NORMAL], ['ss'],
'Save current window',
function() CommandExMode().open('sessionsave! ')
group.mappings.add([modes.NORMAL], ['sa'],
'Append tab(s) to a session file',
function() CommandExMode().open('sessionappend ')
function() CommandExMode().open('sessionload ')
XML.ignoreWhitespace = false;
XML.prettyPrinting = false;
var INFO =
<plugin name="penta-sessions" version="0.2"
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
href="https://github.com/gwash/penta-sessions"
summary="Pentadactyl Session Manager"
xmlns={NS}>
<author email="mrawash@gmail.com">M Rawash</author>
<license href="http://www.gnu.org/licenses/gpl.html">GPL</license>
<project name="Pentadactyl" min-version="1.0"/>
<p>
This plugin provides Vim-like session handeling.
</p>
<note>Only operates on current window</note>
<item>
<tags>'sesdir' 'sessiondir'</tags>
<spec>'sessiondir' 'sesdir'</spec>
<type>string</type>
<default>{options.get("sessiondir").stringDefaultValue}</default>
<description>
<p>
The default directory to save/load sessions from.
</p>
</description>
</item>
<item>
<tags>'sesfile' 'sessionfile'</tags>
<spec>'sessionfile' 'sesfile'</spec>
<type>string</type>
<default></default>
<description>
<p>
The session file you are currently working with, this will be set
automatically whenever you save or load a session, but you can set it
manually if you want.
</p>
</description>
</item>
<item>
<tags>'sesop' 'sessionoptions'</tags>
<spec>'sessionoptions' 'sesop'</spec>
<type>stringlist</type>
<default>{options.get("sessionoptions").stringDefaultValue}</default>
<description>
<p>
Changes the effect of the <ex>:sessionsave</ex> command. It is a comma
separated list of words. Each word enables saving and restoring
something:
</p>
<dl>
{ template.map(options.get("sessionoptions").completer(), function ([k, v])
<><dt>{k}</dt> <dd>{v}</dd></>) }
</dl>
<note>
"sesdir" overrides "curdir" if added.
</note>
</description>
</item>
<item>
<tags>ss :sessions :sessionsave :mkses :mksession</tags>
<strut/>
<spec>:sessions<oa>ave</oa><oa>!</oa> <oa>file</oa></spec>
<spec>ss</spec>
<description>
<p>
Saves current session to an ExCommand <oa>file</oa>, which can be
restored later with <ex>:sessionload <oa>file</oa></ex>.
</p>
<p>
If <oa>file</oa> is just a basename or a relative path (without leading
directory path), it will create a session file with that name in the
<o>sessiondir</o>. It also takes care of creating new directories if
specified.
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
<example>
<ex>:sessionsave</ex> pythonref
</example>
</p>
<p>
If no <oa>file</oa> was specified it will save to a numbered file
(based on current date) in <o>sessiondir</o>.
</p>
<p>
Adding ! will overwrite the file if it exists.
<example>
<ex>:sessionsave!</ex> {options.runtimepath}/sessions/gapi.penta
</example>
</p>
</description>
</item>
<item>
<tags>sa :sessiona :sessionappend :sessionadd</tags>
<strut/>
<spec>:sessiona<oa>ppend</oa><oa>!</oa> <oa>file</oa></spec>
<spec>sa</spec>
<description>
<p>
Appends current tab to an existing session <oa>file</oa>. If a ! was
supplied it will append all tabs in current window instead.
</p>
<p>
If <oa>file</oa> is a basename/relative path, it will look for it in
<o>sessiondir</o>.
</p>
</description>
</item>
<item>
<tags>sl :sessionl :sessionload</tags>
<strut/>
<spec>:sessionl<oa>oad</oa><oa>!</oa> <oa>file</oa></spec>
<spec>sl</spec>
<description>
<p>
Loads session from <oa>file</oa>, replacing all tabs in current window
if no ! was added.
</p>
<p>
If <oa>file</oa> is a basename/relative path, it will look for it in
<o>sessiondir</o>.
</p>
</description>
</item>
</plugin>;