- step 1: put the following into ~/.vim/fullscreen.vim
" vim fullscreen mode set background=dark set guifont=Monaco:h17 set guioptions=egmLtT set lines=40 columns=80 " `fullscreen` needs to go after `lines` etc set fuoptions= set fullscreen highlight clear highlight Normal guifg=#00a000 guibg=Black highlight NonText guifg=#002000 highlight Search guifg=Black guibg=#606000 gui=bold highlight Visual guifg=#404040 gui=bold highlight Cursor guifg=Black guibg=Green gui=bold highlight Special guifg=#004000 highlight Comment guifg=#008000 highlight StatusLine guifg=blue guibg=white highlight Statement guifg=#004000 gui=NONE highlight constant guifg=#005000 gui=NONE highlight preproc guifg=#005000 gui=NONE highlight Type gui=NONE
- step 2: add this line to your ~/.bashrc
alias fvim="mvim -S ~/.vim/fullscreen.vim"
- step 3: fire it up...
$ fvim README.txt
- step 4: focus!
Tuesday, November 10, 2009
write in the vim room?
Thursday, July 16, 2009
light serving needs
if you ever have the need to serve a few static pages — say munin output, for example — next to your elaborate "plone/zope behind haproxy behind nginx behind varnish" setup :), here's a quick way to run lighttpd via supervisor using buildout.
with a buildout.cfg like:
[buildout] parts = lighttpd lighttpdconf supervisor [lighttpd] recipe = zc.recipe.cmmi url = http://www.lighttpd.net/download/lighttpd-1.4.23.tar.gz [lighttpdconf] recipe = collective.recipe.template input = ${buildout:directory}/lighttpd.conf.in output = ${buildout:directory}/etc/lighttpd.conf directory = /var/www/munin port = 8080 [supervisor] recipe = collective.recipe.supervisor programs = 10 lighttpd ${buildout:directory}/parts/lighttpd/sbin/lighttpd [-D -f ${buildout:directory}/etc/lighttpd.conf]and a configuration template (saved as lighttpd.conf.in) like:
server.document-root = "${lighttpdconf:directory}" server.port = "${lighttpdconf:port}" server.tag ="lighttpd" index-file.names = ( "index.html" ) mimetype.assign = ( ".html" => "text/html", ".txt" => "text/plain", ".jpg" => "image/jpeg", ".png" => "image/png", ".css" => "text/css", ".js" => "text/javascript", ".xml" => "text/xml", ".pdf" => "application/pdf", )all you need to do is the following:
$ python bootstrap.py $ bin/buildout $ bin/supervisordafter which you can access the contents of /var/www/munin at http://localhost:8080/.
please refer to the lighttpd documentation if you need more than this rather minimal setup...
Tuesday, July 7, 2009
running out of varnish
if (req.url ~ "(/at_download/|@@download$|\.mp4$|\.mov$)") { pipe; }this works, but is rather crude, of course. you'll need to somehow catch & specify all potentially big content, making it likely to miss some. unfortunately though, varnish only allows to "pipe" from inside its vcl_recv, so it's not possible to check the actual size after fetching the object from the backend, for example...
Monday, April 20, 2009
zope batch undo
here's a quick tip for everyone tired of selecting dozens of checkboxes when trying to undo ZODB changes via the ZMI (or fighting with the batched display of the transactions). i mean, really there should be a "select all" button like in ZMI's folder listing, but until this has been done and released, here's a workaround...
first, and this is only needed once, of course, you bookmark the following javascript-snippet:
javascript:cbs=document.getElementsByName("transaction_info:list");for(n=0;n<cbs.length;++n){cbs[n].checked=true};then, when you're ready to undo things you get out of the frameset and select a rough number of transactions to undo using a direct link like:
http://localhost:8080/manage_UndoForm?PrincipiaUndoBatchSize:int=200and afterwards simply click your bookmark to select all checkboxes at once. perhaps you'll still need to unselect the last few or else adjust the number in the link and finally click "undo"...
Monday, January 26, 2009
flattened...
some time ago back at the plone performance sprint in copenhagen i was trying to help optimizing zope start-up time a little more after hannosch's impressive pre-sprint effort.
while profiling i found a recursive implementation of a "list flatten" function, which was called way too often. i figured this could be done better and wanted to see what approaches other people had used before. a blog post titled more on python flatten sounded promising, but the proposed best method somehow seemed overly complicated and longish to me. next thing of course the perfectionist in me crept up, and well, we were at a sprint after all, so why not have some fun? :)
while the first version worked for my use-case and decreased plone start-up time by about 0.2 seconds (which i thought was not too bad for a small change like that), it was a bit oversimplified in that it didn't consider some egde-case. that wasn't too hard to fix, though, and eventually i posted what i considered good enough as a comment in that blog post:
def flatten(l, ltypes=(list, tuple)): n = 0 for i in iter(l): if isinstance(i, ltypes): l[n:n+1] = [] n += 1 l[n:n] = list(i) return ljudging by the fact nobody ever replied to it, i guess its workings might have been not too obvious after all. but today, after someone else posted another version i checked back on the post finding that "this one whoops all of the others for speed, nesting level support and elegance!":
def flatten(l, ltypes=(list, tuple)): ltype = type(l) l = list(l) i = 0 while i < len(l): while isinstance(l[i], ltypes): if not l[i]: l.pop(i) i -= 1 break else: l[i:i + 1] = l[i] i += 1 return ltype(l)it was referring back to Mike C. Fletcher's BasicTypes library, hence dubbed "mr. fletcher's version" and even compared to ruby's built-in flatten method (implemented in C), almost living up to it.
i got curious and wanted to see how my version was doing in comparison, and surprisingly it it about 33% faster. and that's after i fixed it to be non-destructive with regard to the passed in list:
$ python flatter.py fletchers_flatten: 9.197 sec my_flatten: 5.934 sec comparison: 64.53 %and without wanting to brag too much, i still think my version is quite a bit slicker, too... ;)
anyway, here's the whole test script in case you want to run it yourself:
# mr. fletcher's version def fletchers_flatten(l, ltypes=(list, tuple)): ltype = type(l) l = list(l) i = 0 while i < len(l): while isinstance(l[i], ltypes): if not l[i]: l.pop(i) i -= 1 break else: l[i:i + 1] = l[i] i += 1 return ltype(l) # my approach... def my_flatten(l, ltypes=(list, tuple)): ltype = type(l) l = list(l) n = 0 for i in iter(l): if isinstance(i, ltypes): l[n:n+1] = [] n += 1 l[n:n] = list(i) return ltype(l) # set up a nested list a = [] for i in xrange(2000): a = [a, i] # make sure it works as advertised backup = a assert my_flatten([[]]) == [] assert my_flatten(a) == list(reversed(xrange(2000))) assert a == backup # benchmark from time import time now = time() for n in xrange(5000): a = fletchers_flatten(a) fletcher = time() - now now = time() for n in xrange(5000): a = my_flatten(a) my = time() - now print 'fletchers_flatten: %.3f sec' % fletcher print 'my_flatten: %.3f sec' % my print 'comparison: %.2f %%' % (my / fletcher * 100)
update:
MJ was right, of course. the fixed version reads like this...
def my_flatten(l, ltypes=(list, tuple)): ltype = type(l) l = list(l) n = 0 for i in iter(l): if isinstance(i, ltypes): l[n:n+1] = [] l[n+1:n+1] = list(i) n += 1 return ltype(l)
Thursday, January 22, 2009
please downgrade my buildout!
[buildout] extends = buildout.cfg [plone] recipe = plone.recipe.distros urls = http://launchpad.net/plone/2.5/2.5.5/+download/Plone-2.5.5.tar.gz nested-packages = Plone-2.5.5.tar.gz version-suffix-packages = Plone-2.5.5.tar.gz eggs = [zope2] url = http://www.zope.org/Products/Zope/2.9.8/Zope-2.9.8-final.tgz fake-zope-eggs = true [instance] products = ${buildout:directory}/products ${productdistros:location} ${plone:location}
Friday, January 9, 2009
what a git!
imagine you're offline, in a train or plane or cafe, and feel like getting some work done. you're starting to make changes and quickly realize you'd rather split things into several commits than just a single big one. however, you're working against a subversion repository and have — since you're offline — no way to commit things back right away or (conveniently) keep the patches separate. well, except perhaps for copying the whole directory for every single one and later merge/commit them one by one. not really worth the trouble... but git to the rescue!
even without a previously cloned svn repos it's quite easy to locally commit away and later replay your changes. here's a quick step-by-step howto:
- initialize an empty git repos, propbably best done in the top dir of your working tree:
$ git init
$ git add * $ git commit -m 'import'
$ vi ... # or emacs if you must ;) $ git commit -a
- format/export the patches you've made (the rev specifier ":/import.." translates to "between a commit starting with 'import' and head) to separate files:
$ git format-patch :/import..
this will output numbered files, one file per patch, like:0001-fix-1.patch 0002-fix-2.patch ...
- remove your temporary git repos (or move it out of the way):
$ rm -rf .git
$ git svn clone svn://svn-url
$ git am 00*.patch
$ git svn dcommit