diff --git a/Makefile b/Makefile index a568535..11e185c 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ FILES = bashrc vimrc zshrc emacs.el gitconfig screenrc commonshrc \ - gnomerc gvimrc muttrc pentadactylrc vimperatorrc mailcap latexmkrc + gnomerc gvimrc muttrc pentadactylrc mailcap latexmkrc FILES2 = msmtprc .PHONY: install clean check diff --git a/notmuch-address b/notmuch-address deleted file mode 100755 index 150ff54..0000000 --- a/notmuch-address +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env perl -use Text::vCard::Addressbook; -my $address_book = - Text::vCard::Addressbook->load( ["$ENV{HOME}/.contacts.vcf"] ); - -my $query = $ARGV[0]; - -if ( my ($category) = ( $query =~ /^#(.*)/ ) ) { - my @members; - foreach my $vcard ( $address_book->vcards() ) { - for ( @{ $vcard->get('categories') || [] } ) { - next unless $_->value() =~ /(^|,)$category/i; - if ( my $email = $vcard->get_simple_type('email') ) { - push @members, sprintf "%s <%s>", $vcard->fullname(), $email; - } - } - } - print join( ', ', @members ), "\n" if @members; -} -else { - foreach my $vcard ( $address_book->vcards() ) { - if ( $vcard->fullname() =~ /$query/i ) { - printf "%s <%s>\n", $vcard->fullname(), $_->value() - for @{ $vcard->get('email') || [] }; - } - } -} diff --git a/notmuch-config.el b/notmuch-config.el deleted file mode 100644 index 99d8703..0000000 --- a/notmuch-config.el +++ /dev/null @@ -1,29 +0,0 @@ -(setq mm-text-html-renderer 'w3m - send-mail-function 'sendmail-send-it - mail-interactive nil - message-kill-buffer-on-exit t - notmuch-search-oldest-first nil) - -; swap r and R -(define-key notmuch-show-mode-map "r" 'notmuch-show-reply) -(define-key notmuch-show-mode-map "R" 'notmuch-show-reply-sender) -(define-key notmuch-search-mode-map "r" 'notmuch-search-reply-to-thread) -(define-key notmuch-search-mode-map "R" 'notmuch-search-reply-to-thread-sender) - -(setq notmuch-fcc-dirs nil) -(add-hook 'message-header-setup-hook 'notmuch-bcc-header-setup) -(defun notmuch-bcc-header-setup () - (message-add-header "Bcc: gebner@gebner.org")) - -(setq mail-specify-envelope-from t - mail-envelope-from 'header - message-sendmail-f-is-evil nil - message-sendmail-envelope-from 'header) - -(setq notmuch-address-command "~/etc/notmuch-address") -(notmuch-address-message-insinuate) - -; start with inbox -(defun notmuch () - (interactive) - (notmuch-search "tag:inbox")) diff --git a/vimperator/plugin/_libly.js b/vimperator/plugin/_libly.js deleted file mode 100644 index be989d7..0000000 --- a/vimperator/plugin/_libly.js +++ /dev/null @@ -1,737 +0,0 @@ -/*** BEGIN LICENSE BLOCK {{{ - Copyright (c) 2008 suVene - Copyright (c) 2008-2011 anekos - - distributable under the terms of an MIT-style license. - http://www.opensource.jp/licenses/mit-license.html -}}} END LICENSE BLOCK ***/ -// PLUGIN_INFO//{{{ -/* -var PLUGIN_INFO = xml` - - libly(filename _libly.js) - Vimperator plugins library? - 適当なライブラリっぽいものたち。 - suVene - anekos - MIT - 0.1.38 - 2.3pre - https://github.com/vimpr/vimperator-plugins/raw/master/_libly.js - || - { - original: オリジナルの関数 - current: 現在の関数 - restore: 元に戻すための関数 - } - ||< -bind(obj, func): - func に obj を bind します。 - func内からは this で obj が参照できるようになります。 -eval(text): - Sandbox による、window.eval を極力利用するようにします。 - Snadbox が利用できない場合は、unsafe な window の eval が直接利用されます。 -evalJson(str, toRemove): - str を decode します。 - toRemove が true の場合、文字列の前後を1文字削除します。 - "(key:value)" 形式の場合などに true を指定して下さい。 -dateFormat(dtm, fmt): - Date型インスタンスを、指定されたフォーマットで文字列に変換します。 - fmt を省略した場合、"%y/%M/%d %h:%m:%s" となります。 -runnable(generator): - gererator を実行し、再帰的に resume する為の引数を渡します。 - -== Browser == -getSelectedString: - window の選択文字列を返却します。 -getUserAndPassword(hostname, formSubmitURL, username): - login-manager から [username, password] を取得します。 - 引数の username が省略された場合、検索された 1件目を返却します。 - データが存在しない場合は、null を返却します。 - -== System == -readDirectory(path, fileter, func): - path で指定したディレクトリから、filter で指定された正規表現に match する場合、 - func をファイル名を引数にコールバックします。 - filter は Function を指定することも可能です。 - -== HTML, XML, DOM, E4X == -pathToURL(a, baseURL, doc): - 相対パスを絶対パスに変換します。 -getHTMLFragment(html): - ※1 - ※1 の文字列を取得します。 -stripTags(str, tags): - str から tags で指定されたタグを取り除いて返却します。 - tags は文字列、または配列で指定して下さい。 -createHTMLDocument(str, xmlns): - 引数 str より、HTMLFragment を作成します。 -getFirstNodeFromXPath(xpath, context): - xpath を評価しオブジェクトをを返却します。 -getNodesFromXPath(xpath, context, callback, thisObj): - xpath を評価し snapshot の配列を返却します。 -xmlSerialize(xml): - xml を文字列化します。 -xmlToDom(node, doc, nodes): - for vimperator1.2. - @see vimperator2.0pre util. -getElementPosition(elem): - elem の offset を返却します。 - return {top: 0, left: 0} -toStyleText(style): - スタイルが格納されているオブジェクトを - >|| - position: fixed; - left: 10px; - ||< - のような文字列に変換します。 - -== Object Request == -Request(url, headers, options): - コンストラクタ - url: - HTTPリクエスト先のURL - headers: - 以下のようにHTTPヘッダの値を指定できる(省略可) - >|| - { - 'Referer' : 'http://example.com/' - } - ||< - 以下の値はデフォルトで設定される('Content-type'はPOST時のみ) - >|| - { - 'Accept': 'text/javascript, application/javascript, text/html, application/xhtml+xml, application/xml, text/xml, * /*;q=0.1', - 'Content-type': 'application/x-www-form-urlencoded; charset=' + options.encodingの値 - } - ||< - - options: - オプションとして以下のようなオブジェクトを指定できる(省略可) - asynchronous: - true: 非同期モード/false: 同期モード(デフォルト:true) - encoding: - エンコーディング(デフォルト: 'UTF-8') - username: - BASIC認証時のuser名 - password: - BASIC認証時のパスワード - postBody: - POSTメソッドにより送信するbody -addEventListener(name, func): - イベントリスナを登録する。 - name: - 'success': - 成功時 - 'failure': - 失敗を表すステータスコードが返ってきた時 - 'exception': - 例外発生時 - func: - イベント発火時の処理 - 引数として以下Responseオブジェクトが渡される -get(): - GETメソッドによりHTTPリクエストを発行する。 -post(): - POSTメソッドによりHTTPリクエストを発行する。 - -== Object Response == -HTTPレスポンスを表すオブジェクト -req: - レスポンスと対となるRequestオブジェクト -doc: - レスポンスから生成されたHTMLDocumentオブジェクト -isSuccess(): - ステータスコードが成功を表していればtrue、失敗であればfalse -getStatus(): - ステータスコードを取得する -getStatusText(): - ステータを表す文字列を取得する -getHTMLDocument(xpath, xmlns, ignoreTags, callback, thisObj): - レスポンスからHTMLDocumentオブジェクトを生成し、xpath を評価した結果の snapshot の配列を返す - -== Object Wedata == -~/vimperator/info/profile_name/plugins-libly-wedata-????? -に store されます。 -getItems(expire, itemCallback, finalCallback): - インスタンス作成時に指定した dbname から、item を読込みます。 -=== TODO === -clearCache: - wedata 読込み成功したら、強制的にキャッシュと置き換えるの作って! - - ]]> -`; -*/ -//}}} -//if (!liberator.plugins.libly) { - -liberator.plugins.libly = {}; -var libly = liberator.plugins.libly; - -// XXX for backward compatibillity -function fixEventName(name) { - return name.replace(/^on/, '').toLowerCase(); -} - -libly.$U = {//{{{ - // Logger {{{ - getLogger: function(prefix) { - return new function() { - this.log = function(msg, level) { - if (typeof msg == 'object') msg = util.objectToString(msg); - liberator.log(libly.$U.dateFormat(new Date()) + ': ' + (prefix || '') + ': ' + msg, (level || 0)); - }; - this.echo = function(msg, flg) { - flg = flg || commandline.FORCE_MULTILINE; - // this.log(msg); - liberator.echo(msg, flg); - }; - this.echoerr = function(msg) { - this.log('error: ' + msg); - liberator.echoerr(msg); - }; - } - }, - // }}} - // Object Utility {{{ - extend: function(dst, src) { - for (let prop in src) - dst[prop] = src[prop]; - return dst; - }, - A: function(iterable) { - var ret = []; - if (!iterable) return ret; - if (typeof iterable == 'string') return [iterable]; - if (!(typeof iterable == 'function' && iterable == '[object NodeList]') && - iterable.toArray) return iterable.toArray(); - if (typeof iterable.length != 'undefined') { - for (let i = 0, len = iterable.length; i < len; ret.push(iterable[i++])); - } else { - for each (let item in iterable) ret.push(item); - } - return ret; - }, - around: (function () { - function getPluginPath () { - let pluginPath; - Error('hoge').stack.split(/\n/).some( - function (s) - let (m = s.match(/-> liberator:\/\/template\/chrome:\/\/liberator\/content\/liberator\.js -> (.+):\d+$/)) - (m && (pluginPath = m[1].replace(/\?.*$/, ''))) - ); - return pluginPath; - } - - let restores = {}; - - return function (obj, name, func, autoRestore) { - let original; - let restore = function () obj[name] = original; - if (autoRestore) { - let pluginPath = getPluginPath(); - if (pluginPath) { - restores[pluginPath] = - (restores[pluginPath] || []).filter( - function (res) ( - res.object != obj || - res.name != name || - (res.restore() && false) - ) - ); - restores[pluginPath].push({ - object: obj, - name: name, - restore: restore - }); - } else { - liberator.echoerr('getPluginPath failed'); - } - } - original = obj[name]; - let current = obj[name] = function () { - let self = this, args = arguments; - return func.call(self, function (_args) original.apply(self, _args || args), args); - }; - libly.$U.extend(current, {original: original && original.original || original, restore: restore}); - return libly.$U.extend({ - original: original, - current: current, - restore: restore - }, [original, current]); - }; - })(), - bind: function(obj, func) { - return function() { - return func.apply(obj, arguments); - } - }, - eval: function(text) { - var fnc = window.eval; - var sandbox; - try { - sandbox = new Components.utils.Sandbox("about:blank"); - if (Components.utils.evalInSandbox('true', sandbox) === true) { - fnc = function(text) { return Components.utils.evalInSandbox(text, sandbox); }; - } - } catch (e) { liberator.log('warning: _libly.js is working with unsafe sandbox.'); } - - return fnc(text); - }, - evalJson: function(str, toRemove) { - var json; - try { - json = Components.classes['@mozilla.org/dom/json;1'].getService(Components.interfaces.nsIJSON); - if (toRemove) str = str.substring(1, str.length - 1); - return json.decode(str); - } catch (e) { return null; } - }, - dateFormat: function(dtm, fmt) { - var d = { - y: dtm.getFullYear(), - M: dtm.getMonth() + 1, - d: dtm.getDate(), - h: dtm.getHours(), - m: dtm.getMinutes(), - s: dtm.getSeconds(), - '%': '%' - }; - for (let [n, v] in Iterator(d)) { - if (v < 10) - d[n] = '0' + v; - } - return (fmt || '%y/%M/%d %h:%m:%s').replace(/%([yMdhms%])/g, function (_, n) d[n]); - }, - /** - * example) - * $U.runnable(function(resume) { - * // execute asynchronous function. - * // goto next yield; - * var val = yield setTimeout(function() { resume('value!'), 1000) }); - * alert(val); // value! - * yield; - * }); - */ - runnable: function(generator) { - var it = generator(function(value) { - try { it.send(value); } catch (e) {} - }); - it.next(); - }, - // }}} - // Browser {{{ - getSelectedString: function() { - return (new XPCNativeWrapper(window.content.window)).getSelection().toString(); - }, - getUserAndPassword: function(hostname, formSubmitURL, username) { - var passwordManager, logins; - try { - passwordManager = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); - logins = passwordManager.findLogins({}, hostname, formSubmitURL, null); - if (logins.length) { - if (username) { - for (let i = 0, len = logins.lengh; i < len; i++) { - if (logins[i].username == username) - return [logins[i].username, logins[i].password] - } - liberator.log(this.dateFormat(new Date()) +': [getUserAndPassword] username notfound'); - //throw 'username notfound.'; - return []; - } else { - return [logins[0].username, logins[0].password]; - } - } else { - liberator.log(this.dateFormat(new Date()) + ': [getUserAndPassword] account notfound'); - return []; - } - } catch (e) { - liberator.log(this.dateFormat(new Date()) + ': [getUserAndPassword] error: ' + e, 0); - return null; - } - }, - // }}} - // System {{{ - readDirectory: function(path, filter, func) { - var d = io.File(path); - if (d.exists() && d.isDirectory()) { - let enm = d.directoryEntries; - let flg = false; - while (enm.hasMoreElements()) { - let item = enm.getNext(); - item.QueryInterface(Components.interfaces.nsIFile); - flg = false; - if (typeof filter == 'string') { - if ((new RegExp(filter)).test(item.leafName)) flg = true; - } else if (typeof filter == 'function') { - flg = filter(item); - } - if (flg) func(item); - } - } - }, - // }}} - // HTML, XML, DOM, E4X {{{ - pathToURL: function(a, baseURL, doc) { - if (!a) return ''; - var XHTML_NS = "http://www.w3.org/1999/xhtml"; - var XML_NS = "http://www.w3.org/XML/1998/namespace"; - //var path = (a.href || a.getAttribute('src') || a.action || a.value || a); - var path = (a.getAttribute('href') || a.getAttribute('src') || a.action || a.value || a); - if (/^https?:\/\//.test(path)) return path; - var link = (doc || window.content.documtent).createElementNS(XHTML_NS, 'a'); - link.setAttributeNS(XML_NS, 'xml:base', baseURL); - link.href = path; - return link.href; - }, - getHTMLFragment: function(html) { - if (!html) return html; - return html.replace(/^[\s\S]*?]*)?>|<\/html[ \t\r\n]*>[\S\s]*$/ig, ''); - }, - stripTags: function(str, tags) { - var ignoreTags = '(?:' + [].concat(tags).join('|') + ')'; - return str.replace(new RegExp('<' + ignoreTags + '(?:[ \\t\\n\\r][^>]*|/)?>([\\S\\s]*?)<\/' + ignoreTags + '[ \\t\\r\\n]*>', 'ig'), ''); - }, - createHTMLDocument: function(str, xmlns, doc) { - let root = document.createElementNS("http://www.w3.org/1999/xhtml", "html"); - let uhService = Cc["@mozilla.org/feed-unescapehtml;1"].getService(Ci.nsIScriptableUnescapeHTML); - let text = str.replace(/^[\s\S]*?]*)?>[\s]*|<\/body[ \t\r\n]*>[\S\s]*$/ig, ''); - let fragment = uhService.parseFragment(text, false, null, root); - let doctype = document.implementation.createDocumentType('html', '-//W3C//DTD HTML 4.01//EN', 'http://www.w3.org/TR/html4/strict.dtd'); - let htmlFragment = document.implementation.createDocument(null, 'html', doctype); - htmlFragment.documentElement.appendChild(htmlFragment.importNode(fragment,true)); - return htmlFragment; - /* うまく動いていない場合はこちらに戻してください - doc = doc || window.content.document; - var htmlFragment = doc.implementation.createDocument(null, 'html', null); - var range = doc.createRange(); - range.setStartAfter(doc.body); - htmlFragment.documentElement.appendChild(htmlFragment.importNode(range.createContextualFragment(str), true)); - return htmlFragment; - */ - }, - getFirstNodeFromXPath: function(xpath, context) { - if (!xpath) return null; - context = context || window.content.document; - var result = (context.ownerDocument || context).evaluate(xpath, context, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); - return result.singleNodeValue || null; - }, - getNodesFromXPath: function(xpath, context, callback, thisObj) { - var ret = []; - if (!xpath) return ret; - context = context || window.content.document; - var nodesSnapshot = (context.ownerDocument || context).evaluate(xpath, context, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - for (let i = 0, l = nodesSnapshot.snapshotLength; i < l; i++) { - if (typeof callback == 'function') callback.call(thisObj, nodesSnapshot.snapshotItem(i), i); - ret.push(nodesSnapshot.snapshotItem(i)); - } - return ret; - }, - xmlSerialize: function(xml) { - try { - return (new XMLSerializer()).serializeToString(xml) - .replace(//g, '') - .replace(/<\s*\/?\s*\w+/g, function(all) all.toLowerCase()); - } catch (e) { return '' } - }, - xmlToDom: function xmlToDom(node, doc, nodes) - { - return util.xmlToDom(node, doc, nodes); - }, - getElementPosition: function(elem) { - var offsetTrail = elem; - var offsetLeft = 0; - var offsetTop = 0; - while (offsetTrail) { - offsetLeft += offsetTrail.offsetLeft; - offsetTop += offsetTrail.offsetTop; - offsetTrail = offsetTrail.offsetParent; - } - offsetTop = offsetTop || null; - offsetLeft = offsetLeft || null; - return {top: offsetTop, left: offsetLeft}; - }, - toStyleText: function(style) { - var result = ''; - for (let name in style) { - result += name.replace(/[A-Z]/g, function (c) ('-' + c.toLowerCase())) + - ': ' + - style[name] + - ';\n'; - } - return result; - } - // }}} -}; -//}}} - -libly.Request = function() {//{{{ - this.initialize.apply(this, arguments); -}; -libly.Request.EVENTS = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; -libly.Request.requestCount = 0; -libly.Request.prototype = { - initialize: function(url, headers, options) { - this.url = url; - this.headers = headers || {}; - this.options = libly.$U.extend({ - asynchronous: true, - encoding: 'UTF-8' - }, options || {}); - this.observers = {}; - }, - addEventListener: function(name, func) { - name = fixEventName(name); - try { - if (typeof this.observers[name] == 'undefined') this.observers[name] = []; - this.observers[name].push(func); - } catch (e) { - if (!this.fireEvent('exception', new libly.Response(this), e)) throw e; - } - }, - fireEvent: function(name, args, asynchronous) { - name = fixEventName(name); - if (!(this.observers[name] instanceof Array)) return false; - this.observers[name].forEach(function(event) { - if (asynchronous) { - setTimeout(event, 10, args); - } else { - event(args); - } - }); - return true; - }, - _complete: false, - _request: function(method) { - - try { - libly.Request.requestCount++; - - this.method = method; - this.transport = new XMLHttpRequest(); - this.transport.open(method, this.url, this.options.asynchronous, this.options.username, this.options.password); - - var stateChangeException; - this.transport.onreadystatechange = libly.$U.bind(this, function () { - try { - this._onStateChange(); - } catch (e) { - stateChangeException = e; - } - }); - this.setRequestHeaders(); - this.transport.overrideMimeType(this.options.mimetype || 'text/html; charset=' + this.options.encoding); - - this.body = this.method == 'POST' ? this.options.postBody : null; - - this.transport.send(this.body); - - if (!this.options.asynchronous && stateChangeException) throw stateChangeException; - - // Force Firefox to handle ready state 4 for synchronous requests - if (!this.options.asynchronous && this.transport.overrideMimeType) - this._onStateChange(); - - } catch (e) { - if (!this.fireEvent('exception', new libly.Response(this), e)) throw e; - } - }, - _onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState > 1 && !(readyState == 4 && this._complete)) - this.respondToReadyState(this.transport.readyState); - }, - getStatus: function() { - try { - return this.transport.status || 0; - } catch (e) { return 0; } - }, - isSuccess: function() { - var status = this.getStatus(); - return !status || (status >= 200 && status < 300); - }, - respondToReadyState: function(readyState) { - var state = libly.Request.EVENTS[readyState]; - var res = new libly.Response(this); - - if (state == 'Complete') { - libly.Request.requestCount--; - try { - this._complete = true; - this.fireEvent(this.isSuccess() ? 'success' : 'failure', res, this.options.asynchronous); - } catch (e) { - if (!this.fireEvent('exception', res, e)) throw e; - } - } - }, - setRequestHeaders: function() { - var headers = { - 'Accept': 'text/javascript, application/javascript, text/html, application/xhtml+xml, application/xml, text/xml, */*;q=0.1' - }; - - if (this.method == 'POST') { - headers['Content-type'] = 'application/x-www-form-urlencoded' + - (this.options.encoding ? '; charset=' + this.options.encoding : ''); - - if (this.transport.overrideMimeType) { - let year = parseInt((navigator.userAgent.match(/\bGecko\/(\d{4})/) || [0, 2005])[1], 10); - if (0 < year && year < 2005) - headers['Connection'] = 'close'; - } - } - - for (let key in this.headers) - if (this.headers.hasOwnProperty(key)) headers[key] = this.headers[key]; - - for (let name in headers) - this.transport.setRequestHeader(name, headers[name]); - }, - get: function() { - this._request('GET'); - }, - post: function() { - this._request('POST'); - } -};//}}} - -libly.Response = function() {//{{{ - this.initialize.apply(this, arguments); -}; -libly.Response.prototype = { - initialize: function(req) { - this.req = req; - this.transport = req.transport; - this.isSuccess = req.isSuccess; - this.readyState = this.transport.readyState; - - if (this.readyState == 4) { - this.status = this.getStatus(); - this.statusText = this.getStatusText(); - this.responseText = (this.transport.responseText == null) ? '' : this.transport.responseText; - this.responseXML = this.transport.responseXML; - } - - this.doc = null; - this.htmlFragmentstr = ''; - }, - status: 0, - statusText: '', - getStatus: libly.Request.prototype.getStatus, - getStatusText: function() { - try { - return this.transport.statusText || ''; - } catch (e) { return ''; } - }, - getHTMLDocument: function(xpath, xmlns, ignoreTags, callback, thisObj) { - if (!this.doc) { - //if (doc.documentElement.nodeName != 'HTML') { - // return new DOMParser().parseFromString(str, 'application/xhtml+xml'); - //} - this.htmlFragmentstr = libly.$U.getHTMLFragment(this.responseText); - this.htmlStripScriptFragmentstr = libly.$U.stripTags(this.htmlFragmentstr, ignoreTags); - this.doc = libly.$U.createHTMLDocument(this.htmlStripScriptFragmentstr, xmlns); - } - if (!xpath) xpath = '//*'; - return libly.$U.getNodesFromXPath(xpath, this.doc, callback, thisObj); - } -}; -//}}} - -libly.Wedata = function(dbname) { // {{{ - this.initialize.apply(this, arguments); -}; -libly.Wedata.prototype = { - initialize: function(dbname) { - this.HOST_NAME = 'http://wedata.net/'; - this.dbname = dbname; - this.logger = libly.$U.getLogger('libly.Wedata'); - }, - getItems: function(expire, itemCallback, finalCallback) { - - var logger = this.logger; - var STORE_KEY = 'plugins-libly-wedata-' + encodeURIComponent(this.dbname) + '-items'; - var store = storage.newMap(STORE_KEY, {store: true}); - var cache = store && store.get('data'); - - if (store && cache && new Date(store.get('expire')) > new Date()) { - logger.log('return cache. '); - cache.forEach(function(item) { if (typeof itemCallback == 'function') itemCallback(item); }); - if (typeof finalCallback == 'function') - finalCallback(true, cache); - return; - } - - expire = expire || 0; - - function errDispatcher(msg, cache) { - if (cache) { - logger.log('return cache. -> ' + msg); - cache.forEach(function(item) { if (typeof itemCallback == 'function') itemCallback(item); }); - if (typeof finalCallback == 'function') - finalCallback(true, cache); - } else { - logger.log(msg + ': cache notfound.'); - if (typeof finalCallback == 'function') - finalCallback(false, msg); - } - } - - var req = new libly.Request(this.HOST_NAME + 'databases/' + encodeURIComponent(this.dbname) + '/items.json'); - req.addEventListener('success', libly.$U.bind(this, function(res) { - var text = res.responseText; - if (!text) { - errDispatcher('response is null.', cache); - return; - } - var json = libly.$U.evalJson(text); - if (!json) { - errDispatcher('failed eval json.', cache); - return; - } - logger.log('success get wedata.'); - store.set('expire', new Date(new Date().getTime() + expire).toString()); - store.set('data', json); - store.save(); - json.forEach(function(item) { if (typeof itemCallback == 'function') itemCallback(item); }); - if (typeof finalCallback == 'function') - finalCallback(true, json); - })); - req.addEventListener('failure', function() errDispatcher('onFailure', cache)); - req.addEventListener('exception', function() errDispatcher('onException', cache)); - req.get(); - } -}; -//}}} - -//} -// vim: set fdm=marker sw=4 ts=4 sts=0 et: - diff --git a/vimperator/plugin/feedSomeKeys_3.js b/vimperator/plugin/feedSomeKeys_3.js deleted file mode 100644 index fd08ec6..0000000 --- a/vimperator/plugin/feedSomeKeys_3.js +++ /dev/null @@ -1,726 +0,0 @@ -/* NEW BSD LICENSE {{{ -Copyright (c) 2010-2011, anekos. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -THE POSSIBILITY OF SUCH DAMAGE. - - -################################################################################### -# http://sourceforge.jp/projects/opensource/wiki/licenses%2Fnew_BSD_license # -# に参考になる日本語訳がありますが、有効なのは上記英文となります。 # -################################################################################### - -}}} */ - -// INFO {{{ -let INFO = -xml` - anekos - New BSD License - -

- Feed key events directly into web contents. -

- - :fmap - :fmap -events=eventnamelist -xpath=xpath -frame=framenumber -urls=urlpattern -modes=modes lhs rhs - -

- Define one mapping. -

-

- If -urls=urlpattern is given, - the mappings becomes effective mappings only on the page specifed by urlpattern. -

-
-
- - :fmaps - :fmaps -events=eventnamelist -xpath=xpath -frame=framenumber -urls=urlpattern -pprefix=prefix -modes=modes mappingpair .... - -

- Two or more mappings are defined at once. - mappingpair is a pair of key names separated by ",". -

e.g. "<Leader><S-j>,j"

-

-

- If -urls=urlpattern is given, - the mappings becomes effective mappings only on the page specifed by urlpattern. -

-
-
- - :fmapc - :fmapc! -modes=modes urlpattern - -

- Remove the mappings matched with urlpattern. - If "!" is given, remove all mappings. -

-
-
- - :funmap - :funmap -urls=urlpattern -modes=modes lhs - -

- Remove the mappings. -

-

- If you wish to remove url-local mappings, give -urls=urlpattern. -

-
-
-

urlpattern

-

- The value of urlpattern should be regular expression. -

-

xpath

-

- The XPath for a target element. -

-

framenumber

-

- The number of a target frame. - Refer the completion for this number. -

-

eventnamelist

-

- eventnamelist is the list constructed with the below values. -

-
    -
  • keypress
  • -
  • keydown
  • -
  • keyup
  • -
  • vkeypress
  • -
  • vkeydown
  • -
  • vkeyup
  • -
-

"v..." values use virtual key code.

-

The event is generated in the order of writing of each key.

-

The default value of this option is "keypress".

-

modes

-

- List of mapping modes. (Default is NORMAL mode) -

-

fmaps examples for .vimperatorrc

-

If you input directly these commands in vimperator commandline, remove the ":lazy".

- -:command! -nargs=+ lazy autocmd VimperatorEnter .* <args> -:lazy fmaps -u='mail\.google\.com/mail' c / j k n p o u e x s r a # [ ] ? gi gs gt gd ga gc -:lazy fmaps -u='mail\.google\.com/mail/.*/[0-9a-f]+$' c / j,n k,p n,j p,k o u e x s r a # [ ] ? gi gs gt gd ga gc -:lazy fmaps -u='www\.google\.co\.jp/reader' -events=vkeypress j k n p m s v A r S N P X O gh ga gs gt gu u / ? J K -:lazy fmaps -u='(fastladder|livedoor)\.com/reader' j k s a p o v c i,p <Space> <S-Space> z b < > q w e,g -:lazy fmaps -u='https?://www\.rememberthemilk\.com/home/' j k m i c t ? d F,f G,g S,s L,l Y,y H,h M,m <Del> <C-S-Left> <C-S-Right> -:lazy fmaps -u='http://code.google.com/p/vimperator-labs/issues/list' o j k -:lazy fmaps -u='http://code.google.com/p/vimperator-labs/issues/detail' u - -
- - anekos - New BSD License - -

- Web コンテンツに直接キーイベントを送ります。 -

- - :fmap - :fmap -events=eventnamelist -xpath=xpath -frame=framenumber -urls=urlpattern -modes=modes lhs rhs - -

- マッピングを一つ定義します。 -

-

- -urls=urlpattern が与えられたとき、 - そのマッピングは urlpattern で指定されたページのみで有効になります。 -

-
-
- - :fmaps - :fmaps -events=eventnamelist -xpath=xpath -frame=framenumber -urls=urlpattern -pprefix=prefix -modes=modes mappingpair .... - -

- 一度に複数のマッピングを定義できます。 - mappingpair は、"," で区切られたキー名の組です。 -

例: "<Leader><S-j>,j"

-

-

- -urls=urlpattern が与えられたとき、 - そのマッピングは urlpattern で指定されたページのみで有効になります。 -

-
-
- - :fmapc - :fmapc! -modes=modes urlpattern - -

- urlpattern のマッピングを削除します。 - "!" が与えられたときは、全てのマッピングが削除されます。 -

-
-
- - :funmap - :funmap -urls=urlpattern -modes=modes lhs - -

- マッピングを削除します。 -

-

- urlpattern 付きのマッピングを削除するときは、-urls を指定する必要があります。 -

-
-
-

urlpattern

-

- urlpattern の値は正規表現でなければいけません。 -

-

eventnamelist

-

- eventnamelist は以下の値から構成されたリストです。 -

-
    -
  • keypress
  • -
  • keydown
  • -
  • keyup
  • -
  • vkeypress
  • -
  • vkeydown
  • -
  • vkeyup
  • -
-

"v..." のものは、仮想キーコードでイベントを発行します。

-

キー毎に、書かれた順にイベントが発行されます。

-

このオプションのデフォルト値は "keypress" です。

-

xpath

-

- キーイベントを送るべき要素を指定するための XPath。 -

-

framenumber

-

- キーイベントを送るべきフレームの番号。 - 番号は、補完を参考にしてください。 -

-

modes

-

- マップするモードのリスト (デフォルトは、NORMALモード) -

-

.vimperatorrc 用の fmaps サンプル

-

コマンドラインで直接に入力するときは、":lazy" を除いてください。

- -:command! -nargs=+ lazy autocmd VimperatorEnter .* <args> -:lazy fmaps -u='mail\.google\.com/mail' c / j k n p o u e x s r a # [ ] ? gi gs gt gd ga gc -:lazy fmaps -u='mail\.google\.com/mail/.*/[0-9a-f]+$' c / j,n k,p n,j p,k o u e x s r a # [ ] ? gi gs gt gd ga gc -:lazy fmaps -u='www\.google\.co\.jp/reader' -events=vkeypress j k n p m s v A r S N P X O gh ga gs gt gu u / ? J K -:lazy fmaps -u='(fastladder|livedoor)\.com/reader' j k s a p o v c i,p <Space> <S-Space> z b < > q w e,g -:lazy fmaps -u='https?://www\.rememberthemilk\.com/home/' j k m i c t ? d F,f G,g S,s L,l Y,y H,h M,m <Del> <C-S-Left> <C-S-Right> -:lazy fmaps -u='http://code.google.com/p/vimperator-labs/issues/list' o j k -:lazy fmaps -u='http://code.google.com/p/vimperator-labs/issues/detail' u - -
`; - -// }}} - -(function () { - - const EVENTS = 'keypress keydown keyup'.split(/\s+/); - const EVENTS_WITH_V = EVENTS.concat(['v' + n for each (n in EVENTS)]); - const IGNORE_URLS = //; - - const VKeys = { - '0': KeyEvent.DOM_VK_0, - '1': KeyEvent.DOM_VK_1, - '2': KeyEvent.DOM_VK_2, - '3': KeyEvent.DOM_VK_3, - '4': KeyEvent.DOM_VK_4, - '5': KeyEvent.DOM_VK_5, - '6': KeyEvent.DOM_VK_6, - '7': KeyEvent.DOM_VK_7, - '8': KeyEvent.DOM_VK_8, - '9': KeyEvent.DOM_VK_9, - ';': KeyEvent.DOM_VK_SEMICOLON, - '=': KeyEvent.DOM_VK_EQUALS, - 'a': KeyEvent.DOM_VK_A, - 'b': KeyEvent.DOM_VK_B, - 'c': KeyEvent.DOM_VK_C, - 'd': KeyEvent.DOM_VK_D, - 'e': KeyEvent.DOM_VK_E, - 'f': KeyEvent.DOM_VK_F, - 'g': KeyEvent.DOM_VK_G, - 'h': KeyEvent.DOM_VK_H, - 'i': KeyEvent.DOM_VK_I, - 'j': KeyEvent.DOM_VK_J, - 'k': KeyEvent.DOM_VK_K, - 'l': KeyEvent.DOM_VK_L, - 'm': KeyEvent.DOM_VK_M, - 'n': KeyEvent.DOM_VK_N, - 'o': KeyEvent.DOM_VK_O, - 'p': KeyEvent.DOM_VK_P, - 'q': KeyEvent.DOM_VK_Q, - 'r': KeyEvent.DOM_VK_R, - 's': KeyEvent.DOM_VK_S, - 't': KeyEvent.DOM_VK_T, - 'u': KeyEvent.DOM_VK_U, - 'v': KeyEvent.DOM_VK_V, - 'w': KeyEvent.DOM_VK_W, - 'x': KeyEvent.DOM_VK_X, - 'y': KeyEvent.DOM_VK_Y, - 'z': KeyEvent.DOM_VK_Z, - '*': KeyEvent.DOM_VK_MULTIPLY, - '+': KeyEvent.DOM_VK_ADD, - '-': KeyEvent.DOM_VK_SUBTRACT, - ',': KeyEvent.DOM_VK_COMMA, - '.': KeyEvent.DOM_VK_PERIOD, - '/': KeyEvent.DOM_VK_SLASH, - '?': KeyEvent.DOM_VK_SLASH, - '`': KeyEvent.DOM_VK_BACK_QUOTE, - '{': KeyEvent.DOM_VK_OPEN_BRACKET, - '\\': KeyEvent.DOM_VK_BACK_SLASH, - '}': KeyEvent.DOM_VK_CLOSE_BRACKET, - '\'': KeyEvent.DOM_VK_QUOTE - }; - - const State = { - feeding: false - }; - - function id (v) - v; - - function or (list, func) - (list.length && let ([head,] = list) (func(head) || or(list.slice(1), func))); - - function getFrames () { - function bodyCheck (content) - (content.document && content.document.body && content.document.body.localName.toLowerCase() === 'body'); - - function get (content) - (bodyCheck(content) && result.push(content), Array.slice(content.frames).forEach(get)); - - let result = []; - get(content); - return result; - } - - function fromXPath (doc, xpath) { - let result = util.evaluateXPath(xpath, doc); - return result.snapshotLength && result.snapshotItem(0); - } - - function createEvent (eventName, event) { - let result = content.document.createEvent('KeyEvents'); - result.initKeyEvent( - eventName, - true, - true, - content, - event.ctrlKey, - event.altKey, - event.shiftKey, - event.metaKey, - event.keyCode, - event.charCode - ); - return result; - } - - function virtualize (event) { - let cc = event.charCode; - if (/^[A-Z]$/.test(String.fromCharCode(cc))) - event.shiftKey = true; - event.keyCode = VKeys[String.fromCharCode(cc).toLowerCase()]; - event.charCode = 0; - return event; - } - - function feed (keys, eventNames, target) { - function finalize (){ - modes.passAllKeys = _passAllKeys; - State.feeding = false; - } - - State.feeding = true; - - let _passAllKeys = modes.passAllKeys; - - try { - modes.passAllKeys = true; - modes.passNextKey = false; - - for (let [, keyEvent] in Iterator(events.fromString(keys))) { - eventNames.forEach(function (eventName) { - let ke = util.cloneObject(keyEvent); - let [, vkey, name] = eventName.match(/^(v)?(.+)$/); - if (vkey) - virtualize(ke); - let event = createEvent(name, ke); - target.dispatchEvent(event); - }); - } - } catch (e) { - finalize(); - throw e; - } - - finalize(); - } - - function makeTryValidator (func) - function (value) { - try { - liberator.log(value); - func(value); - return true; - } catch (e) {} - return false; - }; - - let regexpValidator = makeTryValidator(RegExp); - - let xpathValidator = - makeTryValidator(function (expr) document.evaluate(expr, document, null, null, null)) - - function fromModeString (s){ - for (let [, {name, mask, char}] in Iterator(modes._modeMap)) - if (s === name || s === char) - return mask; - } - - function fromModeStrings (ss, def) { - if (def && (!ss || ss.length < 1)) - return [modes.NORMAL]; - return ss.map(fromModeString).filter(function (it) (typeof it === 'number')); - } - - function modeStringsValidator (ss) - (!ss || (fromModeStrings(ss).length === ss.length)); - - function makeListValidator (list) - function (values) - (values && !values.some(function (value) !list.some(function (event) event === value))); - - function findMappings ({all, filter, urls, ignoreUrls, not, result, modes: targetModes}) { - function match (map) { - let r = ( - map.feedSomeKeys && - (all || - (!filter || filter === map.names[0]) && - (ignoreUrls || urls === IGNORE_URLS || mappings._matchingUrlsTest(map, urls))) - ); - if (result && r) { - if (typeof result.matched === 'number') - result.matched++; - else - result.matched = 1; - } - return !!r ^ !!not; - } - - if (filter) - filter = mappings._expandLeader(filter); - if (urls) - urls = RegExp(urls); - - // FIXME 同じオブジェクトがダブって返るかも(あるいはそれで良い?) - let result = []; - for (let [, m] in Iterator(targetModes || [modes.NORMAL])) - result = result.concat(mappings._user[m].filter(match)); - - return result; - } - - function unmap (condition) { - condition = Object.create(condition); - let ms = condition.modes || [modes.NORMAL]; - condition.not = true; - condition.modes = undefined; - for (let [, m] in Iterator(ms)) { - condition.modes = [m]; - mappings._user[m] = findMappings(condition); - } - } - - function list (condition) { - let maps = findMappings(condition); - let template = modules.template; - let length = 0; - let list = - xml` - ${ - template.map(maps, function (map){ - ++length; - return template.map(map.names, function (name) - xml` - - - - `) - }) - } -
${name}${map.feedSomeKeys.rhs}${map.matchingUrls ? map.matchingUrls : '[Global]'}
`; - - if (length == 0) { - liberator.echomsg("No mapping found"); - return; - } - commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE); - } - - function fmapCompleter (context, args) { - context.title = ['name', 'rhs & url']; - context.completions = [ - [ - xml`${map.names[0]}, - - ${map.feedSomeKeys.rhs} - ${ - args['-ignoreurls'] - ? xml` for ${map.matchingUrls ? map.matchingUrls : 'Global'}` - : '' - } - ` - ] - for each (map in findMappings({urls: args['-urls'], ignoreUrls: args['-ignoreurls']})) - ]; - } - - function urlCompleter ({currentURL}) { - return function (context, args) { - let maps = findMappings({all: true}); - let uniq = {}; - let result = [ - (uniq[map.matchingUrls] = 1, [map.matchingUrls.source, map.names]) - for each (map in maps) - if (map.matchingUrls && !uniq[map.matchingUrls]) - ]; - if (currentURL) { - result.unshift(['^' + util.escapeRegex(buffer.URL), 'Current URL']); - if (content.document.domain) - result.unshift([util.escapeRegex(content.document.domain), 'Current domain']); - } - return result; - }; - } - - function frameCompleter (context, args) { - return [ - [i, frame.document.location] - for each ([i, frame] in Iterator(getFrames())) - ]; - } - - const ModeStringsCompleter = [ - [name, disp + ' mode' + (char ? ' (alias: ' + char + ')' : '')] - for ([n, {name, char, disp, extended}] in Iterator(modes._modeMap)) - if (!extended && /^\D+$/.test(n)) - ]; - - - 'fmap fmaps'.split(/\s+/).forEach(function (cmd) { - let multi = cmd === 'fmaps'; - - function action (multi) { - return function (args) { - let prefix = args['-prefix'] || ''; - let ms = fromModeStrings(args['-modes'], true); - - function add ([lhs, rhs]) { - if (!lhs) - return; - - rhs = rhs || lhs; - mappings.addUserMap( - ms, - [prefix + lhs], - args['description'] || 'by feedSomeKeys_3.js', - function () { - function body (win) - (win.document.body || win.document); - - let win = document.commandDispatcher.focusedWindow; - let frames = getFrames(); - - let elem = liberator.focus || body(win); - - if (typeof args['-frame'] !== 'undefined') { - frames = [frames[args['-frame']]]; - elem = body(frames[0]); - } - - if (args['-xpath']) { - elem = or(frames, function (f) fromXPath(f.document, args['-xpath'])) || elem; - } - - if (args['-selector']) { - elem = or(frames, function (f) f.document.querySelector(args['-selector'])) || elem; - } - - feed(rhs, args['-events'] || ['keypress'], elem); - }, - { - matchingUrls: args['-urls'], - feedSomeKeys: { - rhs: rhs, - } - }, - true - ); - } - - if (multi) { - let sep = let (s = args['-separator'] || ',') function (v) v.split(s); - args.literalArg.split(/\s+/).map(String.trim).map(sep).forEach(add); - } else { - let [, lhs, rhs] = args.literalArg.match(/^(\S+)\s+(.*)$/) || args.literalArg; - if (!rhs) { - list({ - filter: prefix + args.literalArg.trim(), - urls: args['-urls'], - ignoreUrls: !args['-urls'], - modes: ms - }); - } else { - add([lhs, rhs]); - } - } - }; - } - - commands.addUserCommand( - [cmd], - 'Feed map a key sequence', - action(multi), - { - literal: 0, - options: [ - [['-modes', '-m'], commands.OPTION_LIST, modeStringsValidator, ModeStringsCompleter], - [['-urls', '-u'], commands.OPTION_STRING, regexpValidator, urlCompleter({currentURL: true})], - [['-desc', '-description', '-d'], commands.OPTION_STRING], - [['-frame', '-f'], commands.OPTION_INT, null, frameCompleter], - [['-xpath', '-x'], commands.OPTION_STRING, xpathValidator], - [['-selector', '-s'], commands.OPTION_STRING], - [['-prefix', '-p'], commands.OPTION_STRING], - [ - ['-events', '-e'], - commands.OPTION_LIST, - makeListValidator(EVENTS_WITH_V), - EVENTS_WITH_V.map(function (v) [v, v]) - ] - ].concat( - multi ? [[['-separator', '-s'], commands.OPTION_STRING]] - : [] - ), - completer: multi ? null : fmapCompleter - }, - true - ); - }); - - commands.addUserCommand( - ['fmapc'], - 'Clear fmappings', - function (args) { - let ms = fromModeStrings(args['-modes'], true); - if (args.bang) { - unmap({ignoreUrls: true, modes: ms}); - liberator.log('All fmappings were removed.'); - } else { - let result = {}; - unmap({urls: args.literalArg, result: result, modes: ms}); - liberator.echo(result.matched ? 'Some fmappings were removed.' : 'Not found specifed fmappings.'); - } - }, - { - literal: 0, - bang: true, - completer: function (context) { - context.title = ['URL Pattern']; - context.completions = urlCompleter({})(context); - }, - options: [ - [['-modes', '-m'], commands.OPTION_LIST], - ] - }, - true - ); - - commands.addUserCommand( - ['funmap'], - 'Remove fmappings', - function (args) { - let urls = args['-urls']; - let name = args.literalArg; - if (!name) - return liberator.echoerr('E471: Argument required'); - - let result = {}; - unmap({ - filter: name, - urls: urls, - ignoreUrls: args['-ignoreurls'], - result: result, - modes: fromModeStrings(args['-modes'], true) - }); - liberator.echo(result.matched ? 'Some fmappings were removed.' : 'Not found specifed fmappings.'); - }, - { - literal: 0, - options: [ - [['-modes', '-m'], commands.OPTION_LIST], - [['-urls', '-u'], commands.OPTION_STRING, regexpValidator, urlCompleter({})], - [['-ignoreurls', '-iu'], commands.OPTION_NOARG] - ], - completer: fmapCompleter - }, - true - ); - - plugins.libly.$U.around( - mappings, - 'getCandidates', - function (next, [mode, prefix, patternOrUrl]) { - let map = mappings.get(mode, prefix, patternOrUrl); - if (map && map.matchingUrls) - return []; - return next(); - } - ); - - __context__.API = - 'State VKeys feed getFrames fromXPath virtualize unmap findMappings list'.split(/\s+/).reduce( - function (result, name) - (result[name] = eval(name), result), - {} - ); - -})(); - -// vim:sw=2 ts=2 et si fdm=marker: diff --git a/vimperator/plugin/wallabag.js b/vimperator/plugin/wallabag.js deleted file mode 100644 index 363677b..0000000 --- a/vimperator/plugin/wallabag.js +++ /dev/null @@ -1,35 +0,0 @@ -let PLUGIN_INFO = xml` - - wallabag - Pocket - 0.1.1 - 3.2 - Philipp Schmitt - https://raw.github.com/pschmitt/vimperator-wallabag/master/wallabag.js - -`; - -(function() { - - let wallabag_url = (liberator.globalVariables.wallabag_url) ? liberator.globalVariables.wallabag_url : ''; - - commands.addUserCommand(['wallabag', 'wg'], 'Wallabag plugin', - function(args) { - let url = buffer.URL; - - if (typeof args != 'undefined' && args.length > 0) { - url = args; - } - - if (wallabag_url == '') { - liberator.echoerr('Wallabag URL undefined. Please add let g:wallabag_url="http://YOURURL" to your vimperatorrc'); - } else { - liberator.open(wallabag_url + '/?action=add&url=' + btoa(url), liberator.NEW_TAB); - } - } - ); - - -})(); diff --git a/vimperatorrc b/vimperatorrc deleted file mode 100644 index cea513a..0000000 --- a/vimperatorrc +++ /dev/null @@ -1,55 +0,0 @@ -set runtimepath=~/etc/vimperator - -set gui=none,tabs -"set tabnumbers - -set defsearch=g - -" follow hints on return -set followhints=1 - -" don't auto-focus input fields -set focuscontent - -set incsearch hlsearch -set ignorecase smartcase - -set noerrorbells novisualbell -js liberator.beep = function() { return false; } - -map d :tabclose - -" google -map s og -map S tg - -" fast scrolling -noremap j -noremap k - -let g:wallabag_url="https://wllbg.gebner.org" - -js <