diff --git a/README.md b/README.md index d8f37c5..af44253 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,28 @@ + ### Maddy's SurfingKeys Configuration This is my personal configuration for the wonderful [SurfingKeys](https://github.com/brookhong/Surfingkeys) Chrome Extension. +#### Table of Contents -It currently includes Search Engine auto-completions for 31 sites, -along with some convenience functions and key remappings. + 1. [Bundled Search Engine Completions](#bundled-search-engine-completions) + 2. [Installation Instructions](#installation) -| Alias | Name | Domain | +#### Bundled Search Engine Completions + +There are currently 36 Search Engine auto-completions. + +You can a Search Engine auto-completion by pressing the search leader key, which is `a` by default, followed by the search engine alias. + +For example, to open the Wikipedia completion, you would type `awp` while in normal mode. + +| Alias | Name | Domain | | ---- | ------ | ----- | | `al` | `archlinux` | `www.archlinux.org` | | `au` | `AUR` | `aur.archlinux.org` | @@ -20,9 +36,10 @@ along with some convenience functions and key remappings. | `dg` | `duckduckgo` | `duckduckgo.com` | | `dh` | `dockerhub` | `hub.docker.com` | | `do` | `domainr` | `domainr.com` | -| `ex` | `hexdocs` | `hex.pm` | +| `ex` | `exdocs` | `hex.pm` | | `gd` | `godoc` | `godoc.org` | | `gh` | `github` | `github.com` | +| `gl` | `google-lucky` | `www.google.com` | | `go` | `google` | `www.google.com` | | `gs` | `go-search` | `go-search.org` | | `ha` | `hackage` | `hackage.haskell.org` | @@ -34,49 +51,76 @@ along with some convenience functions and key remappings. | `hy` | `hayoo` | `hayoo.fh-wedel.de` | | `md` | `mdn` | `developer.mozilla.org` | | `np` | `npm` | `www.npmjs.com` | +| `ow` | `owasp` | `www.owasp.org` | | `re` | `reddit` | `www.reddit.com` | | `so` | `stackoverflow` | `stackoverflow.com` | +| `th` | `thesaurus` | `www.onelook.com` | +| `vw` | `vimwikia` | `vim.wikia.com` | +| `wa` | `wolframalpha` | `www.wolframalpha.com` | | `wp` | `wikipedia` | `en.wikipedia.org` | | `yp` | `yelp` | `www.yelp.com` | | `yt` | `youtube` | `www.youtube.com` | + #### Installation -You'll need `git`, `node`, and `gulp`. +##### Dependencies -First, clone the repo: + - `git` + - `node` + - `gulp`. + +##### 1. Clone ```shell $ git clone http://github.com/b0o/surfingkeys-conf $ cd surfingkeys-conf ``` -Next, follow the instructions inside [conf.priv.example.js](conf.priv.example.js). -If you don't want to add any API keys, just copy the file as instructed but leave it as-is: - -```shell -$ cp ./conf.priv.example.js ./conf.priv.js -``` - -Next, run `npm install`: +##### 2. NPM Install ```shell $ npm install ``` -Run `gulp install`. -This will build the final configuration file and place it in `~/.surfingkeys`. -If you already have a file in that location, make sure you back it up first! +##### 3. Private API Key Configuration + +Copy the example private configuration: + +```shell +$ cp ./conf.priv.example.js ./conf.priv.js +``` + +Open `./conf.priv.js` in your favorite editor and follow the instructions inside: + +```shell +$ vim ./conf.priv.js +``` + +##### 4. Gulp Build/Install ```shell $ gulp install ``` -In order to reference a local file, you need to check __Allow access to file URLs__ in [chrome://extensions/](chrome://extensions/) for the SurfingKeys extension. +This will build the final configuration file and place it in `~/.surfingkeys`. +If you already have a file in that location, make sure you back it up first! -Finally, you'll need to open the SurfingKeys [configuration page](chrome-extension://mffcegbjcdejldmihkogmcnkgbbhioid/pages/options.html) and set the __Load settings from__ option to __"file:///home/YOUR_USERNAME_HERE/.surfingkeys"__. (This is for Unix-like Operating Systems. For Windows, you'll need to figure out the proper path) +##### 5. Load your configuration in the SurfingKeys Extension -If you make a change to __conf.js__ in the future, simply run `gulp install` again. +The final step is to tell SurfingKeys where to find your configuration file: + + - __I.__ Visit [`chrome://extensions/`](chrome://extensions/) and enable `Allow access to file URLs` for the Surfingkeys extension + + - __II.__ Open the SurfingKeys [configuration page](chrome-extension://mffcegbjcdejldmihkogmcnkgbbhioid/pages/options.html) + + - __III.__ Set __Load settings from__ option to the correct path (substituting `$USER` for your username): + - __Linux, MacOS, Unix__: `file:///home/$USER/.surfingkeys` + - __Windows__: `file://%Homedrive%%Homepath%/.surfingkeys` (This is a guess, please correct me if I'm wrong.) + +##### 6. Hack Away! + +If you ever make a change to any of your configuration files in the future, simply run `gulp install` again and your settings will be immediately updated. ### License ©2017 Maddison Hellstrom - MIT License diff --git a/README.tmpl.md b/README.tmpl.md new file mode 100644 index 0000000..d3c5a2b --- /dev/null +++ b/README.tmpl.md @@ -0,0 +1,84 @@ + +### Maddy's SurfingKeys Configuration + +This is my personal configuration for the wonderful [SurfingKeys](https://github.com/brookhong/Surfingkeys) Chrome Extension. + +#### Table of Contents + + 1. [Bundled Search Engine Completions](#bundled-search-engine-completions) + 2. [Installation Instructions](#installation) + +#### Bundled Search Engine Completions + +There are currently Search Engine auto-completions. + +You can a Search Engine auto-completion by pressing the search leader key, which is `a` by default, followed by the search engine alias. + +For example, to open the Wikipedia completion, you would type `awp` while in normal mode. + +| Alias | Name | Domain | +| ---- | ------ | ----- | + + +#### Installation + +##### Dependencies + + - `git` + - `node` + - `gulp`. + +##### 1. Clone + +```shell +$ git clone http://github.com/b0o/surfingkeys-conf +$ cd surfingkeys-conf +``` + +##### 2. NPM Install + +```shell +$ npm install +``` + +##### 3. Private API Key Configuration + +Copy the example private configuration: + +```shell +$ cp ./conf.priv.example.js ./conf.priv.js +``` + +Open `./conf.priv.js` in your favorite editor and follow the instructions inside: + +```shell +$ vim ./conf.priv.js +``` + +##### 4. Gulp Build/Install + +```shell +$ gulp install +``` + +This will build the final configuration file and place it in `~/.surfingkeys`. +If you already have a file in that location, make sure you back it up first! + +##### 5. Load your configuration in the SurfingKeys Extension + +The final step is to tell SurfingKeys where to find your configuration file: + + - __I.__ Visit [`chrome://extensions/`](chrome://extensions/) and enable `Allow access to file URLs` for the Surfingkeys extension + + - __II.__ Open the SurfingKeys [configuration page](chrome-extension://mffcegbjcdejldmihkogmcnkgbbhioid/pages/options.html) + + - __III.__ Set __Load settings from__ option to the correct path (substituting `$USER` for your username): + - __Linux, MacOS, Unix__: `file:///home/$USER/.surfingkeys` + - __Windows__: `file://%Homedrive%%Homepath%/.surfingkeys` (This is a guess, please correct me if I'm wrong.) + +##### 6. Hack Away! + +If you ever make a change to any of your configuration files in the future, simply run `gulp install` again and your settings will be immediately updated. + +### License +©2017 Maddison Hellstrom - MIT License diff --git a/completions.js b/completions.js new file mode 100644 index 0000000..ad48c23 --- /dev/null +++ b/completions.js @@ -0,0 +1,851 @@ +var keys = keys +if (!keys && typeof require === 'function') { + keys = require("./conf.priv.js") +} + +var completions = [ + { alias: 'al' + , name: 'archlinux' + , search: 'https://www.archlinux.org/packages/?arch=x86_64&q=' + , compl: '' + , callback: function() {} + }, + { alias: 'au' + , name: 'AUR' + , search: 'https://aur.archlinux.org/packages/?O=0&SeB=nd&outdated=&SB=v&SO=d&PP=100&do_Search=Go&K=' + , compl: 'https://aur.archlinux.org/rpc?type=suggest&arg=' + , callback: function(response) { + var res = JSON.parse(response.text); + Omnibar.listResults(res, function(s) { + return Omnibar.createURLItem({ + title: s, + url: "https://aur.archlinux.org/packages/" + s + }); + }); + } + }, + { alias: 'aw' + , name: 'archwiki' + , search: 'https://wiki.archlinux.org/index.php?go=go&search=' + , compl: 'https://wiki.archlinux.org/api.php?action=opensearch&format=json&formatversion=2&namespace=0&limit=10&suggest=true&search=' + , callback: function(response) { + Omnibar.listWords(JSON.parse(response.text)[1]); + } + }, + { alias: 'ow' + , name: 'owasp' + , search: 'https://www.owasp.org/index.php?go=go&search=' + , compl: 'https://www.owasp.org/api.php?action=opensearch&format=json&formatversion=2&namespace=0&limit=10&suggest=true&search=' + , callback: function(response) { + Omnibar.listWords(JSON.parse(response.text)[1]); + } + }, + { alias: 'vw' + , name: 'vimwikia' + , search: 'https://vim.wikia.com/wiki/Special:Search?query=' + , compl: 'https://vim.wikia.com/api.php?action=opensearch&format=json&formatversion=2&namespace=0&limit=10&suggest=true&search=' + , callback: function(response) { + Omnibar.listWords(JSON.parse(response.text)[1]); + } + }, + { alias: 'az' + , name: 'amazon' + , search: 'https://smile.amazon.com/s/?field-keywords=' + , compl: 'https://completion.amazon.com/search/complete?method=completion&mkt=1&search-alias=aps&q=' + , callback: function(response) { + var res = JSON.parse(response.text)[1]; + Omnibar.listWords(res); + } + }, + { alias: 'cl' + , name: 'craigslist' + , search: 'https://craigslist.org/search/sss?query=' + , compl: 'https://craigslist.org/suggest?v=12&type=search&cat=sss&area=1&term=' + , callback: function(response) { + Omnibar.listWords(JSON.parse(response.text)); + } + }, + { alias: 'wa' + , name: 'wolframalpha' + , search: 'http://www.wolframalpha.com/input/?i=' + , compl: `http://api.wolframalpha.com/v2/query?appid=${keys.wolframalpha}&format=plaintext&output=json&reinterpret=true&input=%s` + , callback: function(response) { + var res = JSON.parse(response.text).queryresult; + + if (res.error) { + Omnibar.listResults([""], function() { + var li = $('
  • ').html(` +
    +
    Error (Code ${res.error.code})
    +
    ${res.error.msg}
    +
    + `); + return li; + }); + return; + } + + if (!res.success) { + if (res.tips) { + Omnibar.listResults([""], function() { + var li = $('
  • ').html(` +
    +
    No Results
    +
    ${res.tips.text}
    +
    + `); + return li; + }); + } + if (res.didyoumeans) { + Omnibar.listResults(res.didyoumeans, function(s) { + var li = $('
  • ').html(` +
    +
    Did you mean...?
    +
    ${s.val}
    +
    + `); + return li; + }); + } + return; + } + + var results = []; + res.pods.map(function(p){ + var result = { + title: p.title, + values: [], + url: "http://www.wolframalpha.com/input/?i=", + }; + if (p.numsubpods > 0) { + result.url += encodeURIComponent(p.subpods[0].plaintext); + p.subpods.map(function(sp) { + if (!sp.plaintext) return; + var v = ""; + if (sp.title) { + v += `${sp.title}: `; + } + v += sp.plaintext; + result.values.push(`
    ${v}
    `); + }); + } + if (result.values.length > 0) { + results.push(result); + } + }); + + Omnibar.listResults(results, function(r) { + var li = $('
  • ').html(` +
    +
    ${r.title}
    + ${r.values.join("\n")} +
    + `); + li.data('url', r.url); + return li; + }); + } + }, + { alias: 'co' + , name: 'crunchbase-orgs' + , search: 'https://www.crunchbase.com/app/search/?q=' + , compl: `https://api.crunchbase.com/v/3/odm_organizations?user_key=${keys.crunchbase}&query=%s` + , callback: function(response) { + var res = JSON.parse(response.text).data.items; + var orgs = []; + res.map(function(rr){ + var r = rr.properties; + var p = { + name: r.name, + domain: r.domain, + desc: r.short_description, + role: r.primary_role, + img: blank, + loc: "", + url: "https://www.crunchbase.com/" + r.web_path + }; + + p.loc += (r.city_name !== null) ? r.city_name : ""; + p.loc += (r.region_name !== null && p.loc !== "") ? ", " : ""; + p.loc += (r.region_name !== null) ? r.region_name : ""; + p.loc += (r.country_code !== null && p.loc !== "") ? ", " : ""; + p.loc += (r.country_code !== null) ? r.country_code : ""; + p.loc += (p.loc === "") ? "Earth" : ""; + + if (r.profile_image_url !== null) { + var url = r.profile_image_url + , path = url.split('/') + , img = path[path.length-1]; + p.img = "http://public.crunchbase.com/t_api_images/v1402944794/c_pad,h_50,w_50/" + img; + } + + orgs.push(p); + }); + + Omnibar.listResults(orgs, function(p) { + var li = $('
  • ').html(` +
    +
    + ${p.name} +
    +
    +
    ${p.name}
    +
    Type: ${p.role}, Domain: ${p.domain}
    +
    ${p.desc}
    +
    ${p.loc}
    +
    +
    + `); + li.data('url', p.url); + return li; + }); + } + }, + { alias: 'cp' + , name: 'crunchbase-people' + , search: 'https://www.crunchbase.com/app/search/?q=' + , compl: `https://api.crunchbase.com/v/3/odm_people?user_key=${keys.crunchbase}&query=%s` + , callback: function(response) { + var res = JSON.parse(response.text).data.items; + var people = []; + res.map(function(rr){ + var r = rr.properties; + var p = { + name: r.first_name + " " + r.last_name, + desc: "", + img: blank, + loc: "", + url: "https://www.crunchbase.com/" + r.web_path + }; + + p.desc += (r.title !== null) ? r.title : ""; + p.desc += (r.organization_name !== null && p.desc !== "") ? ", " : ""; + p.desc += (r.organization_name !== null) ? r.organization_name : ""; + p.desc += (p.desc === "") ? "Human" : ""; + + p.loc += (r.city_name !== null) ? r.city_name : ""; + p.loc += (r.region_name !== null && p.loc !== "") ? ", " : ""; + p.loc += (r.region_name !== null) ? r.region_name : ""; + p.loc += (r.country_code !== null && p.loc !== "") ? ", " : ""; + p.loc += (r.country_code !== null) ? r.country_code : ""; + p.loc += (p.loc === "") ? "Earth" : ""; + + if (r.profile_image_url !== null) { + var url = r.profile_image_url + , path = url.split('/') + , img = path[path.length-1]; + p.img = "http://public.crunchbase.com/t_api_images/v1402944794/c_pad,h_50,w_50/" + img; + } + + people.push(p); + }); + + Omnibar.listResults(people, function(p) { + var li = $('
  • ').html(` +
    +
    + ${p.name} +
    +
    +
    ${p.name}
    +
    ${p.desc}
    +
    ${p.loc}
    +
    +
    + `); + li.data('url', p.url); + return li; + }); + } + }, + { alias: 'cs' + , name: 'chromestore' + , search: 'https://chrome.google.com/webstore/search/' + , compl: '' + , callback: function() {} + }, + { alias: 'th' + , name: 'thesaurus' + , search: 'https://www.onelook.com/reverse-dictionary.shtml?s=' + , compl: 'https://api.datamuse.com/words?md=d&ml=%s' + , callback: function(response) { + var res = JSON.parse(response.text); + var defs = []; + res.map(function(r){ + if (!r.defs || r.defs.length === 0) { + defs.push([r.word, "", ""]); + return; + } + r.defs.map(function(d) { + d = d.split("\t"); + + var sp = "(" + d[0] + ")", + def = d[1]; + + defs.push([r.word, sp, def]); + }); + }); + Omnibar.listResults(defs, function(d) { + var li = $('
  • ').html(`
    ${d[0]} ${d[1]} ${d[2]}
    `); + li.data('url', "http://onelook.com/?w=" + d[0]); + return li; + }); + } + }, + { alias: 'de' + , name: 'define' + , search: 'http://onelook.com/?w=' + , compl: 'https://api.datamuse.com/words?md=d&sp=%s*' + , callback: function(response) { + var res = JSON.parse(response.text); + var defs = []; + res.map(function(r){ + if (!r.defs || r.defs.length === 0) { + defs.push([r.word, "", ""]); + return; + } + r.defs.map(function(d) { + d = d.split("\t"); + + var sp = "(" + d[0] + ")", + def = d[1]; + + defs.push([r.word, sp, def]); + }); + }); + Omnibar.listResults(defs, function(d) { + var li = $('
  • ').html(`
    ${d[0]} ${d[1]} ${d[2]}
    `); + li.data('url', "http://onelook.com/?w=" + d[0]); + return li; + }); + } + }, + { alias: 'dg' + , name: 'duckduckgo' + , search: 'https://duckduckgo.com/?q=' + , compl: 'https://duckduckgo.com/ac/?q=' + , callback: function(response) { + var res = JSON.parse(response.text).map(function(r){ + return r.phrase; + }); + Omnibar.listWords(res); + } + }, + { alias: 'dh' + , name: 'dockerhub' + , search: 'https://hub.docker.com/search/?page=1&q=' + , compl: 'https://hub.docker.com/v2/search/repositories/?page_size=20&query=' + , callback: function(response) { + var res = JSON.parse(response.text); + Omnibar.listResults(res.results, function(s) { + var meta = "" + , repo = s.repo_name; + meta += "[★" + s.star_count + "] "; + meta += "[↓" + s.pull_count + "] "; + if (repo.indexOf("/") === -1) { + repo = "_/" + repo; + } + var li = $('
  • ').html(` +
    +
    ${s.repo_name}
    +
    ${meta}
    +
    ${s.short_description}
    +
    + `); + li.data('url', "https://hub.docker.com/r/" + repo); + return li; + }); + } + }, + { alias: 'do' + , name: 'domainr' + , search: 'https://domainr.com/?q=' + , compl: `https://api.domainr.com/v2/search?client_id=${keys.domainr}&query=%s` + , callback: function(response) { + var res = JSON.parse(response.text).results; + var domains = []; + res.map(function(r){ + var d = { + id: r.domain.replace('.', '-'), + domain: r.domain + }; + domains.push(d); + }); + + var domainQuery = domains.map(function(d) { return d.domain; }).join(','); + + runtime.command({ + action: 'request', + method: 'get', + url: `https://api.domainr.com/v2/status?client_id=${keys.domainr}&domain=${domainQuery}` + }, function(sresponse) { + var sres = JSON.parse(sresponse.text).status; + sres.map(function(s) { + var id = "#sk-domain-" + s.domain.replace('.', '-') + , available = s.summary === "inactive" + , color = available ? "#23b000" : "#ff4d00" + , symbol = available ? "✔ " : "✘ "; + $(id).text(symbol + $(id).text()).css("color", color); + }); + }); + + Omnibar.listResults(domains, function(d) { + var li = $('
  • ').html(` +
    +
    ${d.domain}
    +
    + `); + li.data('url', `https://domainr.com/${d.domain}`); + return li; + }); + } + }, + { alias: 'ex' // Similar to `hd` but searches inside docs using Google Custom Search + , name: 'exdocs' + , search: 'https://hex.pm/packages?sort=downloads&search=' + , compl: `https://www.googleapis.com/customsearch/v1?key=${keys.google_ex}&cx=${keys.google_ex_cx}&q=` + , callback: function(response) { + var res = JSON.parse(response.text).items; + Omnibar.listResults(res, function(s) { + var snippet = s.htmlSnippet; + var hash = ""; + + // Hacky way to extract the desired function's + // signature to use as an anchor because + // Google Custom Search doesn't link to the appropriate + // section of the documentation page + // A regex would probably work better. + (function() { + var openTag = "" + , closeTag = "" + , openArgs = "(" + , closeArgs = ")"; + + var f1 = snippet.indexOf(openTag); + if (f1 === -1) { + return; + } + var f2 = snippet.indexOf(closeTag); + if (f2 === -1) { + return; + } + + f1 += openTag.length; + f3 = f2 + closeTag.length; + fname = snippet.slice(f1, f2); + snippetEnd = snippet.slice(f3); + + var a1 = snippetEnd.indexOf(openArgs); + if (a1 !== 0) { + return; + } + var a2 = snippetEnd.indexOf(closeArgs); + if (a2 === -1) { + return; + } + + a2 += closeArgs.length; + var fargs = snippetEnd.slice(a1, a2); + var fary = fargs.replace(new RegExp(openArgs + closeArgs), '').split(',').length; + hash = fname + '/' + fary; + })(); + + var moduleName = s.title.split(' –')[0]; + + var subtitle = ""; + if (hash) { + subtitle = ` +
    + ${moduleName}.${hash} +
    `; + } + var li = $('
  • ').html(` +
    +
    ${s.htmlTitle}
    + ${subtitle} +
    ${s.htmlSnippet}
    +
    + `); + li.data('url', s.link + "#" + hash); + return li; + }); + } + }, + { alias: 'gd' + , name: 'godoc' + , search: 'https://godoc.org/?q=' + , compl: 'https://api.godoc.org/search?q=' + , callback: function(response) { + var res = JSON.parse(response.text).results; + Omnibar.listResults(res, function(s) { + var prefix = ""; + if (s.import_count) { + prefix += "[↓" + s.import_count + "] "; + } + if (s.stars) { + prefix += "[★" + s.stars + "] "; + } + return Omnibar.createURLItem({ + title: prefix + s.path, + url: "https://godoc.org/" + s.path + }); + }); + } + }, + { alias: 'gh' + , name: 'github' + , search: 'https://github.com/search?q=' + , compl: 'https://api.github.com/search/repositories?sort=stars&order=desc&q=' + , callback: function(response) { + var res = JSON.parse(response.text).items; + Omnibar.listResults(res, function(s) { + var prefix = ""; + if (s.stargazers_count) { + prefix += "[★" + s.stargazers_count + "] "; + } + return Omnibar.createURLItem({ + title: prefix + s.full_name, + url: s.html_url + }); + }); + } + }, + { alias: 'go' + , name: 'google' + , search: 'https://www.google.com/search?q=' + , compl: 'https://www.google.com/complete/search?client=chrome-omni&gs_ri=chrome-ext&oit=1&cp=1&pgcl=7&q=' + , callback: function(response) { + Omnibar.listWords(JSON.parse(response.text)[1]); + } + }, + { alias: 'gl' + , name: 'google-lucky' + , search: 'https://www.google.com/search?btnI=1&q=' + , compl: 'https://www.google.com/complete/search?client=chrome-omni&gs_ri=chrome-ext&oit=1&cp=1&pgcl=7&q=' + , callback: function(response) { + Omnibar.listWords(JSON.parse(response.text)[1]); + } + }, + { alias: 'gs' + , name: 'go-search' + , search: 'http://go-search.org/search?q=' + , compl: 'http://go-search.org/api?action=search&q=' + , callback: function(response) { + var res = JSON.parse(response.text).hits + .map(function(r){ + return r.package; + }); + Omnibar.listWords(res); + } + }, + { alias: 'ha' + , name: 'hackage' + , search: 'https://hackage.haskell.org/packages/search?terms=' + , compl: 'https://hackage.haskell.org/packages/search.json?terms=' + , callback: function(response) { + var res = JSON.parse(response.text); + Omnibar.listResults(res, function(s) { + return Omnibar.createURLItem({ + title: s.name, + url: 'https://hackage.haskell.org/package/' + s.name + }); + }); + } + }, + { alias: 'hd' // Same as hex but links to documentation pages + , name: 'hexdocs' + , search: 'https://hex.pm/packages?sort=downloads&search=' + , compl: 'https://hex.pm/api/packages?sort=downloads&search=' + , callback: function(response) { + var res = JSON.parse(response.text); + Omnibar.listResults(res, function(s) { + var dls = "" + , desc = "" + , liscs = ""; + if (s.downloads && s.downloads.all) { + dls = "[↓" + s.downloads.all + "]"; + } + if(s.meta) { + if (s.meta.description) { + desc = s.meta.description; + } + if (s.meta.licenses) { + s.meta.licenses.forEach(function(l) { + liscs += "[©" + l + "] "; + }); + } + } + var li = $('
  • ').html(` +
    +
    ${s.repository}/${s.name}
    +
    ${dls}${liscs}
    +
    ${desc}
    +
    + `); + li.data('url', "https://hexdocs.pm/" + s.name); + return li; + }); + } + }, + { alias: 'hn' + , name: 'hackernews' + , search: 'https://hn.algolia.com/?query=' + , compl: 'https://hn.algolia.com/api/v1/search?tags=(story,comment)&query=' + , callback: function(response) { + var res = JSON.parse(response.text).hits; + Omnibar.listResults(res, function(s) { + var title = ""; + var prefix = ""; + if (s.points) { + prefix += "[↑" + s.points + "] "; + } + if (s.num_comments) { + prefix += "[↲" + s.num_comments + "] "; + } + switch(s._tags[0]) { + case "story": + title = s.title; + break; + case "comment": + title = s.comment_text; + break; + default: + title = s.objectID; + } + return Omnibar.createURLItem({ + title: prefix + title, + url: "https://news.ycombinator.com/item?id=" + s.objectID + }); + }); + } + }, + { alias: 'ho' + , name: 'hoogle' + , search: 'https://www.haskell.org/hoogle/?hoogle=' + + encodeURIComponent("+platform +xmonad +xmonad-contrib ") // This tells Hoogle to include these modules in the search - encodeURIComponent is only used for better readability + , compl: 'https://www.haskell.org/hoogle/?mode=json&hoogle=' + + encodeURIComponent("+platform +xmonad +xmonad-contrib ") + , callback: function(response) { + var res = JSON.parse(response.text).results; + Omnibar.listResults(res, function(s) { + return Omnibar.createURLItem({ + title: s.self, + url: s.location + }); + }); + } + }, + { alias: 'hw' + , name: 'haskellwiki' + , search: 'https://wiki.haskell.org/index.php?go=go&search=' + , compl: 'https://wiki.haskell.org/api.php?action=opensearch&format=json&formatversion=2&namespace=0&limit=10&suggest=true&search=' + , callback: function(response) { + Omnibar.listWords(JSON.parse(response.text)[1]); + } + }, + { alias: 'hx' + , name: 'hex' + , search: 'https://hex.pm/packages?sort=downloads&search=' + , compl: 'https://hex.pm/api/packages?sort=downloads&search=' + , callback: function(response) { + var res = JSON.parse(response.text); + Omnibar.listResults(res, function(s) { + var dls = "" + , desc = "" + , liscs = ""; + if (s.downloads && s.downloads.all) { + dls = "[↓" + s.downloads.all + "] "; + } + if(s.meta) { + if (s.meta.description) { + desc = s.meta.description; + } + if (s.meta.licenses) { + s.meta.licenses.forEach(function(l) { + liscs += "[©" + l + "] "; + }); + } + } + var li = $('
  • ').html(` +
    +
    ${s.repository}/${s.name}
    +
    ${dls}${liscs}
    +
    ${desc}
    +
    + `); + li.data('url', s.html_url); + return li; + }); + } + }, + { alias: 'hy' + , name: 'hayoo' + , search: 'http://hayoo.fh-wedel.de/?query=' + , compl: 'http://hayoo.fh-wedel.de/json?query=' + , callback: function(response) { + var res = JSON.parse(response.text).result; + Omnibar.listResults(res, function(s) { + return Omnibar.createURLItem({ + title: "[" + s.resultType + "] " + s.resultName, + url: s.resultUri + }); + }); + } + }, + { alias: 'md' + , name: 'mdn' + , search: 'https://developer.mozilla.org/en-US/search?q=' + , compl: 'https://developer.mozilla.org/en-US/search.json?q=' + , callback: function(response) { + var res = JSON.parse(response.text); + Omnibar.listResults(res.documents, function(s) { + var excerpt = s.excerpt; + if(excerpt.length > 240) { + excerpt = excerpt.slice(0, 240) + '…'; + } + res.query.split(" ").forEach(function(q) { + excerpt = excerpt.replace(new RegExp(q, 'gi'), "$&"); + }); + var li = $('
  • ').html(` +
    +
    ${s.title}
    +
    ${s.slug}
    +
    ${excerpt}
    +
    + `); + li.data('url', s.url); + return li; + }); + } + }, + { alias: 'np' + , name: 'npm' + , search: 'https://www.npmjs.com/search?q=' + , compl: 'https://api.npms.io/v2/search/suggestions?size=20&q=' + , callback: function(response) { + var res = JSON.parse(response.text); + Omnibar.listResults(res, function(s) { + var flags = "" + , desc = "" + , stars = ""; + if (s.package.description) { + desc = s.package.description; + } + if(s.score) { + if (s.score.final) { + score = Math.round(s.score.final * 5); + stars = "★".repeat(score) + "☆".repeat(5-score); + } + } + if (s.flags) { + Object.keys(s.flags).forEach(function(f) { + flags += "[ " + f + "] "; + }); + } + var li = $('
  • ').html(` +
    + +
    ${s.highlight}
    +
    + ${stars} + ${flags} +
    +
    ${desc}
    +
    + `); + li.data('url', s.package.links.npm); + return li; + }); + } + }, + { alias: 're' + , name: 'reddit' + , search: 'https://www.reddit.com/search?sort=relevance&t=all&q=' + , compl: 'https://api.reddit.com/search?syntax=plain&sort=relevance&limit=20&q=' + , callback: function(response) { + var res = JSON.parse(response.text).data.children; + Omnibar.listResults(res, function(s) { + var d = s.data; + return Omnibar.createURLItem({ + title: "[" + d.score + "] " + d.title, + url: "https://reddit.com" + d.permalink + }); + }); + } + }, + { alias: 'so' + , name: 'stackoverflow' + , search: 'https://stackoverflow.com/search?q=' + , compl: 'https://api.stackexchange.com/2.2/search/advanced?pagesize=10&order=desc&sort=relevance&site=stackoverflow&q=' + , callback: function(response) { + var res = JSON.parse(response.text).items; + Omnibar.listResults(res, function(s) { + return Omnibar.createURLItem({ + title: "[" + s.score + "] " + s.title, + url: s.link + }); + }); + } + }, + { alias: 'wp' + , name: 'wikipedia' + , search: 'https://en.wikipedia.org/w/index.php?search=' + , compl: 'https://en.wikipedia.org/w/api.php?action=query&format=json&list=prefixsearch&utf8&pssearch=' + , callback: function(response) { + var res = JSON.parse(response.text).query.prefixsearch + .map(function(r){ + return r.title; + }); + Omnibar.listWords(res); + } + }, + { alias: 'yp' + , name: 'yelp' + , search: 'https://www.yelp.com/search?find_desc=' + , compl: 'https://www.yelp.com/search_suggest/v2/prefetch?prefix=' + , callback: function(response) { + var res = JSON.parse(response.text).response; + var words = []; + res.map(function(r){ + r.suggestions.map(function(s) { + var w = s.query; + if (words.indexOf(w) === -1) { + words.push(w); + } + }); + }); + Omnibar.listWords(words); + } + }, + { alias: 'yt' + , name: 'youtube' + , search: 'https://www.youtube.com/search?q=' + , compl: `https://www.googleapis.com/youtube/v3/search?maxResults=20&part=snippet&type=video,channel&key=${keys.google_yt}&safeSearch=none&q=` + , callback: function(response) { + var res = JSON.parse(response.text).items; + Omnibar.listResults(res, function(s) { + switch(s.id.kind) { + case "youtube#channel": + return Omnibar.createURLItem({ + title: s.snippet.channelTitle + ": " + s.snippet.description, + url: "https://youtube.com/channel/" + s.id.channelId + }); + case "youtube#video": + return Omnibar.createURLItem({ + title: " ▶ " + s.snippet.title, + url: "https://youtu.be/" + s.id.videoId + }); + } + }); + } + }, +]; + +if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = completions; +} diff --git a/conf.js b/conf.js index 9e65b3f..7a35ae5 100644 --- a/conf.js +++ b/conf.js @@ -125,853 +125,10 @@ let sl = 'a'; // the crunchbase Omnibar results if they don't have an image let blank = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAAAAAByaaZbAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAACYktHRAD/h4/MvwAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAAd0SU1FB+EICxEMErRVWUQAAABOdEVYdFJhdyBwcm9maWxlIHR5cGUgZXhpZgAKZXhpZgogICAgICAyMAo0NTc4Njk2NjAwMDA0OTQ5MmEwMDA4MDAwMDAwMDAwMDAwMDAwMDAwCnwMkD0AAAGXSURBVEjH1ZRvc4IwDMb7/T8dbVr/sEPlPJQd3g22GzJdmxVOHaQa8N2WN7wwvyZ5Eh/hngzxTwDr0If/TAK67POxbqxnpgCIx9dkrkEvswYnAFiutFSgtQapS4ejwFYqbXQXBmC+QxawuI/MJb0LiCq0DICNHoZRKQdYLKQZEhATcQmwDYD5GR8DDtfqaYAMActvTiVMaUvqhZPVYhYAK2SBAwGMTHngnc4wVmFPW9L6k1PJxbSCkfvhqolKSQhsWSClizNyxwAWdzIADixQRXRmdWSHthsg+TknaztFMZgC3vh/nG/qo68TLAKrCSrUg1ulp3cH+BpItBp3DZf0lFXVOIDnBdwKkLO4D5Q3QMO6HJ+hUb1NKNWMGJn3jf4ejPKn99CXOtsuyab95obGL/rpdZ7oIJK87iPiumG01drbdggoCZuq/f0XaB8/FbG62Ta5cD97XJwuZUT7ONbZTIK5m94hBuQs8535MsL5xxPw6ZoNj0DiyzhhcyMf9BJ0Jk1uRRpNyb4y0UaM9UI7E8+kt/EHgR/R6042JzmiwgAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wOC0xMVQxNzoxMjoxOC0wNDowMLy29LgAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDgtMTFUMTc6MTI6MTgtMDQ6MDDN60wEAAAAAElFTkSuQmCC"; -// Search engines -var search = [ - { alias: 'al' - , name: 'archlinux' - , search: 'https://www.archlinux.org/packages/?arch=x86_64&q=' - , compl: '' - , callback: function() {} - }, - { alias: 'au' - , name: 'AUR' - , search: 'https://aur.archlinux.org/packages/?O=0&SeB=nd&outdated=&SB=v&SO=d&PP=100&do_Search=Go&K=' - , compl: 'https://aur.archlinux.org/rpc?type=suggest&arg=' - , callback: function(response) { - var res = JSON.parse(response.text); - Omnibar.listResults(res, function(s) { - return Omnibar.createURLItem({ - title: s, - url: "https://aur.archlinux.org/packages/" + s - }); - }); - } - }, - { alias: 'aw' - , name: 'archwiki' - , search: 'https://wiki.archlinux.org/index.php?go=go&search=' - , compl: 'https://wiki.archlinux.org/api.php?action=opensearch&format=json&formatversion=2&namespace=0&limit=10&suggest=true&search=' - , callback: function(response) { - Omnibar.listWords(JSON.parse(response.text)[1]); - } - }, - { alias: 'ow' - , name: 'owasp' - , search: 'https://www.owasp.org/index.php?go=go&search=' - , compl: 'https://www.owasp.org/api.php?action=opensearch&format=json&formatversion=2&namespace=0&limit=10&suggest=true&search=' - , callback: function(response) { - Omnibar.listWords(JSON.parse(response.text)[1]); - } - }, - { alias: 'vw' - , name: 'vimwikia' - , search: 'https://vim.wikia.com/wiki/Special:Search?query=' - , compl: 'https://vim.wikia.com/api.php?action=opensearch&format=json&formatversion=2&namespace=0&limit=10&suggest=true&search=' - , callback: function(response) { - Omnibar.listWords(JSON.parse(response.text)[1]); - } - }, - { alias: 'az' - , name: 'amazon' - , search: 'https://smile.amazon.com/s/?field-keywords=' - , compl: 'https://completion.amazon.com/search/complete?method=completion&mkt=1&search-alias=aps&q=' - , callback: function(response) { - var res = JSON.parse(response.text)[1]; - Omnibar.listWords(res); - } - }, - { alias: 'cl' - , name: 'craigslist' - , search: 'https://craigslist.org/search/sss?query=' - , compl: 'https://craigslist.org/suggest?v=12&type=search&cat=sss&area=1&term=' - , callback: function(response) { - Omnibar.listWords(JSON.parse(response.text)); - } - }, - { alias: 'wa' - , name: 'wolframalpha' - , search: 'http://www.wolframalpha.com/input/?i=' - , compl: `http://api.wolframalpha.com/v2/query?appid=${keys.wolframalpha}&format=plaintext&output=json&reinterpret=true&input=%s` - , callback: function(response) { - var res = JSON.parse(response.text).queryresult; - - if (res.error) { - Omnibar.listResults([""], function() { - var li = $('
  • ').html(` -
    -
    Error (Code ${res.error.code})
    -
    ${res.error.msg}
    -
    - `); - return li; - }); - return; - } - - if (!res.success) { - if (res.tips) { - Omnibar.listResults([""], function() { - var li = $('
  • ').html(` -
    -
    No Results
    -
    ${res.tips.text}
    -
    - `); - return li; - }); - } - if (res.didyoumeans) { - Omnibar.listResults(res.didyoumeans, function(s) { - var li = $('
  • ').html(` -
    -
    Did you mean...?
    -
    ${s.val}
    -
    - `); - return li; - }); - } - return; - } - - var results = []; - res.pods.map(function(p){ - var result = { - title: p.title, - values: [], - url: "http://www.wolframalpha.com/input/?i=", - }; - if (p.numsubpods > 0) { - result.url += encodeURIComponent(p.subpods[0].plaintext); - p.subpods.map(function(sp) { - if (!sp.plaintext) return; - var v = ""; - if (sp.title) { - v += `${sp.title}: `; - } - v += sp.plaintext; - result.values.push(`
    ${v}
    `); - }); - } - if (result.values.length > 0) { - results.push(result); - } - }); - - Omnibar.listResults(results, function(r) { - var li = $('
  • ').html(` -
    -
    ${r.title}
    - ${r.values.join("\n")} -
    - `); - li.data('url', r.url); - return li; - }); - } - }, - { alias: 'co' - , name: 'crunchbase-orgs' - , search: 'https://www.crunchbase.com/app/search/?q=' - , compl: `https://api.crunchbase.com/v/3/odm_organizations?user_key=${keys.crunchbase}&query=%s` - , callback: function(response) { - var res = JSON.parse(response.text).data.items; - var orgs = []; - res.map(function(rr){ - var r = rr.properties; - var p = { - name: r.name, - domain: r.domain, - desc: r.short_description, - role: r.primary_role, - img: blank, - loc: "", - url: "https://www.crunchbase.com/" + r.web_path - }; - - p.loc += (r.city_name !== null) ? r.city_name : ""; - p.loc += (r.region_name !== null && p.loc !== "") ? ", " : ""; - p.loc += (r.region_name !== null) ? r.region_name : ""; - p.loc += (r.country_code !== null && p.loc !== "") ? ", " : ""; - p.loc += (r.country_code !== null) ? r.country_code : ""; - p.loc += (p.loc === "") ? "Earth" : ""; - - if (r.profile_image_url !== null) { - var url = r.profile_image_url - , path = url.split('/') - , img = path[path.length-1]; - p.img = "http://public.crunchbase.com/t_api_images/v1402944794/c_pad,h_50,w_50/" + img; - } - - orgs.push(p); - }); - - Omnibar.listResults(orgs, function(p) { - var li = $('
  • ').html(` -
    -
    - ${p.name} -
    -
    -
    ${p.name}
    -
    Type: ${p.role}, Domain: ${p.domain}
    -
    ${p.desc}
    -
    ${p.loc}
    -
    -
    - `); - li.data('url', p.url); - return li; - }); - } - }, - { alias: 'cp' - , name: 'crunchbase-people' - , search: 'https://www.crunchbase.com/app/search/?q=' - , compl: `https://api.crunchbase.com/v/3/odm_people?user_key=${keys.crunchbase}&query=%s` - , callback: function(response) { - var res = JSON.parse(response.text).data.items; - var people = []; - res.map(function(rr){ - var r = rr.properties; - var p = { - name: r.first_name + " " + r.last_name, - desc: "", - img: blank, - loc: "", - url: "https://www.crunchbase.com/" + r.web_path - }; - - p.desc += (r.title !== null) ? r.title : ""; - p.desc += (r.organization_name !== null && p.desc !== "") ? ", " : ""; - p.desc += (r.organization_name !== null) ? r.organization_name : ""; - p.desc += (p.desc === "") ? "Human" : ""; - - p.loc += (r.city_name !== null) ? r.city_name : ""; - p.loc += (r.region_name !== null && p.loc !== "") ? ", " : ""; - p.loc += (r.region_name !== null) ? r.region_name : ""; - p.loc += (r.country_code !== null && p.loc !== "") ? ", " : ""; - p.loc += (r.country_code !== null) ? r.country_code : ""; - p.loc += (p.loc === "") ? "Earth" : ""; - - if (r.profile_image_url !== null) { - var url = r.profile_image_url - , path = url.split('/') - , img = path[path.length-1]; - p.img = "http://public.crunchbase.com/t_api_images/v1402944794/c_pad,h_50,w_50/" + img; - } - - people.push(p); - }); - - Omnibar.listResults(people, function(p) { - var li = $('
  • ').html(` -
    -
    - ${p.name} -
    -
    -
    ${p.name}
    -
    ${p.desc}
    -
    ${p.loc}
    -
    -
    - `); - li.data('url', p.url); - return li; - }); - } - }, - { alias: 'cs' - , name: 'chromestore' - , search: 'https://chrome.google.com/webstore/search/' - , compl: '' - , callback: function() {} - }, - { alias: 'th' - , name: 'thesaurus' - , search: 'https://www.onelook.com/reverse-dictionary.shtml?s=' - , compl: 'https://api.datamuse.com/words?md=d&ml=%s' - , callback: function(response) { - var res = JSON.parse(response.text); - var defs = []; - res.map(function(r){ - if (!r.defs || r.defs.length === 0) { - defs.push([r.word, "", ""]); - return; - } - r.defs.map(function(d) { - d = d.split("\t"); - - var sp = "(" + d[0] + ")", - def = d[1]; - - defs.push([r.word, sp, def]); - }); - }); - Omnibar.listResults(defs, function(d) { - var li = $('
  • ').html(`
    ${d[0]} ${d[1]} ${d[2]}
    `); - li.data('url', "http://onelook.com/?w=" + d[0]); - return li; - }); - } - }, - { alias: 'de' - , name: 'define' - , search: 'http://onelook.com/?w=' - , compl: 'https://api.datamuse.com/words?md=d&sp=%s*' - , callback: function(response) { - var res = JSON.parse(response.text); - var defs = []; - res.map(function(r){ - if (!r.defs || r.defs.length === 0) { - defs.push([r.word, "", ""]); - return; - } - r.defs.map(function(d) { - d = d.split("\t"); - - var sp = "(" + d[0] + ")", - def = d[1]; - - defs.push([r.word, sp, def]); - }); - }); - Omnibar.listResults(defs, function(d) { - var li = $('
  • ').html(`
    ${d[0]} ${d[1]} ${d[2]}
    `); - li.data('url', "http://onelook.com/?w=" + d[0]); - return li; - }); - } - }, - { alias: 'dg' - , name: 'duckduckgo' - , search: 'https://duckduckgo.com/?q=' - , compl: 'https://duckduckgo.com/ac/?q=' - , callback: function(response) { - var res = JSON.parse(response.text).map(function(r){ - return r.phrase; - }); - Omnibar.listWords(res); - } - }, - { alias: 'dh' - , name: 'dockerhub' - , search: 'https://hub.docker.com/search/?page=1&q=' - , compl: 'https://hub.docker.com/v2/search/repositories/?page_size=20&query=' - , callback: function(response) { - var res = JSON.parse(response.text); - Omnibar.listResults(res.results, function(s) { - var meta = "" - , repo = s.repo_name; - meta += "[★" + s.star_count + "] "; - meta += "[↓" + s.pull_count + "] "; - if (repo.indexOf("/") === -1) { - repo = "_/" + repo; - } - var li = $('
  • ').html(` -
    -
    ${s.repo_name}
    -
    ${meta}
    -
    ${s.short_description}
    -
    - `); - li.data('url', "https://hub.docker.com/r/" + repo); - return li; - }); - } - }, - { alias: 'do' - , name: 'domainr' - , search: 'https://domainr.com/?q=' - , compl: `https://api.domainr.com/v2/search?client_id=${keys.domainr}&query=%s` - , callback: function(response) { - var res = JSON.parse(response.text).results; - var domains = []; - res.map(function(r){ - var d = { - id: r.domain.replace('.', '-'), - domain: r.domain - }; - domains.push(d); - }); - - var domainQuery = domains.map(function(d) { return d.domain; }).join(','); - - runtime.command({ - action: 'request', - method: 'get', - url: `https://api.domainr.com/v2/status?client_id=${keys.domainr}&domain=${domainQuery}` - }, function(sresponse) { - var sres = JSON.parse(sresponse.text).status; - sres.map(function(s) { - var id = "#sk-domain-" + s.domain.replace('.', '-') - , available = s.summary === "inactive" - , color = available ? "#23b000" : "#ff4d00" - , symbol = available ? "✔ " : "✘ "; - $(id).text(symbol + $(id).text()).css("color", color); - }); - }); - - Omnibar.listResults(domains, function(d) { - var li = $('
  • ').html(` -
    -
    ${d.domain}
    -
    - `); - li.data('url', `https://domainr.com/${d.domain}`); - return li; - }); - } - }, - { alias: 'ex' // Similar to `hd` but searches inside docs using Google Custom Search - , name: 'exdocs' - , search: 'https://hex.pm/packages?sort=downloads&search=' - , compl: `https://www.googleapis.com/customsearch/v1?key=${keys.google_ex}&cx=${keys.google_ex_cx}&q=` - , callback: function(response) { - var res = JSON.parse(response.text).items; - Omnibar.listResults(res, function(s) { - var snippet = s.htmlSnippet; - var hash = ""; - - // Hacky way to extract the desired function's - // signature to use as an anchor because - // Google Custom Search doesn't link to the appropriate - // section of the documentation page - // A regex would probably work better. - (function() { - var openTag = "" - , closeTag = "" - , openArgs = "(" - , closeArgs = ")"; - - var f1 = snippet.indexOf(openTag); - if (f1 === -1) { - return; - } - var f2 = snippet.indexOf(closeTag); - if (f2 === -1) { - return; - } - - f1 += openTag.length; - f3 = f2 + closeTag.length; - fname = snippet.slice(f1, f2); - snippetEnd = snippet.slice(f3); - - var a1 = snippetEnd.indexOf(openArgs); - if (a1 !== 0) { - return; - } - var a2 = snippetEnd.indexOf(closeArgs); - if (a2 === -1) { - return; - } - - a2 += closeArgs.length; - var fargs = snippetEnd.slice(a1, a2); - var fary = fargs.replace(new RegExp(openArgs + closeArgs), '').split(',').length; - hash = fname + '/' + fary; - })(); - - var moduleName = s.title.split(' –')[0]; - - var subtitle = ""; - if (hash) { - subtitle = ` -
    - ${moduleName}.${hash} -
    `; - } - var li = $('
  • ').html(` -
    -
    ${s.htmlTitle}
    - ${subtitle} -
    ${s.htmlSnippet}
    -
    - `); - li.data('url', s.link + "#" + hash); - return li; - }); - } - }, - { alias: 'gd' - , name: 'godoc' - , search: 'https://godoc.org/?q=' - , compl: 'https://api.godoc.org/search?q=' - , callback: function(response) { - var res = JSON.parse(response.text).results; - Omnibar.listResults(res, function(s) { - var prefix = ""; - if (s.import_count) { - prefix += "[↓" + s.import_count + "] "; - } - if (s.stars) { - prefix += "[★" + s.stars + "] "; - } - return Omnibar.createURLItem({ - title: prefix + s.path, - url: "https://godoc.org/" + s.path - }); - }); - } - }, - { alias: 'gh' - , name: 'github' - , search: 'https://github.com/search?q=' - , compl: 'https://api.github.com/search/repositories?sort=stars&order=desc&q=' - , callback: function(response) { - var res = JSON.parse(response.text).items; - Omnibar.listResults(res, function(s) { - var prefix = ""; - if (s.stargazers_count) { - prefix += "[★" + s.stargazers_count + "] "; - } - return Omnibar.createURLItem({ - title: prefix + s.full_name, - url: s.html_url - }); - }); - } - }, - { alias: 'go' - , name: 'google' - , search: 'https://www.google.com/search?q=' - , compl: 'https://www.google.com/complete/search?client=chrome-omni&gs_ri=chrome-ext&oit=1&cp=1&pgcl=7&q=' - , callback: function(response) { - Omnibar.listWords(JSON.parse(response.text)[1]); - } - }, - { alias: 'gl' - , name: 'google-lucky' - , search: 'https://www.google.com/search?btnI=1&q=' - , compl: 'https://www.google.com/complete/search?client=chrome-omni&gs_ri=chrome-ext&oit=1&cp=1&pgcl=7&q=' - , callback: function(response) { - Omnibar.listWords(JSON.parse(response.text)[1]); - } - }, - { alias: 'gs' - , name: 'go-search' - , search: 'http://go-search.org/search?q=' - , compl: 'http://go-search.org/api?action=search&q=' - , callback: function(response) { - var res = JSON.parse(response.text).hits - .map(function(r){ - return r.package; - }); - Omnibar.listWords(res); - } - }, - { alias: 'ha' - , name: 'hackage' - , search: 'https://hackage.haskell.org/packages/search?terms=' - , compl: 'https://hackage.haskell.org/packages/search.json?terms=' - , callback: function(response) { - var res = JSON.parse(response.text); - Omnibar.listResults(res, function(s) { - return Omnibar.createURLItem({ - title: s.name, - url: 'https://hackage.haskell.org/package/' + s.name - }); - }); - } - }, - { alias: 'hd' // Same as hex but links to documentation pages - , name: 'hexdocs' - , search: 'https://hex.pm/packages?sort=downloads&search=' - , compl: 'https://hex.pm/api/packages?sort=downloads&search=' - , callback: function(response) { - var res = JSON.parse(response.text); - Omnibar.listResults(res, function(s) { - var dls = "" - , desc = "" - , liscs = ""; - if (s.downloads && s.downloads.all) { - dls = "[↓" + s.downloads.all + "]"; - } - if(s.meta) { - if (s.meta.description) { - desc = s.meta.description; - } - if (s.meta.licenses) { - s.meta.licenses.forEach(function(l) { - liscs += "[©" + l + "] "; - }); - } - } - var li = $('
  • ').html(` -
    -
    ${s.repository}/${s.name}
    -
    ${dls}${liscs}
    -
    ${desc}
    -
    - `); - li.data('url', "https://hexdocs.pm/" + s.name); - return li; - }); - } - }, - { alias: 'hn' - , name: 'hackernews' - , search: 'https://hn.algolia.com/?query=' - , compl: 'https://hn.algolia.com/api/v1/search?tags=(story,comment)&query=' - , callback: function(response) { - var res = JSON.parse(response.text).hits; - Omnibar.listResults(res, function(s) { - var title = ""; - var prefix = ""; - if (s.points) { - prefix += "[↑" + s.points + "] "; - } - if (s.num_comments) { - prefix += "[↲" + s.num_comments + "] "; - } - switch(s._tags[0]) { - case "story": - title = s.title; - break; - case "comment": - title = s.comment_text; - break; - default: - title = s.objectID; - } - return Omnibar.createURLItem({ - title: prefix + title, - url: "https://news.ycombinator.com/item?id=" + s.objectID - }); - }); - } - }, - { alias: 'ho' - , name: 'hoogle' - , search: 'https://www.haskell.org/hoogle/?hoogle=' + - encodeURIComponent("+platform +xmonad +xmonad-contrib ") // This tells Hoogle to include these modules in the search - encodeURIComponent is only used for better readability - , compl: 'https://www.haskell.org/hoogle/?mode=json&hoogle=' + - encodeURIComponent("+platform +xmonad +xmonad-contrib ") - , callback: function(response) { - var res = JSON.parse(response.text).results; - Omnibar.listResults(res, function(s) { - return Omnibar.createURLItem({ - title: s.self, - url: s.location - }); - }); - } - }, - { alias: 'hw' - , name: 'haskellwiki' - , search: 'https://wiki.haskell.org/index.php?go=go&search=' - , compl: 'https://wiki.haskell.org/api.php?action=opensearch&format=json&formatversion=2&namespace=0&limit=10&suggest=true&search=' - , callback: function(response) { - Omnibar.listWords(JSON.parse(response.text)[1]); - } - }, - { alias: 'hx' - , name: 'hex' - , search: 'https://hex.pm/packages?sort=downloads&search=' - , compl: 'https://hex.pm/api/packages?sort=downloads&search=' - , callback: function(response) { - var res = JSON.parse(response.text); - Omnibar.listResults(res, function(s) { - var dls = "" - , desc = "" - , liscs = ""; - if (s.downloads && s.downloads.all) { - dls = "[↓" + s.downloads.all + "] "; - } - if(s.meta) { - if (s.meta.description) { - desc = s.meta.description; - } - if (s.meta.licenses) { - s.meta.licenses.forEach(function(l) { - liscs += "[©" + l + "] "; - }); - } - } - var li = $('
  • ').html(` -
    -
    ${s.repository}/${s.name}
    -
    ${dls}${liscs}
    -
    ${desc}
    -
    - `); - li.data('url', s.html_url); - return li; - }); - } - }, - { alias: 'hy' - , name: 'hayoo' - , search: 'http://hayoo.fh-wedel.de/?query=' - , compl: 'http://hayoo.fh-wedel.de/json?query=' - , callback: function(response) { - var res = JSON.parse(response.text).result; - Omnibar.listResults(res, function(s) { - return Omnibar.createURLItem({ - title: "[" + s.resultType + "] " + s.resultName, - url: s.resultUri - }); - }); - } - }, - { alias: 'md' - , name: 'mdn' - , search: 'https://developer.mozilla.org/en-US/search?q=' - , compl: 'https://developer.mozilla.org/en-US/search.json?q=' - , callback: function(response) { - var res = JSON.parse(response.text); - Omnibar.listResults(res.documents, function(s) { - var excerpt = s.excerpt; - if(excerpt.length > 240) { - excerpt = excerpt.slice(0, 240) + '…'; - } - res.query.split(" ").forEach(function(q) { - excerpt = excerpt.replace(new RegExp(q, 'gi'), "$&"); - }); - var li = $('
  • ').html(` -
    -
    ${s.title}
    -
    ${s.slug}
    -
    ${excerpt}
    -
    - `); - li.data('url', s.url); - return li; - }); - } - }, - { alias: 'np' - , name: 'npm' - , search: 'https://www.npmjs.com/search?q=' - , compl: 'https://api.npms.io/v2/search/suggestions?size=20&q=' - , callback: function(response) { - var res = JSON.parse(response.text); - Omnibar.listResults(res, function(s) { - var flags = "" - , desc = "" - , stars = ""; - if (s.package.description) { - desc = s.package.description; - } - if(s.score) { - if (s.score.final) { - score = Math.round(s.score.final * 5); - stars = "★".repeat(score) + "☆".repeat(5-score); - } - } - if (s.flags) { - Object.keys(s.flags).forEach(function(f) { - flags += "[ " + f + "] "; - }); - } - var li = $('
  • ').html(` -
    - -
    ${s.highlight}
    -
    - ${stars} - ${flags} -
    -
    ${desc}
    -
    - `); - li.data('url', s.package.links.npm); - return li; - }); - } - }, - { alias: 're' - , name: 'reddit' - , search: 'https://www.reddit.com/search?sort=relevance&t=all&q=' - , compl: 'https://api.reddit.com/search?syntax=plain&sort=relevance&limit=20&q=' - , callback: function(response) { - var res = JSON.parse(response.text).data.children; - Omnibar.listResults(res, function(s) { - var d = s.data; - return Omnibar.createURLItem({ - title: "[" + d.score + "] " + d.title, - url: "https://reddit.com" + d.permalink - }); - }); - } - }, - { alias: 'so' - , name: 'stackoverflow' - , search: 'https://stackoverflow.com/search?q=' - , compl: 'https://api.stackexchange.com/2.2/search/advanced?pagesize=10&order=desc&sort=relevance&site=stackoverflow&q=' - , callback: function(response) { - var res = JSON.parse(response.text).items; - Omnibar.listResults(res, function(s) { - return Omnibar.createURLItem({ - title: "[" + s.score + "] " + s.title, - url: s.link - }); - }); - } - }, - { alias: 'wp' - , name: 'wikipedia' - , search: 'https://en.wikipedia.org/w/index.php?search=' - , compl: 'https://en.wikipedia.org/w/api.php?action=query&format=json&list=prefixsearch&utf8&pssearch=' - , callback: function(response) { - var res = JSON.parse(response.text).query.prefixsearch - .map(function(r){ - return r.title; - }); - Omnibar.listWords(res); - } - }, - { alias: 'yp' - , name: 'yelp' - , search: 'https://www.yelp.com/search?find_desc=' - , compl: 'https://www.yelp.com/search_suggest/v2/prefetch?prefix=' - , callback: function(response) { - var res = JSON.parse(response.text).response; - var words = []; - res.map(function(r){ - r.suggestions.map(function(s) { - var w = s.query; - if (words.indexOf(w) === -1) { - words.push(w); - } - }); - }); - Omnibar.listWords(words); - } - }, - { alias: 'yt' - , name: 'youtube' - , search: 'https://www.youtube.com/search?q=' - , compl: `https://www.googleapis.com/youtube/v3/search?maxResults=20&part=snippet&type=video,channel&key=${keys.google_yt}&safeSearch=none&q=` - , callback: function(response) { - var res = JSON.parse(response.text).items; - Omnibar.listResults(res, function(s) { - switch(s.id.kind) { - case "youtube#channel": - return Omnibar.createURLItem({ - title: s.snippet.channelTitle + ": " + s.snippet.description, - url: "https://youtube.com/channel/" + s.id.channelId - }); - case "youtube#video": - return Omnibar.createURLItem({ - title: " ▶ " + s.snippet.title, - url: "https://youtu.be/" + s.id.videoId - }); - } - }); - } - }, -]; - -for(var i = 0; i < search.length; i++) { - var s = search[i], // Search object - la = sl + s.alias; // Search leader + alias +// Register Search Engine Completions +for(var i = 0; i < completions.length; i++) { + var s = completions[i], // Search Engine object + la = sl + s.alias; // Search leader + alias addSearchAliasX(s.alias, s.name, s.search, sl, s.compl, s.callback); mapkey(la, '#8Search ' + s.name, 'Front.openOmnibar({type: "SearchEngine", extra: "' + s.alias + '"})'); diff --git a/gulpfile.js b/gulpfile.js index 3136547..3e8002e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,13 +1,27 @@ -const gulp = require('gulp'); -const concat = require('gulp-concat'); -const jshint = require('gulp-jshint'); -const del = require('del'); -const os = require('os'); +const gulp = require('gulp'); +const concat = require('gulp-concat'); +const replace = require('gulp-replace'); +const rename = require('gulp-rename'); +const jshint = require('gulp-jshint'); +const del = require('del'); +const os = require('os'); +const { URL } = require('url'); +const compl = require('./completions'); var paths = { - scripts: ['conf.priv.js', 'conf.js'] + scripts: ['conf.priv.js', 'completions.js', 'conf.js'], + readme: ['README.tmpl.md'], }; +const disclaimer = `\ +`; + gulp.task('clean', function() { return del(['build']); }); @@ -18,7 +32,7 @@ gulp.task('lint', function() { .pipe(jshint.reporter('jshint-stylish')); }); -gulp.task('build', ['clean', 'lint'], function() { +gulp.task('build', ['clean', 'lint', 'readme'], function() { return gulp.src(paths.scripts) .pipe(concat('.surfingkeys')) .pipe(gulp.dest('build')); @@ -31,6 +45,31 @@ gulp.task('install', ['build'], function() { gulp.task('watch', function() { gulp.watch(paths.scripts, ['build']); + gulp.watch(paths.readme, ['readme']); }); +gulp.task('readme', function() { + var complTable = ""; + compl.sort(function(a, b) { + if (a.alias < b.alias) { + return -1; + } + if (a.alias > b.alias) { + return 1; + } + return 0; + }).forEach(function(c) { + var u = new URL(c.search); + complTable += `| \`${c.alias}\` | \`${c.name}\` | \`${u.hostname}\` |\n`; + }) + + + gulp.src(['./README.tmpl.md']) + .pipe(replace("", disclaimer)) + .pipe(replace("", compl.length)) + .pipe(replace("", complTable)) + .pipe(rename('README.md')) + .pipe(gulp.dest('.')); +}) + gulp.task('default', ['build']); diff --git a/package-lock.json b/package-lock.json index a78f3f5..583e13b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -75,6 +75,11 @@ "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" }, + "binaryextensions": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-1.0.1.tgz", + "integrity": "sha1-HmN0iLNbWL2l9HdL+WpSEqjJB1U=" + }, "brace-expansion": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", @@ -737,6 +742,50 @@ } } }, + "gulp-rename": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.2.2.tgz", + "integrity": "sha1-OtRCh2PwXidk3sHGfYaNsnVoeBc=" + }, + "gulp-replace": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-0.6.1.tgz", + "integrity": "sha1-Eb+Mj85TPjPi9qjy9DC5VboL4GY=", + "requires": { + "istextorbinary": "1.0.2", + "readable-stream": "2.3.3", + "replacestream": "4.0.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "gulp-util": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", @@ -985,6 +1034,15 @@ } } }, + "istextorbinary": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-1.0.2.tgz", + "integrity": "sha1-rOGTVNGpoBc+/rEITOD4ewrX3s8=", + "requires": { + "binaryextensions": "1.0.1", + "textextensions": "1.0.2" + } + }, "jshint": { "version": "2.9.5", "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", @@ -1569,6 +1627,50 @@ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" }, + "replacestream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz", + "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==", + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1", + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "resolve": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", @@ -1657,6 +1759,11 @@ "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=" }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, "string-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", @@ -1665,11 +1772,6 @@ "strip-ansi": "3.0.1" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -1702,6 +1804,11 @@ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, + "textextensions": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-1.0.2.tgz", + "integrity": "sha1-ZUhjk+4fK7A5pgy7oFsLaL2VAdI=" + }, "through2": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", diff --git a/package.json b/package.json index 5f55958..bb08104 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "gulp": "^3.9.1", "gulp-concat": "^2.6.1", "gulp-jshint": "^2.0.4", + "gulp-rename": "^1.2.2", + "gulp-replace": "^0.6.1", "jshint": "^2.9.5", "jshint-stylish": "^2.2.1" }