assorted-commits Mailing List for Assorted projects (Page 7)
Brought to you by:
yangzhang
You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(9) |
Dec
(12) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(86) |
Feb
(265) |
Mar
(96) |
Apr
(47) |
May
(136) |
Jun
(28) |
Jul
(57) |
Aug
(42) |
Sep
(20) |
Oct
(67) |
Nov
(37) |
Dec
(34) |
2009 |
Jan
(39) |
Feb
(85) |
Mar
(96) |
Apr
(24) |
May
(82) |
Jun
(13) |
Jul
(10) |
Aug
(8) |
Sep
(2) |
Oct
(20) |
Nov
(31) |
Dec
(17) |
2010 |
Jan
(16) |
Feb
(11) |
Mar
(17) |
Apr
(53) |
May
(31) |
Jun
(13) |
Jul
(3) |
Aug
(6) |
Sep
(11) |
Oct
(4) |
Nov
(17) |
Dec
(17) |
2011 |
Jan
(3) |
Feb
(19) |
Mar
(5) |
Apr
(17) |
May
(3) |
Jun
(4) |
Jul
(14) |
Aug
(3) |
Sep
(2) |
Oct
(1) |
Nov
(3) |
Dec
(2) |
2012 |
Jan
(3) |
Feb
(7) |
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
(4) |
Aug
(5) |
Sep
(2) |
Oct
(3) |
Nov
|
Dec
|
2013 |
Jan
|
Feb
|
Mar
(9) |
Apr
(5) |
May
|
Jun
(2) |
Jul
(1) |
Aug
(10) |
Sep
(1) |
Oct
(2) |
Nov
|
Dec
|
2014 |
Jan
(1) |
Feb
(3) |
Mar
(3) |
Apr
(1) |
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2016 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2017 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(5) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(2) |
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <yan...@us...> - 2011-02-18 22:40:46
|
Revision: 1752 http://assorted.svn.sourceforge.net/assorted/?rev=1752&view=rev Author: yangzhang Date: 2011-02-18 22:40:40 +0000 (Fri, 18 Feb 2011) Log Message: ----------- Add numpy demo Added Paths: ----------- sandbox/trunk/src/py/numpydemo.py Added: sandbox/trunk/src/py/numpydemo.py =================================================================== --- sandbox/trunk/src/py/numpydemo.py (rev 0) +++ sandbox/trunk/src/py/numpydemo.py 2011-02-18 22:40:40 UTC (rev 1752) @@ -0,0 +1,16 @@ +from __future__ import division +#import random +#successes, trials = 0, 999 +#for t in xrange(trials): +# days = 365*[False] +# for p in xrange(2000): +# days[random.randrange(365)] = True +# if all(days): successes += 1 +#print successes / trials +from numpy import * +A = matrix(diag([i/365 for i in xrange(1,366)])) +# Other ways to do this: +# print A + concatenate((transpose(matrix(zeros(len(A)))), diag(1-diag(A))[:,:-1]), -1) +# A.ravel()[1::A.shape[1]] = 1 - A.ravel()[:-1:A.shape[1]] +for i in xrange(364): A[i,i+1] = 1 - A[i,i] +print A**1000 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2011-02-18 22:40:12
|
Revision: 1751 http://assorted.svn.sourceforge.net/assorted/?rev=1751&view=rev Author: yangzhang Date: 2011-02-18 22:40:06 +0000 (Fri, 18 Feb 2011) Log Message: ----------- Add demo of mysterious Python subprocess delay Added Paths: ----------- sandbox/trunk/src/py/stuckproc.py Added: sandbox/trunk/src/py/stuckproc.py =================================================================== --- sandbox/trunk/src/py/stuckproc.py (rev 0) +++ sandbox/trunk/src/py/stuckproc.py 2011-02-18 22:40:06 UTC (rev 1751) @@ -0,0 +1,39 @@ +# Unexpected waiting Python subprocesses +# I reduced a problem I was seeing in my application down into the following test case. In this code, a parent process concurrently spawns 2 (you can spawn more) subprocesses that read a big message from the parent over stdin, sleep for 5 seconds, and write something back. However, there's unexpected waiting happening somewhere, causing the code to complete in 10 seconds instead of the expected 5. If you set verbose=True, you can see that the straggling subprocess is receiving most of the messages, then waiting for the last chunk of 3 chars---it's not detecting that the pipe has been closed. Furthermore, if I simply don't do anything with the second process, the first process will *never* see the EOF. Any ideas what's happening? +# Posted to mailing list, stackoverflow, bugs.python.org +from subprocess import * +from threading import * +from time import * +import sys +msg = (40*4096+3)*'a' +verbose = False +def elapsed(): return '%7.3f' % (time() - start) +if sys.argv[1:]: + start = float(sys.argv[2]) + if verbose: + for chunk in iter(lambda: sys.stdin.read(4096), ''): + print >> sys.stderr, '..', time(), sys.argv[1], 'read', len(chunk) + else: + sys.stdin.read() + print >> sys.stderr, elapsed(), '..', sys.argv[1], 'done reading' + sleep(5) +else: + start = time() + def go(i): + print elapsed(), i, 'starting' + p = Popen(['python','stuckproc.py',str(i), str(start)], stdin=PIPE, stdout=PIPE) + if False: + print elapsed(), i, 'communicating' + p.communicate(msg) + else: + print elapsed(), i, 'writing' + p.stdin.write(msg) + print elapsed(), i, 'closing' + p.stdin.close() + print elapsed(), i, 'waiting' + p.wait() + print elapsed(), i, 'done' + ts = [Thread(target=go, args=(i,)) for i in xrange(2)] + for t in ts: t.start() + for t in ts: t.join() +# vim: et sw=2 ts=2 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2011-02-18 22:39:23
|
Revision: 1750 http://assorted.svn.sourceforge.net/assorted/?rev=1750&view=rev Author: yangzhang Date: 2011-02-18 22:39:17 +0000 (Fri, 18 Feb 2011) Log Message: ----------- Add tutorial chrome extension to sandbox Added Paths: ----------- sandbox/trunk/src/misc/chrome-ext/icon.png sandbox/trunk/src/misc/chrome-ext/manifest.json sandbox/trunk/src/misc/chrome-ext/popup.html Added: sandbox/trunk/src/misc/chrome-ext/icon.png =================================================================== (Binary files differ) Property changes on: sandbox/trunk/src/misc/chrome-ext/icon.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: sandbox/trunk/src/misc/chrome-ext/manifest.json =================================================================== --- sandbox/trunk/src/misc/chrome-ext/manifest.json (rev 0) +++ sandbox/trunk/src/misc/chrome-ext/manifest.json 2011-02-18 22:39:17 UTC (rev 1750) @@ -0,0 +1,12 @@ +{ + "name": "Yang's Extension", + "version": "1.0", + "description": "The first extension that I made.", + "browser_action": { + "default_icon": "icon.png" + //"popup": "popup.html" + }, + "permissions": [ + "http://api.flickr.com/" + ], +} Added: sandbox/trunk/src/misc/chrome-ext/popup.html =================================================================== --- sandbox/trunk/src/misc/chrome-ext/popup.html (rev 0) +++ sandbox/trunk/src/misc/chrome-ext/popup.html 2011-02-18 22:39:17 UTC (rev 1750) @@ -0,0 +1,23 @@ +<html> + <head> + <style> + body { + min-width:357px; + overflow-x:hidden; + } + + img { + margin:5px; + border:2px solid black; + vertical-align:middle; + width:75px; + height:75px; + } + </style> + </head> + + <body> + hello, world! + </body> + +</html> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2011-02-18 22:38:44
|
Revision: 1749 http://assorted.svn.sourceforge.net/assorted/?rev=1749&view=rev Author: yangzhang Date: 2011-02-18 22:38:38 +0000 (Fri, 18 Feb 2011) Log Message: ----------- Add tutorial chrome extension to sandbox Added Paths: ----------- sandbox/trunk/src/misc/chrome-ext/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2011-02-18 22:37:45
|
Revision: 1748 http://assorted.svn.sourceforge.net/assorted/?rev=1748&view=rev Author: yangzhang Date: 2011-02-18 22:37:39 +0000 (Fri, 18 Feb 2011) Log Message: ----------- Disable surrounding pairs characters Modified Paths: -------------- configs/trunk/src/vim/plugin/_yang.vim Modified: configs/trunk/src/vim/plugin/_yang.vim =================================================================== --- configs/trunk/src/vim/plugin/_yang.vim 2011-02-18 22:36:21 UTC (rev 1747) +++ configs/trunk/src/vim/plugin/_yang.vim 2011-02-18 22:37:39 UTC (rev 1748) @@ -21,15 +21,15 @@ " From " http://concisionandconcinnity.blogspot.com/2009/07/vim-part-ii-matching-pairs.html -vnoremap ( <ESC>`>a)<ESC>`<i(<ESC> -vnoremap ) <ESC>`>a)<ESC>`<i(<ESC> -vnoremap { <ESC>`>a}<ESC>`<i{<ESC> -vnoremap } <ESC>`>a}<ESC>`<i{<ESC> -vnoremap " <ESC>`>a"<ESC>`<i"<ESC> -vnoremap ' <ESC>`>a'<ESC>`<i'<ESC> -vnoremap ` <ESC>`>a`<ESC>`<i`<ESC> -vnoremap [ <ESC>`>a]<ESC>`<i[<ESC> -vnoremap ] <ESC>`>a]<ESC>`<i[<ESC> +" vnoremap ( <ESC>`>a)<ESC>`<i(<ESC> +" vnoremap ) <ESC>`>a)<ESC>`<i(<ESC> +" vnoremap { <ESC>`>a}<ESC>`<i{<ESC> +" vnoremap } <ESC>`>a}<ESC>`<i{<ESC> +" vnoremap " <ESC>`>a"<ESC>`<i"<ESC> +" vnoremap ' <ESC>`>a'<ESC>`<i'<ESC> +" vnoremap ` <ESC>`>a`<ESC>`<i`<ESC> +" vnoremap [ <ESC>`>a]<ESC>`<i[<ESC> +" vnoremap ] <ESC>`>a]<ESC>`<i[<ESC> nnoremap <silent> \va :call AlignWordWithWordInPreviousLine()<CR> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2011-02-18 22:36:26
|
Revision: 1747 http://assorted.svn.sourceforge.net/assorted/?rev=1747&view=rev Author: yangzhang Date: 2011-02-18 22:36:21 +0000 (Fri, 18 Feb 2011) Log Message: ----------- Fix typo in comment doc Modified Paths: -------------- python-commons/trunk/src/commons/seqs.py Modified: python-commons/trunk/src/commons/seqs.py =================================================================== --- python-commons/trunk/src/commons/seqs.py 2011-02-18 22:35:45 UTC (rev 1746) +++ python-commons/trunk/src/commons/seqs.py 2011-02-18 22:36:21 UTC (rev 1747) @@ -404,7 +404,7 @@ Takes a sequence and breaks it up into multiple subsequences, which are groups keyed on L{key}. - >>> map(lis, group_as_subseqs(range(10), lambda x: x/3)) + >>> map(list, group_as_subseqs(range(10), lambda x: x/3)) [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] """ xs = iter(xs) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2011-02-18 22:35:51
|
Revision: 1746 http://assorted.svn.sourceforge.net/assorted/?rev=1746&view=rev Author: yangzhang Date: 2011-02-18 22:35:45 +0000 (Fri, 18 Feb 2011) Log Message: ----------- Add scp-resume & /proc-based utils (from gnprice) /proc utils include phantom-progress, sample-context-switches, oom-scores Modified Paths: -------------- shell-tools/trunk/src/bash-commons/common.bash Modified: shell-tools/trunk/src/bash-commons/common.bash =================================================================== --- shell-tools/trunk/src/bash-commons/common.bash 2011-02-18 22:11:22 UTC (rev 1745) +++ shell-tools/trunk/src/bash-commons/common.bash 2011-02-18 22:35:45 UTC (rev 1746) @@ -667,6 +667,43 @@ psql } +# Resume SCP; from <http://joen.dk/wordpress/?p=34> +scp-resume() { + rsync --partial --progress "$@" +} + +# Show a running process's progress through a file. (Or, "when it's too late +# for pv....") +# <http://blog.ksplice.com/2011/01/solving-problems-with-proc/> +phantom-progress() { + local fd=/proc/$1/fd/$2 + local fdinfo=/proc/$1/fdinfo/$2 + local name=$(readlink $fd) + local size=$(wc -c $fd | awk '{print $1}') + local dialog=${dialog:-gdialog} # can also use 'dialog' + while [ -e $fd ]; do + local progress=$(cat $fdinfo | grep ^pos | awk '{print $2}') + echo $((100*$progress / $size)) + sleep 1 + done | $dialog --gauge "Progress reading $name" 7 100 +} + +# Sample info on context switches. Mostly voluntary means IO-bound. +sample-context-switches() { + watch -d -n 1 "cat /proc/$PID/status | fgrep ctxt_switches" +} + +# Report OOM scores. +oom-scores() { + for procdir in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+'); do + printf "%10d %6d %s\n" \ + "$(cat $procdir/oom_score)" \ + "$(basename $procdir)" \ + "$(cat $procdir/cmdline | tr '\0' ' ' | head -c 100)" + done 2>/dev/null | sort -nr | head -n 20 +} + + #if ! is_declared indent ; then # noindent #else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2011-02-18 22:11:28
|
Revision: 1745 http://assorted.svn.sourceforge.net/assorted/?rev=1745&view=rev Author: yangzhang Date: 2011-02-18 22:11:22 +0000 (Fri, 18 Feb 2011) Log Message: ----------- Add rel="me" link to Google profile to connect sites Modified Paths: -------------- personal-site/trunk/src/index.txt Modified: personal-site/trunk/src/index.txt =================================================================== --- personal-site/trunk/src/index.txt 2011-01-28 19:49:35 UTC (rev 1744) +++ personal-site/trunk/src/index.txt 2011-02-18 22:11:22 UTC (rev 1745) @@ -16,7 +16,7 @@ alt="Tim the Beaver and me" style="box-shadow: 3px 3px 10px black; -webkit-box-shadow: 3px 3px 10px black;"/> </div> - <a target="_blank" title="Follow on Google Buzz" class="google-buzz-button" href="http://www.google.com/profiles/yaaang" data-button-style="follow">Follow on Buzz</a> + <a rel="me" target="_blank" title="Follow on Google Buzz" class="google-buzz-button" href="http://www.google.com/profiles/yaaang" data-button-style="follow">Follow on Buzz</a> <script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script> </div> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2011-01-28 19:49:41
|
Revision: 1744 http://assorted.svn.sourceforge.net/assorted/?rev=1744&view=rev Author: yangzhang Date: 2011-01-28 19:49:35 +0000 (Fri, 28 Jan 2011) Log Message: ----------- Finish documenting setup, add gitit.conf Modified Paths: -------------- personal-site/trunk/README Added Paths: ----------- personal-site/trunk/gitit.conf Modified: personal-site/trunk/README =================================================================== --- personal-site/trunk/README 2011-01-25 00:19:40 UTC (rev 1743) +++ personal-site/trunk/README 2011-01-28 19:49:35 UTC (rev 1744) @@ -14,14 +14,22 @@ - /var/www/ - wp database in mysql -Install packages: +System +------ - # Haskell Platform +Install packages (this is probably incomplete; it was written up long +afterward): + + # Haskell Platform, LAMP, LaTeX (for Gitit), Keychain (for git pulls) + sudo aptitude install python-software-properties sudo add-apt-repository ppa:justinbogner/haskell-platform - sudo aptitude install haskell-platform + sudo aptitude install haskell-platform build-essential \ + apache2 mysql-server libapache2-mod-proxy-html php5 php5-mysql \ + texlive-latex-extra \ + keychain # Pandoc with support for source code highlighting - sudo cabal install pandoc -fhighlighting + sudo cabal install --global -fhighlighting highlighting-kate pandoc # Our own Gitit, which sets Pandoc's tabstop to 2 instead of default of 4 git clone gi...@gi...:yang/gitit.git @@ -31,12 +39,21 @@ # Misc sudo a2enmod headers proxy_html proxy_http rewrite -Set up data: +Static Website +-------------- - # After unpacking old www/ +Set up static web data: + + # After unpacking old www/, which includes wp/ sudo chgrp -R yang /var/www/ sudo chmod -R g+w /var/www/ + # Make sure wp/ is owned by www-data +Publish static site content with `make publish`. + +WordPress +--------- + # MySQL mysql -u root -p -e ' create database wp; @@ -56,6 +73,9 @@ In WP, edit twentyten's style.css, header.php. Working on a better solution. +Apache +------ + In sites-enabled/000-default: <Directory /var/www/wp/> @@ -76,8 +96,58 @@ RequestHeader unset Accept-Encoding </Location> -Publish static site content with `make publish`. +Gitit +----- +Create an ssh key, register it on Github, and have keychain manage it. + +Then set up Gitit. Either copy over the old directory or set it up from +scratch. If setting up from scratch, don't forget to push the old wikidata and +to copy over the gitit-users and gitit.log files. Here's how to set up from +scratch: + + # Set up gitit + mkdir ~/gitit/ + ln -s .../personal-site/trunk/gitit.conf ~/gitit/config + cd ~/gitit/ + gitit -f config # ctrl-c once it creates the missing files/dirs + + # Install jsMath, if using that + wget -P /tmp/ \ + 'http://sourceforge.net/projects/jsmath/files/jsMath/3.6e/jsMath-3.6e.zip' \ + 'http://sourceforge.net/projects/jsmath/files/jsMath%20Image%20Fonts/1.3/jsMath-fonts-1.3.zip' + mkdir static/js/ + unzip -d static/js/ /tmp/jsMath-3.6e.zip + mv static/js/jsMath{-3.6e,} + + # Use your notes git repository + rm -rf wikidata/ # Remove the default wikidata + git clone gi...@gi...:yang/notes.git + + # Copy over gitit.log, gitit-users + +Now create /etc/init/gitit.conf to start gitit on boot: + + start on runlevel [2345] + stop on runlevel [!2345] + + respawn + + exec su - yang -c 'cd gitit/; exec gitit -f config' + +Install this cronjob script: + + ln -s .../assorted/configs/trunk/src/cron/pull-gitit.bash ~/.cron/ + +Add this to your crontab to pull every minute (test it!): + + * * * * * $HOME/.cron/pull-gitit.bash + +Start everything: + + sudo start gitit # make sure this is working! + sudo service apache2 restart + Related ======= Added: personal-site/trunk/gitit.conf =================================================================== --- personal-site/trunk/gitit.conf (rev 0) +++ personal-site/trunk/gitit.conf 2011-01-28 19:49:35 UTC (rev 1744) @@ -0,0 +1,238 @@ +# gitit wiki configuration file + +port: 5001 +# sets the port on which the web server will run. + +wiki-title: Yang's Wiki +# the title of the wiki. + +repository-type: Git +# specifies the type of repository used for wiki content. +# Options are Git, Darcs, and Mercurial. + +repository-path: wikidata +# specifies the path of the repository directory. If it does not +# exist, gitit will create it on startup. + +authentication-method: form +# 'form' means that users will be logged in and registered +# using forms in the gitit web interface. 'http' means +# that gitit will assume that HTTP authentication is in +# place and take the logged in username from the "Authorization" +# field of the HTTP request header (in addition, +# the login/logout and registration links will be +# suppressed). 'generic' means that gitit will assume that +# some form of authentication is in place that directly +# sets REMOTE_USER to the name of the authenticated user +# (e.g. mod_auth_cas on apache). + +user-file: gitit-users +# specifies the path of the file containing user login information. +# If it does not exist, gitit will create it (with an empty user list). +# This file is not used if 'http' is selected for authentication-method. + +session-timeout: 60 +# number of minutes of inactivity before a session expires. + +static-dir: static +# specifies the path of the static directory (containing javascript, +# css, and images). If it does not exist, gitit will create it +# and populate it with required scripts, stylesheets, and images. + +default-page-type: Markdown +# specifies the type of markup used to interpret pages in the wiki. +# Possible values are Markdown, RST, LaTeX, HTML, Markdown+LHS, RST+LHS, +# and LaTeX+LHS. (The +LHS variants treat the input as +# literate Haskell. See pandoc's documentation for more details.) If +# Markdown is selected, pandoc's syntax extensions (for footnotes, +# delimited code blocks, etc.) will be enabled. Note that pandoc's +# reStructuredText parser is not complete, so some pages may not be +# rendered correctly if RST is selected. The same goes for LaTeX and +# HTML. + +math: jsMath +# specifies how LaTeX math is to be displayed. Possible values +# are MathML, raw, jsMath, and google. If mathml is selected, gitit will +# convert LaTeX math to MathML and link in a script, MathMLinHTML.js, +# that allows the MathML to be seen in Gecko browsers, IE + +# mathplayer, and Opera. In other browsers you may get a jumble +# of characters. If raw is selected, the LaTeX math will be displayed +# as raw LaTeX math. If jsMath is selected, gitit will link to +# the script /js/jsMath/easy/load.js, and will assume that jsMath +# has been installed into the js/jsMath directory. This is the most +# portable solution. If google is selected, the google chart API is +# called to render the formula as an image. This requires a connection +# to google, and might raise a technical or a privacy problem. + +show-lhs-bird-tracks: no +# specifies whether to show Haskell code blocks in "bird style", +# with "> " at the beginning of each line. + +templates-dir: templates +# specifies the path of the directory containing page templates. +# If it does not exist, gitit will create it with default templates. +# Users may wish to edit the templates to customize the appearance of +# their wiki. The template files are HStringTemplate templates. +# Variables to be interpolated appear between $'s. Literal $'s must be +# backslash-escaped. + +log-file: gitit.log +# specifies the path of gitit's log file. If it does not exist, +# gitit will create it. The log is in Apache combined log format. + +log-level: INFO +# determines how much information is logged. +# Possible values (from most to least verbose) are DEBUG, INFO, +# NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY. + +front-page: Front Page +# specifies which wiki page is to be used as the wiki's front page. +# Gitit creates a default front page on startup, if one does not exist +# already. + +no-delete: Front Page, Help +# specifies pages that cannot be deleted through the web interface. +# (They can still be deleted directly using git or darcs.) +# A comma-separated list of page names. Leave blank to allow +# every page to be deleted. + +no-edit: Help +# specifies pages that cannot be edited through the web interface. +# Leave blank to allow every page to be edited. + +default-summary: +# specifies text to be used in the change description if the author +# leaves the "description" field blank. If default-summary is blank +# (the default), the author will be required to fill in the description +# field. + +table-of-contents: yes +# specifies whether to print a tables of contents (with links to +# sections) on each wiki page. + +plugins: +# specifies a list of plugins to load. Plugins may be specified +# either by their path or by their module name. If the plugin name +# starts with Gitit.Plugin., gitit will assume that the plugin is +# an installed module and will not try to find a source file. +# Examples: +# plugins: plugins/DotPlugin.hs, CapitalizeEmphasisPlugin.hs +# plugins: plugins/DotPlugin +# plugins: Gitit.Plugin.InterwikiLinks + +use-cache: no +# specifies whether to cache rendered pages. Note that if use-feed +# is selected, feeds will be cached regardless of the value of use-cache. + +cache-dir: cache +# directory where rendered pages will be cached + +max-upload-size: 100K +# specifies an upper limit on the size (in bytes) of files uploaded +# through the wiki's web interface. +# To disable uploads, set this to 0K. +# This will result in the uploads link disappearing +# and the _upload url becoming inactive. + +max-page-size: 100K +# specifies an upper limit on the size (in bytes) of pages + +debug-mode: no +# if "yes", causes debug information to be logged while gitit is running. + +compress-responses: no +# specifies whether HTTP responses should be compressed. + +mime-types-file: /etc/mime.types +# specifies the path of a file containing mime type mappings. +# Each line of the file should contain two fields, separated by +# whitespace. The first field is the mime type, the second is a +# file extension. For example: +# video/x-ms-wmx wmx +# If the file is not found, some simple defaults will be used. + +use-recaptcha: no +# if "yes", causes gitit to use the reCAPTCHA service +# (http://recaptcha.net) to prevent bots from creating accounts. + +recaptcha-private-key: +recaptcha-public-key: +# specifies the public and private keys for the reCAPTCHA service. +# To get these, you need to create an account at http://recaptcha.net. + +access-question: +access-question-answers: +# specifies a question that users must answer when they attempt to create +# an account, along with a comma-separated list of acceptable answers. +# This can be used to institute a rudimentary password for signing up as +# a user on the wiki, or as an alternative to reCAPTCHA. +# Example: +# access-question: What is the code given to you by Ms. X? +# access-question-answers: RED DOG, red dog + +mail-command: sendmail %s +# specifies the command to use to send notification emails. +# '%s' will be replaced by the destination email address. +# The body of the message will be read from stdin. +# If this field is left blank, password reset will not be offered. + +reset-password-message: + > From: nobody@$hostname$ + > To: $useremail$ + > Subject: Wiki password reset + > + > Dear $username$: + > + > To reset your password, please follow the link below: + > http://$hostname$/notes$resetlink$ + > + > Yours sincerely, + > The Wiki Master + +# gives the text of the message that will be sent to the user should she +# want to reset her password, or change other registration info. +# The lines must be indented, and must begin with '>'. The initial +# spaces and '> ' will be stripped off. $username$ will be replaced +# by the user's username, $useremail$ by her email address, +# $hostname$ by the hostname on which the wiki is running (as +# returned by the hostname system call), $port$ by the port on +# which the wiki is running, and $resetlink$ by the +# relative path of a reset link derived from the user's existing +# hashed password. If your gitit wiki is being proxied to a location +# other than the root path of $port$, you should change the link to +# reflect this: for example, to +# http://$hostname$/path/to/wiki$resetlink$ or +# http://gitit.$hostname$$resetlink$ + +use-feed: yes +# specifies whether an ATOM feed should be enabled (for the site and for +# individual pages) + +base-url: +# the base URL of the wiki, to be used in constructing feed IDs. +# If this field is left blank, gitit will get the base URL from the +# request header 'Host'. For most users, this should be fine, but +# if you are proxying a gitit instance to a subdirectory URL, you will +# want to set this manually. + +feed-days: 30 +# number of days to be included in feeds. + +feed-refresh-time: 60 +# number of minutes to cache feeds before refreshing + +pdf-export: no +# TODO enable only if there are no security issues +# if yes, PDF will appear in export options. PDF will be created using +# pdflatex, which must be installed and in the path. Note that PDF +# exports create significant additional server load. + +pandoc-user-data: +# if a directory is specified, this will be searched for pandoc +# customizations. These can include a templates/ directory for custom +# templates for various export formats, an S5 directory for custom +# S5 styles, and a reference.odt for ODT exports. If no directory is +# specified, $HOME/.pandoc will be searched. See pandoc's README for +# more information. + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2011-01-25 00:19:46
|
Revision: 1743 http://assorted.svn.sourceforge.net/assorted/?rev=1743&view=rev Author: yangzhang Date: 2011-01-25 00:19:40 +0000 (Tue, 25 Jan 2011) Log Message: ----------- Add pg-grant-tables Modified Paths: -------------- shell-tools/trunk/src/bash-commons/common.bash Modified: shell-tools/trunk/src/bash-commons/common.bash =================================================================== --- shell-tools/trunk/src/bash-commons/common.bash 2011-01-08 02:41:57 UTC (rev 1742) +++ shell-tools/trunk/src/bash-commons/common.bash 2011-01-25 00:19:40 UTC (rev 1743) @@ -655,6 +655,18 @@ openssl enc -kfile /dev/fd/0 -in /dev/zero -aes-128-cbc > "$@" } +# Given a user, grant permissions (default: all) on all tables in some schema +# (default: public) to that user. +pg-grant-tables() { + local schema=${schema:-public} perms=${perms:-all} user=$1 + psql -A -t -c " + select 'grant $perms on '||schemaname||'.'||tablename||' to $user;' + from pg_tables + where schemaname = '$schema' + order by schemaname, tablename;" | + psql +} + #if ! is_declared indent ; then # noindent #else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2011-01-08 02:42:03
|
Revision: 1742 http://assorted.svn.sourceforge.net/assorted/?rev=1742&view=rev Author: yangzhang Date: 2011-01-08 02:41:57 +0000 (Sat, 08 Jan 2011) Log Message: ----------- Document Gitit/Pandoc customization; document file/DB migration; reorganized docs Modified Paths: -------------- personal-site/trunk/README Modified: personal-site/trunk/README =================================================================== --- personal-site/trunk/README 2010-12-24 09:10:22 UTC (rev 1741) +++ personal-site/trunk/README 2011-01-08 02:41:57 UTC (rev 1742) @@ -9,15 +9,53 @@ Setup ===== -Web server setup on Ubuntu 10.04: +What to copy/migrate when moving hosts: +- /var/www/ +- wp database in mysql + +Install packages: + + # Haskell Platform sudo add-apt-repository ppa:justinbogner/haskell-platform sudo aptitude install haskell-platform - sudo cabal install --global gitit + + # Pandoc with support for source code highlighting + sudo cabal install pandoc -fhighlighting + + # Our own Gitit, which sets Pandoc's tabstop to 2 instead of default of 4 + git clone gi...@gi...:yang/gitit.git + cd gitit/ + sudo cabal install --global + + # Misc sudo a2enmod headers proxy_html proxy_http rewrite + +Set up data: + + # After unpacking old www/ sudo chgrp -R yang /var/www/ sudo chmod -R g+w /var/www/ + # MySQL + mysql -u root -p -e ' + create database wp; + create user wp identified by "PASSWORD"; -- set this + grant all on wp.* to wp; + ' + + # Import old mysql data into wp + mysql -u wp -p wp < /tmp/mysqldump + +**Note**: MySQL is using MyISAM tables. I can't switch to MyISAM yet because +the YARP plugin requires MyISAM full-text indices. Otherwise it would be as +simple as adding to /etc/mysql/my.cnf: + + [mysqld] + default-storage-engine=innodb + +In WP, edit twentyten's style.css, header.php. Working on a better solution. + In sites-enabled/000-default: <Directory /var/www/wp/> @@ -38,17 +76,8 @@ RequestHeader unset Accept-Encoding </Location> -Edit twentyten's style.css, header.php. Working on a better solution. - Publish static site content with `make publish`. -**Note**: MySQL is using MyISAM tables. I can't switch to MyISAM yet because -the YARP plugin requires MyISAM full-text indices. Otherwise it would be as -simple as adding to /etc/mysql/my.cnf: - - [mysqld] - default-storage-engine=innodb - Related ======= This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-24 09:10:28
|
Revision: 1741 http://assorted.svn.sourceforge.net/assorted/?rev=1741&view=rev Author: yangzhang Date: 2010-12-24 09:10:22 +0000 (Fri, 24 Dec 2010) Log Message: ----------- Added stupid lang perf comparisons Added Paths: ----------- sandbox/trunk/src/misc/perfcmps/ sandbox/trunk/src/misc/perfcmps/README sandbox/trunk/src/misc/perfcmps/ballsbins.cc sandbox/trunk/src/misc/perfcmps/ballsbins.py Added: sandbox/trunk/src/misc/perfcmps/README =================================================================== --- sandbox/trunk/src/misc/perfcmps/README (rev 0) +++ sandbox/trunk/src/misc/perfcmps/README 2010-12-24 09:10:22 UTC (rev 1741) @@ -0,0 +1,30 @@ +$ time ./a.out +1 1 +2 2.99733 +3 5.49854 +4 8.33333 +5 11.4044 +6 14.7145 +7 18.1225 +8 21.766 +9 25.4201 + +real 0m0.854s +user 0m0.860s +sys 0m0.000s + +$ time python /tmp/go.py +1 1.0 +2 3.00057 +3 5.48621 +4 8.31665 +5 11.41543 +6 14.70859 +7 18.11071 +8 21.69454 +9 25.41788 + +real 0m22.365s +user 0m22.350s +sys 0m0.020s + Added: sandbox/trunk/src/misc/perfcmps/ballsbins.cc =================================================================== --- sandbox/trunk/src/misc/perfcmps/ballsbins.cc (rev 0) +++ sandbox/trunk/src/misc/perfcmps/ballsbins.cc 2010-12-24 09:10:22 UTC (rev 1741) @@ -0,0 +1,26 @@ +#include <iostream> +#include <vector> +#include <cstdlib> +using namespace std; +int main() { + int trials=100000; + for (int b = 1; b < 10; b++) { + int sum=0; + for (int t = 0; t < trials; t++) { + vector<bool> B(b, false); + for (int i = 0;; i++) { + B.at(random() % b) = true; + bool all=true; + for (int j = 0; j < b; j++) { + all=all&&B.at(j); + } + if (all) { + sum += i+1; + break; + } + } + } + cout<<b<<' '<<(double)sum/trials<<endl; + } + return 0; +} Added: sandbox/trunk/src/misc/perfcmps/ballsbins.py =================================================================== --- sandbox/trunk/src/misc/perfcmps/ballsbins.py (rev 0) +++ sandbox/trunk/src/misc/perfcmps/ballsbins.py 2010-12-24 09:10:22 UTC (rev 1741) @@ -0,0 +1,12 @@ +import itertools, random +trials=100000 +def gen(b): + for t in xrange(trials): + B=[False]*b + for i in itertools.count(): + B[random.randrange(b)]=True + if all(B): + yield i+1 + break +for b in xrange(1, 10): + print b, sum(gen(b))/float(trials) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-24 05:28:12
|
Revision: 1740 http://assorted.svn.sourceforge.net/assorted/?rev=1740&view=rev Author: yangzhang Date: 2010-12-24 05:28:06 +0000 (Fri, 24 Dec 2010) Log Message: ----------- Added magic-space Modified Paths: -------------- configs/trunk/src/inputrc Modified: configs/trunk/src/inputrc =================================================================== --- configs/trunk/src/inputrc 2010-12-21 23:45:36 UTC (rev 1739) +++ configs/trunk/src/inputrc 2010-12-24 05:28:06 UTC (rev 1740) @@ -31,3 +31,7 @@ #set input-meta on #set convert-meta on #set output-meta on + +$if Bash + Space: magic-space +$endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-21 23:45:42
|
Revision: 1739 http://assorted.svn.sourceforge.net/assorted/?rev=1739&view=rev Author: yangzhang Date: 2010-12-21 23:45:36 +0000 (Tue, 21 Dec 2010) Log Message: ----------- Flightscraper, comment, typo in setup-cron Modified Paths: -------------- configs/trunk/setup-cron.bash Modified: configs/trunk/setup-cron.bash =================================================================== --- configs/trunk/setup-cron.bash 2010-12-21 23:39:23 UTC (rev 1738) +++ configs/trunk/setup-cron.bash 2010-12-21 23:45:36 UTC (rev 1739) @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Installs cron jobs. +# Installs cron jobs meant to be run by personal server yz.mit.edu. . common.bash || exit 1 @@ -17,13 +17,14 @@ local arg="$1" if [[ "${arg:0:1}" == / ]] then [ -f "$arg" ] || die "could not find file $arg" - else silence type "$arg" || die "could not find proram $arg" + else silence type "$arg" || die "could not find program $arg" fi } check duplicity check gbookmark2delicious check ~/.gbookmark2delicious.auth +check flightscraper check mlf.py check ~/.mlf.auth check mysqldump This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-21 23:39:29
|
Revision: 1738 http://assorted.svn.sourceforge.net/assorted/?rev=1738&view=rev Author: yangzhang Date: 2010-12-21 23:39:23 +0000 (Tue, 21 Dec 2010) Log Message: ----------- Filled out README documentation Modified Paths: -------------- personal-site/trunk/README Modified: personal-site/trunk/README =================================================================== --- personal-site/trunk/README 2010-12-21 23:39:08 UTC (rev 1737) +++ personal-site/trunk/README 2010-12-21 23:39:23 UTC (rev 1738) @@ -1,3 +1,55 @@ -out: staging area for `make publish` -static: images, css files, and other files that are directly copied into the published directory -src: the source files that generate files to be published +File Organization +================= + +- out: staging area for `make publish` +- static: images, css files, and other files that are directly copied into the + published directory +- src: the source files that generate files to be published + +Setup +===== + +Web server setup on Ubuntu 10.04: + + sudo add-apt-repository ppa:justinbogner/haskell-platform + sudo aptitude install haskell-platform + sudo cabal install --global gitit + sudo a2enmod headers proxy_html proxy_http rewrite + sudo chgrp -R yang /var/www/ + sudo chmod -R g+w /var/www/ + +In sites-enabled/000-default: + + <Directory /var/www/wp/> + RewriteEngine On + RewriteBase /wp/ + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /wp/index.php [L] + </Directory> + + RedirectMatch permanent ^/notes([/]*)$ /notes/ + <Location /notes/> + Allow from all + ProxyPass http://127.0.0.1:5001/ + SetOutputFilter proxy-html + ProxyPassReverse / + ProxyHTMLURLMap / /notes/ + RequestHeader unset Accept-Encoding + </Location> + +Edit twentyten's style.css, header.php. Working on a better solution. + +Publish static site content with `make publish`. + +**Note**: MySQL is using MyISAM tables. I can't switch to MyISAM yet because +the YARP plugin requires MyISAM full-text indices. Otherwise it would be as +simple as adding to /etc/mysql/my.cnf: + + [mysqld] + default-storage-engine=innodb + +Related +======= + +See also: configs' setup-cron.bash. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-21 23:39:14
|
Revision: 1737 http://assorted.svn.sourceforge.net/assorted/?rev=1737&view=rev Author: yangzhang Date: 2010-12-21 23:39:08 +0000 (Tue, 21 Dec 2010) Log Message: ----------- Tweaked site list Modified Paths: -------------- personal-site/trunk/Makefile Modified: personal-site/trunk/Makefile =================================================================== --- personal-site/trunk/Makefile 2010-12-21 08:03:39 UTC (rev 1736) +++ personal-site/trunk/Makefile 2010-12-21 23:39:08 UTC (rev 1737) @@ -23,7 +23,7 @@ sed 's/<body>/<body onload="javascript:body_onload();">/' > $(PLAIN) publish: all - scp -o CompressionLevel=9 -r out/* nr:/var/www/ + scp -o CompressionLevel=9 -r out/* yz.mit.edu:/var/www/ publish-redir: $(REDIR) scp $(REDIR) cs:public_html/ @@ -31,8 +31,10 @@ scp $(REDIR) pdos:public_html/ scp $(REDIR) lin:www/ scp $(REDIR) lin:web_scripts/ + scp $(REDIR) hv:public_html/ scp $(REDIR) nms:public_html/ - scp $(REDIR) hv:public_html/ + scp $(REDIR) nr:public_html/ + scp $(REDIR) yz.csail.mit.edu:public_html/ scp $(REDIR) zs:public_html/ clean: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-21 08:03:45
|
Revision: 1736 http://assorted.svn.sourceforge.net/assorted/?rev=1736&view=rev Author: yangzhang Date: 2010-12-21 08:03:39 +0000 (Tue, 21 Dec 2010) Log Message: ----------- Fixed rtun upstart to retry on its own Modified Paths: -------------- configs/trunk/src/upstart/rtun.conf Modified: configs/trunk/src/upstart/rtun.conf =================================================================== --- configs/trunk/src/upstart/rtun.conf 2010-12-16 03:52:36 UTC (rev 1735) +++ configs/trunk/src/upstart/rtun.conf 2010-12-21 08:03:39 UTC (rev 1736) @@ -21,6 +21,11 @@ respawn -exec su yang -c 'ssh -N -R1122:localhost:22 -i /home/yang/.ssh/rtun \ - -o BatchMode=yes -o ServerAliveInterval=300 -o TCPKeepAlive=yes \ - rtun@HOST' +# Upstart seems to squish together all the lines, hence the semicolons +exec su yang -c ' + while true ; do + ssh -N -R1122:localhost:22 -i /home/yang/.ssh/rtun + -o BatchMode=yes -o ServerAliveInterval=300 -o TCPKeepAlive=yes + rtun@HOST ; + sleep 5 ; + done &>> /tmp/rtun.log' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-16 03:52:42
|
Revision: 1735 http://assorted.svn.sourceforge.net/assorted/?rev=1735&view=rev Author: yangzhang Date: 2010-12-16 03:52:36 +0000 (Thu, 16 Dec 2010) Log Message: ----------- Simplified genpass Modified Paths: -------------- shell-tools/trunk/src/bash-commons/bashrc.bash Modified: shell-tools/trunk/src/bash-commons/bashrc.bash =================================================================== --- shell-tools/trunk/src/bash-commons/bashrc.bash 2010-12-14 19:30:29 UTC (rev 1734) +++ shell-tools/trunk/src/bash-commons/bashrc.bash 2010-12-16 03:52:36 UTC (rev 1735) @@ -353,7 +353,8 @@ } function genpass { - apg -M SNCL -n 3 -m 8 -x 8 + # apg -M SNCL -n 3 -m 8 -x 8 + < /dev/urandom tr -cd [[:graph:]] | head -c16 | xargs echo } # TODO fix This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-14 19:30:35
|
Revision: 1734 http://assorted.svn.sourceforge.net/assorted/?rev=1734&view=rev Author: yangzhang Date: 2010-12-14 19:30:29 +0000 (Tue, 14 Dec 2010) Log Message: ----------- Fixed check for interactive shell, set HOME Modified Paths: -------------- shell-tools/trunk/src/bash-commons/bashrc.bash Modified: shell-tools/trunk/src/bash-commons/bashrc.bash =================================================================== --- shell-tools/trunk/src/bash-commons/bashrc.bash 2010-12-09 21:07:50 UTC (rev 1733) +++ shell-tools/trunk/src/bash-commons/bashrc.bash 2010-12-14 19:30:29 UTC (rev 1734) @@ -36,6 +36,11 @@ export DEBEMAIL='ya...@gm...' export TERM=xterm-256color +# monit unsets HOME +if [[ ! $HOME ]] +then export HOME=~ +fi + # TODO this is from sht; mv it to a mini-commons # TODO is this necessary in light of advanced var expansions? is_declared() { @@ -856,7 +861,7 @@ # -t 1 checks if fd 1 (stdout) is a terminal; if so then we're running # interactively. -if [[ -t 1 ]] +if [[ "$PS1" && -t 1 ]] then keychain_flags= else keychain_flags=--noask fi @@ -875,7 +880,7 @@ # particular it re/undefines `have`), so it's best to move this near the # top # Note that this tends to be the most expensive part of my startup. -if [[ -t 1 ]] ; then +if [[ "$PS1" && -t 1 ]] ; then if [[ -f /etc/bash_completion && -z "$BASH_COMPLETION" ]] then . /etc/bash_completion fi This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-09 21:07:56
|
Revision: 1733 http://assorted.svn.sourceforge.net/assorted/?rev=1733&view=rev Author: yangzhang Date: 2010-12-09 21:07:50 +0000 (Thu, 09 Dec 2010) Log Message: ----------- Updated documentation for rtun.conf Modified Paths: -------------- configs/trunk/src/upstart/rtun.conf Modified: configs/trunk/src/upstart/rtun.conf =================================================================== --- configs/trunk/src/upstart/rtun.conf 2010-12-07 05:07:55 UTC (rev 1732) +++ configs/trunk/src/upstart/rtun.conf 2010-12-09 21:07:50 UTC (rev 1733) @@ -2,17 +2,15 @@ # remote host (HOST) of your choice. This enables connections made to HOST:1122 # to connect to localhost:22. # +# Locally: +# +# ssh-keygen -P '' -f ~/.ssh/rtun +# # On the remote host (HOST): # # useradd -mr --shell=/usr/sbin/nologin rtun # sudo -u rtun bash -c 'mkdir -p ~rtun/.ssh; vim ~rtun/.ssh/authorized_keys' # -# Locally: -# -# sudo ln -s /lib/init/upstart-job /etc/init.d/rtun -# sudo update-rc.d rtun defaults -# ssh-keygen -P '' -f ~/.ssh/rtun -# # Warning: creating keys that are not protected by a passphrase will let anyone # ssh into HOST as rtun (hence the nologin shell). This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-07 05:08:01
|
Revision: 1732 http://assorted.svn.sourceforge.net/assorted/?rev=1732&view=rev Author: yangzhang Date: 2010-12-07 05:07:55 +0000 (Tue, 07 Dec 2010) Log Message: ----------- Added missing quotes in rtun.conf Modified Paths: -------------- configs/trunk/src/upstart/rtun.conf Modified: configs/trunk/src/upstart/rtun.conf =================================================================== --- configs/trunk/src/upstart/rtun.conf 2010-12-07 04:54:17 UTC (rev 1731) +++ configs/trunk/src/upstart/rtun.conf 2010-12-07 05:07:55 UTC (rev 1732) @@ -23,6 +23,6 @@ respawn -exec su yang -c ssh -N -R1122:localhost:22 -i /home/yang/.ssh/rtun \ +exec su yang -c 'ssh -N -R1122:localhost:22 -i /home/yang/.ssh/rtun \ -o BatchMode=yes -o ServerAliveInterval=300 -o TCPKeepAlive=yes \ - rtun@HOST + rtun@HOST' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-07 04:54:23
|
Revision: 1731 http://assorted.svn.sourceforge.net/assorted/?rev=1731&view=rev Author: yangzhang Date: 2010-12-07 04:54:17 +0000 (Tue, 07 Dec 2010) Log Message: ----------- Added rtun.conf upstart configuration Added Paths: ----------- configs/trunk/src/upstart/ configs/trunk/src/upstart/rtun.conf Added: configs/trunk/src/upstart/rtun.conf =================================================================== --- configs/trunk/src/upstart/rtun.conf (rev 0) +++ configs/trunk/src/upstart/rtun.conf 2010-12-07 04:54:17 UTC (rev 1731) @@ -0,0 +1,28 @@ +# This will ensure that at startup a reverse ssh tunnel is created to the +# remote host (HOST) of your choice. This enables connections made to HOST:1122 +# to connect to localhost:22. +# +# On the remote host (HOST): +# +# useradd -mr --shell=/usr/sbin/nologin rtun +# sudo -u rtun bash -c 'mkdir -p ~rtun/.ssh; vim ~rtun/.ssh/authorized_keys' +# +# Locally: +# +# sudo ln -s /lib/init/upstart-job /etc/init.d/rtun +# sudo update-rc.d rtun defaults +# ssh-keygen -P '' -f ~/.ssh/rtun +# +# Warning: creating keys that are not protected by a passphrase will let anyone +# ssh into HOST as rtun (hence the nologin shell). + +description "Reverse tunneling gateway to enable firewall traversal" + +start on runlevel [2345] +stop on runlevel [!2345] + +respawn + +exec su yang -c ssh -N -R1122:localhost:22 -i /home/yang/.ssh/rtun \ + -o BatchMode=yes -o ServerAliveInterval=300 -o TCPKeepAlive=yes \ + rtun@HOST This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-07 00:38:51
|
Revision: 1730 http://assorted.svn.sourceforge.net/assorted/?rev=1730&view=rev Author: yangzhang Date: 2010-12-07 00:38:45 +0000 (Tue, 07 Dec 2010) Log Message: ----------- Migrated flight-search to github as flight-scraper Removed Paths: ------------- sandbox/trunk/src/one-off-scripts/flight-search/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-06 08:16:39
|
Revision: 1729 http://assorted.svn.sourceforge.net/assorted/?rev=1729&view=rev Author: yangzhang Date: 2010-12-06 08:16:29 +0000 (Mon, 06 Dec 2010) Log Message: ----------- Added speeddating.vim Added Paths: ----------- configs/trunk/src/vim/doc/speeddating.txt configs/trunk/src/vim/plugin/speeddating.vim Added: configs/trunk/src/vim/doc/speeddating.txt =================================================================== --- configs/trunk/src/vim/doc/speeddating.txt (rev 0) +++ configs/trunk/src/vim/doc/speeddating.txt 2010-12-06 08:16:29 UTC (rev 1729) @@ -0,0 +1,101 @@ +*speeddating.vim* Use CTRL-A/CTRL-X to increment dates, times, and more + +Author: Tim Pope <vim...@tp...> *speeddating-author* +License: Same terms as Vim itself (see |license|) + +This plugin is only available if 'compatible' is not set. + +INTRODUCTION *speeddating* + +The easiest way to get a feel for this plugin is to copy the following lines +to a temp file and go to town on them with <C-A> and <C-X>. When you're done, +come back here and read about some of the more advanced features, like +incrementing lists and custom formats. > + + Fri, 31 Dec 1999 23:59:59 +0000 + Fri Dec 31 23:59:59 UTC 1999 + 2008-01-05T04:59:59Z + 1865-04-15 + 11/Sep/01 + January 14th, 1982 + 11:55 AM + 3rd + XXXVIII +< +MAPS *speeddating-maps* + +Here, "component" refers to any year, month, day, hour, minute, or second +written as either a number or a word ("January") in any recognized format, or +a number or ordinal ("1st") outside of a time. + + *speeddating-CTRL-A* +<C-A> Increment by [count] the component under the cursor. + + *speeddating-CTRL-X* +<C-X> Decrement by [count] the component under the cursor. + + *speeddating-d_CTRL-A* +d<C-A> Change the time under the cursor to the current time + in UTC. + + *speeddating-d_CTRL-X* +d<C-X> Change the time under the cursor to the current local + time. + + *speeddating-v_CTRL-A* +{Visual}<C-A> Increment by [count] the component under the cursor on + each line of the linewise visual selection. If a + component is absent on a line, it is filled in as + being [count] higher than on the line above it. This + can be used to create sequences. For example, place a + "0" on a line followed by 4 blank lines, visually + select all 5 lines, and press <C-A> to get a sequence + of 1 through 5. You can use letters in visual mode + too: make the first entry Z if you want a list + starting with A. + + *speeddating-v_CTRL-X* +{Visual}<C-X> Like |v_CTRL-A|, but decrement. + + *speeddating-.* +. If you want to use |.| to repeat a speeddating.vim + mapping, install repeat.vim. + +FORMATS *speeddating-formats* + +One can use the :SpeedDatingFormat command to list, add, and remove formats. + + *:SpeedDatingFormat* +:SpeedDatingFormat List defined formats. + +:SpeedDatingFormat! Help for defining formats. + +:SpeedDatingFormat {format} + Define a new format. + +:{count}SpeedDatingFormat {format} + Define a new format with the specified priority. + +:SpeedDatingFormat! {format} + Remove an existing format. + +:{count}SpeedDatingFormat! + Remove an existing format by priority. + +Of note is that the built-in support for Roman numerals is actually +implemented with a Roman numeral year format and can be removed. + +CAVEATS *speeddating-caveats* + +Gregorian calendar always used. + +Time zone abbreviation support is limited to a few predefined codes on Windows +and other platforms without strftime("%Z") support. If your time zone +abbreviation is not correctly identified set the g:speeddating_zone and +g:speeddating_zone_dst variables. + +Beginning a format with a digit causes Vim to treat leading digits as a count +instead. To work around this escape it with %[] (e.g., %[2]0%0y%0m%0d%* is a +decent format for DNS serials). + + vim:tw=78:et:ft=help:norl: Added: configs/trunk/src/vim/plugin/speeddating.vim =================================================================== --- configs/trunk/src/vim/plugin/speeddating.vim (rev 0) +++ configs/trunk/src/vim/plugin/speeddating.vim 2010-12-06 08:16:29 UTC (rev 1729) @@ -0,0 +1,833 @@ +" speeddating.vim - Use CTRL-A/CTRL-X to increment dates, times, and more +" Maintainer: Tim Pope <vim...@tp...> +" Version: 20100301 +" GetLatestVimScripts: 2120 1 :AutoInstall: speeddating.vim + +" Initialization {{{1 + +if exists("g:loaded_speeddating") || &cp || v:version < 700 + finish +endif +let g:loaded_speeddating = 1 + +let s:cpo_save = &cpo +set cpo&vim + +let g:speeddating_handlers = [] + +let s:install_dir = expand("<sfile>:p:h:h") + +" }}}1 +" Utility Functions {{{1 + +function! s:function(name) + return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\d\+_'),'')) +endfunction + +" In Vim, -4 % 3 == -1. Let's return 2 instead. +function! s:mod(a,b) + if (a:a < 0 && a:b > 0 || a:a > 0 && a:b < 0) && a:a % a:b != 0 + return (a:a % a:b) + a:b + else + return a:a % a:b + endif +endfunction + +" In Vim, -4 / 3 == -1. Let's return -2 instead. +function! s:div(a,b) + if a:a < 0 && a:b > 0 + return (a:a-a:b+1)/a:b + elseif a:a > 0 && a:b < 0 + return (a:a-a:b-1)/a:b + else + return a:a / a:b + endif +endfunction + +function! s:match(...) + let b = call("match",a:000) + let e = call("matchend",a:000) + let s = call("matchlist",a:000) + if s == [] + let s = ["","","","","","","","","",""] + endif + return [b,e] + s +endfunction + +function! s:findatoffset(string,pattern,offset) + let line = a:string + let curpos = 0 + let offset = a:offset + while strpart(line,offset,1) == " " + let offset += 1 + endwhile + let [start,end,string;caps] = s:match(line,a:pattern,curpos,0) + while start >= 0 + if offset >= start && offset < end + break + endif + let curpos = start + 1 + let [start,end,string;caps] = s:match(line,a:pattern,curpos,0) + endwhile + return [start,end,string] + caps +endfunction + +function! s:findinline(pattern) + return s:findatoffset(getline('.'),a:pattern,col('.')-1) +endfunction + +function! s:replaceinline(start,end,new) + let line = getline('.') + let before_text = strpart(line,0,a:start) + let after_text = strpart(line,a:end) + " If this generates a warning it will be attached to an ugly backtrace. + " No warning at all is preferable to that. + silent call setline('.',before_text.a:new.after_text) + call setpos("'[",[0,line('.'),strlen(before_text)+1,0]) + call setpos("']",[0,line('.'),a:start+strlen(a:new),0]) +endfunction + +" }}}1 +" Normal Mode {{{1 + +function! s:increment(increment) + for handler in s:time_handlers + g:speeddating_handlers + let pattern = type(handler.regexp) == type(function('tr')) ? handler.regexp() : handler.regexp + let [start,end,string;caps] = s:findinline('\C'.pattern) + if string != "" + let [repl,offset] = handler.increment(string,col('.')-1-start,a:increment) + if offset < 0 + let offset += strlen(repl) + 1 + endif + if repl != "" + call s:replaceinline(start,end,repl) + call setpos('.',[0,line('.'),start+offset,0]) + silent! call repeat#set("\<Plug>SpeedDating" . (a:increment < 0 ? "Down" : "Up"),a:increment < 0 ? -a:increment : a:increment) + return + endif + endif + endfor + if a:increment > 0 + exe "norm! ". a:increment."\<C-A>" + else + exe "norm! ".-a:increment."\<C-X>" + endif + silent! call repeat#set("\<Plug>SpeedDating" . (a:increment < 0 ? "Down" : "Up"),a:increment < 0 ? -a:increment : a:increment) +endfunction + +" }}}1 +" Visual Mode {{{1 + +function! s:setvirtcol(line,col) + call setpos('.',[0,a:line,a:col,0]) + while virtcol('.') < a:col + call setpos('.',[0,a:line,col('.')+1,0]) + endwhile + while virtcol('.') > a:col + call setpos('.',[0,a:line,col('.')-1,0]) + endwhile + return col('.') + getpos('.')[3] +endfunction + +function! s:chars(string) + return strlen(substitute(a:string,'.','.','g')) +endfunction + +function! s:incrementstring(string,offset,count) + let repl = "" + let offset = -1 + for handler in s:time_handlers + g:speeddating_handlers + s:visual_handlers + let pattern = type(handler.regexp) == type(function('tr')) ? handler.regexp() : handler.regexp + let [start,end,string;caps] = s:findatoffset(a:string,'\C'.pattern,a:offset) + if string != "" + let [repl,offset] = handler.increment(string,a:offset,a:count) + if repl != "" + break + endif + endif + endfor + if offset < 0 + let offset += strlen(repl) + 1 + endif + + if repl != "" + let before_text = strpart(a:string,0,start) + let change = s:chars(repl) - s:chars(string) + if change < 0 && before_text !~ '\w$' + let offset -= change + let repl = repeat(' ',-change) . repl + elseif change > 0 && before_text =~ ' $' + let before_text = substitute(before_text,' \{1,'.change.'\}$','','') + let before_text = substitute(before_text,'\w$','& ','') + let start = strlen(before_text) + endif + let offset += start + let repl = before_text.repl.strpart(a:string,end) + endif + return [repl,offset,start,end] +endfunction + +function! s:incrementvisual(count) + let ve = &ve + set virtualedit=all + exe "norm! gv\<Esc>" + let vcol = virtcol('.') + let lnum = line("'<") + let lastrepl = "" + call s:setvirtcol(lnum,vcol) + call setpos("'[",[0,line("'<"),1,0]) + while lnum <= line("'>") + call s:setvirtcol(lnum,vcol) + let [repl,offset,start,end] = s:incrementstring(getline('.'),col('.')-1,a:count) + if repl == "" && lastrepl != "" + call setpos(".",[0,lnum-1,laststart,0]) + let start = s:setvirtcol(lnum,virtcol('.')) + call setpos(".",[0,lnum-1,lastend,0]) + let end = s:setvirtcol(lnum,virtcol('.')) + call s:setvirtcol(lnum,vcol) + if strpart(getline('.'),start,end-start) =~ '^\s*$' + let before_padded = printf("%-".start."s",strpart(getline('.'),0,start)) + let tweaked_line = before_padded.strpart(lastrepl,laststart,lastend-laststart).strpart(getline('.'),end) + let [repl,offset,start,end] = s:incrementstring(tweaked_line,col('.')-1,a:count*(lnum-lastlnum)) + endif + elseif repl != "" + let [lastrepl,laststart,lastend,lastlnum] = [repl,start,end,lnum] + endif + if repl != "" + silent call setline('.',repl) + endif + let lnum += 1 + endwhile + let &ve = ve + call setpos("']",[0,line('.'),col('$'),0]) +endfunction + +" }}}1 +" Visual Mode Handlers {{{1 + +let s:visual_handlers = [] + +function! s:numberincrement(string,offset,increment) + let n = (a:string + a:increment) + if a:string =~# '^0x.*[A-F]' + return [printf("0x%X",n),-1] + elseif a:string =~# '^0x' + return [printf("0x%x",n),-1] + elseif a:string =~# '^00*[^0]' + return [printf("0%o",n),-1] + else + return [printf("%d",n),-1] + endif +endfunction + +let s:visual_handlers += [{'regexp': '-\=\<\%(0x\x\+\|\d\+\)\>', 'increment': s:function("s:numberincrement")}] + +function! s:letterincrement(string,offset,increment) + return [nr2char((char2nr(toupper(a:string)) - char2nr('A') + a:increment) % 26 + (a:string =~# '[A-Z]' ? char2nr('A') : char2nr('a'))),-1] +endfunction + +let s:visual_handlers += [{'regexp': '\<[A-Za-z]\>', 'increment': s:function("s:letterincrement")}] + +" }}}1 +" Ordinals {{{1 + +function! s:ordinalize(number) + let n = a:number + let a = n < 0 ? -n : +n + if a % 100 == 11 || a % 100 == 12 || a % 100 == 13 + return n."th" + elseif a % 10 == 1 + return n."st" + elseif a % 10 == 2 + return n."nd" + elseif a % 10 == 3 + return n."rd" + else + return n."th" + endif +endfunction + +function! s:ordinalincrement(string,offset,increment) + return [s:ordinalize(a:string+a:increment),-1] +endfunction + +let g:speeddating_handlers += [{'regexp': '-\=\<\d\+\%(st\|nd\|rd\|th\)\>', 'increment': s:function("s:ordinalincrement")}] + +" }}}1 +" Roman Numerals {{{1 + +" Based on similar functions from VisIncr.vim + +let s:a2r = [[1000, 'm'], [900, 'cm'], [500, 'd'], [400, 'cd'], [100, 'c'], + \ [90 , 'xc'], [50 , 'l'], [40 , 'xl'], [10 , 'x'], + \ [9 , 'ix'], [5 , 'v'], [4 , 'iv'], [1 , 'i']] + +function! s:roman2arabic(roman) + let roman = tolower(a:roman) + let sign = 1 + let arabic = 0 + while roman != '' + if roman =~ '^[-n]' + let sign = -sign + endif + for [numbers,letters] in s:a2r + if roman =~ '^'.letters + let arabic += sign * numbers + let roman = strpart(roman,strlen(letters)-1) + break + endif + endfor + let roman = strpart(roman,1) + endwhile + + return arabic +endfunction + +function! s:arabic2roman(arabic) + if a:arabic <= 0 + let arabic = -a:arabic + let roman = "n" + else + let arabic = a:arabic + let roman = "" + endif + for [numbers, letters] in s:a2r + let roman .= repeat(letters,arabic/numbers) + let arabic = arabic % numbers + endfor + return roman +endfunction + +" }}}1 +" Time Helpers {{{1 + +function! s:ary2pat(array) + return '\%('.join(a:array,'\|').'\)' + return '\%('.join(map(copy(a:array),'substitute(v:val,"[[:alpha:]]","[\\u&\\l&]","g")'),'\|').'\)' +endfunction + +function! s:initializetime(time) + call extend(a:time,{'y': '','b':1,'d':0,'h':0,'m':0,'s':0,'o':0},"keep") + if get(a:time,'b','') !~ '^\d*$' + let full = index(s:months_full ,a:time.b,0,1) + 1 + let engl = index(s:months_engl ,a:time.b,0,1) + 1 + let abbr = index(s:months_abbr ,a:time.b,0,1) + 1 + if full + let a:time.b = full + elseif engl + let a:time.b = engl + elseif abbr + let a:time.b = abbr + else + let a:time.b = 1 + endif + endif + if has_key(a:time,'p') + let a:time.h = a:time.h % 12 + if a:time.p ==? "PM" + let a:time.h += 12 + endif + call remove(a:time,"p") + endif + if a:time.y !~ '^\d*$' + let a:time.y = s:roman2arabic(a:time.y) + elseif a:time.y =~ '^-\=0..' + let a:time.y = substitute(a:time.y,'0\+','','') + elseif a:time.y < 38 && a:time.y >= 0 && ''.a:time.y != '' + let a:time.y += 2000 + elseif a:time.y < 100 && a:time.y >= 38 + let a:time.y += 1900 + endif + if has_key(a:time,'w') + let full = index(s:days_full,a:time.w,0,1) + let engl = index(s:days_engl,a:time.w,0,1) + let abbr = index(s:days_abbr,a:time.w,0,1) + let a:time.w = full > 0 ? full : (engl > 0 ? engl : (abbr > 0 ? abbr : a:time.w)) + if a:time.d == 0 + let a:time.d = s:mod(a:time.w - s:jd(a:time.y,a:time.b,1),7) + elseif a:time.y == '' && a:time.b * a:time.d > 0 + let a:time.y = strftime("%Y")-2 + while s:mod(s:jd(a:time.y,a:time.b,a:time.d)+1,7) != a:time.w + let a:time.y += 1 + endwhile + endif + call remove(a:time,'w') + endif + if a:time.d == 0 + let a:time.d = 1 + endif + if ''.a:time.y == '' + let a:time.y = 2000 + endif + if a:time.o =~ '^[+-]\d\d:\=\d\d$' + let a:time.o = (a:time.o[0]=="-" ? -1 : 1)*(a:time.o[1:2]*60+matchstr(a:time.o,'\d\d$')) + elseif get(a:time,'z','') == g:speeddating_zone + let a:time.o = s:offset + elseif get(a:time,'z','') == g:speeddating_zone_dst + let a:time.o = s:offset_dst + endif + return a:time +endfunction + +" Julian day (always Gregorian calendar) +function! s:jd(year,mon,day) + let y = a:year + 4800 - (a:mon <= 2) + let m = a:mon + (a:mon <= 2 ? 9 : -3) + let jul = a:day + (153*m+2)/5 + s:div(1461*y,4) - 32083 + return jul - s:div(y,100) + s:div(y,400) + 38 +endfunction + +function! s:gregorian(jd) + let l = a:jd + 68569 + let n = s:div(4 * l, 146097) + let l = l - s:div(146097 * n + 3, 4) + let i = ( 4000 * ( l + 1 ) ) / 1461001 + let l = l - ( 1461 * i ) / 4 + 31 + let j = ( 80 * l ) / 2447 + let d = l - ( 2447 * j ) / 80 + let l = j / 11 + let m = j + 2 - ( 12 * l ) + let y = 100 * ( n - 49 ) + i + l + return {'y':y,'b':m,'d':d} +endfunction + +function! s:normalizetime(time) + let a:time.y += s:div(a:time.b-1,12) + let a:time.b = s:mod(a:time.b-1,12)+1 + let seconds = a:time.h * 3600 + a:time.m * 60 + a:time.s + let a:time.s = s:mod(seconds,60) + let a:time.m = s:mod(s:div(seconds,60),60) + let a:time.h = s:mod(s:div(seconds,3600),24) + if seconds != 0 || a:time.b != 1 || a:time.d != 1 + let day = s:gregorian(s:jd(a:time.y,a:time.b,a:time.d)+s:div(seconds,86400)) + return extend(a:time,day) + else + return a:time + endif +endfunction + +function! s:applymodifer(number,modifier,width) + if a:modifier == '-' + return substitute(a:number,'^0*','','') + elseif a:modifier == '_' + return printf('%'.a:width.'d',a:number) + elseif a:modifier == '^' + return toupper(a:number) + else + return printf('%0'.a:width.'s',a:number) + endif +endfunction + +function! s:modyear(y) + return printf('%02d',s:mod(a:y,100)) +endfunction + +function! s:strftime(pattern,time) + if type(a:time) == type({}) + let time = s:normalizetime(copy(a:time)) + else + let time = s:normalizetime(s:initializetime({'y':1970,'s':a:time})) + endif + let time.w = s:mod(s:jd(time.y,time.b,time.d)+1,7) + let time.p = time.h + let expanded = "" + let remaining = a:pattern + while remaining != "" + if remaining =~ '^%' + let modifier = matchstr(remaining,'%\zs[-_0^]\=\ze.') + let specifier = matchstr(remaining,'%[-_0^]\=\zs.') + let remaining = matchstr(remaining,'%[-_0^]\=.\zs.*') + if specifier == '%' + let expanded .= '%' + elseif has_key(s:strftime_items,specifier) + let item = s:strftime_items[specifier] + let number = time[item[1]] + if type(item[4]) == type([]) + let expanded .= s:applymodifer(item[4][number % len(item[4])],modifier,1) + elseif type(item[4]) == type(function('tr')) + let expanded .= s:applymodifer(call(item[4],[number]),modifier,1) + else + let expanded .= s:applymodifer(number,modifier,item[4]) + endif + else + let expanded .= '%'.modifier.specifier + endif + else + let expanded .= matchstr(remaining,'[^%]*') + let remaining = matchstr(remaining,'[^%]*\zs.*') + endif + endwhile + return expanded +endfunction + +function! s:localtime(...) + let ts = a:0 ? a:1 : localtime() + let time = { + \ 'y': +strftime('%Y',ts), + \ 'b': +strftime('%m',ts), + \ 'd': +strftime('%d',ts), + \ 'h': +strftime('%H',ts), + \ 'm': +strftime('%M',ts), + \ 's': +strftime('%S',ts)} + let jd = s:jd(time.y,time.b,time.d) - s:jd(1970,1,1) + let real_ts = jd * 86400 + time.h * 3600 + time.m * 60 + time.s + let time.o = (real_ts - ts) / 60 + return time +endfunction + +function! s:formattz(offset) + if a:offset < 0 + let offset = -a:offset + let sign = "-" + else + let offset = a:offset + let sign = "+" + endif + return printf("%s%02d%02d",sign,offset/60,offset%60) +endfunction + +" }}}1 +" Time Data {{{1 + +let s:offset = s:localtime(( 0+30*365)*86400).o +if !exists("g:speeddating_zone") + let g:speeddating_zone = strftime("%Z",30*365*86400) + if g:speeddating_zone == "" + let g:speeddating_zone = get({-8:'PST',-7:'MST',-6:'CST',-5:'EST',0:'WET',1:'CET',2:'EET'},s:offset/60,"XST") + endif +endif + +let s:offset_dst = s:localtime((180+30*365)*86400).o +if !exists("g:speeddating_zone_dst") + let g:speeddating_zone_dst = strftime("%Z",(180+30*365)*86400) + if g:speeddating_zone_dst == "" + if s:offset == s:offset_dst + let g:speeddating_zone_dst = g:speeddating_zone + else + let g:speeddating_zone_dst = get({-7:'PDT',-6:'MDT',-5:'CDT',-4:'EDT',1:'WEST',2:'CEST',3:'EEST'},s:offset_dst/60,"XDT") + endif + endif +endif + +let s:days_engl =["Sun","Mon","Tue","Wed","Thu","Fri","Sat"] +let s:days_abbr =map(range(86400*3+43200-s:offset*60,86400*12,86400),'strftime("%a",v:val)')[0:6] +let s:days_full =map(range(86400*3+43200-s:offset*60,86400*12,86400),'strftime("%A",v:val)')[0:6] + +let s:months_engl =["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"] +let s:months_abbr =map(range(86400*2,86400*365,86400*31),'strftime("%b",v:val)') +let s:months_full =map(range(86400*2,86400*365,86400*31),'strftime("%B",v:val)') + +let s:strftime_items = { + \ "a": ['d','w',s:ary2pat(s:days_abbr), 'weekday (abbreviation)',s:days_abbr], + \ "A": ['d','w',s:ary2pat(s:days_full), 'weekday (full name)',s:days_full], + \ "i": ['d','w',s:ary2pat(s:days_engl), 'weekday (English abbr)',s:days_engl], + \ "b": ['b','b',s:ary2pat(s:months_abbr), 'month (abbreviation)',[""]+s:months_abbr], + \ "B": ['b','b',s:ary2pat(s:months_full), 'month (full name)',[""]+s:months_full], + \ "h": ['b','b',s:ary2pat(s:months_engl), 'month (English abbr)',[""]+s:months_engl], + \ "d": ['d','d','[ 0-3]\=\d', 'day (01-31)',2], + \ "H": ['h','h','[ 0-2]\=\d', 'hour (00-23)',2], + \ "I": ['h','h','[ 0-2]\=\d', 'hour (01-12)',['12', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11']], + \ "m": ['b','b','[ 0-1]\=\d', 'month (01-12)',2], + \ "M": ['m','m','[ 0-5]\=\d', 'minutes',2], + \ "o": ['d','d','[ 0-3]\=\d\%(st\|nd\|rd\|th\)','day (1st-31st)',s:function("s:ordinalize")], + \ "P": ['h','p','[ap]m', 'am/pm',repeat(['am'],12) + repeat(['pm'],12)], + \ "S": ['s','s','[ 0-5]\=\d', 'seconds',2], + \ "v": ['y','y','[ivxlcdmn]\+','year (roman numerals)',s:function("s:arabic2roman")], + \ "y": ['y','y','\d\d','year (00-99)',s:function("s:modyear")], + \ "Y": ['y','y','-\=\d\d\d\=\d\=','year',4], + \ "z": ['o','o','[+-]\d\d\d\d','timezone offset',s:function("s:formattz")], + \ "Z": [' ','z','[A-Z]\{3,5}','timezone (incomplete)',3]} + +" }}}1 +" Time Handler {{{1 + +function! s:timestamp(utc,count) + for handler in s:time_handlers + let [start,end,string;caps] = s:findinline('\C'.join(handler.groups,'')) + if string != "" + let format = substitute(handler.strftime,'\\\([1-9]\)','\=caps[submatch(1)-1]','g') + if a:utc || a:count + let offset = (a:utc ? 1 : -1) * a:count * 15 + let time = s:initializetime({'y':1970,'s':localtime()+offset*60,'o':offset}) + else + let time = s:localtime() + endif + if a:utc && !a:count + let time.z = 'UTC' + elseif time.o == s:offset + let time.z = g:speeddating_zone + elseif time.o == s:offset_dst + let time.z = g:speeddating_zone_dst + elseif time.o == 0 + let time.z = 'UTC' + else + let time.z = 'XXT' + endif + let newstring = s:strftime(format,time) + call s:replaceinline(start,end,newstring) + call setpos('.',[0,line('.'),start+strlen(newstring),0]) + silent! call repeat#set("\<Plug>SpeedDatingNow".(a:utc ? "UTC" : "Local"),a:count) + return "" + endif + endfor + let [start,end,string;caps] = s:findinline('-\=\<\d\+\>') + if string != "" + let newstring = localtime() + (a:utc ? 1 : -1) * a:count * 60*15 + call s:replaceinline(start,end,newstring) + call setpos('.',[0,line('.'),start+strlen(newstring),0]) + silent! call repeat#set("\<Plug>SpeedDatingNow".(a:utc ? "UTC" : "Local"),a:count) + endif +endfunction + +function! s:dateincrement(string,offset,increment) dict + let [start,end,string;caps] = s:match(a:string,'\C'.join(self.groups,'')) + let string = a:string + let offset = a:offset + let cursor_capture = 1 + let idx = 0 + while idx < len(self.groups) + let partial_matchend = matchend(string,join(self.groups[0:idx],'')) + if partial_matchend > offset + break + endif + let idx += 1 + endwhile + while get(self.targets,idx,"") == " " + let idx += 1 + endwhile + while get(self.targets,idx," ") == " " + let idx -= 1 + endwhile + let partial_pattern = join(self.groups[0:idx],'') + let char = self.targets[idx] + let i = 0 + let time = {} + for cap in caps + if get(self.reader,i," ") !~ '^\s\=$' + let time[self.reader[i]] = substitute(cap,'^\s*','','') + endif + let i += 1 + endfor + call s:initializetime(time) + let inner_offset = 0 + if char == 'o' + let inner_offset = partial_matchend - offset - 1 + let factor = 15 + if inner_offset <= 0 + let inner_offset = 0 + let factor = 1 + elseif inner_offset > 1 + let factor = 60 + let inner_offset = 2 + endif + let time.o += factor * a:increment + let time.m += factor * a:increment + elseif char == 'b' + let time.b += a:increment + let goal = time.y*12 + time.b + call s:normalizetime(time) + while time.y*12 + time.b > goal + let time.d -= 1 + call s:normalizetime(time) + endwhile + else + let time[char] += a:increment + endif + let format = substitute(self.strftime,'\\\([1-9]\)','\=caps[submatch(1)-1]','g') + let time_string = s:strftime(format,time) + return [time_string, matchend(time_string,partial_pattern)-inner_offset] +endfunction + +function! s:timeregexp() dict + return join(self.groups,'') +endfunction + +function! s:createtimehandler(format) + let pattern = '^\%(%?\=\[.\{-\}\]\|%[-_0^]\=.\|[^%]*\)' + let regexp = ['\%(\<\|-\@=\)'] + let reader = [] + let targets = [' '] + let template = "" + let default = "" + let remaining = substitute(a:format,'\C%\@<!%p','%^P','g') + let group = 0 + let usergroups = [] + let userdefaults = [] + while remaining != "" + let fragment = matchstr(remaining,pattern) + let remaining = matchstr(remaining,pattern.'\zs.*') + if fragment =~ '^%\*\W' + let suffix = '*' + let fragment = '%' . strpart(fragment,2) + elseif fragment =~ '^%?\W' + let suffix = '\=' + let fragment = '%' . strpart(fragment,2) + else + let suffix = '' + endif + let targets += [' '] + if fragment =~ '^%' && has_key(s:strftime_items,matchstr(fragment,'.$')) + let item = s:strftime_items[matchstr(fragment,'.$')] + let modifier = matchstr(fragment,'^%\zs.\ze.$') + let targets[-1] = item[0] + let reader += [item[1]] + if modifier == '^' + let pat = substitute(item[2],'\C\\\@<![[:lower:]]','\u&','g') + elseif modifier == '0' + let pat = substitute(item[2],' \|-\@<!\\=','','g') + else + let pat = item[2] + endif + let regexp += ['\('.pat.'\)'] + let group += 1 + let template .= fragment + let default .= fragment + elseif fragment =~ '^%\[.*\]$' + let reader += [' '] + let regexp += ['\('.matchstr(fragment,'\[.*').suffix.'\)'] + let group += 1 + let usergroups += [group] + let template .= "\\".group + if suffix == "" + let default .= strpart(fragment,2,1) + let userdefaults += [strpart(fragment,2,1)] + else + let userdefaults += [""] + endif + elseif fragment =~ '^%\d' + let regexp += ["\\".usergroups[strpart(fragment,1)-1]] + let template .= regexp[-1] + let default .= userdefaults[strpart(fragment,1)-1] + elseif fragment == '%*' + if len(regexp) == 1 + let regexp = [] + let targets = [] + else + let regexp += ['\(.*\)'] + endif + else + let regexp += [escape(fragment,'.*^$[\]~')] + let template .= fragment + let default .= fragment + endif + endwhile + if regexp[-1] == '\(.*\)' + call remove(regexp,-1) + call remove(targets,-1) + else + let regexp += ['\>'] + endif + return {'source': a:format, 'strftime': template, 'groups': regexp, 'regexp': s:function('s:timeregexp'), 'reader': reader, 'targets': targets, 'default': default, 'increment': s:function('s:dateincrement')} +endfunction + +function! s:comparecase(i1, i2) + if a:i1 ==? a:i2 + return a:i1 ==# a:i2 ? 0 : a:i1 ># a:i2 ? 1 : -1 + else + return tolower(a:i1) > tolower(a:i2) ? 1 : -1 + endif +endfunction + +function! s:adddate(master,count,bang) + if a:master == "" + let time = s:initializetime({'y':1970,'s':localtime(),'z': 'UTC'}) + if a:bang && a:count + silent! call remove(s:time_handlers,a:count - 1) + elseif a:bang + echo "SpeedDatingFormat List defined formats" + echo "SpeedDatingFormat! This help" + echo "SpeedDatingFormat %Y-%m-%d Add a format" + echo "1SpeedDatingFormat %Y-%m-%d Add a format before first format" + echo "SpeedDatingFormat! %Y-%m-%d Remove a format" + echo "1SpeedDatingFormat! Remove first format" + echo " " + echo "Expansions:" + for key in sort(keys(s:strftime_items),s:function("s:comparecase")) + echo printf("%2s %-25s %s",'%'.key,s:strftime_items[key][3],s:strftime('%'.key,time)) + endfor + echo '%0x %x with mandatory leading zeros' + echo '%_x %x with spaces rather than leading zeros' + echo '%-x %x with no leading spaces or zeros' + echo '%^x %x in uppercase' + echo '%* at beginning/end, surpress \</\> respectively' + echo '%[..] any one character \([..]\)' + echo '%?[..] up to one character \([..]\=\)' + echo '%1 character from first collection match \1' + echo " " + echo "Examples:" + echo 'SpeedDatingFormat %m%[/-]%d%1%Y " American 12/25/2007' + echo 'SpeedDatingFormat %d%[/-]%m%1%Y " European 25/12/2007' + echo " " + echo "Define formats in ".s:install_dir."/after/plugin/speeddating.vim" + elseif a:count + echo get(s:time_handlers,a:count-1,{'source':''}).source + else + let i = 0 + for handler in s:time_handlers + let i += 1 + echo printf("%3d %-32s %-32s",i,handler.source,s:strftime(handler.default,time)) + endfor + endif + elseif a:bang + call filter(s:time_handlers,'v:val.source != a:master') + else + let handler = s:createtimehandler(a:master) + if a:count + call insert(s:time_handlers,handler,a:count - 1) + else + let s:time_handlers += [handler] + endif + endif +endfunction + +let s:time_handlers = [] + +command! -bar -bang -count=0 -nargs=? SpeedDatingFormat :call s:adddate(<q-args>,<count>,<bang>0) + +" }}}1 +" Default Formats {{{1 + +SpeedDatingFormat %i, %d %h %Y %H:%M:%S %z " RFC822 +SpeedDatingFormat %i, %h %d, %Y at %I:%M:%S%^P %z " mutt default date format +SpeedDatingFormat %a %b %_d %H:%M:%S %Z %Y " default date(1) format +SpeedDatingFormat %a %h %-d %H:%M:%S %Y %z " git +SpeedDatingFormat %h %_d %H:%M:%S " syslog +SpeedDatingFormat %Y-%m-%d%[ T_-]%H:%M:%S %z +SpeedDatingFormat %Y-%m-%d%[ T_-]%H:%M:%S%?[Z] " SQL, etc. +SpeedDatingFormat %Y-%m-%d +SpeedDatingFormat %-I:%M:%S%?[ ]%^P +SpeedDatingFormat %-I:%M%?[ ]%^P +SpeedDatingFormat %-I%?[ ]%^P +SpeedDatingFormat %H:%M:%S +SpeedDatingFormat %B %o, %Y +SpeedDatingFormat %d%[-/ ]%b%1%y +SpeedDatingFormat %d%[-/ ]%b%1%Y " These three are common in the +SpeedDatingFormat %Y %b %d " 'Last Change:' headers of +SpeedDatingFormat %b %d, %Y " Vim runtime files +SpeedDatingFormat %^v +SpeedDatingFormat %v + +" }}}1 +" Maps {{{1 + +nnoremap <silent> <Plug>SpeedDatingUp :<C-U>call <SID>increment(v:count1)<CR> +nnoremap <silent> <Plug>SpeedDatingDown :<C-U>call <SID>increment(-v:count1)<CR> +vnoremap <silent> <Plug>SpeedDatingUp :<C-U>call <SID>incrementvisual(v:count1)<CR> +vnoremap <silent> <Plug>SpeedDatingDown :<C-U>call <SID>incrementvisual(-v:count1)<CR> +nnoremap <silent> <Plug>SpeedDatingNowLocal :<C-U>call <SID>timestamp(0,v:count)<CR> +nnoremap <silent> <Plug>SpeedDatingNowUTC :<C-U>call <SID>timestamp(1,v:count)<CR> + +if !exists("g:speeddating_no_mappings") || !g:speeddating_no_mappings + nmap <C-A> <Plug>SpeedDatingUp + nmap <C-X> <Plug>SpeedDatingDown + xmap <C-A> <Plug>SpeedDatingUp + xmap <C-X> <Plug>SpeedDatingDown + nmap d<C-A> <Plug>SpeedDatingNowUTC + nmap d<C-X> <Plug>SpeedDatingNowLocal +endif + +" }}}1 + +let &cpo = s:cpo_save + +" vim:set et sw=4 sts=4: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-12-06 08:14:51
|
Revision: 1728 http://assorted.svn.sourceforge.net/assorted/?rev=1728&view=rev Author: yangzhang Date: 2010-12-06 08:14:38 +0000 (Mon, 06 Dec 2010) Log Message: ----------- Added abolish.vim Added Paths: ----------- configs/trunk/src/vim/doc/abolish.txt configs/trunk/src/vim/plugin/abolish.vim Added: configs/trunk/src/vim/doc/abolish.txt =================================================================== --- configs/trunk/src/vim/doc/abolish.txt (rev 0) +++ configs/trunk/src/vim/doc/abolish.txt 2010-12-06 08:14:38 UTC (rev 1728) @@ -0,0 +1,162 @@ +*abolish.txt* Language friendly searches, substitutions, and abbreviations + +Author: Tim Pope <vim...@tp...> *abolish-author* +License: Same terms as Vim itself (see |license|) + +This plugin is only available if 'compatible' is not set. + +INTRODUCTION *abolish* *:Abolish* *:Subvert* + +Abolish lets you quickly find, substitute, and abbreviate several variations +of a word at once. By default, three case variants (foo, Foo, and FOO) are +operated on by every command. + +Two commands are provided. :Abolish is the most general interface. +:Subvert provides an alternative, more concise syntax for searching and +substituting. +> + :Abolish [options] {abbreviation} {replacement} + :Abolish -delete [options] {abbreviation} + + :Abolish -search [options] {pattern} + :Subvert/{pattern}[/flags] + :Abolish!-search [options] {pattern} + :Subvert?{pattern}[?flags] + + :Abolish -search [options] {pattern} {grep-arguments} + :Subvert /{pattern}/[flags] {grep-options} + :Abolish!-search [options] {pattern} {grep-arguments} + :Subvert!/{pattern}/[flags] {grep-options} + + :[range]Abolish -substitute [options] {pattern} {replacement} + :[range]Subvert/{pattern}/{replacement}[/flags] +< + *:S* +In addition to the :Subvert command, a :S synonym is provided if not +already defined. This will be used in examples below. + +PATTERNS *abolish-patterns* + +Patterns can include brace pairs that contain comma separated alternatives: + + box{,es} => box, boxes, Box, Boxes, BOX, BOXES + +For commands with a replacement, corresponding brace pairs are used in both +halves. If the replacement should be identical to the pattern, an empty +brace pair may be used. If fewer replacements are given than were given in +the pattern, they are looped. That is, {a,b} on the replacement side is the +same as {a,b,a,b,a,b,...} repeated indefinitely. + +The following replaces several different misspellings of "necessary": +> + :%S/{,un}nec{ce,ces,e}sar{y,ily}/{}nec{es}sar{}/g +< +ABBREVIATING *abolish-abbrev* + +By default :Abolish creates abbreviations, which replace words automatically +as you type. This is good for words you frequently misspell, or as +shortcuts for longer words. Since these are just Vim abbreviations, only +whole words will match. +> + :Abolish anomol{y,ies} anomal{} + :Abolish {,in}consistant{,ly} {}consistent{} + :Abolish Tqbf The quick, brown fox jumps over the lazy dog +< +Accepts the following options: + + -buffer: buffer local + -cmdline: work in command line in addition to insert mode + +A good place to define abbreviations is "after/plugin/abolish.vim", +relative to ~\vimfiles on Windows and ~/.vim everywhere else. + +With a bang (:Abolish!) the abbreviation is also appended to the file in +g:abolish_save_file. The default is "after/plugin/abolish.vim", relative +to the install directory. + +Abbreviations can be removed with :Abolish -delete: +> + Abolish -delete -buffer -cmdline anomol{y,ies} +< +SEARCHING *abolish-search* + +The -search command does a search in a manner similar to / key. +search. After searching, you can use |n| and |N| as you would with a normal +search. + +The following will search for box, Box, and BOX: +> + :Abolish -search box +< +When given a single word to operate on, :Subvert defaults to doing a +search as well: +> + :S/box/ +< +This one searches for box, boxes, boxed, boxing, Box, Boxes, Boxed, Boxing, +BOX, BOXES, BOXED, and BOXING: +> + :S/box{,es,ed,ing}/ +< +The following syntaxes search in reverse. +> + :Abolish! -search box + :S?box? +< +Flags can be given with the -flags= option to :Abolish, or by appending them +after the separator to :Subvert. The flags trigger the following behaviors: + + I: Disable case variations (box, Box, BOX) + v: Match inside variable names (match my_box, myBox, but not mybox) + w: Match whole words (like surrounding with \< and \>) + +A |search-offset| may follow the flags. +> + :Abolish -search -flags=avs+1 box + :S?box{,es,ed,ing}?we +< +GREPPING *abolish-grep* + +Grepping works similar to searching, and is invoked when additional options +are given. These options are passed directly to the :grep command. +> + :Abolish -search box{,es} + :S /box{,es}/ * + :S /box/aw *.txt *.html +< +The slash delimiters must both be present if used with :Subvert. They may +both be omitted if no flags are used. + +Both an external grepprg and vimgrep (via grepprg=internal) are supported. +With an external grep, the "v" flag behaves less intelligently, due to the +lack of look ahead and look behind support in grep regexps. + +SUBSTITUTING *abolish-substitute* + +Giving a range switches :Subvert into substitute mode. This command will +change box -> bag, boxes -> bags, Box -> Bag, Boxes -> Bags, BOX -> BAG, +BOXES -> BAGS across the entire document: +> + :%Abolish -substitute -flags=g box{,es} bag{,s} + :%S/box{,es}/bag{,s}/g +< +The "c", "e", "g", and "n" flags can be used from the substitute command +|:s_flags|, along with the "a", "I", "v", and "w" flags from searching. + +COERCION *abolish-coercion* *cr* + +Abolish's case mutating algorithms can be applied to the word under the cursor +using the cr mapping (mnemonic: CoeRce) followed by one of the following +characters: + + c: camelCase + m: MixedCase + _: snake_case + s: snake_case + u: SNAKE_UPPERCASE + -: dash-case (not reversible) + +For example, cru on a lowercase word is a slightly easier to type equivalent +to gUiw. + + vim:tw=78:ts=8:ft=help:norl: Added: configs/trunk/src/vim/plugin/abolish.vim =================================================================== --- configs/trunk/src/vim/plugin/abolish.vim (rev 0) +++ configs/trunk/src/vim/plugin/abolish.vim 2010-12-06 08:14:38 UTC (rev 1728) @@ -0,0 +1,613 @@ +" abolish.vim - Language friendly searches, substitutions, and abbreviations +" Maintainer: Tim Pope +" Version: 1.0 + +" Install this file as plugin/abolish.vim. See doc/abolish.txt for details. +" To access it from Vim, see :help add-local-help (hint: :helptags ~/.vim/doc) +" Afterwards, you should be able to do :help abolish + +" Initialization {{{1 + +" Exit quickly when: +" - this plugin was already loaded (or disabled) +" - when 'compatible' is set +" - Vim is older than 7.0 +if (exists("g:loaded_abolish") && g:loaded_abolish) || &cp || v:version < 700 + finish +endif +let g:loaded_abolish = 1 + +let s:cpo_save = &cpo +set cpo&vim + +if !exists("g:abolish_save_file") + if strpart(expand("<sfile>"),0,strlen(expand("~"))) == expand("~") + let g:abolish_save_file = expand("<sfile>:h:h")."/after/plugin/abolish.vim" + elseif isdirectory(expand("~/.vim")) + let g:abolish_save_file = expand("~/.vim/after/plugin/abolish.vim") + elseif isdirectory(expand("~/vimfiles")) || has("win32") + let g:abolish_save_file = expand("~/vimfiles/after/plugin/abolish.vim") + else + let g:abolish_save_file = expand("~/.vim/after/plugin/abolish.vim") + endif +endif + +" }}}1 +" Utility functions {{{1 + +function! s:function(name) + return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\d\+_'),'')) +endfunction + +function! s:send(self,func,...) + if type(a:func) == type('') || type(a:func) == type(0) + let Func = get(a:self,a:func,'') + else + let Func = a:func + endif + let s = type(a:self) == type({}) ? a:self : {} + if type(Func) == type(function('tr')) + return call(Func,a:000,s) + elseif type(Func) == type({}) && has_key(Func,'apply') + return call(Func.apply,a:000,Func) + elseif type(Func) == type({}) && has_key(Func,'call') + return call(Func.call,a:000,s) + elseif type(Func) == type('') && Func == '' && has_key(s,'function missing') + return call('s:send',[s,'function missing',a:func] + a:000) + else + return Func + endif +endfunction + +let s:object = {} +function! s:object.clone(...) + let sub = deepcopy(self) + return a:0 ? extend(sub,a:1) : sub +endfunction + +if !exists("g:Abolish") + let Abolish = {} +endif +call extend(Abolish, s:object, 'force') +call extend(Abolish, {'Coercions': {}}, 'keep') + +function! s:throw(msg) + let v:errmsg = a:msg + throw "Abolish: ".a:msg +endfunction + +function! s:words() + let words = [] + let lnum = line('w0') + while lnum <= line('w$') + let line = getline(lnum) + let col = 0 + while match(line,'\<\k\k\+\>',col) != -1 + let words += [matchstr(line,'\<\k\k\+\>',col)] + let col = matchend(line,'\<\k\k\+\>',col) + endwhile + let lnum += 1 + endwhile + return words +endfunction + +function! s:extractopts(list,opts) + let i = 0 + while i < len(a:list) + if a:list[i] =~ '^-[^=]' && has_key(a:opts,matchstr(a:list[i],'-\zs[^=]*')) + let key = matchstr(a:list[i],'-\zs[^=]*') + let value = matchstr(a:list[i],'=\zs.*') + if type(get(a:opts,key)) == type([]) + let a:opts[key] += [value] + elseif type(get(a:opts,key)) == type(0) + let a:opts[key] = 1 + else + let a:opts[key] = value + endif + else + let i += 1 + continue + endif + call remove(a:list,i) + endwhile + return a:opts +endfunction + +" }}}1 +" Dictionary creation {{{1 + +function! s:mixedcase(word) + return substitute(s:camelcase(a:word),'^.','\u&','') +endfunction + +function! s:camelcase(word) + if a:word !~# '_' && a:word =~# '\l' + return substitute(a:word,'^.','\l&','') + else + return substitute(a:word,'\C\(_\)\=\(.\)','\=submatch(1)==""?tolower(submatch(2)) : toupper(submatch(2))','g') + endif +endfunction + +function! s:snakecase(word) + let word = substitute(a:word,'::','/','g') + let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g') + let word = substitute(word,'\(\l\|\d\)\(\u\)','\1_\2','g') + let word = substitute(word,'-','_','g') + let word = tolower(word) + return word +endfunction + +function! s:uppercase(word) + return toupper(s:snakecase(a:word)) +endfunction + +function! s:dashcase(word) + return substitute(s:snakecase(a:word),'_','-','') +endfunction + +call extend(Abolish, { + \ 'camelcase': s:function('s:camelcase'), + \ 'mixedcase': s:function('s:mixedcase'), + \ 'snakecase': s:function('s:snakecase'), + \ 'uppercase': s:function('s:uppercase'), + \ 'dashcase': s:function('s:dashcase') + \ }, 'keep') + +function! s:create_dictionary(lhs,rhs,opts) + let dictionary = {} + let i = 0 + let expanded = s:expand_braces({a:lhs : a:rhs}) + for [lhs,rhs] in items(expanded) + if get(a:opts,'case',1) + let dictionary[s:mixedcase(lhs)] = s:mixedcase(rhs) + let dictionary[tolower(lhs)] = tolower(rhs) + let dictionary[toupper(lhs)] = toupper(rhs) + endif + let dictionary[lhs] = rhs + endfor + let i += 1 + return dictionary +endfunction + +function! s:expand_braces(dict) + let new_dict = {} + for [key,val] in items(a:dict) + if key =~ '{.*}' + let redo = 1 + let [all,kbefore,kmiddle,kafter;crap] = matchlist(key,'\(.\{-\}\){\(.\{-\}\)}\(.*\)') + let [all,vbefore,vmiddle,vafter;crap] = matchlist(val,'\(.\{-\}\){\(.\{-\}\)}\(.*\)') + ["","","",""] + if all == "" + let [vbefore,vmiddle,vafter] = [val, ",", ""] + endif + let targets = split(kmiddle,',',1) + let replacements = split(vmiddle,',',1) + if replacements == [""] + let replacements = targets + endif + for i in range(0,len(targets)-1) + let new_dict[kbefore.targets[i].kafter] = vbefore.replacements[i%len(replacements)].vafter + endfor + else + let new_dict[key] = val + endif + endfor + if exists("redo") + return s:expand_braces(new_dict) + else + return new_dict + " old_dict + endif +endfunction + +" }}}1 +" Abolish Dispatcher {{{1 + +function! s:SubComplete(A,L,P) + if a:A =~ '^[/?]\k\+$' + let char = strpart(a:A,0,1) + return join(map(s:words(),'char . v:val'),"\n") + elseif a:A =~# '^\k\+$' + return join(s:words(),"\n") + endif +endfunction + +function! s:Complete(A,L,P) + let g:L = a:L + " Vim bug: :Abolish -<Tab> calls this function with a:A equal to 0 + if a:A =~# '^[^/?-]' && type(a:A) != type(0) + return join(s:words(),"\n") + elseif a:L =~# '^\w\+\s\+\%(-\w*\)\=$' + return "-search\n-substitute\n-delete\n-buffer\n-cmdline\n" + elseif a:L =~# ' -\%(search\|substitute\)\>' + return "-flags=" + else + return "-buffer\n-cmdline" + endif +endfunction + +let s:commands = {} +let s:commands.abstract = s:object.clone() + +function! s:commands.abstract.dispatch(bang,line1,line2,count,args) + return self.clone().go(a:bang,a:line1,a:line2,a:count,a:args) +endfunction + +function! s:commands.abstract.go(bang,line1,line2,count,args) + let self.bang = a:bang + let self.line1 = a:line1 + let self.line2 = a:line2 + let self.count = a:count + return self.process(a:bang,a:line1,a:line2,a:count,a:args) +endfunction + +function! s:dispatcher(bang,line1,line2,count,args) + let i = 0 + let args = copy(a:args) + let command = s:commands.abbrev + while i < len(args) + if args[i] =~# '^-\w\+$' && has_key(s:commands,matchstr(args[i],'-\zs.*')) + let command = s:commands[matchstr(args[i],'-\zs.*')] + call remove(args,i) + break + endif + let i += 1 + endwhile + try + return command.dispatch(a:bang,a:line1,a:line2,a:count,args) + catch /^Abolish: / + echohl ErrorMsg + echo v:errmsg + echohl NONE + return "" + endtry +endfunction + +" }}}1 +" Subvert Dispatcher {{{1 + +function! s:subvert_dispatcher(bang,line1,line2,count,args) + try + return s:parse_subvert(a:bang,a:line1,a:line2,a:count,a:args) + catch /^Subvert: / + echohl ErrorMsg + echo v:errmsg + echohl NONE + return "" + endtry +endfunction + +function! s:parse_subvert(bang,line1,line2,count,args) + if a:args =~ '^\%(\w\|$\)' + let args = (a:bang ? "!" : "").a:args + else + let args = a:args + endif + let separator = matchstr(args,'^.') + let split = split(args,separator,1)[1:] + if a:count || split == [""] + return s:parse_substitute(a:bang,a:line1,a:line2,a:count,split) + elseif len(split) == 1 + return s:find_command(separator,"",split[0]) + elseif len(split) == 2 && split[1] =~# '^[A-Za-z]*n[A-Za-z]*$' + return s:parse_substitute(a:bang,a:line1,a:line2,a:count,[split[0],"",split[1]]) + elseif len(split) == 2 && split[1] =~# '^[A-Za-z]*\%([+-]\d\+\)\=$' + return s:find_command(separator,split[1],split[0]) + elseif len(split) >= 2 && split[1] =~# '^[A-Za-z]* ' + let flags = matchstr(split[1],'^[A-Za-z]*') + let rest = matchstr(join(split[1:],separator),' \zs.*') + return s:grep_command(rest,a:bang,flags,split[0]) + elseif len(split) >= 2 && separator == ' ' + return s:grep_command(join(split[1:],' '),a:bang,"",split[0]) + else + return s:parse_substitute(a:bang,a:line1,a:line2,a:count,split) + endif +endfunction + +function! s:normalize_options(flags) + if type(a:flags) == type({}) + let opts = a:flags + let flags = get(a:flags,"flags","") + else + let opts = {} + let flags = a:flags + endif + let g:op1 = copy(opts) + if flags =~# 'w' + let opts.boundaries = 2 + elseif flags =~# 'v' + let opts.boundaries = 1 + elseif !has_key(opts,'boundaries') + let opts.boundaries = 0 + endif + let opts.case = (flags !~# 'I' ? get(opts,'case',1) : 0) + let opts.flags = substitute(flags,'\C[avIiw]','','g') + let g:op2 = copy(opts) + return opts +endfunction + +" }}}1 +" Searching {{{1 + +function! s:subesc(pattern) + return substitute(a:pattern,'[][\\/.*~]','\\&','g') +endfunction + +function! s:sort(a,b) + if a:a ==? a:b + return a:a == a:b ? 0 : a:a > a:b ? 1 : -1 + elseif strlen(a:a) == strlen(a:b) + return a:a >? a:b ? 1 : -1 + else + return strlen(a:a) < strlen(a:b) ? 1 : -1 + endif +endfunction + +function! s:pattern(dict,boundaries) + if a:boundaries == 2 + let a = '<' + let b = '>' + elseif a:boundaries + let a = '%(<|_@<=|[[:lower:]]@<=[[:upper:]]@=)' + let b = '%(>|_@=|[[:lower:]]@<=[[:upper:]]@=)' + else + let a = '' + let b = '' + endif + return '\v\C'.a.'%('.join(map(sort(keys(a:dict),function('s:sort')),'s:subesc(v:val)'),'|').')'.b +endfunction + +function! s:egrep_pattern(dict,boundaries) + if a:boundaries == 2 + let a = '\<' + let b = '\>' + elseif a:boundaries + let a = '(\<\|_)' + let b = '(\>\|_\|[[:upper:]][[:lower:]])' + else + let a = '' + let b = '' + endif + return a.'('.join(map(sort(keys(a:dict),function('s:sort')),'s:subesc(v:val)'),'\|').')'.b +endfunction + +function! s:c() + call histdel('search',-1) + return "" +endfunction + +function! s:find_command(cmd,flags,word) + let opts = s:normalize_options(a:flags) + let dict = s:create_dictionary(a:word,"",opts) + " This is tricky. If we use :/pattern, the search drops us at the + " beginning of the line, and we can't use position flags (e.g., /foo/e). + " If we use :norm /pattern, we leave ourselves vulnerable to "press enter" + " prompts (even with :silent). + let cmd = (a:cmd =~ '[?!]' ? '?' : '/') + let @/ = s:pattern(dict,opts.boundaries) + if opts.flags == "" || !search(@/,'n') + return "norm! ".cmd."\<CR>" + elseif opts.flags =~ ';[/?]\@!' + call s:throw("E386: Expected '?' or '/' after ';'") + else + return "exe 'norm! ".cmd.cmd.opts.flags."\<CR>'|call histdel('search',-1)" + return "" + endif +endfunction + +function! s:grep_command(args,bang,flags,word) + let opts = s:normalize_options(a:flags) + let dict = s:create_dictionary(a:word,"",opts) + if &grepprg == "internal" + let lhs = "'".s:pattern(dict,opts.boundaries)."'" + else + let lhs = "-E '".s:egrep_pattern(dict,opts.boundaries)."'" + endif + return "grep".(a:bang ? "!" : "")." ".lhs." ".a:args +endfunction + +let s:commands.search = s:commands.abstract.clone() +let s:commands.search.options = {"word": 0, "variable": 0, "flags": ""} + +function! s:commands.search.process(bang,line1,line2,count,args) + call s:extractopts(a:args,self.options) + if self.options.word + let self.options.flags .= "w" + elseif self.options.variable + let self.options.flags .= "v" + endif + let opts = s:normalize_options(self.options) + if len(a:args) > 1 + return s:grep_command(join(a:args[1:]," "),a:bang,opts,a:args[0]) + elseif len(a:args) == 1 + return s:find_command(a:bang ? "!" : " ",opts,a:args[0]) + else + call s:throw("E471: Argument required") + endif +endfunction + +" }}}1 +" Substitution {{{1 + +function! Abolished() + return get(g:abolish_last_dict,submatch(0),submatch(0)) +endfunction + +function! s:substitute_command(cmd,bad,good,flags) + let opts = s:normalize_options(a:flags) + let dict = s:create_dictionary(a:bad,a:good,opts) + let lhs = s:pattern(dict,opts.boundaries) + let g:abolish_last_dict = dict + return a:cmd.'/'.lhs.'/\=Abolished()'."/".opts.flags +endfunction + +function! s:parse_substitute(bang,line1,line2,count,args) + if get(a:args,0,'') =~ '^[/?'']' + let separator = matchstr(a:args[0],'^.') + let args = split(join(a:args,' '),separator,1) + call remove(args,0) + else + let args = a:args + endif + if len(args) < 2 + call s:throw("E471: Argument required") + elseif len(args) > 3 + call s:throw("E488: Trailing characters") + endif + let [bad,good,flags] = (args + [""])[0:2] + if a:count == 0 + let cmd = "substitute" + else + let cmd = a:line1.",".a:line2."substitute" + endif + return s:substitute_command(cmd,bad,good,flags) +endfunction + +let s:commands.substitute = s:commands.abstract.clone() +let s:commands.substitute.options = {"word": 0, "variable": 0, "flags": "g"} + +function! s:commands.substitute.process(bang,line1,line2,count,args) + call s:extractopts(a:args,self.options) + if self.options.word + let self.options.flags .= "w" + elseif self.options.variable + let self.options.flags .= "v" + endif + let opts = s:normalize_options(self.options) + if len(a:args) <= 1 + call s:throw("E471: Argument required") + else + let good = join(a:args[1:],"") + let cmd = a:bang ? "." : "%" + return s:substitute_command(cmd,a:args[0],good,self.options) + endif +endfunction + +" }}}1 +" Abbreviations {{{1 + +function! s:badgood(args) + let words = filter(copy(a:args),'v:val !~ "^-"') + call filter(a:args,'v:val =~ "^-"') + if empty(words) + call s:throw("E471: Argument required") + elseif !empty(a:args) + call s:throw("Unknown argument: ".a:args[0]) + endif + let [bad; words] = words + return [bad, join(words," ")] +endfunction + +function! s:abbreviate_from_dict(cmd,dict) + for [lhs,rhs] in items(a:dict) + exe a:cmd lhs rhs + endfor +endfunction + +let s:commands.abbrev = s:commands.abstract.clone() +let s:commands.abbrev.options = {"buffer":0,"cmdline":0,"delete":0} +function! s:commands.abbrev.process(bang,line1,line2,count,args) + call s:extractopts(a:args,self.options) + if self.options.delete + let cmd = "unabbrev" + let good = "" + else + let cmd = "noreabbrev" + endif + if !self.options.cmdline + let cmd = "i" . cmd + endif + if self.options.delete + let cmd = "silent! ".cmd + endif + if self.options.buffer + let cmd = cmd . " <buffer>" + endif + let [bad, good] = s:badgood(a:args) + if substitute(bad,'{.\{-\}.}','','g') !~ '^\k\+$' + call s:throw("E474: Invalid argument (not a keyword: ".string(bad).")") + endif + if !self.options.delete && good == "" + call s:throw("E471: Argument required".a:args[0]) + endif + let dict = s:create_dictionary(bad,good,self.options) + call s:abbreviate_from_dict(cmd,dict) + if a:bang + let i = 0 + let str = "Abolish ".join(a:000," ") + let file = g:abolish_save_file + call s:mkdir(fnamemodify(file,':h'),"p") + if filereadable(file) + let old = readfile(file) + else + let old = ["\" Exit if :Abolish isn't available.","if !exists(':Abolish')"," finish","endif",""] + endif + call writefile(old + [str],file) + endif + return "" +endfunction + +let s:commands.delete = s:commands.abbrev.clone() +let s:commands.delete.options.delete = 1 + +" }}}1 +" Maps {{{1 + +function! s:unknown_coercion(letter,word) + return a:word +endfunction + +call extend(Abolish.Coercions, { + \ 'c': Abolish.camelcase, + \ 'm': Abolish.mixedcase, + \ 's': Abolish.snakecase, + \ '_': Abolish.snakecase, + \ 'u': Abolish.uppercase, + \ '-': Abolish.dashcase, + \ "function missing": s:function("s:unknown_coercion") + \}, "keep") + +function! s:coerce(transformation) + let regbody = getreg('"') + let regtype = getregtype('"') + let c = v:count1 + while c > 0 + let c -= 1 + norm! yiw + let word = @@ + let @@ = s:send(g:Abolish.Coercions,a:transformation,word) + if !exists('begin') + let begin = getpos("'[") + endif + if word !=# @@ + let changed = 1 + norm! viwpw + else + norm! w + endif + endwhile + call setreg('"',regbody,regtype) + call setpos("'[",begin) + call setpos(".",begin) + if exists("changed") + silent! call repeat#set("\<Plug>Coerce".a:transformation) + endif +endfunction + +nnoremap <silent> <Plug>Coerce :<C-U>call <SID>coerce(nr2char(getchar()))<CR> + +" }}}1 + +nmap cr <Plug>Coerce + +command! -nargs=+ -bang -bar -range=0 -complete=custom,s:Complete Abolish + \ :exec s:dispatcher(<bang>0,<line1>,<line2>,<count>,[<f-args>]) +command! -nargs=1 -bang -bar -range=0 -complete=custom,s:SubComplete Subvert + \ :exec s:subvert_dispatcher(<bang>0,<line1>,<line2>,<count>,<q-args>) +if exists(':S') != 2 + command -nargs=1 -bang -bar -range=0 -complete=custom,s:SubComplete S + \ :exec s:subvert_dispatcher(<bang>0,<line1>,<line2>,<count>,<q-args>) +endif + +let &cpo = s:cpo_save + +" vim:set ft=vim ts=8 sw=4 sts=4: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |