Permalink
Browse files

Fuck all of this.

  • Loading branch information...
1 parent 5dbc1c6 commit 9ef7b95afc5723af876edea183fa5d5e5946a0c5 @sjl committed Jul 17, 2013
Showing with 8 additions and 19,348 deletions.
  1. +0 −31 .hgignore
  2. +0 −1 .pythonrc.py
  3. +8 −0 README.markdown
  4. +0 −22 ackrc
  5. +0 −33 bash_profile
  6. +0 −1,563 bcvi/bcvi
  7. +0 −54 bin/addcontact
  8. +0 −51 bin/bootstrap.sh
  9. +0 −28 bin/clean_mail
  10. +0 −365 bin/colortest
  11. +0 −1 bin/ffind
  12. +0 −3 bin/figlet-find-font
  13. +0 −8 bin/figlet-out
  14. +0 −21 bin/git_prompt_status
  15. +0 −313 bin/lein
  16. +0 −2 bin/lilypond
  17. +0 −31 bin/longcat
  18. +0 −5 bin/maven
  19. +0 −1 bin/mutt-notmuch-py
  20. +0 −3 bin/mvim
  21. +0 −17 bin/myctags
  22. +0 −10 bin/pb
  23. +0 −1 bin/peat
  24. +0 −24 bin/rdio-current-track-tmux
  25. +0 −3 bin/vim
  26. +0 −32 ctags
  27. +0 −1 dotcss/amara.readthedocs.org.css
  28. +0 −1 dotcss/bitbucket.org.css
  29. +0 −3 dotcss/bugzilla.pculture.org.css
  30. +0 −7 dotcss/debuggex.com.css
  31. +0 −4 dotcss/default.css
  32. +0 −4 dotcss/dpaste.com.css
  33. +0 −6 dotcss/gist.github.com.css
  34. +0 −20 dotcss/github.com.css
  35. +0 −3 dotcss/goodreads.com.css
  36. +0 −3 dotcss/google.com.css
  37. +0 −2 dotcss/khanacademy.org.css
  38. +0 −15 dotcss/linkedin.com.css
  39. +0 −2 dotcss/news.ycombinator.com.css
  40. +0 −5 dotcss/okcupid.com.css
  41. +0 −8 dotcss/readthedocs.org.css
  42. +0 −4 dotcss/refheap.com.css
  43. +0 −1 dotcss/secure.flickr.com.css
  44. +0 −3 dotcss/unisubs.example.com.css
  45. +0 −12 dotcss/unisubs.sifterapp.com.css
  46. +0 −209 dotcss/weather.com.css
  47. +0 −3 dotcss/youtube.com.css
  48. +0 −8 dotjs/500px.com.js
  49. 0 dotjs/bugzilla.pculture.org.js
  50. +0 −4 dotjs/democratandchronicle.com.js
  51. +0 −4 dotjs/dev.universalsubtitles.org.js
  52. +0 −1 dotjs/encrypted.google.com.js
  53. +0 −3 dotjs/flickr.com.js
  54. +0 −48 dotjs/getprismatic.com.js
  55. +0 −72 dotjs/github.com.js
  56. +0 −151 dotjs/google.com.js
  57. +0 −7 dotjs/nytimes.com.js
  58. +0 −19 dotjs/readability.com.js
  59. +0 −1 dotjs/reddit.com.js
  60. +0 −1 dotjs/secure.flickr.com.js
  61. +0 −1 dotjs/staging.universalsubtitles.org
  62. +0 −1 dotjs/unisubs.example.com.js
  63. +0 −14 dotjs/unisubs.sifterapp.com.js
  64. +0 −2 dotjs/youtube.com.js
  65. +0 −5 ffignore
  66. +0 −364 fish/config.fish
  67. +0 −47 fish/virtualenv.fish
  68. +0 −111 gitconfig
  69. +0 −5 gitignore
  70. +0 −56 grc/conf.maven
  71. +0 −6 hgignore
  72. +0 −273 hgrc
  73. 0 inputrc
  74. +0 −1 keymando/Plugins/abbrev
  75. +0 −49 keymando/keymandorc.rb
  76. +0 −131 keyremap4macbook/cadet.py
  77. +0 −1,120 keyremap4macbook/private.xml
  78. +0 −14 launchagents/com.stevelosh.dammitkeymando.plist
  79. +0 −14 launchagents/com.stevelosh.mailsync.plist
  80. +0 −17 mutt/Equifax_Secure_CA.cert
  81. 0 mutt/cache/.placeholder
  82. 0 mutt/cache/bodies/.placeholder
  83. 0 mutt/cache/headers/.placeholder
  84. +0 −43 mutt/colors.muttrc
  85. +0 −35 mutt/mailcap
  86. +0 −228 mutt/muttrc
  87. +0 −87 mutt/notmuch-config
  88. +0 −16 mutt/offlineimap.py
  89. +0 −18 mutt/offlineimapsync.sh
  90. +0 −6 mutt/sidebar.muttrc
  91. +0 −1 mutt/sig
  92. 0 mutt/temp/.placeholder
  93. +0 −127 mutt/view_attachment.sh
  94. +0 −74 offlineimaprc
  95. +0 −195 osx.sh
  96. +0 −66 pentadactylrc
  97. +0 −28 slate
  98. +0 −119 tmux/tmux.conf
  99. +0 −1 urlview
  100. +0 −1 vim/.VimballRecord
  101. +0 −1 vim/.agignore
  102. +0 −43 vim/after/ftplugin/markdown.vim
  103. +0 −63 vim/after/plugin/fireplace-map-unfucking.vim
  104. +0 −48 vim/after/plugin/fireplace.vim
  105. +0 −2 vim/after/plugin/surround-mapping.vim
  106. +0 −166 vim/autoload/Powerline/Colorschemes/badwolf.vim
  107. +0 −250 vim/autoload/pathogen.vim
  108. +0 −1 vim/bullshit/python
  109. +0 −1 vim/bundle/AnsiEsc.vim
  110. +0 −1 vim/bundle/ack
  111. +0 −1 vim/bundle/alienscript/ftdetect/alienscript.vim
  112. +0 −8 vim/bundle/alienscript/ftplugin/alienscript.vim
  113. +0 −33 vim/bundle/alienscript/indent/alienscript.vim
  114. +0 −59 vim/bundle/alienscript/syntax/alienscript.vim
  115. +0 −1 vim/bundle/clojure-static
  116. +0 −47 vim/bundle/closetags-custom/ftplugin/html/closetags.vim
  117. +0 −1 vim/bundle/closetags-custom/ftplugin/htmldjango
  118. +0 −1 vim/bundle/closetags-custom/ftplugin/htmljinja
  119. +0 −1 vim/bundle/command-t
  120. +0 −1 vim/bundle/commaobject
  121. +0 −1 vim/bundle/commentary
  122. +0 −1 vim/bundle/ctrlp
  123. +0 −1 vim/bundle/delimitmate
  124. +0 −1 vim/bundle/dispatch
  125. +0 −29 vim/bundle/django-custom/ftplugin/django.vim
  126. +0 −1 vim/bundle/django-custom/ftplugin/htmldjango/sparkup.py
  127. +0 −1 vim/bundle/django-custom/ftplugin/htmldjango/sparkup.vim
  128. +0 −79 vim/bundle/django-custom/indent/htmldjango.vim
  129. +0 −96 vim/bundle/django-custom/syntax/django.vim
  130. +0 −1 vim/bundle/easymotion
  131. +0 −1 vim/bundle/fireplace
  132. +0 −1 vim/bundle/fugitive
  133. +0 −1 vim/bundle/hammer
  134. +0 −190 vim/bundle/haskellmode/autoload/haskellmode.vim
  135. +0 −535 vim/bundle/haskellmode/compiler/ghc.vim
  136. +0 −465 vim/bundle/haskellmode/doc/haskellmode.txt
  137. +0 −13 vim/bundle/haskellmode/ftplugin/haskell.vim
  138. +0 −880 vim/bundle/haskellmode/ftplugin/haskell_doc.vim
  139. +0 −79 vim/bundle/haskellmode/ftplugin/haskell_hpaste.vim
  140. +0 −1 vim/bundle/html5
  141. +0 −1 vim/bundle/indent-object
  142. +0 −1 vim/bundle/javascript
  143. +0 −29 vim/bundle/jinja-custom/syntax/htmljinja.vim
  144. +0 −113 vim/bundle/jinja-custom/syntax/jinja.vim
  145. +0 −19 vim/bundle/lilypond/compiler/lilypond.vim
  146. +0 −4 vim/bundle/lilypond/ftdetect/lilypond.vim
  147. +0 −57 vim/bundle/lilypond/ftplugin/lilypond.vim
  148. +0 −60 vim/bundle/lilypond/indent/lilypond.vim
  149. +0 −1,268 vim/bundle/lilypond/syntax/lilypond-words
  150. +0 −3 vim/bundle/lilypond/syntax/lilypond-words.vim
  151. +0 −87 vim/bundle/lilypond/syntax/lilypond.vim
  152. +0 −1 vim/bundle/linediff
  153. +0 −1 vim/bundle/makegreen
  154. +0 −1 vim/bundle/markdown
  155. +0 −1 vim/bundle/maven
  156. +0 −1 vim/bundle/nerdcommenter
  157. +0 −1 vim/bundle/nerdtree
  158. +0 −1 vim/bundle/nosecompiler
  159. +0 −1 vim/bundle/orgmode
  160. +0 −1 vim/bundle/pgsql
  161. +0 −1 vim/bundle/potion/ftdetect/potion.vim
  162. +0 −33 vim/bundle/potion/syntax/potion.vim
  163. +0 −1 vim/bundle/powerline
  164. +0 −1 vim/bundle/puppet/ftdetect/puppet.vim
  165. +0 −89 vim/bundle/puppet/syntax/puppet.vim
  166. +0 −1 vim/bundle/pydoc
  167. +0 −1 vim/bundle/python
  168. +0 −1 vim/bundle/python-mode
  169. +0 −1 vim/bundle/rainbow-parens
  170. +0 −1 vim/bundle/rainbow-parentheses
  171. +0 −1 vim/bundle/repeat
  172. +0 −1 vim/bundle/salt
  173. +0 −1 vim/bundle/scala
  174. +0 −1 vim/bundle/scriptease
  175. +0 −1 vim/bundle/smartinput
  176. +0 −1 vim/bundle/sparkup
  177. +0 −1 vim/bundle/supertab
  178. +0 −1 vim/bundle/surround
  179. +0 −1 vim/bundle/syntastic
  180. +0 −1 vim/bundle/tasklist
  181. +0 −1 vim/bundle/tslime
  182. +0 −1 vim/bundle/utl
  183. +0 −1 vim/bundle/vim-arpeggio
  184. +0 −1 vim/bundle/vim-clojure-static
  185. +0 −1 vim/bundle/vim-coffee-script
  186. +0 −1 vim/bundle/vim-commentary
  187. +0 −1 vim/bundle/vim-javascript
  188. +0 −1 vim/bundle/vim-makegreen
  189. +0 −1 vim/bundle/vim-orgmode
  190. +0 −1 vim/bundle/vim-speeddating
  191. +0 −1 vim/bundle/yankring
  192. +0 −41 vim/castrate.py
  193. +0 −246 vim/colors/molokai.vim
  194. +0 −60 vim/colors/mustang.vim
  195. +0 −55 vim/colors/vitamins.vim
  196. +0 −33 vim/compiler/cake-test-wrapper.py
  197. +0 −20 vim/compiler/clojure.vim
  198. +0 −123 vim/custom-dictionary.utf-8.add
  199. +0 −5 vim/ftdetect/io.vim
  200. +0 −111 vim/ftplugin/clojure/folding.vim
  201. +0 −82 vim/ftplugin/html.vim
  202. +0 −43 vim/ftplugin/lisp/lispfolding.vim
  203. +0 −254 vim/ftplugin/python/folding.vim
  204. +0 −249 vim/haskellmode.config
  205. +0 −76 vim/indent/less.vim
  206. +0 −197 vim/indent/python.vim
  207. +0 −115 vim/jsl.conf
  208. +0 −19 vim/plugin/grep-operator.vim
  209. +0 −110 vim/plugin/scratch.vim
  210. +0 −1 vim/sadness/sparkup
  211. +0 −17 vim/snippets/_.snippets
  212. +0 −66 vim/snippets/autoit.snippets
  213. +0 −110 vim/snippets/c.snippets
  214. +0 −12 vim/snippets/clojure.snippets
  215. +0 −30 vim/snippets/cpp.snippets
  216. +0 −128 vim/snippets/django.snippets
  217. +0 −190 vim/snippets/html.snippets
  218. +0 −135 vim/snippets/htmldjango.snippets
  219. +0 −1 vim/snippets/htmljinja.snippets
  220. +0 −78 vim/snippets/java.snippets
  221. +0 −76 vim/snippets/javascript.snippets
  222. +0 −17 vim/snippets/jinja.snippets
  223. +0 −34 vim/snippets/lisp.snippets
  224. +0 −54 vim/snippets/mako.snippets
  225. +0 −10 vim/snippets/markdown.snippets
  226. +0 −184 vim/snippets/objc.snippets
  227. +0 −91 vim/snippets/perl.snippets
  228. +0 −216 vim/snippets/php.snippets
  229. +0 −31 vim/snippets/python.snippets
  230. +0 −420 vim/snippets/ruby.snippets
  231. +0 −3 vim/snippets/scheme.snippets
  232. +0 −28 vim/snippets/sh.snippets
  233. +0 −7 vim/snippets/snippet.snippets
  234. +0 −92 vim/snippets/tcl.snippets
  235. +0 −115 vim/snippets/tex.snippets
  236. +0 −32 vim/snippets/vim.snippets
  237. +0 −58 vim/snippets/zsh.snippets
  238. +0 −205 vim/syntax/confluencewiki.vim
  239. +0 −41 vim/syntax/cram.vim
  240. +0 −92 vim/syntax/creole.vim
  241. +0 −138 vim/syntax/fish.vim
  242. +0 −89 vim/syntax/io.vim
  243. +0 −312 vim/syntax/less.vim
  244. +0 −664 vim/syntax/nginx.vim
  245. +0 −109 vim/syntax/pentadactyl.vim
  246. +0 −7 vim/syntax/python.vim
  247. 0 vim/tmp/backup/.placeholder
  248. 0 vim/tmp/swap/.placeholder
  249. 0 vim/tmp/undo/.placeholder
  250. +0 −2,038 vim/vimrc
  251. +0 −38 weechat/alias.conf
  252. +0 −19 weechat/aspell.conf
  253. +0 −42 weechat/buffers.conf
  254. +0 −11 weechat/charset.conf
  255. BIN weechat/icon.png
  256. +0 −26 weechat/logger.conf
Sorry, we could not display the entire diff because it was too big.
View
31 .hgignore
@@ -1,31 +0,0 @@
-syntax: glob
-
-.DS_Store
-*.pyc
-.netrwhist
-*.swp
-*.swo
-tags
-config/bcvi
-*.un~
-
-vim/tmp
-vim/bundle/gundo
-
-mutt/temp
-mutt/cache
-vim/spell
-fishd*
-fish_history
-bundle/vim-fugitive
-bundle/vermilion
-weechat/logs
-weechat/weechat.log
-weechat/python/autoload/servers.py
-weechat/urls.log
-weechat/irc.conf
-vim/bundle/potion
-vim/custom-dictionary.utf-8.add.spl
-bin/http_load
-fish/fish_read_history
-fish/completions
View
1 .pythonrc.py
@@ -1 +0,0 @@
-from see import see
View
8 README.markdown
@@ -0,0 +1,8 @@
+[View my dotfiles on BitBucket](http://bitbucket.org/sjl/dotfiles/)
+
+For a while I've been maintaining a mirror of my dotfiles here on GitHub.
+
+Unfortunately at some point, something shat the bed inside the giant Rube
+Goldberg machine of hg-git and GitHub. My life is too short to deal with this
+bullshit, so I'm not maintaining this mirror any more. You can still go look at
+them on BitBucket.
View
22 ackrc
@@ -1,22 +0,0 @@
---smart-case
---type-set
-log=.log
---type-set
-django=.py,.html
---type-set
-less=.less
---type-set
-vim=.vim
---type-set
-puppet=.pp
---type-set
-fe=.html,.js,.less
---type-set
-fea=.html,.js,.less,.css
---type-set
-docs=.markdown,.md,.mdown,.rst
---ignore-dir=public/media/cache
---ignore-dir=public/static/cache
---ignore-dir=build/html
---ignore-dir=docs/build
---ignore-dir=migrations
View
33 bash_profile
@@ -1,33 +0,0 @@
-#!/usr/bin/env bash
-
-shopt -s expand_aliases
-
-
-# This file contains aliases and functions that duplicate some fish
-# functionality, because Vim will use bash as its external command shell.
-
-AG_BIN="`which ag`"
-function ag() {
- if test -f '.agignore' && grep -q 'pragma: skipvcs' '.agignore'; then
- $AG_BIN --search-files -U "$@"
- else
- $AG_BIN --search-files "$@"
- fi
-}
-
-export PATH=~/bin:~/lib/dotfiles/bin:/usr/local/share/python:/usr/local/bin/:$PATH
-
-alias h='hg'
-alias g='git'
-alias pbc='pbcopy'
-alias pbp='pbpaste'
-alias pbpb='pbp | pb'
-alias vu='vagrant up'
-alias vs='vagrant suspend'
-alias o='open'
-alias oo='open .'
-alias t='~/lib/t/t.py --task-dir="~/Dropbox/tasks" --list=tasks.txt'
-
-function psg() {
- ps auxww | grep --color=always $* | grep -v grep | collapse | cuts -f 2,11-
-}
View
1,563 bcvi/bcvi
@@ -1,1563 +0,0 @@
-#!/usr/bin/perl
-##############################################################################
-#
-# Script: bcvi
-#
-# The 'Back-Channel vim' tool works with SSH to allow commands which are run
-# on an SSH server to invoke processes back on the originating SSH client
-# machine.
-#
-# Use 'bcvi --help' for the documentation
-#
-# Copyright (c) 2007-2010 Grant McLean <grantm@cpan.org>
-#
-
-use strict;
-use warnings;
-
-require 5.008;
-
-##############################################################################
-# This package implements some common functionality required by both the
-# client and the server.
-#
-# It also serves as the entry-point for the command-line script.
-##############################################################################
-
-package App::BCVI;
-BEGIN {
- $App::BCVI::VERSION = '3.05';
-}
-
-use File::Spec;
-use File::Path;
-use Getopt::Long qw();
-use Encode qw(encode decode);
-use IO::Socket::INET;
-
-my %class_map = (
- base => 'App::BCVI',
- client => 'App::BCVI::Client',
- server => 'App::BCVI::Server',
- pod => 'App::BCVI::POD',
-);
-
-my %response_message = (
- 100 => "Ready ($App::BCVI::VERSION)",
- 200 => "Success",
- 300 => "Response follows",
- 900 => "Permission denied",
- 910 => "Unrecognised command",
-);
-
-my $LF = "\x0A";
-
-my(
- %options, %option_name, %commands, @aliases, @installables,
- %plugin_loaded, @plugins,
-);
-
-run(@ARGV) unless caller(); # Don't run anything if loaded via 'require'
-
-sub run {
- App::BCVI->base_init();
-
- App::BCVI->load_plugins();
-
- App::BCVI->base_class()->process_command_line(@_);
-
- exit;
-}
-
-sub version { return $App::BCVI::VERSION; }
-sub base_class { return $class_map{base}; }
-sub client_class { return $class_map{client}; }
-sub server_class { return $class_map{server}; }
-sub pod_class { return $class_map{pod}; }
-sub map_class { $class_map{$_[1]} = $_[2]; }
-sub sock { shift->{sock}; }
-
-sub installable_files { return @installables; }
-sub message_from_code { $response_message{$_[1]}; }
-
-sub base_init {
- my($class) = @_;
-
- $class->register_option(
- name => 'help',
- alias => '?',
- dispatch_to => 'show_help',
- summary => 'detailed help message',
- description => <<'END_POD'
-Display this documentation.
-END_POD
- );
-
- $class->register_option(
- name => 'add-aliases',
- dispatch_to => 'add_aliases',
- summary => 'install bcvi into shell startup files',
- description => <<'END_POD'
-Edit the bash startup script to add (or update) the required command aliases
-for bcvi.
-END_POD
- );
-
- $class->register_option(
- name => 'listener',
- alias => 'l',
- dispatch_to => 'start_listener',
- summary => 'start in listener mode',
- description => <<'END_POD'
-Start a background listener process. Also generates a new authentication key.
-END_POD
- );
-
- $class->register_option(
- name => 'install',
- arg_name => '<hosts>',
- dispatch_to => 'install_to_hosts',
- summary => 'copy bcvi to named hosts and install aliases',
- description => <<'END_POD'
-Copy the C<bcvi> script to the C<$HOME/bin> directory on the specified host
-and then remotely invoke it with the C<--add-aliases> option.
-END_POD
- );
-
- $class->register_option(
- name => 'unpack-term',
- dispatch_to => 'unpack_term',
- summary => 'unpack the overloaded TERM variable',
- description => <<'END_POD'
-This option is intended for use from a F<.profile> script. It outputs a
-snippet of shell script to be passed to C<eval> in the calling shell.
-END_POD
- );
-
- $class->register_option(
- name => 'wrap-ssh',
- alias => 's',
- dispatch_to => 'wrap_ssh',
- summary => 'pass all args after -- to ssh',
- description => <<'END_POD'
-A wrapper around invoking ssh to connect to a specified host. Ensures the
-environment is set up to pass the authentication key and other data to the
-C<bcvi> client on the remote server.
-END_POD
- );
-
- $class->register_option(
- name => 'version',
- alias => 'v',
- dispatch_to => 'show_versions',
- summary => 'display bcvi version number',
- description => <<'END_POD'
-When invoking a command use this option to indicate that the arguments are not
-filenames and the translation of relative pathnames to absolute should be
-skipped.
-END_POD
- );
-
- $class->register_option(
- name => 'no-path-xlate',
- alias => 'n',
- summary => 'skip translation of args from relative to absolute',
- description => <<'END_POD'
-Displays the version number of the bcvi client and if applicable, of the
-listener process.
-END_POD
- );
-
- $class->register_option(
- name => 'port',
- alias => 'p',
- arg_spec => '=i',
- arg_name => '<port>',
- summary => 'port number for listener/port-forward',
- description => <<'END_POD'
-When used with C<--listener>, this is the port the server process will listen
-on. When used with C<--wrap-ssh> this is the port number on the remote machine
-that will be forwarded back to the listener process. The default in both cases
-is calculated using the user's numeric UID multiplied by 10 and added to 9.
-The intent is to reduce the chance of collisions with other bcvi users.
-END_POD
- );
-
- $class->register_option(
- name => 'command',
- alias => 'c',
- arg_spec => '=s',
- arg_name => '<cmnd>',
- summary => 'command to send over back-channel',
- description => <<'END_POD'
-Use C<cmnd> as the command to send over the back-channel (default: vi).
-Recognised commands are described in L<COMMANDS> below.
-END_POD
- );
-
- $class->register_option(
- name => 'reuse-auth',
- summary => "don't generate a new auth key on listener startup",
- description => <<'END_POD'
-A new (random) authorisation key is generated when the listener process is
-started - this will invalidate the keys in use by existing SSH sessions.
-This option is for use when it is necessary to restart the listener process
-without invalidating client keys.
-END_POD
- );
-
- $class->register_option(
- name => 'plugin-help',
- arg_spec => '=s',
- arg_name => '<plugin>',
- dispatch_to => 'plugin_help',
- summary => "display documentation for <plugin>",
- description => <<'END_POD'
-The --help output includes a list of installed plugins. Use this option to
-read the documentation for a named plugin.
-END_POD
- );
-
-
- $class->register_command(
- name => 'vi',
- description => <<'END_POD'
-Invokes C<gvim> on the remote file - after translating the host+path to
-an scp URI. This is the default command if no C<--command> option is
-specified. If multiple filenames are supplied, the first will be opened
-in gvim and you should use C<:n> to load the 'next' file.
-END_POD
- );
-
- $class->register_command(
- name => 'viwait',
- description => <<'END_POD'
-This command works exactly the same as C<vi> above, except it waits for the
-editor process to exit before bcvi exits on the remote machine. This is
-primarily for use with C<sudoedit>. Note: when used with C<sudoedit>, the file
-will not be updated on the remote machine until you exit the editor on your
-workstation.
-END_POD
- );
-
- $class->register_command(
- name => 'scpd',
- description => <<'END_POD'
-Uses C<scp> to copy the specified files or directories to the calling user's
-F<~/Desktop>.`
-END_POD
- );
-
-
- $class->add_home_bin();
- $class->register_aliases(
- 'test -n "$(which bcvi)" && eval "$(bcvi --unpack-term)"',
- 'test -n "${BCVI_CONF}" && alias vi="bcvi"',
- 'test -n "${BCVI_CONF}" && alias suvi="EDITOR=\'bcvi -c viwait\' sudoedit"',
- 'test -n "${BCVI_CONF}" && alias bcp="bcvi -c scpd"',
- );
-
- $class->pod_class->init();
-
-}
-
-
-sub register_option {
- my $class = shift;
- my $opt = { @_ };
- my $key = $opt->{name};
-
- if(!defined $key or !length $key) {
- die "Can't register option without 'name'";
- }
-
- my($package, $filename, $line) = caller();
- $opt->{provider} = "$package at $filename line $line";
- my $taken = $options{$key};
- if($taken && !$opt->{force_override}) {
- warn "option '--$key' already registered by $taken->{provider}\n";
- }
- if($opt->{alias}) {
- foreach my $a (map { s/^-+//; $_ } split /\|/, $opt->{alias}) {
- if($option_name{$a} && !$opt->{force_override}) {
- if($taken = $options{$option_name{$a}}) {
- warn "alias '$a' already registered for option "
- . "'--$taken->{name}' by $taken->{provider}\n";
- }
- }
- $option_name{$a} = $key;
- }
- }
- $options{$key} = $opt;
-}
-
-
-sub register_command {
- my $class = shift;
- my $cmd = { @_ };
- my $key = $cmd->{name};
-
- if(!defined $key or !length $key) {
- die "Can't register command without 'name'";
- }
-
- $cmd->{dispatch_to} ||= "execute_$key";
-
- my($package, $filename, $line) = caller();
- $cmd->{provider} = "$package at $filename line $line";
- warn "option '$key' already registered by $commands{$key}->{provider}\n"
- if $commands{$key} && !$cmd->{force_override};
- $commands{$key} = $cmd;
-}
-
-
-sub each_option {
- my($class, $sub) = @_;
-
- $sub->($options{$_}) foreach sort keys %options;
-}
-
-
-sub each_command {
- my($class, $sub) = @_;
-
- $sub->($commands{$_}) foreach sort keys %commands;
-}
-
-
-sub command_handler {
- my($class, $name) = @_;
-
- return unless defined $name;
- return "execute_commands_pod" if $name eq 'commands_pod';
- my $spec = $commands{$name} or return;
- return $spec->{dispatch_to};
-}
-
-
-sub add_home_bin {
- my $class = shift;
- my $home_bin = $class->home_directory . '/bin';
- $class->register_aliases(
- qq{echo \$PATH | grep -q $home_bin || PATH="$home_bin/\$PATH"},
- );
-}
-
-
-sub register_aliases {
- my $class = shift;
- push @aliases, @_;
-}
-
-
-sub register_installable {
- my $class = shift;
- my($package, $filename, $line) = caller();
- push @installables, $filename;
-}
-
-
-sub shell_aliases {
- my($self) = @_;
-
- return
- "## START-BCVI\n"
- . join("\n", map { " $_" } @aliases)
- . "\n## END-BCVI\n";
-}
-
-
-sub load_plugins {
- my($class) = @_;
-
- my $dir = $class->conf_directory();
- foreach my $file (sort glob("$dir/*.pm")) {
- $class->load_plugin_file($file);
- }
-}
-
-
-sub load_plugin_file {
- my($class, $file) = @_;
-
- my @parts = File::Spec->splitdir($file);
- my $key = pop @parts;
- return if $plugin_loaded{$key};
-
- eval { require $file; };
- if($@) {
- die qq{Error loading plugin "$file"\n$@\n}
- }
-
- $plugin_loaded{$key} = $file;
-}
-
-
-sub hook_client_class {
- my($class) = @_;
-
- my($calling_class, $calling_file) = caller();
- my $client_class = $class->client_class();
- $class->map_class(client => $calling_class);
-
- no strict 'refs';
- unshift @{"${calling_class}::ISA"}, $client_class;
- push @plugins, { class => $calling_class, file => $calling_file };
- return 1;
-}
-
-
-sub hook_server_class {
- my($class) = @_;
-
- my($calling_class, $calling_file) = caller();
- my $server_class = $class->server_class();
- $class->map_class(server => $calling_class);
-
- no strict 'refs';
- unshift @{"${calling_class}::ISA"}, $server_class;
- push @plugins, { class => $calling_class, file => $calling_file };
- return 1;
-}
-
-
-sub process_command_line {
- my($class, @args) = @_;
-
- my $opt = $class->option_defaults();
- my @cfg = $class->getopt_config();
-
- local(@ARGV) = @args;
- Getopt::Long::GetOptions($opt, @cfg) or $class->die_synopsis();
-
- my $handler = $opt->{listener}
- ? $class->server_class
- : $class->client_class;
-
- $handler->new(_options => $opt)->dispatch(@ARGV);
-}
-
-
-sub option_defaults {
- return { };
-}
-
-
-sub getopt_config {
- my($class) = @_;
-
- my @spec;
- $class->each_option(sub {
- my($o) = @_;
- my $def = $o->{name};
- $def .= "|$o->{alias}" if defined $o->{alias};
- $def .= $o->{arg_spec} if defined $o->{arg_spec};
- push @spec, $def;
- });
- return @spec
-}
-
-
-sub die_synopsis {
- my($class, $message) = @_;
-
- warn "$message\n" if $message;
- $class->pod_class->synopsis();
- exit(1);
-}
-
-
-sub new {
- my $class = shift;
-
- return bless { @_ }, $class;
-}
-
-
-sub dispatch {
- my($self, @args) = @_;
-
- if(my $method = $self->dispatch_option) {
- $self->$method(@args);
- exit;
- }
- elsif(!$self->opt('command') and !@args) {
- $self->die_synopsis();
- }
-
- $self->send_command(@args);
-}
-
-
-sub opt {
- my($self, $key) = @_;
-
- return $self->{_options}->{$key};
-}
-
-
-sub set_opt {
- my($self, $key, $value) = @_;
-
- return $self->{_options}->{$key} = $value;
-}
-
-
-sub dispatch_option {
- my($self) = @_;
-
- my @set;
- $self->each_option(sub {
- my($o) = @_;
- push @set, $o if $o->{dispatch_to} && defined $self->opt($o->{name});
- });
- return unless @set;
- if(@set > 1) {
- @set = map { "--$_->{name}" } @set;
- my $last = pop @set;
- $self->die_synopsis(
- "Which did you want: " . join(', ', @set) . " or $last?"
- );
- }
- return $set[0]->{dispatch_to};
-}
-
-
-sub default_port {
- return( ($< * 10 + 9) % 65536 );
-}
-
-
-sub listen_address {
- return 'localhost';
-};
-
-
-sub default_command {
- return 'vi';
-}
-
-
-sub read_file {
- my($self, $path) = @_;
-
- return unless -e $path;
- return if -d $path;
- my $data = do {
- open my $fh, '<', $path or die "open($path): $!\n";
- local($/) = undef;
- <$fh>;
- };
- return $data;
-}
-
-
-sub home_directory {
- return (getpwuid($>))[7];
-}
-
-
-sub conf_directory {
- my($self) = @_;
-
- my $conf_dir = File::Spec->catdir($self->home_directory(), '.config', 'bcvi');
- File::Path::mkpath($conf_dir) unless -d $conf_dir;
- return $conf_dir;
-}
-
-
-sub auth_key_filename {
- return File::Spec->catfile(shift->conf_directory(), 'listener_key');
-}
-
-
-sub listener_port_filename {
- return File::Spec->catfile(shift->conf_directory(), 'listener_port');
-}
-
-
-sub get_listener_auth_key {
- my($self) = @_;
-
- my $auth_file = $self->auth_key_filename();
- my $auth_key = $self->read_file($auth_file)
- or die "Auth key file does not exist: $auth_file";
- chomp($auth_key);
- return $auth_key;
-}
-
-
-sub list_plugins {
- my($self) = @_;
-
- my @plugins;
- foreach my $name (sort keys %plugin_loaded) {
- my $path = $plugin_loaded{$name};
- $name =~ s{[.]pm$}{};
- if(my $title = $self->pod_class->extract_title($path)) {
- push @plugins, "$name - $title";
- }
- else {
- push @plugins, "$name - no documentation";
- }
- }
- return @plugins;
-}
-
-
-sub plugin_help {
- my($self) = @_;
-
- my $plugin = $self->opt('plugin-help');
- if(my $path = $plugin_loaded{"${plugin}.pm"}) {
- $self->pod_class->show_plugin_help($path);
- }
- else {
- die "Can't find plugin: '$plugin'\n";
- }
-}
-
-
-##############################################################################
-# The App::BCVI::Client class implements the command-line UI and the client
-# side of the BCVI protocol. You can use inheritance to customise the
-# behaviour of this class.
-##############################################################################
-
-package App::BCVI::Client;
-BEGIN {
- $App::BCVI::Client::VERSION = '3.05';
-}
-
-BEGIN { @App::BCVI::Client::ISA = qw( App::BCVI ); }
-
-
-sub get_connection_details {
- my($self) = @_;
-
- if(not $ENV{BCVI_CONF}) {
- die "The \$BCVI_CONF environment variable has not been set\n";
- }
- my($alias, $gateway, $port, $auth_key) = split(/:/, $ENV{BCVI_CONF});
- $self->{host_alias} = $alias;
- $self->{gateway_address} = $gateway;
- $self->{port} = $port;
- $self->{auth_key} = $auth_key;
-}
-
-
-sub host_alias { return shift->{host_alias}; }
-sub gateway_address { return shift->{gateway_address}; }
-sub port { return shift->{port}; }
-sub auth_key { return shift->{auth_key}; }
-sub server_version { return shift->{server_version}; }
-sub response_code { return shift->{response_code}; }
-sub response_message { return shift->{response_message}; }
-sub response { return shift->{response}; }
-
-
-sub send_command {
- my($self, @files) = @_;
-
- my $command = $self->opt('command') || $self->default_command();
-
- my $sock = $self->connect_to_listener();
-
- $sock->write(
- "Auth-Key: " . $self->auth_key . $LF .
- "Host-Alias: " . $self->host_alias . $LF .
- "Command: " . $command . $LF
- ) or die "Error sending command through backchannel: $!";
-
- $self->send_body(\@files);
- return if $self->check_response() =~ /^(?:200|300)$/;
- die $self->response_message . "\n";
-}
-
-
-sub send_body {
- my($self, $files) = @_;
-
- my $translate_paths = ! $self->opt('no-path-xlate');
-
- my $body = join '', map {
- $_ = File::Spec->rel2abs($_) if $translate_paths;
- "$_$LF";
- } @$files;
-
- $self->sock->write(
- 'Content-Length: ' . length($body) . $LF .
- $LF .
- $body
- ) or die "Error sending command through backchannel: $!";
-}
-
-
-sub check_response {
- my($self) = @_;
-
- my $response = $self->sock->getline() or die "Server hung up\n";
- if(my($code, $message) = $response =~ m{^(\d\d\d) (.*)$}) {
- ($self->{response_code}, $self->{response_message}) = ($code, $message);
- $self->read_response() if $code eq '300';
- return $code;
- }
- die "Unexpected response: '$response'\n";
-}
-
-
-sub read_response {
- my($self) = @_;
-
- my $sock = $self->sock();
- my $resp = {};
- while(my($line) = $sock->getline() || '') {
- chomp($line);
- last if $line eq '';
- $line = Encode::decode('utf8', $line);
- if(my($name, $value) = $line =~ m{^(\S+)\s*:\s*(.*)$}) {
- $name =~ s/-/_/;
- $resp->{lc($name)} = $value;
- }
- }
- $self->{response} = $resp;
-
- my $bytes = $resp->{content_length} || return;;
-
- my $buf = '';
- while(my $count = $sock->read($buf, $bytes, length($buf))) {
- $bytes -= $count;
- last if $bytes < 1;
- }
- $resp->{body} = $buf;
-}
-
-
-sub connect_to_listener {
- my($self) = @_;
-
- $self->get_connection_details();
-
- my $peer = $self->gateway_address . ':' . $self->port;
- my $sock = IO::Socket::INET->new(
- PeerAddr => $peer,
- ) or die "Can't connect to '$peer': $!\n";
-
- binmode($sock);
- my $welcome = $sock->getline() or die "No listener?\n";
- if($welcome =~ /^100 Ready \(([^)]+)\)/) {
- $self->{server_version} = $1;
- }
- $self->{sock} = $sock;
-}
-
-
-sub show_versions {
- my($self) = @_;
-
- print "bcvi client: $App::BCVI::VERSION\n";
-
- if($ENV{BCVI_CONF}) {
- $self->connect_to_listener();
- print "bcvi server: $App::BCVI::VERSION\n";
- }
-}
-
-
-sub show_help {
- my($self) = @_;
-
- $self->pod_class->full_pod($self);
-}
-
-
-sub commands_pod {
- my($self) = @_;
-
- eval {
- $self->set_opt(command => 'commands_pod');
- $self->send_command();
- };
- if($@) {
- $@ = '';
- return;
- }
- return $self->response->{body};
-}
-
-
-sub wrap_ssh {
- my($self, @args_in) = @_;
-
- if(my($target, @args_out) = $self->parse_ssh_args(@args_in)) {
- $self->execute_wrapped_ssh($target, @args_out);
- }
- else {
- warn "bcvi: unable to extract hostname from ssh command line\n";
- $self->execute_ssh(@args_in);
- }
-}
-
-
-sub parse_ssh_args {
- my($self, @args_in) = @_;
-
- my %need_arg = map { $_ => 1} split //, 'bcDeFiLlmOopRS';
-
- my(@args_out, @hosts, $user);
- while(@args_in) {
- $_ = shift @args_in;
- if(/^-l(.*)$/) { # extract username if specified with -l
- $user = $1 ? $1 : $args_in[0];
- }
- if(/^-(.)(.*)$/) {
- push @args_out, $_;
- push @args_out, shift @args_in
- if $need_arg{$1} && !length($2) && @args_in;
- }
- else {
- push @args_out, $_;
- push @hosts, $_;
- }
- }
- return unless @hosts == 1;
- my($target) = @hosts;
- if($user and $target !~ /@/) {
- $target = $user . '@' . $target;
- }
- return($target, @args_out);
-}
-
-
-sub execute_wrapped_ssh {
- my($self, $target, @args) = @_;
-
- my $remote_port = $self->opt('port') || $self->default_port();
- my $local_port = $self->listener_port();
- $ENV{TERM} = "$ENV{TERM}\n"
- . "BCVI_CONF=${target}:localhost:$remote_port:"
- . $self->get_listener_auth_key();
- unshift @args, "-R $remote_port:localhost:$local_port";
- $self->execute_ssh(@args);
-}
-
-
-sub execute_ssh {
- my($self, @args) = @_;
-
- system 'ssh', @args;
-}
-
-
-sub listener_port {
- my($self) = @_;
-
- my $port = $self->read_file($self->listener_port_filename())
- or return $self->default_port();
- chomp($port);
- return $port;
-}
-
-
-sub unpack_term {
- my($self) = @_;
-
- my @parts = split /\x0D?\x0A/, $ENV{TERM} || '';
- return unless @parts > 1;
- print "TERM=$parts[0]\n";
- shift @parts;
- foreach (@parts) {
- print if s{^(\w+)=(.*)$}{export $1="$2"\n};
- }
-}
-
-
-sub install_to_hosts {
- my($self, @args) = @_;
-
- die "You must list one or more target hostnames\n" unless @args;
-
- $self->install_to_host($_) foreach @args;
-}
-
-
-sub install_to_host {
- my($self, $host) = @_;
-
- $self->install_bin_directory($host);
- $self->install_bcvi_script($host);
- $self->install_plugins($host);
- $self->install_remote_aliases($host);
-}
-
-
-sub install_bin_directory {
- my($self, $host) = @_;
-
- if(system("ssh $host test -d ./bin") != 0) {
- print "Creating ~/bin directory on $host\n";
- system("ssh $host mkdir ./bin") == 0
- or die "** mkdir failed on $host";
- }
-}
-
-
-sub install_bcvi_script {
- my($self, $host) = @_;
-
- print "Copying bcvi to remote bin directory on $host\n";
- my $output = `scp $0 $host:bin/bcvi 2>&1`;
- if($? != 0) {
- die "** failed to copy bcvi to remote bin directory on $host\n"
- . $output;
- }
-}
-
-
-sub install_plugins {
- my($self, $host) = @_;
-
- return unless @installables;
- if(system("ssh $host test -d ./.config/bcvi") != 0) {
- print "Creating plugins directory on $host\n";
- system("ssh $host mkdir -p ./.config/bcvi") == 0
- or die "** mkdir failed on $host";
- }
- print "Copying plugin files to $host\n";
- my $output = `scp @installables $host:.config/bcvi 2>&1`;
- if($? != 0) {
- die "** failed to copy bcvi to remote plugins directory on $host\n"
- . $output;
- }
-}
-
-
-sub install_remote_aliases {
- my($self, $host) = @_;
-
- system("ssh $host bin/bcvi --add-aliases") == 0
- or die "** failed to install aliases on $host";
-}
-
-
-sub add_aliases {
- my($self) = @_;
-
- my $bcvi_commands = $self->shell_aliases();
-
- $self->update_existing_aliases($bcvi_commands)
- or $self->aliases_initial_install($bcvi_commands);
-}
-
-
-sub update_existing_aliases {
- my($self, $bcvi_commands) = @_;
-
- foreach my $file ( $self->candidate_rc_files() ) {
- my($script) = $self->read_file($file) or next;
- if(index($script, $bcvi_commands) > -1) {
- print "Found bcvi commands in $file\n";
- return 1;
- }
- if($script =~ s{^## START-BCVI.*^## END-BCVI\r?\n}{$bcvi_commands}sm) {
- open my $fh, '>', $file or die "open($file): $!";
- print $fh $script;
- close($fh);
- print "Updated bcvi commands in $file\n";
- return 1;
- }
- if($script =~ m{^[^#]*\bbcvi\b}m) {
- print "Adhoc bcvi commands found in $file\n"
- . "*** Manual update may be required. ***\n"
- . "*** Consider deleting commands and re-adding. ***\n";
- return 1;
- }
- }
- return; # No existing aliases found
-}
-
-
-sub aliases_initial_install {
- my($self, $bcvi_commands) = @_;
-
- my $target = $self->preferred_rc_file();
-
- open my $fh, '>>', $target or die "open(>>$target): $!";
- print $fh "\n$bcvi_commands\n";
- close($fh);
- print "Added bcvi commands to $target\n";
-}
-
-
-sub candidate_rc_files {
- my($self) = @_;
- my $home = $self->home_directory();
- return(
- "$home/.bashrc_local",
- "$home/.bashrc",
- "$home/.bash_profile_local",
- "$home/.bash_profile",
- "$home/.profile",
- "$home/.common-configs/bashrc",
- );
-}
-
-
-sub preferred_rc_file {
- my($self) = @_;
-
- # Add to .bashrc_local if it is referenced from .bashrc
-
- my $home = $self->home_directory();
- my $bashrc = "$home/.bashrc";
- my $bashrc_local = "$home/.bashrc_local";
-
- my $script = $self->read_file($bashrc) || '';
-
- return $script =~ m{/[.]bashrc_local\b}
- ? $bashrc_local
- : $bashrc;
-}
-
-
-##############################################################################
-# The App::BCVI::Server class implements the server ('listener') side of the
-# BCVI protocol. You can use inheritance to customise the behaviour of this
-# class.
-##############################################################################
-
-package App::BCVI::Server;
-BEGIN {
- $App::BCVI::Server::VERSION = '3.05';
-}
-
-BEGIN { @App::BCVI::Server::ISA = qw( App::BCVI ); }
-
-use Digest::MD5 qw(md5_hex);
-use Errno qw();
-
-
-sub start_listener {
- my($self) = @_;
-
- $self->kill_current_listener();
- $self->save_pid();
- $self->generate_auth_key();
- $self->create_listener_socket();
- $self->accept_loop();
- die "bcvi listener accept loop terminated unexpectedly\n";
-}
-
-
-sub auth_key { shift->{auth_key}; }
-sub client_sock { shift->{client}; }
-sub request { shift->{request}; }
-sub calling_host { shift->{request}->{host_alias}; }
-
-
-sub kill_current_listener {
- my($self) = @_;
-
- my($pid) = $self->read_file($self->pid_file) or return;
- foreach my $i (1..5) {
- if(kill 0, $pid) {
- kill($i > 2 ? 9 : 1, $pid);
- }
- elsif($!{ESRCH}) { # no such process
- return;
- }
- elsif($!{EPERM}) { # pid file was probably stale
- return;
- }
- sleep 1;
- }
-}
-
-
-sub save_pid {
- my($self) = @_;
-
- my $pid_file = $self->pid_file;
- open my $fh, '>', $pid_file or die "open(>$pid_file): $!";
- print $fh "$$\n";
-}
-
-
-sub save_port {
- my($self, $port) = @_;
-
- my $port_file = $self->listener_port_filename;
- open my $fh, '>', $port_file or die "open(>$port_file): $!";
- print $fh "$port\n";
-}
-
-
-sub pid_file {
- return File::Spec->catfile(shift->conf_directory(), 'listener_pid');
-}
-
-
-sub generate_auth_key {
- my($self) = @_;
-
- if($self->opt('reuse-auth')) {
- $self->{auth_key} = $self->get_listener_auth_key();
- return;
- }
-
- my $data = "$self" . $$ . time() . rand();
- $self->{auth_key} = md5_hex($data);
-
- my $auth_file = $self->auth_key_filename();
- open my $fh, '>', $auth_file or die "open(>$auth_file): $!";
- print $fh $self->{auth_key}, "\n";
-}
-
-
-sub create_listener_socket {
- my($self) = @_;
-
- my $port = $self->opt('port') || $self->default_port();
- $self->save_port($port);
- my $local_addr = $self->listen_address . ':' . $port;
- $self->{sock} = IO::Socket::INET->new(
- LocalAddr => $local_addr,
- ReuseAddr => 1,
- Proto => 'tcp',
- Listen => 5,
- Blocking => 1,
- ) or die "Error creating listener for port '$local_addr': $!";
-}
-
-
-sub accept_loop {
- my($self) = @_;
-
- $SIG{CHLD} = 'IGNORE'; # let Perl reap the zombies
-
- my $sock = $self->sock();
- while(1) {
- my $new = $sock->accept();
- next if $!{EINTR};
- if(fork()) { # In parent
- close $new;
- }
- else { # In child
- close $sock;
- $self->{sock} = $new;
- $self->dispatch_request();
- exit(0);
- }
- }
-}
-
-
-sub dispatch_request {
- my($self) = @_;
-
- $self->send_response(100);
- my $req = $self->collect_headers();
- $self->validate_auth_key($req->{auth_key})
- or $self->exit_response(900);
- my $method = $self->command_handler($req->{command})
- or $self->exit_response(910);
- $self->$method();
- $self->send_response(200);
-}
-
-
-sub validate_auth_key {
- my($self, $key) = @_;
-
- return 1 if $key && $key eq $self->auth_key;
- my $alias = $self->calling_host();
- warn "Invalid Auth-Key in request from $alias\n" if -t 2;
- return;
-}
-
-
-sub send_response {
- my($self, $code) = @_;
-
- my $message = $self->message_from_code($code) || 'Invalid response code';
- $message = Encode::encode('utf8', $message);
- $self->sock->write(qq{$code $message\x0A});
-}
-
-
-sub exit_response {
- my($self, $code) = @_;
-
- $self->send_response($code);
- exit(0);
-}
-
-
-sub collect_headers {
- my($self) = @_;
-
- my $sock = $self->sock();
- my $req = {};
- while(my($line) = $sock->getline() || '') {
- chomp($line);
- last if $line eq '';
- $line = Encode::decode('utf8', $line);
- if(my($name, $value) = $line =~ m{^(\S+)\s*:\s*(.*)$}) {
- $name =~ s/-/_/;
- $req->{lc($name)} = $value;
- }
- }
- $self->{request} = $req;
-}
-
-
-sub read_request_body {
- my($self) = @_;
-
- my $bytes = $self->request->{content_length};
- my $sock = $self->sock();
- my $buf = '';
- while(my $count = $sock->read($buf, $bytes, length($buf))) {
- $bytes -= $count;
- last if $bytes < 1;
- }
- return $buf;
-}
-
-
-sub get_filenames {
- my($self) = @_;
-
- return split /\x0a/, Encode::decode('utf8', $self->read_request_body());
-}
-
-
-sub execute_commands_pod {
- my($self) = @_;
-
- $self->send_response(300);
- my $pod = $self->pod_class->command_detail();
- $pod = Encode::encode('utf8', $pod);
- $self->sock->write(
- 'Content-Type: text/pod' . $LF .
- 'Content-Length: ' . length($pod) . $LF .
- $LF .
- $pod
- ) or die "Error sending response body: $!";
-}
-
-
-sub execute_vi {
- my($self) = @_;
-
- my $alias = $self->calling_host();
- my @files = map { "scp://$alias/$_" } $self->get_filenames();
- system('mvim', '--', @files);
-}
-
-
-sub execute_viwait {
- my($self) = @_;
-
- my $alias = $self->calling_host();
- my @files = map { "scp://$alias/$_" } $self->get_filenames();
- system('mvim', '-f', '--', @files);
-}
-
-
-sub execute_scpd {
- my($self) = @_;
-
- my $dest = File::Spec->catdir($self->home_directory(), 'Desktop');
-
- my $alias = $self->calling_host();
- my @files = map { "$alias:$_" } $self->get_filenames();
-
- system('scp', '-q', '-r', '--', @files, $dest);
-}
-
-
-##############################################################################
-# The App::BCVI::POD class implements POD extraction and formatting on
-# platforms where POD::Text is available.
-##############################################################################
-
-package App::BCVI::POD;
-BEGIN {
- $App::BCVI::POD::VERSION = '3.05';
-}
-
-use Pod::Text;
-
-my $pod_skeleton;
-
-
-sub init {
- my($class) = @_;
-
- $pod_skeleton = do {
- local($/) = undef;
- <DATA>;
- };
- close(DATA);
-}
-
-
-sub full_pod {
- my($class, $app) = @_;
-
- my $commands_pod;
- if($app && $app->can('commands_pod')) {
- $commands_pod = $app->commands_pod();
- }
- $commands_pod ||= $class->command_detail();
- my $plugins_pod = $class->plugins_pod($app);
-
- my $pager = $class->pager();
- my $pod = $pod_skeleton;
- $pod =~ s{^=for BCVI_OPTIONS_SUMMARY\s*\n}{ $class->option_summary()}me;
- $pod =~ s{^=for BCVI_OPTIONS\s*\n}{ $class->option_detail() }me;
- $pod =~ s{^=for BCVI_COMMANDS\s*\n}{ $commands_pod }me;
- $pod =~ s{^=for BCVI_PLUGINS\s*\n}{ $plugins_pod }me;
- if(Pod::Text->isa('Pod::Simple')) {
- my $parser = Pod::Text->new (sentence => 1, width => 78);
- $parser->output_fh($pager);
- $parser->parse_string_document($pod);
- }
- else {
- open my $pod_fh, '<', \$pod or die "open(\$pod): $!";
- my $parser = Pod::Text->new (sentence => 1, width => 78);
- $parser->parse_from_filehandle($pod_fh, $pager);
- }
-}
-
-
-sub synopsis {
- my($class) = @_;
-
- my $pod = $pod_skeleton;
- $pod =~ s{\A.*?^=head1 SYNOPSIS\s*?\n}{Usage:}ms;
- $pod =~ s{^=.*\z}{}ms;
- $pod .= $class->option_summary();
-
- print $pod;
-}
-
-
-sub option_summary {
- my($class) = @_;
-
- my $w = 12;
- my @lines;
- App::BCVI->base_class->each_option(sub {
- my($o) = @_;
- my $short = "--$o->{name}";
- $short .= "|-$o->{alias}" if $o->{alias};
- $short .= " $o->{arg_name}" if $o->{arg_name};
- push @lines, [ $short, $o->{summary} ];
- $w = length($short) if length($short) > $w;
- });
-
- return join('', map { sprintf(" %-*s %s\n", $w, @$_) } @lines) . "\n";
-}
-
-
-sub option_detail {
- my($class) = @_;
-
- my @lines = "=over 4\n";
- App::BCVI->base_class->each_option(sub {
- my($o) = @_;
- my $pod = "\n=item B<--$o->{name}>";
- $pod .= " (alias: -$o->{alias})" if $o->{alias};
- $pod .= " $o->{arg_name}" if $o->{arg_name};
- $pod .= "\n\n$o->{description}\n";
- push @lines, $pod;
- });
- push @lines, "\n=back\n\n";
-
- return join '', @lines;
-}
-
-
-sub command_detail {
- my($class) = @_;
-
- my @lines = "=over 4\n";
- App::BCVI->base_class->each_command(sub {
- my($c) = @_;
- my $pod = "\n=item B<$c->{name}>";
- $pod .= "\n\n$c->{description}\n";
- push @lines, $pod;
- });
- push @lines, "\n=back\n\n";
-
- return join '', @lines;
-}
-
-
-sub plugins_pod {
- my($class, $app) = @_;
-
- if(my @plugin_list = $app->list_plugins()) {
- my $s = @plugin_list == 1 ? '' : 's';
- return join("\n\n",
- "You have the following plugin$s installed:",
- @plugin_list,
- "Use C<< bcvi --plugin-help plugin-name >> for detailed info.",
- ) . "\n\n";
- }
-
- return "You have no plugins installed.\n\n";
-}
-
-
-sub extract_title {
- my($class, $path) = @_;
-
- open my $fh, '<', $path or return;
- my $name_section = 0;
- while(<$fh>) {
- chomp;
- if(/^=head1\s+NAME$/) {
- $name_section++;
- }
- elsif($name_section and /\S/) {
- s{^.+?\s-\s}{};
- return $_;
- }
- }
- return;
-}
-
-
-sub show_plugin_help {
- my($class, $path) = @_;
-
- my $pager = $class->pager();
- if(Pod::Text->isa('Pod::Simple')) {
- my $parser = Pod::Text->new (sentence => 1, width => 78);
- $parser->output_fh($pager);
- $parser->parse_file($path);
- }
- else {
- open my $pod_fh, '<', $path or die "open($path): $!";
- my $parser = Pod::Text->new (sentence => 1, width => 78);
- $parser->parse_from_filehandle($pod_fh, $pager);
- }
-}
-
-
-sub pager {
- my @commands = $ENV{PAGER} ? ( $ENV{PAGER} ) : qw(pager less more);
- foreach my $file (@commands) {
- foreach my $dir ( File::Spec->path() ) {
- my $exe_path = File::Spec->catfile($dir, $file);
- if(-x $exe_path) {
- open my $fh, '|-', $exe_path or next;
- return $fh;
- }
- }
- }
- return \*STDOUT;
-}
-
-
-1;
-
-__DATA__
-
-=head1 NAME
-
-bcvi - Back-channel vi, a shell utility to proxy commands back over ssh
-
-=head1 SYNOPSIS
-
- bcvi [options] [<files>]
-
- Options:
-
-=for BCVI_OPTIONS_SUMMARY
-
-=head1 DESCRIPTION
-
-This utility works with SSH to allow commands issued on the SSH server host to
-be 'proxied' back to the SSH client host. For example:
-
-=over 4
-
-=item *
-
-user F<sally> establishes an SSH connection from her workstation to a server
-named F<pluto> and runs the command C<bcvi .bashrc>
-
-=item *
-
-bcvi tunnels the details back to sally's workstation which then invokes the
-command C<gvim scp://pluto//home/sally/.bashrc>
-
-=item *
-
-the result is that sally gets a responsive GUI editor running on her local
-machine, but editing a file on the remote machine
-
-=back
-
-See C<< perldoc App::BCVI >> for more examples and background information.
-
-=head1 OPTIONS
-
-=for BCVI_OPTIONS
-
-=head1 COMMANDS
-
-The following commands can be passed back to the listener process.
-
-=for BCVI_COMMANDS
-
-=head1 USING BCVI
-
-You'll need to start a listener process on your workstation (perhaps from
-your window manager session startup).
-
- bcvi -l &
-
-To install the bcvi client to a remote machine:
-
- bcvi --install <hostname>
-
-To ssh to a server with tunnelling enabled:
-
- bcvi --wrap-ssh -- hostname
-
-To enable bcvi on all ssh connections:
-
- alias ssh="bcvi --wrap-ssh --"
-
-On a target server, you'll need to unpack the overloaded TERM variable:
-
- test -n "$(which bcvi)" && eval "$(bcvi --unpack-term)"
-
-To use vi over the back-channel:
-
- bcvi filename
-
-The installation to a remote server should set up aliases, e.g.:
-
- test -n "${BCVI_CONF}" && alias vi="bcvi"
- test -n "${BCVI_CONF}" && alias bcp="bcvi -c scpd"
-
-=head1 PLUGINS
-
-=for BCVI_PLUGINS
-
-=head1 COPYRIGHT
-
-Copyright 2007-2010 Grant McLean E<lt>grantm@cpan.orgE<gt>
-
-This library is free software; you can redistribute it and/or modify it
-under the same terms as Perl itself.
-
-=cut
-
-
View
54 bin/addcontact
@@ -1,54 +0,0 @@
-#!/bin/bash
-osascript -e "tell application \"Address Book\"" \
--e " set firstParam to \"$1\"" \
--e " set secondParam to \"$2\"" \
--e " set thirdParam to \"$3\"" \
--e " set fourthParam to \"$4\"" \
--e " set contactEmailLabel to \"\"" \
--e " set spaceOffset to (offset of \" \" in firstParam)" \
--e " if (spaceOffset is not equal to 0) then" \
--e " set AppleScript's text item delimiters to \" \"" \
--e " set firstName to (text item 1 of firstParam)" \
--e " set lastName to (text item 2 of firstParam)" \
--e " set firstEmailParam to secondParam" \
--e " set secondEmailParam to thirdParam" \
--e " else" \
--e " set firstName to firstParam" \
--e " set lastName to secondParam" \
--e " set firstEmailParam to thirdParam" \
--e " set secondEmailParam to fourthParam" \
--e " end if" \
--e " set atOffset to (offset of \"@\" in firstEmailParam)" \
--e " if (atOffset is not equal to 0) then" \
--e " set contactEmail to firstEmailParam" \
--e " else" \
--e " set contactEmailLabel to firstEmailParam" \
--e " set contactEmail to secondEmailParam" \
--e " end if" \
--e " set bracketOffset to (offset of \"<\" in contactEmail)" \
--e " if (bracketOffset is not equal to 0) then" \
--e " set contactEmail to text 2 thru -2 of contactEmail" \
--e " end if" \
--e " if (contactEmailLabel is equal to \"\") then" \
--e " set contactEmailLabel to \"Home\"" \
--e " end if" \
--e " set newPerson to (make new person with properties {first name:firstName, last name:lastName})" \
--e " make new email at end of emails of newPerson with properties {label:contactEmailLabel, value:contactEmail}" \
--e " save" \
--e " if (newPerson exists) then" \
--e " if (firstName exists) then" \
--e " set returnString to (\"First name: \" & firstName)" \
--e " end if" \
--e " if (lastName exists) then" \
--e " set returnString to (returnString & \"; Last name: \" & lastName)" \
--e " end if" \
--e " if (contactEmailLabel exists) then" \
--e " set returnString to (returnString & \"; Email label: \" & contactEmailLabel)" \
--e " end if" \
--e " if (contactEmail exists) then" \
--e " set returnString to (returnString & \"; Email address: \" & contactEmail)" \
--e " end if" \
--e " return returnString" \
--e " end if" \
--e "end tell"
-
View
51 bin/bootstrap.sh
@@ -1,51 +0,0 @@
-#!/bin/bash
-# THIS IS A WORK IN PROGRESS
-# BE CAREFUL, DAMMIT
-
-set -e
-
-echo "prerequisites: python git pip dulwich tmux weechat offlineimap mutt hg ack zsh vim"
-
-function ensure_link {
- test -L "$HOME/$2" || ln -s "$HOME/$1" "$HOME/$2"
-}
-
-mkdir -p ~/.config/fish
-mkdir -p ~/lib/hg
-mkdir -p ~/lib/virtualenvs
-mkdir -p ~/bin
-mkdir -p ~/src
-
-ensure_link "lib/dotfiles/hgrc" ".hgrc"
-
-test -d ~/.hg-git/ || hg clone "bb://durin42/hg-git/" "$HOME/.hg-git"
-test -d ~/lib/dulwich || git clone "git://github.com/jelmer/dulwich.git" "$HOME/lib/dulwich"
-
-ensure_link "lib/dulwich/dulwich" "lib/hg/hg/dulwich"
-
-test -d ~/lib/dotfiles || hg clone http://bitbucket.org/sjl/dotfiles ~/lib/dotfiles
-
-ensure_link "lib/dotfiles/slate" ".slate"
-ensure_link "lib/dotfiles/tmux/tmux.conf" ".tmux.conf"
-ensure_link "lib/dotfiles/vim" ".vim"
-ensure_link "lib/dotfiles/vim/vimrc" ".vimrc"
-ensure_link "lib/dotfiles/gitconfig" ".gitconfig"
-ensure_link "lib/dotfiles/ackrc" ".ackrc"
-ensure_link "lib/dotfiles/weechat" ".weechat"
-ensure_link "lib/dotfiles/urlview" ".urlview"
-ensure_link "lib/dotfiles/pentadactylrc" ".pentadactylrc"
-ensure_link "lib/dotfiles/offlineimaprc" ".offlineimaprc"
-ensure_link "lib/dotfiles/mutt" ".mutt"
-ensure_link "lib/dotfiles/dotjs" ".js"
-ensure_link "lib/dotfiles/dotcss" ".css"
-ensure_link "lib/dotfiles/hgignore" ".hgignore"
-ensure_link "lib/dotfiles/gitignore" ".gitignore"
-ensure_link "lib/dotfiles/ffignore" ".ffignore"
-ensure_link "lib/dotfiles/ctags" ".ctags"
-ensure_link "lib/dotfiles/grc" ".grc"
-ensure_link "lib/dotfiles/mutt/notmuch-config" ".notmuch-config"
-ensure_link "lib/dotfiles/bash_profile" ".bash_profile"
-ensure_link "lib/dotfiles/inputrc" ".inputrc"
-ensure_link "lib/dotfiles/fish/config.fish" ".config/fish/config.fish"
-
-echo completed
View
28 bin/clean_mail
@@ -1,28 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-
-
-def next_line():
- l = sys.stdin.readline()
- if not l:
- sys.exit(0)
- return l
-
-# Skip headers
-l = next_line()
-while l.strip():
- sys.stdout.write(l)
- l = next_line()
-
-# One blank line in between headers and the start of the message
-while not l.strip():
- l = next_line()
-
-sys.stdout.write('\n')
-sys.stdout.write(l)
-
-# Dump the rest straight through
-for l in sys.stdin.readlines():
- sys.stdout.write(l)
-
View
365 bin/colortest
@@ -1,365 +0,0 @@
-#!/usr/bin/perl
-
-# by entheon, do whatever the hell you want with this file
-
-print "\n";
-print "**************************\n";
-print "*XTERM 256Color Test Chart\n";
-print "**************************\n";
-print "* 16 = black\n";
-print "* 255 = white\n";
-print "*\n";
-print "* Usage:\n";
-print "* colortest -w\n";
-print "* wide display\n";
-print "*\n";
-print "* colortest -w -r\n";
-print "* wide display reversed\n";
-print "*\n";
-print "* colortest -w -s\n";
-print "* extra spaces padding\n";
-print "*\n";
-print "* colortest -w -r -s\n";
-print "* available combination\n";
-print "*\n";
-print "**************************\n";
-
-if( $ARGV[0] eq "-w" || $ARGV[1] eq "-w" || $ARGV[2] eq "-w" ) {
- push(@arr, [( " 16: 00/00/00", " 17: 00/00/5f", " 18: 00/00/87", " 19: 00/00/af", " 20: 00/00/d7", " 21: 00/00/ff")] );
- push(@arr, [( " 22: 00/5f/00", " 23: 00/5f/5f", " 24: 00/5f/87", " 25: 00/5f/af", " 26: 00/5f/d7", " 27: 00/5f/ff")] );
- push(@arr, [( " 28: 00/87/00", " 29: 00/87/5f", " 30: 00/87/87", " 31: 00/87/af", " 32: 00/87/d7", " 33: 00/87/ff")] );
- push(@arr, [( " 34: 00/af/00", " 35: 00/af/5f", " 36: 00/af/87", " 37: 00/af/af", " 38: 00/af/d7", " 39: 00/af/ff")] );
- push(@arr, [( " 40: 00/d7/00", " 41: 00/d7/5f", " 42: 00/d7/87", " 43: 00/d7/af", " 44: 00/d7/d7", " 45: 00/d7/ff")] );
- push(@arr, [( " 46: 00/ff/00", " 47: 00/ff/5f", " 48: 00/ff/87", " 49: 00/ff/af", " 50: 00/ff/d7", " 51: 00/ff/ff")] );
- push(@arr, [( " 52: 5f/00/00", " 53: 5f/00/5f", " 54: 5f/00/87", " 55: 5f/00/af", " 56: 5f/00/d7", " 57: 5f/00/ff")] );
- push(@arr, [( " 58: 5f/5f/00", " 59: 5f/5f/5f", " 60: 5f/5f/87", " 61: 5f/5f/af", " 62: 5f/5f/d7", " 63: 5f/5f/ff")] );
- push(@arr, [( " 64: 5f/87/00", " 65: 5f/87/5f", " 66: 5f/87/87", " 67: 5f/87/af", " 68: 5f/87/d7", " 69: 5f/87/ff")] );
- push(@arr, [( " 70: 5f/af/00", " 71: 5f/af/5f", " 72: 5f/af/87", " 73: 5f/af/af", " 74: 5f/af/d7", " 75: 5f/af/ff")] );
- push(@arr, [( " 76: 5f/d7/00", " 77: 5f/d7/5f", " 78: 5f/d7/87", " 79: 5f/d7/af", " 80: 5f/d7/d7", " 81: 5f/d7/ff")] );
- push(@arr, [( " 82: 5f/ff/00", " 83: 5f/ff/5f", " 84: 5f/ff/87", " 85: 5f/ff/af", " 86: 5f/ff/d7", " 87: 5f/ff/ff")] );
- push(@arr, [( " 88: 87/00/00", " 89: 87/00/5f", " 90: 87/00/87", " 91: 87/00/af", " 92: 87/00/d7", " 93: 87/00/ff")] );
- push(@arr, [( " 94: 87/5f/00", " 95: 87/5f/5f", " 96: 87/5f/87", " 97: 87/5f/af", " 98: 87/5f/d7", " 99: 87/5f/ff")] );
- push(@arr, [( " 100: 87/87/00"