[
  {
    "path": ".gitignore",
    "content": "doc/tags\n"
  },
  {
    "path": "LICENSE",
    "content": "BSD 3-Clause License\n\nCopyright (c) 2013, Takuya Fujiwara\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Makefile",
    "content": "\nrelease:\n\tgit archive HEAD plugin autoload doc --output=open-browser-github-$(shell git describe --tags HEAD).zip\n\n.PHONY: release\n"
  },
  {
    "path": "README.md",
    "content": "# open-browser-github.vim\n\n## About\n\nOpens GitHub URL of current file, etc. from Vim.\nAlso supports GitHub Enterprise.\n\n## Install\n\nThis plugin requires:\n\n* [open-browser.vim](https://github.com/tyru/open-browser.vim)\n* `git` command in your PATH\n\n## Usage\n\nThere are 4 commands.\n\n### `:OpenGithubFile`\n\nOpens a specific file in github.com repository(it also opens in the current branch by default).\n\n```vimL\n\" Opens current files URL in github.com\n:OpenGithubFile\n\" Opens current files highlighted place in github.com \n:'<,'>OpenGithubFile\n\" Opens a specific file in github.com\n:OpenGithubFile PATH/TO/FILE\n```\n\n### `:OpenGithubIssue`\n\nOpens a specific Issue.\n\n```vimL\n\" Opens current repositories Issue #1\n:OpenGithubIssue 1\n\" Opens a specific repositories Issue #1\n:OpenGithubIssue 1 tyru/open-browser.vim\n\" Opens current repositories Issue List\n:OpenGithubIssue\n\" Opens a specific repositories Issue list\n:OpenGithubIssue tyru/open-browser.vim\n```\n\n### `:OpenGithubPullReq`\n\nThis command opens `/pulls` page when it has no argument.  Otherwise, it does entirely the same thing as `:OpenGithubIssue` since GitHub redirects `/issues/1` to `/pull/1` if #1 is a Pull Request.\n\n### `:OpenGithubProject`\n\nOpens a project page.\n\n```vimL\n\" Opens current opening file's repository.\n\" ex) https://{hostname}/{user}/{name}\n:OpenGithubProject\n\n\" Opens current opening file's repository.\n\" ex) https://{hostname}/tyru/open-browser.vim\n:OpenGithubProject tyru/open-browser.vim\n```\n\n## GitHub Enterprise setting\n\n### If you have `hub` command\n\nIf you have [hub command](https://github.com/github/hub) in your PATH,\n`openbrowser-github` executes the following command:\n\n```\nhub browse -u -- {path}\n```\n\nAnd it will open the returned (output) URL.\n\n### If you _don't_ have `hub` command\n\nIf you don't have `hub` command in your PATH, `openbrowser-github` tries to\nget each part of URL from the following gitconfig key:\n\n* hub.host\n\nYou can specify GitHub Enterprise repository URL by setting above keys in\ngitconfig.\n\nFor example, you can set `hub.host` by executing the following command in your\ngit repository which you want to specify GitHub Enterprise repository URL.\n\n```\ngit config --local hub.host my.git.org\n```\n"
  },
  {
    "path": "autoload/openbrowser/github.vim",
    "content": "\" vim:foldmethod=marker:fen:\nscriptencoding utf-8\n\n\" Saving 'cpoptions' {{{\nlet s:save_cpo = &cpo\nset cpo&vim\n\" }}}\n\nlet s:V = vital#of('open_browser_github')\nlet s:Filepath = s:V.import('System.Filepath')\nlet s:List = s:V.import('Data.List')\nunlet s:V\n\n\nfunction! openbrowser#github#load() abort\n  \" dummy function to load this script.\nendfunction\n\nfunction! openbrowser#github#file(args, rangegiven, firstlnum, lastlnum) abort\n  let file = s:resolve(expand(get(a:args, 0, '%')))\n  let worktree = s:lookup_git_worktree(file)\n  let lastlnum = max([a:firstlnum, a:lastlnum]) \" a:firstlnum could be bigger in NeoVim\n  call s:call_with_temp_dir(worktree, 's:cmd_file', [a:args, a:rangegiven, a:firstlnum, lastlnum])\nendfunction\n\n\" Opens a specific file in github.com repository.\nfunction! s:cmd_file(args, rangegiven, firstlnum, lastlnum) abort\n  let rangegiven = a:rangegiven || get(g:, 'openbrowser_github_select_current_line', 0)\n  let [path, err] = s:parse_cmd_file_args(a:args, rangegiven, a:firstlnum, a:lastlnum)\n  if err !=# ''\n    call s:error(err)\n    return\n  endif\n  if executable('hub')\n    let url = s:hub('browse', '-u', '--', path)\n  else\n    let [url, err] = s:get_url_from_git({'path': path})\n    if err !=# ''\n      call s:error(err)\n      return\n    endif\n  endif\n  if !s:url_exists(url) && input(\n  \\   \"Maybe you are opening a URL which is not git-push'ed yet. OK?[y/n]: \"\n  \\) !~? '^\\%[YES]$'\n    \" TODO: Retry\n    return\n  endif\n  return openbrowser#open(url)\nendfunction\n\n\" * :OpenGithubFile [{path}]\nfunction! s:parse_cmd_file_args(args, rangegiven, firstlnum, lastlnum) abort\n  let file = s:resolve(expand(empty(a:args) ? '%' : a:args[0]))\n  if !filereadable(file)\n    if a:0 is 0\n      return ['', 'current buffer is not a file.']\n    else\n      return ['', printf('''%s'' is not readable.', file)]\n    endif\n  endif\n\n  let relpath = s:get_repos_relpath(file)\n\n  if g:openbrowser_github_always_used_branch !=# ''\n    let branch = g:openbrowser_github_always_used_branch\n  elseif g:openbrowser_github_always_use_commit_hash\n    let branch = s:git('rev-parse', 'HEAD')\n  else\n    \" When working tree is detached state,\n    \" branch becomes commit hash.\n    let head_ref = s:git('symbolic-ref', '--short', '-q', 'HEAD')\n    let is_detached_state = (head_ref ==# '')\n    if is_detached_state\n      let branch = s:git('rev-parse', 'HEAD')\n    else\n      let branch = head_ref\n    endif\n  endif\n\n  if a:rangegiven\n    let lnum = '#L'.a:firstlnum\n    \\          .(a:firstlnum is a:lastlnum ? '' : '-L'.a:lastlnum)\n  else\n    let lnum = ''\n  endif\n\n  \" Check input values.\n  if branch ==# ''\n    return ['', 'Could not detect current branch name.']\n  endif\n  if relpath ==# ''\n    return ['', 'Could not detect relative path of repository.']\n  endif\n\n  let path = 'blob/' . branch . '/' . relpath . lnum\n  return [path, '']\nendfunction\n\nfunction! s:get_url_from_git(repoinfo) abort\n  let host = s:get_github_host()\n  let user = get(a:repoinfo, 'user', '')\n  let repos = get(a:repoinfo, 'repos', '')\n  let path = get(a:repoinfo, 'path', '')\n\n  if user ==# '' || repos ==# ''\n    \" May prompt user to choose which repos is used.\n    try\n      let github_repos =\n      \\   s:detect_github_repos_from_git_remote(host)\n    catch /^INVALID INDEX$/\n      return ['', 'canceled or invalid GitHub URL was selected.']\n    endtry\n    let user  = get(github_repos, 'user', '')\n    let repos = get(github_repos, 'repos', '')\n  endif\n\n  if user ==# ''\n    return ['', 'Could not detect repos user.']\n  endif\n  if repos ==# ''\n    return ['', 'Could not detect current repos name on github.']\n  endif\n\n  let url = 'https://' . host . '/' . user . '/' . repos . '/' . path\n  return [url, '']\nendfunction\n\nfunction! s:url_exists(url) abort\n  if g:openbrowser_github_url_exists_check ==# 'ignore'\n    return 1\n  endif\n  if !executable('curl')\n    call s:warn('You must have ''curl'' command to check whether the opening URL exists.')\n    call s:warn('You can suppress this check by writing the following '\n    \\         . 'config in your vimrc (:help g:openbrowser_github_url_exists_check).')\n    call s:warn('  let g:openbrowser_github_url_exists_check = ''ignore''')\n    call input('Press ENTER to continue...')\n    return 1\n  endif\n  let cmdline = 'curl -k -LI \"' . a:url . '\"'\n  let headers = split(system(cmdline), '\\n')\n  if v:shell_error\n    call s:warn(cmdline)\n    call s:warn('curl returned error code: ' . v:shell_error)\n    return 1\n  endif\n  let re = '^status:'\n  let status_line = get(filter(headers, 'v:val =~? re'), 0, '')\n  if status_line ==# ''\n    call s:warn(cmdline)\n    call s:warn('curl received a response without ''Status'' header.')\n    return 1\n  endif\n  return status_line =~? '^status:\\s*2'\nendfunction\n\nlet s:TYPE_ISSUE = 0\nfunction! openbrowser#github#issue(args) abort\n  let file = expand('%')\n  let worktree = s:lookup_git_worktree(file)\n  call s:call_with_temp_dir(worktree, 's:cmd_open_url', [a:args, s:TYPE_ISSUE])\nendfunction\n\nlet s:TYPE_PULLREQ = 1\nfunction! openbrowser#github#pullreq(args) abort\n  let file = expand('%')\n  let worktree = s:lookup_git_worktree(file)\n  call s:call_with_temp_dir(worktree, 's:cmd_open_url', [a:args, s:TYPE_PULLREQ])\nendfunction\n\nlet s:TYPE_PROJECT = 2\nfunction! openbrowser#github#project(args) abort\n  let file = expand('%')\n  let worktree = s:lookup_git_worktree(file)\n  call s:call_with_temp_dir(worktree, 's:cmd_open_url', [a:args, s:TYPE_PROJECT])\nendfunction\n\nlet s:TYPE_COMMIT = 3\nfunction! openbrowser#github#commit(args) abort\n  let file = expand('%')\n  let worktree = s:lookup_git_worktree(file)\n  call s:call_with_temp_dir(worktree, 's:cmd_open_url', [a:args, s:TYPE_COMMIT])\nendfunction\n\n\" Opens a specific Issue/Pullreq/Project.\nfunction! s:cmd_open_url(...) abort\n  try\n    let repoinfo = call('s:parse_cmd_open_url_args', a:000)\n  catch\n    call s:error(v:exception)\n    return\n  endtry\n  if executable('hub')\n    let url = s:hub('browse', '-u', '--', repoinfo.path)\n  else\n    let [url, err] = s:get_url_from_git(repoinfo)\n    if err !=# ''\n      call s:error(err)\n      return\n    endif\n  endif\n  return openbrowser#open(url)\nendfunction\n\n\" * :OpenGithubIssue\n\" * :OpenGithubIssue [#]{number} [{user}/{repos}]\n\" * :OpenGithubIssue {user}/{repos}\n\" * :OpenGithubPullReq\n\" * :OpenGithubPullReq [#]{number} [{user}/{repos}]\n\" * :OpenGithubPullReq #{branch} [{user}/{repos}]\n\" * :OpenGithubPullReq {user}/{repos}\n\" * :OpenGithubProject [{user}/{repos}]\n\" * :OpenGithubCommit {commit hash} [{user}/{repos}]\nfunction! s:parse_cmd_open_url_args(args, type) abort\n  if a:type ==# s:TYPE_ISSUE\n    \" ex) '#1', '1'\n    let nr = matchstr(get(a:args, 0, ''), '^#\\?\\zs\\d\\+\\ze$')\n    if nr !=# ''\n      let path = 'issues/' . nr\n    else\n      let path = 'issues'\n    endif\n    \" If the argument of repository was given and valid format, get user and repos.\n    let idx = nr ==# '' ? 0 : 1\n    let m = matchlist(get(a:args, idx, ''),\n    \\                     '^\\([^/]\\+\\)/\\([^/]\\+\\)$')\n    let [user, repos] = !empty(m) ? m[1:2] : ['', '']\n  elseif a:type ==# s:TYPE_PULLREQ\n    \" ex) '#1', '1', '#branch_name_of_pull_request'\n    let nr_or_branch = matchstr(get(a:args, 0, ''), '^\\%(#\\?\\zs\\d\\+\\ze\\|#\\zs.\\+\\ze\\)$')\n    if nr_or_branch !=# ''\n      let path = 'pull/' . nr_or_branch\n    else\n      let path = 'pulls'\n    endif\n    \" If the argument of repository was given and valid format, get user and repos.\n    let idx = nr_or_branch ==# '' ? 0 : 1\n    let m = matchlist(get(a:args, idx, ''),\n    \\                     '^\\([^/]\\+\\)/\\([^/]\\+\\)$')\n    let [user, repos] = !empty(m) ? m[1:2] : ['', '']\n  elseif a:type ==# s:TYPE_PROJECT\n    let path = ''\n    let m = matchlist(get(a:args, 0, ''),\n    \\                     '^\\([^/]\\+\\)/\\([^/]\\+\\)$')\n    let [user, repos] = !empty(m) ? m[1:2] : ['', '']\n  else    \" if a:type ==# s:TYPE_COMMIT\n    if len(a:args) > 1\n      let hash = a:args[0]\n    else\n      let hash = s:git('rev-parse', a:args[0])\n      if v:shell_error\n        throw \"'\" . a:args[0] .  \"' is not valid commit hash\"\n      endif\n    endif\n    let path = 'commit/' . hash\n    let m = matchlist(get(a:args, 1, ''),\n    \\                     '^\\([^/]\\+\\)/\\([^/]\\+\\)$')\n    let [user, repos] = !empty(m) ? m[1:2] : ['', '']\n  endif\n\n  return {\n  \\ 'path': path,\n  \\ 'user': user,\n  \\ 'repos': repos,\n  \\}\nendfunction\n\n\nfunction! s:call_with_temp_dir(dir, funcname, args) abort\n  let haslocaldir = haslocaldir()\n  let cwd = getcwd()\n  \" a:dir could be empty string\n  \" when specifying opening repos.\n  \" e.g.)\n  \" * :OpenGithubFile path/to/file\n  \" * :OpenGithubIssue [#]{number} {user}/{repos}\n  if a:dir !=# '' && a:dir !=# cwd\n    execute 'lcd' a:dir\n  endif\n  try\n    return call(a:funcname, a:args)\n  finally\n    if a:dir !=# cwd\n      execute (haslocaldir ? 'lcd' : 'cd') cwd\n    endif\n  endtry\nendfunction\n\nfunction! s:parse_github_remote_url(github_host) abort\n  let host_re = escape(a:github_host, '.')\n  let gh_host_re = 'github\\.com'\n\n  \" ex) ssh_re_fmt also supports 'ssh://' protocol. (#10)\n  \" - git@github.com:tyru/open-github-browser.vim\n  \" - ssh://git@github.com/tyru/open-github-browser.vim\n  let ssh_re_fmt = 'git@%s[:/]\\([^/]\\+\\)/\\([^/]\\+\\)\\s'\n  let ssh2_re_fmt = '\\s%s[:/]\\([^/]\\+\\)/\\([^/]\\+\\)\\s'\n  let ssh3_re_fmt = 'ssh://%s/\\([^/]\\+\\)/\\([^/]\\+\\)\\s'\n  let git_re_fmt = 'git://%s/\\([^/]\\+\\)/\\([^/]\\+\\)\\s'\n  let https_re_fmt = 'https\\?://%s/\\([^/]\\+\\)/\\([^/]\\+\\)\\s'\n\n  let ssh_re = printf(ssh_re_fmt, host_re)\n  let ssh2_re = printf(ssh2_re_fmt, host_re)\n  let ssh3_re = printf(ssh3_re_fmt, host_re)\n  let git_re = printf(git_re_fmt, host_re)\n  let https_re = printf(https_re_fmt, host_re)\n\n  let gh_ssh_re = printf(ssh_re_fmt, gh_host_re)\n  let gh_ssh2_re = printf(ssh2_re_fmt, gh_host_re)\n  let gh_ssh3_re = printf(ssh3_re_fmt, gh_host_re)\n  let gh_git_re = printf(git_re_fmt, gh_host_re)\n  let gh_https_re = printf(https_re_fmt, gh_host_re)\n\n  let matched = []\n  for line in s:git_lines('remote', '-v')\n    \" Even if host is not 'github.com',\n    \" parse also 'github.com'.\n    for re in [ssh_re, ssh2_re, ssh3_re, git_re, https_re] +\n    \\   (a:github_host !=# 'github.com' ?\n    \\       [gh_ssh_re, gh_ssh2_re, gh_ssh3_re, gh_git_re, gh_https_re] : [])\n      let m = matchlist(line, re)\n      if !empty(m)\n        call add(matched, {\n        \\   'user': m[1],\n        \\   'repos': substitute(m[2], '\\.git$', '', ''),\n        \\})\n      endif\n    endfor\n  endfor\n  return matched\nendfunction\n\n\" Detect user name and repos name from 'git remote -v' output.\n\" * Duplicated candidates of user and repos are removed.\n\" * Returns empty Dictionary if no valid GitHub repos are found.\n\" * Returns an Dictionary with 'user' and 'repos'\n\"   if exact 1 repos is found.\n\" * Prompt a user to choose which repos\n\"   if 2 or more repos are found.\n\"   * Throws \"INVALID INDEX\" if invalid input was given.\nfunction! s:detect_github_repos_from_git_remote(github_host) abort\n  let github_urls = s:parse_github_remote_url(a:github_host)\n  let github_urls = s:List.uniq_by(github_urls, 'v:val.user.\"/\".v:val.repos')\n  let NONE = {}\n  if len(github_urls) ==# 0\n    return NONE\n  elseif len(github_urls) ==# 1\n    return github_urls[0]\n  else\n    \" Prompt which GitHub URL.\n    let GITHUB_URL_FORMAT = 'https://%s/%s/%s'\n    let list = ['Which GitHub repository?']\n    for i in range(len(github_urls))\n      let url = printf(GITHUB_URL_FORMAT,\n      \\                a:github_host,\n      \\                github_urls[i].user,\n      \\                github_urls[i].repos)\n      call add(list, (i+1).'. '.url)\n    endfor\n    let index = inputlist(list)\n    if 1 <=# index && index <=# len(github_urls)\n      return github_urls[index-1]\n    else\n      throw 'INVALID INDEX'\n    endif\n  endif\nendfunction\n\nfunction! s:get_repos_relpath(file) abort\n  let relpath = ''\n  if s:Filepath.is_relative(a:file)\n    let dir = s:git('rev-parse', '--show-prefix')\n    let dir = dir !=# '' ? dir.'/' : ''\n    let relpath = dir.a:file\n  else\n    let relpath = s:lookup_git_relpath(a:file)\n  endif\n  let relpath = substitute(relpath, '\\', '/', 'g')\n  let relpath = substitute(relpath, '/\\{2,}', '/', 'g')\n  return relpath\nendfunction\n\nfunction! s:lookup_git_relpath(path) abort\n  return get(s:split_repos_path(a:path), 1, '')\nendfunction\n\nfunction! s:lookup_git_worktree(path) abort\n  return get(s:split_repos_path(a:path), 0, '')\nendfunction\n\n\" Returns [git worktree, relative path] when git dir is found.\n\" Otherwise, returns empty List.\nfunction! s:split_repos_path(path, ...) abort\n  let parent = s:Filepath.dirname(a:path)\n  let basename = s:Filepath.basename(a:path)\n  let removed_path = a:0 ? a:1 : ''\n  if a:path ==# parent\n    \" a:path is root directory. not found.\n    return []\n  elseif s:is_git_worktree(a:path)\n    return [a:path, removed_path]\n  else\n    if removed_path ==# ''\n      let removed_path = basename\n    else\n      let removed_path = s:Filepath.join(basename, removed_path)\n    endif\n    return s:split_repos_path(parent, removed_path)\n  endif\nendfunction\n\nfunction! s:is_git_worktree(path) abort\n  \" .git may be a file when its repository is a submodule.\n  let gitdir = s:Filepath.join(a:path, '.git')\n  return isdirectory(gitdir) || filereadable(gitdir)\nendfunction\n\n\" Enterprise GitHub is supported.\n\" ('hub' command is using this config key)\nfunction! s:get_github_host() abort\n  let url = s:git('config', '--get', 'hub.host')\n  return url !=# '' ? url : 'github.com'\nendfunction\n\n\n\n\" Default value is 1 (use vimproc)\nif get(g:, 'openbrowser_use_vimproc', 1)\n\\       && globpath(&rtp, 'autoload/vimproc.vim') !=# ''\n  function! s:git(...) abort\n    return s:trim(vimproc#system(['git'] + a:000))\n  endfunction\n\n  function! s:hub(...) abort\n    return s:trim(vimproc#system(['hub'] + a:000))\n  endfunction\nelse\n  function! s:git(...) abort\n    return s:trim(system(join(['git'] + a:000, ' ')))\n  endfunction\n\n  function! s:hub(...) abort\n    return s:trim(system(join(['hub'] + a:000, ' ')))\n  endfunction\nendif\n\nfunction! s:git_lines(...) abort\n  let output = call('s:git', a:000)\n  let keepempty = 1\n  return split(output, '\\n', keepempty)\nendfunction\n\n\n\nfunction! s:trim(str) abort\n  let str = a:str\n  let str = substitute(str, '^[ \\t\\n]\\+', '', 'g')\n  let str = substitute(str, '[ \\t\\n]\\+$', '', 'g')\n  return str\nendfunction\n\nfunction! s:resolve(path) abort\n  return exists('*resolve') ? resolve(a:path) : a:path\nendfunction\n\nfunction! s:echomsg(msg, hl) abort\n  execute 'echohl' a:hl\n  try\n    echomsg '[openbrowser-github]' a:msg\n  finally\n    echohl None\n  endtry\nendfunction\n\nfunction! s:warn(msg) abort\n  call s:echomsg(a:msg, 'WarningMsg')\nendfunction\n\nfunction! s:error(msg) abort\n  call s:echomsg(a:msg, 'ErrorMsg')\nendfunction\n\n\n\" Restore 'cpoptions' {{{\nlet &cpo = s:save_cpo\n\" }}}\n"
  },
  {
    "path": "autoload/vital/_open_browser_github/Data/List.vim",
    "content": "\" Utilities for list.\n\nlet s:save_cpo = &cpo\nset cpo&vim\n\nfunction! s:pop(list)\n  return remove(a:list, -1)\nendfunction\n\nfunction! s:push(list, val)\n  call add(a:list, a:val)\n  return a:list\nendfunction\n\nfunction! s:shift(list)\n  return remove(a:list, 0)\nendfunction\n\nfunction! s:unshift(list, val)\n  return insert(a:list, a:val)\nendfunction\n\nfunction! s:cons(x, xs)\n  return [a:x] + a:xs\nendfunction\n\nfunction! s:conj(xs, x)\n  return a:xs + [a:x]\nendfunction\n\n\" Removes duplicates from a list.\nfunction! s:uniq(list)\n  return s:uniq_by(a:list, 'v:val')\nendfunction\n\n\" Removes duplicates from a list.\nfunction! s:uniq_by(list, f)\n  let list = map(copy(a:list), printf('[v:val, %s]', a:f))\n  let i = 0\n  let seen = {}\n  while i < len(list)\n    let key = string(list[i][1])\n    if has_key(seen, key)\n      call remove(list, i)\n    else\n      let seen[key] = 1\n      let i += 1\n    endif\n  endwhile\n  return map(list, 'v:val[0]')\nendfunction\n\nfunction! s:clear(list)\n  if !empty(a:list)\n    unlet! a:list[0 : len(a:list) - 1]\n  endif\n  return a:list\nendfunction\n\n\" Concatenates a list of lists.\n\" XXX: Should we verify the input?\nfunction! s:concat(list)\n  let memo = []\n  for Value in a:list\n    let memo += Value\n  endfor\n  return memo\nendfunction\n\n\" Take each elements from lists to a new list.\nfunction! s:flatten(list, ...)\n  let limit = a:0 > 0 ? a:1 : -1\n  let memo = []\n  if limit == 0\n    return a:list\n  endif\n  let limit -= 1\n  for Value in a:list\n    let memo +=\n          \\ type(Value) == type([]) ?\n          \\   s:flatten(Value, limit) :\n          \\   [Value]\n    unlet! Value\n  endfor\n  return memo\nendfunction\n\n\" Sorts a list with expression to compare each two values.\n\" a:a and a:b can be used in {expr}.\nfunction! s:sort(list, expr)\n  if type(a:expr) == type(function('function'))\n    return sort(a:list, a:expr)\n  endif\n  let s:expr = a:expr\n  return sort(a:list, 's:_compare')\nendfunction\n\nfunction! s:_compare(a, b)\n  return eval(s:expr)\nendfunction\n\n\" Sorts a list using a set of keys generated by mapping the values in the list\n\" through the given expr.\n\" v:val is used in {expr}\nfunction! s:sort_by(list, expr)\n  let pairs = map(a:list, printf('[v:val, %s]', a:expr))\n  return map(s:sort(pairs,\n  \\      'a:a[1] ==# a:b[1] ? 0 : a:a[1] ># a:b[1] ? 1 : -1'), 'v:val[0]')\nendfunction\n\n\" Returns a maximum value in {list} through given {expr}.\n\" Returns 0 if {list} is empty.\n\" v:val is used in {expr}\nfunction! s:max_by(list, expr)\n  if empty(a:list)\n    return 0\n  endif\n  let list = map(copy(a:list), a:expr)\n  return a:list[index(list, max(list))]\nendfunction\n\n\" Returns a minimum value in {list} through given {expr}.\n\" Returns 0 if {list} is empty.\n\" v:val is used in {expr}\n\" FIXME: -0x80000000 == 0x80000000\nfunction! s:min_by(list, expr)\n  return s:max_by(a:list, '-(' . a:expr . ')')\nendfunction\n\n\" Returns List of character sequence between [a:from, a:to]\n\" e.g.: s:char_range('a', 'c') returns ['a', 'b', 'c']\nfunction! s:char_range(from, to)\n  return map(\n  \\   range(char2nr(a:from), char2nr(a:to)),\n  \\   'nr2char(v:val)'\n  \\)\nendfunction\n\n\" Returns true if a:list has a:value.\n\" Returns false otherwise.\nfunction! s:has(list, value)\n  return index(a:list, a:value) isnot -1\nendfunction\n\n\" Returns true if a:list[a:index] exists.\n\" Returns false otherwise.\n\" NOTE: Returns false when a:index is negative number.\nfunction! s:has_index(list, index)\n  \" Return true when negative index?\n  \" let index = a:index >= 0 ? a:index : len(a:list) + a:index\n  return 0 <= a:index && a:index < len(a:list)\nendfunction\n\n\" similar to Haskell's Data.List.span\nfunction! s:span(f, xs)\n  let border = len(a:xs)\n  for i in range(len(a:xs))\n    if !eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))\n      let border = i\n      break\n    endif\n  endfor\n  return border == 0 ? [[], copy(a:xs)] : [a:xs[: border - 1], a:xs[border :]]\nendfunction\n\n\" similar to Haskell's Data.List.break\nfunction! s:break(f, xs)\n  return s:span(printf('!(%s)', a:f), a:xs)\nendfunction\n\n\" similar to Haskell's Data.List.takeWhile\nfunction! s:take_while(f, xs)\n  return s:span(a:f, a:xs)[0]\nendfunction\n\n\" similar to Haskell's Data.List.partition\nfunction! s:partition(f, xs)\n  return [filter(copy(a:xs), a:f), filter(copy(a:xs), '!(' . a:f . ')')]\nendfunction\n\n\" similar to Haskell's Prelude.all\nfunction! s:all(f, xs)\n  return !s:any(printf('!(%s)', a:f), a:xs)\nendfunction\n\n\" similar to Haskell's Prelude.any\nfunction! s:any(f, xs)\n  return !empty(filter(map(copy(a:xs), a:f), 'v:val'))\nendfunction\n\n\" similar to Haskell's Prelude.and\nfunction! s:and(xs)\n  return s:all('v:val', a:xs)\nendfunction\n\n\" similar to Haskell's Prelude.or\nfunction! s:or(xs)\n  return s:any('v:val', a:xs)\nendfunction\n\nfunction! s:map_accum(expr, xs, init)\n  let memo = []\n  let init = a:init\n  for x in a:xs\n    let expr = substitute(a:expr, 'v:memo', init, 'g')\n    let expr = substitute(expr, 'v:val', x, 'g')\n    let [tmp, init] = eval(expr)\n    call add(memo, tmp)\n  endfor\n  return memo\nendfunction\n\n\" similar to Haskell's Prelude.foldl\nfunction! s:foldl(f, init, xs)\n  let memo = a:init\n  for x in a:xs\n    let expr = substitute(a:f, 'v:val', string(x), 'g')\n    let expr = substitute(expr, 'v:memo', string(memo), 'g')\n    unlet memo\n    let memo = eval(expr)\n  endfor\n  return memo\nendfunction\n\n\" similar to Haskell's Prelude.foldl1\nfunction! s:foldl1(f, xs)\n  if len(a:xs) == 0\n    throw 'foldl1'\n  endif\n  return s:foldl(a:f, a:xs[0], a:xs[1:])\nendfunction\n\n\" similar to Haskell's Prelude.foldr\nfunction! s:foldr(f, init, xs)\n  return s:foldl(a:f, a:init, reverse(copy(a:xs)))\nendfunction\n\n\" similar to Haskell's Prelude.fold11\nfunction! s:foldr1(f, xs)\n  if len(a:xs) == 0\n    throw 'foldr1'\n  endif\n  return s:foldr(a:f, a:xs[-1], a:xs[0:-2])\nendfunction\n\n\" similar to python's zip()\nfunction! s:zip(...)\n  return map(range(min(map(copy(a:000), 'len(v:val)'))), \"map(copy(a:000), 'v:val['.v:val.']')\")\nendfunction\n\n\" similar to zip(), but goes until the longer one.\nfunction! s:zip_fill(xs, ys, filler)\n  if empty(a:xs) && empty(a:ys)\n    return []\n  elseif empty(a:ys)\n    return s:cons([a:xs[0], a:filler], s:zip_fill(a:xs[1 :], [], a:filler))\n  elseif empty(a:xs)\n    return s:cons([a:filler, a:ys[0]], s:zip_fill([], a:ys[1 :], a:filler))\n  else\n    return s:cons([a:xs[0], a:ys[0]], s:zip_fill(a:xs[1 :], a:ys[1: ], a:filler))\n  endif\nendfunction\n\n\" Inspired by Ruby's with_index method.\nfunction! s:with_index(list, ...)\n  let base = a:0 > 0 ? a:1 : 0\n  return s:zip(a:list, range(base, len(a:list)+base-1))\nendfunction\n\n\" similar to Ruby's detect or Haskell's find.\n\" TODO spec and doc\nfunction! s:find(list, default, f)\n  for x in a:list\n    if eval(substitute(a:f, 'v:val', string(x), 'g'))\n      return x\n    endif\n  endfor\n  return a:default\nendfunction\n\n\" Return non-zero if a:list1 and a:list2 have any common item(s).\n\" Return zero otherwise.\nfunction! s:has_common_items(list1, list2)\n  return !empty(filter(copy(a:list1), 'index(a:list2, v:val) isnot -1'))\nendfunction\n\n\" similar to Ruby's group_by.\nfunction! s:group_by(xs, f)\n  let result = {}\n  let list = map(copy(a:xs), printf('[v:val, %s]', a:f))\n  for x in list\n    let Val = x[0]\n    let key = type(x[1]) !=# type('') ? string(x[1]) : x[1]\n    if has_key(result, key)\n      call add(result[key], Val)\n    else\n      let result[key] = [Val]\n    endif\n    unlet Val\n  endfor\n  return result\nendfunction\n\nlet &cpo = s:save_cpo\nunlet s:save_cpo\n\n\" vim:set et ts=2 sts=2 sw=2 tw=0:\n"
  },
  {
    "path": "autoload/vital/_open_browser_github/System/Filepath.vim",
    "content": "\" You should check the following related builtin functions.\n\" fnamemodify()\n\" resolve()\n\" simplify()\n\nlet s:save_cpo = &cpo\nset cpo&vim\n\nlet s:path_sep_pattern = (exists('+shellslash') ? '[\\\\/]' : '/') . '\\+'\nlet s:is_windows = has('win16') || has('win32') || has('win64') || has('win95')\nlet s:is_cygwin = has('win32unix')\nlet s:is_mac = !s:is_windows && !s:is_cygwin\n      \\ && (has('mac') || has('macunix') || has('gui_macvim') ||\n      \\   (!isdirectory('/proc') && executable('sw_vers')))\n\n\" Get the directory separator.\nfunction! s:separator()\n  return fnamemodify('.', ':p')[-1 :]\nendfunction\n\n\" Get the path separator.\nlet s:path_separator = s:is_windows ? ';' : ':'\nfunction! s:path_separator()\n  return s:path_separator\nendfunction\n\n\" Get the path extensions\nfunction! s:path_extensions()\n  if !exists('s:path_extensions')\n    if s:is_windows\n      if exists('$PATHEXT')\n        let pathext = $PATHEXT\n      else\n        \" get default PATHEXT\n        let pathext = matchstr(system('set pathext'), '^pathext=\\zs.*\\ze\\n', 'i')\n      endif\n      let s:path_extensions = map(split(pathext, s:path_separator), 'tolower(v:val)')\n    elseif s:is_cygwin\n      \" cygwin is not use $PATHEXT\n      let s:path_extensions = ['', '.exe']\n    else\n      let s:path_extensions = ['']\n    endif\n  endif\n  return s:path_extensions\nendfunction\n\n\" Convert all directory separators to \"/\".\nfunction! s:unify_separator(path)\n  return substitute(a:path, s:path_sep_pattern, '/', 'g')\nendfunction\n\n\" Get the full path of command.\nif exists('*exepath')\n  function! s:which(str)\n    return exepath(a:str)\n  endfunction\nelse\n  function! s:which(command, ...)\n    let pathlist = a:command =~# s:path_sep_pattern ? [''] :\n    \\              !a:0                  ? split($PATH, s:path_separator) :\n    \\              type(a:1) == type([]) ? copy(a:1) :\n    \\                                      split(a:1, s:path_separator)\n\n    let pathext = s:path_extensions()\n    if index(pathext, '.' . tolower(fnamemodify(a:command, ':e'))) != -1\n      let pathext = ['']\n    endif\n\n    let dirsep = s:separator()\n    for dir in pathlist\n      let head = dir ==# '' ? '' : dir . dirsep\n      for ext in pathext\n        let full = fnamemodify(head . a:command . ext, ':p')\n        if filereadable(full)\n          if s:is_case_tolerant()\n            let full = glob(substitute(\n            \\               toupper(full), '\\u:\\@!', '[\\0\\L\\0]', 'g'), 1)\n          endif\n          if full != ''\n            return full\n          endif\n        endif\n      endfor\n    endfor\n\n    return ''\n  endfunction\nendif\n\n\" Split the path with directory separator.\n\" Note that this includes the drive letter of MS Windows.\nfunction! s:split(path)\n  return split(a:path, s:path_sep_pattern)\nendfunction\n\n\" Join the paths.\n\" join('foo', 'bar')            => 'foo/bar'\n\" join('foo/', 'bar')           => 'foo/bar'\n\" join('/foo/', ['bar', 'buz/']) => '/foo/bar/buz/'\nfunction! s:join(...)\n  let sep = s:separator()\n  let path = ''\n  for part in a:000\n    let path .= sep .\n    \\ (type(part) is type([]) ? call('s:join', part) :\n    \\                           part)\n    unlet part\n  endfor\n  return substitute(path[1 :], s:path_sep_pattern, sep, 'g')\nendfunction\n\n\" Check if the path is absolute path.\nif s:is_windows\n  function! s:is_absolute(path)\n    return a:path =~? '^[a-z]:[/\\\\]'\n  endfunction\nelse\n  function! s:is_absolute(path)\n    return a:path[0] ==# '/'\n  endfunction\nendif\n\nfunction! s:is_relative(path)\n  return !s:is_absolute(a:path)\nendfunction\n\n\" Return the parent directory of the path.\n\" NOTE: fnamemodify(path, ':h') does not return the parent directory\n\" when path[-1] is the separator.\nfunction! s:dirname(path)\n  let path = a:path\n  let orig = a:path\n\n  let path = s:remove_last_separator(path)\n  if path == ''\n    return orig    \" root directory\n  endif\n\n  let path = fnamemodify(path, ':h')\n  return path\nendfunction\n\n\" Return the basename of the path.\n\" NOTE: fnamemodify(path, ':h') does not return basename\n\" when path[-1] is the separator.\nfunction! s:basename(path)\n  let path = a:path\n  let orig = a:path\n\n  let path = s:remove_last_separator(path)\n  if path == ''\n    return orig    \" root directory\n  endif\n\n  let path = fnamemodify(path, ':t')\n  return path\nendfunction\n\n\" Remove the separator at the end of a:path.\nfunction! s:remove_last_separator(path)\n  let sep = s:separator()\n  let pat = (sep == '\\' ? '\\\\' : '/') . '\\+$'\n  return substitute(a:path, pat, '', '')\nendfunction\n\n\n\" Return true if filesystem ignores alphabetic case of a filename.\n\" Return false otherwise.\nlet s:is_case_tolerant = filereadable(expand('<sfile>:r') . '.VIM')\nfunction! s:is_case_tolerant()\n  return s:is_case_tolerant\nendfunction\n\n\nlet &cpo = s:save_cpo\nunlet s:save_cpo\n\n\" vim:set et ts=2 sts=2 sw=2 tw=0:\n"
  },
  {
    "path": "autoload/vital/_open_browser_github.vim",
    "content": "let s:self_version = expand('<sfile>:t:r')\n\n\" Note: The extra argument to globpath() was added in Patch 7.2.051.\nlet s:globpath_third_arg = v:version > 702 || v:version == 702 && has('patch51')\n\nlet s:loaded = {}\n\nfunction! s:import(name, ...)\n  let target = {}\n  let functions = []\n  for a in a:000\n    if type(a) == type({})\n      let target = a\n    elseif type(a) == type([])\n      let functions = a\n    endif\n    unlet a\n  endfor\n  let module = s:_import(a:name)\n  if empty(functions)\n    call extend(target, module, 'keep')\n  else\n    for f in functions\n      if has_key(module, f) && !has_key(target, f)\n        let target[f] = module[f]\n      endif\n    endfor\n  endif\n  return target\nendfunction\n\nfunction! s:load(...) dict\n  for arg in a:000\n    let [name; as] = type(arg) == type([]) ? arg[: 1] : [arg, arg]\n    let target = split(join(as, ''), '\\W\\+')\n    let dict = self\n    while 1 <= len(target)\n      let ns = remove(target, 0)\n      if !has_key(dict, ns)\n        let dict[ns] = {}\n      endif\n      if type(dict[ns]) == type({})\n        let dict = dict[ns]\n      else\n        unlet dict\n        break\n      endif\n    endwhile\n\n    if exists('dict')\n      call extend(dict, s:_import(name))\n    endif\n    unlet arg\n  endfor\n  return self\nendfunction\n\nfunction! s:unload()\n  let s:loaded = {}\nendfunction\n\nfunction! s:exists(name)\n  return s:_get_module_path(a:name) !=# ''\nendfunction\n\nfunction! s:search(pattern)\n  let paths = s:_vital_files(a:pattern)\n  let modules = sort(map(paths, 's:_file2module(v:val)'))\n  return s:_uniq(modules)\nendfunction\n\nfunction! s:expand_modules(entry, all)\n  if type(a:entry) == type([])\n    let candidates = s:_concat(map(copy(a:entry), 's:search(v:val)'))\n    if empty(candidates)\n      throw printf('vital: Any of module %s is not found', string(a:entry))\n    endif\n    if eval(join(map(copy(candidates), 'has_key(a:all, v:val)'), '+'))\n      let modules = []\n    else\n      let modules = [candidates[0]]\n    endif\n  else\n    let modules = s:search(a:entry)\n    if empty(modules)\n      throw printf('vital: Module %s is not found', a:entry)\n    endif\n  endif\n  call filter(modules, '!has_key(a:all, v:val)')\n  for module in modules\n    let a:all[module] = 1\n  endfor\n  return modules\nendfunction\n\nfunction! s:_import(name)\n  if type(a:name) == type(0)\n    return s:_build_module(a:name)\n  endif\n  let path = s:_get_module_path(a:name)\n  if path ==# ''\n    throw 'vital: module not found: ' . a:name\n  endif\n  let sid = s:_get_sid_by_script(path)\n  if !sid\n    try\n      execute 'source' fnameescape(path)\n    catch /^Vim\\%((\\a\\+)\\)\\?:E484/\n      throw 'vital: module not found: ' . a:name\n    catch /^Vim\\%((\\a\\+)\\)\\?:E127/\n      \" Ignore.\n    endtry\n\n    let sid = s:_get_sid_by_script(path)\n  endif\n  return s:_build_module(sid)\nendfunction\n\nfunction! s:_get_module_path(name)\n  if s:_is_absolute_path(a:name) && filereadable(a:name)\n    return a:name\n  endif\n  if a:name ==# ''\n    let paths = [s:self_file]\n  elseif a:name =~# '\\v^\\u\\w*%(\\.\\u\\w*)*$'\n    let paths = s:_vital_files(a:name)\n  else\n    throw 'vital: Invalid module name: ' . a:name\n  endif\n\n  call filter(paths, 'filereadable(expand(v:val, 1))')\n  let path = get(paths, 0, '')\n  return path !=# '' ? path : ''\nendfunction\n\nfunction! s:_get_sid_by_script(path)\n  let path = s:_unify_path(a:path)\n  for line in filter(split(s:_redir('scriptnames'), \"\\n\"),\n  \\                  'stridx(v:val, s:self_version) > 0')\n    let list = matchlist(line, '^\\s*\\(\\d\\+\\):\\s\\+\\(.\\+\\)\\s*$')\n    if !empty(list) && s:_unify_path(list[2]) ==# path\n      return list[1] - 0\n    endif\n  endfor\n  return 0\nendfunction\n\nfunction! s:_file2module(file)\n  let filename = fnamemodify(a:file, ':p:gs?[\\\\/]\\+?/?')\n  let tail = matchstr(filename, 'autoload/vital/_\\w\\+/\\zs.*\\ze\\.vim$')\n  return join(split(tail, '[\\\\/]\\+'), '.')\nendfunction\n\nif filereadable(expand('<sfile>:r') . '.VIM')\n  \" resolve() is slow, so we cache results.\n  let s:_unify_path_cache = {}\n  \" Note: On windows, vim can't expand path names from 8.3 formats.\n  \" So if getting full path via <sfile> and $HOME was set as 8.3 format,\n  \" vital load duplicated scripts. Below's :~ avoid this issue.\n  function! s:_unify_path(path)\n    if has_key(s:_unify_path_cache, a:path)\n      return s:_unify_path_cache[a:path]\n    endif\n    let value = tolower(fnamemodify(resolve(fnamemodify(\n    \\                   a:path, ':p')), ':~:gs?[\\\\/]\\+?/?'))\n    let s:_unify_path_cache[a:path] = value\n    return value\n  endfunction\nelse\n  function! s:_unify_path(path)\n    return resolve(fnamemodify(a:path, ':p:gs?[\\\\/]\\+?/?'))\n  endfunction\nendif\n\nif s:globpath_third_arg\n  function! s:_runtime_files(path)\n    return split(globpath(&runtimepath, a:path, 1), \"\\n\")\n  endfunction\nelse\n  function! s:_runtime_files(path)\n    return split(globpath(&runtimepath, a:path), \"\\n\")\n  endfunction\nendif\n\nlet s:_vital_files_cache_runtimepath = ''\nlet s:_vital_files_cache = []\nfunction! s:_vital_files(pattern)\n  if s:_vital_files_cache_runtimepath !=# &runtimepath\n    let path = printf('autoload/vital/%s/**/*.vim', s:self_version)\n    let s:_vital_files_cache = s:_runtime_files(path)\n    let mod = ':p:gs?[\\\\/]\\+?/?'\n    call map(s:_vital_files_cache, 'fnamemodify(v:val, mod)')\n    let s:_vital_files_cache_runtimepath = &runtimepath\n  endif\n  let target = substitute(a:pattern, '\\.', '/', 'g')\n  let target = substitute(target, '\\*', '[^/]*', 'g')\n  let regexp = printf('autoload/vital/%s/%s.vim', s:self_version, target)\n  return filter(copy(s:_vital_files_cache), 'v:val =~# regexp')\nendfunction\n\n\" Copy from System.Filepath\nif has('win16') || has('win32') || has('win64')\n  function! s:_is_absolute_path(path)\n    return a:path =~? '^[a-z]:[/\\\\]'\n  endfunction\nelse\n  function! s:_is_absolute_path(path)\n    return a:path[0] ==# '/'\n  endfunction\nendif\n\nfunction! s:_build_module(sid)\n  if has_key(s:loaded, a:sid)\n    return copy(s:loaded[a:sid])\n  endif\n  let functions = s:_get_functions(a:sid)\n\n  let prefix = '<SNR>' . a:sid . '_'\n  let module = {}\n  for func in functions\n    let module[func] = function(prefix . func)\n  endfor\n  if has_key(module, '_vital_loaded')\n    let V = vital#{s:self_version}#new()\n    if has_key(module, '_vital_depends')\n      let all = {}\n      let modules =\n      \\     s:_concat(map(module._vital_depends(),\n      \\                   's:expand_modules(v:val, all)'))\n      call call(V.load, modules, V)\n    endif\n    try\n      call module._vital_loaded(V)\n    catch\n      \" FIXME: Show an error message for debug.\n    endtry\n  endif\n  if !get(g:, 'vital_debug', 0)\n    call filter(module, 'v:key =~# \"^\\\\a\"')\n  endif\n  let s:loaded[a:sid] = module\n  return copy(module)\nendfunction\n\nif exists('+regexpengine')\n  function! s:_get_functions(sid)\n    let funcs = s:_redir(printf(\"function /\\\\%%#=2^\\<SNR>%d_\", a:sid))\n    let map_pat = '<SNR>' . a:sid . '_\\zs\\w\\+'\n    return map(split(funcs, \"\\n\"), 'matchstr(v:val, map_pat)')\n  endfunction\nelse\n  function! s:_get_functions(sid)\n    let prefix = '<SNR>' . a:sid . '_'\n    let funcs = s:_redir('function')\n    let filter_pat = '^\\s*function ' . prefix\n    let map_pat = prefix . '\\zs\\w\\+'\n    return map(filter(split(funcs, \"\\n\"),\n    \\          'stridx(v:val, prefix) > 0 && v:val =~# filter_pat'),\n    \\          'matchstr(v:val, map_pat)')\n  endfunction\nendif\n\nif exists('*uniq')\n  function! s:_uniq(list)\n    return uniq(a:list)\n  endfunction\nelse\n  function! s:_uniq(list)\n    let i = len(a:list) - 1\n    while 0 < i\n      if a:list[i] ==# a:list[i - 1]\n        call remove(a:list, i)\n        let i -= 2\n      else\n        let i -= 1\n      endif\n    endwhile\n    return a:list\n  endfunction\nendif\n\nfunction! s:_concat(lists)\n  let result_list = []\n  for list in a:lists\n    let result_list += list\n  endfor\n  return result_list\nendfunction\n\nfunction! s:_redir(cmd)\n  let [save_verbose, save_verbosefile] = [&verbose, &verbosefile]\n  set verbose=0 verbosefile=\n  redir => res\n    silent! execute a:cmd\n  redir END\n  let [&verbose, &verbosefile] = [save_verbose, save_verbosefile]\n  return res\nendfunction\n\nfunction! vital#{s:self_version}#new()\n  return s:_import('')\nendfunction\n\nlet s:self_file = s:_unify_path(expand('<sfile>'))\n"
  },
  {
    "path": "autoload/vital/open_browser_github.vital",
    "content": "open_browser_github\ne8ec38a\n\nSystem.Filepath\nData.List\n"
  },
  {
    "path": "autoload/vital.vim",
    "content": "function! vital#of(name)\n  let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital')\n  let file = split(files, \"\\n\")\n  if empty(file)\n    throw 'vital: version file not found: ' . a:name\n  endif\n  let ver = readfile(file[0], 'b')\n  if empty(ver)\n    throw 'vital: invalid version file: ' . a:name\n  endif\n  return vital#_{substitute(ver[0], '\\W', '', 'g')}#new()\nendfunction\n"
  },
  {
    "path": "doc/openbrowser-github.txt",
    "content": "*openbrowser-github* Launch GitHub quickly from Vim\n\nAuthor:\n  tyru <tyru.exe@gmail.com>\nVersion: 1.0.0\nLicense: See LICENSE file in this repository\n\n==============================================================================\nCONTENTS\t\t\t\t\t\t*openbrowser-github-contents*\n\nIntroduction\t\t|openbrowser-github-introduction|\nRequirements\t\t|openbrowser-github-requirements|\nInterface\t\t\t|openbrowser-github-interface|\n  Variables\t\t\t|openbrowser-github-variables|\n  Commands\t\t\t|openbrowser-github-commands|\nTODO\t\t\t\t|openbrowser-github-todo|\nChangelog\t\t\t|openbrowser-github-changelog|\n\n\n==============================================================================\nINTRODUCTION\t\t\t\t\t\t*openbrowser-github-introduction* {{{\n\nOpens GitHub URL of current file, etc. from Vim.\nAlso supports GitHub Enterprise(|openbrowser-github-enterprise|).\n\nSee |openbrowser-github-commands| for the details of available commands.\n\n}}}\n==============================================================================\nREQUIREMENTS\t\t\t\t\t\t*openbrowser-github-requirements* {{{\n\nYou must install the following plugin/libraries.\n\n* open-browser.vim\n  https://github.com/tyru/open-browser.vim\n* git command in your PATH\n\n}}}\n==============================================================================\nGITHUB ENTERPRISE SETTING\t\t\t*openbrowser-github-enterprise* {{{\n\nIf you have `hub` command\n-----------------------\n\nIf you have `hub` command(https://github.com/github/hub) in your PATH,\n|openbrowser-github| executes the following command: >\n\thub browse -u -- {path}\nAnd it will open the returned (output) URL.\n\nIf you _don't_ have `hub` command\n-------------------------------\n\nIf you don't have `hub` command in your PATH, |openbrowser-github| tries to\nget each part of URL from the following gitconfig key:\n\n* hub.host\n\nYou can specify GitHub Enterprise repository URL by setting above keys in\ngitconfig.\n\nFor example, you can set `hub.host` by executing the following command in your\ngit repository which you want to specify GitHub Enterprise repository URL.\n>\n\tgit config --local hub.host my.git.org\n<\n}}}\n==============================================================================\nINTERFACE\t\t\t\t*openbrowser-github-interface* {{{\n------------------------------------------------------------------------------\nVARIABLES\t\t\t\t\t*openbrowser-github-variables* {{{\n\n\t\t\t\t\t*g:openbrowser_github_always_used_branch*\ng:openbrowser_github_always_used_branch\n\t\t\t\t\t\t\t(Default: \"\")\n\tIf this variable is not empty string,\n\t|openbrowser-github| always opens current file\n\tin the branch.\n\n\t\t\t\t\t*g:openbrowser_github_always_use_commit_hash*\ng:openbrowser_github_always_use_commit_hash\n\t\t\t\t\t\t\t(Default: 1)\n\tIf this variable is non-zero value,\n\t|openbrowser-github| always opens a URL\n\twith a current commit hash.\n\tex) https://github.com/tyru/open-browser.vim/blob/9f1de0e38a1e378061a8f10df6ed8e22c48aa9ae/autoload/openbrowser.vim\n\n\tIf this variable is zero value,\n\t|openbrowser-github| opens a URL\n\twith a current commit hash\n\tif current working tree is detached state.\n\tOtherwise, |openbrowser-github| opens a URL\n\twith a current branch's latest file.\n\tex) https://github.com/tyru/open-browser.vim/blob/master/autoload/openbrowser.vim\n\n\t\t\t\t\t*g:openbrowser_github_url_exists_check*\ng:openbrowser_github_url_exists_check\n\t\t\t\t\t\t\t(Default: \"yes\")\n\tThis determines the behavior when you\n\tpush to the non-existent/unauthorized repository.\n\tIf this variable is \"yes\", shows prompt to ask you\n\tif you really open URL.\n\tIf this variable is \"ignore\", any prompts and warning\n\tmessages aren't showed.\n\tOtherwise, it is treated as default value (\"yes\").\n\n\t\t\t\t\t*g:openbrowser_github_select_current_line*\ng:openbrowser_github_select_current_line\n\t\t\t\t\t\t\t(Default: 0)\n\t|:OpenGithubFile| opens a github page that current line is highlighted on.\n\tIf this variable is non-zero, always opens URL with current line fragment\n\t(`...#Lxxx`) even the line is not selected in visual-mode.  If this\n\tvariable is zero (default), it opens URL with current line fragment only\n\twhen the line is selected in visual-mode.\n\n}}}\n------------------------------------------------------------------------------\nCOMMANDS\t\t\t\t\t*openbrowser-github-commands* {{{\n\n:OpenGithubFile [{path}]\t\t\t\t\t*:OpenGithubFile*\n------------------------\n\nOpens a specific file in github.com repository(it also opens in the current branch by default).\n>\n\t\" Opens current files URL in github.com\n\t\" ex) https://{hostname}/{user}/{repos}/blob/{hash or branch}/{relpath}\n\t:OpenGithubFile\n\n\t\" Opens current files highlighted place in github.com\n\t\" ex) https://{hostname}/{user}/{repos}/blob/{hash or branch}/{relpath}#{lnum}\n\t:'<,'>OpenGithubFile\n\n\t\" Opens a specific file in github.com\n\t\" ex) https://{hostname}/{user}/{repos}/blob/{hash or branch}/PATH/TO/FILE#{lnum}\n\t:OpenGithubFile PATH/TO/FILE\n<\n\tThose URLs are influenced by some global variables.\n\tSee:\n\t* |g:openbrowser_github_always_used_branch|\n\t* |g:openbrowser_github_always_use_commit_hash|\n\n\n\t\t\t\t\t\t\t*:OpenGithubIssue*\n:OpenGithubIssue\n:OpenGithubIssue [#]{number} [{user}/{repos}]\n:OpenGithubIssue {user}/{repos}\n-----------------------------------\n\nOpens a specific Issue.\n>\n\t\" Opens current repositories Issue #1\n\t\" ex) https://{hostname}/{user}/{repos}/issues/1\n\t:OpenGithubIssue 1\n\n\t\" Opens a specific repositories Issue #1\n\t\" ex) https://{hostname}/tyru/open-browser.vim/issues/1\n\t:OpenGithubIssue 1 tyru/open-browser.vim\n\n\t\" Opens current repositories Issue List\n\t\" ex) https://{hostname}/{user}/{repos}/issues\n\t:OpenGithubIssue\n\n\t\" Opens a specific repositories Issue list\n\t\" ex) https://{hostname}/tyru/open-browser.vim/issues\n\t:OpenGithubIssue tyru/open-browser.vim\n<\n\n\t\t\t\t\t\t\t*:OpenGithubPullReq*\n:OpenGithubPullReq\n:OpenGithubPullReq [#]{number} [{user}/{repos}]\n:OpenGithubPullReq #{branch} [{user}/{repos}]\n:OpenGithubPullReq {user}/{repos}\n-------------------------------------\n\nOpens '/pulls' page when it has no argument.\nOtherwise, it does entirely the same thing as |:OpenGithubIssue|\nsince GitHub redirects '/issues/1' to '/pull/1'\nif #1 is a Pull Request.\n\nAdditionally, this command supports opening a pull request page by branch name.\n>\n\t\" Opens current repository's pull request of specified branch name\n\t:OpenGithubPullReq #branch_name_of_pull_request\n\t\" Opens https://github.com/tyru/open-browser-github.vim/pull/25\n\t:OpenGithubPullReq #OpenGithubPullReq-branch-argument tyru/open-browser-github.vim\n<\n\n\t\t\t\t\t\t\t*:OpenGithubProject*\n:OpenGithubProject [{user}/{repos}]\n\nOpens a project page.\n>\n\t\" Opens current opening file's repository.\n\t\" ex) https://{hostname}/{user}/{name}\n\t:OpenGithubProject\n>\n\t\" Opens current opening file's repository.\n\t\" ex) https://{hostname}/tyru/open-browser.vim\n\t:OpenGithubProject tyru/open-browser.vim\n<\n\t\t\t\t\t\t\t*:OpenGithubCommit*\n:OpenGithubCommit {commit hash} [{user}/{repos}]\n\nOpens a commit page.\n>\n\t\" Opens current repository's commit.\n\t\" ex) https://{hostname}/{user}/{name}/commit/{hash}\n\t:OpenGithubCommit HEAD\n>\n\t\" Opens speicified repository's commit.\n\t\" ex) https://{hostname}/vim/vim/commit/b1c9198afb\n\t:OpenGithubCommit b1c9198afb vim/vim\n\n}}}\n}}}\n==============================================================================\nTODO\t\t\t\t\t\t*openbrowser-github-todo* {{{\n\nAny requests? ;)\n\nhttps://github.com/tyru/open-browser-github.vim/issues\n\n}}}\n==============================================================================\nCHANGELOG\t\t\t\t\t\t*openbrowser-github-changelog* {{{\n\n1.0.0:\n- Initial upload\n\n}}}\n==============================================================================\nvim:tw=78:fo=tcq2mM:ts=4:ft=help:norl:noet:fdm=marker:fen\n"
  },
  {
    "path": "plugin/openbrowser/github.vim",
    "content": "\" vim:foldmethod=marker:fen:\nscriptencoding utf-8\n\n\" Load Once {{{\nif get(g:, 'loaded_openbrowser_github', 0) || &cp\n  finish\nendif\nlet g:loaded_openbrowser_github = 1\n\" }}}\n\" Saving 'cpoptions' {{{\nlet s:save_cpo = &cpo\nset cpo&vim\n\" }}}\n\n\nfunction! s:error(msg) abort\n  echohl ErrorMsg\n  echomsg a:msg\n  echohl None\nendfunction\n\nif !executable('git')\n  call s:error('Please install git in your PATH.')\n  finish\nendif\nif globpath(&rtp, 'plugin/openbrowser.vim') ==# ''\n  call s:error('open-browser-github.vim depends on open-browser.vim. Please install open-browser.vim')\n  finish\nendif\n\nif !exists('g:openbrowser_github_always_used_branch')\n  let g:openbrowser_github_always_used_branch = ''\nendif\nif !exists('g:openbrowser_github_always_use_commit_hash')\n  let g:openbrowser_github_always_use_commit_hash = 1\nendif\nif !exists('g:openbrowser_github_url_exists_check')\n  let g:openbrowser_github_url_exists_check = 'yes'\nendif\nif !exists('g:openbrowser_github_select_current_line')\n  let g:openbrowser_github_select_current_line = 0\nendif\n\n\ncommand! -range=0 -bar -nargs=* -complete=file\n\\   OpenGithubFile\n\\   call openbrowser#github#file([<f-args>], <count>, <line1>, <line2>)\n\ncommand! -bar -nargs=*\n\\   OpenGithubIssue\n\\   call openbrowser#github#issue([<f-args>])\n\ncommand! -bar -nargs=*\n\\   OpenGithubPullReq\n\\   call openbrowser#github#pullreq([<f-args>])\n\ncommand! -bar -nargs=*\n\\   OpenGithubProject\n\\   call openbrowser#github#project([<f-args>])\n\ncommand! -bar -nargs=+\n\\   OpenGithubCommit\n\\   call openbrowser#github#commit([<f-args>])\n\n\n\" Restore 'cpoptions' {{{\nlet &cpo = s:save_cpo\n\" }}}\n"
  }
]