dotfiles

configuration files for different softwares
git clone git://z3bra.org/dotfiles
Log | Files | Refs

commit 5089d103ed9727146af232f694d72ef3dcd701fb
Author: Willy Goiffon <w.goiffon@gmail.com>
Date:   Tue May 28 11:04:14 2013

first commit

Diffstat:
 .gitignore                                                  |   12 +-
 Xresources                                                  |  102 +-
 bashrc                                                      |  109 +-
 copy.sh                                                     |   49 +-
 cwmrc                                                       |  111 +-
 elinks/bookmarks                                            |    1 +-
 elinks/cookies                                              |    6 +-
 elinks/elinks.conf                                          |  255 +-
 elinks/formhist                                             |   49 +-
 elinks/globhist                                             |  186 +-
 elinks/gotohist                                             |   32 +-
 elinks/searchhist                                           |    3 +-
 evilwmrc                                                    |   13 +-
 irssi/default.theme                                         |  295 +-
 irssi/scripts/autorun/adv_windowlist.pl                     | 2478 ++++++++++++-
 mutt/.gitignore                                             |    7 +-
 mutt/binding                                                |   83 +-
 mutt/colors                                                 |   61 +-
 mutt/geek.signature                                         |    6 +-
 mutt/muttrc                                                 |  120 +-
 ncmpcpp/config                                              |  214 +-
 ncmpcpp/error.log                                           |    0
 rtorrent.rc                                                 |  108 +-
 screenrc                                                    |  116 +-
 tmux.conf                                                   |  165 +-
 vim/.netrwhist                                              |    3 +-
 vim/autoload/pathogen.vim                                   |  326 ++-
 vim/bundle/custom/colors/ambient.vim                        |   58 +-
 vim/bundle/custom/ftplugin/header.vim                       |   28 +-
 vim/bundle/custom/plugin/gpg.vim                            |   31 +-
 vim/bundle/matchit/.gitignore                               |    4 +-
 vim/bundle/matchit/doc/matchit.txt                          |  406 ++-
 vim/bundle/matchit/plugin/matchit.vim                       |  812 ++++-
 vim/bundle/snipmate/README.markdown                         |    5 +-
 vim/bundle/snipmate/after/plugin/snipMate.vim               |   40 +-
 vim/bundle/snipmate/autoload/snipMate.vim                   |  435 ++-
 vim/bundle/snipmate/doc/snipMate.txt                        |  322 ++-
 vim/bundle/snipmate/ftplugin/html_snip_helper.vim           |   10 +-
 vim/bundle/snipmate/plugin-info.txt                         |    8 +-
 vim/bundle/snipmate/plugin/snipMate.vim                     |  271 +-
 vim/bundle/snipmate/snippets/_.snippets                     |    9 +-
 vim/bundle/snipmate/snippets/autoit.snippets                |   66 +-
 vim/bundle/snipmate/snippets/c.snippets                     |  113 +-
 vim/bundle/snipmate/snippets/cpp.snippets                   |   34 +-
 vim/bundle/snipmate/snippets/erlang.snippets                |   39 +-
 vim/bundle/snipmate/snippets/html.snippets                  |  190 +-
 vim/bundle/snipmate/snippets/java.snippets                  |   95 +-
 vim/bundle/snipmate/snippets/javascript.snippets            |   74 +-
 vim/bundle/snipmate/snippets/mako.snippets                  |   54 +-
 vim/bundle/snipmate/snippets/objc.snippets                  |  247 +-
 vim/bundle/snipmate/snippets/perl.snippets                  |   97 +-
 vim/bundle/snipmate/snippets/php.snippets                   |  216 +-
 vim/bundle/snipmate/snippets/python.snippets                |   86 +-
 vim/bundle/snipmate/snippets/ruby.snippets                  |  504 ++-
 vim/bundle/snipmate/snippets/sh.snippets                    |   28 +-
 vim/bundle/snipmate/snippets/snippet.snippets               |    7 +-
 vim/bundle/snipmate/snippets/tcl.snippets                   |   92 +-
 vim/bundle/snipmate/snippets/tex.snippets                   |  115 +-
 vim/bundle/snipmate/snippets/vim.snippets                   |   32 +-
 vim/bundle/snipmate/snippets/zsh.snippets                   |   58 +-
 vim/bundle/snipmate/syntax/snippet.vim                      |   19 +-
 vim/bundle/tcomment/.gitignore                              |   10 +-
 vim/bundle/tcomment/CHANGES.TXT                             |  205 +-
 vim/bundle/tcomment/README                                  |  104 +-
 vim/bundle/tcomment/addon-info.json                         |    9 +-
 vim/bundle/tcomment/autoload/tcomment.vim                   | 1679 ++++++++-
 vim/bundle/tcomment/doc/tcomment.txt                        |  495 ++-
 vim/bundle/tcomment/plugin/tcomment.vim                     |  177 +-
 vim/bundle/tcomment/spec/tcomment/issue30.vim               |   12 +-
 vim/bundle/tcomment/spec/tcomment/issue30_sel=exclusive.vim |   14 +-
 vim/bundle/tcomment/spec/tcomment/issue30_sel=inclusive.vim |   11 +-
 vim/bundle/tcomment/spec/tcomment/issue30_test.c            |    4 +-
 vim/bundle/tcomment/spec/tcomment/issue30_test_1.c          |    6 +-
 vim/bundle/tcomment/spec/tcomment/issue30_test_2.c          |    4 +-
 vim/bundle/tcomment/spec/tcomment/issue30_test_3.c          |    4 +-
 vimrc                                                       |  382 ++-
 xbindkeysrc                                                 |   66 +-
 xinitrc                                                     |   48 +-
 zshrc                                                       |  155 +-
 79 files changed, 12900 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,12 @@ +# nothing interesting here... +irssi/config + +# mutt's uninteresting / personnal files +mutt/account +mutt/aliases +mutt/bored.signature +mutt/cache +mutt/hcache +mutt/mailcap +mutt/temp +mutt/.passwd.gpg diff --git a/Xresources b/Xresources @@ -0,0 +1,102 @@ +! =============== X.org default configurations ================= +! file: ~/.Xresources +! author: Willy Goiffon +! vim: set fenc=utf-8:nu:ai:si:et:ts=4:sw=4:ft=xdefaults: +! ============================================================== + +! Terminal colors ---------------------------------------------- +! DARK BACKGROUND +! *background:#1d1d16 +! *foreground:#ffffa2 +! *color0: #303030 +! *color8: #5F5F5F +! *color1: #c03000 +! *color9: #ff4400 +! *color2: #5f7f03 +! *color10: #aaff00 +! *color3: #ce8510 +! *color11: #ffff00 +! *color4: #327074 +! *color12: #44aadd +! *color5: #73446f +! *color13: #ff44bb +! *color6: #32a084 +! *color14: #4bffbe +! *color7: #baba77 +! *color15: #ffffa2 + +! LIGHT BACKGROUND +*background:#e8e9ca +*foreground:#443c28 +*color0: #101010 +*color8: #443c28 +*color1: #3f0f04 +*color9: #c03000 +*color2: #323e14 +*color10: #5f7f03 +*color3: #4f3103 +*color11: #ce8510 +*color4: #00212a +*color12: #327074 +*color5: #281130 +*color13: #73446f +*color6: #003f3f +*color14: #125b58 +*color7: #a28c64 +*color15: #e8e9ca + +! URxvt (rxvt-unicode) ----------------------------------------- + +URxvt*termName: rxvt-256color +URxvt*loginShell: false +URxvt*saveLines: 1024 +URxvt*geometry: 96x28 +URxvt*depth: 32 +URxvt*font: -misc-tamsyn-medium-*-*--14-101-*-*-*-*-* +URxvt*boldFont: -misc-tamsyn-medium-*-*--14-101-*-*-*-*-* +! URxvt*font: -gohu-gohufont-medium-*-*--11-80-*-*-*-*-iso8859-1 +! URxvt*boldFont: -gohu-gohufont-bold-*-*--11-80-*-*-*-*-iso8859-1 +! URxvt*letterSpace: -1 +URxvt*scrollBar: false +URxvt*cursorBlink: false +URxvt*cursorColor: #443c28 +URxvt*cursorColor2: #e8e9ca +URxvt*underlineColor: #999999 +URxvt*internalBorder: 4 +URxvt*perl-ext-common: default,clipboard,url-select,keyboard-select +URxvt.url-select.launcher: /usr/bin/dwb +URxvt.url-select.underline: true +URxvt.keysym.M-u: perl:url-select:select_next +URxvt.keysym.M-v: perl:keyboard-select:activate +URxvt.keysym.M-s: perl:keyboard-select:search + +! Colored man pages +URxvt.colorIT: #cacaca +URxvt.colorBD: #ae8510 +URxvt.colorUL: #a28c64 + + + + +! XTerm --------------------------------------------------------- + +xterm*scrollBar: false +xterm*faceName: gohu +xterm*faceSize: 8 +xterm*geometry: 64x2 +xterm*boldMode: false +xterm*cutNewline: false +xterm*on4Clicks: group +xterm*on5Clicks: page +xterm*internalBorder: 8 +xterm*metaSendsEscape: true +xterm*colorBD: #ffffff +xterm*colorBDMode: true +xterm*cursorBlink: false +xterm*cursorColor: #e8e9ca +xterm*veryBoldColors: 14 +xterm*loginShell: true +xterm*charClass: 33:48,35:48,37:48,43:48,45-47:48,64:48,95:48,126:48,35:48,58:48,63:48,61:48,44:48,38:48,59:48 +xterm*jumpScroll: true +xterm*multiScroll: true +xterm*saveLines: 512 diff --git a/bashrc b/bashrc @@ -0,0 +1,109 @@ +# +# ~/.bashrc +# + +# If not running interactively, don't do anything +[[ $- != *i* ]] && return + +[ -r /etc/bash_completion ] && . /etc/bash_completion + +# don't put duplicate lines in the history. See bash(1) for more options +# ... or force ignoredups and ignorespace +HISTCONTROL=ignoredups:ignorespace + +# colors +black=$(tput setaf 0) +red=$(tput setaf 1) +green=$(tput setaf 2) +yellow=$(tput setaf 3) +blue=$(tput setaf 4) +magenta=$(tput setaf 5) +cyan=$(tput setaf 6) +white=$(tput setaf 7) +bold=$(tput bold) +none=$(tput sgr0) + + +# set the command prompt +export PS1="\[$yellow\]\w \[$none\]\$ " + +# add folders to PATH +export PATH=$PATH:~/bin:. + +# use auto-completion after those words +complete -cf sudo +complete -cf man +complete -cf killall +complete -cf pkill + +# vim as default editor +export EDITOR='vim' + +# use vi-like CLI +set -o vi + + +## ALIASES ## + +## Terminal +alias q="exit" +alias quit="exit" +alias c="clear" +alias reload="source ~/.bashrc" + +# Add a 'proctection' on rm | mv | cp +alias rm='rm -i' +alias cp='cp -rvi' +alias mv='mv -i' + +# Alias to avoid some "RAAAAAAAAAH !!" +alias :q="quit" +alias cd..="cd .." +alias fuck='sudo $(fc -n -l -1)' + +# Make some output colorfull +alias ls='ls --color=auto' + +alias grep='grep --color=auto' +alias fgrep='fgrep --color=auto' +alias egrep='egrep --color=auto' + +# some more ls aliases +alias ll='ls -alhF --color=auto' +alias la='ls -A --color=auto' +alias l='ls -CF --color=auto' + +## Applications +export EDITOR="vim" +alias v="vim" +alias sv="sudo vim" + +alias vol="alsamixer" + +alias t='tmux attach' + +## Softwares +alias ssh='eval $(/usr/bin/keychain --eval --agents ssh -Q --quiet ~/.ssh/id_ecdsa) && ssh' + +# IRC client aliases to join networks +alias irc='irssi' + +## Functions +function start() { sudo systemctl start $@; } +function stop() { sudo systemctl stop $@; } +function restart() { sudo systemctl restart $@; } +function enable() { sudo systemctl enable $@; } +function disable() { sudo systemctl disable $@; } + +function thumbify() { + if [ -f $1 ]; then + cp $1 thumb-$1 + if [ $2 ]; then + mogrify -resize $2 thumb-$1 + else + mogrify -resize 250x250 thumb-$1 + fi + else + echo "Error: '$1' is not a valid file!" + fi +} diff --git a/copy.sh b/copy.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +TMPFILE=/tmp/dotfiles.list + +OK="[$(tput setaf 3)OK$(tput sgr0)]" +NOPE="[$(tput setaf 1)FAIL$(tput sgr0)]" + +cat <<EOF > $TMPFILE +## +## Here is an auto-generated file for linking +## config file to your $home directory +## +## The $0 script will read filenames from that +## file in order to create ONLY the links you +## want. +## +## The following list lists every. single. file +## or directory. Just remove the line that you +## don't want to be linked. +## Then, save that file, and watch the magic happen... +## +EOF + +echo "listing the whole directory" +ls $PWD >> $TMPFILE + +$EDITOR $TMPFILE + +echo "simulating..." +for f in $(grep -v '^#' $TMPFILE); do + echo "$f -> ~/.$f" +done + +echo "attempting to link config file to ~ ..." +read -p "Hit <Enter> to continue, <Ctrl-C> to abort..." +for f in $(grep -v '^#' $TMPFILE); do + ln -s $PWD/$f ~/.$f + if [ -L ~/.$f ] ; then + echo $OK -> $f + else + echo $NOPE -> $f + fi +done + +echo "removing temporary files" +rm $TMPFILE + +echo "finished." + diff --git a/cwmrc b/cwmrc @@ -0,0 +1,111 @@ +# Set default Xft(3) font +fontname "cure" + +# Turn on sticky-group mode +sticky yes + +# Any entry here is shown in the application menu +command term urxvt +command internet chromium +command qlprism "/home/willy/.quakelive/qlprism/qlprism.sh" + +# Ignore programs by that name by not drawing borders around them. +ignore bar +ignore wbar + +# automatic grouping for specific windows +autogroup 3 Dwb +autogroup 5 QLPrism + +# behavior, look & feel +borderwidth 8 +color activeborder "#666666" +color inactiveborder "#444444" +color font "#443c28" +color selfont "#e8e9ca" +color menubg "#e8e9ca" +color menufg "#443c28" +color groupborder "#2244ac" +color ungroupborder "#ac4422" + +gap 10 40 10 10 +moveamount 4 +snapdist 0 + +# Keybindings + # unbind + bind M-return unmap +# Windows control + # SIZE + bind 4-equal vmaximize + bind 4S-equal hmaximize + bind 4-x maximise + bind 4M-h resizeleft + bind 4M-j resizedown + bind 4M-k resizeup + bind 4M-l resizeright + bind 4MS-h bigresizeleft + bind 4MS-j bigresizedown + bind 4MS-k bigresizeup + bind 4MS-l bigresizeright + + # POSITION + bind 4-s htile + bind 4-v vtile + bind 4-h moveleft + bind 4-j movedown + bind 4-k moveup + bind 4-l moveright + bind 4S-h bigmoveleft + bind 4S-j bigmovedown + bind 4S-k bigmoveup + bind 4S-l bigmoveright + + # CONTROL + bind 4-a label + bind 4-Escape delete + bind 4-n cycle + bind 4-p rcycle + +# Group control +bind M-g grouptoggle +bind M-l cyclegroup +bind M-h rcyclegroup +bind M-F1 group1 +bind M-F2 group2 +bind M-F3 group3 +bind M-F4 group4 +bind M-F5 group5 +bind M-F6 group6 +bind M-F7 group7 +bind M-F8 group8 +bind M-F9 group9 +bind M-F10 nogroup +bind MS-F1 grouponly1 +bind MS-F2 grouponly2 +bind MS-F3 grouponly3 +bind MS-F4 grouponly4 +bind MS-F5 grouponly5 +bind MS-F6 grouponly6 +bind MS-F7 grouponly7 +bind MS-F8 grouponly8 +bind MS-F9 grouponly9 + +# Session management +bind CM-r restart +bind CM-q quit + + +# Applications +bind 4-Return terminal +bind 4-space terminal +bind 4-w dwb +bind 4-q 'sh -c ~/.quakelive/qlprism/qlprism.sh' +bind 4-exclam exec +bind 4-colon ssh +bind 4S-slash search + +# Mousebindings +mousebind M-1 window_move +mousebind M-2 window_grouptoggle +mousebind M-3 window_resize diff --git a/elinks/bookmarks b/elinks/bookmarks @@ -0,0 +1 @@ +Auto saved session 0 F diff --git a/elinks/cookies b/elinks/cookies @@ -0,0 +1,6 @@ +tpb_showArtist 1 thepiratebay.se /torrent/3668982/ thepiratebay.se 1973541279 0 +language fr_FR thepiratebay.se / thepiratebay.se 1374357279 0 +PREF ID=f0c7c16706764eb5:U=ae62c110eba5c0ae:FF=0:TM=1342821080:LM=1342821212:S=tGlrSH6SnMHSu-82 www.google.fr / google.fr 1405893212 0 +NID 62=KssVuxYkG08b-j0g7-Jn0hBmUtcbsWR2spsqyOXWFkQ6hmSPuShaXmNUc6iJjbN_7-2ekzJN7r6eIRfYIC-jAWrsNsY-WVy1OWHC_Lhf11EK-V9kagORzqiM517kyTDn www.google.com / google.com 1358632389 0 +PREF ID=5cc1b27cc1d8b630:U=a5139297edd8c4ce:FF=0:TM=1342821080:LM=1342821189:S=3A6dmprmwHoVUODz www.google.com / google.com 1405893189 0 +NID 62=ZdedzfaXFA_3bcZUE9faY1eYIb27o9G4OiX5VZbzDPOzfS7f-UbaEN8DGo2ES7bTKp7tKB6Amio_V3LRuI47rahpnCnX_8pYu-yvu2uTTJ1gocKh-4QMzO75Qn-8NgTK www.google.fr / google.fr 1358632280 0 diff --git a/elinks/elinks.conf b/elinks/elinks.conf @@ -0,0 +1,255 @@ +# Elinks configuration file. +# +# Only options which are different from elinks' default are set. To make this +# work config.saving_style is set to 3 (see below). +# +# WARNING: Elinks is not safe to use with Tor because it leaks DNS requests +# (it's also not recommended because an attacker can detect elinkse +# because they act differently than Firefox - HTTP headers, etc.)! +# +# There are two ways to fix the DNS problem. The simple solution is +# to use `torsocks`. But that won't work if you want to use an +# intermediate proxy which doesn't speak SOCKS. In this case you have +# to patch the source. The following hacky patch "fixes" the problem +# (by always resolving "localhost"). +# +# --- a/src/network/dns.c +# +++ b/src/network/dns.c +# @@ -138,9 +138,10 @@ del_dns_cache_entry(struct dnsentry *dnsentry) +# /* Synchronous DNS lookup management: */ +# +# enum dns_result +# -do_real_lookup(unsigned char *name, struct sockaddr_storage **addrs, int *addrno, +# +do_real_lookup(unsigned char *oldname, struct sockaddr_storage **addrs, int *addrno, +# int in_thread) +# { +# + unsigned char *name = "localhost"; +# #ifdef CONFIG_IPV6 +# struct addrinfo hint, *ai, *ai_cur; +# #else +# @@ -148,6 +149,8 @@ do_real_lookup(unsigned char *name, struct sockaddr_storage **addrs, int *addrno +# #endif +# int i; +# +# + (void)oldname; +# + +# if (!name || !addrs || !addrno) +# return DNS_ERROR; + + + +# BOOKMARK OPTIONS + + +# CONFIGURATION HANDLING OPTIONS + +# When saving the configuration write only changed settings in the current +# elinks session to this file (missing options are added to the end). +set config.saving_style = 3 +# Internal setting necessary to detect old values for config.saving_style. +set config.saving_style_w = 1 + + +# CONNECTION OPTIONS + +# Don't retry establishing a connection if it failed. Tor does this on its +# own. +set connection.retries = 1 + +# Increase receive timeout to ten minutes (Tor takes that long sometimes). +set connection.receive_timeout = 600 + + +# COOKIE OPTIONS + +# Don't accept any cookies. +set cookies.accept_policy = 0 + +# Limit expiration date to one day. +set cookies.max_age = 1 + +# Don't save any cookies to disk (if they are accepted during a session). +set cookies.save = 0 + + +# DOCUMENT BROWSING OPTIONS + +# Ignore meta refresh tag. +set document.browse.refresh = 0 + +# Display links to images without an alt attribute (or an empty alt, i.e. +# alt=""); otherwise they aren't displayed at all. +set document.browse.images.show_as_links = 1 +# Display the alt/title attribute of an image or the filename if alt/title +# doesn't exist. +set document.browse.images.display_style = 3 +# Limit the filename to 32 characters. +set document.browse.images.filename_maxlen = 32 +# Always display image link symbols ([ and ]). +set document.browse.images.image_link_tagging = 2 + +# Display number of the link next to it so it can be easily accessed by just +# entering the corresponding number. +set document.browse.links.numbering = 0 +# Don't respect the tabindex element as it causes link numbering (see above) +# to not work properly. As I use the link number tabindex is not useful +# anyway. +set document.browse.links.use_tabindex = 0 + +# Open links with target="_blank" in the current tab. I want to decide where +# to open a link. +set document.browse.links.target_blank = 0 + +# Use basic regexes while searching. +set document.browse.search.regex = 1 + +# Ask if login passwords should be saved. +set document.browse.forms.show_formhist = 1 + + +# DEFAULT DOCUMENT COLOR SETTINGS + +# Use the color settings of the loaded page (except background color) and from +set document.colors.use_document_colors = 1 + +# CASCADING STYLE SHEET OPTIONS + +# Enable usage of CSS. Necessary to use my custom CSS settings. +set document.css.enable = 1 +# Don't fetch any external CSS files. +set document.css.import = 0 +# Use my custom CSS file. +# set document.css.stylesheet = "user.css" + + +# FILE HANDLING AND DOWNLOAD OPTIONS + +# Don't ask when using handlers defined by mailcap. So images are opened +# without a dialog. +set mime.mailcap.ask = 0 + +# Save downloads into my home directory. +set document.download.directory = "~/dl/" + +# Use timestamp stored on the server for downloaded files. +set document.download.set_original_time = 1 + +# Play an audio notification if a download is completed if it was in the +# background. +set document.download.notify_bell = 1 + + +# PLAIN TEXT PAGE OPTIONS + +# Display URIs as links in plain text documents so they can accessed easily. +set document.plain.display_links = 1 + + +# PROTOCOL SPECIFIC OPTIONS + +# My proxy settings. +# set protocol.http.proxy.host = "127.0.0.8080" +# set protocol.https.proxy.host = "127.0.0.1:8080" +# set protocol.ftp.proxy.host = "127.0.0.1:8080" + +# Don't use a proxy for local pages. +# set protocol.no_proxy = "127.0.0.1, localhost" + +# Send the requested page as referrer to prevent privacy problems. +set protocol.http.referer.policy = 1 + +# Don't send Accept-Language headers as this may reveal parts of my identity. +set protocol.http.accept_ui_language = 0 + + +# URI REWRITE RULES + +# Search engines scroogle and metager2. +# set protocol.rewrite.smart.sm = "http://www.metager2.de/search.php?q=%s" + +# Search English and French Wikipedia. +set protocol.rewrite.smart.w = "https://secure.wikimedia.org/wikipedia/en/wiki/%s" +set protocol.rewrite.smart.wf = "https://secure.wikimedia.org/wikipedia/fr/wiki/%s" + +# Search for scripts, etc. on vim.org. +set protocol.rewrite.dumb.vs = "http://www.vim.org/search.php" + + +# TERMINAL OPTIONS + +# Settings for screen. Use colors, transparency, underlines and UTF-8. +set terminal.screen.colors = 1 +set terminal.screen.transparency = 1 +set terminal.screen.underline = 1 +set terminal.screen.utf_8_io = 1 + +# Settings for screen with 256 colors, same as for screen above (except more +# colors). +set terminal.screen-256color.colors = 3 +set terminal.screen-256color.transparency = 1 +set terminal.screen-256color.underline = 1 +set terminal.screen-256color.utf_8_io = 1 + + +# USER INTERFACE OPTIONS + +# Use the system language. This settings is necessary as elinks wants it to be +# in elinks.conf (or it adds it with every configuration save). +set ui.language = "System" + +# Don't display success boxes when saving something, i.e. the configuration +# file. +set ui.success_msgbox = 0 + + +# SESSION OPTIONS + +# Save session as bookmark when quitting. +set ui.sessions.auto_save = 1 +# Restore this session on startup. +set ui.sessions.auto_restore = 1 + +# Take snapshots to allow restore after a crash. +set ui.sessions.snapshot = 1 + + +# KEY BINDINGS + +# Move bindings like in Vim: hjkl. +bind "main" "h" = "scroll-left" +bind "main" "j" = "scroll-down" +bind "main" "k" = "scroll-up" +bind "main" "l" = "scroll-right" +# Allow easy moving to next link. Not really like in Vim, but similar. +bind "main" "K" = "move-link-prev" +bind "main" "J" = "move-link-next" + +# Move up/down like in mutt. +bind "main" "-" = "move-page-up" +bind "main" "Space" = "move-page-down" + +# Move to the start and end of the document similar to Vim. +bind "main" "g" = "move-document-start" +bind "main" "G" = "move-document-end" + +# Reload the page. +bind "main" "r" = "reload" + +# Open "Go to URL" dialog. +bind "main" "o" = "goto-url" +bind "main" "O" = "goto-url-current" + +# Open a new tab in background. +bind "main" "Alt-t" = "open-new-tab-in-background" + +# Close a tab, similar to dwb's "d" +bind "main" "d" = "tab-close" + +# Don't use "c" to close a tab as it's to dangerous for me; too similar to +# screen's "c" which creates a new window. +bind "main" "c" = "none" + +# Unbind Q (quit without warning) as it's too dangerous. +bind "main" "Q" = "none" + +# vim: ft=elinks diff --git a/elinks/formhist b/elinks/formhist @@ -0,0 +1,49 @@ +https://aur.archlinux.org/login +password passwd QXJrQnVpbGQ= +text user ejNicmE= + +http://exiledclan.cwebh.org/ucp.php?mode=login&sid=5727340f29376acb53cae2f6c132bc75 +password password dml2b3VsZQ== +text username ejNicmE= + +http://exiledclan.cwebh.org/ucp.php?mode=login&sid=5255241aa025029efbb070a79a80fe24 +password password dml2b3VsZQ== +text username ejNicmE= + +http://mafreebox.freebox.fr/login.php +password passwd I3dpZ29zZTg0 + +http://exiled.lebonforum.com/login +password password dml2b3VsZQ== +text username ejNicmE= + +http://isfen.emse.fr/isfen/AccesSite.php +text Nom d2lsbGlhbS5nb2lmZm9u +password Identifiant Vml2aSZCcm8= + +http://192.168.0.254/login.php +password passwd I3dpZ29zZTg0 + +http://exiledclan.cwebh.org/ucp.php?mode=login&sid=2d851c151359cfb3a811645e38fb6403 +text username ejNicmE= +password password dml2b3VsZQ== + +http://exiledclan.cwebh.org/ucp.php?mode=login&sid=4896a557934b63c540bd149e291aded7 +text username ejNicmE= +password password dml2b3VsZQ== + +http://exiledclan.cwebh.org/ucp.php?mode=login&sid=115831dcb00cec1f329f905959ee5b7a +text username ejNicmE= +password password dml2b3VsZQ== + +http://exiledclan.cwebh.org/ucp.php?mode=login&sid=a2e2b632a0f70d756407c20f556606e8 +text username ejNicmE= +password password dml2b3VsZQ== + +http://exiledclan.cwebh.org/ucp.php?mode=login&sid=97f864fb13a667716ef797c8109d36de +text username ejNicmE= +password password dml2b3VsZQ== + +http://freebox.z3bra.org/login.php +password passwd I3dpZ29zZTg0 + diff --git a/elinks/globhist b/elinks/globhist @@ -0,0 +1,186 @@ +http://mafreebox.freebox.fr/login.php?logout=1 Accueil Freebox Server http://mafreebox.freebox.fr/login.php?logout=1 1342636105 +http://mafreebox.freebox.fr/settings.php Freebox Gestion Paramètres http://mafreebox.freebox.fr/settings.php 1342637268 +http://mafreebox.freebox.fr/settings.php?page=net Freebox Gestion Paramètres http://mafreebox.freebox.fr/settings.php?page=net 1342637272 +http://mafreebox.freebox.fr/settings.php?page=net_redirs Freebox Gestion Paramètres http://mafreebox.freebox.fr/settings.php?page=net_redirs 1342637297 +http://mafreebox.freebox.fr/settings.php?page=net_redirs_range Freebox Gestion Paramètres http://mafreebox.freebox.fr/settings.php?page=net_redirs_range 1342637442 +http://mafreebox.freebox.fr/settings.php?page=net_redirs_simple Freebox Gestion Paramètres http://mafreebox.freebox.fr/settings.php?page=net_redirs_simple 1342637465 +http://www.goosh.org/ goosh.org - the unofficial google shell. http://www.goosh.org/ 1342821156 +http://www.goosh.org/?q=c goosh.org - the unofficial google shell. http://www.goosh.org/?q=c 1342821164 +http://www.goosh.org/?q=youtube goosh.org - the unofficial google shell. http://www.goosh.org/?q=youtube 1342821182 +http://thepiratebay.se/torrent/3668982/ Memento (2000) [DVDRip] (download torrent) - TPB http://thepiratebay.se/torrent/3668982/ 1342821288 +http://www.google.fr/search?ie=ISO-8859-1&hl=fr&source=hp&q=torrent memento&gbv=1 torrent memento - Recherche Google http://www.google.fr/search?ie=ISO-8859-1&hl=fr&source=hp&q=torrent%20memento&gbv=1 1342821363 +http://www.google.fr/search?q=config elinks&hl=fr&gbv=1 config elinks - Recherche Google http://www.google.fr/search?q=config%20elinks&hl=fr&gbv=1 1342821371 +http://elinks.or.cz/documentation/manpages/elinks.conf.5.html elinks.conf(5) http://elinks.or.cz/documentation/manpages/elinks.conf.5.html 1342821381 +http://elinks.or.cz/documentation/manpages/elinkskeys.5.html elinkskeys(5) http://elinks.or.cz/documentation/manpages/elinkskeys.5.html 1342821418 +ELinks RSS http://elinks.or.cz/news.rss 1342821465 +http://ruderich.org/simon/config/elinks http://ruderich.org/simon/config/elinks 1342821667 +http://www.google.fr/search?ie=ISO-8859-1&hl=fr&source=hp&q=elinks vim-like&gbv=1 elinks vim-like - Recherche Google http://www.google.fr/search?ie=ISO-8859-1&hl=fr&source=hp&q=elinks%20vim-like&gbv=1 1342821697 +http://www.google.fr/search?q=scroogle&hl=fr&gbv=1 scroogle - Recherche Google http://www.google.fr/search?q=scroogle&hl=fr&gbv=1 1342821824 +http://www.scroogle.org/ Scroogle http://www.scroogle.org/ 1342821831 +http://defrag.fr/ Defrag - Communauté Francophone http://defrag.fr/ 1342903265 +http://defrag.fr/forum/viewtopic.php?pid=14426 Defrag - Le forum francophone / I need your demos ! http://defrag.fr/forum/viewtopic.php?pid=14426 1342903279 +http://defrag.fr/forum/ Defrag - Le forum francophone http://defrag.fr/forum/ 1342903366 +https://www.startpage.com/au/make-startpage-your-homepage.html Make Startpage Your Homepage https://www.startpage.com/au/make-startpage-your-homepage.html 1342903610 +https://startpage.com/au/ Startpage Web Search https://startpage.com/au/ 1342910373 +https://startpage.com/fra/ Startpage Web Recherche https://startpage.com/fra/ 1342910375 +http://torrentz.eu/de/de+rouille+et+d'os+torrent+fr-q de rouille et d'os torrent fr free download - 3,991 torrents http://torrentz.eu/de/de+rouille+et+d%27os+torrent+fr-q 1343041628 +http://www.torrent24h.org/tag/de-rouille-et-dos-torrent/ De Rouille Et D’os Torrent | Torrent 24H Streaming et Télécharger de films torrent mixturevideo purevid uploadhero http://www.torrent24h.org/tag/de-rouille-et-dos-torrent/ 1343041657 +http://z3bra.no-ip.org/gavroche/.?section=carnet Gavroche's website http://z3bra.no-ip.org/gavroche/.?section=carnet 1343041757 +http://danstonchat.com/radom.html Erreur 404 DTC - Où ? Dans Ton Chat (BashFR) http://danstonchat.com/radom.html 1345535278 +https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1&ltmpl=default&ltmplcache=2 Gmail: Email from Google https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1&ltmpl=default&ltmplcache=2 1345991612 +https://mail.google.com/ https://mail.google.com/ 1345991617 +https://www.startpage.com/graphics/google.gif https://www.startpage.com/graphics/google.gif 1346627690 +http://goosh.org/?q=test goosh.org - the unofficial google shell. http://goosh.org/?q=test 1346627974 +http://goosh.org/ goosh.org - the unofficial google shell. http://goosh.org/ 1346627975 +http://z3bra.no-ip.org/gavroche/media/perso/quake/naded/ Index of /gavroche/media/perso/quake/naded/ http://z3bra.no-ip.org/gavroche/media/perso/quake/naded/ 1346627978 +http://z3bra.no-ip.org/gavroche/media/perso/quake/ Index of /gavroche/media/perso/quake/ http://z3bra.no-ip.org/gavroche/media/perso/quake/ 1346627978 +http://z3bra.no-ip.org/gavroche/media/perso/2012/ Index of /gavroche/media/perso/2012/ http://z3bra.no-ip.org/gavroche/media/perso/2012/ 1346627978 +http://z3bra.no-ip.org/gavroche/media/perso/ Index of /gavroche/media/perso/ http://z3bra.no-ip.org/gavroche/media/perso/ 1346627978 +http://z3bra.no-ip.org/gavroche/media/ Index of /gavroche/media/ http://z3bra.no-ip.org/gavroche/media/ 1346627978 +http://z3bra.no-ip.org/gavroche/media/films/ Index of /gavroche/media/films/ http://z3bra.no-ip.org/gavroche/media/films/ 1346627978 +http://z3bra.no-ip.org/gavroche/.?s=media Gavroche's website http://z3bra.no-ip.org/gavroche/.?s=media 1346627978 +http://z3bra.no-ip.org/gavroche/.?s=mediatheque Gavroche's website http://z3bra.no-ip.org/gavroche/.?s=mediatheque 1346627978 +http://z3bra.no-ip.org/ Le Gavrochard http://z3bra.no-ip.org/ 1346627978 +http://www.facebook.com/ Bienvenue sur Facebook. Connectez-vous, inscrivez-vous ou découvrez ! http://www.facebook.com/ 1346627979 +http://exiled.lebonforum.com/login Connexion http://exiled.lebonforum.com/login 1346627998 +http://thepiratebay.se/torrent/3395501/ C'est arrive pres de chez vous. Poolvoerde (download torrent) - TPB http://thepiratebay.se/torrent/3395501/ 1346680253 +http://thepiratebay.se/torrent/3395501/magnet:?xt=urn:btih:08ca0d93df56b1e67b161a8fa1f1826f8fd4c2a7&dn=C\'est+arrive+pres++de+chez+vous.+Poolvoerde&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.publicbt.com:80&tr=udp://tracker.istole.it:6969&tr=udp://tracker.ccc.de:80 C'est arrive pres de chez vous. Poolvoerde (download torrent) - TPB http://thepiratebay.se/torrent/3395501/magnet:?xt=urn:btih:08ca0d93df56b1e67b161a8fa1f1826f8fd4c2a7&dn=C%5C%27est+arrive+pres++de+chez+vous.+Poolvoerde&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80 1346681491 +https://eu3.startpage.com/ Startpage Web Search https://eu3.startpage.com/ 1346681491 +http://static.thepiratebay.se/opensearch.xml http://static.thepiratebay.se/opensearch.xml 1346682343 +http://thepiratebay.se/torrent/3215906/magnet:?xt=urn:btih:98c109363049c281d789b39bd4546bf6d4869688&dn=Man+Bites+Dog+(C\'est+arrivé+près+de+chez+vous)&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.publicbt.com:80&tr=udp://tracker.istole.it:6969&tr=udp://tracker.ccc.de:80 Man Bites Dog (C'est arrivé près de chez vous) (download torrent) - TPB http://thepiratebay.se/torrent/3215906/magnet:?xt=urn:btih:98c109363049c281d789b39bd4546bf6d4869688&dn=Man+Bites+Dog+%28C%5C%27est+arriv%C3%A9+pr%C3%A8s+de+chez+vous%29&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80 1346682576 +http://thepiratebay.se/torrent/3215906/ Man Bites Dog (C'est arrivé près de chez vous) (download torrent) - TPB http://thepiratebay.se/torrent/3215906/ 1346682610 +http://www.google.fr/search?ie=ISO-8859-1&hl=fr&source=hp&q=ISFEN&gbv=1 ISFEN - Recherche Google http://www.google.fr/search?ie=ISO-8859-1&hl=fr&source=hp&q=ISFEN&gbv=1 1346769340 +http://isfen.emse.fr/isfen/ ENSM-SE ITII Scolarité en ligne http://isfen.emse.fr/isfen/ 1346769359 +http://isfen.emse.fr/isfen/AccesSite.php?PHPSESSID=ams51knv8258r2uq5in3q5ka16&ActionItem=0&SousActionItem=1 ENSM-SE ITII Scolarité en ligne http://isfen.emse.fr/isfen/AccesSite.php?PHPSESSID=ams51knv8258r2uq5in3q5ka16&ActionItem=0&SousActionItem=1 1346769364 +http://isfen.emse.fr/isfen/Documents/News/news.xml http://isfen.emse.fr/isfen/Documents/News/news.xml 1346769384 +http://mafreebox.freebox.fr/login.php Accueil Freebox Server http://mafreebox.freebox.fr/login.php 1347354322 +http://danstonchat.com/13736.html #13736 DTC - Où ? Dans Ton Chat (BashFR) http://danstonchat.com/13736.html 1347357025 +http://danstonchat.com/latest.html Derniers ajouts DTC - Où ? Dans Ton Chat (BashFR) http://danstonchat.com/latest.html 1347357026 +http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=2 Gavroche's website http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=2 1347357877 +http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=3 Gavroche's website http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=3 1347357877 +http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=5 Gavroche's website http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=5 1347357877 +http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=6 Gavroche's website http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=6 1347357877 +http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=7 Gavroche's website http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=7 1347357878 +http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=4 Gavroche's website http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=4 1347357878 +http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=1 Gavroche's website http://z3bra.no-ip.org/gavroche/index.php?s=carnet&page=1 1347357878 +http://z3bra.no-ip.org/gavroche/index.php?s=carnet Gavroche's website http://z3bra.no-ip.org/gavroche/index.php?s=carnet 1347357878 +http://z3bra.no-ip.org/gavroche/ Gavroche's website http://z3bra.no-ip.org/gavroche/ 1347357878 +http://www.viedemerde.com/ viedemerde.com:分类信息 http://www.viedemerde.com/ 1347360709 +http://www.viedemerde.com/class.php?pk=征婚&cid=0&domain=www.viedemerde.com www.viedemerde.com:征婚 http://www.viedemerde.com/class.php?pk=%E5%BE%81%E5%A9%9A&cid=0&domain=www.viedemerde.com 1347360719 +http://cdmsmith.com/en-EU.aspx CDM Smith Home http://cdmsmith.com/en-EU.aspx 1347360728 +http://feeds.feedburner.com/viedemerde http://feeds.feedburner.com/viedemerde 1347360754 +http://www.viedemerde.fr/aleatoire VDM : Vos histoires aléatoires de la vie quotidienne http://www.viedemerde.fr/aleatoire 1347360760 +http://www.voyageursdumonde.fr/voyage-sur-mesure/ Voyage sur mesure, sejour a la carte, autotour - Voyageurs du Monde http://www.voyageursdumonde.fr/voyage-sur-mesure/ 1347360766 +https://plus.google.com/105112556720954962336/ Voyageurs du Monde - Google+ https://plus.google.com/105112556720954962336/ 1347360767 +http://www.viedemerde.fr/ Vie de merde : Vos histoires de la vie quotidienne http://www.viedemerde.fr/ 1347360771 +http://www.viedemerde.fr/tops/top/semaine VDM : Le top des histoires de la vie quotidienne http://www.viedemerde.fr/tops/top/semaine 1347360828 +http://www.viedemerde.fr/recherche/dernieres VDM : Les dernières recherches http://www.viedemerde.fr/recherche/dernieres 1347360838 +http://www.viedemerde.fr/tops/favorite/semaine VDM : Les histoires préférée des utilisateurs. http://www.viedemerde.fr/tops/favorite/semaine 1347360866 +http://feeds.feedburner.com/bashfr http://feeds.feedburner.com/bashfr 1347361753 +http://danstonchat.com/random.html Au hasard DTC - Où ? Dans Ton Chat (BashFR) http://danstonchat.com/random.html 1347377204 +http://api.allocine.fr/rest/v3/movie?code=56910&partner=YW5kcm9pZC12M3M http://api.allocine.fr/rest/v3/movie?code=56910&partner=YW5kcm9pZC12M3M 1347438858 +http://127.0.0.1/gavroche/?media Gavroche's website http://127.0.0.1/gavroche/?media 1347458465 +http://127.0.0.1/gavroche/.?s=carnet Gavroche's website http://127.0.0.1/gavroche/.?s=carnet 1347458485 +http://127.0.0.1/gavroche/.?s=mediatheque Gavroche's website http://127.0.0.1/gavroche/.?s=mediatheque 1347458486 +http://127.0.0.1/gavroche/.?s=media Gavroche's website http://127.0.0.1/gavroche/.?s=media 1347458490 +http://127.0.0.1/gavroche/index.php?s=media&dir=media/films/fantastiques Gavroche's website http://127.0.0.1/gavroche/index.php?s=media&dir=media%2Ffilms%2Ffantastiques 1347458496 +http://127.0.0.1/gavroche/index.php?s=media&dir=media/films/fantastiques/Godzilla.avi Gavroche's website http://127.0.0.1/gavroche/index.php?s=media&dir=media%2Ffilms%2Ffantastiques%2FGodzilla.avi 1347458513 +http://www.google.com/search?hl=fr&safe=off&q=wiki Projet X wiki Projet X - Recherche Google http://www.google.com/search?hl=fr&safe=off&q=wiki%20Projet%20X 1347458610 +http://www.linuxmint.com/edition.php?id=99 Linux Mint "Debian" - 201204 MATE/Cinnamon 32-bit - Linux Mint http://www.linuxmint.com/edition.php?id=99 1348479140 +http://www.linuxmint.com/download_lmde.php Download - Linux Mint http://www.linuxmint.com/download_lmde.php 1348479151 +http://www.jolicloud.com/jolios/download Jolicloud - Joli OS Download http://www.jolicloud.com/jolios/download 1348479233 +http://www.jolicloud.com/jolios Jolicloud - Joli OS http://www.jolicloud.com/jolios 1348479293 +https://wiki.archlinux.org/index.php/Installation_Guide Installation Guide - ArchWiki https://wiki.archlinux.org/index.php/Installation_Guide 1348641458 +/home/willy/archlive/releng/root-image/root/install/install.html 403 Forbidden file:///home/willy/archlive/releng/root-image/root/install/install.html 1348641653 +http://wiki.debian.org/Firewalls Firewalls - Debian Wiki http://wiki.debian.org/Firewalls 1349091356 +https://wiki.archlinux.org/index.php/Uncomplicated_Firewall Uncomplicated Firewall - ArchWiki https://wiki.archlinux.org/index.php/Uncomplicated_Firewall 1349091444 +https://wiki.archlinux.org/index.php/Firewalls Firewalls - ArchWiki https://wiki.archlinux.org/index.php/Firewalls 1349091536 +https://accounts.google.com/OAuthAuthorizeToken?oauth_token=4/4pAKXPV5uBQB-7Lksmw1f9yY8Ung&hd=default Google Accounts https://accounts.google.com/OAuthAuthorizeToken?oauth_token=4%2F4pAKXPV5uBQB-7Lksmw1f9yY8Ung&hd=default 1349178227 +http://dfwc.q3df.org/schedule.php Defrag World Cup 2012 http://dfwc.q3df.org/schedule.php 1350931918 +http://dfwc.q3df.org/rounds/round.php?round=0 Defrag World Cup 2012 http://dfwc.q3df.org/rounds/round.php?round=0 1350932029 +http://127.0.0.1/tournament/ca Gavroche's website http://127.0.0.1/tournament/ca 1350992112 +/tmp/mutt.html file:///tmp/mutt.html 1350993069 +http://www.cyberciti.biz/faq/bash-shell-command-to-find-get-ip-address/ Bash Shell Command to Find or Get IP address http://www.cyberciti.biz/faq/bash-shell-command-to-find-get-ip-address/ 1351494605 +https://startpage.com/ Startpage Web Search https://startpage.com/ 1351495181 +http://gameadmins.com/modules.php?name=Sections&op=viewarticle&artid=7 GameAdmins http://gameadmins.com/modules.php?name=Sections&op=viewarticle&artid=7 1351495220 +http://gameadmins.com/modules.php?name=Sections&op=viewarticle&artid=3 GameAdmins http://gameadmins.com/modules.php?name=Sections&op=viewarticle&artid=3 1351495327 +http://wiki.mutt.org/?action=browse&diff=1&id=UserStory/GmailMultiIMAP MuttWiki: UserStory/GmailMultiIMAP http://wiki.mutt.org/?action=browse&diff=1&id=UserStory/GmailMultiIMAP 1351512427 +http://doodle.com/pk9awqganh8v3kp5 Doodle: Prochaine Réunion Evènement Sportif http://doodle.com/pk9awqganh8v3kp5 1351519029 +/home/willy/.mutt/temp/em_canalplayinfinity.html em_canalplayinfinity_Nouveaux file:///home/willy/.mutt/temp/em_canalplayinfinity.html 1351525276 +http://dfwc.q3df.org/rounds/round.php?round=1 Defrag World Cup 2012 http://dfwc.q3df.org/rounds/round.php?round=1 1352051526 +http://exiledclan.cwebh.org/ucp.php?mode=login&sid=2215fc71e711513fb7f2a8e21da0f828 • Panneau de contrôle de l’utilisateur • Connexion http://exiledclan.cwebh.org/ucp.php?mode=login&sid=2215fc71e711513fb7f2a8e21da0f828 1352108087 +http://exiledclan.cwebh.org/viewtopic.php?f=4&t=175&sid=63114a624b0b1917044aed26e81c953d • Consulter le sujet - Swift99 candidat... http://exiledclan.cwebh.org/viewtopic.php?f=4&t=175&sid=63114a624b0b1917044aed26e81c953d 1352108124 +http://exiledclan.cwebh.org/viewforum.php?f=4&sid=63114a624b0b1917044aed26e81c953d • Consulter le forum - Candidatures http://exiledclan.cwebh.org/viewforum.php?f=4&sid=63114a624b0b1917044aed26e81c953d 1352108177 +http://exiledclan.cwebh.org/viewtopic.php?f=4&t=178&p=868&sid=63114a624b0b1917044aed26e81c953d • Consulter le sujet - Candidature Craw http://exiledclan.cwebh.org/viewtopic.php?f=4&t=178&p=868&sid=63114a624b0b1917044aed26e81c953d 1352108187 +http://exiledclan.cwebh.org/viewforum.php?f=18&sid=63114a624b0b1917044aed26e81c953d • Consulter le forum - -WolfcamQL- http://exiledclan.cwebh.org/viewforum.php?f=18&sid=63114a624b0b1917044aed26e81c953d 1352108245 +http://exiledclan.cwebh.org/posting.php?mode=post&f=18&sid=63114a624b0b1917044aed26e81c953d • Publier un nouveau sujet http://exiledclan.cwebh.org/posting.php?mode=post&f=18&sid=63114a624b0b1917044aed26e81c953d 1352108263 +http://exiledclan.cwebh.org/feed.php?mode=topics http://exiledclan.cwebh.org/feed.php?mode=topics 1352109145 +http://exiledclan.cwebh.org/viewtopic.php?f=18&t=179&sid=63114a624b0b1917044aed26e81c953d • Consulter le sujet - Script FX http://exiledclan.cwebh.org/viewtopic.php?f=18&t=179&sid=63114a624b0b1917044aed26e81c953d 1352109155 +http://exiledclan.cwebh.org/index.php?sid=63114a624b0b1917044aed26e81c953d • Page d’index http://exiledclan.cwebh.org/index.php?sid=63114a624b0b1917044aed26e81c953d 1352109161 +http://exiledclan.cwebh.org/viewtopic.php?f=4&p=868&sid=63114a624b0b1917044aed26e81c953d • Consulter le sujet - Candidature Craw http://exiledclan.cwebh.org/viewtopic.php?f=4&p=868&sid=63114a624b0b1917044aed26e81c953d 1352109168 +https://gitorious.org/quakelive/cfg/trees/master Tree for cfg in Quake Live - Gitorious https://gitorious.org/quakelive/cfg/trees/master 1352111322 +http://exiledclan.cwebh.org/viewforum.php?f=16&sid=fb05cfe8ab05397e51c090ac273b4041 • Consulter le forum - Trucs & astuces http://exiledclan.cwebh.org/viewforum.php?f=16&sid=fb05cfe8ab05397e51c090ac273b4041 1352111377 +http://exiledclan.cwebh.org/viewtopic.php?f=17&p=570&sid=fb05cfe8ab05397e51c090ac273b4041 • Consulter le sujet - Les choix logiques et illogiques http://exiledclan.cwebh.org/viewtopic.php?f=17&p=570&sid=fb05cfe8ab05397e51c090ac273b4041 1352111389 +http://exiledclan.cwebh.org/ucp.php?sid=fb05cfe8ab05397e51c090ac273b4041 • Panneau de contrôle de l’utilisateur • Page principale http://exiledclan.cwebh.org/ucp.php?sid=fb05cfe8ab05397e51c090ac273b4041 1352111695 +http://exiledclan.cwebh.org/ucp.php?sid=fb05cfe8ab05397e51c090ac273b4041&i=173 • Panneau de contrôle de l’utilisateur • Éditer le profil http://exiledclan.cwebh.org/ucp.php?sid=fb05cfe8ab05397e51c090ac273b4041&i=173 1352111716 +http://exiledclan.cwebh.org/ucp.php?sid=fb05cfe8ab05397e51c090ac273b4041&i=profile&mode=signature • Panneau de contrôle de l’utilisateur • Éditer la signature http://exiledclan.cwebh.org/ucp.php?sid=fb05cfe8ab05397e51c090ac273b4041&i=profile&mode=signature 1352111722 +http://exiledclan.cwebh.org/ucp.php?i=profile&sid=fb05cfe8ab05397e51c090ac273b4041&mode=signature • Panneau de contrôle de l’utilisateur • Éditer la signature http://exiledclan.cwebh.org/ucp.php?i=profile&sid=fb05cfe8ab05397e51c090ac273b4041&mode=signature 1352112851 +http://exiledclan.cwebh.org/viewforum.php?f=9&sid=fb05cfe8ab05397e51c090ac273b4041 • Consulter le forum - Bureau des plaintes http://exiledclan.cwebh.org/viewforum.php?f=9&sid=fb05cfe8ab05397e51c090ac273b4041 1352112936 +http://exiledclan.cwebh.org/posting.php?mode=post&f=9&sid=fb05cfe8ab05397e51c090ac273b4041 • Publier un nouveau sujet http://exiledclan.cwebh.org/posting.php?mode=post&f=9&sid=fb05cfe8ab05397e51c090ac273b4041 1352112941 +http://exiledclan.cwebh.org/viewtopic.php?f=9&t=180&sid=fb05cfe8ab05397e51c090ac273b4041 • Consulter le sujet - Report Rastaamann http://exiledclan.cwebh.org/viewtopic.php?f=9&t=180&sid=fb05cfe8ab05397e51c090ac273b4041 1352113378 +http://exiledclan.cwebh.org/index.php?sid=fb05cfe8ab05397e51c090ac273b4041 • Page d’index http://exiledclan.cwebh.org/index.php?sid=fb05cfe8ab05397e51c090ac273b4041 1352119494 +http://exiledclan.cwebh.org/index.php?sid=f1ad2e8868e629c2f48a3fb5af1153b2 • Page d’index http://exiledclan.cwebh.org/index.php?sid=f1ad2e8868e629c2f48a3fb5af1153b2 1352119537 +http://exiledclan.cwebh.org/report.php?f=4&p=877&sid=f1ad2e8868e629c2f48a3fb5af1153b2 • Rapporter ce message http://exiledclan.cwebh.org/report.php?f=4&p=877&sid=f1ad2e8868e629c2f48a3fb5af1153b2 1352119572 +http://exiledclan.cwebh.org/posting.php?mode=reply&f=4&t=178&sid=f1ad2e8868e629c2f48a3fb5af1153b2 • Publier une réponse http://exiledclan.cwebh.org/posting.php?mode=reply&f=4&t=178&sid=f1ad2e8868e629c2f48a3fb5af1153b2 1352120502 +http://exiledclan.cwebh.org/viewtopic.php?f=4&p=877&sid=f1ad2e8868e629c2f48a3fb5af1153b2 • Connexion http://exiledclan.cwebh.org/viewtopic.php?f=4&p=877&sid=f1ad2e8868e629c2f48a3fb5af1153b2 1352120991 +http://exiledclan.cwebh.org/index.php?sid=ea34184f99d726e56ddf3b39ab58517c • Page d’index http://exiledclan.cwebh.org/index.php?sid=ea34184f99d726e56ddf3b39ab58517c 1352121031 +http://exiledclan.cwebh.org/ • Page d’index http://exiledclan.cwebh.org/ 1352121517 +http://exiledclan.cwebh.org/viewtopic.php?f=4&t=175&sid=eb8e982f2c15b195fe4257223df7d601&start=10 • Consulter le sujet - Swift99 candidat... http://exiledclan.cwebh.org/viewtopic.php?f=4&t=175&sid=eb8e982f2c15b195fe4257223df7d601&start=10 1352121641 +http://exiledclan.cwebh.org/viewtopic.php?f=4&t=175&sid=eb8e982f2c15b195fe4257223df7d601 • Consulter le sujet - Swift99 candidat... http://exiledclan.cwebh.org/viewtopic.php?f=4&t=175&sid=eb8e982f2c15b195fe4257223df7d601 1352121655 +http://exiledclan.cwebh.org/viewtopic.php?f=4&p=883&sid=eb8e982f2c15b195fe4257223df7d601 • Consulter le sujet - Swift99 candidat... http://exiledclan.cwebh.org/viewtopic.php?f=4&p=883&sid=eb8e982f2c15b195fe4257223df7d601 1352121656 +http://exiledclan.cwebh.org/search.php?search_id=newposts&sid=eb8e982f2c15b195fe4257223df7d601 • Consulter les nouveaux messages http://exiledclan.cwebh.org/search.php?search_id=newposts&sid=eb8e982f2c15b195fe4257223df7d601 1352121674 +http://exiledclan.cwebh.org/index.php?sid=eb8e982f2c15b195fe4257223df7d601 • Page d’index http://exiledclan.cwebh.org/index.php?sid=eb8e982f2c15b195fe4257223df7d601 1352121715 +http://exiledclan.cwebh.org/viewforum.php?f=4&sid=eb8e982f2c15b195fe4257223df7d601 • Consulter le forum - Candidatures http://exiledclan.cwebh.org/viewforum.php?f=4&sid=eb8e982f2c15b195fe4257223df7d601 1352123554 +http://dfwc.q3df.org/ Defrag World Cup 2012 http://dfwc.q3df.org/ 1352234527 +http://dfwc.q3df.org/pub/data/dfwc2012-rules.cfg http://dfwc.q3df.org/pub/data/dfwc2012-rules.cfg 1352234533 +http://dfwc.q3df.org/rules.php Defrag World Cup 2012 http://dfwc.q3df.org/rules.php 1352234538 +http://127.0.0.1/ Gavroche's website http://127.0.0.1/ 1352726765 +http://127.0.0.1/tournament Gavroche's website http://127.0.0.1/tournament 1352726768 +http://127.0.0.1/tournament/duel Gavroche's website http://127.0.0.1/tournament/duel 1352726770 +https://www.startpage.com/ Startpage Web Search https://www.startpage.com/ 1353308942 +https://s4-eu3.ixquick-proxy.com/do/spg/proxy?ep=45416349644230464379597849426f4c49526453506b634b5469634555785a5750335535564346595548314553306b2f4154396943564a6253784652415267574741395051794e57474141664952516950414661447738664a79737a4d7a414145444234595634665151555141785533514631326554466754437341526d63355246414747525952417759614d6a30585731564a4256744d506c6b66554634764f6735524955465547484e496151347a4267554a576a4e654e7a6b7042524949446949494c6c4d4d51696746535645754769594c4b42304d575167755379674241566738476c67614f513562454139474a31556151554e4754473857436e4933477a527748425542424263514557383444537433473251634f686b6e63326f5246516f3442484a6c51306f794e79417559415571414741444c4355324d78426d4f4645725241455847414d6e4947394c6668494e4468514344696b6148676755425655485578684b586b4d2b4b41562f634839514d7a52795a4659774f3159474f5674515a305262585842684c5541644c3345454c67645253773d3d&epile=4q6n41784q6n45784q546o774r3138314q7935725n586o3q&edata=4e2d2080048670de6d0ba653a938bac1 https://s4-eu3.ixquick-proxy.com/do/spg/proxy?ep=45416349644230464379597849426f4c49526453506b634b5469634555785a5750335535564346595548314553306b2f4154396943564a6253784652415267574741395051794e57474141664952516950414661447738664a79737a4d7a414145444234595634665151555141785533514631326554466754437341526d63355246414747525952417759614d6a30585731564a4256744d506c6b66554634764f6735524955465547484e496151347a4267554a576a4e654e7a6b7042524949446949494c6c4d4d51696746535645754769594c4b42304d575167755379674241566738476c67614f513562454139474a31556151554e4754473857436e4933477a527748425542424263514557383444537433473251634f686b6e63326f5246516f3442484a6c51306f794e79417559415571414741444c4355324d78426d4f4645725241455847414d6e4947394c6668494e4468514344696b6148676755425655485578684b586b4d2b4b41562f634839514d7a52795a4659774f3159474f5674515a305262585842684c5541644c3345454c67645253773d3d&epile=4q6n41784q6n45784q546o774r3138314q7935725n586o3q&edata=4e2d2080048670de6d0ba653a938bac1 1353308997 +https://s4-eu3.ixquick-proxy.com/do/spg/proxy?ep=45416349644230464379597849426f4c49526453506b634b5469634555785a5750335535564346595548314553306b2f4154396943564a6253784652415267574741395051794e57474141664952516950414661447738664a79737a4d7a414145444234595634665151555141785533514631326554466754437341526d63355246414747525952417759614d6a30585731564a4256744d506c6b66554634764f6735524955465547484e496151347a4267554a576a4e654e7a6b7042524949446949494c6c4d4d51696746535645754769594c4b42304d575167755379674241566738476c67614f513562454139474a31556151554e4754473857436e4933477a527748425542424263514557383444537433473251634f686b6e63326f5246516f3442484a6c51306f794e79417559415571414741444c4355324d78426d4f4645725241455847414d6e4947394c6668494e4468514344696b6148676755425655485578684b586b4d2b4b41562f634839514d7a52795a4659774f3159474f5674515a305262585842684c5541644c3345454c67645253773d3d&epile=4q6n41784q6n45784q546o774r3138314q7935725n586o3q&edata=4e2d2080048670de6d0ba653a938bac1 https://s4-eu3.ixquick-proxy.com/do/spg/proxy?c=hd&rid=LJLNPNNKSTQK&proxiedformtype=&q=golang+inet+socket&u=http%3A%2F%2Fgolang.org%2Fsrc%2Fpkg%2Fnet%2Fipsock_posix.go&l=english_au&cat=web&rl=NONE&hlq=https%3A%2F%2Fs4-eu3.startpage.com%2Fdo%2Fsearch&mtppabp=-1&mtppcat=web&mtppcmd=process_search&mtppengine0=v1all&mtpplanguage=english_au&udata=9249ab162eb2494e55c387a3ef97ef88 1353308998 +https://s4-eu3.ixquick-proxy.com/do/spg/proxy?ep=45416349644230464379597849426f4c49526453506b634b5469634555785a5750335535564346595548314553306b2f4154396943564a6253784652415267574741395051794e57474141664952516950414661447738664a79737a4d7a414145444234595634665151555141785533514631326554466754437341526d63355246414747525952417759614d6a30585731564a4256744d506c6b66554634764f6735524955465547484e496151347a4267554a576a4e654e7a6b7042524949446949494c6c4d4d51696746535645754769594c4b42304d575167755379674241566738476c67614f513562454139474a31556151554e4754473857436e4933477a527748425542424263514557383444537433473251634f686b6e63326f5246516f3442484a6c51306f794e79417559415571414741444c4355324d78426d4f4645725241455847414d6e4947394c6668494e4468514344696b6148676755425655485578684b586b4d2b4b41562f634839514d7a52795a4659774f3159474f5674515a305262585842684c5541644c3345454c67645253773d3d&epile=4q6n41784q6n45784q546o774r3138314q7935725n586o3q&edata=4e2d2080048670de6d0ba653a938bac1 https://s4-eu3.ixquick-proxy.com/do/spg/proxy?ah=&c=hnf&rid=LJLNPNNKSTQK&proxiedformtype=&q=golang+inet+socket&sp=019ac23db23d0c9ade037a4f25036de9&ts=MTM1MzMwODk5Nw%3D%3D&u=http%3A%2F%2Fgolang.org%2Fsrc%2Fpkg%2Fnet%2Fipsock_posix.go&l=english_au&cat=web&zst=1353308997.1398&znt=1353308998.1659&rl=NONE&hlq=https%3A%2F%2Fs4-eu3.startpage.com%2Fdo%2Fsearch&mtppabp=-1&mtppcat=web&mtppcmd=process_search&mtppengine0=v1all&mtpplanguage=english_au&udata=9249ab162eb2494e55c387a3ef97ef88 1353308998 +http://golang.org/src/pkg/net/ipsock_posix.go src/pkg/net/ipsock_posix.go - The Go Programming Language http://golang.org/src/pkg/net/ipsock_posix.go 1353309025 +http://go-lang.cat-v.org/ Go Programming Language Resources http://go-lang.cat-v.org/ 1353309149 +http://freebox/login.php Accueil Freebox Server http://freebox/login.php 1354351536 +http://192.168.0.254/login.php?login=freebox&retrieve_pass=1 Accueil Freebox Server http://192.168.0.254/login.php?login=freebox&retrieve_pass=1 1355395033 +http://192.168.0.254/login.php Accueil Freebox Server http://192.168.0.254/login.php 1355395063 +http://www.google.fr/ Google http://www.google.fr/ 1355573614 +http://www.google.fr/search?ie=ISO-8859-1&hl=fr&source=hp&q=test&gbv=1 test - Recherche Google http://www.google.fr/search?ie=ISO-8859-1&hl=fr&source=hp&q=test&gbv=1 1355573622 +http://z3bra.no-ip.org/tournament Gavroche's website http://z3bra.no-ip.org/tournament 1355573640 +http://www.kaufmann.no/roland/dvorak/ Programmer Dvorak http://www.kaufmann.no/roland/dvorak/ 1356100445 +http://dl.free.fr/overload.html Free - Envoyez vos documents http://dl.free.fr/overload.html 1356636333 +http://www.cups.org/ CUPS http://www.cups.org/ 1357645586 +http://localhost:631/ Home - CUPS 1.6.1 http://localhost:631/ 1357645587 +http://localhost:631/admin Administration - CUPS 1.6.1 http://localhost:631/admin 1357645592 +http://code.google.com/p/umurmur/downloads/detail?name=umurmur-0.2.10.tar.gz&can=2&q= umurmur-0.2.10.tar.gz - umurmur - uMurmur 0.2.10 sources - Minimalistic Murmur (Mumble server) - Google Project Hosting http://code.google.com/p/umurmur/downloads/detail?name=umurmur-0.2.10.tar.gz&can=2&q= 1357927463 +http://danstonchat.com/ Bienvenue DTC - Où ? Dans Ton Chat (BashFR) http://danstonchat.com/ 1358855535 +http://danstonchat.com/random0.html Au hasard mais au-dessus de zero DTC - Où ? Dans Ton Chat (BashFR) http://danstonchat.com/random0.html 1358855539 +http://localhost:8200/ MiniDLNA 1.0.25 http://localhost:8200/ 1359364186 +/backup/willy/quake/QUAKE3/Extras/Help/Index.htm Quake III Arena Help System file:///backup/willy/quake/QUAKE3/Extras/Help/Index.htm 1359382852 +/backup/willy/quake/QUAKE3/Extras/Help/Readme.htm Readme file:///backup/willy/quake/QUAKE3/Extras/Help/Readme.htm 1359382862 +http://localhost/tournament Gavroche's website http://localhost/tournament 1359468692 +http://localhost/lan/subscribe Gavroche's website http://localhost/lan/subscribe 1359474538 +http://localhost/lan Gavroche's website http://localhost/lan 1359474553 +http://localhost/ Gavroche's website http://localhost/ 1359474555 +http://freebox.z3bra.org/login.php Accueil Freebox Server http://freebox.z3bra.org/login.php 1360049292 +http://www.deezer.com/fr/ Musique à la demande, musique gratuite et illimitée sans téléchargement http://www.deezer.com/fr/ 1363450192 +http://z3bra.org/ Gavroche's website http://z3bra.org/ 1363982725 +/home/willy/.mutt/temp/mutt.html file:///home/willy/.mutt/temp/mutt.html 1366924201 +http://www.codingconfessional.com/ Coding Confessional http://www.codingconfessional.com/ 1367265056 +https://www.archlinux.org/packages/ Arch Linux - Package Database https://www.archlinux.org/packages/ 1367934731 +https://aur.archlinux.org/ AUR (en) - Home https://aur.archlinux.org/ 1367934736 +https://aur.archlinux.org/submit AUR (en) - Submit https://aur.archlinux.org/submit 1367934754 +https://aur.archlinux.org/login/ AUR (en) - AUR Login https://aur.archlinux.org/login/ 1367934759 +/home/willy/usr/doc/papers/factures/z3bra-org.html Nom de domaine et hébergement cloud - Gandi.net file:///home/willy/usr/doc/papers/factures/z3bra-org.html 1368445785 diff --git a/elinks/gotohist b/elinks/gotohist @@ -0,0 +1,32 @@ +http://mafreebox.freebox.fr/settings.php?page=net_redirs +www.goosh.org +www.duckduckgo +defrag.fr +www.danstonchat.com/random.html +exiled.lebonforum.com +facebook.com +z3bra.no-ip.org +http://z3bra.no-ip.org/gavroche/.?s=media +goosh.org +startpage.org +google.com +danstonchat.com/random.html +startpage.com +mafreebox.freebox.fr +z3bra.no-ip.org/gavroche +danstonchat.com +viedemerde.com +cdm.com +vdm.com +viedemerde.fr +api.allocine.fr/rest/v3/movie?code=56910&partner=YW5kcm9pZC12M3M +http://127.0.0.1/gavroche/.?s=media +192.168.0.254 +exiledclan.cwebh.org +127.0.0.1 +z3bra.no-ip.org/tournament +http://localhost:631 +http://localhost/lan/subscribe +http://localhost/lan +www.codingconfessional.com +https://aur.archlinux.org/submit diff --git a/elinks/searchhist b/elinks/searchhist @@ -0,0 +1,3 @@ +ratonn +rcon +z3bra diff --git a/evilwmrc b/evilwmrc @@ -0,0 +1,13 @@ +fn gelly +mask1 mod4 +mask2 alt +altmask shift +term urxvtc +snap 10 +bw 8 +fg #443c28 +fc #e8e9ca +bg #323232 +app wbar +fixed +dock diff --git a/irssi/default.theme b/irssi/default.theme @@ -0,0 +1,295 @@ +# {{{ +# When testing changes, the easiest way to reload the theme is with /RELOAD. +# This reloads the configuration file too, so if you did any changes remember +# to /SAVE it first. Remember also that /SAVE overwrites the theme file with +# old data so keep backups :) + +# TEMPLATES: + +# The real text formats that irssi uses are the ones you can find with +# /FORMAT command. Back in the old days all the colors and texts were mixed +# up in those formats, and it was really hard to change the colors since you +# might have had to change them in tens of different places. So, then came +# this templating system. + +# Now the /FORMATs don't have any colors in them, and they also have very +# little other styling. Most of the stuff you need to change is in this +# theme file. If you can't change something here, you can always go back +# to change the /FORMATs directly, they're also saved in these .theme files. + +# So .. the templates. They're those {blahblah} parts you see all over the +# /FORMATs and here. Their usage is simply {name parameter1 parameter2}. +# When irssi sees this kind of text, it goes to find "name" from abstracts +# block below and sets "parameter1" into $0 and "parameter2" into $1 (you +# can have more parameters of course). Templates can have subtemplates. +# Here's a small example: +# /FORMAT format hello {colorify {underline world}} +# abstracts = { colorify = "%G$0-%n"; underline = "%U$0-%U"; } +# When irssi expands the templates in "format", the final string would be: +# hello %G%Uworld%U%n +# ie. underlined bright green "world" text. +# and why "$0-", why not "$0"? $0 would only mean the first parameter, +# $0- means all the parameters. With {underline hello world} you'd really +# want to underline both of the words, not just the hello (and world would +# actually be removed entirely). + +# COLORS: + +# You can find definitions for the color format codes in docs/formats.txt. + +# There's one difference here though. %n format. Normally it means the +# default color of the terminal (white mostly), but here it means the +# "reset color back to the one it was in higher template". For example +# if there was /FORMAT test %g{foo}bar, and foo = "%Y$0%n", irssi would +# print yellow "foo" (as set with %Y) but "bar" would be green, which was +# set at the beginning before the {foo} template. If there wasn't the %g +# at start, the normal behaviour of %n would occur. If you _really_ want +# to use the terminal's default color, use %N. +# }}} + +############################################################################# + +# +# +# default foreground color (%N) - -1 is the "default terminal color" +default_color = "-1"; + +# print timestamp/servertag at the end of line, not at beginning +info_eol = "false"; + +# these characters are automatically replaced with specified color +# (dark grey by default) +replaces = { "[]" = "%g$*%n"; }; + +abstracts = { # {{{ + + ############# generic ############################### + + indent_default = "11"; + + # text to insert at the beginning of each non-message line + # line_start = "%g//%n "; + line_start = ""; + + # timestamp styling, nothing by default + timestamp = ""; + + # any kind of text that needs hilighting, default is to bold + hilight = "%_$*%_"; + + # any kind of error message, default is bright red + error = "%R$*%n"; + + # channel name is printed + channel = "%b$*%n"; + + # nick is printed + nick = "%_$*%_"; + + # nick host is printed + nickhost = "%g$*"; + + # server name is printed + server = "%_$*%_"; + + # some kind of comment is printed + comment = "%n(%b\"$*\"%n);"; + + # reason for something is printed (part, quit, kick, ..) + reason = "{comment $*}"; + + # mode change is printed ([+o nick]) + mode = "{comment $*}"; + + ## channel specific messages + + # highlighted nick/host is printed (joins) + channick_hilight = "%g$*%N"; + chanhost_hilight = "{nickhost $*}"; + + # nick/host is printed (parts, quits, etc.) + channick = "$*"; + chanhost = "{nickhost $*}"; + + # highlighted channel name is printed + channelhilight = "%g$*%n"; + + # ban/ban exception/invite list mask is printed + ban = "$*"; + + ########### messages ################################# + + # the basic styling of how to print message, $0 = nick mode, $1 = nick + # msgnick = "$1-$0%K·%N %|"; + msgnick = "%w$0%n $1 %w│%n %|"; + + # $0 = nick mode, $1 = nick + ownmsgnick = "{msgnick $0 $1}"; + ownnick = "%Y$*%n"; + + # public message in channel, $0 = nick mode, $1 = nick + pubmsgnick = "{msgnick $0 $1}"; + pubnick = "%N$*%n"; + + # public highlighted message in channel + pubmsghinick = "{msgnick $0 $1}%w"; + menick = "%R$*%n"; + + # channel name is printed with message + msgchannel = "%K:%m$*%n"; + + # private message, $0 = nick, $1 = host + privmsg = "$0=%b\"$1-\"%n "; + + # private message from you, $0 = "msg", $1 = target nick + ownprivmsg = "$0=%b\"$1-\"%n "; + + # private message in query + # privmsgnick = "{msgnick $*}"; + privmsgnick = "%g<%N %|"; + + # own private message in query + #ownprivmsgnick = "{privmsgnick $*}"; + ownprivmsgnick = "%r>%N %|"; + #ownprivnick = "$*"; + + + ########## Actions (/ME stuff) ######################### + + # generic one that's used by most actions + action = " %m$* %M* %m%|"; + + # own action, both private/public + # ownaction = "{action $*}"; + ownaction = " %m$* %M*%N%m"; + + # own action with target, both private/public + ownaction_target = "{action $*}"; + + # private action sent by others + pvtaction = "{action $*}"; + pvtaction_query = "{action $*}"; + + # public action sent by others + pubaction = "{action $*}"; + + + ########## other IRC events ############################# + + # whois + whois = "%# $[8]0 = $1-;"; + + # notices + ownnotice = "%NNote n = %Mnew%n $0 ($1-) "; + notice = "%M$*%n "; + pubnotice_channel = " %N($*)"; + pvtnotice_host = " %N($*)"; + servernotice = " %N($*)"; + + # CTCPs + ownctcp = "%NCTCP c = %Mnew%n $0 ($1-) "; + ctcp = "%N$*%n"; + + # wallops + wallop = "%K$*%n: "; + wallop_nick = "%n$*"; + wallop_action = "%K * $*%n "; + + # netsplits + netsplit = " %Knsplit %R< %b\"$*\"%n"; + netjoin = " %Knjoin %G> %b\"$*\"%n"; + + # /names list + names_prefix = "%Y!%K! names %Y!%n "; + names_nick = "%_$2$0%_%n$1- "; + names_nick_op = "{names_nick $* %R}"; + names_nick_halfop = "{names_nick $* %C}"; + names_nick_voice = "{names_nick $* %K}"; + names_users = "%Y!%K! names %Y!%n $1"; + names_channel = "\"%b$*\"%n"; + + # DCC + dcc = "%g$*%n"; + dccfile = "%_$*%_"; + + # DCC chat, own msg/action + dccownmsg = "%g /* $0 ($1-) */"; + dccownnick = "$*%n"; + dccownquerynick = "$*%n"; + dccownaction = "{action $*}"; + dccownaction_target = "{action $*}"; + + # DCC chat, others + dccmsg = "%g/* $1- ($0) */"; + dccquerynick = "%g$*%n"; + dccaction = "{action $*}"; + + ######## statusbar/topicbar ############################ + + # default background for all statusbars. You can also give + # the default foreground color for statusbar items. + sb_background = "%n"; + + # default background for "default" statusbar group + sb_prompt_bg = "%n"; + + prompt = "%w:%n "; + + sb = "$*"; + + # ',' separator + sb_act_sep = " "; + # normal text + sb_act_text = "%n$*"; + # public message + sb_act_msg = "%Y$*%n"; + # hilight + sb_act_hilight = "%r$*%n"; + # hilight with specified color, $0 = color, $1 = text + sb_act_hilight_color = "%r$1-%n"; +}; # }}} + +######################################################## + +formats = { # {{{ + "fe-common/core" = { # {{{ + line_start = "{line_start}"; + line_start_irssi = "{line_start}"; + + join = "%G>%K> join %g>%n {channick $0}"; + part = "%R<%K< part %r<%n {channick $0}"; + kick = "%R<%K< kicked %r<%n {channick $0}"; + quit = "%R<%K< quit %r<%n {channick $0}"; + quit_once = "{channel $3} {channick $0} {chanhost $1} %kquit {reason %C$2}"; + + nick_changed = "%K{channick $[-13]0} %G>%n {channick $1}"; + your_nick_changed = "%K you %G>%n {channick $1}"; + + pubmsg = "{pubmsgnick $2 {pubnick $[-11]0}}$1"; + + own_msg = "{ownmsgnick $2 {ownnick $[-11]0}}$1"; + own_msg_channel = "{ownmsgnick $3 {ownnick $[-11]0}{msgchannel $1}}$2"; + own_msg_private_query = "{ownprivmsgnick {ownprivnick $[-11]2}}$1"; + + pubmsg_me = "{pubmsghinick $2 {menick $[-11]0}}$1"; + pubmsg_me_channel = "{pubmsghinick $3 {menick $[-11]0}{msgchannel $1}}$2"; + + pubmsg_hilight = "{pubmsghinick $3 {menick $[-11]1}}$2"; + pubmsg_hilight_channel = "{pubmsghinick $0 $[-11]1$4{msgchannel $2}}$3"; + + pubmsg_channel = "{pubmsgnick {pubnick %G$[-11]0}$2}$1"; + msg_private_query = "{privmsgnick $[-11]0}$2"; + new_topic = " %ctopic %K= %|%B'$2' %non %b$1%n%K[set by {nick %y$0}]"; + + endofnames = "%Y!%K! names %Y!%m Total: {hilight $2} ops, {hilight $3} halfops, {hilight $4} voices, {hilight $5} normal%n"; + }; # }}} + "fe-common/irc" = { # {{{ + chanmode_change = "%Y!%K! mode %y!%n {channick $1}"; + server_chanmode_change = "%Y!%K! mode %y!%n {channick $1}"; + + own_action = "{ownaction $[-11]0} $1"; + action_private = "{pvtaction $[-11]0}$1"; + action_private_query = "{pvtaction_query $[-11]0} $2"; + action_public = "{pubaction $[-11]0}$1"; + }; # }}} +}; # }}} diff --git a/irssi/scripts/autorun/adv_windowlist.pl b/irssi/scripts/autorun/adv_windowlist.pl @@ -0,0 +1,2478 @@ +use strict; # use warnings; + +# {{{ debug + +#BEGIN { +# open STDERR, '>', '/home/ailin/wlstatwarnings'; +#}; + +# FIXME COULD SOMEONE PLEASE TELL ME HOW TO SHUT UP +# +# ... +# Variable "*" will not stay shared at (eval *) line *. +# Variable "*" will not stay shared at (eval *) line *. +# ... +# Can't locate package Irssi::Nick for @Irssi::Irc::Nick::ISA at (eval *) line *. +# ... +# +# THANKS + +# }}} + +# if you don't know how to operate folds, type zn + +# {{{ header + +use Irssi (); # which is the minimum required version of Irssi ? +use Irssi::TextUI; + +use vars qw($VERSION %IRSSI); + +$VERSION = '0.6ca'; +%IRSSI = ( + original_authors => q(BC-bd, Veli, Timo Sirainen, ). + q(Wouter Coekaerts, Jean-Yves Lefort), # (decadix) + original_contact => q(bd@bc-bd.org, veli@piipiip.net, tss@iki.fi, ). + q(wouter@coekaerts.be, jylefort@brutele.be), + authors => q(Nei), + contact => q(Nei @ anti@conference.jabber.teamidiot.de), + url => "http://anti.teamidiot.de/", + name => q(awl), + description => q(Adds a permanent advanced window list on the right or ). + q(in a statusbar.), + description2 => q(Based on chanact.pl which was apparently based on ). + q(lightbar.c and nicklist.pl with various other ideas ). + q(from random scripts.), + license => q(GNU GPLv2 or later), +); + +# }}} + +# {{{ *** D O C U M E N T A T I O N *** + +# adapted by Nei + +############### +# {{{ original comment +# ########### +# # Adds new powerful and customizable [Act: ...] item (chanelnames,modes,alias). +# # Lets you give alias characters to windows so that you can select those with +# # meta-<char>. +# # +# # for irssi 0.8.2 by bd@bc-bd.org +# # +# # inspired by chanlist.pl by 'cumol@hammerhart.de' +# # +# ######### +# # {{{ Contributors +# ######### +# # +# # veli@piipiip.net /window_alias code +# # qrczak@knm.org.pl chanact_abbreviate_names +# # qerub@home.se Extra chanact_show_mode and chanact_chop_status +# # }}} +# }}} +# +# {{{ FURTHER THANKS TO +# ############ +# # buu, fxn, Somni, Khisanth, integral, tybalt89 for much support in any aspect perl +# # and the channel in general ( #perl @ freenode ) and especially the ir_* functions +# # +# # Valentin 'senneth' Batz ( vb@g-23.org ) for the pointer to grep.pl, continuous support +# # and help in digging up ir_strip_codes +# # +# # OnetrixNET technology networks for the debian environment +# # +# # Monkey-Pirate.com / Spaceman Spiff for the webspace +# # +# }}} + +###### +# {{{ M A I N P R O B L E M +##### +# +# It is impossible to place the awl on a statusbar together with other items, +# because I do not know how to calculate the size that it is going to get +# granted, and therefore I cannot do the linebreaks properly. +# This is what is missing to make a nice script out of awl. +# If you have any ideas, please contact me ASAP :). +# }}} +###### + +###### +# {{{ UTF-8 PROBLEM +##### +# +# Please help me find a solution to this: +# this be your statusbar, it is using up the maximum term size +# [[1=1]#abc [2=2]#defghi] +# +# now consider this example:i +# "ascii" characters are marked with ., utf-8 characters with * +# [[1=1]#... [2=2]#...***] +# +# you should think that this is how it would be displayed? WRONG! +# [[1=1]#... [2=2]#...*** ] +# +# this is what Irssi does.. I believe my length calculating code to be correct, +# however, I'd love to be proven wrong (or receive any other fix, too, of +# course!) +# }}} +###### + +######### +# {{{ USAGE +### +# +# copy the script to ~/.irssi/scripts/ +# +# In irssi: +# +# /script load awl +# +# +# Hint: to get rid of the old [Act:] display +# /statusbar window remove act +# +# to get it back: +# /statusbar window add -after lag -priority 10 act +# }}} +########## +# {{{ OPTIONS +######## +# +# {{{ /set awl_display_nokey <string> +# /set awl_display_key <string> +# /set awl_display_nokey_active <string> +# /set awl_display_key_active <string> +# * string : Format String for one window. The following $'s are expanded: +# $C : Name +# $N : Number of the Window +# $Q : meta-Keymap +# $H : Start highlighting +# $S : Stop highlighting +# /+++++++++++++++++++++++++++++++++, +# | **** I M P O R T A N T : **** | +# | | +# | don't forget to use $S if you | +# | used $H before! | +# | | +# '+++++++++++++++++++++++++++++++++/ +# XXX NOTE ON *_active: there is a BUG somewhere in the length +# XXX calculation. currently it's best to NOT remove $H/$S from those +# XXX settings if you use it in the non-active settings. +# }}} +# {{{ /set awl_separator <string> +# * string : Charater to use between the channel entries +# you'll need to escape " " space and "$" like this: +# "/set awl_separator \ " +# "/set awl_separator \$" +# and {}% like this: +# "/set awl_separator %{" +# "/set awl_separator %}" +# "/set awl_separator %%" +# (reason being, that the separator is used inside a {format }) +# }}} +# {{{ /set awl_prefer_name <ON|OFF> +# * this setting decides whether awl will use the active_name (OFF) or the +# window name as the name/caption in awl_display_*. +# That way you can rename windows using /window name myownname. +# }}} +# {{{ /set awl_hide_data <num> +# * num : hide the window if its data_level is below num +# set it to 0 to basically disable this feature, +# 1 if you don't want windows without activity to be shown +# 2 to show only those windows with channel text or hilight +# 3 to show only windows with hilight +# }}} +# {{{ /set awl_maxlines <num> +# * num : number of lines to use for the window list (0 to disable, negative +# lock) +# }}} +# {{{ /set awl_columns <num> +# * num : number of columns to use in screen mode (0 for unlimited) +# }}} +# {{{ /set awl_block <num> +# * num : width of a column in screen mode (negative values = block display) +# /+++++++++++++++++++++++++++++++++, +# | ****** W A R N I N G ! ****** | +# | | +# | If your block display looks | +# | DISTORTED, you need to add the | +# | following line to your .theme | +# | file under | +# | abstracts = { : | +# | | +# | sb_act_none = "%n$*"; | +# | | +# '+++++++++++++++++++++++++++++++++/ +#.02:08:26. < shi> Irssi::current_theme()->get_format <.. can this be used? +# }}} +# {{{ /set awl_sbar_maxlength <ON|OFF> +# * if you enable the maxlength setting, the block width will be used as a +# maximum length for the non-block statusbar mode too. +# }}} +# {{{ /set awl_height_adjust <num> +# * num : how many lines to leave empty in screen mode +# }}} +# {{{ /set awl_sort <-data_level|-last_line|refnum> +# * you can change the window sort order with this variable +# -data_level : sort windows with hilight first +# -last_line : sort windows in order of activity +# refnum : sort windows by window number +# }}} +# {{{ /set awl_placement <top|bottom> +# /set awl_position <num> +# * these settings correspond to /statusbar because awl will create +# statusbars for you +# (see /help statusbar to learn more) +# }}} +# {{{ /set awl_all_disable <ON|OFF> +# * if you set awl_all_disable to ON, awl will also remove the +# last statusbar it created if it is empty. +# As you might guess, this only makes sense with awl_hide_data > 0 ;) +# }}} +# {{{ /set awl_automode <sbar|screen|emulate_lightbar> +# * this setting defines whether the window list is shown in statusbars or +# whether the screen hack is used (from nicklist.pl) +# }}} +# }}} +########## +# {{{ COMMANDS +######## +# {{{ /awl paste <ON|OFF|TOGGLE> +# * enables or disables the screen hack windowlist. This is useful when you +# want to mark & copy text that you want to paste somewhere (hence the +# name). (ON means AWL disabled!) +# This is nicely bound to a function key for example. +# }}} +# {{{ /awl redraw +# * redraws the screen hack windowlist. There are many occasions where the +# screen hack windowlist can get destroyed so you can use this command to +# fix it. +# }}} +# }}} +### +# {{{ WISHES +#### +# +# if you fiddle with my mess, provide me with your fixes so I can benefit as well +# +# Nei =^.^= ( anti@conference.jabber.teamidiot.de ) +# }}} + +# }}} + +# {{{ modules + +#use Class::Classless; +#use Term::Info; + +# }}} + +# {{{ global variables + +my $replaces = '[=]'; # AARGH!!! (chars that are always surrounded by weird + # colour codes by Irssi) + +my $actString = []; # statusbar texts +my $currentLines = 0; +my $resetNeeded; # layout/screen has changed, redo everything +my $needRemake; # "normal" changes +#my $callcount = 0; +sub GLOB_QUEUE_TIMER () { 100 } +my $globTime = undef; # timer to limit remake() calls + + +my $SCREEN_MODE; +my $DISABLE_SCREEN_TEMP; +my $currentColumns = 0; +my $screenResizing; +my ($screenHeight, $screenWidth); +my $screenansi = bless { + NAME => 'Screen::ANSI', + PARENTS => [], + METHODS => { + dcs => sub { "\033P" }, + st => sub { "\033\\"}, + } +}, 'Class::Classless::X'; +#my $terminfo = new Term::Info 'xterm'; # xterm here, make this modular +# {{{{{{{{{{{{{{{ +my $terminfo = bless { # xterm here, make this modular + NAME => 'Term::Info::xterm', + PARENTS => [], + METHODS => { + # civis=\E[?25l, + civis => sub { "\033[?25l" }, + # sc=\E7, + sc => sub { "\0337" }, + # cup=\E[%i%p1%d;%p2%dH, + cup => sub { shift;shift; "\033[" . ($_[0] + 1) . ';' . ($_[1] + 1) . 'H' }, + # el=\E[K, + el => sub { "\033[K" }, + # rc=\E8, + rc => sub { "\0338" }, + # cnorm=\E[?25h, + cnorm => sub { "\033[?25h" }, + # setab=\E[4%p1%dm, + setab => sub { shift;shift; "\033[4" . $_[0] . 'm' }, + # setaf=\E[3%p1%dm, + setaf => sub { shift;shift; "\033[3" . $_[0] . 'm' }, + # bold=\E[1m, + bold => sub { "\033[1m" }, + # blink=\E[5m, + blink => sub { "\033[5m" }, + # rev=\E[7m, + rev => sub { "\033[7m" }, + # op=\E[39;49m, + op => sub { "\033[39;49m" }, + } +}, 'Class::Classless::X'; +# }}}}}}}}}}}}}}} + + +sub setc () { + $IRSSI{'name'} +} +sub set ($) { + setc . '_' . shift +} + +# }}} + + +# {{{ sbar mode + +my %statusbars; # currently active statusbars + +# maybe I should just tie the array ? +sub add_statusbar { + for (@_) { + # add subs + for my $l ($_) { { + no strict 'refs'; # :P + *{set$l} = sub { awl($l, @_) }; + }; } + Irssi::command('statusbar ' . (set$_) . ' reset'); + Irssi::command('statusbar ' . (set$_) . ' enable'); + if (lc Irssi::settings_get_str(set 'placement') eq 'top') { + Irssi::command('statusbar ' . (set$_) . ' placement top'); + } + if ((my $x = int Irssi::settings_get_int(set 'position')) != 0) { + Irssi::command('statusbar ' . (set$_) . ' position ' . $x); + } + Irssi::command('statusbar ' . (set$_) . ' add -priority 100 -alignment left barstart'); + Irssi::command('statusbar ' . (set$_) . ' add ' . (set$_)); + Irssi::command('statusbar ' . (set$_) . ' add -priority 100 -alignment right barend'); + Irssi::command('statusbar ' . (set$_) . ' disable'); + Irssi::statusbar_item_register(set$_, '$0', set$_); + $statusbars{$_} = {}; + } +} + +sub remove_statusbar { + for (@_) { + Irssi::command('statusbar ' . (set$_) . ' reset'); + Irssi::statusbar_item_unregister(set$_); # XXX does this actually work ? + # DO NOT REMOVE the sub before you have unregistered it :)) + for my $l ($_) { { + no strict 'refs'; + undef &{set$l}; + }; } + delete $statusbars{$_}; + } +} + +sub syncLines { + my $temp = $currentLines; + $currentLines = @$actString; + #Irssi::print("current lines: $temp new lines: $currentLines"); + my $currMaxLines = Irssi::settings_get_int(set 'maxlines'); + if ($currMaxLines > 0 and @$actString > $currMaxLines) { + $currentLines = $currMaxLines; + } + elsif ($currMaxLines < 0) { + $currentLines = abs($currMaxLines); + } + return if ($temp == $currentLines); + if ($currentLines > $temp) { + for ($temp .. ($currentLines - 1)) { + add_statusbar($_); + Irssi::command('statusbar ' . (set$_) . ' enable'); + } + } + else { + for ($_ = ($temp - 1); $_ >= $currentLines; $_--) { + Irssi::command('statusbar ' . (set$_) . ' disable'); + remove_statusbar($_); + } + } +} + +# FIXME implement $get_size_only check, and user $item->{min|max-size} ?? +sub awl { + my ($line, $item, $get_size_only) = @_; + + if ($needRemake) { + $needRemake = undef; + remake(); + } + + my $text = $actString->[$line]; # DO NOT set the actual $actString->[$line] to '' here or + $text = '' unless defined $text; # you'll screw up the statusbar counter ($currentLines) + $item->default_handler($get_size_only, $text, '', 1); +} + +# remove old statusbars +my %killBar; +sub get_old_status { + my ($textDest, $cont, $cont_stripped) = @_; + if ($textDest->{'level'} == 524288 and $textDest->{'target'} eq '' + and !defined($textDest->{'server'}) + ) { + my $name = quotemeta(set ''); + if ($cont_stripped =~ m/^$name(\d+)\s/) { $killBar{$1} = {}; } + Irssi::signal_stop(); + } +} +sub killOldStatus { + %killBar = (); + Irssi::signal_add_first('print text' => 'get_old_status'); + Irssi::command('statusbar'); + Irssi::signal_remove('print text' => 'get_old_status'); + remove_statusbar(keys %killBar); +} +#killOldStatus(); + +# end sbar mode }}} + + +# {{{ keymaps + +my %keymap; + +sub get_keymap { + my ($textDest, undef, $cont_stripped) = @_; + if ($textDest->{'level'} == 524288 and $textDest->{'target'} eq '' + and !defined($textDest->{'server'}) + ) { + if ($cont_stripped =~ m/((?:meta-)+)(.)\s+change_window (\d+)/) { + my ($level, $key, $window) = ($1, $2, $3); + my $numlevel = ($level =~ y/-//) - 1; + $keymap{$window} = ('-' x $numlevel) . "$key"; + } + Irssi::signal_stop(); + } +} + +sub update_keymap { + %keymap = (); + Irssi::signal_remove('command bind' => 'watch_keymap'); + Irssi::signal_add_first('print text' => 'get_keymap'); + Irssi::command('bind'); # stolen from grep + Irssi::signal_remove('print text' => 'get_keymap'); + Irssi::signal_add('command bind' => 'watch_keymap'); + Irssi::timeout_add_once(100, 'eventChanged', undef); +} + +# watch keymap changes +sub watch_keymap { + Irssi::timeout_add_once(1000, 'update_keymap', undef); +} + +update_keymap(); + +# end keymaps }}} + +# {{{ format handling + +# a bad way do do expansions but who cares +sub expand { + my ($string, %format) = @_; + my ($exp, $repl); + $string =~ s/\$$exp/$repl/g while (($exp, $repl) = each(%format)); + return $string; +} + +my %strip_table = ( + # fe-common::core::formats.c:format_expand_styles + # delete format_backs format_fores bold_fores other stuff + (map { $_ => '' } (split //, '04261537' . 'kbgcrmyw' . 'KBGCRMYW' . 'U9_8:|FnN>#[')), + # escape + (map { $_ => $_ } (split //, '{}%')), +); +sub ir_strip_codes { # strip %codes + my $o = shift; + $o =~ s/(%(.))/exists $strip_table{$2} ? $strip_table{$2} : $1/gex; + $o +} + +sub ir_parse_special { + my $o; my $i = shift; + #if ($_[0]) { # for the future?!? + # eval { + # $o = $_[0]->parse_special($i); + # }; + # unless ($@) { + # return $o; + # } + #} + my $win = shift || Irssi::active_win(); + my $server = Irssi::active_server(); + if (ref $win and ref $win->{'active'}) { + $o = $win->{'active'}->parse_special($i); + } + elsif (ref $win and ref $win->{'active_server'}) { + $o = $win->{'active_server'}->parse_special($i); + } + elsif (ref $server) { + $o = $server->parse_special($i); + } + else { + $o = Irssi::parse_special($i); + } + $o +} +sub ir_parse_special_protected { + my $o; my $i = shift; + $i =~ s/ + ( \\. ) | # skip over escapes (maybe) + ( \$[^% $\]+ ) # catch special variables + / + if ($1) { $1 } + elsif ($2) { my $i2 = $2; ir_fe(ir_parse_special($i2, @_)) } + else { $& } + /gex; + $i +} + + +sub sb_ctfe { # Irssi::current_theme->format_expand wrapper + Irssi::current_theme->format_expand( + shift, + ( + Irssi::EXPAND_FLAG_IGNORE_REPLACES + | + ($_[0]?0:Irssi::EXPAND_FLAG_IGNORE_EMPTY) + ) + ) +} +sub sb_expand { # expand {format }s (and apply parse_special for $vars) + ir_parse_special( + sb_ctfe(shift) + ) +} +sub sb_strip { + ir_strip_codes( + sb_expand(shift) + ); # does this get us the actual length of that s*ty bar :P ? +} +sub sb_length { + # unicode cludge, d*mn broken Irssi + # screw it, this will fail from broken joining anyway (and cause warnings) + my $term_type = 'term_type'; + if (Irssi::version > 20040819) { # this is probably wrong, but I don't know + # when the setting name got changed + $term_type = 'term_charset'; + } + #if (lc Irssi::settings_get_str($term_type) eq '8bit' + # or Irssi::settings_get_str($term_type) =~ /^iso/i + #) { + # length(sb_strip(shift)) + #} + #else { + my $temp = sb_strip(shift); + # try to get the displayed width + my $length; + eval { + require Text::CharWidth; + $length = Text::CharWidth::mbswidth($temp); + }; + unless ($@) { + return $length; + } + else { + if (lc Irssi::settings_get_str($term_type) eq 'utf-8') { + # try to switch on utf8 + eval { + no warnings; + require Encode; + #$temp = Encode::decode_utf8($temp); # thanks for the hint, but I have my + # # reasons for _utf8_on + Encode::_utf8_on($temp); + }; + } + # there is nothing more I can do + length($temp) + } + #} +} + +# !!! G*DD*MN Irssi is adding an additional layer of backslashitis per { } layer +# !!! AND I still don't know what I need to escape. +# !!! and NOONE else seems to know or care either. +# !!! f*ck open source. I mean it. +# XXX any Irssi::print debug statement leads to SEGFAULT - why ? + +# major parts of the idea by buu (#perl @ freenode) +# thanks to fxn and Somni for debugging +# while ($_[0] =~ /(.)/g) { +# my $c = $1; # XXX sooo... goto kills $1 +# if ($q eq '%') { goto ESC; } + +## <freenode:#perl:tybalt89> s/%(.)|(\{)|(\})|(\\|\$)/$1?$1:$2?($level++,$2):$3?($level>$min_level&&$level--,$3):'\\'x(2**$level-1).$4/ge; # untested... +sub ir_escape { + my $min_level = $_[1] || 0; my $level = $min_level; + my $o = shift; + $o =~ s/ + ( %. ) | # $1 + ( \{ ) | # $2 + ( \} ) | # $3 + ( \\ ) | # $4 + ( \$(?=[^\\]) ) | # $5 + ( \$ ) # $6 + / + if ($1) { $1 } # %. escape + elsif ($2) { $level++; $2 } # { nesting start + elsif ($3) { if ($level > $min_level) { $level--; } $3 } # } nesting end + elsif ($4) { '\\'x(2**$level) } # \ needs \\escaping + elsif ($5) { '\\'x(2**$level-1) . '$' . '\\'x(2**$level-1) } # and $ needs even more because of "parse_special" + else { '\\'x(2**$level-1) . '$' } # $ needs \$ escaping + /gex; + $o +} +#sub ir_escape { +# my $min_level = $_[1] || 0; my $level = $min_level; +# my $o = shift; +# $o =~ s/ +# ( %. ) | # $1 +# ( \{ ) | # $2 +# ( \} ) | # $3 +# ( \\ | \$ ) # $4 +# / +# if ($1) { $1 } # %. escape +# elsif ($2) { $level++; $2 } # { nesting start +# elsif ($3) { if ($level > $min_level) { $level--; } $3 } # } nesting end +# else { '\\'x(2**($level-1)-1) . $4 } # \ or $ needs \\escaping +# /gex; +# $o +#} + +sub ir_fe { # try to fix format stuff + my $x = shift; + # XXX why do I have to use two/four % here instead of one/two ?? + # answer: you screwed up in ir_escape + $x =~ s/([%{}])/%$1/g; + #$x =~ s/(\\|\$|[ ])/\\$1/g; # XXX HOW CAN I HANDLE THE SPACES CORRECTLY XXX + $x =~ s/(\\|\$)/\\$1/g; + #$x =~ s/(\$(?=.))|(\$)/$1?"\\\$\\":"\\\$"/ge; # I think this should be here + # # (logic), but it doesn't work + # # that way :P + #$x =~ s/\\/\\\\/g; # that's right, escape escapes + $x +} +sub ir_ve { # escapes special vars but leave colours alone + my $x = shift; + #$x =~ s/([%{}])/%$1/g; + $x =~ s/(\\|\$|[ ])/\\$1/g; + $x +} + +my %ansi_table; +{ + my ($i, $j, $k) = (0, 0, 0); + %ansi_table = ( + # fe-common::core::formats.c:format_expand_styles + # do format_backs + (map { $_ => $terminfo->setab($i++) } (split //, '01234567' )), + # do format_fores + (map { $_ => $terminfo->setaf($j++) } (split //, 'krgybmcw' )), + # do bold_fores + (map { $_ => $terminfo->bold() . + $terminfo->setaf($k++) } (split //, 'KRGYBMCW')), + # reset + #(map { $_ => $terminfo->op() } (split //, 'nN')), + (map { $_ => $terminfo->op() } (split //, 'n')), + (map { $_ => "\033[0m" } (split //, 'N')), # XXX quick and DIRTY + # flash/bright + F => $terminfo->blink(), + # reverse + 8 => $terminfo->rev(), + # bold + (map { $_ => $terminfo->bold() } (split //, '9_')), + # delete other stuff + (map { $_ => '' } (split //, ':|>#[')), + # escape + (map { $_ => $_ } (split //, '{}%')), + ) +} +sub formats_to_ansi_basic { + my $o = shift; + $o =~ s/(%(.))/exists $ansi_table{$2} ? $ansi_table{$2} : $1/gex; + $o +} + +sub lc1459 ($) { my $x = shift; $x =~ y/A-Z][\^/a-z}{|~/; $x } +Irssi::settings_add_str(setc, 'banned_channels', ''); +Irssi::settings_add_bool(setc, 'banned_channels_on', 0); +my %banned_channels = map { lc1459($_) => undef } +split ' ', Irssi::settings_get_str('banned_channels'); +Irssi::settings_add_str(setc, 'fancy_abbrev', 'fancy'); + +# }}} + +# {{{ main + +sub remake () { + #$callcount++; + #my $xx = $callcount; Irssi::print("starting remake [ $xx ]"); + my ($hilight, $number, $display); + my $separator = '{sb_act_sep ' . Irssi::settings_get_str(set 'separator') . + '}'; + my $custSort = Irssi::settings_get_str(set 'sort'); + my $custSortDir = 1; + if ($custSort =~ /^[-!](.*)/) { + $custSortDir = -1; + $custSort = $1; + } + + my @wins = + sort { + ( + ( (int($a->{$custSort}) <=> int($b->{$custSort})) * $custSortDir ) + || + ($a->{'refnum'} <=> $b->{'refnum'}) + ) + } Irssi::windows; + my $block = Irssi::settings_get_int(set 'block'); + my $columns = $currentColumns; + my $oldActString = $actString if $SCREEN_MODE; + $actString = $SCREEN_MODE ? [' A W L'] : []; + my $line = $SCREEN_MODE ? 1 : 0; + my $width = $SCREEN_MODE + ? + $screenWidth - abs($block)*$columns + 1 + : + ([Irssi::windows]->[0]{'width'} - sb_length('{sb x}')); + my $height = $screenHeight - abs(Irssi::settings_get_int(set + 'height_adjust')); + my ($numPad, $keyPad) = (0, 0); + my %abbrevList; + if ($SCREEN_MODE or Irssi::settings_get_bool(set 'sbar_maxlength') + or ($block < 0) + ) { + %abbrevList = (); + if (Irssi::settings_get_str('fancy_abbrev') !~ /^(no|off|head)/i) { + my @nameList = map { ref $_ ? $_->get_active_name : '' } @wins; + for (my $i = 0; $i < @nameList - 1; ++$i) { + my ($x, $y) = ($nameList[$i], $nameList[$i + 1]); + for ($x, $y) { s/^[+#!=]// } + my $res = Algorithm::LCSS::LCSS($x, $y); + if (defined $res) { + #Irssi::print("common pattern $x $y : $res"); + #Irssi::print("found at $nameList[$i] ".index($nameList[$i], + # $res)); + $abbrevList{$nameList[$i]} = int (index($nameList[$i], $res) + + (length($res) / 2)); + #Irssi::print("found at ".$nameList[$i+1]." ".index($nameList[$i+1], + # $res)); + $abbrevList{$nameList[$i+1]} = int (index($nameList[$i+1], $res) + + (length($res) / 2)); + } + } + } + if ($SCREEN_MODE or ($block < 0)) { + $numPad = length((sort { length($b) <=> length($a) } keys %keymap)[0]); + $keyPad = length((sort { length($b) <=> length($a) } values %keymap)[0]); + } + } + if ($SCREEN_MODE) { + print STDERR $screenansi->dcs(). + $terminfo->civis(). + $terminfo->sc(). + $screenansi->st(); + if (@$oldActString < 1) { + print STDERR $screenansi->dcs(). + $terminfo->cup(0, $width). + $actString->[0]. + $terminfo->el(). + $screenansi->st(); + } + } + foreach my $win (@wins) { + unless ($SCREEN_MODE) { + $actString->[$line] = '' unless defined $actString->[$line] + or Irssi::settings_get_bool(set 'all_disable'); + } + + # all stolen from chanact, what does this code do and why do we need it ? + !ref($win) && next; + + my $name = $win->get_active_name; + $name = '*' if (Irssi::settings_get_bool('banned_channels_on') and exists + $banned_channels{lc1459($name)}); + $name = $win->{'name'} if $name ne '*' and $win->{'name'} ne '' + and Irssi::settings_get_bool(set 'prefer_name'); + my $active = $win->{'active'}; + my $colour = $win->{'hilight_color'}; + if (!defined $colour) { $colour = ''; } + + if ($win->{'data_level'} < Irssi::settings_get_int(set 'hide_data')) { + next; } # for Geert + if ($win->{'data_level'} == 0) { $hilight = '{sb_act_none '; } + elsif ($win->{'data_level'} == 1) { $hilight = '{sb_act_text '; } + elsif ($win->{'data_level'} == 2) { $hilight = '{sb_act_msg '; } + elsif ($colour ne '') { $hilight = "{sb_act_hilight_color $colour "; } + elsif ($win->{'data_level'} == 3) { $hilight = '{sb_act_hilight '; } + else { $hilight = '{sb_act_special '; } + + $number = $win->{'refnum'}; + my @display = ('display_nokey'); + if (defined $keymap{$number} and $keymap{$number} ne '') { + unshift @display, map { (my $cpy = $_) =~ s/_no/_/; $cpy } @display; + } + if (Irssi::active_win->{'refnum'} == $number) { + unshift @display, map { my $cpy = $_; $cpy .= '_active'; $cpy } @display; + } + #Irssi::print("win $number [@display]: " . join '.', split //, join '<<', map { + # Irssi::settings_get_str(set $_) } @display); + $display = (grep { $_ } + map { Irssi::settings_get_str(set $_) } + @display)[0]; + #Irssi::print("win $number : " . join '.', split //, $display); + + if ($SCREEN_MODE or Irssi::settings_get_bool(set 'sbar_maxlength') + or ($block < 0) + ) { + my $baseLength = sb_length(ir_escape(ir_ve(ir_parse_special_protected(sb_ctfe( + '{sb_background}' . expand($display, + C => ir_fe('x'), + N => $number . (' 'x($numPad - length($number))), + Q => ir_fe((' 'x($keyPad - length($keymap{$number}))) . $keymap{$number}), + H => $hilight, + S => '}{sb_background}' + ), 1), $win)))) - 1; + my $diff = abs($block) - (length($name) + $baseLength); + if ($diff < 0) { # too long + if (abs($diff) >= length($name)) { $name = '' } # forget it + elsif (abs($diff) + 1 >= length($name)) { $name = substr($name, + 0, 1); } + else { + my $middle = exists $abbrevList{$name} ? + (($abbrevList{$name} + (2*(length($name) / 2)))/3) : + ((Irssi::settings_get_str('fancy_abbrev') =~ /^head/i) ? + length($name) : + (length($name) / 2)); + my $cut = int($middle - (abs($diff) / 2) + .55); + $cut = 1 if $cut < 1; + $cut = length($name) - abs($diff) - 1 if $cut > (length($name) - + abs($diff) - 1); + $name = substr($name, 0, $cut) . '~' . substr($name, $cut + + abs($diff) + 1); + } + } + elsif ($SCREEN_MODE or ($block < 0)) { + $name .= (' ' x $diff); + } + } + + my $add = ir_ve(ir_parse_special_protected(sb_ctfe('{sb_background}' . expand($display, + C => ir_fe($name), + N => $number . (' 'x($numPad - length($number))), + Q => ir_fe((' 'x($keyPad - length($keymap{$number}))) . $keymap{$number}), + H => $hilight, + S => '}{sb_background}' + ), 1), $win)); + if ($SCREEN_MODE) { + $actString->[$line] = $add; + if ((!defined $oldActString->[$line] + or $oldActString->[$line] ne $actString->[$line]) + and + $line <= ($columns * $height) + ) { + print STDERR $screenansi->dcs(). + $terminfo->cup(($line-1) % $height+1, $width + ( + abs($block) * int(($line-1) / $height))). + formats_to_ansi_basic(sb_expand(ir_escape($actString->[$line]))). + #$terminfo->el(). + $screenansi->st(); + } + $line++; + } + else { + #$temp =~ s/\{\S+?(?:\s(.*?))?\}/$1/g; + #$temp =~ s/\\\\\\\\/\\/g; # XXX I'm actually guessing here, someone point me + # # XXX to docs please + $actString->[$line] = '' unless defined $actString->[$line]; + + # XXX how can I check whether the content still fits in the bar? this would + # XXX allow awlstatus to reside on a statusbar together with other items... + if (sb_length(ir_escape($actString->[$line] . $add)) >= $width) { + # XXX doesn't correctly handle utf-8 multibyte ... help !!? + $actString->[$line] .= ' ' x ($width - sb_length(ir_escape( + $actString->[$line]))); + $line++; + } + $actString->[$line] .= $add . $separator; + # XXX if I use these prints, output layout gets screwed up... why ? + #Irssi::print("line $line: ".$actString->[$line]); + #Irssi::print("temp $line: ".$temp); + } + } + + if ($SCREEN_MODE) { + while ($line <= ($columns * $height)) { + print STDERR $screenansi->dcs(). + $terminfo->cup(($line-1) % $height+1, $width + ( + abs($block) * int(($line-1) / $height))). + $terminfo->el(). + $screenansi->st(); + $line++; + } + print STDERR $screenansi->dcs(). + $terminfo->rc(). + $terminfo->cnorm(). + $screenansi->st(); + } + else { + # XXX the Irssi::print statements lead to the MOST WEIRD results + # e.g.: the loop gets executed TWICE for p > 0 ?!? + for (my $p = 0; $p < @$actString; $p++) { # wrap each line in {sb }, escape it + my $x = $actString->[$p]; # properly, etc. + $x =~ s/\Q$separator\E([ ]*)$/$1/; + #Irssi::print("[$p]".'current:'.join'.',split//,sb_strip(ir_escape($x,0))); + #Irssi::print("assumed length before:".sb_length(ir_escape($x,0))); + $x = "{sb $x}"; + #Irssi::print("[$p]".'new:'.join'.',split//,sb_expand(ir_escape($x,0))); + #Irssi::print("[$p]".'new:'.join'.',split//,ir_escape($x,0)); + #Irssi::print("assumed length after:".sb_length(ir_escape($x,0))); + $x = ir_escape($x); + #Irssi::print("[$p]".'REALnew:'.join'.',split//,sb_strip($x)); + $actString->[$p] = $x; + # XXX any Irssi::print debug statement leads to SEGFAULT (sometimes) - why ? + } + } + #Irssi::print("remake [ $xx ] finished"); +} + +sub awlHasChanged () { + $globTime = undef; + my $temp = ($SCREEN_MODE ? + "\\\n" . Irssi::settings_get_int(set 'block'). + Irssi::settings_get_int(set 'height_adjust') + : "!\n" . Irssi::settings_get_str(set 'placement'). + Irssi::settings_get_int(set 'position')). + Irssi::settings_get_str(set 'automode'); + if ($temp ne $resetNeeded) { wlreset(); return; } + #Irssi::print("awl has changed, calls to remake so far: $callcount"); + $needRemake = 1; + + #remake(); + if ( + ($SCREEN_MODE and !$DISABLE_SCREEN_TEMP) + or + ($needRemake and Irssi::settings_get_bool(set 'all_disable')) + or + (!Irssi::settings_get_bool(set 'all_disable') and $currentLines < 1) + ) { + $needRemake = undef; + remake(); + } + + unless ($SCREEN_MODE) { + # XXX Irssi crashes if I try to do this without timer, why ? What's the minimum + # XXX delay I need to use in the timer ? + Irssi::timeout_add_once(100, 'syncLines', undef); + + for (keys %statusbars) { + Irssi::statusbar_items_redraw(set$_); + } + } + else { + Irssi::timeout_add_once(100, 'syncColumns', undef); + } +} + +sub eventChanged () { # Implement a change queue/blocker -.-) + if (defined $globTime) { + Irssi::timeout_remove($globTime); + } # delay the update further + $globTime = Irssi::timeout_add_once(GLOB_QUEUE_TIMER, 'awlHasChanged', undef); +} + +# }}} + + +# {{{ screen mode + +sub screenFullRedraw { + my ($window) = @_; + if (!ref $window or $window->{'refnum'} == Irssi::active_win->{'refnum'}) { + $actString = []; + eventChanged(); + } +} + +sub screenSize { # from nicklist.pl + $screenResizing = 1; + # fit screen + system 'screen -x '.$ENV{'STY'}.' -X fit'; + # get size + my ($row, $col) = split ' ', `stty size`; + # set screen width + $screenWidth = $col-1; + $screenHeight = $row-1; + + # on some recent systems, "screen -X fit; screen -X width -w 50" doesn't work, needs a sleep in between the 2 commands + # so we wait a second before setting the width + Irssi::timeout_add_once(100, sub { + my ($new_irssi_width) = @_; + $new_irssi_width -= abs(Irssi::settings_get_int(set + 'block'))*$currentColumns - 1; + system 'screen -x '.$ENV{'STY'}.' -X width -w ' . $new_irssi_width; + # and then we wait another second for the resizing, and then redraw. + Irssi::timeout_add_once(10,sub {$screenResizing = 0; screenFullRedraw()}, []); + }, $screenWidth); +} + +sub screenOff { + my ($unloadMode) = @_; + Irssi::signal_remove('gui print text finished' => 'screenFullRedraw'); + Irssi::signal_remove('gui page scrolled' => 'screenFullRedraw'); + Irssi::signal_remove('window changed' => 'screenFullRedraw'); + Irssi::signal_remove('window changed automatic' => 'screenFullRedraw'); + if ($unloadMode) { + Irssi::signal_remove('terminal resized' => 'resizeTerm'); + } + system 'screen -x '.$ENV{'STY'}.' -X fit'; +} + +sub syncColumns { + return if (@$actString == 0); + my $temp = $currentColumns; + #Irssi::print("current columns $temp"); + my $height = $screenHeight - abs(Irssi::settings_get_int(set + 'height_adjust')); + $currentColumns = int(($#$actString-1) / $height) + 1; + #Irssi::print("objects in actstring:".scalar(@$actString).", screen height:". + # $height); + my $currMaxColumns = Irssi::settings_get_int(set 'columns'); + if ($currMaxColumns > 0 and $currentColumns > $currMaxColumns) { + $currentColumns = $currMaxColumns; + } + elsif ($currMaxColumns < 0) { + $currentColumns = abs($currMaxColumns); + } + return if ($temp == $currentColumns); + screenSize(); +} + +#$needRemake = 1; +sub resizeTerm () { + if ($SCREEN_MODE and !$screenResizing) { + $screenResizing = 1; + Irssi::timeout_add_once(10, 'screenSize', undef); + } + Irssi::timeout_add_once(100, 'eventChanged', undef); +} + +# }}} + + +# {{{ settings add + +Irssi::settings_add_str(setc, set 'display_nokey', '[$N]$H$C$S'); +Irssi::settings_add_str(setc, set 'display_key', '[$Q=$N]$H$C$S'); +Irssi::settings_add_str(setc, set 'display_nokey_active', ''); +Irssi::settings_add_str(setc, set 'display_key_active', ''); +Irssi::settings_add_str(setc, set 'separator', "\\ "); +Irssi::settings_add_bool(setc, set 'prefer_name', 0); +Irssi::settings_add_int(setc, set 'hide_data', 0); +Irssi::settings_add_int(setc, set 'maxlines', 9); +Irssi::settings_add_int(setc, set 'columns', 1); +Irssi::settings_add_int(setc, set 'block', 20); +Irssi::settings_add_bool(setc, set 'sbar_maxlength', 0); +Irssi::settings_add_int(setc, set 'height_adjust', 2); +Irssi::settings_add_str(setc, set 'sort', 'refnum'); +Irssi::settings_add_str(setc, set 'placement', 'bottom'); +Irssi::settings_add_int(setc, set 'position', 0); +Irssi::settings_add_bool(setc, set 'all_disable', 0); +Irssi::settings_add_str(setc, set 'automode', 'sbar'); + +# }}} + + +# {{{ init + +sub wlreset { + $actString = []; + $currentLines = 0; # 1; # mhmmmm .. we actually enable one line down there so + # let's try this. + #update_keymap(); + killOldStatus(); + # Register statusbar + #add_statusbar(0); + #Irssi::command('statusbar wl0 enable'); + my $was_screen_mode = $SCREEN_MODE; + if ($SCREEN_MODE = (Irssi::settings_get_str(set 'automode') =~ /screen/i) + and + !$was_screen_mode + ) { + if (!defined $ENV{'STY'}) { + Irssi::print('Screen mode can only be used in GNU screen but no '. + 'screen was found.', MSGLEVEL_CLIENTERROR); + $SCREEN_MODE = undef; + } + else { + Irssi::signal_add_last('gui print text finished' => 'screenFullRedraw'); + Irssi::signal_add_last('gui page scrolled' => 'screenFullRedraw'); + Irssi::signal_add('window changed' => 'screenFullRedraw'); + Irssi::signal_add('window changed automatic' => 'screenFullRedraw'); + } + } + elsif ($was_screen_mode and !$SCREEN_MODE) { + screenOff(); + } + $resetNeeded = ($SCREEN_MODE ? + "\\\n" . Irssi::settings_get_int(set 'block'). + Irssi::settings_get_int(set 'height_adjust') + : "!\n" . Irssi::settings_get_str(set 'placement'). + Irssi::settings_get_int(set 'position')). + Irssi::settings_get_str(set 'automode'); + resizeTerm(); +} + +wlreset(); + +# }}} + + +# {{{ unload/deinit + +my $Unload; +sub unload ($$$) { + $Unload = 1; + # pretend we didn't do anything ASAP + Irssi::timeout_add_once(10, sub { $Unload = undef; }, undef); +} +# last try to catch a sigsegv +Irssi::signal_add_first('gui exit' => sub { $Unload = undef; }); +sub UNLOAD { + # this might well crash Irssi... try /eval /script unload someotherscript ; + # /quit (= SEGFAULT !) + if ($Unload) { + $actString = ['']; # syncLines(); # XXX Irssi crashes when trying to disable + killOldStatus(); # XXX all statusbars ? + if ($SCREEN_MODE) { + screenOff('unload mode'); + } + } +} + +# }}} + + +# {{{ signals + +sub addPrintTextHook { # update on print text + return if $_[0]->{'level'} == 262144 and $_[0]->{'target'} eq '' + and !defined($_[0]->{'server'}); + if (Irssi::settings_get_str(set 'sort') =~ /^[-!]?last_line$/) { + Irssi::timeout_add_once(100, 'eventChanged', undef); + } +} + +#sub _x { my ($x, $y) = @_; ($x, sub { Irssi::print('-->signal '.$x); eval "$y();"; }) } +#sub _x { @_ } +Irssi::signal_add_first( + 'command script unload' => 'unload' +); +Irssi::signal_add_last({ + 'setup changed' => 'eventChanged', + 'print text' => 'addPrintTextHook', + 'terminal resized' => 'resizeTerm', + 'setup reread' => 'wlreset', + 'window hilight' => 'eventChanged', +}); +Irssi::signal_add({ + 'window created' => 'eventChanged', + 'window destroyed' => 'eventChanged', + 'window name changed' => 'eventChanged', + 'window refnum changed' => 'eventChanged', + 'window changed' => 'eventChanged', + 'window changed automatic' => 'eventChanged', +}); + +#Irssi::signal_add('nick mode changed', 'chanactHasChanged'); # relicts + +# }}} + +# {{{ commands + + +sub runsub { + my ($cmd) = @_; + sub { + my ($data, $server, $item) = @_; + Irssi::command_runsub($cmd, $data, $server, $item); + }; +} +Irssi::command_bind( setc() => runsub(setc()) ); +Irssi::command_bind( setc() . ' paste' => runsub(setc() . ' paste') ); +Irssi::command_bind( + setc() . ' paste on' => sub { + return unless $SCREEN_MODE; + my $was_disabled = $DISABLE_SCREEN_TEMP; + $DISABLE_SCREEN_TEMP = 1; + Irssi::print('Paste mode is now ON, '.uc(setc()).' is temporarily '. + 'disabled.'); + if (!$was_disabled) { + $screenResizing = 1; + screenOff(); + } + } +); +Irssi::command_bind( + setc() . ' paste off' => sub { + return unless $SCREEN_MODE; + my $was_disabled = $DISABLE_SCREEN_TEMP; + $DISABLE_SCREEN_TEMP = undef; + Irssi::print('Paste mode is now OFF, '.uc(setc()).' is enabled.'); + if ($was_disabled) { + $SCREEN_MODE = undef; + $screenResizing = 0; + wlreset(); + } + } +); +Irssi::command_bind( + setc() . ' paste toggle' => sub { + if ($DISABLE_SCREEN_TEMP) { + Irssi::command(setc() . ' paste off'); + } + else { + Irssi::command(setc() . ' paste on'); + } + } +); +Irssi::command_bind( + setc() . ' redraw' => sub { + return unless $SCREEN_MODE; + screenFullRedraw(); + } +); + + +# }}} + +# {{{ Algorithm::LCSS module +{ + package Algorithm::Diff; + # Skip to first "=head" line for documentation. + use strict; + + use integer; # see below in _replaceNextLargerWith() for mod to make + # if you don't use this + + # McIlroy-Hunt diff algorithm + # Adapted from the Smalltalk code of Mario I. Wolczko, <mario@wolczko.com> + # by Ned Konz, perl@bike-nomad.com + # Updates by Tye McQueen, http://perlmonks.org/?node=tye + + # Create a hash that maps each element of $aCollection to the set of + # positions it occupies in $aCollection, restricted to the elements + # within the range of indexes specified by $start and $end. + # The fourth parameter is a subroutine reference that will be called to + # generate a string to use as a key. + # Additional parameters, if any, will be passed to this subroutine. + # + # my $hashRef = _withPositionsOfInInterval( \@array, $start, $end, $keyGen ); + + sub _withPositionsOfInInterval + { + my $aCollection = shift; # array ref + my $start = shift; + my $end = shift; + my $keyGen = shift; + my %d; + my $index; + for ( $index = $start ; $index <= $end ; $index++ ) + { + my $element = $aCollection->[$index]; + my $key = &$keyGen( $element, @_ ); + if ( exists( $d{$key} ) ) + { + unshift ( @{ $d{$key} }, $index ); + } + else + { + $d{$key} = [$index]; + } + } + return wantarray ? %d : \%d; + } + + # Find the place at which aValue would normally be inserted into the + # array. If that place is already occupied by aValue, do nothing, and + # return undef. If the place does not exist (i.e., it is off the end of + # the array), add it to the end, otherwise replace the element at that + # point with aValue. It is assumed that the array's values are numeric. + # This is where the bulk (75%) of the time is spent in this module, so + # try to make it fast! + + sub _replaceNextLargerWith + { + my ( $array, $aValue, $high ) = @_; + $high ||= $#$array; + + # off the end? + if ( $high == -1 || $aValue > $array->[-1] ) + { + push ( @$array, $aValue ); + return $high + 1; + } + + # binary search for insertion point... + my $low = 0; + my $index; + my $found; + while ( $low <= $high ) + { + $index = ( $high + $low ) / 2; + + # $index = int(( $high + $low ) / 2); # without 'use integer' + $found = $array->[$index]; + + if ( $aValue == $found ) + { + return undef; + } + elsif ( $aValue > $found ) + { + $low = $index + 1; + } + else + { + $high = $index - 1; + } + } + + # now insertion point is in $low. + $array->[$low] = $aValue; # overwrite next larger + return $low; + } + + # This method computes the longest common subsequence in $a and $b. + + # Result is array or ref, whose contents is such that + # $a->[ $i ] == $b->[ $result[ $i ] ] + # foreach $i in ( 0 .. $#result ) if $result[ $i ] is defined. + + # An additional argument may be passed; this is a hash or key generating + # function that should return a string that uniquely identifies the given + # element. It should be the case that if the key is the same, the elements + # will compare the same. If this parameter is undef or missing, the key + # will be the element as a string. + + # By default, comparisons will use "eq" and elements will be turned into keys + # using the default stringizing operator '""'. + + # Additional parameters, if any, will be passed to the key generation + # routine. + + sub _longestCommonSubsequence + { + my $a = shift; # array ref or hash ref + my $b = shift; # array ref or hash ref + my $counting = shift; # scalar + my $keyGen = shift; # code ref + my $compare; # code ref + + if ( ref($a) eq 'HASH' ) + { # prepared hash must be in $b + my $tmp = $b; + $b = $a; + $a = $tmp; + } + + # Check for bogus (non-ref) argument values + if ( !ref($a) || !ref($b) ) + { + my @callerInfo = caller(1); + die 'error: must pass array or hash references to ' . $callerInfo[3]; + } + + # set up code refs + # Note that these are optimized. + if ( !defined($keyGen) ) # optimize for strings + { + $keyGen = sub { $_[0] }; + $compare = sub { my ( $a, $b ) = @_; $a eq $b }; + } + else + { + $compare = sub { + my $a = shift; + my $b = shift; + &$keyGen( $a, @_ ) eq &$keyGen( $b, @_ ); + }; + } + + my ( $aStart, $aFinish, $matchVector ) = ( 0, $#$a, [] ); + my ( $prunedCount, $bMatches ) = ( 0, {} ); + + if ( ref($b) eq 'HASH' ) # was $bMatches prepared for us? + { + $bMatches = $b; + } + else + { + my ( $bStart, $bFinish ) = ( 0, $#$b ); + + # First we prune off any common elements at the beginning + while ( $aStart <= $aFinish + and $bStart <= $bFinish + and &$compare( $a->[$aStart], $b->[$bStart], @_ ) ) + { + $matchVector->[ $aStart++ ] = $bStart++; + $prunedCount++; + } + + # now the end + while ( $aStart <= $aFinish + and $bStart <= $bFinish + and &$compare( $a->[$aFinish], $b->[$bFinish], @_ ) ) + { + $matchVector->[ $aFinish-- ] = $bFinish--; + $prunedCount++; + } + + # Now compute the equivalence classes of positions of elements + $bMatches = + _withPositionsOfInInterval( $b, $bStart, $bFinish, $keyGen, @_ ); + } + my $thresh = []; + my $links = []; + + my ( $i, $ai, $j, $k ); + for ( $i = $aStart ; $i <= $aFinish ; $i++ ) + { + $ai = &$keyGen( $a->[$i], @_ ); + if ( exists( $bMatches->{$ai} ) ) + { + $k = 0; + for $j ( @{ $bMatches->{$ai} } ) + { + + # optimization: most of the time this will be true + if ( $k and $thresh->[$k] > $j and $thresh->[ $k - 1 ] < $j ) + { + $thresh->[$k] = $j; + } + else + { + $k = _replaceNextLargerWith( $thresh, $j, $k ); + } + + # oddly, it's faster to always test this (CPU cache?). + if ( defined($k) ) + { + $links->[$k] = + [ ( $k ? $links->[ $k - 1 ] : undef ), $i, $j ]; + } + } + } + } + + if (@$thresh) + { + return $prunedCount + @$thresh if $counting; + for ( my $link = $links->[$#$thresh] ; $link ; $link = $link->[0] ) + { + $matchVector->[ $link->[1] ] = $link->[2]; + } + } + elsif ($counting) + { + return $prunedCount; + } + + return wantarray ? @$matchVector : $matchVector; + } + + sub traverse_sequences + { + my $a = shift; # array ref + my $b = shift; # array ref + my $callbacks = shift || {}; + my $keyGen = shift; + my $matchCallback = $callbacks->{'MATCH'} || sub { }; + my $discardACallback = $callbacks->{'DISCARD_A'} || sub { }; + my $finishedACallback = $callbacks->{'A_FINISHED'}; + my $discardBCallback = $callbacks->{'DISCARD_B'} || sub { }; + my $finishedBCallback = $callbacks->{'B_FINISHED'}; + my $matchVector = _longestCommonSubsequence( $a, $b, 0, $keyGen, @_ ); + + # Process all the lines in @$matchVector + my $lastA = $#$a; + my $lastB = $#$b; + my $bi = 0; + my $ai; + + for ( $ai = 0 ; $ai <= $#$matchVector ; $ai++ ) + { + my $bLine = $matchVector->[$ai]; + if ( defined($bLine) ) # matched + { + &$discardBCallback( $ai, $bi++, @_ ) while $bi < $bLine; + &$matchCallback( $ai, $bi++, @_ ); + } + else + { + &$discardACallback( $ai, $bi, @_ ); + } + } + + # The last entry (if any) processed was a match. + # $ai and $bi point just past the last matching lines in their sequences. + + while ( $ai <= $lastA or $bi <= $lastB ) + { + + # last A? + if ( $ai == $lastA + 1 and $bi <= $lastB ) + { + if ( defined($finishedACallback) ) + { + &$finishedACallback( $lastA, @_ ); + $finishedACallback = undef; + } + else + { + &$discardBCallback( $ai, $bi++, @_ ) while $bi <= $lastB; + } + } + + # last B? + if ( $bi == $lastB + 1 and $ai <= $lastA ) + { + if ( defined($finishedBCallback) ) + { + &$finishedBCallback( $lastB, @_ ); + $finishedBCallback = undef; + } + else + { + &$discardACallback( $ai++, $bi, @_ ) while $ai <= $lastA; + } + } + + &$discardACallback( $ai++, $bi, @_ ) if $ai <= $lastA; + &$discardBCallback( $ai, $bi++, @_ ) if $bi <= $lastB; + } + + return 1; + } + + sub traverse_balanced + { + my $a = shift; # array ref + my $b = shift; # array ref + my $callbacks = shift || {}; + my $keyGen = shift; + my $matchCallback = $callbacks->{'MATCH'} || sub { }; + my $discardACallback = $callbacks->{'DISCARD_A'} || sub { }; + my $discardBCallback = $callbacks->{'DISCARD_B'} || sub { }; + my $changeCallback = $callbacks->{'CHANGE'}; + my $matchVector = _longestCommonSubsequence( $a, $b, 0, $keyGen, @_ ); + + # Process all the lines in match vector + my $lastA = $#$a; + my $lastB = $#$b; + my $bi = 0; + my $ai = 0; + my $ma = -1; + my $mb; + + while (1) + { + + # Find next match indices $ma and $mb + do { + $ma++; + } while( + $ma <= $#$matchVector + && !defined $matchVector->[$ma] + ); + + last if $ma > $#$matchVector; # end of matchVector? + $mb = $matchVector->[$ma]; + + # Proceed with discard a/b or change events until + # next match + while ( $ai < $ma || $bi < $mb ) + { + + if ( $ai < $ma && $bi < $mb ) + { + + # Change + if ( defined $changeCallback ) + { + &$changeCallback( $ai++, $bi++, @_ ); + } + else + { + &$discardACallback( $ai++, $bi, @_ ); + &$discardBCallback( $ai, $bi++, @_ ); + } + } + elsif ( $ai < $ma ) + { + &$discardACallback( $ai++, $bi, @_ ); + } + else + { + + # $bi < $mb + &$discardBCallback( $ai, $bi++, @_ ); + } + } + + # Match + &$matchCallback( $ai++, $bi++, @_ ); + } + + while ( $ai <= $lastA || $bi <= $lastB ) + { + if ( $ai <= $lastA && $bi <= $lastB ) + { + + # Change + if ( defined $changeCallback ) + { + &$changeCallback( $ai++, $bi++, @_ ); + } + else + { + &$discardACallback( $ai++, $bi, @_ ); + &$discardBCallback( $ai, $bi++, @_ ); + } + } + elsif ( $ai <= $lastA ) + { + &$discardACallback( $ai++, $bi, @_ ); + } + else + { + + # $bi <= $lastB + &$discardBCallback( $ai, $bi++, @_ ); + } + } + + return 1; + } + + sub prepare + { + my $a = shift; # array ref + my $keyGen = shift; # code ref + + # set up code ref + $keyGen = sub { $_[0] } unless defined($keyGen); + + return scalar _withPositionsOfInInterval( $a, 0, $#$a, $keyGen, @_ ); + } + + sub LCS + { + my $a = shift; # array ref + my $b = shift; # array ref or hash ref + my $matchVector = _longestCommonSubsequence( $a, $b, 0, @_ ); + my @retval; + my $i; + for ( $i = 0 ; $i <= $#$matchVector ; $i++ ) + { + if ( defined( $matchVector->[$i] ) ) + { + push ( @retval, $a->[$i] ); + } + } + return wantarray ? @retval : \@retval; + } + + sub LCS_length + { + my $a = shift; # array ref + my $b = shift; # array ref or hash ref + return _longestCommonSubsequence( $a, $b, 1, @_ ); + } + + sub LCSidx + { + my $a= shift @_; + my $b= shift @_; + my $match= _longestCommonSubsequence( $a, $b, 0, @_ ); + my @am= grep defined $match->[$_], 0..$#$match; + my @bm= @{$match}[@am]; + return \@am, \@bm; + } + + sub compact_diff + { + my $a= shift @_; + my $b= shift @_; + my( $am, $bm )= LCSidx( $a, $b, @_ ); + my @cdiff; + my( $ai, $bi )= ( 0, 0 ); + push @cdiff, $ai, $bi; + while( 1 ) { + while( @$am && $ai == $am->[0] && $bi == $bm->[0] ) { + shift @$am; + shift @$bm; + ++$ai, ++$bi; + } + push @cdiff, $ai, $bi; + last if ! @$am; + $ai = $am->[0]; + $bi = $bm->[0]; + push @cdiff, $ai, $bi; + } + push @cdiff, 0+@$a, 0+@$b + if $ai < @$a || $bi < @$b; + return wantarray ? @cdiff : \@cdiff; + } + + sub diff + { + my $a = shift; # array ref + my $b = shift; # array ref + my $retval = []; + my $hunk = []; + my $discard = sub { + push @$hunk, [ '-', $_[0], $a->[ $_[0] ] ]; + }; + my $add = sub { + push @$hunk, [ '+', $_[1], $b->[ $_[1] ] ]; + }; + my $match = sub { + push @$retval, $hunk + if 0 < @$hunk; + $hunk = [] + }; + traverse_sequences( $a, $b, + { MATCH => $match, DISCARD_A => $discard, DISCARD_B => $add }, @_ ); + &$match(); + return wantarray ? @$retval : $retval; + } + + sub sdiff + { + my $a = shift; # array ref + my $b = shift; # array ref + my $retval = []; + my $discard = sub { push ( @$retval, [ '-', $a->[ $_[0] ], "" ] ) }; + my $add = sub { push ( @$retval, [ '+', "", $b->[ $_[1] ] ] ) }; + my $change = sub { + push ( @$retval, [ 'c', $a->[ $_[0] ], $b->[ $_[1] ] ] ); + }; + my $match = sub { + push ( @$retval, [ 'u', $a->[ $_[0] ], $b->[ $_[1] ] ] ); + }; + traverse_balanced( + $a, + $b, + { + MATCH => $match, + DISCARD_A => $discard, + DISCARD_B => $add, + CHANGE => $change, + }, + @_ + ); + return wantarray ? @$retval : $retval; + } + + ######################################## + my $Root= __PACKAGE__; + package Algorithm::Diff::_impl; + use strict; + + sub _Idx() { 0 } # $me->[_Idx]: Ref to array of hunk indices + # 1 # $me->[1]: Ref to first sequence + # 2 # $me->[2]: Ref to second sequence + sub _End() { 3 } # $me->[_End]: Diff between forward and reverse pos + sub _Same() { 4 } # $me->[_Same]: 1 if pos 1 contains unchanged items + sub _Base() { 5 } # $me->[_Base]: Added to range's min and max + sub _Pos() { 6 } # $me->[_Pos]: Which hunk is currently selected + sub _Off() { 7 } # $me->[_Off]: Offset into _Idx for current position + sub _Min() { -2 } # Added to _Off to get min instead of max+1 + + sub Die + { + require Carp; + Carp::confess( @_ ); + } + + sub _ChkPos + { + my( $me )= @_; + return if $me->[_Pos]; + my $meth= ( caller(1) )[3]; + Die( "Called $meth on 'reset' object" ); + } + + sub _ChkSeq + { + my( $me, $seq )= @_; + return $seq + $me->[_Off] + if 1 == $seq || 2 == $seq; + my $meth= ( caller(1) )[3]; + Die( "$meth: Invalid sequence number ($seq); must be 1 or 2" ); + } + + sub getObjPkg + { + my( $us )= @_; + return ref $us if ref $us; + return $us . "::_obj"; + } + + sub new + { + my( $us, $seq1, $seq2, $opts ) = @_; + my @args; + for( $opts->{keyGen} ) { + push @args, $_ if $_; + } + for( $opts->{keyGenArgs} ) { + push @args, @$_ if $_; + } + my $cdif= Algorithm::Diff::compact_diff( $seq1, $seq2, @args ); + my $same= 1; + if( 0 == $cdif->[2] && 0 == $cdif->[3] ) { + $same= 0; + splice @$cdif, 0, 2; + } + my @obj= ( $cdif, $seq1, $seq2 ); + $obj[_End] = (1+@$cdif)/2; + $obj[_Same] = $same; + $obj[_Base] = 0; + my $me = bless \@obj, $us->getObjPkg(); + $me->Reset( 0 ); + return $me; + } + + sub Reset + { + my( $me, $pos )= @_; + $pos= int( $pos || 0 ); + $pos += $me->[_End] + if $pos < 0; + $pos= 0 + if $pos < 0 || $me->[_End] <= $pos; + $me->[_Pos]= $pos || !1; + $me->[_Off]= 2*$pos - 1; + return $me; + } + + sub Base + { + my( $me, $base )= @_; + my $oldBase= $me->[_Base]; + $me->[_Base]= 0+$base if defined $base; + return $oldBase; + } + + sub Copy + { + my( $me, $pos, $base )= @_; + my @obj= @$me; + my $you= bless \@obj, ref($me); + $you->Reset( $pos ) if defined $pos; + $you->Base( $base ); + return $you; + } + + sub Next { + my( $me, $steps )= @_; + $steps= 1 if ! defined $steps; + if( $steps ) { + my $pos= $me->[_Pos]; + my $new= $pos + $steps; + $new= 0 if $pos && $new < 0; + $me->Reset( $new ) + } + return $me->[_Pos]; + } + + sub Prev { + my( $me, $steps )= @_; + $steps= 1 if ! defined $steps; + my $pos= $me->Next(-$steps); + $pos -= $me->[_End] if $pos; + return $pos; + } + + sub Diff { + my( $me )= @_; + $me->_ChkPos(); + return 0 if $me->[_Same] == ( 1 & $me->[_Pos] ); + my $ret= 0; + my $off= $me->[_Off]; + for my $seq ( 1, 2 ) { + $ret |= $seq + if $me->[_Idx][ $off + $seq + _Min ] + < $me->[_Idx][ $off + $seq ]; + } + return $ret; + } + + sub Min { + my( $me, $seq, $base )= @_; + $me->_ChkPos(); + my $off= $me->_ChkSeq($seq); + $base= $me->[_Base] if !defined $base; + return $base + $me->[_Idx][ $off + _Min ]; + } + + sub Max { + my( $me, $seq, $base )= @_; + $me->_ChkPos(); + my $off= $me->_ChkSeq($seq); + $base= $me->[_Base] if !defined $base; + return $base + $me->[_Idx][ $off ] -1; + } + + sub Range { + my( $me, $seq, $base )= @_; + $me->_ChkPos(); + my $off = $me->_ChkSeq($seq); + if( !wantarray ) { + return $me->[_Idx][ $off ] + - $me->[_Idx][ $off + _Min ]; + } + $base= $me->[_Base] if !defined $base; + return ( $base + $me->[_Idx][ $off + _Min ] ) + .. ( $base + $me->[_Idx][ $off ] - 1 ); + } + + sub Items { + my( $me, $seq )= @_; + $me->_ChkPos(); + my $off = $me->_ChkSeq($seq); + if( !wantarray ) { + return $me->[_Idx][ $off ] + - $me->[_Idx][ $off + _Min ]; + } + return + @{$me->[$seq]}[ + $me->[_Idx][ $off + _Min ] + .. ( $me->[_Idx][ $off ] - 1 ) + ]; + } + + sub Same { + my( $me )= @_; + $me->_ChkPos(); + return wantarray ? () : 0 + if $me->[_Same] != ( 1 & $me->[_Pos] ); + return $me->Items(1); + } + + my %getName; + %getName= ( + same => \&Same, + diff => \&Diff, + base => \&Base, + min => \&Min, + max => \&Max, + range=> \&Range, + items=> \&Items, # same thing + ); + + sub Get + { + my $me= shift @_; + $me->_ChkPos(); + my @value; + for my $arg ( @_ ) { + for my $word ( split ' ', $arg ) { + my $meth; + if( $word !~ /^(-?\d+)?([a-zA-Z]+)([12])?$/ + || not $meth= $getName{ lc $2 } + ) { + Die( $Root, ", Get: Invalid request ($word)" ); + } + my( $base, $name, $seq )= ( $1, $2, $3 ); + push @value, scalar( + 4 == length($name) + ? $meth->( $me ) + : $meth->( $me, $seq, $base ) + ); + } + } + if( wantarray ) { + return @value; + } elsif( 1 == @value ) { + return $value[0]; + } + Die( 0+@value, " values requested from ", + $Root, "'s Get in scalar context" ); + } + + + my $Obj= getObjPkg($Root); + no strict 'refs'; + + for my $meth ( qw( new getObjPkg ) ) { + *{$Root."::".$meth} = \&{$meth}; + *{$Obj ."::".$meth} = \&{$meth}; + } + for my $meth ( qw( + Next Prev Reset Copy Base Diff + Same Items Range Min Max Get + _ChkPos _ChkSeq + ) ) { + *{$Obj."::".$meth} = \&{$meth}; + } + +}; +{ + package Algorithm::LCSS; + + use strict; + { + no strict 'refs'; + *traverse_sequences = \&Algorithm::Diff::traverse_sequences; + } + + sub _tokenize { [split //, $_[0]] } + + sub CSS { + my $is_array = ref $_[0] eq 'ARRAY' ? 1 : 0; + my ( $seq1, $seq2, @match, $from_match ); + my $i = 0; + if ( $is_array ) { + $seq1 = $_[0]; + $seq2 = $_[1]; + traverse_sequences( $seq1, $seq2, { + MATCH => sub { push @{$match[$i]}, $seq1->[$_[0]]; $from_match = 1 }, + DISCARD_A => sub { do{$i++; $from_match = 0} if $from_match }, + DISCARD_B => sub { do{$i++; $from_match = 0} if $from_match }, + }); + } + else { + $seq1 = _tokenize($_[0]); + $seq2 = _tokenize($_[1]); + traverse_sequences( $seq1, $seq2, { + MATCH => sub { $match[$i] .= $seq1->[$_[0]]; $from_match = 1 }, + DISCARD_A => sub { do{$i++; $from_match = 0} if $from_match }, + DISCARD_B => sub { do{$i++; $from_match = 0} if $from_match }, + }); + } + return \@match; + } + + sub CSS_Sorted { + my $match = CSS(@_); + if ( ref $_[0] eq 'ARRAY' ) { + @$match = map{$_->[0]}sort{$b->[1]<=>$a->[1]}map{[$_,scalar(@$_)]}@$match + } + else { + @$match = map{$_->[0]}sort{$b->[1]<=>$a->[1]}map{[$_,length($_)]}@$match + } + return $match; + } + + sub LCSS { + my $is_array = ref $_[0] eq 'ARRAY' ? 1 : 0; + my $css = CSS(@_); + my $index; + my $length = 0; + if ( $is_array ) { + for( my $i = 0; $i < @$css; $i++ ) { + next unless @{$css->[$i]}>$length; + $index = $i; + $length = @{$css->[$i]}; + } + } + else { + for( my $i = 0; $i < @$css; $i++ ) { + next unless length($css->[$i])>$length; + $index = $i; + $length = length($css->[$i]); + } + } + return $css->[$index]; + } + +}; +# }}} +#{{{ Class::Classless module +{ + package Class::Classless; + use strict; + use vars qw(@ISA); + use Carp; + + @ISA = (); + + ########################################################################### + + @Class::Classless::X::ISA = (); + + ########################################################################### + ########################################################################### + + sub Class::Classless::X::AUTOLOAD { + # This's the big dispatcher. + + my $it = shift @_; + my $m = ($Class::Classless::X::AUTOLOAD =~ m/([^:]+)$/s ) + ? $1 : $Class::Classless::X::AUTOLOAD; + + croak "Can't call Class::Classless methods (like $m) without an object" + unless ref $it; # sanity, basically. + + my $prevstate; + $prevstate = ${shift @_} + if scalar(@_) && defined($_[0]) && + ref($_[0]) eq 'Class::Classless::CALLSTATE::SHIMMY' + ; # A shim! we were called via $callstate->NEXT + + my $no_fail = $prevstate ? $prevstate->[3] : undef; + my $i = $prevstate ? ($prevstate->[1] + 1) : 0; + # where to start scanning + my $lineage; + + # Get the linearization of the ISA tree + if($prevstate) { + $lineage = $prevstate->[2]; + } elsif(defined $it->{'ISA_CACHE'} and ref $it->{'ISA_CACHE'} ){ + $lineage = $it->{'ISA_CACHE'}; + } else { + $lineage = [ &Class::Classless::X::ISA_TREE($it) ]; + } + + # Was: + #my @lineage = + # $prevstate ? @{$prevstate->[2]} + # : &Class::Classless::X::ISA_TREE($it); + # # Get the linearization of the ISA tree + # # ISA-memoization happens in the ISA_TREE function. + + for(; $i < @$lineage; ++$i) { + + if( !defined($no_fail) and exists($lineage->[$i]{'NO_FAIL'}) ) { + $no_fail = ($lineage->[$i]{'NO_FAIL'} || 0); + # so the first NO_FAIL sets it + } + + if( ref($lineage->[$i]{'METHODS'} || 0) # sanity + && exists($lineage->[$i]{'METHODS'}{$m}) + ){ + # We found what we were after. Now see what to do with it. + my $v = $lineage->[$i]{'METHODS'}{$m}; + return $v unless defined $v and ref $v; + + if(ref($v) eq 'CODE') { # normal case, I expect! + # Used to have copying of the arglist here. + # But it was apparently useless, so I deleted it + unshift @_, + $it, # $_[0] -- target object + # a NEW callstate + bless([$m, $i, $lineage, $no_fail, $prevstate ? 1 : 0], + 'Class::Classless::CALLSTATE' + ), # $_[1] -- the callstate + ; + goto &{ $v }; # yes, magic goto! bimskalabim! + } + return @$v if ref($v) eq '_deref_array'; + return $$v if ref($v) eq '_deref_scalar'; + return $v; # fallthru + } + } + + if($m eq 'DESTROY') { # mitigate DESTROY-lookup failure at global destruction + # should be impossible + } else { + if($no_fail || 0) { + return; + } + croak "Can't find ", $prevstate ? 'NEXT method' : 'method', + " $m in ", $it->{'NAME'} || $it, + " or any ancestors\n"; + } + } + + ########################################################################### + ########################################################################### + + sub Class::Classless::X::DESTROY { + # noop + } + + ########################################################################### + sub Class::Classless::X::ISA_TREE { + # The linearizer! + # Returns the search path for $_[0], starting with $_[0] + # Possibly memoized. + + # I stopped being able to understand this algorithm about five + # minutes after I wrote it. + use strict; + + my $set_cache = 0; # flag to set the cache on the way out + + if(exists($_[0]{'ISA_CACHE'})) { + return @{$_[0]{'ISA_CACHE'}} + if defined $_[0]{'ISA_CACHE'} + and ref $_[0]{'ISA_CACHE'}; + + # Otherwise, if exists but is not a ref, it's a signal that it should + # be replaced at the earliest, with a listref + $set_cache = 1; + } + + my $has_mi = 0; # set to 0 on the first node we see with 2 parents! + # First, just figure out what's in the tree. + my %last_child = ($_[0] => 1); # as if already seen + + # if $last_child{$x} == $y, that means: + # 1) incidentally, we've passed the node $x before. + # 2) $x is the last child of $y, + # so that means that $y can be pushed to the stack only after + # we've pushed $x to the stack. + + my @tree_nodes; + { + my $current; + my @in_stack = ($_[0]); + while(@in_stack) { + next unless + defined($current = shift @in_stack) + && ref($current) # sanity + && ref($current->{'PARENTS'} || 0) # sanity + ; + + push @tree_nodes, $current; + + $has_mi = 1 if @{$current->{'PARENTS'}} > 1; + unshift + @in_stack, + map { + if(exists $last_child{$_}) { # seen before! + $last_child{$_} = $current; + (); # seen -- don't re-explore + } else { # first time seen + $last_child{$_} = $current; + $_; # first time seen -- explore now + } + } + @{$current->{'PARENTS'}} + ; + } + + # If there was no MI, then that first scan was sufficient. + unless($has_mi) { + $_[0]{'ISA_CACHE'} = \@tree_nodes if $set_cache; + return @tree_nodes; + } + + # Otherwise, toss this list and rescan, consulting %last_child + } + + # $last_child{$parent} holds the last (or only) child of $parent + # in this tree. When walking the tree this time, only that + # child is authorized to put its parent on the @in_stack. + # And that's the only way a node can get added to @in_stack, + # except for $_[0] (the start node) being there at the beginning. + + # Now, walk again, but this time exploring parents the LAST + # time seen in the tree, not the first. + + my @out; + { + my $current; + my @in_stack = ($_[0]); + while(@in_stack) { + next unless defined($current = shift @in_stack) && ref($current); + push @out, $current; # finally. + unshift + @in_stack, + grep( + ( + defined($_) # sanity + && ref($_) # sanity + && $last_child{$_} eq $current, + ), + # I'm lastborn (or onlyborn) of this parent + # so it's OK to explore now + @{$current->{'PARENTS'}} + ) + if ref($current->{'PARENTS'} || 0) # sanity + ; + } + + unless(scalar(@out) == scalar(keys(%last_child))) { + # the counts should be equal + my %good_ones; + @good_ones{@out} = (); + croak + "ISA tree for " . + ($_[0]{'NAME'} || $_[0]) . + " is apparently cyclic, probably involving the nodes " . + nodelist( grep { ref($_) && !exists $good_ones{$_} } + values(%last_child) ) + . "\n"; + } + } + #print "Contents of out: ", nodelist(@out), "\n"; + + $_[0]{'ISA_CACHE'} = \@out if $set_cache; + return @out; + } + + ########################################################################### + + sub Class::Classless::X::can { # NOT like UNIVERSAL::can ... + # return 1 if $it is capable of the method given -- otherwise 0 + my($it, $m) = @_[0,1]; + return undef unless ref $it; + + croak "undef is not a valid method name" unless defined($m); + croak "null-string is not a valid method name" unless length($m); + + foreach my $o (&Class::Classless::X::ISA_TREE($it)) { + return 1 + if ref($o->{'METHODS'} || 0) # sanity + && exists $o->{'METHODS'}{$m}; + } + + return 0; + } + + + ########################################################################### + + sub Class::Classless::X::isa { # Like UNIVERSAL::isa + # Returns true for $X->isa($Y) iff $Y is $X or is an ancestor of $X. + + return unless ref($_[0]) && ref($_[1]); + return scalar(grep {$_ eq $_[1]} &Class::Classless::X::ISA_TREE($_[0])); + } + + ########################################################################### + + sub nodelist { join ', ', map { "" . ($_->{'NAME'} || $_) . ""} @_ } + + ########################################################################### + ########################################################################### + ########################################################################### + # Methods for the CALLSTATE class. + # Basically, CALLSTATE objects represent the state of the dispatcher, + # frozen at the moment when the method call was dispatched to the + # appropriate sub. + # In the grand scheme of things, this needn't be a class -- I could + # have just made the callstate data-object be a hash with documented + # keys, or a closure that responded to only certain parameters, + # etc. But I like it this way. And I like being able to say simply + # $cs->NEXT + # Yes, these are a bit cryptically written, but it's behoovy for + # them to be very very efficient. + + @Class::Classless::ISA = (); + sub Class::Classless::CALLSTATE::found_name { $_[0][0] } + # the method name called and found + sub Class::Classless::CALLSTATE::found_depth { $_[0][1] } + # my depth in the lineage + sub Class::Classless::CALLSTATE::lineage { @{$_[0][2]} } + # my lineage + sub Class::Classless::CALLSTATE::target { $_[0][2][ 0 ] } + # the object that's the target -- same as $_[0] for the method called + sub Class::Classless::CALLSTATE::home { $_[0][2][ $_[0][1] ] } + # the object I was found in + sub Class::Classless::CALLSTATE::sub_found { + $_[0][2][ $_[0][1] ]{'METHODS'}{ $_[0][0] } + } # the routine called + + sub Class::Classless::CALLSTATE::no_fail { $_[0][3] } + sub Class::Classless::CALLSTATE::set_no_fail_true { $_[0][3] = 1 } + sub Class::Classless::CALLSTATE::set_fail_false { $_[0][3] = 0 } + sub Class::Classless::CALLSTATE::set_fail_undef { $_[0][3] = undef } + + sub Class::Classless::CALLSTATE::via_next { $_[0][4] } + + sub Class::Classless::CALLSTATE::NEXT { + #croak "NEXT needs at least one argument: \$cs->NEXT('method'...)" + # unless @_ > 1; + # no longer true. + my $cs = shift @_; + my $m = shift @_; # which may be (or come out) undef... + $m = $cs->[0] unless defined $m; # the method name called and found + + ($cs->[2][0])->$m( + bless( \$cs, 'Class::Classless::CALLSTATE::SHIMMY' ), + @_ + ); + } + + ########################################################################### +}; +#}}} + +############### +### +# +# {{{ *** C h a n g e l o g *** +# +# 0.6ca +# - add screen support (from nicklist.pl) +# - rename to adv_windowlist.pl (advanced window list) since it isn't just a +# window list status bar (wlstat) anymore +# - names can now have a max length and window names can be used +# - fixed a bug with block display in screen mode and statusbar mode +# - added space handling to ir_fe and removed it again +# - now handling formats on my own +# - added warning about missing sb_act_none abstract leading to +# - display*active settings +# - added warning about the bug in awl_display_(no)key_active settings +# +# 0.5d +# - add setting to also hide the last statusbar if empty (awl_all_disable) +# - reverted to old utf8 code to also calculate broken utf8 length correctly +# - simplified dealing with statusbars in wlreset +# - added a little tweak for the renamed term_type somewhere after Irssi 0.8.9 +# - fixed bug in handling channel #$$ +# - typo on line 200 spotted by f0rked +# - reset background colour at the beginning of an entry +# +# 0.4d +# - fixed order of disabling statusbars +# - several attempts at special chars, without any real success +# and much more weird new bugs caused by this +# - setting to specify sort order +# - reduced timeout values +# - added awl_hide_data for Geert Hauwaerts ( geert@irssi.org ) :) +# - make it so the dynamic sub is actually deleted +# - fix a bug with removing of the last separator +# - take into consideration parse_special +# +# 0.3b +# - automatically kill old statusbars +# - reset on /reload +# - position/placement settings +# +# 0.2 +# - automated retrieval of key bindings (thanks grep.pl authors) +# - improved removing of statusbars +# - got rid of status chop +# +# 0.1 +# - rewritten to suit my needs +# - based on chanact 0.5.5 +# }}} +# vim: se fdm=marker tw=80 : diff --git a/mutt/.gitignore b/mutt/.gitignore @@ -0,0 +1,7 @@ +account +aliases +bored.signature +cache +hcache +mailcap +temp diff --git a/mutt/binding b/mutt/binding @@ -0,0 +1,83 @@ +## +## KEY-BINDING +# + +# Unbind +bind index,pager h noop +bind index,pager j noop +bind index,pager k noop +bind index,pager l noop +bind index,pager <up> noop +bind index,pager <down> noop +bind index,pager <right> noop +bind index,pager <left> noop +bind index,pager <Enter> noop + +# Generic +bind generic l select-entry + + +# Common +bind index,pager R group-reply +bind index,pager n next-entry +bind index,pager p previous-entry +macro index,pager <F4> ":source ~/.mutt/muttrc<enter>" "reload mutt's configuration" +macro index,pager <F5> "!fdm -l fetch<enter>" "force mail fetching" + +# Sidebar +bind index,pager J sidebar-next +bind index,pager K sidebar-prev +bind index,pager <pagedown> sidebar-next +bind index,pager <pageup> sidebar-prev +bind index,pager <space> sidebar-open +macro index,pager b '<enter-command>toggle sidebar_visible<enter>' + +# Index +# bind index <F5> fetch-mail +bind index h change-folder +bind index j next-entry +bind index k previous-entry +bind index l display-message +bind index <return> display-message +bind index G last-entry +bind index gg first-entry +bind index B bounce-message +bind index z collapse-thread +bind index Z collapse-all +# To make all "new" mails to "read" (Ignore) +macro index I '<tag-pattern>~N^M<tag-prefix><toggle-new><tag-prefix><tag-entry>' +macro index C "<copy-message>?" "copy a message to a folder" +macro index M "<save-message>?" "move a message to a folder" +macro index A "<copy-message>+archive<enter>" "copy mail to 'archives'" +macro index D "<save-message>+archive<enter>" "move mail to 'archives'" + +# Navigation +bind editor <space> noop # avoid errors with spaces in names +macro index gi "<change-folder>=INBOX<enter>" "Go to inbox" +macro index gd "<change-folder>=draft<enter>" "Go to drafts" +macro index gs "<change-folder>=sent<enter>" "Go to sent items" +macro index ga "<change-folder>=archive<enter>" "Go to all mails" + + +# Pager +bind pager gg top +bind pager G bottom +bind pager J next-entry +bind pager K previous-entry +bind pager j next-line +bind pager k previous-line +bind pager h exit +bind pager l view-attachments +bind pager <return> view-attachments +macro pager M "<save-message>?" "move a message to a folder" + +# Attach +bind attach l view-mailcap +bind attach h exit +bind attach H display-toggle-weed +bind attach <return> view-mailcap + +# Compose +bind compose l view-attach + +# vim: set ft=muttrc tw=72: diff --git a/mutt/colors b/mutt/colors @@ -0,0 +1,61 @@ +# Global +color hdrdefault black default +color quoted magenta default +color signature brightblue default +color attachment yellow default +color message brightyellow default +color error brightwhite red +color indicator brightwhite brightblack +color status white default +color tree black default +color normal brightblack default +color markers red default +color search black default +color tilde brightmagenta default +color sidebar_new black white + +# Colors +color index brightblack default ~F +color index brightyellow default "~N|~O" +color index default green ~T +color index brightred default ~D +mono index bold ~N +mono index bold ~F +mono index bold ~T +mono index bold ~D + +# Highlights inside the body of a message. + +# URLs +color body brightgreen default "(http|ftp|news|telnet|finger)://[^ \"\t\r\n]*" +color body brightgreen default "mailto:[-a-z_0-9.]+@[-a-z_0-9.]+" +mono body bold "(http|ftp|news|telnet|finger)://[^ \"\t\r\n]*" +mono body bold "mailto:[-a-z_0-9.]+@[-a-z_0-9.]+" + +# email addresses +color body brightgreen default "[-a-z_0-9.%$]+@[-a-z_0-9.]+\\.[-a-z][-a-z]+" +mono body bold "[-a-z_0-9.%$]+@[-a-z_0-9.]+\\.[-a-z][-a-z]+" + +# header +color header brightblue default "^from:" +color header red default "^to:" +color header green default "^cc:" +color header blue default "^date:" +color header yellow default "^newsgroups:" +color header yellow default "^reply-to:" +color header brightcyan default "^subject:" +color header red default "^x-spam-rule:" +color header green default "^x-mailer:" +color header yellow default "^message-id:" +color header yellow default "^Organization:" +color header yellow default "^Organisation:" +color header yellow default "^User-Agent:" +color header yellow default "^message-id: .*pine" +color header yellow default "^X-Fnord:" +color header yellow default "^X-WebTV-Stationery:" +color header yellow default "^X-Message-Flag:" +color header yellow default "^X-Spam-Status:" +color header yellow default "^X-SpamProbe:" +color header red default "^X-SpamProbe: SPAM" + +# vim: set ft=muttrc tw=72: diff --git a/mutt/geek.signature b/mutt/geek.signature @@ -0,0 +1,6 @@ +-----BEGIN GEEK CODE BLOCK----- +Version: 3.12 +GCS/E d--(+) s+: a-- C++(++++)>$ UL++>$ P+ L+++ E--- W++ N-- o-- K- w--- +O? M-- V- PS+ PE Y+ PGP+(++) t 5? X- R* tv b+ DI? D++(++++) G e- h+ +r+>++ y+ +------END GEEK CODE BLOCK------ diff --git a/mutt/muttrc b/mutt/muttrc @@ -0,0 +1,120 @@ +## MUTT - CLI mail client +# +# "All client maill sucks, this is just one that sucks less." + + +## --- Me, myself and I --- +source ~/.mutt/account + +## --- Send mails (msmtp) --- +set sendmail="/usr/bin/msmtp" + +## --- Fetch mails (fdm) --- +set mbox_type=Maildir +set header_cache=~/.cach/mutt + +## --- Folders --- +set folder=$HOME/var/mail/ +set spoolfile=+INBOX +set record=+sent +set postponed=+draft +set mbox=+archive + + +## --- Local directories --- +set mailcap_path = "~/.mutt/mailcap" # how to view attachements +set header_cache="~/.mutt/hcache" # store headers +set tmpdir = "~/.mutt/temp" # where store postponed +set message_cachedir="~/.mutt/cache/body" # store bodies +set certificate_file="~/.mutt/certificates" # certificates + + +## --- Status bar --- +set status_chars = " *%A" +set status_format = "────[ Folder: %f ]───[ %r%m messages%?n?\ + (%n new)?%?d? (%d to delete)?%?t?\ + (%t tagged)? ]───%>─%?p?( %p postponed )?───" + +## --- Sidebar --- +set sidebar_visible = yes # why not ! +set sidebar_width = 32 # column size +set sidebar_delim = "|" # separator +set sidebar_format = " %B %! %> %?N?(%N)?%S " # content +set sidebar_folderindent = no # respect indent +set sidebar_sort = no # sort alphabeticaly +set sidebar_shortpath = yes # fix first char column + +mailboxes +INBOX \ + +--[folders]------------------------\ + +paperwork \ + +purchase \ + +isfen \ + +stuffs \ + +dev \ + +--[mail-list]----------------------\ + +archlinux \ + +vim \ + +--[done]---------------------------\ + +sent \ + +draft \ + +archive + + +## --- Editing --- +set editor="vim" # use vim to edit +set edit_headers=yes # allow header editing +set forward_format = "fwd: %s" # forwarding +set attribution = "%n wrote:" # quoting +set charset="utf-8" # terminal charset +set send_charset="us-ascii:utf-8:iso-8859-1"# encoding for outgoings +set signature="~/.mutt/geek.signature" # signature +# set signature="fortune -n 200 -so calvin|" # signature.alt + + +## --- Viewing --- +set date_format = "%m/%d" +auto_view text/html # dump html +set tilde # show tildes like in vim +unset markers # no ugly plus signs +set quote_regexp = "^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+" +alternative_order text/plain text/html text/enriched + + +## --- Index settings --- +set index_format = " %?M?+& ?[%Z] %D %-20.20F %?M?(%2M)& ? %s" +set sort = threads # like gmail +set sort_aux = reverse-last-date-received # like gmail +unset collapse_unread # don't collapse unread +set sort_re # thread based on regex +set reply_regexp = "^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*" + + +## --- Pager settings --- +set pager_index_lines = 10 # number of index lines to show +set pager_context = 3 # number of context lines to show +set pager_stop # don't go to next message automatically +set menu_scroll # scroll in menus + + +## --- Header settings --- +ignore * # ignore all headers +unignore from: to: cc: date: subject: # show only these +unhdr_order * # order things +hdr_order from: to: cc: date: subject: # and in this order +my_hdr Bcc: $my_address # helps with conversations +charset-hook ^iso-8859-1$ windows-1252 # use windows encoding for + # charset ISO-8859-1 + +## --- Aliases --- +set alias_file="~/.mutt/aliases" +set reverse_alias +set sort_alias="alias" +source $alias_file + +## --- Colors --- +source ~/.mutt/colors + +## --- Binding --- +source ~/.mutt/binding + +# vim: set ft=muttrc tw=72 colorcolumn=73: diff --git a/ncmpcpp/config b/ncmpcpp/config @@ -0,0 +1,214 @@ +# +## ============================================= +## mpd configuration =========================== +## +mpd_host = "mpdconf@localhost" +mpd_port = "6600" +mpd_music_dir = "/mnt/music/" +# mpd_crossfade_time = "5" + + +# +## ============================================= +## delays ====================================== +## +playlist_disable_highlight_delay = "1" +message_delay_time = "4" + +# +## ============================================= +## song formatting ============================= +## +## Song format : +## +## %l - length +## %f - filename +## %D - directory +## %a - artist +## %t - title +## %b - album +## %y - year +## %n - track number (01/12 -> 01) +## %N - full track info (01/12 -> 01/12) +## %g - genre +## %c - composer +## %p - performer +## %d - disc +## %C - comment +## $R - begin right alignment +## +## Display if set : {} +## This or that : {%this}|{%that} +## +## Color format : +## +## - 0 - default window color (discards all other colors) +## - 1 - black +## - 2 - red +## - 3 - green +## - 4 - yellow +## - 5 - blue +## - 6 - magenta +## - 7 - cyan +## - 8 - white +## - 9 - end of current color +## + +song_list_format = "$0{{$7%a$9} $1»»$9 {%t}}|{%f}$R{$1%l$9}" +song_status_format = "$0{{$7%a$9 }{%t}}|{$7%f$9}" +song_library_format = "$0{$7%n$9 }{%t}|{%f}" +tag_editor_album_format = "%b {($7%y$9)}" + +## +## Only available for the above +## +## - b - bold +## - u - underline +## - r - reverse colors (see color1 & color2 @"color defifinition" +## - a - alternative character set +## +## Set attribute : $? +## Unset attribute : $/? +## + +now_playing_prefix = "$b" +now_playing_suffix = "$/b" +browser_playlist_prefix = "[$b$7playlists$9$/b] " +selected_item_prefix = "$0" +selected_item_suffix = "$9" + +## colors are not supported for below variable +song_window_title_format = "{{%t} -- {%a}}|{%f}" + +# +## ============================================= +## column format =============================== +## +## - syntax for each column is: +## +## (width of column)[column's color]{displayed tag} +## +## Note: Width is by default in %, if you want a column to +## have fixed size, add 'f' after the value, e.g. (10)[white]{a} +## will be the column that take 10% of screen (so the real column's +## width will depend on actual screen size), whereas (10f)[white]{a} +## will take 10 terminal cells, no matter how wide the screen is. +## +## - color is optional (if you want the default one, type []) +## +## Note: You can give a column additional attributes by putting appropriate +## character after displayed tag character. Available attributes are: +## +## - r - column will be right aligned +## - E - if tag is empty, empty tag marker won't be displayed +## +## E.g. {lr} will give you right aligned column of lengths. +## + +song_columns_list_format = "(20)[cyan]{a|f} (20)[white]{t} (50)[cyan]{bEr} (6f)[black]{l}" + + + +# +## ============================================= +## color definition ============================ +## +colors_enabled = "yes" +empty_tag_color = "cyan" +header_window_color = "white" +volume_color = "white" +state_line_color = "black" +state_flags_color = "cyan" +main_window_color = "white" +color1 = "white" +color2 = "black" +main_window_highlight_color = "white" +progressbar_color = "white" +statusbar_color = "white" +alternative_ui_separator_color = "black" +active_column_color = "cyan" +window_border_color = "blue" +active_window_border = "cyan" + + +# +## ============================================= +## visualisation =============================== +## + +visualizer_fifo_path = "/tmp/mpd.fifo" +visualizer_output_name = "FIFO Visual" +visualizer_sync_interval = "30" +visualizer_in_stereo = "no" +visualizer_type = "spectrum" # (spectrum/wave) +visualizer_color = "cyan" +visualizer_look = "◆▋" + +# +## ============================================= +## other settings ============================== +## +## +## Note: Custom command that will be executed each +## time song changes. Useful for notifications etc. +## +## Attention: It doesn't support song format anymore. +## Use `ncmpcpp --now-playing SONG_FORMAT` instead. +## + +startup_screen = "10" +# execute_on_song_change = "" +playlist_show_remaining_time = "yes" +playlist_display_mode = "columns" (classic/columns) +browser_display_mode = "classic" (classic/columns) +#search_engine_display_mode = "classic" (classic/columns) +#incremental_seeking = "yes" +#seek_time = "1" +#autocenter_mode = "no" +centered_cursor = "yes" +progressbar_look = "─╼·" # ".·" +#default_place_to_search_in = "database" (database/playlist) +user_interface = "alternative" (classic/alternative) +# media_library_left_column = "a" (possible values: a,y,g,c,p, legend above) +default_find_mode = "wrapped" (wrapped/normal) +default_space_mode = "add" (add/select) +#default_tag_editor_left_col = "albums" (albums/dirs) +#default_tag_editor_pattern = "%n - %t" +header_visibility = "yes" +statusbar_visibility = "yes" +header_text_scrolling = "yes" +fancy_scrolling = "yes" +cyclic_scrolling = "yes" +#lines_scrolled = "2" +follow_now_playing_lyrics = "yes" +ncmpc_like_songs_adding = "yes" # (enabled - add/remove, disabled - always add) +show_hidden_files_in_local_browser = "no" +jump_to_now_playing_song_at_start = "yes" +ask_before_clearing_main_playlist = "yes" +clock_display_seconds = "no" +display_bitrate = "no" +display_remaining_time = "yes" +regular_expressions = "extended" (basic/extended) + +## +## Note: If below is enabled, ncmpcpp will ignore leading +## "The" word while sorting items in browser, tags in +## media library, etc. +## +ignore_leading_the = "yes" +#block_search_constraints_change_if_items_found = "yes" +mouse_support = "yes" +#mouse_list_scroll_whole_page = "yes" +empty_tag_marker = "/none\\" +#tag_editor_extended_numeration = "no" +enable_window_title = "no" + +##### lyrics support ##### +## +## supported lyrics databases: +## +## - 1 - lyricsplugin.com +## +#lyrics_database = "1" +external_editor = "vim" +use_console_editor = "yes" # (set to yes, if your editor is console app) diff --git a/ncmpcpp/error.log b/ncmpcpp/error.log diff --git a/rtorrent.rc b/rtorrent.rc @@ -0,0 +1,108 @@ +# This is an example resource file for rTorrent. Copy to +# ~/.rtorrent.rc and enable/modify the options as needed. Remember to +# uncomment the options you wish to enable. + +# Maximum and minimum number of peers to connect to per torrent. +#min_peers = 40 +#max_peers = 100 + +# Same as above but for seeding completed torrents (-1 = same as downloading) +#min_peers_seed = 10 +#max_peers_seed = 50 + +# Maximum number of simultanious uploads per torrent. +#max_uploads = 15 + +# Global upload and download rate in KiB. "0" for unlimited. +#download_rate = 0 +#upload_rate = 0 + +# Default directory to save the downloaded torrents. +directory = /home/willy/var/torrent/out/ + +# Default session directory. Make sure you don't run multiple instance +# of rtorrent using the same session directory. Perhaps using a +# relative path? +#session = /home/willy/usr/torrent/session + +# Watch a directory for new torrents, and stop those that have been +# deleted. +schedule = watch_directory,5,5,load_start=/home/willy/usr/torrent/in/*.torrent +#schedule = untied_directory,5,5,stop_untied= + +# Close torrents when diskspace is low. +#schedule = low_diskspace,5,60,close_low_diskspace=100M + +# Stop torrents when reaching upload ratio in percent, +# when also reaching total upload in bytes, or when +# reaching final upload ratio in percent. +# example: stop at ratio 2.0 with at least 200 MB uploaded, or else ratio 20.0 +#schedule = ratio,60,60,"stop_on_ratio=200,200M,2000" + +# The ip address reported to the tracker. +#ip = 127.0.0.1 +#ip = rakshasa.no + +# The ip address the listening socket and outgoing connections is +# bound to. +#bind = 127.0.0.1 +#bind = rakshasa.no + +# Port range to use for listening. +port_range = 6890-6999 + +# Start opening ports at a random position within the port range. +port_random = no + +# Check hash for finished torrents. Might be usefull until the bug is +# fixed that causes lack of diskspace not to be properly reported. +#check_hash = no + +# Set whetever the client should try to connect to UDP trackers. +#use_udp_trackers = yes + +# Alternative calls to bind and ip that should handle dynamic ip's. +#schedule = ip_tick,0,1800,ip=rakshasa +#schedule = bind_tick,0,1800,bind=rakshasa + +# Encryption options, set to none (default) or any combination of the following: +# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext +# +# The example value allows incoming encrypted connections, starts unencrypted +# outgoing connections but retries with encryption if they fail, preferring +# plaintext to RC4 encryption after the encrypted handshake +# +# encryption = allow_incoming,enable_retry,prefer_plaintext + +# Enable DHT support for trackerless torrents or when all trackers are down. +# May be set to "disable" (completely disable DHT), "off" (do not start DHT), +# "auto" (start and stop DHT as needed), or "on" (start DHT immediately). +# The default is "off". For DHT to work, a session directory must be defined. +# +# dht = auto + +# UDP port to use for DHT. +# +# dht_port = 6881 + +# Enable peer exchange (for torrents not marked private) +# +# peer_exchange = yes + +# +# Do not modify the following parameters unless you know what you're doing. +# + +# Hash read-ahead controls how many MB to request the kernel to read +# ahead. If the value is too low the disk may not be fully utilized, +# while if too high the kernel might not be able to keep the read +# pages in memory thus end up trashing. +#hash_read_ahead = 10 + +# Interval between attempts to check the hash, in milliseconds. +#hash_interval = 100 + +# Number of attempts to check the hash while using the mincore status, +# before forcing. Overworked systems might need lower values to get a +# decent hash checking rate. +#hash_max_tries = 10 diff --git a/screenrc b/screenrc @@ -0,0 +1,116 @@ +# +# ~/.screenrc +# + +# ------------------------------------------------------------------------------ +# SCREEN SETTINGS +# ------------------------------------------------------------------------------ + +escape "^ " + +# session options +sessionname gavroche +multiuser on +acladd willy + +startup_message off +#nethack on + +#defflow on # will force screen to process ^S/^Q +deflogin on +autodetach on + +# save my eyes !!! +vbell off +vbell_msg " Wuff ---- Wuff!! " + +# define a bigger scrollback, default is 100 lines +defscrollback 1024 + +# ------------------------------------------------------------------------------ +# SCREEN KEYBINDINGS +# ------------------------------------------------------------------------------ + +# Window managing +bindkey ² focus next # bind "²" (²) to switch the input focus to the next region +bindkey œ focus next # bind "œ" (²) to switch the input focus to the next region +bindkey ^[Od prev # change window with ctrl-left +bindkey ^[Oc next # change window with ctrl-right + +# Split managing +bind V split -v +bind S split +bind o only +bind r remove + +bind R eval "source ~/.screenrc" "echo '.screenrc reloaded !'" + +# Remove some stupid / dangerous key bindings +bind ^k +bind L +bind ^\ + +# Make them better +bind I login on +bind O login off +bind } history + +# vi-style keybindings +bind j focus down +bind k focus up +bind h focus left +bind l focus right + +bindkey ^j focus down +bindkey ^k focus up +bindkey ^h focus left +bindkey ^l focus right + +bind = resize = +bind > resize -h +4 +bind < resize -h -4 +bind + resize -v +2 +bind - resize -v -2 +bind _ resize max + +bind w focus next + +bind s split +bind v split -v + +bind : colon # screen's default anyway... + +# ------------------------------------------------------------------------------ +# TERMINAL SETTINGS +# ------------------------------------------------------------------------------ + +# turn sending of screen messages to hardstatus off +# hardstatus on +# Set the hardstatus prop on gui terms to set the titlebar/icon title +termcapinfo xterm*|rxvt*|kterm*|Eterm* hs:ts=\E]0;:fs=\007:ds=\E]0;\007 + +# clear screen after editing a file with console based editor +altscreen on + +# always display the last line status bar +caption always +hardstatus alwayslastline + +# set these terminals up to be 'optimal' instead of vt100 +termcapinfo xterm*|linux*|rxvt* OP + +# Change the xterm initialization string from is2=\E[!p\E[?3;4l\E[4l\E> +# (This fixes the "Aborted because of window size change" konsole symptoms found +# in bug #134198) +termcapinfo xterm 'is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;4;6l' + +# Use 256 colors from rxvt terminal +terminfo rxvt-unicode 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm' + +# Enable non-blocking mode to better cope with flaky ssh connections. +defnonblock 5 + + +# Bars +caption string "%{= Kw}%?%F%{=b cW}%? %f*%t %=%?%F.: current :.%? %= .:%F%n %t " +hardstatus string "%{= K}///%{w}//%{W}/%{dd} %{=b W}$LOGNAME%{-b w}@%{+b W}%H %= %{-b c} %-Lw%?%F%{=b W}[%2n* %t ]%?%{-b c}%+Lw %{dd} %= %{=b w} .: %D%d :: %c:%s :. %-10=" diff --git a/tmux.conf b/tmux.conf @@ -0,0 +1,165 @@ +# --- TMUX.CONF -------------------------------------------------------- +# +# Configuration file for tmux (terminal multiplexer) +# Use {screen,vim}-like key-bindings and +# +# ---------------------------------------------------------------------- + +## PREFIX KEY {{{ + ## Set the prefix key to Ctrl-Space + set-option -g prefix C-Space + bind-key C-Space send-prefix +## }}} + +## STANDARD OPTIONS {{{ + ## Remove Esc-Wait (makes Vi works) + set-option -sg escape-time 0 + + ## All kind of options + set-option -g history-limit 1024 + set-option -g bell-action any + set-option -g default-terminal screen + set-option -g display-panes-colour red + set-option -g message-bg cyan + set-option -g message-fg black + set-option -g mouse-select-pane off + set-option -g visual-activity off + set-option -g visual-bell off + set-option -g default-path "" + setw -g aggressive-resize on + + ## Detach session + bind-key d detach + bind-key C-d detach + + ## Lock screen + bind-key x lock-server + bind-key C-x lock-server + bind-key -n M-x lock-server + set-option -g lock-after-time 0 + set-option -g lock-server on + set-option -g lock-command "vlock" +## }}} + +## STATUS BAR {{{ + + # standard options + set-option -g status on + set-option -g automatic-rename on + set-option -g status-interval 15 + set-option -g status-utf8 on + set-option -g status-justify "left" + + # default statusbar colors + set-option -g status-fg black + set-option -g status-bg default + # set-option -g status-attr bright + + # default window title colors + set-window-option -g window-status-fg white + set-window-option -g window-status-bg default + set-window-option -g window-status-attr dim + set-window-option -g window-status-format ' #I#F#W ' + + # active window title colors + set-window-option -g window-status-current-fg black + set-window-option -g window-status-current-bg default + # set-window-option -g window-status-current-attr bright + set-window-option -g window-status-current-format '#[fg=white,nobold]>#[fg=black,bold]>#[fg=default]#I#F#W' + + # default pane border color + set-option -g pane-border-bg default + set-option -g pane-border-fg black + + # active pane border color + set-option -g pane-active-border-bg default + set-option -g pane-active-border-fg black + + # Left / Right status + set-option -g status-left-length 96 + set-option -g status-right-length 96 + set-option -g status-left " " + set-option -g status-right " #(~/bin/statusline.sh) " +## }}} + +## KEY MAPPING {{{ + ## Move around windows + unbind-key c ; bind-key c new-window + unbind-key n ; bind-key n next-window + unbind-key p ; bind-key p previous-window + unbind-key C-Left ; bind-key -n C-Left prev + unbind-key C-Right; bind-key -n C-Right next + unbind-key " " ; bind-key " " last-window + + ## Choose windows + unbind-key w ; bind-key w list-windows + unbind-key * ; bind-key * choose-window + + ## Prompts + unbind-key : ; bind-key : command-prompt -p "tmux:" + unbind-key g ; bind-key g command-prompt -p "number:" "move-window -t '%%'" + unbind-key m ; bind-key m command-prompt -p "man:" "split-window -h 'man %%'" + unbind-key A ; bind-key A command-prompt -p "rename:" "rename-window %%" + unbind-key K ; bind-key K confirm-before "kill-window" + + ## Create / Delete panes + # unbind-key | ; bind-key | split-window -h + # unbind-key - ; bind-key - split-window -v + unbind-key | ; bind-key | choose-window "join-pane -h -s %%" + unbind-key - ; bind-key - choose-window "join-pane -v -s %%" + unbind-key o ; bind-key o break-pane + unbind-key r ; bind-key r break-pane -d + + ## Move around panes + unbind-key % + unbind-key Tab ; bind-key -r Tab select-pane -t:.+ + unbind-key BTab ; bind-key -r BTab select-pane -t:.- + unbind-key C-h ; bind-key -r C-h select-pane -L + unbind-key C-j ; bind-key -r C-j select-pane -D + unbind-key C-k ; bind-key -r C-k select-pane -U + unbind-key C-l ; bind-key -r C-l select-pane -R + + ## Refresh screen + unbind-key ^L ; bind-key ^L refresh-client + + ## Reload config + unbind-key R ; bind-key R source-file "$HOME/.tmux.conf" \; display-message "Configuration reloaded !" + + ## Copy-mode + set-window-option -g mode-keys vi + set-window-option -g mode-mouse off + set-option buffer-limit 10 + unbind-key C-v ; bind-key C-v copy-mode + unbind-key Escape ; bind-key Escape copy-mode + unbind-key C-NPage ; bind-key -n C-NPage copy-mode + unbind-key C-PPage ; bind-key -n C-PPage copy-mode + unbind-key i ; bind-key i paste-buffer + unbind-key ] ; bind-key ] paste-buffer + unbind-key -t vi-copy v ; bind-key -t vi-copy v begin-selection + unbind-key -t vi-copy y ; bind-key -t vi-copy y copy-selection + unbind-key -t vi-copy Enter ; bind-key -t vi-copy Enter copy-selection + unbind-key -t vi-copy b ; bind-key -t vi-copy b rectangle-toggle + + + ## VIM-LIKE {{{ + unbind-key s ; bind-key s split-window -v + unbind-key v ; bind-key v split-window -h + + # move around panes with hjkl + unbind-key h ; bind-key h select-pane -L + unbind-key j ; bind-key j select-pane -D + unbind-key k ; bind-key k select-pane -U + unbind-key l ; bind-key l select-pane -R + + # swap panes + unbind-key H ; bind-key H swap-pane -s:.- + unbind-key J ; bind-key J swap-pane -Ds:.- + unbind-key K ; bind-key K swap-pane -Us:.+ + unbind-key L ; bind-key L swap-pane -s:.+ + + # reset pane layout + unbind-key = ; bind-key = select-layout main-vertical + ## }}} +## }}} + +# vim:ft=tmux:foldmethod=marker diff --git a/vim/.netrwhist b/vim/.netrwhist @@ -0,0 +1,3 @@ +let g:netrw_dirhistmax =10 +let g:netrw_dirhist_cnt =1 +let g:netrw_dirhist_1='/home/willy/etc/ncmpcpp' diff --git a/vim/autoload/pathogen.vim b/vim/autoload/pathogen.vim @@ -0,0 +1,326 @@ +" pathogen.vim - path option manipulation +" Maintainer: Tim Pope <http://tpo.pe/> +" Version: 2.2 + +" Install in ~/.vim/autoload (or ~\vimfiles\autoload). +" +" For management of individually installed plugins in ~/.vim/bundle (or +" ~\vimfiles\bundle), adding `call pathogen#infect()` to the top of your +" .vimrc is the only other setup necessary. +" +" The API is documented inline below. For maximum ease of reading, +" :set foldmethod=marker + +if exists("g:loaded_pathogen") || &cp + finish +endif +let g:loaded_pathogen = 1 + +function! s:warn(msg) + echohl WarningMsg + echomsg a:msg + echohl NONE +endfunction + +" Point of entry for basic default usage. Give a relative path to invoke +" pathogen#incubate() (defaults to "bundle/{}"), or an absolute path to invoke +" pathogen#surround(). For backwards compatibility purposes, a full path that +" does not end in {} or * is given to pathogen#runtime_prepend_subdirectories() +" instead. +function! pathogen#infect(...) abort " {{{1 + for path in a:0 ? reverse(copy(a:000)) : ['bundle/{}'] + if path =~# '^[^\\/]\+$' + call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')') + call pathogen#incubate(path . '/{}') + elseif path =~# '^[^\\/]\+[\\/]\%({}\|\*\)$' + call pathogen#incubate(path) + elseif path =~# '[\\/]\%({}\|\*\)$' + call pathogen#surround(path) + else + call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')') + call pathogen#surround(path . '/{}') + endif + endfor + call pathogen#cycle_filetype() + return '' +endfunction " }}}1 + +" Split a path into a list. +function! pathogen#split(path) abort " {{{1 + if type(a:path) == type([]) | return a:path | endif + let split = split(a:path,'\\\@<!\%(\\\\\)*\zs,') + return map(split,'substitute(v:val,''\\\([\\,]\)'',''\1'',"g")') +endfunction " }}}1 + +" Convert a list to a path. +function! pathogen#join(...) abort " {{{1 + if type(a:1) == type(1) && a:1 + let i = 1 + let space = ' ' + else + let i = 0 + let space = '' + endif + let path = "" + while i < a:0 + if type(a:000[i]) == type([]) + let list = a:000[i] + let j = 0 + while j < len(list) + let escaped = substitute(list[j],'[,'.space.']\|\\[\,'.space.']\@=','\\&','g') + let path .= ',' . escaped + let j += 1 + endwhile + else + let path .= "," . a:000[i] + endif + let i += 1 + endwhile + return substitute(path,'^,','','') +endfunction " }}}1 + +" Convert a list to a path with escaped spaces for 'path', 'tag', etc. +function! pathogen#legacyjoin(...) abort " {{{1 + return call('pathogen#join',[1] + a:000) +endfunction " }}}1 + +" Remove duplicates from a list. +function! pathogen#uniq(list) abort " {{{1 + let i = 0 + let seen = {} + while i < len(a:list) + if (a:list[i] ==# '' && exists('empty')) || has_key(seen,a:list[i]) + call remove(a:list,i) + elseif a:list[i] ==# '' + let i += 1 + let empty = 1 + else + let seen[a:list[i]] = 1 + let i += 1 + endif + endwhile + return a:list +endfunction " }}}1 + +" \ on Windows unless shellslash is set, / everywhere else. +function! pathogen#separator() abort " {{{1 + return !exists("+shellslash") || &shellslash ? '/' : '\' +endfunction " }}}1 + +" Convenience wrapper around glob() which returns a list. +function! pathogen#glob(pattern) abort " {{{1 + let files = split(glob(a:pattern),"\n") + return map(files,'substitute(v:val,"[".pathogen#separator()."/]$","","")') +endfunction "}}}1 + +" Like pathogen#glob(), only limit the results to directories. +function! pathogen#glob_directories(pattern) abort " {{{1 + return filter(pathogen#glob(a:pattern),'isdirectory(v:val)') +endfunction "}}}1 + +" Turn filetype detection off and back on again if it was already enabled. +function! pathogen#cycle_filetype() " {{{1 + if exists('g:did_load_filetypes') + filetype off + filetype on + endif +endfunction " }}}1 + +" Check if a bundle is disabled. A bundle is considered disabled if it ends +" in a tilde or its basename or full name is included in the list +" g:pathogen_disabled. +function! pathogen#is_disabled(path) " {{{1 + if a:path =~# '\~$' + return 1 + elseif !exists("g:pathogen_disabled") + return 0 + endif + let sep = pathogen#separator() + let blacklist = g:pathogen_disabled + return index(blacklist, strpart(a:path, strridx(a:path, sep)+1)) != -1 && index(blacklist, a:path) != 1 +endfunction "}}}1 + +" Prepend the given directory to the runtime path and append its corresponding +" after directory. If the directory is already included, move it to the +" outermost position. Wildcards are added as is. Ending a path in /{} causes +" all subdirectories to be added (except those in g:pathogen_disabled). +function! pathogen#surround(path) abort " {{{1 + let sep = pathogen#separator() + let rtp = pathogen#split(&rtp) + if a:path =~# '[\\/]{}$' + let path = fnamemodify(a:path[0:-4], ':p:s?[\\/]\=$??') + let before = filter(pathogen#glob_directories(path.sep.'*'), '!pathogen#is_disabled(v:val)') + let after = filter(reverse(pathogen#glob_directories(path.sep."*".sep."after")), '!pathogen#is_disabled(v:val[0:-7])') + call filter(rtp,'v:val[0:strlen(path)-1] !=# path') + else + let path = fnamemodify(a:path, ':p:s?[\\/]\=$??') + let before = [path] + let after = [path . sep . 'after'] + call filter(rtp, 'index(before + after, v:val) == -1') + endif + let &rtp = pathogen#join(before, rtp, after) + return &rtp +endfunction " }}}1 + +" Prepend all subdirectories of path to the rtp, and append all 'after' +" directories in those subdirectories. Deprecated. +function! pathogen#runtime_prepend_subdirectories(path) " {{{1 + call s:warn('Change pathogen#runtime_prepend_subdirectories('.string(a:path).') to pathogen#surround('.string(a:path.'/{}').')') + return pathogen#surround(a:path . pathogen#separator() . '{}') +endfunction " }}}1 + +" For each directory in the runtime path, add a second entry with the given +" argument appended. If the argument ends in '/{}', add a separate entry for +" each subdirectory. The default argument is 'bundle/{}', which means that +" .vim/bundle/*, $VIM/vimfiles/bundle/*, $VIMRUNTIME/bundle/*, +" $VIM/vim/files/bundle/*/after, and .vim/bundle/*/after will be added (on +" UNIX). +function! pathogen#incubate(...) abort " {{{1 + let sep = pathogen#separator() + let name = a:0 ? a:1 : 'bundle/{}' + if "\n".s:done_bundles =~# "\\M\n".name."\n" + return "" + endif + let s:done_bundles .= name . "\n" + let list = [] + for dir in pathogen#split(&rtp) + if dir =~# '\<after$' + if name =~# '{}$' + let list += filter(pathogen#glob_directories(substitute(dir,'after$',name[0:-3],'').'*'.sep.'after'), '!pathogen#is_disabled(v:val[0:-7])') + [dir] + else + let list += [dir, substitute(dir, 'after$', '', '') . name . sep . 'after'] + endif + else + if name =~# '{}$' + let list += [dir] + filter(pathogen#glob_directories(dir.sep.name[0:-3].'*'), '!pathogen#is_disabled(v:val)') + else + let list += [dir . sep . name, dir] + endif + endif + endfor + let &rtp = pathogen#join(pathogen#uniq(list)) + return 1 +endfunction " }}}1 + +" Deprecated alias for pathogen#incubate(). +function! pathogen#runtime_append_all_bundles(...) abort " {{{1 + if a:0 + call s:warn('Change pathogen#runtime_append_all_bundles('.string(a:1).') to pathogen#incubate('.string(a:1.'/{}').')') + else + call s:warn('Change pathogen#runtime_append_all_bundles() to pathogen#incubate()') + endif + return call('pathogen#incubate', map(copy(a:000),'v:val . "/{}"')) +endfunction + +let s:done_bundles = '' +" }}}1 + +" Invoke :helptags on all non-$VIM doc directories in runtimepath. +function! pathogen#helptags() abort " {{{1 + let sep = pathogen#separator() + for glob in pathogen#split(&rtp) + for dir in split(glob(glob), "\n") + if (dir.sep)[0 : strlen($VIMRUNTIME)] !=# $VIMRUNTIME.sep && filewritable(dir.sep.'doc') == 2 && !empty(filter(split(glob(dir.sep.'doc'.sep.'*'),"\n>"),'!isdirectory(v:val)')) && (!filereadable(dir.sep.'doc'.sep.'tags') || filewritable(dir.sep.'doc'.sep.'tags')) + silent! execute 'helptags' pathogen#fnameescape(dir.'/doc') + endif + endfor + endfor +endfunction " }}}1 + +command! -bar Helptags :call pathogen#helptags() + +" Execute the given command. This is basically a backdoor for --remote-expr. +function! pathogen#execute(...) abort " {{{1 + for command in a:000 + execute command + endfor + return '' +endfunction " }}}1 + +" Like findfile(), but hardcoded to use the runtimepath. +function! pathogen#runtime_findfile(file,count) abort "{{{1 + let rtp = pathogen#join(1,pathogen#split(&rtp)) + let file = findfile(a:file,rtp,a:count) + if file ==# '' + return '' + else + return fnamemodify(file,':p') + endif +endfunction " }}}1 + +" Backport of fnameescape(). +function! pathogen#fnameescape(string) abort " {{{1 + if exists('*fnameescape') + return fnameescape(a:string) + elseif a:string ==# '-' + return '\-' + else + return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','') + endif +endfunction " }}}1 + +if exists(':Vedit') + finish +endif + +let s:vopen_warning = 0 + +function! s:find(count,cmd,file,lcd) " {{{1 + let rtp = pathogen#join(1,pathogen#split(&runtimepath)) + let file = pathogen#runtime_findfile(a:file,a:count) + if file ==# '' + return "echoerr 'E345: Can''t find file \"".a:file."\" in runtimepath'" + endif + if !s:vopen_warning + let s:vopen_warning = 1 + let warning = '|echohl WarningMsg|echo "Install scriptease.vim to continue using :V'.a:cmd.'"|echohl NONE' + else + let warning = '' + endif + if a:lcd + let path = file[0:-strlen(a:file)-2] + execute 'lcd `=path`' + return a:cmd.' '.pathogen#fnameescape(a:file) . warning + else + return a:cmd.' '.pathogen#fnameescape(file) . warning + endif +endfunction " }}}1 + +function! s:Findcomplete(A,L,P) " {{{1 + let sep = pathogen#separator() + let cheats = { + \'a': 'autoload', + \'d': 'doc', + \'f': 'ftplugin', + \'i': 'indent', + \'p': 'plugin', + \'s': 'syntax'} + if a:A =~# '^\w[\\/]' && has_key(cheats,a:A[0]) + let request = cheats[a:A[0]].a:A[1:-1] + else + let request = a:A + endif + let pattern = substitute(request,'/\|\'.sep,'*'.sep,'g').'*' + let found = {} + for path in pathogen#split(&runtimepath) + let path = expand(path, ':p') + let matches = split(glob(path.sep.pattern),"\n") + call map(matches,'isdirectory(v:val) ? v:val.sep : v:val') + call map(matches,'expand(v:val, ":p")[strlen(path)+1:-1]') + for match in matches + let found[match] = 1 + endfor + endfor + return sort(keys(found)) +endfunction " }}}1 + +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Ve :execute s:find(<count>,'edit<bang>',<q-args>,0) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vedit :execute s:find(<count>,'edit<bang>',<q-args>,0) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vopen :execute s:find(<count>,'edit<bang>',<q-args>,1) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vsplit :execute s:find(<count>,'split',<q-args>,<bang>1) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vvsplit :execute s:find(<count>,'vsplit',<q-args>,<bang>1) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vtabedit :execute s:find(<count>,'tabedit',<q-args>,<bang>1) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vpedit :execute s:find(<count>,'pedit',<q-args>,<bang>1) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vread :execute s:find(<count>,'read',<q-args>,<bang>1) + +" vim:set et sw=2: diff --git a/vim/bundle/custom/colors/ambient.vim b/vim/bundle/custom/colors/ambient.vim @@ -0,0 +1,58 @@ +" Maintainer: Kevin Hamer <kevin@imarc.net> +" Version: 1.2 +" Last Change: Fri Aug 12 16:53:40 EDT 2011 + +" Changes: +" 1.2 lightened the blue slightly +" 1.1 lightened both orange-reds + +"" Based off the colors for Ambiance, the 2011 Ubuntu dark human theme. +"" Derived from Mustang by Henrique C. Alves (hcarvalhoalves@gmail.com) +"" Offers 256 color support. + +set background=light + +hi clear + +if exists("syntax_on") + syntax reset +endif + +let colors_name = "ambient" + +" Vim >= 7.0 specific colors +if version >= 700 + " hi CursorLine cterm=underline + hi CursorLine cterm=underline + hi ColorColumn ctermfg=15 ctermbg=7 cterm=none + hi MatchParen ctermfg=15 ctermbg=8 cterm=bold + hi Pmenu ctermfg=15 ctermbg=8 + hi PmenuSel ctermfg=8 ctermbg=15 +endif +" General colors +hi Cursor ctermbg=12 +hi Normal ctermfg=8 +hi NonText ctermfg=237 +hi LineNr ctermfg=239 +hi StatusLine ctermfg=8 ctermbg=15 +hi StatusLineNC ctermfg=246 +hi VertSplit ctermfg=234 +hi Folded ctermfg=80 +hi Title ctermfg=8 +hi Visual ctermfg=15 +hi SpecialKey ctermfg=239 + +" Syntax highlight +hi Comment ctermfg=6 +hi Boolean ctermfg=5 +hi String ctermfg=13 +hi Identifier ctermfg=13 +hi Function ctermfg=8 +hi Type ctermfg=10 +hi Statement ctermfg=11 +hi Keyword ctermfg=4 +hi Constant ctermfg=5 +hi Number ctermfg=13 +hi Special ctermfg=5 +hi PreProc ctermfg=7 +hi Todo ctermfg=15 ctermbg=8 diff --git a/vim/bundle/custom/ftplugin/header.vim b/vim/bundle/custom/ftplugin/header.vim @@ -0,0 +1,28 @@ +fu! AddFileHeader() + let s:line=1 + call append(0, "\/*") + call append(s:line, " * ===== SOURCE FILE ==========================================") + call append(s:line+1, " *") + call append(s:line+2, " * Filename: " .expand("%")) + call append(s:line+3, " * Author: Willy Goiffon") + call append(s:line+4, " *") + call append(s:line+5, " * Creation Date: " .strftime("%d-%m-%Y %H:%M:%S")) + call append(s:line+6, " * Last Modified: ") + call append(s:line+7, " * Compiler: " .$CC) + call append(s:line+8, " *") + call append(s:line+9, " * Description: ") + call append(s:line+10, " *") + call append(s:line+11," * ============================================================") + call append(s:line+12, " */") + call append(s:line+13, "") + unlet s:line +endfunc + +fu! UpdateFileHeader() + normal ma + exe "8g/Last Modified/s/Last Modified:.*/Last Modified: " .strftime("%c") + normal `a +endfunc + +au BufNewFile *.c exe "call AddFileHeader()" +au BufWritePre *.c exe "call UpdateFileHeader()" diff --git a/vim/bundle/custom/plugin/gpg.vim b/vim/bundle/custom/plugin/gpg.vim @@ -0,0 +1,31 @@ +" Transparent editing of gpg encrypted files. +augroup encrypted +au! +" First make sure nothing is written to ~/.viminfo while editing +" an encrypted file. +autocmd BufReadPre,FileReadPre *.gpg set viminfo= +" We don't want a swap file, as it writes unencrypted data to disk +autocmd BufReadPre,FileReadPre *.gpg set noswapfile +" Switch to binary mode to read the encrypted file +autocmd BufReadPre,FileReadPre *.gpg set bin +autocmd BufReadPre,FileReadPre *.gpg let ch_save = &ch|set ch=2 +autocmd BufReadPre,FileReadPre *.gpg let shsave=&sh +autocmd BufReadPre,FileReadPre *.gpg let &sh='sh' +autocmd BufReadPre,FileReadPre *.gpg let ch_save = &ch|set ch=2 +autocmd BufReadPost,FileReadPost *.gpg '[,']!gpg --decrypt --default-recipient-self 2> /dev/null +autocmd BufReadPost,FileReadPost *.gpg let &sh=shsave +" Switch to normal mode for editing +autocmd BufReadPost,FileReadPost *.gpg set nobin +autocmd BufReadPost,FileReadPost *.gpg let &ch = ch_save|unlet ch_save +autocmd BufReadPost,FileReadPost *.gpg execute ":doautocmd BufReadPost " . expand("%:r") +" Convert all text to encrypted text before writing +autocmd BufWritePre,FileWritePre *.gpg set bin +autocmd BufWritePre,FileWritePre *.gpg let shsave=&sh +autocmd BufWritePre,FileWritePre *.gpg let &sh='sh' +autocmd BufWritePre,FileWritePre *.gpg '[,']!gpg --encrypt --default-recipient-self 2>/dev/null +autocmd BufWritePre,FileWritePre *.gpg let &sh=shsave +" Undo the encryption so we are back in the normal text, directly +" after the file has been written. +autocmd BufWritePost,FileWritePost *.gpg silent u +autocmd BufWritePost,FileWritePost *.gpg set nobin +augroup END diff --git a/vim/bundle/matchit/.gitignore b/vim/bundle/matchit/.gitignore @@ -0,0 +1,4 @@ +# File types to be ignored by our git repositories + +.DS_Store +doc/tags diff --git a/vim/bundle/matchit/doc/matchit.txt b/vim/bundle/matchit/doc/matchit.txt @@ -0,0 +1,406 @@ +*matchit.txt* Extended "%" matching + +For instructions on installing this file, type + :help matchit-install +inside Vim. + +For Vim version 6.3. Last change: 2007 Aug 29 + + + VIM REFERENCE MANUAL by Benji Fisher + +*matchit* *matchit.vim* + +1. Extended matching with "%" |matchit-intro| +2. Activation |matchit-activate| +3. Configuration |matchit-configure| +4. Supporting a New Language |matchit-newlang| +5. Known Bugs and Limitations |matchit-bugs| + +The functionality mentioned here is a plugin, see |add-plugin|. +This plugin is only available if 'compatible' is not set. +You can avoid loading this plugin by setting the "loaded_matchit" variable +in your |vimrc| file: > + :let loaded_matchit = 1 + +{Vi does not have any of this} + +============================================================================== +1. Extended matching with "%" *matchit-intro* + + *matchit-%* +% Cycle forward through matching groups, such as "if", "else", "endif", + as specified by |b:match_words|. + + *g%* *v_g%* *o_g%* +g% Cycle backwards through matching groups, as specified by + |b:match_words|. For example, go from "if" to "endif" to "else". + + *[%* *v_[%* *o_[%* +[% Go to [count] previous unmatched group, as specified by + |b:match_words|. Similar to |[{|. + + *]%* *v_]%* *o_]%* +]% Go to [count] next unmatched group, as specified by + |b:match_words|. Similar to |]}|. + + *v_a%* +a% In Visual mode, select the matching group, as specified by + |b:match_words|, containing the cursor. Similar to |v_a[|. + A [count] is ignored, and only the first character of the closing + pattern is selected. + +In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace, +bracket, or paren to its match. This can be configured with the 'matchpairs' +option. The matchit plugin extends this in several ways: + + You can match whole words, such as "if" and "endif", not just + single characters. You can also specify a |regular-expression|. + You can define groups with more than two words, such as "if", + "else", "endif". Banging on the "%" key will cycle from the "if" to + the first "else", the next "else", ..., the closing "endif", and back + to the opening "if". Nested structures are skipped. Using |g%| goes + in the reverse direction. + By default, words inside comments and strings are ignored, unless + the cursor is inside a comment or string when you type "%". If the + only thing you want to do is modify the behavior of "%" so that it + behaves this way, you do not have to define |b:match_words|, since the + script uses the 'matchpairs' option as well as this variable. + +See |matchit-details| for details on what the script does, and |b:match_words| +for how to specify matching patterns. + +MODES: *matchit-modes* *matchit-v_%* *matchit-o_%* + +Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in +|motion| commands in |Operator-pending| and |Visual| modes. However, you +cannot make these motions |linewise| or |characterwise|, since the |:omap|s +that define them start with "v" in order to make the default behavior +inclusive. (See |o_v|.) In other words, "dV%" will not work. The +work-around is to go through Visual mode: "V%d" will work. + +LANGUAGES: *matchit-languages* + +Currently, the following languages are supported: Ada, ASP with VBS, Csh, +DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal, +SGML, Shell, Tcsh, Vim, XML. Other languages may already have support via +the default |filetype-plugin|s in the standard vim distribution. + +To support a new language, see |matchit-newlang| below. + +DETAILS: *matchit-details* *matchit-parse* + +Here is an outline of what matchit.vim does each time you hit the "%" key. If +there are |backref|s in |b:match_words| then the first step is to produce a +version in which these back references have been eliminated; if there are no +|backref|s then this step is skipped. This step is called parsing. For +example, "\(foo\|bar\):end\1" is parsed to yield +"\(foo\|bar\):end\(foo\|bar\)". This can get tricky, especially if there are +nested groups. If debugging is turned on, the parsed version is saved as +|b:match_pat|. + + *matchit-choose* +Next, the script looks for a word on the current line that matches the pattern +just constructed. It includes the patterns from the 'matchpairs' option. +The goal is to do what you expect, which turns out to be a little complicated. +The script follows these rules: + + Insist on a match that ends on or after the cursor. + Prefer a match that includes the cursor position (that is, one that + starts on or before the cursor). + Prefer a match that starts as close to the cursor as possible. + If more than one pattern in |b:match_words| matches, choose the one + that is listed first. + +Examples: + + Suppose you > + :let b:match_words = '<:>,<tag>:</tag>' +< and hit "%" with the cursor on or before the "<" in "a <tag> is born". + The pattern '<' comes first, so it is preferred over '<tag>', which + also matches. If the cursor is on the "t", however, then '<tag>' is + preferred, because this matches a bit of text containing the cursor. + If the two groups of patterns were reversed then '<' would never be + preferred. + + Suppose you > + :let b:match_words = 'if:end if' +< (Note the space!) and hit "%" with the cursor at the end of "end if". + Then "if" matches, which is probably not what you want, but if the + cursor starts on the "end " then "end if" is chosen. (You can avoid + this problem by using a more complicated pattern.) + +If there is no match, the cursor does not move. (Before version 1.13 of the +script, it would fall back on the usual behavior of |%|). If debugging is +turned on, the matched bit of text is saved as |b:match_match| and the cursor +column of the start of the match is saved as |b:match_col|. + +Next, the script looks through |b:match_words| (original and parsed versions) +for the group and pattern that match. If debugging is turned on, the group is +saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest). If +there are |backref|s then, in addition, the matching pattern is saved as +|b:match_word| and a table of translations is saved as |b:match_table|. If +there are |backref|s, these are determined from the matching pattern and +|b:match_match| and substituted into each pattern in the matching group. + +The script decides whether to search forwards or backwards and chooses +arguments for the |searchpair()| function. Then, the cursor is moved to the +start of the match, and |searchpair()| is called. By default, matching +structures inside strings and comments are ignored. This can be changed by +setting |b:match_skip|. + +============================================================================== +2. Activation *matchit-activate* + +You can use this script as a plugin, by copying it to your plugin directory. +See |add-global-plugin| for instructions. You can also add a line to your +|vimrc| file, such as > + :source $VIMRUNTIME/macros/matchit.vim +or > + :runtime macros/matchit.vim +Either way, the script should start working the next time you start up Vim. + +(Earlier versions of the script did nothing unless a |buffer-variable| named +|b:match_words| was defined. Even earlier versions contained autocommands +that set this variable for various file types. Now, |b:match_words| is +defined in many of the default |filetype-plugin|s instead.) + +For a new language, you can add autocommands to the script or to your vimrc +file, but the recommended method is to add a line such as > + let b:match_words = '\<foo\>:\<bar\>' +to the |filetype-plugin| for your language. See |b:match_words| below for how +this variable is interpreted. + +TROUBLESHOOTING *matchit-troubleshoot* + +The script should work in most installations of Vim. It may not work if Vim +was compiled with a minimal feature set, for example if the |+syntax| option +was not enabled. If your Vim has support for syntax compiled in, but you do +not have |syntax| highlighting turned on, matchit.vim should work, but it may +fail to skip matching groups in comments and strings. If the |filetype| +mechanism is turned off, the |b:match_words| variable will probably not be +defined automatically. + +============================================================================== +3. Configuration *matchit-configure* + +There are several variables that govern the behavior of matchit.vim. Note +that these are variables local to the buffer, not options, so use |:let| to +define them, not |:set|. Some of these variables have values that matter; for +others, it only matters whether the variable has been defined. All of these +can be defined in the |filetype-plugin| or autocommand that defines +|b:match_words| or "on the fly." + +The main variable is |b:match_words|. It is described in the section below on +supporting a new language. + + *MatchError* *matchit-hl* *matchit-highlight* +MatchError is the highlight group for error messages from the script. By +default, it is linked to WarningMsg. If you do not want to be bothered by +error messages, you can define this to be something invisible. For example, +if you use the GUI version of Vim and your command line is normally white, you +can do > + :hi MatchError guifg=white guibg=white +< + *b:match_ignorecase* +If you > + :let b:match_ignorecase = 1 +then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END" +are equivalent. If you > + :let b:match_ignorecase = 0 +then matchit.vim treats "end" and "END" differently. (There will be no +b:match_infercase option unless someone requests it.) + + *b:match_debug* +Define b:match_debug if you want debugging information to be saved. See +|matchit-debug|, below. + + *b:match_skip* +If b:match_skip is defined, it is passed as the skip argument to +|searchpair()|. This controls when matching structures are skipped, or +ignored. By default, they are ignored inside comments and strings, as +determined by the |syntax| mechanism. (If syntax highlighting is turned off, +nothing is skipped.) You can set b:match_skip to a string, which evaluates to +a non-zero, numerical value if the match is to be skipped or zero if the match +should not be skipped. In addition, the following special values are +supported by matchit.vim: + s:foo becomes (current syntax item) =~ foo + S:foo becomes (current syntax item) !~ foo + r:foo becomes (line before cursor) =~ foo + R:foo becomes (line before cursor) !~ foo +(The "s" is meant to suggest "syntax", and the "r" is meant to suggest +"regular expression".) + +Examples: + + You can get the default behavior with > + :let b:match_skip = 's:comment\|string' +< + If you want to skip matching structures unless they are at the start + of the line (ignoring whitespace) then you can > + :let b:match_skip = 'R:^\s*' +< Do not do this if strings or comments can span several lines, since + the normal syntax checking will not be done if you set b:match_skip. + + In LaTeX, since "%" is used as the comment character, you can > + :let b:match_skip = 'r:%' +< Unfortunately, this will skip anything after "\%", an escaped "%". To + allow for this, and also "\\%" (an excaped backslash followed by the + comment character) you can > + :let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%' +< + See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both + syntax and a regular expression. + +============================================================================== +4. Supporting a New Language *matchit-newlang* + *b:match_words* +In order for matchit.vim to support a new language, you must define a suitable +pattern for |b:match_words|. You may also want to set some of the +|matchit-configure| variables, as described above. If your language has a +complicated syntax, or many keywords, you will need to know something about +Vim's |regular-expression|s. + +The format for |b:match_words| is similar to that of the 'matchpairs' option: +it is a comma (,)-separated list of groups; each group is a colon(:)-separated +list of patterns (regular expressions). Commas and backslashes that are part +of a pattern should be escaped with backslashes ('\:' and '\,'). It is OK to +have only one group; the effect is undefined if a group has only one pattern. +A simple example is > + :let b:match_words = '\<if\>:\<endif\>,' + \ . '\<while\>:\<continue\>:\<break\>:\<endwhile\>' +(In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if" +matches the end of "endif" but "\<if\>" does not.) Then banging on the "%" +key will bounce the cursor between "if" and the matching "endif"; and from +"while" to any matching "continue" or "break", then to the matching "endwhile" +and back to the "while". It is almost always easier to use |literal-string|s +(single quotes) as above: '\<if\>' rather than "\\<if\\>" and so on. + +Exception: If the ":" character does not appear in b:match_words, then it is +treated as an expression to be evaluated. For example, > + :let b:match_words = 'GetMatchWords()' +allows you to define a function. This can return a different string depending +on the current syntax, for example. + +Once you have defined the appropriate value of |b:match_words|, you will +probably want to have this set automatically each time you edit the +appropriate file type. The recommended way to do this is by adding the +definition to a |filetype-plugin| file. + +Tips: Be careful that your initial pattern does not match your final pattern. +See the example above for the use of word-boundary expressions. It is usually +better to use ".\{-}" (as many as necessary) instead of ".*" (as many as +possible). See |\{-|. For example, in the string "<tag>label</tag>", "<.*>" +matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "<tag>" and +"</tag>". + + *matchit-spaces* *matchit-s:notend* +If "if" is to be paired with "end if" (Note the space!) then word boundaries +are not enough. Instead, define a regular expression s:notend that will match +anything but "end" and use it as follows: > + :let s:notend = '\%(\<end\s\+\)\@<!' + :let b:match_words = s:notend . '\<if\>:\<end\s\+if\>' +< *matchit-s:sol* +This is a simplified version of what is done for Ada. The s:notend is a +|script-variable|. Similarly, you may want to define a start-of-line regular +expression > + :let s:sol = '\%(^\|;\)\s*' +if keywords are only recognized after the start of a line or after a +semicolon (;), with optional white space. + + *matchit-backref* *matchit-\1* +In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the +INITIAL pattern enclosed in |\(|escaped parentheses|\)|. These are referred +to as back references, or backrefs. For example, > + :let b:match_words = '\<b\(o\+\)\>:\(h\)\1\>' +means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on. Note +that "\1" does not refer to the "\(h\)" in this example. If you have +"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything +up to and including the matching "\)": in "\(nested\(parentheses\)\)", "\1" +refers to everything and "\2" refers to "\(parentheses\)". If you use a +variable such as |s:notend| or |s:sol| in the previous paragraph then remember +to count any "\(" patterns in this variable. You do not have to count groups +defined by |\%(\)|. + +It should be possible to resolve back references from any pattern in the +group. For example, > + :let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2' +would not work because "\2" cannot be determined from "morefoo" and "\1" +cannot be determined from "andbar". On the other hand, > + :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' +should work (and have the same effect as "foobar:barfoo:endfoobar"), although +this has not been thoroughly tested. + +You can use |zero-width| patterns such as |\@<=| and |\zs|. (The latter has +not been thouroughly tested in matchit.vim.) For example, if the keyword "if" +must occur at the start of the line, with optional white space, you might use +the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of +at the start of the line. For another example, if HTML had only one tag then +one could > + :let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>' +so that "%" can bounce between matching "<" and ">" pairs or (starting on +"tag" or "/tag") between matching tags. Without the |\@<=|, the script would +bounce from "tag" to the "<" in "</tag>", and another "%" would not take you +back to where you started. + +DEBUGGING *matchit-debug* *:MatchDebug* + +If you are having trouble figuring out the appropriate definition of +|b:match_words| then you can take advantage of the same information I use when +debugging the script. This is especially true if you are not sure whether +your patterns or my script are at fault! To make this more convenient, I have +made the command :MatchDebug, which defines the variable |b:match_debug| and +creates a Matchit menu. This menu makes it convenient to check the values of +the variables described below. You will probably also want to read +|matchit-details| above. + +Defining the variable |b:match_debug| causes the script to set the following +variables, each time you hit the "%" key. Several of these are only defined +if |b:match_words| includes |backref|s. + + *b:match_pat* +The b:match_pat variable is set to |b:match_words| with |backref|s parsed. + *b:match_match* +The b:match_match variable is set to the bit of text that is recognized as a +match. + *b:match_col* +The b:match_col variable is set to the cursor column of the start of the +matching text. + *b:match_wholeBR* +The b:match_wholeBR variable is set to the comma-separated group of patterns +that matches, with |backref|s unparsed. + *b:match_iniBR* +The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|. + *b:match_ini* +The b:match_ini variable is set to the first pattern in |b:match_wholeBR|, +with |backref|s resolved from |b:match_match|. + *b:match_tail* +The b:match_tail variable is set to the remaining patterns in +|b:match_wholeBR|, with |backref|s resolved from |b:match_match|. + *b:match_word* +The b:match_word variable is set to the pattern from |b:match_wholeBR| that +matches |b:match_match|. + *b:match_table* +The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in +|b:match_word|. + +============================================================================== +5. Known Bugs and Limitations *matchit-bugs* + +Just because I know about a bug does not mean that it is on my todo list. I +try to respond to reports of bugs that cause real problems. If it does not +cause serious problems, or if there is a work-around, a bug may sit there for +a while. Moral: if a bug (known or not) bothers you, let me know. + +The various |:vmap|s defined in the script (%, |g%|, |[%|, |]%|, |a%|) may +have undesired effects in Select mode |Select-mode-mapping|. At least, if you +want to replace the selection with any character in "ag%[]" there will be a +pause of |'updatetime'| first. + +It would be nice if "\0" were recognized as the entire pattern. That is, it +would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1". I may +try to implement this in a future version. (This is not so easy to arrange as +you might think!) + +============================================================================== +vim:tw=78:fo=tcq2: diff --git a/vim/bundle/matchit/plugin/matchit.vim b/vim/bundle/matchit/plugin/matchit.vim @@ -0,0 +1,812 @@ +" matchit.vim: (global plugin) Extended "%" matching +" Last Change: Fri Jan 25 10:00 AM 2008 EST +" Maintainer: Benji Fisher PhD <benji@member.AMS.org> +" Version: 1.13.2, for Vim 6.3+ +" URL: http://www.vim.org/script.php?script_id=39 + +" Documentation: +" The documentation is in a separate file, matchit.txt . + +" Credits: +" Vim editor by Bram Moolenaar (Thanks, Bram!) +" Original script and design by Raul Segura Acevedo +" Support for comments by Douglas Potts +" Support for back references and other improvements by Benji Fisher +" Support for many languages by Johannes Zellner +" Suggestions for improvement, bug reports, and support for additional +" languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark +" Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner. + +" Debugging: +" If you'd like to try the built-in debugging commands... +" :MatchDebug to activate debugging for the current buffer +" This saves the values of several key script variables as buffer-local +" variables. See the MatchDebug() function, below, for details. + +" TODO: I should think about multi-line patterns for b:match_words. +" This would require an option: how many lines to scan (default 1). +" This would be useful for Python, maybe also for *ML. +" TODO: Maybe I should add a menu so that people will actually use some of +" the features that I have implemented. +" TODO: Eliminate the MultiMatch function. Add yet another argument to +" Match_wrapper() instead. +" TODO: Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' +" TODO: Make backrefs safer by using '\V' (very no-magic). +" TODO: Add a level of indirection, so that custom % scripts can use my +" work but extend it. + +" allow user to prevent loading +" and prevent duplicate loading +if exists("loaded_matchit") || &cp + finish +endif +let loaded_matchit = 1 +let s:last_mps = "" +let s:last_words = ":" + +let s:save_cpo = &cpo +set cpo&vim + +nnoremap <silent> % :<C-U>call <SID>Match_wrapper('',1,'n') <CR> +nnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'n') <CR> +vnoremap <silent> % :<C-U>call <SID>Match_wrapper('',1,'v') <CR>m'gv`` +vnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'v') <CR>m'gv`` +onoremap <silent> % v:<C-U>call <SID>Match_wrapper('',1,'o') <CR> +onoremap <silent> g% v:<C-U>call <SID>Match_wrapper('',0,'o') <CR> + +" Analogues of [{ and ]} using matching patterns: +nnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "n") <CR> +nnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W", "n") <CR> +vmap [% <Esc>[%m'gv`` +vmap ]% <Esc>]%m'gv`` +" vnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "v") <CR>m'gv`` +" vnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W", "v") <CR>m'gv`` +onoremap <silent> [% v:<C-U>call <SID>MultiMatch("bW", "o") <CR> +onoremap <silent> ]% v:<C-U>call <SID>MultiMatch("W", "o") <CR> + +" text object: +vmap a% <Esc>[%v]% + +" Auto-complete mappings: (not yet "ready for prime time") +" TODO Read :help write-plugin for the "right" way to let the user +" specify a key binding. +" let g:match_auto = '<C-]>' +" let g:match_autoCR = '<C-CR>' +" if exists("g:match_auto") +" execute "inoremap " . g:match_auto . ' x<Esc>"=<SID>Autocomplete()<CR>Pls' +" endif +" if exists("g:match_autoCR") +" execute "inoremap " . g:match_autoCR . ' <CR><C-R>=<SID>Autocomplete()<CR>' +" endif +" if exists("g:match_gthhoh") +" execute "inoremap " . g:match_gthhoh . ' <C-O>:call <SID>Gthhoh()<CR>' +" endif " gthhoh = "Get the heck out of here!" + +let s:notslash = '\\\@<!\%(\\\\\)*' + +function! s:Match_wrapper(word, forward, mode) range + " In s:CleanUp(), :execute "set" restore_options . + let restore_options = (&ic ? " " : " no") . "ignorecase" + if exists("b:match_ignorecase") + let &ignorecase = b:match_ignorecase + endif + let restore_options = " ve=" . &ve . restore_options + set ve= + " If this function was called from Visual mode, make sure that the cursor + " is at the correct end of the Visual range: + if a:mode == "v" + execute "normal! gv\<Esc>" + endif + " In s:CleanUp(), we may need to check whether the cursor moved forward. + let startline = line(".") + let startcol = col(".") + " Use default behavior if called with a count. + if v:count + exe "normal! " . v:count . "%" + return s:CleanUp(restore_options, a:mode, startline, startcol) + end + + " First step: if not already done, set the script variables + " s:do_BR flag for whether there are backrefs + " s:pat parsed version of b:match_words + " s:all regexp based on s:pat and the default groups + " + if !exists("b:match_words") || b:match_words == "" + let match_words = "" + " Allow b:match_words = "GetVimMatchWords()" . + elseif b:match_words =~ ":" + let match_words = b:match_words + else + execute "let match_words =" b:match_words + endif +" Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion! + if (match_words != s:last_words) || (&mps != s:last_mps) || + \ exists("b:match_debug") + let s:last_words = match_words + let s:last_mps = &mps + " The next several lines were here before + " BF started messing with this script. + " quote the special chars in 'matchpairs', replace [,:] with \| and then + " append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif) + " let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+', + " \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>' + let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") . + \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>' + " s:all = pattern with all the keywords + let match_words = match_words . (strlen(match_words) ? "," : "") . default + if match_words !~ s:notslash . '\\\d' + let s:do_BR = 0 + let s:pat = match_words + else + let s:do_BR = 1 + let s:pat = s:ParseWords(match_words) + endif + let s:all = substitute(s:pat, s:notslash . '\zs[,:]\+', '\\|', 'g') + let s:all = '\%(' . s:all . '\)' + " let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)' + if exists("b:match_debug") + let b:match_pat = s:pat + endif + endif + + " Second step: set the following local variables: + " matchline = line on which the cursor started + " curcol = number of characters before match + " prefix = regexp for start of line to start of match + " suffix = regexp for end of match to end of line + " Require match to end on or after the cursor and prefer it to + " start on or before the cursor. + let matchline = getline(startline) + if a:word != '' + " word given + if a:word !~ s:all + echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE + return s:CleanUp(restore_options, a:mode, startline, startcol) + endif + let matchline = a:word + let curcol = 0 + let prefix = '^\%(' + let suffix = '\)$' + " Now the case when "word" is not given + else " Find the match that ends on or after the cursor and set curcol. + let regexp = s:Wholematch(matchline, s:all, startcol-1) + let curcol = match(matchline, regexp) + " If there is no match, give up. + if curcol == -1 + return s:CleanUp(restore_options, a:mode, startline, startcol) + endif + let endcol = matchend(matchline, regexp) + let suf = strlen(matchline) - endcol + let prefix = (curcol ? '^.*\%' . (curcol + 1) . 'c\%(' : '^\%(') + let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$' : '\)$') + endif + if exists("b:match_debug") + let b:match_match = matchstr(matchline, regexp) + let b:match_col = curcol+1 + endif + + " Third step: Find the group and single word that match, and the original + " (backref) versions of these. Then, resolve the backrefs. + " Set the following local variable: + " group = colon-separated list of patterns, one of which matches + " = ini:mid:fin or ini:fin + " + " Reconstruct the version with unresolved backrefs. + let patBR = substitute(match_words.',', + \ s:notslash.'\zs[,:]*,[,:]*', ',', 'g') + let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g') + " Now, set group and groupBR to the matching group: 'if:endif' or + " 'while:endwhile' or whatever. A bit of a kluge: s:Choose() returns + " group . "," . groupBR, and we pick it apart. + let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR) + let i = matchend(group, s:notslash . ",") + let groupBR = strpart(group, i) + let group = strpart(group, 0, i-1) + " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix + if s:do_BR " Do the hard part: resolve those backrefs! + let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline) + endif + if exists("b:match_debug") + let b:match_wholeBR = groupBR + let i = matchend(groupBR, s:notslash . ":") + let b:match_iniBR = strpart(groupBR, 0, i-1) + endif + + " Fourth step: Set the arguments for searchpair(). + let i = matchend(group, s:notslash . ":") + let j = matchend(group, '.*' . s:notslash . ":") + let ini = strpart(group, 0, i-1) + let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g') + let fin = strpart(group, j) + "Un-escape the remaining , and : characters. + let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') + let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') + let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') + " searchpair() requires that these patterns avoid \(\) groups. + let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g') + let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g') + let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g') + " Set mid. This is optimized for readability, not micro-efficiency! + if a:forward && matchline =~ prefix . fin . suffix + \ || !a:forward && matchline =~ prefix . ini . suffix + let mid = "" + endif + " Set flag. This is optimized for readability, not micro-efficiency! + if a:forward && matchline =~ prefix . fin . suffix + \ || !a:forward && matchline !~ prefix . ini . suffix + let flag = "bW" + else + let flag = "W" + endif + " Set skip. + if exists("b:match_skip") + let skip = b:match_skip + elseif exists("b:match_comment") " backwards compatibility and testing! + let skip = "r:" . b:match_comment + else + let skip = 's:comment\|string' + endif + let skip = s:ParseSkip(skip) + if exists("b:match_debug") + let b:match_ini = ini + let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin + endif + + " Fifth step: actually start moving the cursor and call searchpair(). + " Later, :execute restore_cursor to get to the original screen. + let restore_cursor = virtcol(".") . "|" + normal! g0 + let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor + normal! H + let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor + execute restore_cursor + call cursor(0, curcol + 1) + " normal! 0 + " if curcol + " execute "normal!" . curcol . "l" + " endif + if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on")) + let skip = "0" + else + execute "if " . skip . "| let skip = '0' | endif" + endif + let sp_return = searchpair(ini, mid, fin, flag, skip) + let final_position = "call cursor(" . line(".") . "," . col(".") . ")" + " Restore cursor position and original screen. + execute restore_cursor + normal! m' + if sp_return > 0 + execute final_position + endif + return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin) +endfun + +" Restore options and do some special handling for Operator-pending mode. +" The optional argument is the tail of the matching group. +fun! s:CleanUp(options, mode, startline, startcol, ...) + execute "set" a:options + " Open folds, if appropriate. + if a:mode != "o" + if &foldopen =~ "percent" + normal! zv + endif + " In Operator-pending mode, we want to include the whole match + " (for example, d%). + " This is only a problem if we end up moving in the forward direction. + elseif (a:startline < line(".")) || + \ (a:startline == line(".") && a:startcol < col(".")) + if a:0 + " Check whether the match is a single character. If not, move to the + " end of the match. + let matchline = getline(".") + let currcol = col(".") + let regexp = s:Wholematch(matchline, a:1, currcol-1) + let endcol = matchend(matchline, regexp) + if endcol > currcol " This is NOT off by one! + execute "normal!" . (endcol - currcol) . "l" + endif + endif " a:0 + endif " a:mode != "o" && etc. + return 0 +endfun + +" Example (simplified HTML patterns): if +" a:groupBR = '<\(\k\+\)>:</\1>' +" a:prefix = '^.\{3}\(' +" a:group = '<\(\k\+\)>:</\(\k\+\)>' +" a:suffix = '\).\{2}$' +" a:matchline = "123<tag>12" or "123</tag>12" +" then extract "tag" from a:matchline and return "<tag>:</tag>" . +fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline) + if a:matchline !~ a:prefix . + \ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix + return a:group + endif + let i = matchend(a:groupBR, s:notslash . ':') + let ini = strpart(a:groupBR, 0, i-1) + let tailBR = strpart(a:groupBR, i) + let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix, + \ a:groupBR) + let i = matchend(word, s:notslash . ":") + let wordBR = strpart(word, i) + let word = strpart(word, 0, i-1) + " Now, a:matchline =~ a:prefix . word . a:suffix + if wordBR != ini + let table = s:Resolve(ini, wordBR, "table") + else + " let table = "----------" + let table = "" + let d = 0 + while d < 10 + if tailBR =~ s:notslash . '\\' . d + " let table[d] = d + let table = table . d + else + let table = table . "-" + endif + let d = d + 1 + endwhile + endif + let d = 9 + while d + if table[d] != "-" + let backref = substitute(a:matchline, a:prefix.word.a:suffix, + \ '\'.table[d], "") + " Are there any other characters that should be escaped? + let backref = escape(backref, '*,:') + execute s:Ref(ini, d, "start", "len") + let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len) + let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d, + \ escape(backref, '\\'), 'g') + endif + let d = d-1 + endwhile + if exists("b:match_debug") + if s:do_BR + let b:match_table = table + let b:match_word = word + else + let b:match_table = "" + let b:match_word = "" + endif + endif + return ini . ":" . tailBR +endfun + +" Input a comma-separated list of groups with backrefs, such as +" a:groups = '\(foo\):end\1,\(bar\):end\1' +" and return a comma-separated list of groups with backrefs replaced: +" return '\(foo\):end\(foo\),\(bar\):end\(bar\)' +fun! s:ParseWords(groups) + let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g') + let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g') + let parsed = "" + while groups =~ '[^,:]' + let i = matchend(groups, s:notslash . ':') + let j = matchend(groups, s:notslash . ',') + let ini = strpart(groups, 0, i-1) + let tail = strpart(groups, i, j-i-1) . ":" + let groups = strpart(groups, j) + let parsed = parsed . ini + let i = matchend(tail, s:notslash . ':') + while i != -1 + " In 'if:else:endif', ini='if' and word='else' and then word='endif'. + let word = strpart(tail, 0, i-1) + let tail = strpart(tail, i) + let i = matchend(tail, s:notslash . ':') + let parsed = parsed . ":" . s:Resolve(ini, word, "word") + endwhile " Now, tail has been used up. + let parsed = parsed . "," + endwhile " groups =~ '[^,:]' + let parsed = substitute(parsed, ',$', '', '') + return parsed +endfun + +" TODO I think this can be simplified and/or made more efficient. +" TODO What should I do if a:start is out of range? +" Return a regexp that matches all of a:string, such that +" matchstr(a:string, regexp) represents the match for a:pat that starts +" as close to a:start as possible, before being preferred to after, and +" ends after a:start . +" Usage: +" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1) +" let i = match(getline("."), regexp) +" let j = matchend(getline("."), regexp) +" let match = matchstr(getline("."), regexp) +fun! s:Wholematch(string, pat, start) + let group = '\%(' . a:pat . '\)' + let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^') + let len = strlen(a:string) + let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$') + if a:string !~ prefix . group . suffix + let prefix = '' + endif + return prefix . group . suffix +endfun + +" No extra arguments: s:Ref(string, d) will +" find the d'th occurrence of '\(' and return it, along with everything up +" to and including the matching '\)'. +" One argument: s:Ref(string, d, "start") returns the index of the start +" of the d'th '\(' and any other argument returns the length of the group. +" Two arguments: s:Ref(string, d, "foo", "bar") returns a string to be +" executed, having the effect of +" :let foo = s:Ref(string, d, "start") +" :let bar = s:Ref(string, d, "len") +fun! s:Ref(string, d, ...) + let len = strlen(a:string) + if a:d == 0 + let start = 0 + else + let cnt = a:d + let match = a:string + while cnt + let cnt = cnt - 1 + let index = matchend(match, s:notslash . '\\(') + if index == -1 + return "" + endif + let match = strpart(match, index) + endwhile + let start = len - strlen(match) + if a:0 == 1 && a:1 == "start" + return start - 2 + endif + let cnt = 1 + while cnt + let index = matchend(match, s:notslash . '\\(\|\\)') - 1 + if index == -2 + return "" + endif + " Increment if an open, decrement if a ')': + let cnt = cnt + (match[index]=="(" ? 1 : -1) " ')' + " let cnt = stridx('0(', match[index]) + cnt + let match = strpart(match, index+1) + endwhile + let start = start - 2 + let len = len - start - strlen(match) + endif + if a:0 == 1 + return len + elseif a:0 == 2 + return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len + else + return strpart(a:string, start, len) + endif +endfun + +" Count the number of disjoint copies of pattern in string. +" If the pattern is a literal string and contains no '0' or '1' characters +" then s:Count(string, pattern, '0', '1') should be faster than +" s:Count(string, pattern). +fun! s:Count(string, pattern, ...) + let pat = escape(a:pattern, '\\') + if a:0 > 1 + let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g") + let foo = substitute(a:string, pat, a:2, "g") + let foo = substitute(foo, '[^' . a:2 . ']', "", "g") + return strlen(foo) + endif + let result = 0 + let foo = a:string + let index = matchend(foo, pat) + while index != -1 + let result = result + 1 + let foo = strpart(foo, index) + let index = matchend(foo, pat) + endwhile + return result +endfun + +" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where +" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'. That is, the first +" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this +" indicates that all other instances of '\1' in target are to be replaced +" by '\3'. The hard part is dealing with nesting... +" Note that ":" is an illegal character for source and target, +" unless it is preceded by "\". +fun! s:Resolve(source, target, output) + let word = a:target + let i = matchend(word, s:notslash . '\\\d') - 1 + let table = "----------" + while i != -2 " There are back references to be replaced. + let d = word[i] + let backref = s:Ref(a:source, d) + " The idea is to replace '\d' with backref. Before we do this, + " replace any \(\) groups in backref with :1, :2, ... if they + " correspond to the first, second, ... group already inserted + " into backref. Later, replace :1 with \1 and so on. The group + " number w+b within backref corresponds to the group number + " s within a:source. + " w = number of '\(' in word before the current one + let w = s:Count( + \ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1') + let b = 1 " number of the current '\(' in backref + let s = d " number of the current '\(' in a:source + while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1') + \ && s < 10 + if table[s] == "-" + if w + b < 10 + " let table[s] = w + b + let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1) + endif + let b = b + 1 + let s = s + 1 + else + execute s:Ref(backref, b, "start", "len") + let ref = strpart(backref, start, len) + let backref = strpart(backref, 0, start) . ":". table[s] + \ . strpart(backref, start+len) + let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1') + endif + endwhile + let word = strpart(word, 0, i-1) . backref . strpart(word, i+1) + let i = matchend(word, s:notslash . '\\\d') - 1 + endwhile + let word = substitute(word, s:notslash . '\zs:', '\\', 'g') + if a:output == "table" + return table + elseif a:output == "word" + return word + else + return table . word + endif +endfun + +" Assume a:comma = ",". Then the format for a:patterns and a:1 is +" a:patterns = "<pat1>,<pat2>,..." +" a:1 = "<alt1>,<alt2>,..." +" If <patn> is the first pattern that matches a:string then return <patn> +" if no optional arguments are given; return <patn>,<altn> if a:1 is given. +fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...) + let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma) + let i = matchend(tail, s:notslash . a:comma) + if a:0 + let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma) + let j = matchend(alttail, s:notslash . a:comma) + endif + let current = strpart(tail, 0, i-1) + if a:branch == "" + let currpat = current + else + let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g') + endif + while a:string !~ a:prefix . currpat . a:suffix + let tail = strpart(tail, i) + let i = matchend(tail, s:notslash . a:comma) + if i == -1 + return -1 + endif + let current = strpart(tail, 0, i-1) + if a:branch == "" + let currpat = current + else + let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g') + endif + if a:0 + let alttail = strpart(alttail, j) + let j = matchend(alttail, s:notslash . a:comma) + endif + endwhile + if a:0 + let current = current . a:comma . strpart(alttail, 0, j-1) + endif + return current +endfun + +" Call this function to turn on debugging information. Every time the main +" script is run, buffer variables will be saved. These can be used directly +" or viewed using the menu items below. +if !exists(":MatchDebug") + command! -nargs=0 MatchDebug call s:Match_debug() +endif + +fun! s:Match_debug() + let b:match_debug = 1 " Save debugging information. + " pat = all of b:match_words with backrefs parsed + amenu &Matchit.&pat :echo b:match_pat<CR> + " match = bit of text that is recognized as a match + amenu &Matchit.&match :echo b:match_match<CR> + " curcol = cursor column of the start of the matching text + amenu &Matchit.&curcol :echo b:match_col<CR> + " wholeBR = matching group, original version + amenu &Matchit.wh&oleBR :echo b:match_wholeBR<CR> + " iniBR = 'if' piece, original version + amenu &Matchit.ini&BR :echo b:match_iniBR<CR> + " ini = 'if' piece, with all backrefs resolved from match + amenu &Matchit.&ini :echo b:match_ini<CR> + " tail = 'else\|endif' piece, with all backrefs resolved from match + amenu &Matchit.&tail :echo b:match_tail<CR> + " fin = 'endif' piece, with all backrefs resolved from match + amenu &Matchit.&word :echo b:match_word<CR> + " '\'.d in ini refers to the same thing as '\'.table[d] in word. + amenu &Matchit.t&able :echo '0:' . b:match_table . ':9'<CR> +endfun + +" Jump to the nearest unmatched "(" or "if" or "<tag>" if a:spflag == "bW" +" or the nearest unmatched "</tag>" or "endif" or ")" if a:spflag == "W". +" Return a "mark" for the original position, so that +" let m = MultiMatch("bW", "n") ... execute m +" will return to the original position. If there is a problem, do not +" move the cursor and return "", unless a count is given, in which case +" go up or down as many levels as possible and again return "". +" TODO This relies on the same patterns as % matching. It might be a good +" idea to give it its own matching patterns. +fun! s:MultiMatch(spflag, mode) + if !exists("b:match_words") || b:match_words == "" + return "" + end + let restore_options = (&ic ? "" : "no") . "ignorecase" + if exists("b:match_ignorecase") + let &ignorecase = b:match_ignorecase + endif + let startline = line(".") + let startcol = col(".") + + " First step: if not already done, set the script variables + " s:do_BR flag for whether there are backrefs + " s:pat parsed version of b:match_words + " s:all regexp based on s:pat and the default groups + " This part is copied and slightly modified from s:Match_wrapper(). + let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") . + \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>' + " Allow b:match_words = "GetVimMatchWords()" . + if b:match_words =~ ":" + let match_words = b:match_words + else + execute "let match_words =" b:match_words + endif + if (match_words != s:last_words) || (&mps != s:last_mps) || + \ exists("b:match_debug") + let s:last_words = match_words + let s:last_mps = &mps + if match_words !~ s:notslash . '\\\d' + let s:do_BR = 0 + let s:pat = match_words + else + let s:do_BR = 1 + let s:pat = s:ParseWords(match_words) + endif + let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default, + \ '[,:]\+','\\|','g') . '\)' + if exists("b:match_debug") + let b:match_pat = s:pat + endif + endif + + " Second step: figure out the patterns for searchpair() + " and save the screen, cursor position, and 'ignorecase'. + " - TODO: A lot of this is copied from s:Match_wrapper(). + " - maybe even more functionality should be split off + " - into separate functions! + let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default + let open = substitute(s:pat . cdefault, + \ s:notslash . '\zs:.\{-}' . s:notslash . ',', '\\),\\(', 'g') + let open = '\(' . substitute(open, s:notslash . '\zs:.*$', '\\)', '') + let close = substitute(s:pat . cdefault, + \ s:notslash . '\zs,.\{-}' . s:notslash . ':', '\\),\\(', 'g') + let close = substitute(close, '^.\{-}' . s:notslash . ':', '\\(', '') . '\)' + if exists("b:match_skip") + let skip = b:match_skip + elseif exists("b:match_comment") " backwards compatibility and testing! + let skip = "r:" . b:match_comment + else + let skip = 's:comment\|string' + endif + let skip = s:ParseSkip(skip) + " let restore_cursor = line(".") . "G" . virtcol(".") . "|" + " normal! H + " let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor + let restore_cursor = virtcol(".") . "|" + normal! g0 + let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor + normal! H + let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor + execute restore_cursor + + " Third step: call searchpair(). + " Replace '\('--but not '\\('--with '\%(' and ',' with '\|'. + let openpat = substitute(open, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g') + let openpat = substitute(openpat, ',', '\\|', 'g') + let closepat = substitute(close, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g') + let closepat = substitute(closepat, ',', '\\|', 'g') + if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on")) + let skip = '0' + else + execute "if " . skip . "| let skip = '0' | endif" + endif + mark ' + let level = v:count1 + while level + if searchpair(openpat, '', closepat, a:spflag, skip) < 1 + call s:CleanUp(restore_options, a:mode, startline, startcol) + return "" + endif + let level = level - 1 + endwhile + + " Restore options and return a string to restore the original position. + call s:CleanUp(restore_options, a:mode, startline, startcol) + return restore_cursor +endfun + +" Search backwards for "if" or "while" or "<tag>" or ... +" and return "endif" or "endwhile" or "</tag>" or ... . +" For now, this uses b:match_words and the same script variables +" as s:Match_wrapper() . Later, it may get its own patterns, +" either from a buffer variable or passed as arguments. +" fun! s:Autocomplete() +" echo "autocomplete not yet implemented :-(" +" if !exists("b:match_words") || b:match_words == "" +" return "" +" end +" let startpos = s:MultiMatch("bW") +" +" if startpos == "" +" return "" +" endif +" " - TODO: figure out whether 'if' or '<tag>' matched, and construct +" " - the appropriate closing. +" let matchline = getline(".") +" let curcol = col(".") - 1 +" " - TODO: Change the s:all argument if there is a new set of match pats. +" let regexp = s:Wholematch(matchline, s:all, curcol) +" let suf = strlen(matchline) - matchend(matchline, regexp) +" let prefix = (curcol ? '^.\{' . curcol . '}\%(' : '^\%(') +" let suffix = (suf ? '\).\{' . suf . '}$' : '\)$') +" " Reconstruct the version with unresolved backrefs. +" let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g') +" let patBR = substitute(patBR, ':\{2,}', ':', "g") +" " Now, set group and groupBR to the matching group: 'if:endif' or +" " 'while:endwhile' or whatever. +" let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR) +" let i = matchend(group, s:notslash . ",") +" let groupBR = strpart(group, i) +" let group = strpart(group, 0, i-1) +" " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix +" if s:do_BR +" let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline) +" endif +" " let g:group = group +" +" " - TODO: Construct the closing from group. +" let fake = "end" . expand("<cword>") +" execute startpos +" return fake +" endfun + +" Close all open structures. "Get the heck out of here!" +" fun! s:Gthhoh() +" let close = s:Autocomplete() +" while strlen(close) +" put=close +" let close = s:Autocomplete() +" endwhile +" endfun + +" Parse special strings as typical skip arguments for searchpair(): +" s:foo becomes (current syntax item) =~ foo +" S:foo becomes (current syntax item) !~ foo +" r:foo becomes (line before cursor) =~ foo +" R:foo becomes (line before cursor) !~ foo +fun! s:ParseSkip(str) + let skip = a:str + if skip[1] == ":" + if skip[0] == "s" + let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" . + \ strpart(skip,2) . "'" + elseif skip[0] == "S" + let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" . + \ strpart(skip,2) . "'" + elseif skip[0] == "r" + let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'" + elseif skip[0] == "R" + let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'" + endif + endif + return skip +endfun + +let &cpo = s:save_cpo + +" vim:sts=2:sw=2: diff --git a/vim/bundle/snipmate/README.markdown b/vim/bundle/snipmate/README.markdown @@ -0,0 +1,5 @@ +Quickly install with: + + git clone git://github.com/msanders/snipmate.vim.git + cd snipmate.vim + cp -R * ~/.vim diff --git a/vim/bundle/snipmate/after/plugin/snipMate.vim b/vim/bundle/snipmate/after/plugin/snipMate.vim @@ -0,0 +1,40 @@ +" These are the mappings for snipMate.vim. Putting it here ensures that it +" will be mapped after other plugins such as supertab.vim. +if !exists('loaded_snips') || exists('s:did_snips_mappings') + finish +endif +let s:did_snips_mappings = 1 + +" This is put here in the 'after' directory in order for snipMate to override +" other plugin mappings (e.g., supertab). +" +" You can safely adjust these mappings to your preferences (as explained in +" :help snipMate-remap). +ino <silent> <tab> <c-r>=TriggerSnippet()<cr> +snor <silent> <tab> <esc>i<right><c-r>=TriggerSnippet()<cr> +ino <silent> <s-tab> <c-r>=BackwardsSnippet()<cr> +snor <silent> <s-tab> <esc>i<right><c-r>=BackwardsSnippet()<cr> +ino <silent> <c-r><tab> <c-r>=ShowAvailableSnips()<cr> + +" The default mappings for these are annoying & sometimes break snipMate. +" You can change them back if you want, I've put them here for convenience. +snor <bs> b<bs> +snor <right> <esc>a +snor <left> <esc>bi +snor ' b<bs>' +snor ` b<bs>` +snor % b<bs>% +snor U b<bs>U +snor ^ b<bs>^ +snor \ b<bs>\ +snor <c-x> b<bs><c-x> + +" By default load snippets in snippets_dir +if empty(snippets_dir) + finish +endif + +call GetSnippets(snippets_dir, '_') " Get global snippets + +au FileType * if &ft != 'help' | call GetSnippets(snippets_dir, &ft) | endif +" vim:noet:sw=4:ts=4:ft=vim diff --git a/vim/bundle/snipmate/autoload/snipMate.vim b/vim/bundle/snipmate/autoload/snipMate.vim @@ -0,0 +1,435 @@ +fun! Filename(...) + let filename = expand('%:t:r') + if filename == '' | return a:0 == 2 ? a:2 : '' | endif + return !a:0 || a:1 == '' ? filename : substitute(a:1, '$1', filename, 'g') +endf + +fun s:RemoveSnippet() + unl! g:snipPos s:curPos s:snipLen s:endCol s:endLine s:prevLen + \ s:lastBuf s:oldWord + if exists('s:update') + unl s:startCol s:origWordLen s:update + if exists('s:oldVars') | unl s:oldVars s:oldEndCol | endif + endif + aug! snipMateAutocmds +endf + +fun snipMate#expandSnip(snip, col) + let lnum = line('.') | let col = a:col + + let snippet = s:ProcessSnippet(a:snip) + " Avoid error if eval evaluates to nothing + if snippet == '' | return '' | endif + + " Expand snippet onto current position with the tab stops removed + let snipLines = split(substitute(snippet, '$\d\+\|${\d\+.\{-}}', '', 'g'), "\n", 1) + + let line = getline(lnum) + let afterCursor = strpart(line, col - 1) + " Keep text after the cursor + if afterCursor != "\t" && afterCursor != ' ' + let line = strpart(line, 0, col - 1) + let snipLines[-1] .= afterCursor + else + let afterCursor = '' + " For some reason the cursor needs to move one right after this + if line != '' && col == 1 && &ve != 'all' && &ve != 'onemore' + let col += 1 + endif + endif + + call setline(lnum, line.snipLines[0]) + + " Autoindent snippet according to previous indentation + let indent = matchend(line, '^.\{-}\ze\(\S\|$\)') + 1 + call append(lnum, map(snipLines[1:], "'".strpart(line, 0, indent - 1)."'.v:val")) + + " Open any folds snippet expands into + if &fen | sil! exe lnum.','.(lnum + len(snipLines) - 1).'foldopen' | endif + + let [g:snipPos, s:snipLen] = s:BuildTabStops(snippet, lnum, col - indent, indent) + + if s:snipLen + aug snipMateAutocmds + au CursorMovedI * call s:UpdateChangedSnip(0) + au InsertEnter * call s:UpdateChangedSnip(1) + aug END + let s:lastBuf = bufnr(0) " Only expand snippet while in current buffer + let s:curPos = 0 + let s:endCol = g:snipPos[s:curPos][1] + let s:endLine = g:snipPos[s:curPos][0] + + call cursor(g:snipPos[s:curPos][0], g:snipPos[s:curPos][1]) + let s:prevLen = [line('$'), col('$')] + if g:snipPos[s:curPos][2] != -1 | return s:SelectWord() | endif + else + unl g:snipPos s:snipLen + " Place cursor at end of snippet if no tab stop is given + let newlines = len(snipLines) - 1 + call cursor(lnum + newlines, indent + len(snipLines[-1]) - len(afterCursor) + \ + (newlines ? 0: col - 1)) + endif + return '' +endf + +" Prepare snippet to be processed by s:BuildTabStops +fun s:ProcessSnippet(snip) + let snippet = a:snip + " Evaluate eval (`...`) expressions. + " Backquotes prefixed with a backslash "\" are ignored. + " Using a loop here instead of a regex fixes a bug with nested "\=". + if stridx(snippet, '`') != -1 + while match(snippet, '\(^\|[^\\]\)`.\{-}[^\\]`') != -1 + let snippet = substitute(snippet, '\(^\|[^\\]\)\zs`.\{-}[^\\]`\ze', + \ substitute(eval(matchstr(snippet, '\(^\|[^\\]\)`\zs.\{-}[^\\]\ze`')), + \ "\n\\%$", '', ''), '') + endw + let snippet = substitute(snippet, "\r", "\n", 'g') + let snippet = substitute(snippet, '\\`', '`', 'g') + endif + + " Place all text after a colon in a tab stop after the tab stop + " (e.g. "${#:foo}" becomes "${:foo}foo"). + " This helps tell the position of the tab stops later. + let snippet = substitute(snippet, '${\d\+:\(.\{-}\)}', '&\1', 'g') + + " Update the a:snip so that all the $# become the text after + " the colon in their associated ${#}. + " (e.g. "${1:foo}" turns all "$1"'s into "foo") + let i = 1 + while stridx(snippet, '${'.i) != -1 + let s = matchstr(snippet, '${'.i.':\zs.\{-}\ze}') + if s != '' + let snippet = substitute(snippet, '$'.i, s.'&', 'g') + endif + let i += 1 + endw + + if &et " Expand tabs to spaces if 'expandtab' is set. + return substitute(snippet, '\t', repeat(' ', &sts ? &sts : &sw), 'g') + endif + return snippet +endf + +" Counts occurences of haystack in needle +fun s:Count(haystack, needle) + let counter = 0 + let index = stridx(a:haystack, a:needle) + while index != -1 + let index = stridx(a:haystack, a:needle, index+1) + let counter += 1 + endw + return counter +endf + +" Builds a list of a list of each tab stop in the snippet containing: +" 1.) The tab stop's line number. +" 2.) The tab stop's column number +" (by getting the length of the string between the last "\n" and the +" tab stop). +" 3.) The length of the text after the colon for the current tab stop +" (e.g. "${1:foo}" would return 3). If there is no text, -1 is returned. +" 4.) If the "${#:}" construct is given, another list containing all +" the matches of "$#", to be replaced with the placeholder. This list is +" composed the same way as the parent; the first item is the line number, +" and the second is the column. +fun s:BuildTabStops(snip, lnum, col, indent) + let snipPos = [] + let i = 1 + let withoutVars = substitute(a:snip, '$\d\+', '', 'g') + while stridx(a:snip, '${'.i) != -1 + let beforeTabStop = matchstr(withoutVars, '^.*\ze${'.i.'\D') + let withoutOthers = substitute(withoutVars, '${\('.i.'\D\)\@!\d\+.\{-}}', '', 'g') + + let j = i - 1 + call add(snipPos, [0, 0, -1]) + let snipPos[j][0] = a:lnum + s:Count(beforeTabStop, "\n") + let snipPos[j][1] = a:indent + len(matchstr(withoutOthers, '.*\(\n\|^\)\zs.*\ze${'.i.'\D')) + if snipPos[j][0] == a:lnum | let snipPos[j][1] += a:col | endif + + " Get all $# matches in another list, if ${#:name} is given + if stridx(withoutVars, '${'.i.':') != -1 + let snipPos[j][2] = len(matchstr(withoutVars, '${'.i.':\zs.\{-}\ze}')) + let dots = repeat('.', snipPos[j][2]) + call add(snipPos[j], []) + let withoutOthers = substitute(a:snip, '${\d\+.\{-}}\|$'.i.'\@!\d\+', '', 'g') + while match(withoutOthers, '$'.i.'\(\D\|$\)') != -1 + let beforeMark = matchstr(withoutOthers, '^.\{-}\ze'.dots.'$'.i.'\(\D\|$\)') + call add(snipPos[j][3], [0, 0]) + let snipPos[j][3][-1][0] = a:lnum + s:Count(beforeMark, "\n") + let snipPos[j][3][-1][1] = a:indent + (snipPos[j][3][-1][0] > a:lnum + \ ? len(matchstr(beforeMark, '.*\n\zs.*')) + \ : a:col + len(beforeMark)) + let withoutOthers = substitute(withoutOthers, '$'.i.'\ze\(\D\|$\)', '', '') + endw + endif + let i += 1 + endw + return [snipPos, i - 1] +endf + +fun snipMate#jumpTabStop(backwards) + let leftPlaceholder = exists('s:origWordLen') + \ && s:origWordLen != g:snipPos[s:curPos][2] + if leftPlaceholder && exists('s:oldEndCol') + let startPlaceholder = s:oldEndCol + 1 + endif + + if exists('s:update') + call s:UpdatePlaceholderTabStops() + else + call s:UpdateTabStops() + endif + + " Don't reselect placeholder if it has been modified + if leftPlaceholder && g:snipPos[s:curPos][2] != -1 + if exists('startPlaceholder') + let g:snipPos[s:curPos][1] = startPlaceholder + else + let g:snipPos[s:curPos][1] = col('.') + let g:snipPos[s:curPos][2] = 0 + endif + endif + + let s:curPos += a:backwards ? -1 : 1 + " Loop over the snippet when going backwards from the beginning + if s:curPos < 0 | let s:curPos = s:snipLen - 1 | endif + + if s:curPos == s:snipLen + let sMode = s:endCol == g:snipPos[s:curPos-1][1]+g:snipPos[s:curPos-1][2] + call s:RemoveSnippet() + return sMode ? "\<tab>" : TriggerSnippet() + endif + + call cursor(g:snipPos[s:curPos][0], g:snipPos[s:curPos][1]) + + let s:endLine = g:snipPos[s:curPos][0] + let s:endCol = g:snipPos[s:curPos][1] + let s:prevLen = [line('$'), col('$')] + + return g:snipPos[s:curPos][2] == -1 ? '' : s:SelectWord() +endf + +fun s:UpdatePlaceholderTabStops() + let changeLen = s:origWordLen - g:snipPos[s:curPos][2] + unl s:startCol s:origWordLen s:update + if !exists('s:oldVars') | return | endif + " Update tab stops in snippet if text has been added via "$#" + " (e.g., in "${1:foo}bar$1${2}"). + if changeLen != 0 + let curLine = line('.') + + for pos in g:snipPos + if pos == g:snipPos[s:curPos] | continue | endif + let changed = pos[0] == curLine && pos[1] > s:oldEndCol + let changedVars = 0 + let endPlaceholder = pos[2] - 1 + pos[1] + " Subtract changeLen from each tab stop that was after any of + " the current tab stop's placeholders. + for [lnum, col] in s:oldVars + if lnum > pos[0] | break | endif + if pos[0] == lnum + if pos[1] > col || (pos[2] == -1 && pos[1] == col) + let changed += 1 + elseif col < endPlaceholder + let changedVars += 1 + endif + endif + endfor + let pos[1] -= changeLen * changed + let pos[2] -= changeLen * changedVars " Parse variables within placeholders + " e.g., "${1:foo} ${2:$1bar}" + + if pos[2] == -1 | continue | endif + " Do the same to any placeholders in the other tab stops. + for nPos in pos[3] + let changed = nPos[0] == curLine && nPos[1] > s:oldEndCol + for [lnum, col] in s:oldVars + if lnum > nPos[0] | break | endif + if nPos[0] == lnum && nPos[1] > col + let changed += 1 + endif + endfor + let nPos[1] -= changeLen * changed + endfor + endfor + endif + unl s:endCol s:oldVars s:oldEndCol +endf + +fun s:UpdateTabStops() + let changeLine = s:endLine - g:snipPos[s:curPos][0] + let changeCol = s:endCol - g:snipPos[s:curPos][1] + if exists('s:origWordLen') + let changeCol -= s:origWordLen + unl s:origWordLen + endif + let lnum = g:snipPos[s:curPos][0] + let col = g:snipPos[s:curPos][1] + " Update the line number of all proceeding tab stops if <cr> has + " been inserted. + if changeLine != 0 + let changeLine -= 1 + for pos in g:snipPos + if pos[0] >= lnum + if pos[0] == lnum | let pos[1] += changeCol | endif + let pos[0] += changeLine + endif + if pos[2] == -1 | continue | endif + for nPos in pos[3] + if nPos[0] >= lnum + if nPos[0] == lnum | let nPos[1] += changeCol | endif + let nPos[0] += changeLine + endif + endfor + endfor + elseif changeCol != 0 + " Update the column of all proceeding tab stops if text has + " been inserted/deleted in the current line. + for pos in g:snipPos + if pos[1] >= col && pos[0] == lnum + let pos[1] += changeCol + endif + if pos[2] == -1 | continue | endif + for nPos in pos[3] + if nPos[0] > lnum | break | endif + if nPos[0] == lnum && nPos[1] >= col + let nPos[1] += changeCol + endif + endfor + endfor + endif +endf + +fun s:SelectWord() + let s:origWordLen = g:snipPos[s:curPos][2] + let s:oldWord = strpart(getline('.'), g:snipPos[s:curPos][1] - 1, + \ s:origWordLen) + let s:prevLen[1] -= s:origWordLen + if !empty(g:snipPos[s:curPos][3]) + let s:update = 1 + let s:endCol = -1 + let s:startCol = g:snipPos[s:curPos][1] - 1 + endif + if !s:origWordLen | return '' | endif + let l = col('.') != 1 ? 'l' : '' + if &sel == 'exclusive' + return "\<esc>".l.'v'.s:origWordLen."l\<c-g>" + endif + return s:origWordLen == 1 ? "\<esc>".l.'gh' + \ : "\<esc>".l.'v'.(s:origWordLen - 1)."l\<c-g>" +endf + +" This updates the snippet as you type when text needs to be inserted +" into multiple places (e.g. in "${1:default text}foo$1bar$1", +" "default text" would be highlighted, and if the user types something, +" UpdateChangedSnip() would be called so that the text after "foo" & "bar" +" are updated accordingly) +" +" It also automatically quits the snippet if the cursor is moved out of it +" while in insert mode. +fun s:UpdateChangedSnip(entering) + if exists('g:snipPos') && bufnr(0) != s:lastBuf + call s:RemoveSnippet() + elseif exists('s:update') " If modifying a placeholder + if !exists('s:oldVars') && s:curPos + 1 < s:snipLen + " Save the old snippet & word length before it's updated + " s:startCol must be saved too, in case text is added + " before the snippet (e.g. in "foo$1${2}bar${1:foo}"). + let s:oldEndCol = s:startCol + let s:oldVars = deepcopy(g:snipPos[s:curPos][3]) + endif + let col = col('.') - 1 + + if s:endCol != -1 + let changeLen = col('$') - s:prevLen[1] + let s:endCol += changeLen + else " When being updated the first time, after leaving select mode + if a:entering | return | endif + let s:endCol = col - 1 + endif + + " If the cursor moves outside the snippet, quit it + if line('.') != g:snipPos[s:curPos][0] || col < s:startCol || + \ col - 1 > s:endCol + unl! s:startCol s:origWordLen s:oldVars s:update + return s:RemoveSnippet() + endif + + call s:UpdateVars() + let s:prevLen[1] = col('$') + elseif exists('g:snipPos') + if !a:entering && g:snipPos[s:curPos][2] != -1 + let g:snipPos[s:curPos][2] = -2 + endif + + let col = col('.') + let lnum = line('.') + let changeLine = line('$') - s:prevLen[0] + + if lnum == s:endLine + let s:endCol += col('$') - s:prevLen[1] + let s:prevLen = [line('$'), col('$')] + endif + if changeLine != 0 + let s:endLine += changeLine + let s:endCol = col + endif + + " Delete snippet if cursor moves out of it in insert mode + if (lnum == s:endLine && (col > s:endCol || col < g:snipPos[s:curPos][1])) + \ || lnum > s:endLine || lnum < g:snipPos[s:curPos][0] + call s:RemoveSnippet() + endif + endif +endf + +" This updates the variables in a snippet when a placeholder has been edited. +" (e.g., each "$1" in "${1:foo} $1bar $1bar") +fun s:UpdateVars() + let newWordLen = s:endCol - s:startCol + 1 + let newWord = strpart(getline('.'), s:startCol, newWordLen) + if newWord == s:oldWord || empty(g:snipPos[s:curPos][3]) + return + endif + + let changeLen = g:snipPos[s:curPos][2] - newWordLen + let curLine = line('.') + let startCol = col('.') + let oldStartSnip = s:startCol + let updateTabStops = changeLen != 0 + let i = 0 + + for [lnum, col] in g:snipPos[s:curPos][3] + if updateTabStops + let start = s:startCol + if lnum == curLine && col <= start + let s:startCol -= changeLen + let s:endCol -= changeLen + endif + for nPos in g:snipPos[s:curPos][3][(i):] + " This list is in ascending order, so quit if we've gone too far. + if nPos[0] > lnum | break | endif + if nPos[0] == lnum && nPos[1] > col + let nPos[1] -= changeLen + endif + endfor + if lnum == curLine && col > start + let col -= changeLen + let g:snipPos[s:curPos][3][i][1] = col + endif + let i += 1 + endif + + " "Very nomagic" is used here to allow special characters. + call setline(lnum, substitute(getline(lnum), '\%'.col.'c\V'. + \ escape(s:oldWord, '\'), escape(newWord, '\&'), '')) + endfor + if oldStartSnip != s:startCol + call cursor(0, startCol + s:startCol - oldStartSnip) + endif + + let s:oldWord = newWord + let g:snipPos[s:curPos][2] = newWordLen +endf +" vim:noet:sw=4:ts=4:ft=vim diff --git a/vim/bundle/snipmate/doc/snipMate.txt b/vim/bundle/snipmate/doc/snipMate.txt @@ -0,0 +1,322 @@ +*snipMate.txt* Plugin for using TextMate-style snippets in Vim. + +snipMate *snippet* *snippets* *snipMate* +Last Change: December 27, 2009 + +|snipMate-description| Description +|snipMate-syntax| Snippet syntax +|snipMate-usage| Usage +|snipMate-settings| Settings +|snipMate-features| Features +|snipMate-disadvantages| Disadvantages to TextMate +|snipMate-contact| Contact +|snipMate-license| License + +For Vim version 7.0 or later. +This plugin only works if 'compatible' is not set. +{Vi does not have any of these features.} + +============================================================================== +DESCRIPTION *snipMate-description* + +snipMate.vim implements some of TextMate's snippets features in Vim. A +snippet is a piece of often-typed text that you can insert into your +document using a trigger word followed by a <tab>. + +For instance, in a C file using the default installation of snipMate.vim, if +you type "for<tab>" in insert mode, it will expand a typical for loop in C: > + + for (i = 0; i < count; i++) { + + } + + +To go to the next item in the loop, simply <tab> over to it; if there is +repeated code, such as the "i" variable in this example, you can simply +start typing once it's highlighted and all the matches specified in the +snippet will be updated. To go in reverse, use <shift-tab>. + +============================================================================== +SYNTAX *snippet-syntax* + +Snippets can be defined in two ways. They can be in their own file, named +after their trigger in 'snippets/<filetype>/<trigger>.snippet', or they can be +defined together in a 'snippets/<filetype>.snippets' file. Note that dotted +'filetype' syntax is supported -- e.g., you can use > + + :set ft=html.eruby + +to activate snippets for both HTML and eRuby for the current file. + +The syntax for snippets in *.snippets files is the following: > + + snippet trigger + expanded text + more expanded text + +Note that the first hard tab after the snippet trigger is required, and not +expanded in the actual snippet. The syntax for *.snippet files is the same, +only without the trigger declaration and starting indentation. + +Also note that snippets must be defined using hard tabs. They can be expanded +to spaces later if desired (see |snipMate-indenting|). + +"#" is used as a line-comment character in *.snippets files; however, they can +only be used outside of a snippet declaration. E.g.: > + + # this is a correct comment + snippet trigger + expanded text + snippet another_trigger + # this isn't a comment! + expanded text +< +This should hopefully be obvious with the included syntax highlighting. + + *snipMate-${#}* +Tab stops ~ + +By default, the cursor is placed at the end of a snippet. To specify where the +cursor is to be placed next, use "${#}", where the # is the number of the tab +stop. E.g., to place the cursor first on the id of a <div> tag, and then allow +the user to press <tab> to go to the middle of it: + > + snippet div + <div id="${1}"> + ${2} + </div> +< + *snipMate-placeholders* *snipMate-${#:}* *snipMate-$#* +Placeholders ~ + +Placeholder text can be supplied using "${#:text}", where # is the number of +the tab stop. This text then can be copied throughout the snippet using "$#", +given # is the same number as used before. So, to make a C for loop: > + + snippet for + for (${2:i}; $2 < ${1:count}; $1++) { + ${4} + } + +This will cause "count" to first be selected and change if the user starts +typing. When <tab> is pressed, the "i" in ${2}'s position will be selected; +all $2 variables will default to "i" and automatically be updated if the user +starts typing. +NOTE: "$#" syntax is used only for variables, not for tab stops as in TextMate. + +Variables within variables are also possible. For instance: > + + snippet opt + <option value="${1:option}">${2:$1}</option> + +Will, as usual, cause "option" to first be selected and update all the $1 +variables if the user starts typing. Since one of these variables is inside of +${2}, this text will then be used as a placeholder for the next tab stop, +allowing the user to change it if he wishes. + +To copy a value throughout a snippet without supplying default text, simply +use the "${#:}" construct without the text; e.g.: > + + snippet foo + ${1:}bar$1 +< *snipMate-commands* +Interpolated Vim Script ~ + +Snippets can also contain Vim script commands that are executed (via |eval()|) +when the snippet is inserted. Commands are given inside backticks (`...`); for +TextMates's functionality, use the |system()| function. E.g.: > + + snippet date + `system("date +%Y-%m-%d")` + +will insert the current date, assuming you are on a Unix system. Note that you +can also (and should) use |strftime()| for this example. + +Filename([{expr}] [, {defaultText}]) *snipMate-filename* *Filename()* + +Since the current filename is used often in snippets, a default function +has been defined for it in snipMate.vim, appropriately called Filename(). + +With no arguments, the default filename without an extension is returned; +the first argument specifies what to place before or after the filename, +and the second argument supplies the default text to be used if the file +has not been named. "$1" in the first argument is replaced with the filename; +if you only want the filename to be returned, the first argument can be left +blank. Examples: > + + snippet filename + `Filename()` + snippet filename_with_default + `Filename('', 'name')` + snippet filename_foo + `filename('$1_foo')` + +The first example returns the filename if it the file has been named, and an +empty string if it hasn't. The second returns the filename if it's been named, +and "name" if it hasn't. The third returns the filename followed by "_foo" if +it has been named, and an empty string if it hasn't. + + *multi_snip* +To specify that a snippet can have multiple matches in a *.snippets file, use +this syntax: > + + snippet trigger A description of snippet #1 + expand this text + snippet trigger A description of snippet #2 + expand THIS text! + +In this example, when "trigger<tab>" is typed, a numbered menu containing all +of the descriptions of the "trigger" will be shown; when the user presses the +corresponding number, that snippet will then be expanded. + +To create a snippet with multiple matches using *.snippet files, +simply place all the snippets in a subdirectory with the trigger name: +'snippets/<filetype>/<trigger>/<name>.snippet'. + +============================================================================== +USAGE *snipMate-usage* + + *'snippets'* *g:snippets_dir* +Snippets are by default looked for any 'snippets' directory in your +'runtimepath'. Typically, it is located at '~/.vim/snippets/' on *nix or +'$HOME\vimfiles\snippets\' on Windows. To change that location or add another +one, change the g:snippets_dir variable in your |.vimrc| to your preferred +directory, or use the |ExtractSnips()|function. This will be used by the +|globpath()| function, and so accepts the same syntax as it (e.g., +comma-separated paths). + +ExtractSnipsFile({directory}, {filetype}) *ExtractSnipsFile()* *.snippets* + +ExtractSnipsFile() extracts the specified *.snippets file for the given +filetype. A .snippets file contains multiple snippet declarations for the +filetype. It is further explained above, in |snippet-syntax|. + +ExtractSnips({directory}, {filetype}) *ExtractSnips()* *.snippet* + +ExtractSnips() extracts *.snippet files from the specified directory and +defines them as snippets for the given filetype. The directory tree should +look like this: 'snippets/<filetype>/<trigger>.snippet'. If the snippet has +multiple matches, it should look like this: +'snippets/<filetype>/<trigger>/<name>.snippet' (see |multi_snip|). + +ResetAllSnippets() *ResetAllSnippets()* +ResetAllSnippets() removes all snippets from memory. This is useful to put at +the top of a snippet setup file for if you would like to |:source| it multiple +times. + +ResetSnippets({filetype}) *ResetSnippets()* +ResetSnippets() removes all snippets from memory for the given filetype. + +ReloadAllSnippets() *ReloadAllSnippets()* +ReloadAllSnippets() reloads all snippets for all filetypes. This is useful for +testing and debugging. + +ReloadSnippets({filetype}) *ReloadSnippets()* +ReloadSnippets() reloads all snippets for the given filetype. + + *list-snippets* *i_CTRL-R_<Tab>* +If you would like to see what snippets are available, simply type <c-r><tab> +in the current buffer to show a list via |popupmenu-completion|. + +============================================================================== +SETTINGS *snipMate-settings* *g:snips_author* + +The g:snips_author string (similar to $TM_FULLNAME in TextMate) should be set +to your name; it can then be used in snippets to automatically add it. E.g.: > + + let g:snips_author = 'Hubert Farnsworth' + snippet name + `g:snips_author` +< + *snipMate-expandtab* *snipMate-indenting* +If you would like your snippets to be expanded using spaces instead of tabs, +just enable 'expandtab' and set 'softtabstop' to your preferred amount of +spaces. If 'softtabstop' is not set, 'shiftwidth' is used instead. + + *snipMate-remap* +snipMate does not come with a setting to customize the trigger key, but you +can remap it easily in the two lines it's defined in the 'after' directory +under 'plugin/snipMate.vim'. For instance, to change the trigger key +to CTRL-J, just change this: > + + ino <tab> <c-r>=TriggerSnippet()<cr> + snor <tab> <esc>i<right><c-r>=TriggerSnippet()<cr> + +to this: > + ino <c-j> <c-r>=TriggerSnippet()<cr> + snor <c-j> <esc>i<right><c-r>=TriggerSnippet()<cr> + +============================================================================== +FEATURES *snipMate-features* + +snipMate.vim has the following features among others: + - The syntax of snippets is very similar to TextMate's, allowing + easy conversion. + - The position of the snippet is kept transparently (i.e. it does not use + markers/placeholders written to the buffer), which allows you to escape + out of an incomplete snippet, something particularly useful in Vim. + - Variables in snippets are updated as-you-type. + - Snippets can have multiple matches. + - Snippets can be out of order. For instance, in a do...while loop, the + condition can be added before the code. + - [New] File-based snippets are supported. + - [New] Triggers after non-word delimiters are expanded, e.g. "foo" + in "bar.foo". + - [New] <shift-tab> can now be used to jump tab stops in reverse order. + +============================================================================== +DISADVANTAGES *snipMate-disadvantages* + +snipMate.vim currently has the following disadvantages to TextMate's snippets: + - There is no $0; the order of tab stops must be explicitly stated. + - Placeholders within placeholders are not possible. E.g.: > + + '<div${1: id="${2:some_id}}">${3}</div>' +< + In TextMate this would first highlight ' id="some_id"', and if + you hit delete it would automatically skip ${2} and go to ${3} + on the next <tab>, but if you didn't delete it it would highlight + "some_id" first. You cannot do this in snipMate.vim. + - Regex cannot be performed on variables, such as "${1/.*/\U&}" + - Placeholders cannot span multiple lines. + - Activating snippets in different scopes of the same file is + not possible. + +Perhaps some of these features will be added in a later release. + +============================================================================== +CONTACT *snipMate-contact* *snipMate-author* + +To contact the author (Michael Sanders), please email: + msanders42+snipmate <at> gmail <dot> com + +I greatly appreciate any suggestions or improvements offered for the script. + +============================================================================== +LICENSE *snipMate-license* + +snipMate is released under the MIT license: + +Copyright 2009-2010 Michael Sanders. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The software is provided "as is", without warranty of any kind, express or +implied, including but not limited to the warranties of merchantability, +fitness for a particular purpose and noninfringement. In no event shall the +authors or copyright holders be liable for any claim, damages or other +liability, whether in an action of contract, tort or otherwise, arising from, +out of or in connection with the software or the use or other dealings in the +software. + +============================================================================== + +vim:tw=78:ts=8:ft=help:norl: diff --git a/vim/bundle/snipmate/ftplugin/html_snip_helper.vim b/vim/bundle/snipmate/ftplugin/html_snip_helper.vim @@ -0,0 +1,10 @@ +" Helper function for (x)html snippets +if exists('s:did_snip_helper') || &cp || !exists('loaded_snips') + finish +endif +let s:did_snip_helper = 1 + +" Automatically closes tag if in xhtml +fun! Close() + return stridx(&ft, 'xhtml') == -1 ? '' : ' /' +endf diff --git a/vim/bundle/snipmate/plugin-info.txt b/vim/bundle/snipmate/plugin-info.txt @@ -0,0 +1,8 @@ +{ + "name" : "snipmate", + "version" : "dev", + "author" : "Michael Sanders <msanders42@gmail.com>", + "repository" : {"type": "git", "url": "git://github.com/msanders/snipmate.vim.git"}, + "dependencies" : {}, + "description" : "snipMate.vim aims to be a concise vim script that implements some of TextMate's snippets features in Vim." +} diff --git a/vim/bundle/snipmate/plugin/snipMate.vim b/vim/bundle/snipmate/plugin/snipMate.vim @@ -0,0 +1,271 @@ +" File: snipMate.vim +" Author: Michael Sanders +" Version: 0.84 +" Description: snipMate.vim implements some of TextMate's snippets features in +" Vim. A snippet is a piece of often-typed text that you can +" insert into your document using a trigger word followed by a "<tab>". +" +" For more help see snipMate.txt; you can do this by using: +" :helptags ~/.vim/doc +" :h snipMate.txt + +if exists('loaded_snips') || &cp || version < 700 + finish +endif +let loaded_snips = 1 +if !exists('snips_author') | let snips_author = 'Me' | endif + +au BufRead,BufNewFile *.snippets\= set ft=snippet +au FileType snippet setl noet fdm=indent + +let s:snippets = {} | let s:multi_snips = {} + +if !exists('snippets_dir') + let snippets_dir = substitute(globpath(&rtp, 'snippets/'), "\n", ',', 'g') +endif + +fun! MakeSnip(scope, trigger, content, ...) + let multisnip = a:0 && a:1 != '' + let var = multisnip ? 's:multi_snips' : 's:snippets' + if !has_key({var}, a:scope) | let {var}[a:scope] = {} | endif + if !has_key({var}[a:scope], a:trigger) + let {var}[a:scope][a:trigger] = multisnip ? [[a:1, a:content]] : a:content + elseif multisnip | let {var}[a:scope][a:trigger] += [[a:1, a:content]] + else + echom 'Warning in snipMate.vim: Snippet '.a:trigger.' is already defined.' + \ .' See :h multi_snip for help on snippets with multiple matches.' + endif +endf + +fun! ExtractSnips(dir, ft) + for path in split(globpath(a:dir, '*'), "\n") + if isdirectory(path) + let pathname = fnamemodify(path, ':t') + for snipFile in split(globpath(path, '*.snippet'), "\n") + call s:ProcessFile(snipFile, a:ft, pathname) + endfor + elseif fnamemodify(path, ':e') == 'snippet' + call s:ProcessFile(path, a:ft) + endif + endfor +endf + +" Processes a single-snippet file; optionally add the name of the parent +" directory for a snippet with multiple matches. +fun s:ProcessFile(file, ft, ...) + let keyword = fnamemodify(a:file, ':t:r') + if keyword == '' | return | endif + try + let text = join(readfile(a:file), "\n") + catch /E484/ + echom "Error in snipMate.vim: couldn't read file: ".a:file + endtry + return a:0 ? MakeSnip(a:ft, a:1, text, keyword) + \ : MakeSnip(a:ft, keyword, text) +endf + +fun! ExtractSnipsFile(file, ft) + if !filereadable(a:file) | return | endif + let text = readfile(a:file) + let inSnip = 0 + for line in text + ["\n"] + if inSnip && (line[0] == "\t" || line == '') + let content .= strpart(line, 1)."\n" + continue + elseif inSnip + call MakeSnip(a:ft, trigger, content[:-2], name) + let inSnip = 0 + endif + + if line[:6] == 'snippet' + let inSnip = 1 + let trigger = strpart(line, 8) + let name = '' + let space = stridx(trigger, ' ') + 1 + if space " Process multi snip + let name = strpart(trigger, space) + let trigger = strpart(trigger, 0, space - 1) + endif + let content = '' + endif + endfor +endf + +" Reset snippets for filetype. +fun! ResetSnippets(ft) + let ft = a:ft == '' ? '_' : a:ft + for dict in [s:snippets, s:multi_snips, g:did_ft] + if has_key(dict, ft) + unlet dict[ft] + endif + endfor +endf + +" Reset snippets for all filetypes. +fun! ResetAllSnippets() + let s:snippets = {} | let s:multi_snips = {} | let g:did_ft = {} +endf + +" Reload snippets for filetype. +fun! ReloadSnippets(ft) + let ft = a:ft == '' ? '_' : a:ft + call ResetSnippets(ft) + call GetSnippets(g:snippets_dir, ft) +endf + +" Reload snippets for all filetypes. +fun! ReloadAllSnippets() + for ft in keys(g:did_ft) + call ReloadSnippets(ft) + endfor +endf + +let g:did_ft = {} +fun! GetSnippets(dir, filetypes) + for ft in split(a:filetypes, '\.') + if has_key(g:did_ft, ft) | continue | endif + call s:DefineSnips(a:dir, ft, ft) + if ft == 'objc' || ft == 'cpp' || ft == 'cs' + call s:DefineSnips(a:dir, 'c', ft) + elseif ft == 'xhtml' + call s:DefineSnips(a:dir, 'html', 'xhtml') + endif + let g:did_ft[ft] = 1 + endfor +endf + +" Define "aliasft" snippets for the filetype "realft". +fun s:DefineSnips(dir, aliasft, realft) + for path in split(globpath(a:dir, a:aliasft.'/')."\n". + \ globpath(a:dir, a:aliasft.'-*/'), "\n") + call ExtractSnips(path, a:realft) + endfor + for path in split(globpath(a:dir, a:aliasft.'.snippets')."\n". + \ globpath(a:dir, a:aliasft.'-*.snippets'), "\n") + call ExtractSnipsFile(path, a:realft) + endfor +endf + +fun! TriggerSnippet() + if exists('g:SuperTabMappingForward') + if g:SuperTabMappingForward == "<tab>" + let SuperTabKey = "\<c-n>" + elseif g:SuperTabMappingBackward == "<tab>" + let SuperTabKey = "\<c-p>" + endif + endif + + if pumvisible() " Update snippet if completion is used, or deal with supertab + if exists('SuperTabKey') + call feedkeys(SuperTabKey) | return '' + endif + call feedkeys("\<esc>a", 'n') " Close completion menu + call feedkeys("\<tab>") | return '' + endif + + if exists('g:snipPos') | return snipMate#jumpTabStop(0) | endif + + let word = matchstr(getline('.'), '\S\+\%'.col('.').'c') + for scope in [bufnr('%')] + split(&ft, '\.') + ['_'] + let [trigger, snippet] = s:GetSnippet(word, scope) + " If word is a trigger for a snippet, delete the trigger & expand + " the snippet. + if snippet != '' + let col = col('.') - len(trigger) + sil exe 's/\V'.escape(trigger, '/\.').'\%#//' + return snipMate#expandSnip(snippet, col) + endif + endfor + + if exists('SuperTabKey') + call feedkeys(SuperTabKey) + return '' + endif + return "\<tab>" +endf + +fun! BackwardsSnippet() + if exists('g:snipPos') | return snipMate#jumpTabStop(1) | endif + + if exists('g:SuperTabMappingForward') + if g:SuperTabMappingBackward == "<s-tab>" + let SuperTabKey = "\<c-p>" + elseif g:SuperTabMappingForward == "<s-tab>" + let SuperTabKey = "\<c-n>" + endif + endif + if exists('SuperTabKey') + call feedkeys(SuperTabKey) + return '' + endif + return "\<s-tab>" +endf + +" Check if word under cursor is snippet trigger; if it isn't, try checking if +" the text after non-word characters is (e.g. check for "foo" in "bar.foo") +fun s:GetSnippet(word, scope) + let word = a:word | let snippet = '' + while snippet == '' + if exists('s:snippets["'.a:scope.'"]["'.escape(word, '\"').'"]') + let snippet = s:snippets[a:scope][word] + elseif exists('s:multi_snips["'.a:scope.'"]["'.escape(word, '\"').'"]') + let snippet = s:ChooseSnippet(a:scope, word) + if snippet == '' | break | endif + else + if match(word, '\W') == -1 | break | endif + let word = substitute(word, '.\{-}\W', '', '') + endif + endw + if word == '' && a:word != '.' && stridx(a:word, '.') != -1 + let [word, snippet] = s:GetSnippet('.', a:scope) + endif + return [word, snippet] +endf + +fun s:ChooseSnippet(scope, trigger) + let snippet = [] + let i = 1 + for snip in s:multi_snips[a:scope][a:trigger] + let snippet += [i.'. '.snip[0]] + let i += 1 + endfor + if i == 2 | return s:multi_snips[a:scope][a:trigger][0][1] | endif + let num = inputlist(snippet) - 1 + return num == -1 ? '' : s:multi_snips[a:scope][a:trigger][num][1] +endf + +fun! ShowAvailableSnips() + let line = getline('.') + let col = col('.') + let word = matchstr(getline('.'), '\S\+\%'.col.'c') + let words = [word] + if stridx(word, '.') + let words += split(word, '\.', 1) + endif + let matchlen = 0 + let matches = [] + for scope in [bufnr('%')] + split(&ft, '\.') + ['_'] + let triggers = has_key(s:snippets, scope) ? keys(s:snippets[scope]) : [] + if has_key(s:multi_snips, scope) + let triggers += keys(s:multi_snips[scope]) + endif + for trigger in triggers + for word in words + if word == '' + let matches += [trigger] " Show all matches if word is empty + elseif trigger =~ '^'.word + let matches += [trigger] + let len = len(word) + if len > matchlen | let matchlen = len | endif + endif + endfor + endfor + endfor + + " This is to avoid a bug with Vim when using complete(col - matchlen, matches) + " (Issue#46 on the Google Code snipMate issue tracker). + call setline(line('.'), substitute(line, repeat('.', matchlen).'\%'.col.'c', '', '')) + call complete(col, matches) + return '' +endf +" vim:noet:sw=4:ts=4:ft=vim diff --git a/vim/bundle/snipmate/snippets/_.snippets b/vim/bundle/snipmate/snippets/_.snippets @@ -0,0 +1,9 @@ +# Global snippets + +# (c) holds no legal value ;) +snippet c) + Copyright `&enc[:2] == "utf" ? "©" : "(c)"` `strftime("%Y")` ${1:`g:snips_author`}. All Rights Reserved.${2} +snippet date + `strftime("%Y-%m-%d")` +snippet ddate + `strftime("%B %d, %Y")` diff --git a/vim/bundle/snipmate/snippets/autoit.snippets b/vim/bundle/snipmate/snippets/autoit.snippets @@ -0,0 +1,66 @@ +snippet if + If ${1:condition} Then + ${2:; True code} + EndIf +snippet el + Else + ${1} +snippet elif + ElseIf ${1:condition} Then + ${2:; True code} +# If/Else block +snippet ifel + If ${1:condition} Then + ${2:; True code} + Else + ${3:; Else code} + EndIf +# If/ElseIf/Else block +snippet ifelif + If ${1:condition 1} Then + ${2:; True code} + ElseIf ${3:condition 2} Then + ${4:; True code} + Else + ${5:; Else code} + EndIf +# Switch block +snippet switch + Switch (${1:condition}) + Case {$2:case1}: + {$3:; Case 1 code} + Case Else: + {$4:; Else code} + EndSwitch +# Select block +snippet select + Select (${1:condition}) + Case {$2:case1}: + {$3:; Case 1 code} + Case Else: + {$4:; Else code} + EndSelect +# While loop +snippet while + While (${1:condition}) + ${2:; code...} + WEnd +# For loop +snippet for + For ${1:n} = ${3:1} to ${2:count} + ${4:; code...} + Next +# New Function +snippet func + Func ${1:fname}(${2:`indent('.') ? 'self' : ''`}): + ${4:Return} + EndFunc +# Message box +snippet msg + MsgBox(${3:MsgType}, ${1:"Title"}, ${2:"Message Text"}) +# Debug Message +snippet debug + MsgBox(0, "Debug", ${1:"Debug Message"}) +# Show Variable Debug Message +snippet showvar + MsgBox(0, "${1:VarName}", $1) diff --git a/vim/bundle/snipmate/snippets/c.snippets b/vim/bundle/snipmate/snippets/c.snippets @@ -0,0 +1,113 @@ +# main() +snippet main + int main(int argc, const char *argv[]) + { + ${1} + return 0; + } +snippet mainn + int main(void) + { + ${1} + return 0; + } +# #include <...> +snippet inc + #include <${1:stdio}.h>${2} +# #include "..." +snippet Inc + #include "${1:`Filename("$1.h")`}"${2} +# #ifndef ... #define ... #endif +snippet Def + #ifndef $1 + #define ${1:SYMBOL} ${2:value} + #endif${3} +snippet def + #define +snippet ifdef + #ifdef ${1:FOO} + ${2:#define } + #endif +snippet #if + #if ${1:FOO} + ${2} + #endif +# Header Include-Guard +snippet once + #ifndef ${1:`toupper(Filename('$1_H', 'UNTITLED_H'))`} + + #define $1 + + ${2} + + #endif /* end of include guard: $1 */ +# If Condition +snippet if + if (${1:/* condition */}) { + ${2:/* code */} + } +snippet el + else { + ${1} + } +# Ternary conditional +snippet t + ${1:/* condition */} ? ${2:a} : ${3:b} +# Do While Loop +snippet do + do { + ${2:/* code */} + } while (${1:/* condition */}); +# While Loop +snippet wh + while (${1:/* condition */}) { + ${2:/* code */} + } +# For Loop +snippet for + for (${2:i} = 0; $2 < ${1:count}; $2${3:++}) { + ${4:/* code */} + } +# Custom For Loop +snippet forr + for (${1:i} = ${2:0}; ${3:$1 < 10}; $1${4:++}) { + ${5:/* code */} + } +# Function +snippet fun + ${1:void} ${2:function_name}(${3}) + { + ${4:/* code */} + } +# Function Declaration +snippet fund + ${1:void} ${2:function_name}(${3});${4} +# Typedef +snippet td + typedef ${1:int} ${2:MyCustomType};${3} +# Struct +snippet st + struct ${1:`Filename('$1_t', 'name')`} { + ${2:/* data */} + }${3: /* optional variable list */};${4} +# Typedef struct +snippet tds + typedef struct ${2:_$1 }{ + ${3:/* data */} + } ${1:`Filename('$1_t', 'name')`}; +# Typdef enum +snippet tde + typedef enum { + ${1:/* data */} + } ${2:foo}; +# printf +# unfortunately version this isn't as nice as TextMates's, given the lack of a +# dynamic `...` +snippet pr + printf("${1:%s}\n"${2});${3} +# fprintf (again, this isn't as nice as TextMate's version, but it works) +snippet fpr + fprintf(${1:stderr}, "${2:%s}\n"${3});${4} +# This is kind of convenient +snippet . + [${1}]${2} diff --git a/vim/bundle/snipmate/snippets/cpp.snippets b/vim/bundle/snipmate/snippets/cpp.snippets @@ -0,0 +1,34 @@ +# Read File Into Vector +snippet readfile + std::vector<char> v; + if (FILE *${2:fp} = fopen(${1:"filename"}, "r")) { + char buf[1024]; + while (size_t len = fread(buf, 1, sizeof(buf), $2)) + v.insert(v.end(), buf, buf + len); + fclose($2); + }${3} +# std::map +snippet map + std::map<${1:key}, ${2:value}> map${3}; +# std::vector +snippet vector + std::vector<${1:char}> v${2}; +# Namespace +snippet ns + namespace ${1:`Filename('', 'my')`} { + ${2} + } /* $1 */ +# Class +snippet cl + class ${1:`Filename('$1_t', 'name')`} { + public: + $1 (${2:arguments}); + virtual ~$1 (); + + private: + ${3:/* data */} + }; +snippet fori + for (int ${2:i} = 0; $2 < ${1:count}; $2${3:++}) { + ${4:/* code */} + } diff --git a/vim/bundle/snipmate/snippets/erlang.snippets b/vim/bundle/snipmate/snippets/erlang.snippets @@ -0,0 +1,39 @@ +# module and export all +snippet mod + -module(${1:`Filename('', 'my')`}). + + -compile([export_all]). + + start() -> + ${2} + + stop() -> + ok. +# define directive +snippet def + -define(${1:macro}, ${2:body}).${3} +# export directive +snippet exp + -export([${1:function}/${2:arity}]). +# include directive +snippet inc + -include("${1:file}").${2} +# behavior directive +snippet beh + -behaviour(${1:behaviour}).${2} +# if expression +snippet if + if + ${1:guard} -> + ${2:body} + end +# case expression +snippet case + case ${1:expression} of + ${2:pattern} -> + ${3:body}; + end +# record directive +snippet rec + -record(${1:record}, { + ${2:field}=${3:value}}).${4} diff --git a/vim/bundle/snipmate/snippets/html.snippets b/vim/bundle/snipmate/snippets/html.snippets @@ -0,0 +1,190 @@ +# Some useful Unicode entities +# Non-Breaking Space +snippet nbs + &nbsp; +# ← +snippet left + &#x2190; +# → +snippet right + &#x2192; +# ↑ +snippet up + &#x2191; +# ↓ +snippet down + &#x2193; +# ↩ +snippet return + &#x21A9; +# ⇤ +snippet backtab + &#x21E4; +# ⇥ +snippet tab + &#x21E5; +# ⇧ +snippet shift + &#x21E7; +# ⌃ +snippet control + &#x2303; +# ⌅ +snippet enter + &#x2305; +# ⌘ +snippet command + &#x2318; +# ⌥ +snippet option + &#x2325; +# ⌦ +snippet delete + &#x2326; +# ⌫ +snippet backspace + &#x232B; +# ⎋ +snippet escape + &#x238B; +# Generic Doctype +snippet doctype HTML 4.01 Strict + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +snippet doctype HTML 4.01 Transitional + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> +snippet doctype HTML 5 + <!DOCTYPE HTML> +snippet doctype XHTML 1.0 Frameset + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +snippet doctype XHTML 1.0 Strict + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +snippet doctype XHTML 1.0 Transitional + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +snippet doctype XHTML 1.1 + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +# HTML Doctype 4.01 Strict +snippet docts + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +# HTML Doctype 4.01 Transitional +snippet doct + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> +# HTML Doctype 5 +snippet doct5 + <!DOCTYPE HTML> +# XHTML Doctype 1.0 Frameset +snippet docxf + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> +# XHTML Doctype 1.0 Strict +snippet docxs + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +# XHTML Doctype 1.0 Transitional +snippet docxt + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +# XHTML Doctype 1.1 +snippet docx + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +snippet html + <html> + ${1} + </html> +snippet xhtml + <html xmlns="http://www.w3.org/1999/xhtml"> + ${1} + </html> +snippet body + <body> + ${1} + </body> +snippet head + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"`Close()`> + + <title>${1:`substitute(Filename('', 'Page Title'), '^.', '\u&', '')`}</title> + ${2} + </head> +snippet title + <title>${1:`substitute(Filename('', 'Page Title'), '^.', '\u&', '')`}</title>${2} +snippet script + <script type="text/javascript" charset="utf-8"> + ${1} + </script>${2} +snippet scriptsrc + <script src="${1}.js" type="text/javascript" charset="utf-8"></script>${2} +snippet style + <style type="text/css" media="${1:screen}"> + ${2} + </style>${3} +snippet base + <base href="${1}" target="${2}"`Close()`> +snippet r + <br`Close()[1:]`> +snippet div + <div id="${1:name}"> + ${2} + </div> +# Embed QT Movie +snippet movie + <object width="$2" height="$3" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" + codebase="http://www.apple.com/qtactivex/qtplugin.cab"> + <param name="src" value="$1"`Close()`> + <param name="controller" value="$4"`Close()`> + <param name="autoplay" value="$5"`Close()`> + <embed src="${1:movie.mov}" + width="${2:320}" height="${3:240}" + controller="${4:true}" autoplay="${5:true}" + scale="tofit" cache="true" + pluginspage="http://www.apple.com/quicktime/download/" + `Close()[1:]`> + </object>${6} +snippet fieldset + <fieldset id="$1"> + <legend>${1:name}</legend> + + ${3} + </fieldset> +snippet form + <form action="${1:`Filename('$1_submit')`}" method="${2:get}" accept-charset="utf-8"> + ${3} + + + <p><input type="submit" value="Continue &rarr;"`Close()`></p> + </form> +snippet h1 + <h1 id="${1:heading}">${2:$1}</h1> +snippet input + <input type="${1:text/submit/hidden/button}" name="${2:some_name}" value="${3}"`Close()`>${4} +snippet label + <label for="${2:$1}">${1:name}</label><input type="${3:text/submit/hidden/button}" name="${4:$2}" value="${5}" id="${6:$2}"`Close()`>${7} +snippet link + <link rel="${1:stylesheet}" href="${2:/css/master.css}" type="text/css" media="${3:screen}" charset="utf-8"`Close()`>${4} +snippet mailto + <a href="mailto:${1:joe@example.com}?subject=${2:feedback}">${3:email me}</a> +snippet meta + <meta name="${1:name}" content="${2:content}"`Close()`>${3} +snippet opt + <option value="${1:option}">${2:$1}</option>${3} +snippet optt + <option>${1:option}</option>${2} +snippet select + <select name="${1:some_name}" id="${2:$1}"> + <option value="${3:option}">${4:$3}</option> + </select>${5} +snippet table + <table border="${1:0}"> + <tr><th>${2:Header}</th></tr> + <tr><th>${3:Data}</th></tr> + </table>${4} +snippet textarea + <textarea name="${1:Name}" rows="${2:8}" cols="${3:40}">${4}</textarea>${5} diff --git a/vim/bundle/snipmate/snippets/java.snippets b/vim/bundle/snipmate/snippets/java.snippets @@ -0,0 +1,95 @@ +snippet main + public static void main (String [] args) + { + ${1:/* code */} + } +snippet pu + public +snippet po + protected +snippet pr + private +snippet st + static +snippet fi + final +snippet ab + abstract +snippet re + return +snippet br + break; +snippet de + default: + ${1} +snippet ca + catch(${1:Exception} ${2:e}) ${3} +snippet th + throw +snippet sy + synchronized +snippet im + import +snippet imp + implements +snippet ext + extends +snippet j.u + java.util +snippet j.i + java.io. +snippet j.b + java.beans. +snippet j.n + java.net. +snippet j.m + java.math. +snippet if + if (${1}) ${2} +snippet el + else +snippet elif + else if (${1}) ${2} +snippet wh + while (${1}) ${2} +snippet for + for (${1}; ${2}; ${3}) ${4} +snippet fore + for (${1} : ${2}) ${3} +snippet sw + switch (${1}) ${2} +snippet cs + case ${1}: + ${2} + ${3} +snippet tc + public class ${1:`Filename()`} extends ${2:TestCase} +snippet t + public void test${1:Name}() throws Exception ${2} +snippet cl + class ${1:`Filename("", "untitled")`} ${2} +snippet in + interface ${1:`Filename("", "untitled")`} ${2:extends Parent}${3} +snippet m + ${1:void} ${2:method}(${3}) ${4:throws }${5} +snippet v + ${1:String} ${2:var}${3: = null}${4};${5} +snippet co + static public final ${1:String} ${2:var} = ${3};${4} +snippet cos + static public final String ${1:var} = "${2}";${3} +snippet as + assert ${1:test} : "${2:Failure message}";${3} +snippet try + try { + ${3} + } catch(${1:Exception} ${2:e}) { + } +snippet tryf + try { + ${3} + } catch(${1:Exception} ${2:e}) { + } finally { + } +snippet rst + ResultSet ${1:rst}${2: = null}${3};${4} diff --git a/vim/bundle/snipmate/snippets/javascript.snippets b/vim/bundle/snipmate/snippets/javascript.snippets @@ -0,0 +1,74 @@ +# Prototype +snippet proto + ${1:class_name}.prototype.${2:method_name} = + function(${3:first_argument}) { + ${4:// body...} + }; +# Function +snippet fun + function ${1:function_name} (${2:argument}) { + ${3:// body...} + } +# Anonymous Function +snippet f + function(${1}) {${2}}; +# if +snippet if + if (${1:true}) {${2}} +# if ... else +snippet ife + if (${1:true}) {${2}} + else{${3}} +# tertiary conditional +snippet t + ${1:/* condition */} ? ${2:a} : ${3:b} +# switch +snippet switch + switch(${1:expression}) { + case '${3:case}': + ${4:// code} + break; + ${5} + default: + ${2:// code} + } +# case +snippet case + case '${1:case}': + ${2:// code} + break; + ${3} +# for (...) {...} +snippet for + for (var ${2:i} = 0; $2 < ${1:Things}.length; $2${3:++}) { + ${4:$1[$2]} + }; +# for (...) {...} (Improved Native For-Loop) +snippet forr + for (var ${2:i} = ${1:Things}.length - 1; $2 >= 0; $2${3:--}) { + ${4:$1[$2]} + }; +# while (...) {...} +snippet wh + while (${1:/* condition */}) { + ${2:/* code */} + } +# do...while +snippet do + do { + ${2:/* code */} + } while (${1:/* condition */}); +# Object Method +snippet :f + ${1:method_name}: function(${2:attribute}) { + ${4} + }${3:,} +# setTimeout function +snippet timeout + setTimeout(function() {${3}}${2}, ${1:10}; +# Get Elements +snippet get + getElementsBy${1:TagName}('${2}')${3} +# Get Element +snippet gett + getElementBy${1:Id}('${2}')${3} diff --git a/vim/bundle/snipmate/snippets/mako.snippets b/vim/bundle/snipmate/snippets/mako.snippets @@ -0,0 +1,54 @@ +snippet def + <%def name="${1:name}"> + ${2:} + </%def> +snippet call + <%call expr="${1:name}"> + ${2:} + </%call> +snippet doc + <%doc> + ${1:} + </%doc> +snippet text + <%text> + ${1:} + </%text> +snippet for + % for ${1:i} in ${2:iter}: + ${3:} + % endfor +snippet if if + % if ${1:condition}: + ${2:} + % endif +snippet if if/else + % if ${1:condition}: + ${2:} + % else: + ${3:} + % endif +snippet try + % try: + ${1:} + % except${2:}: + ${3:pass} + % endtry +snippet wh + % while ${1:}: + ${2:} + % endwhile +snippet $ + ${ ${1:} } +snippet <% + <% ${1:} %> +snippet <!% + <!% ${1:} %> +snippet inherit + <%inherit file="${1:filename}" /> +snippet include + <%include file="${1:filename}" /> +snippet namespace + <%namespace file="${1:name}" /> +snippet page + <%page args="${1:}" /> diff --git a/vim/bundle/snipmate/snippets/objc.snippets b/vim/bundle/snipmate/snippets/objc.snippets @@ -0,0 +1,247 @@ +# #import <...> +snippet Imp + #import <${1:Cocoa/Cocoa.h}>${2} +# #import "..." +snippet imp + #import "${1:`Filename()`.h}"${2} +# @selector(...) +snippet sel + @selector(${1:method}:)${3} +# @"..." string +snippet s + @"${1}"${2} +# Object +snippet o + ${1:NSObject} *${2:foo} = [${3:$1 alloc}]${4};${5} +# NSLog(...) +snippet log + NSLog(@"${1:%@}"${2});${3} +# Class +snippet objc + @interface ${1:`Filename('', 'someClass')`} : ${2:NSObject} + { + } + @end + + @implementation $1 + ${3} + @end +# Class Interface +snippet int + @interface ${1:`Filename('', 'someClass')`} : ${2:NSObject} + {${3} + } + ${4} + @end +snippet @interface + @interface ${1:`Filename('', 'someClass')`} : ${2:NSObject} + {${3} + } + ${4} + @end +# Class Implementation +snippet impl + @implementation ${1:`Filename('', 'someClass')`} + ${2} + @end +snippet @implementation + @implementation ${1:`Filename('', 'someClass')`} + ${2} + @end +# Protocol +snippet pro + @protocol ${1:`Filename('$1Delegate', 'MyProtocol')`} ${2:<NSObject>} + ${3} + @end +snippet @protocol + @protocol ${1:`Filename('$1Delegate', 'MyProtocol')`} ${2:<NSObject>} + ${3} + @end +# init Definition +snippet init + - (id)init + { + if (self = [super init]) { + ${1} + } + return self; + } +# dealloc Definition +snippet dealloc + - (void) dealloc + { + ${1:deallocations} + [super dealloc]; + } +snippet su + [super ${1:init}]${2} +snippet ibo + IBOutlet ${1:NSSomeClass} *${2:$1};${3} +# Category +snippet cat + @interface ${1:NSObject} (${2:MyCategory}) + @end + + @implementation $1 ($2) + ${3} + @end +# Category Interface +snippet cath + @interface ${1:`Filename('$1', 'NSObject')`} (${2:MyCategory}) + ${3} + @end +# Method +snippet m + - (${1:id})${2:method} + { + ${3} + } +# Method declaration +snippet md + - (${1:id})${2:method};${3} +# IBAction declaration +snippet ibad + - (IBAction)${1:method}:(${2:id})sender;${3} +# IBAction method +snippet iba + - (IBAction)${1:method}:(${2:id})sender + { + ${3} + } +# awakeFromNib method +snippet wake + - (void)awakeFromNib + { + ${1} + } +# Class Method +snippet M + + (${1:id})${2:method} + { + ${3:return nil;} + } +# Sub-method (Call super) +snippet sm + - (${1:id})${2:method} + { + [super $2];${3} + return self; + } +# Accessor Methods For: +# Object +snippet objacc + - (${1:id})${2:thing} + { + return $2; + } + + - (void)set$2:($1)${3:new$2} + { + [$3 retain]; + [$2 release]; + $2 = $3; + }${4} +# for (object in array) +snippet forin + for (${1:Class} *${2:some$1} in ${3:array}) { + ${4} + } +snippet fore + for (${1:object} in ${2:array}) { + ${3:statements} + } +snippet forarray + unsigned int ${1:object}Count = [${2:array} count]; + + for (unsigned int index = 0; index < $1Count; index++) { + ${3:id} $1 = [$2 $1AtIndex:index]; + ${4} + } +snippet fora + unsigned int ${1:object}Count = [${2:array} count]; + + for (unsigned int index = 0; index < $1Count; index++) { + ${3:id} $1 = [$2 $1AtIndex:index]; + ${4} + } +# Try / Catch Block +snippet @try + @try { + ${1:statements} + } + @catch (NSException * e) { + ${2:handler} + } + @finally { + ${3:statements} + } +snippet @catch + @catch (${1:exception}) { + ${2:handler} + } +snippet @finally + @finally { + ${1:statements} + } +# IBOutlet +# @property (Objective-C 2.0) +snippet prop + @property (${1:retain}) ${2:NSSomeClass} ${3:*$2};${4} +# @synthesize (Objective-C 2.0) +snippet syn + @synthesize ${1:property};${2} +# [[ alloc] init] +snippet alloc + [[${1:foo} alloc] init${2}];${3} +snippet a + [[${1:foo} alloc] init${2}];${3} +# retain +snippet ret + [${1:foo} retain];${2} +# release +snippet rel + [${1:foo} release]; +# autorelease +snippet arel + [${1:foo} autorelease]; +# autorelease pool +snippet pool + NSAutoreleasePool *${1:pool} = [[NSAutoreleasePool alloc] init]; + ${2:/* code */} + [$1 drain]; +# Throw an exception +snippet except + NSException *${1:badness}; + $1 = [NSException exceptionWithName:@"${2:$1Name}" + reason:@"${3}" + userInfo:nil]; + [$1 raise]; +snippet prag + #pragma mark ${1:-} +snippet cl + @class ${1:Foo};${2} +snippet color + [[NSColor ${1:blackColor}] set]; +# NSArray +snippet array + NSMutableArray *${1:array} = [NSMutable array];${2} +snippet nsa + NSArray ${1} +snippet nsma + NSMutableArray ${1} +snippet aa + NSArray * array;${1} +snippet ma + NSMutableArray * array;${1} +# NSDictionary +snippet dict + NSMutableDictionary *${1:dict} = [NSMutableDictionary dictionary];${2} +snippet nsd + NSDictionary ${1} +snippet nsmd + NSMutableDictionary ${1} +# NSString +snippet nss + NSString ${1} +snippet nsms + NSMutableString ${1} diff --git a/vim/bundle/snipmate/snippets/perl.snippets b/vim/bundle/snipmate/snippets/perl.snippets @@ -0,0 +1,97 @@ +# #!/usr/bin/perl +snippet #! + #!/usr/bin/perl + +# Hash Pointer +snippet . + => +# Function +snippet sub + sub ${1:function_name} { + ${2:#body ...} + } +# Conditional +snippet if + if (${1}) { + ${2:# body...} + } +# Conditional if..else +snippet ife + if (${1}) { + ${2:# body...} + } + else { + ${3:# else...} + } +# Conditional if..elsif..else +snippet ifee + if (${1}) { + ${2:# body...} + } + elsif (${3}) { + ${4:# elsif...} + } + else { + ${5:# else...} + } +# Conditional One-line +snippet xif + ${1:expression} if ${2:condition};${3} +# Unless conditional +snippet unless + unless (${1}) { + ${2:# body...} + } +# Unless conditional One-line +snippet xunless + ${1:expression} unless ${2:condition};${3} +# Try/Except +snippet eval + eval { + ${1:# do something risky...} + }; + if ($@) { + ${2:# handle failure...} + } +# While Loop +snippet wh + while (${1}) { + ${2:# body...} + } +# While Loop One-line +snippet xwh + ${1:expression} while ${2:condition};${3} +# C-style For Loop +snippet cfor + for (my $${2:var} = 0; $$2 < ${1:count}; $$2${3:++}) { + ${4:# body...} + } +# For loop one-line +snippet xfor + ${1:expression} for @${2:array};${3} +# Foreach Loop +snippet for + foreach my $${1:x} (@${2:array}) { + ${3:# body...} + } +# Foreach Loop One-line +snippet fore + ${1:expression} foreach @${2:array};${3} +# Package +snippet cl + package ${1:ClassName}; + + use base qw(${2:ParentClass}); + + sub new { + my $class = shift; + $class = ref $class if ref $class; + my $self = bless {}, $class; + $self; + } + + 1;${3} +# Read File +snippet slurp + my $${1:var}; + { local $/ = undef; local *FILE; open FILE, "<${2:file}"; $$1 = <FILE>; close FILE }${3} diff --git a/vim/bundle/snipmate/snippets/php.snippets b/vim/bundle/snipmate/snippets/php.snippets @@ -0,0 +1,216 @@ +snippet php + <?php + ${1} + ?> +snippet ec + echo "${1:string}"${2}; +snippet inc + include '${1:file}';${2} +snippet inc1 + include_once '${1:file}';${2} +snippet req + require '${1:file}';${2} +snippet req1 + require_once '${1:file}';${2} +# $GLOBALS['...'] +snippet globals + $GLOBALS['${1:variable}']${2: = }${3:something}${4:;}${5} +snippet $_ COOKIE['...'] + $_COOKIE['${1:variable}']${2} +snippet $_ ENV['...'] + $_ENV['${1:variable}']${2} +snippet $_ FILES['...'] + $_FILES['${1:variable}']${2} +snippet $_ Get['...'] + $_GET['${1:variable}']${2} +snippet $_ POST['...'] + $_POST['${1:variable}']${2} +snippet $_ REQUEST['...'] + $_REQUEST['${1:variable}']${2} +snippet $_ SERVER['...'] + $_SERVER['${1:variable}']${2} +snippet $_ SESSION['...'] + $_SESSION['${1:variable}']${2} +# Start Docblock +snippet /* + /** + * ${1} + **/ +# Class - post doc +snippet doc_cp + /** + * ${1:undocumented class} + * + * @package ${2:default} + * @author ${3:`g:snips_author`} + **/${4} +# Class Variable - post doc +snippet doc_vp + /** + * ${1:undocumented class variable} + * + * @var ${2:string} + **/${3} +# Class Variable +snippet doc_v + /** + * ${3:undocumented class variable} + * + * @var ${4:string} + **/ + ${1:var} $${2};${5} +# Class +snippet doc_c + /** + * ${3:undocumented class} + * + * @packaged ${4:default} + * @author ${5:`g:snips_author`} + **/ + ${1:}class ${2:} + {${6} + } // END $1class $2 +# Constant Definition - post doc +snippet doc_dp + /** + * ${1:undocumented constant} + **/${2} +# Constant Definition +snippet doc_d + /** + * ${3:undocumented constant} + **/ + define(${1}, ${2});${4} +# Function - post doc +snippet doc_fp + /** + * ${1:undocumented function} + * + * @return ${2:void} + * @author ${3:`g:snips_author`} + **/${4} +# Function signature +snippet doc_s + /** + * ${4:undocumented function} + * + * @return ${5:void} + * @author ${6:`g:snips_author`} + **/ + ${1}function ${2}(${3});${7} +# Function +snippet doc_f + /** + * ${4:undocumented function} + * + * @return ${5:void} + * @author ${6:`g:snips_author`} + **/ + ${1}function ${2}(${3}) + {${7} + } +# Header +snippet doc_h + /** + * ${1} + * + * @author ${2:`g:snips_author`} + * @version ${3:$Id$} + * @copyright ${4:$2}, `strftime('%d %B, %Y')` + * @package ${5:default} + **/ + + /** + * Define DocBlock + *// +# Interface +snippet doc_i + /** + * ${2:undocumented class} + * + * @package ${3:default} + * @author ${4:`g:snips_author`} + **/ + interface ${1:} + {${5} + } // END interface $1 +# class ... +snippet class + /** + * ${1} + **/ + class ${2:ClassName} + { + ${3} + function ${4:__construct}(${5:argument}) + { + ${6:// code...} + } + } +# define(...) +snippet def + define('${1}'${2});${3} +# defined(...) +snippet def? + ${1}defined('${2}')${3} +snippet wh + while (${1:/* condition */}) { + ${2:// code...} + } +# do ... while +snippet do + do { + ${2:// code... } + } while (${1:/* condition */}); +snippet if + if (${1:/* condition */}) { + ${2:// code...} + } +snippet ife + if (${1:/* condition */}) { + ${2:// code...} + } else { + ${3:// code...} + } + ${4} +snippet else + else { + ${1:// code...} + } +snippet elseif + elseif (${1:/* condition */}) { + ${2:// code...} + } +# Tertiary conditional +snippet t + $${1:retVal} = (${2:condition}) ? ${3:a} : ${4:b};${5} +snippet switch + switch ($${1:variable}) { + case '${2:value}': + ${3:// code...} + break; + ${5} + default: + ${4:// code...} + break; + } +snippet case + case '${1:value}': + ${2:// code...} + break;${3} +snippet for + for ($${2:i} = 0; $$2 < ${1:count}; $$2${3:++}) { + ${4: // code...} + } +snippet foreach + foreach ($${1:variable} as $${2:key}) { + ${3:// code...} + } +snippet fun + ${1:public }function ${2:FunctionName}(${3}) + { + ${4:// code...} + } +# $... = array (...) +snippet array + $${1:arrayName} = array('${2}' => ${3});${4} diff --git a/vim/bundle/snipmate/snippets/python.snippets b/vim/bundle/snipmate/snippets/python.snippets @@ -0,0 +1,86 @@ +snippet #! + #!/usr/bin/env python + +snippet imp + import ${1:module} +# Module Docstring +snippet docs + ''' + File: ${1:`Filename('$1.py', 'foo.py')`} + Author: ${2:`g:snips_author`} + Description: ${3} + ''' +snippet wh + while ${1:condition}: + ${2:# code...} +snippet for + for ${1:needle} in ${2:haystack}: + ${3:# code...} +# New Class +snippet cl + class ${1:ClassName}(${2:object}): + """${3:docstring for $1}""" + def __init__(self, ${4:arg}): + ${5:super($1, self).__init__()} + self.$4 = $4 + ${6} +# New Function +snippet def + def ${1:fname}(${2:`indent('.') ? 'self' : ''`}): + """${3:docstring for $1}""" + ${4:pass} +snippet deff + def ${1:fname}(${2:`indent('.') ? 'self' : ''`}): + ${3} +# New Method +snippet defs + def ${1:mname}(self, ${2:arg}): + ${3:pass} +# New Property +snippet property + def ${1:foo}(): + doc = "${2:The $1 property.}" + def fget(self): + ${3:return self._$1} + def fset(self, value): + ${4:self._$1 = value} +# Lambda +snippet ld + ${1:var} = lambda ${2:vars} : ${3:action} +snippet . + self. +snippet try Try/Except + try: + ${1:pass} + except ${2:Exception}, ${3:e}: + ${4:raise $3} +snippet try Try/Except/Else + try: + ${1:pass} + except ${2:Exception}, ${3:e}: + ${4:raise $3} + else: + ${5:pass} +snippet try Try/Except/Finally + try: + ${1:pass} + except ${2:Exception}, ${3:e}: + ${4:raise $3} + finally: + ${5:pass} +snippet try Try/Except/Else/Finally + try: + ${1:pass} + except ${2:Exception}, ${3:e}: + ${4:raise $3} + else: + ${5:pass} + finally: + ${6:pass} +# if __name__ == '__main__': +snippet ifmain + if __name__ == '__main__': + ${1:main()} +# __magic__ +snippet _ + __${1:init}__${2} diff --git a/vim/bundle/snipmate/snippets/ruby.snippets b/vim/bundle/snipmate/snippets/ruby.snippets @@ -0,0 +1,504 @@ +# #!/usr/bin/env ruby +snippet #! + #!/usr/bin/env ruby + +# New Block +snippet =b + =begin rdoc + ${1} + =end +snippet y + :yields: ${1:arguments} +snippet rb + #!/usr/bin/env ruby -wKU +snippet beg + begin + ${3} + rescue ${1:Exception} => ${2:e} + end + +snippet req + require "${1}"${2} +snippet # + # => +snippet end + __END__ +snippet case + case ${1:object} + when ${2:condition} + ${3} + end +snippet when + when ${1:condition} + ${2} +snippet def + def ${1:method_name} + ${2} + end +snippet deft + def test_${1:case_name} + ${2} + end +snippet if + if ${1:condition} + ${2} + end +snippet ife + if ${1:condition} + ${2} + else + ${3} + end +snippet elsif + elsif ${1:condition} + ${2} +snippet unless + unless ${1:condition} + ${2} + end +snippet while + while ${1:condition} + ${2} + end +snippet for + for ${1:e} in ${2:c} + ${3} + end +snippet until + until ${1:condition} + ${2} + end +snippet cla class .. end + class ${1:`substitute(Filename(), '^.', '\u&', '')`} + ${2} + end +snippet cla class .. initialize .. end + class ${1:`substitute(Filename(), '^.', '\u&', '')`} + def initialize(${2:args}) + ${3} + end + + + end +snippet cla class .. < ParentClass .. initialize .. end + class ${1:`substitute(Filename(), '^.', '\u&', '')`} < ${2:ParentClass} + def initialize(${3:args}) + ${4} + end + + + end +snippet cla ClassName = Struct .. do .. end + ${1:`substitute(Filename(), '^.', '\u&', '')`} = Struct.new(:${2:attr_names}) do + def ${3:method_name} + ${4} + end + + + end +snippet cla class BlankSlate .. initialize .. end + class ${1:BlankSlate} + instance_methods.each { |meth| undef_method(meth) unless meth =~ /\A__/ } +snippet cla class << self .. end + class << ${1:self} + ${2} + end +# class .. < DelegateClass .. initialize .. end +snippet cla- + class ${1:`substitute(Filename(), '^.', '\u&', '')`} < DelegateClass(${2:ParentClass}) + def initialize(${3:args}) + super(${4:del_obj}) + + ${5} + end + + + end +snippet mod module .. end + module ${1:`substitute(Filename(), '^.', '\u&', '')`} + ${2} + end +snippet mod module .. module_function .. end + module ${1:`substitute(Filename(), '^.', '\u&', '')`} + module_function + + ${2} + end +snippet mod module .. ClassMethods .. end + module ${1:`substitute(Filename(), '^.', '\u&', '')`} + module ClassMethods + ${2} + end + + module InstanceMethods + + end + + def self.included(receiver) + receiver.extend ClassMethods + receiver.send :include, InstanceMethods + end + end +# attr_reader +snippet r + attr_reader :${1:attr_names} +# attr_writer +snippet w + attr_writer :${1:attr_names} +# attr_accessor +snippet rw + attr_accessor :${1:attr_names} +# include Enumerable +snippet Enum + include Enumerable + + def each(&block) + ${1} + end +# include Comparable +snippet Comp + include Comparable + + def <=>(other) + ${1} + end +# extend Forwardable +snippet Forw- + extend Forwardable +# def self +snippet defs + def self.${1:class_method_name} + ${2} + end +# def method_missing +snippet defmm + def method_missing(meth, *args, &blk) + ${1} + end +snippet defd + def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name} +snippet defds + def_delegators :${1:@del_obj}, :${2:del_methods} +snippet am + alias_method :${1:new_name}, :${2:old_name} +snippet app + if __FILE__ == $PROGRAM_NAME + ${1} + end +# usage_if() +snippet usai + if ARGV.${1} + abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3} + end +# usage_unless() +snippet usau + unless ARGV.${1} + abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3} + end +snippet array + Array.new(${1:10}) { |${2:i}| ${3} } +snippet hash + Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${3} } +snippet file File.foreach() { |line| .. } + File.foreach(${1:"path/to/file"}) { |${2:line}| ${3} } +snippet file File.read() + File.read(${1:"path/to/file"})${2} +snippet Dir Dir.global() { |file| .. } + Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${3} } +snippet Dir Dir[".."] + Dir[${1:"glob/**/*.rb"}]${2} +snippet dir + Filename.dirname(__FILE__) +snippet deli + delete_if { |${1:e}| ${2} } +snippet fil + fill(${1:range}) { |${2:i}| ${3} } +# flatten_once() +snippet flao + inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)}${3} +snippet zip + zip(${1:enums}) { |${2:row}| ${3} } +# downto(0) { |n| .. } +snippet dow + downto(${1:0}) { |${2:n}| ${3} } +snippet ste + step(${1:2}) { |${2:n}| ${3} } +snippet tim + times { |${1:n}| ${2} } +snippet upt + upto(${1:1.0/0.0}) { |${2:n}| ${3} } +snippet loo + loop { ${1} } +snippet ea + each { |${1:e}| ${2} } +snippet ead + each do |${1:e}| + ${2} + end +snippet eab + each_byte { |${1:byte}| ${2} } +snippet eac- each_char { |chr| .. } + each_char { |${1:chr}| ${2} } +snippet eac- each_cons(..) { |group| .. } + each_cons(${1:2}) { |${2:group}| ${3} } +snippet eai + each_index { |${1:i}| ${2} } +snippet eaid + each_index do |${1:i}| + end +snippet eak + each_key { |${1:key}| ${2} } +snippet eakd + each_key do |${1:key}| + ${2} + end +snippet eal + each_line { |${1:line}| ${2} } +snippet eald + each_line do |${1:line}| + ${2} + end +snippet eap + each_pair { |${1:name}, ${2:val}| ${3} } +snippet eapd + each_pair do |${1:name}, ${2:val}| + ${3} + end +snippet eas- + each_slice(${1:2}) { |${2:group}| ${3} } +snippet easd- + each_slice(${1:2}) do |${2:group}| + ${3} + end +snippet eav + each_value { |${1:val}| ${2} } +snippet eavd + each_value do |${1:val}| + ${2} + end +snippet eawi + each_with_index { |${1:e}, ${2:i}| ${3} } +snippet eawid + each_with_index do |${1:e},${2:i}| + ${3} + end +snippet reve + reverse_each { |${1:e}| ${2} } +snippet reved + reverse_each do |${1:e}| + ${2} + end +snippet inj + inject(${1:init}) { |${2:mem}, ${3:var}| ${4} } +snippet injd + inject(${1:init}) do |${2:mem}, ${3:var}| + ${4} + end +snippet map + map { |${1:e}| ${2} } +snippet mapd + map do |${1:e}| + ${2} + end +snippet mapwi- + enum_with_index.map { |${1:e}, ${2:i}| ${3} } +snippet sor + sort { |a, b| ${1} } +snippet sorb + sort_by { |${1:e}| ${2} } +snippet ran + sort_by { rand } +snippet all + all? { |${1:e}| ${2} } +snippet any + any? { |${1:e}| ${2} } +snippet cl + classify { |${1:e}| ${2} } +snippet col + collect { |${1:e}| ${2} } +snippet cold + collect do |${1:e}| + ${2} + end +snippet det + detect { |${1:e}| ${2} } +snippet detd + detect do |${1:e}| + ${2} + end +snippet fet + fetch(${1:name}) { |${2:key}| ${3} } +snippet fin + find { |${1:e}| ${2} } +snippet find + find do |${1:e}| + ${2} + end +snippet fina + find_all { |${1:e}| ${2} } +snippet finad + find_all do |${1:e}| + ${2} + end +snippet gre + grep(${1:/pattern/}) { |${2:match}| ${3} } +snippet sub + ${1:g}sub(${2:/pattern/}) { |${3:match}| ${4} } +snippet sca + scan(${1:/pattern/}) { |${2:match}| ${3} } +snippet scad + scan(${1:/pattern/}) do |${2:match}| + ${3} + end +snippet max + max { |a, b| ${1} } +snippet min + min { |a, b| ${1} } +snippet par + partition { |${1:e}| ${2} } +snippet pard + partition do |${1:e}| + ${2} + end +snippet rej + reject { |${1:e}| ${2} } +snippet rejd + reject do |${1:e}| + ${2} + end +snippet sel + select { |${1:e}| ${2} } +snippet seld + select do |${1:e}| + ${2} + end +snippet lam + lambda { |${1:args}| ${2} } +snippet do + do |${1:variable}| + ${2} + end +snippet : + :${1:key} => ${2:"value"}${3} +snippet ope + open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${4} } +# path_from_here() +snippet patfh + File.join(File.dirname(__FILE__), *%2[${1:rel path here}])${2} +# unix_filter {} +snippet unif + ARGF.each_line${1} do |${2:line}| + ${3} + end +# option_parse {} +snippet optp + require "optparse" + + options = {${1:default => "args"}} + + ARGV.options do |opts| + opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} +snippet opt + opts.on( "-${1:o}", "--${2:long-option-name}", ${3:String}, + "${4:Option description.}") do |${5:opt}| + ${6} + end +snippet tc + require "test/unit" + + require "${1:library_file_name}" + + class Test${2:$1} < Test::Unit::TestCase + def test_${3:case_name} + ${4} + end + end +snippet ts + require "test/unit" + + require "tc_${1:test_case_file}" + require "tc_${2:test_case_file}"${3} +snippet as + assert(${1:test}, "${2:Failure message.}")${3} +snippet ase + assert_equal(${1:expected}, ${2:actual})${3} +snippet asne + assert_not_equal(${1:unexpected}, ${2:actual})${3} +snippet asid + assert_in_delta(${1:expected_float}, ${2:actual_float}, ${3:2 ** -20})${4} +snippet asio + assert_instance_of(${1:ExpectedClass}, ${2:actual_instance})${3} +snippet asko + assert_kind_of(${1:ExpectedKind}, ${2:actual_instance})${3} +snippet asn + assert_nil(${1:instance})${2} +snippet asnn + assert_not_nil(${1:instance})${2} +snippet asm + assert_match(/${1:expected_pattern}/, ${2:actual_string})${3} +snippet asnm + assert_no_match(/${1:unexpected_pattern}/, ${2:actual_string})${3} +snippet aso + assert_operator(${1:left}, :${2:operator}, ${3:right})${4} +snippet asr + assert_raise(${1:Exception}) { ${2} } +snippet asnr + assert_nothing_raised(${1:Exception}) { ${2} } +snippet asrt + assert_respond_to(${1:object}, :${2:method})${3} +snippet ass assert_same(..) + assert_same(${1:expected}, ${2:actual})${3} +snippet ass assert_send(..) + assert_send([${1:object}, :${2:message}, ${3:args}])${4} +snippet asns + assert_not_same(${1:unexpected}, ${2:actual})${3} +snippet ast + assert_throws(:${1:expected}) { ${2} } +snippet asnt + assert_nothing_thrown { ${1} } +snippet fl + flunk("${1:Failure message.}")${2} +# Benchmark.bmbm do .. end +snippet bm- + TESTS = ${1:10_000} + Benchmark.bmbm do |results| + ${2} + end +snippet rep + results.report("${1:name}:") { TESTS.times { ${2} }} +# Marshal.dump(.., file) +snippet Md + File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) }${4} +# Mashal.load(obj) +snippet Ml + File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) }${3} +# deep_copy(..) +snippet deec + Marshal.load(Marshal.dump(${1:obj_to_copy}))${2} +snippet Pn- + PStore.new(${1:"file_name.pstore"})${2} +snippet tra + transaction(${1:true}) { ${2} } +# xmlread(..) +snippet xml- + REXML::Document.new(File.read(${1:"path/to/file"}))${2} +# xpath(..) { .. } +snippet xpa + elements.each(${1:"//Xpath"}) do |${2:node}| + ${3} + end +# class_from_name() +snippet clafn + split("::").inject(Object) { |par, const| par.const_get(const) } +# singleton_class() +snippet sinc + class << self; self end +snippet nam + namespace :${1:`Filename()`} do + ${2} + end +snippet tas + desc "${1:Task description\}" + task :${2:task_name => [:dependent, :tasks]} do + ${3} + end diff --git a/vim/bundle/snipmate/snippets/sh.snippets b/vim/bundle/snipmate/snippets/sh.snippets @@ -0,0 +1,28 @@ +# #!/bin/bash +snippet #! + #!/bin/bash + +snippet if + if [[ ${1:condition} ]]; then + ${2:#statements} + fi +snippet elif + elif [[ ${1:condition} ]]; then + ${2:#statements} +snippet for + for (( ${2:i} = 0; $2 < ${1:count}; $2++ )); do + ${3:#statements} + done +snippet wh + while [[ ${1:condition} ]]; do + ${2:#statements} + done +snippet until + until [[ ${1:condition} ]]; do + ${2:#statements} + done +snippet case + case ${1:word} in + ${2:pattern}) + ${3};; + esac diff --git a/vim/bundle/snipmate/snippets/snippet.snippets b/vim/bundle/snipmate/snippets/snippet.snippets @@ -0,0 +1,7 @@ +# snippets for making snippets :) +snippet snip + snippet ${1:trigger} + ${2} +snippet msnip + snippet ${1:trigger} ${2:description} + ${3} diff --git a/vim/bundle/snipmate/snippets/tcl.snippets b/vim/bundle/snipmate/snippets/tcl.snippets @@ -0,0 +1,92 @@ +# #!/usr/bin/env tclsh +snippet #! + #!/usr/bin/env tclsh + +# Process +snippet pro + proc ${1:function_name} {${2:args}} { + ${3:#body ...} + } +#xif +snippet xif + ${1:expr}? ${2:true} : ${3:false} +# Conditional +snippet if + if {${1}} { + ${2:# body...} + } +# Conditional if..else +snippet ife + if {${1}} { + ${2:# body...} + } else { + ${3:# else...} + } +# Conditional if..elsif..else +snippet ifee + if {${1}} { + ${2:# body...} + } elseif {${3}} { + ${4:# elsif...} + } else { + ${5:# else...} + } +# If catch then +snippet ifc + if { [catch {${1:#do something...}} ${2:err}] } { + ${3:# handle failure...} + } +# Catch +snippet catch + catch {${1}} ${2:err} ${3:options} +# While Loop +snippet wh + while {${1}} { + ${2:# body...} + } +# For Loop +snippet for + for {set ${2:var} 0} {$$2 < ${1:count}} {${3:incr} $2} { + ${4:# body...} + } +# Foreach Loop +snippet fore + foreach ${1:x} {${2:#list}} { + ${3:# body...} + } +# after ms script... +snippet af + after ${1:ms} ${2:#do something} +# after cancel id +snippet afc + after cancel ${1:id or script} +# after idle +snippet afi + after idle ${1:script} +# after info id +snippet afin + after info ${1:id} +# Expr +snippet exp + expr {${1:#expression here}} +# Switch +snippet sw + switch ${1:var} { + ${3:pattern 1} { + ${4:#do something} + } + default { + ${2:#do something} + } + } +# Case +snippet ca + ${1:pattern} { + ${2:#do something} + }${3} +# Namespace eval +snippet ns + namespace eval ${1:path} {${2:#script...}} +# Namespace current +snippet nsc + namespace current diff --git a/vim/bundle/snipmate/snippets/tex.snippets b/vim/bundle/snipmate/snippets/tex.snippets @@ -0,0 +1,115 @@ +# \begin{}...\end{} +snippet begin + \begin{${1:env}} + ${2} + \end{$1} +# Tabular +snippet tab + \begin{${1:tabular}}{${2:c}} + ${3} + \end{$1} +# Align(ed) +snippet ali + \begin{align${1:ed}} + ${2} + \end{align$1} +# Gather(ed) +snippet gat + \begin{gather${1:ed}} + ${2} + \end{gather$1} +# Equation +snippet eq + \begin{equation} + ${1} + \end{equation} +# Unnumbered Equation +snippet \ + \\[ + ${1} + \\] +# Enumerate +snippet enum + \begin{enumerate} + \item ${1} + \end{enumerate} +# Itemize +snippet item + \begin{itemize} + \item ${1} + \end{itemize} +# Description +snippet desc + \begin{description} + \item[${1}] ${2} + \end{description} +# Matrix +snippet mat + \begin{${1:p/b/v/V/B/small}matrix} + ${2} + \end{$1matrix} +# Cases +snippet cas + \begin{cases} + ${1:equation}, &\text{ if }${2:case}\\ + ${3} + \end{cases} +# Split +snippet spl + \begin{split} + ${1} + \end{split} +# Part +snippet part + \part{${1:part name}} % (fold) + \label{prt:${2:$1}} + ${3} + % part $2 (end) +# Chapter +snippet cha + \chapter{${1:chapter name}} % (fold) + \label{cha:${2:$1}} + ${3} + % chapter $2 (end) +# Section +snippet sec + \section{${1:section name}} % (fold) + \label{sec:${2:$1}} + ${3} + % section $2 (end) +# Sub Section +snippet sub + \subsection{${1:subsection name}} % (fold) + \label{sub:${2:$1}} + ${3} + % subsection $2 (end) +# Sub Sub Section +snippet subs + \subsubsection{${1:subsubsection name}} % (fold) + \label{ssub:${2:$1}} + ${3} + % subsubsection $2 (end) +# Paragraph +snippet par + \paragraph{${1:paragraph name}} % (fold) + \label{par:${2:$1}} + ${3} + % paragraph $2 (end) +# Sub Paragraph +snippet subp + \subparagraph{${1:subparagraph name}} % (fold) + \label{subp:${2:$1}} + ${3} + % subparagraph $2 (end) +snippet itd + \item[${1:description}] ${2:item} +snippet figure + ${1:Figure}~\ref{${2:fig:}}${3} +snippet table + ${1:Table}~\ref{${2:tab:}}${3} +snippet listing + ${1:Listing}~\ref{${2:list}}${3} +snippet section + ${1:Section}~\ref{${2:sec:}}${3} +snippet page + ${1:page}~\pageref{${2}}${3} diff --git a/vim/bundle/snipmate/snippets/vim.snippets b/vim/bundle/snipmate/snippets/vim.snippets @@ -0,0 +1,32 @@ +snippet header + " File: ${1:`expand('%:t')`} + " Author: ${2:`g:snips_author`} + " Description: ${3} + ${4:" Last Modified: `strftime("%B %d, %Y")`} +snippet guard + if exists('${1:did_`Filename()`}') || &cp${2: || version < 700} + finish + endif + let $1 = 1${3} +snippet f + fun ${1:function_name}(${2}) + ${3:" code} + endf +snippet for + for ${1:needle} in ${2:haystack} + ${3:" code} + endfor +snippet wh + while ${1:condition} + ${2:" code} + endw +snippet if + if ${1:condition} + ${2:" code} + endif +snippet ife + if ${1:condition} + ${2} + else + ${3} + endif diff --git a/vim/bundle/snipmate/snippets/zsh.snippets b/vim/bundle/snipmate/snippets/zsh.snippets @@ -0,0 +1,58 @@ +# #!/bin/zsh +snippet #! + #!/bin/zsh + +snippet if + if ${1:condition}; then + ${2:# statements} + fi +snippet ife + if ${1:condition}; then + ${2:# statements} + else + ${3:# statements} + fi +snippet elif + elif ${1:condition} ; then + ${2:# statements} +snippet for + for (( ${2:i} = 0; $2 < ${1:count}; $2++ )); do + ${3:# statements} + done +snippet fore + for ${1:item} in ${2:list}; do + ${3:# statements} + done +snippet wh + while ${1:condition}; do + ${2:# statements} + done +snippet until + until ${1:condition}; do + ${2:# statements} + done +snippet repeat + repeat ${1:integer}; do + ${2:# statements} + done +snippet case + case ${1:word} in + ${2:pattern}) + ${3};; + esac +snippet select + select ${1:answer} in ${2:choices}; do + ${3:# statements} + done +snippet ( + ( ${1:#statements} ) +snippet { + { ${1:#statements} } +snippet [ + [[ ${1:test} ]] +snippet always + { ${1:try} } always { ${2:always} } +snippet fun + function ${1:name} (${2:args}) { + ${3:# body} + } diff --git a/vim/bundle/snipmate/syntax/snippet.vim b/vim/bundle/snipmate/syntax/snippet.vim @@ -0,0 +1,19 @@ +" Syntax highlighting for snippet files (used for snipMate.vim) +" Hopefully this should make snippets a bit nicer to write! +syn match snipComment '^#.*' +syn match placeHolder '\${\d\+\(:.\{-}\)\=}' contains=snipCommand +syn match tabStop '\$\d\+' +syn match snipCommand '[^\\]`.\{-}`' +syn match snippet '^snippet.*' transparent contains=multiSnipText,snipKeyword +syn match multiSnipText '\S\+ \zs.*' contained +syn match snipKeyword '^snippet'me=s+8 contained +syn match snipError "^[^#s\t].*$" + +hi link snipComment Comment +hi link multiSnipText String +hi link snipKeyword Keyword +hi link snipComment Comment +hi link placeHolder Special +hi link tabStop Special +hi link snipCommand String +hi link snipError Error diff --git a/vim/bundle/tcomment/.gitignore b/vim/bundle/tcomment/.gitignore @@ -0,0 +1,10 @@ +tags +Makefile +TODO.TXT +TODO_archived.viki +*.vba +*.vmb +*.zip +.last_* +test +test_* diff --git a/vim/bundle/tcomment/CHANGES.TXT b/vim/bundle/tcomment/CHANGES.TXT @@ -0,0 +1,205 @@ +0.1 +- Initial release + +0.2 +- Fixed uncommenting of non-aligned comments +- improved support for block comments (with middle lines and indentation) +- using TCommentBlock for file types that don't have block comments creates +single line comments +- removed the TCommentAsBlock command (TCommentAs provides its functionality) +- removed g:tcommentSetCMS +- the default key bindings have slightly changed + +1.3 +- slightly improved recognition of embedded syntax +- if no commentstring is defined in whatever way, reconstruct one from +&comments +- The TComment... commands now have bang variants that don't act as toggles +but always comment out the selected text +- fixed problem with commentstrings containing backslashes +- comment as visual block (allows commenting text to the right of the main +text, i.e., this command doesn't work on whole lines but on the text to the +right of the cursor) +- enable multimode for dsl, vim filetypes +- added explicit support for some other file types I ran into + +1.4 +- Fixed problem when &commentstring was invalid (e.g. lua) +- perl_block by Kyosuke Takayama. +- <c-_>s mapped to :TCommentAs <c-r>=&ft<cr> + +1.5 +- "Inline" visual comments (uses the &filetype_inline style if +available; doesn't check if the filetype actually supports this kind of +comments); tComment can't currently deduce inline comment styles from +&comments or &commentstring (I personally hardly ever use them); default +map: <c-_>i or <c-_>I +- In visual mode: if the selection spans several lines, normal mode is +selected; if the selection covers only a part of one line, inline mode +is selected +- Fixed problem with lines containing ^M or ^@ characters. +- It's no longer necessary to call TCommentCollectFileTypes() after +defining a new filetype via TCommentDefineType() +- Disabled single <c-_> mappings +- Renamed TCommentVisualBlock to TCommentRight +- FIX: Forgot 'x' in ExtractCommentsPart() (thanks to Fredrik Acosta) + +1.6 +- Ignore sql when guessing the comment string in php files; tComment +sometimes chooses the wrong comment string because the use of sql syntax +is used too loosely in php files; if you want to comment embedded sql +code you have to use TCommentAs +- Use keepjumps in commands. +- Map <c-_>p & <L>_p to vip:TComment<cr> +- Made key maps configurable via g:tcommentMapLeader1 and +g:tcommentMapLeader2 + +1.7 +- gc{motion} (see g:tcommentMapLeaderOp1) functions as a comment toggle +operator (i.e., something like gcl... works, mostly); gC{motion} (see +g:tcommentMapLeaderOp2) will unconditionally comment the text. +- TCommentAs takes an optional second argument (the comment level) +- New "n" map: TCommentAs &filetype [COUNT] +- Defined mail comments/citations +- g:tcommentSyntaxMap: Map syntax names to filetypes for buffers with +mixed syntax groups that don't match the filetypeEmbeddedsyntax scheme (e.g. +'vimRubyRegion', which should be commented as ruby syntax, not as vim +syntax) +- FIX: Comments in vim*Region +- TComment: The use of the type argument has slightly changed (IG -> i, +new: >) + +1.8 +- Definitly require vim7 +- Split the plugin into autoload & plugin. +- g:TCommentFileTypes is a list +- Fixed some block comment strings +- Removed extraneous newline in some block comments. +- Maps for visal mode (thanks Krzysztof Goj) + +1.9 +- Fix left offset for inline comments (via operator binding) + +1.10 +- tcomment#Operator defines w:tcommentPos if invoked repeatedly +- s:GuessFileType: use len(getline()) instead of col() + +1.11 +- Support for erlang (thanks to Zhang Jinzhu) + +1.12 +- Moved the definition of some variables from plugin/tComment.vim to +autoload/tcomment.vim +- Changed comment string for eruby (proposed by Vinicius Baggio) +- Support for x86conf + +2.0 +- Enabled key=value pairs to configure commenting +- Renamed the file plugin/tComment.vim to plugin/tcomment.vim +- Renamed certain global functions to tcomment#... + +2.1 +- FIX + +version: "2.02" + - Support for matlab (contributed by D Fong) + MD5 checksum: 29a2742dfae32b52a7abcdfb4de553ad + +version: "2.03" + - s:PrintF(): Silently ignore malformed format strings + - Deal with major.minor pseudo-filetypes + - go-lang + - Remove s:SPrintF() since vim now has printf() + MD5 checksum: 4a13ffb1b1d46bbd2dc8dcee77507983 + +version: "2.04" + - Support for fstab + - g:tcommentOptions: Other key-value options used by |tcomment#Comment()|. + - Support for django (thanks to Jim Tinsky) + - g:tcomment#syntax_substitute: Rewrite syntax names + - django support: minor correction + MD5 checksum: 994e5886d185857848b5472d5457b232 + +version: "2.05" + - Explicit support for python (thanks to brendanarnold) + - Support for samba (thanks Dominic) + - .gitignore + - Define new types: debsources and debcontrol + - Removed some whitespace as proposed by blueyed + - Add config for typoscript filetype. + - EXPERIMENTAL commentstring_rx: Support for using regexps to uncomment code + - s:ProcessedLine: Don't substitute(rv, '\n', '\\\n', 'g') + - Try to handle char-type text objects (disabled by default) + - scss (SASS) filetype + - Add config for 'nginx' filetype. + MD5 checksum: 0e23f194638256fb4fa4a729df645966 + +version: "2.06" + - tcomment#Comment(): Remove last item in search history (reported by Raimond) + - Add config for conkyrc filetype. + - Add config for 'robots' filetype. + - tcomment#GetCommentDef(name) + - g:tcomment_types: override tcomment's default comment styles (fix #12) + - Fixed ft-guessing of htmldjango files + - Add definitions for dnsmasq, pac, resolv and squid. + - Avoid the problem reported in https://github.com/tomtom/tcomment_vim/pull/18 + - Handle nested comments in c mode (fix #19) + MD5 checksum: 0e23f194638256fb4fa4a729df645966 + +version: "2.07" + - Avoid duplicate tag in help file (reported by utkarshkukreti) + - add puppet type + - Use \r instead of ^M + - support for haml and coffeescript + - Support for gitignore + - Merge branch 'master' of https://github.com/ignovak/tcomment_vim + - Enable "filetype guessing" for eruby (fixes #25) + - g:tcommentModeExtra: Always modify how commenting works + - g:tcommentModeExtra: >> ... Like > but also move the cursor to the next line + - adding gnu smalltalk comment style + - Add comment definition for "smarty" + - Sort definition for "sql" + - Merge branch 'master' of https://github.com/clutt0n/tcomment_vim + - added support for jasmine.coffee (cf. https://github.com/claco/jasmine.vim) + - fixed jasmine (have to use syntax instead of filetype) + - Block comments: set &sel = exclusive (fixes #30; bug 1) + - Merge branch 'master' of https://github.com/paulwittmann/tcomment_vim + - spec files for issue 30 + - Inline comments: Include the current character if selection == inclusive (fixes #30 bug 2) + - gC in visual mode: call :TCommentMaybeInline! (fixes #30 bug 3) + - Added Clojure and Clojurescript support. Thou the comment is a single ';' it is a widely adopted convention to comment whole lines with ';;' + - command line completion: also offer rx*= arguments + - Merge branch 'master' of https://github.com/ssedano/tcomment_vim + - clojure: use ";" for inline comments + - TCommentRight used wrong column + - b:tcommentOptions: buffer-local options + - Deal with mode argument (concatenate with commentMode) + - Removed visual/selection maps for :TCommentRight + - <c-_>cc and <c-_>ca maps to temporary set options (count, as) on the fly + - <c-_>1 .. <c-_>9 maps to invoke :TComment count=N (repeat the comment string N times) + - clojure: use the "count" property instead of hardcoding the double semicolon (";;") + - Enable inline comments for insert & normal mode (create empty comments, which isn't always that useful; fixes #33) + - When guessing a filetype, make sure to use custom definitions when no syntax name is found + - gc<count>c maps that set the "count" attribute + - Make sure to ignore %%s in commentstrings + - gc<Count>c{motion} maps work as toggle + - Enable <c-_><Count> maps for insert mode + - Monkey language comment style + MD5 checksum: 0853c50ebdcd4c52a31b2ad2d514d1e0 + +version: "2.08" + - Enable count for gc operator maps (use e.g. 3gc2l instead of gc3c2l; maybe remove gc<count>c maps later on) + - <count>gc operator maps: use v:count instead of v:count1 + - fixed unlet + - Merge branch 'master' of https://github.com/grassofhust/tcomment_vim + - Added vhdl to tcomment#DefineType + - tcomment#GuessCommentType(): Make filetype guessing accessible for other plugins + - FIX: didn't guess filetype correctly for lines containing only one character + - Guess filetype: Improved handling of empty lines + - g:tcommentSyntaxMap: support additional info on how to handle empty lines + - g:tcommentSyntaxMap: support filetype key: explicitly map syntax name per filetype (fixes #39) + - Fix typo + - Add `g:tcommentGuessFileType_smarty = 1` + - Define/handle 'ini' file type (e.g. for php.ini) + MD5 checksum: 702082a857ddeaf75d3b4fd884363173 + diff --git a/vim/bundle/tcomment/README b/vim/bundle/tcomment/README @@ -0,0 +1,104 @@ +tcomment provides easy to use, file-type sensible comments for Vim. It +can handle embedded syntax. + +TComment works like a toggle, i.e., it will comment out text that +contains uncommented lines, and it will remove comment markup for +already commented text (i.e. text that contains no uncommented lines). + +If the file-type is properly defined, TComment will figure out which +comment string to use. Otherwise you use |tcomment#DefineType()| to +override the default choice. + +TComment can properly handle an embedded syntax, e.g., ruby/python/perl +regions in vim scripts, HTML or JavaScript in php code etc. + +tcomment favours the use of line-wise comment styles. This implies that usually +whole line will be commented out. tcomment also knows block-style and inline +comments that can be used via special maps (see below) or the |:TCommentAs| +command. + +Demo: +http://vimsomnia.blogspot.com/2010/11/tcomment-vim-plugin.html + + + *tcomment-maps* +Key bindings~ + +Most of the time the default toggle keys will do what you want (or to be +more precise: what I think you want it to do ;-). + + *tcomment-operator* +As operator (the prefix can be customized via |g:tcommentMapLeaderOp1| +and |g:tcommentMapLeaderOp2|): + + gc{motion} :: Toggle comments (for small comments within one line + the &filetype_inline style will be used, if + defined) + gc<Count>c{motion} :: Toggle comment text with count argument + (see |tcomment#Comment()|) + gcc :: Toggle comment for the current line + gC{motion} :: Comment region + gCc :: Comment the current line + +In visual mode: + + gc :: Toggle comments + gC :: Comment selected text + +CAVEAT: If you visually select text within a line, the visual mode map will +comment out the selected text. If you selected text across several lines, the +visual mode map will assume though that you wanted to comment out lines -- +since this is how many vim maps work. In order to make tcomment use e.g. inline +comments anyway, use the <c-_>i map -- see below. + +By default the cursor stays put. If you want the cursor to the end of +the commented text, set |g:tcommentOpModeExtra| to '>' (but this may not +work properly with exclusive motions). + +Primary key maps for normal and insert mode: + + <c-_><c-_> :: :TComment + <c-_><space> :: :TComment <QUERY COMMENT-BEGIN ?COMMENT-END> + <c-_>b :: :TCommentBlock + <c-_>a :: :TCommentAs <QUERY COMMENT TYPE> + <c-_>n :: :TCommentAs &filetype <QUERY COUNT> + <c-_>s :: :TCommentAs &filetype_<QUERY COMMENT SUBTYPE> + <c-_>i :: :TCommentInline (in normal and insert mode, this map will + create an empty inline comment, which isn't suitable for + all filetypes though) + <c-_>r :: :TCommentRight + <c-_>p :: Comment the current inner paragraph + <c-_><Count> :: :TComment with count argument (a number from 1 to 9) + (see |tcomment#Comment()|) + +Primary key maps for visual mode: + + <c-_><c-_> :: :TComment + <c-_>i :: :TCommentInline + <c-_><Count> :: :TComment with count argument (a number from 1 to 9) + (see |tcomment#Comment()|) + +A secondary set of key maps is defined for normal and insert mode: + + <Leader>__ :: :TComment + <Leader>_p :: Comment the current inner paragraph + <Leader>_<space> :: :TComment <QUERY COMMENT-BEGIN ?COMMENT-END> + <Leader>_i :: :TCommentInline + <Leader>_r :: :TCommentRight + <Leader>_b :: :TCommentBlock + <Leader>_a :: :TCommentAs <QUERY COMMENT TYPE> + <Leader>_n :: :TCommentAs &filetype <QUERY COUNT> + <Leader>_s :: :TCommentAs &filetype_<QUERY COMMENT SUBTYPE> + +... and for select mode: + + <Leader>__ :: :TComment + <Leader>_i :: :TCommentInline + + +----------------------------------------------------------------------- + +Status: Works for me (there may be some minor quirks) +Install: See http://github.com/tomtom/vimtlib/blob/master/INSTALL.TXT +See http://github.com/tomtom for related plugins. + diff --git a/vim/bundle/tcomment/addon-info.json b/vim/bundle/tcomment/addon-info.json @@ -0,0 +1,9 @@ +{ + "name" : "tcomment", + "version" : "dev", + "author" : "Tom Link <micathom at gmail com>", + "maintainer" : "Tom Link <micathom at gmail com>", + "repository" : {"type": "git", "url": "git://github.com/tomtom/tcomment_vim.git"}, + "dependencies" : {}, + "description" : "An easily extensible & universal comment plugin" +} diff --git a/vim/bundle/tcomment/autoload/tcomment.vim b/vim/bundle/tcomment/autoload/tcomment.vim @@ -0,0 +1,1679 @@ +" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) +" @Website: http://www.vim.org/account/profile.php?user_id=4037 +" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) +" @Created: 2007-09-17. +" @Last Change: 2013-03-07. +" @Revision: 1010 + +" call tlog#Log('Load: '. expand('<sfile>')) " vimtlib-sfile + +if !exists("g:tcommentBlankLines") + " If true, comment blank lines too + let g:tcommentBlankLines = 1 "{{{2 +endif + +if !exists("g:tcommentModeExtra") + " Modifies how commenting works. + " > ... Move the cursor to the end of the comment + " >> ... Like above but move the cursor to the next line + " # ... Move the cursor to the position of the commented text + " (NOTE: this only works when creating empty comments using + " |:TCommentInline| from normal or insert mode and should + " not be set here as a global option.) + let g:tcommentModeExtra = '' "{{{2 +endif + +if !exists("g:tcommentOpModeExtra") + " Modifies how the operator works. + " See |g:tcommentModeExtra| for a list of possible values. + let g:tcommentOpModeExtra = '' "{{{2 +endif + +if !exists('g:tcommentOptions') + " Other key-value options used by |tcomment#Comment()|. + " + " Example: If you want to put the opening comment marker always in + " the first column regardless of the block's indentation, put this + " into your |vimrc| file: > + " let g:tcommentOptions = {'col': 1} + let g:tcommentOptions = {} "{{{2 +endif + +if !exists('g:tcomment#ignore_char_type') + " |text-objects| for use with |tcomment#Operator| can have different + " types: line, block, char etc. Text objects like aB, it, at etc. + " have type char but this may not work reliably. By default, + " tcomment handles those text objects most often as if they were of + " type line. Set this variable to 0 in order to change this + " behaviour. Be prepared that the result may not always match your + " intentions. + let g:tcomment#ignore_char_type = 1 "{{{2 +endif + +if !exists("g:tcommentGuessFileType") + " Guess the file type based on syntax names always or for some fileformat only + " If non-zero, try to guess filetypes. + " tcomment also checks g:tcommentGuessFileType_{&filetype} for + " filetype specific values. + " + " Values: + " 0 ... don't guess + " 1 ... guess + " FILETYPE ... assume this filetype + let g:tcommentGuessFileType = 0 "{{{2 +endif +if !exists("g:tcommentGuessFileType_dsl") + " For dsl documents, assume filetype = xml. + let g:tcommentGuessFileType_dsl = 'xml' "{{{2 +endif +if !exists("g:tcommentGuessFileType_php") + " In php documents, the php part is usually marked as phpRegion. We + " thus assume that the buffers default comment style isn't php but + " html. + let g:tcommentGuessFileType_php = 'html' "{{{2 +endif +if !exists("g:tcommentGuessFileType_html") + let g:tcommentGuessFileType_html = 1 "{{{2 +endif +if !exists("g:tcommentGuessFileType_tskeleton") + let g:tcommentGuessFileType_tskeleton = 1 "{{{2 +endif +if !exists("g:tcommentGuessFileType_vim") + let g:tcommentGuessFileType_vim = 1 "{{{2 +endif +if !exists("g:tcommentGuessFileType_django") + let g:tcommentGuessFileType_django = 1 "{{{2 +endif +if !exists("g:tcommentGuessFileType_eruby") + let g:tcommentGuessFileType_eruby = 1 "{{{2 +endif +if !exists("g:tcommentGuessFileType_smarty") + let g:tcommentGuessFileType_smarty = 1 "{{{2 +endif + +if !exists("g:tcommentIgnoreTypes_php") + " In php files, some syntax regions are wrongly highlighted as sql + " markup. We thus ignore sql syntax when guessing the filetype in + " php files. + let g:tcommentIgnoreTypes_php = 'sql' "{{{2 +endif + +if !exists('g:tcomment#syntax_substitute') + " :read: let g:tcomment#syntax_substitute = {...} "{{{2 + " Perform replacements on the syntax name. + let g:tcomment#syntax_substitute = { + \ '\C^javaScript': {'sub': 'javascript'} + \ } +endif + +if !exists('g:tcomment#filetype_map') + " Keys must match the full |filetype|. Regexps must be |magic|. No + " regexp modifiers (like |\V|) are allowed. + " let g:tcomment#filetype_map = {...} "{{{2 + let g:tcomment#filetype_map = { + \ 'rails-views': 'html', + \ 'mkd': 'html', + \ } +endif + +if !exists('g:tcommentSyntaxMap') + " tcomment guesses filetypes based on the name of the current syntax + " region. This works well if the syntax names match + " /filetypeSomeName/. Other syntax names have to be explicitly + " mapped onto the corresponding filetype. + " :read: let g:tcommentSyntaxMap = {...} "{{{2 + let g:tcommentSyntaxMap = { + \ 'erubyExpression': 'ruby', + \ 'vimMzSchemeRegion': 'scheme', + \ 'vimPerlRegion': 'perl', + \ 'vimPythonRegion': 'python', + \ 'vimRubyRegion': 'ruby', + \ 'vimTclRegion': 'tcl', + \ 'Delimiter': { + \ 'filetype': { + \ 'php': 'php', + \ }, + \ }, + \ 'phpRegionDelimiter': { + \ 'prevnonblank': [ + \ {'match': '<?php', 'filetype': 'php'}, + \ {'match': '?>', 'filetype': 'html'}, + \ ], + \ 'nextnonblank': [ + \ {'match': '?>', 'filetype': 'php'}, + \ {'match': '<?php', 'filetype': 'html'}, + \ ], + \ }, + \ } +endif + +if !exists('g:tcomment#replacements_c') + " Replacements for c filetype. + " :read: let g:tcomment#replacements_c = {...} "{{{2 + let g:tcomment#replacements_c = { + \ '/*': '#<{(|', + \ '*/': '|)}>#', + \ } +endif + +if !exists("g:tcommentInlineC") + " Generic c-like comments. + " :read: let g:tcommentInlineC = {...} "{{{2 + let g:tcommentInlineC = { + \ 'commentstring': '/* %s */', + \ 'replacements': g:tcomment#replacements_c + \ } +endif +if !exists("g:tcommentLineC") + " Generic c-like block comments. + let g:tcommentLineC = g:tcommentInlineC +endif +if !exists("g:tcommentBlockC") + let g:tcommentBlockC = { + \ 'commentstring': '/*%s */', + \ 'middle': ' * ', + \ 'rxbeg': '\*\+', + \ 'rxend': '\*\+', + \ 'rxmid': '\*\+', + \ 'replacements': g:tcomment#replacements_c + \ } +endif +if !exists("g:tcommentBlockC2") + " Generic c-like block comments (alternative markup). + " :read: let g:tcommentBlockC2 = {...} "{{{2 + let g:tcommentBlockC2 = { + \ 'commentstring': '/**%s */', + \ 'middle': ' * ', + \ 'rxbeg': '\*\+', + \ 'rxend': '\*\+', + \ 'rxmid': '\*\+', + \ 'replacements': g:tcomment#replacements_c + \ } +endif + +if !exists('g:tcomment#replacements_xml') + " Replacements for xml filetype. + " :read: let g:tcomment#replacements_xml = {...} "{{{2 + let g:tcomment#replacements_xml = { + \ '-': '&#45;', + \ '&': '&#38;', + \ } +endif + +if !exists("g:tcommentBlockXML") + " Generic xml-like block comments. + " :read: let g:tcommentBlockXML = {...} "{{{2 + let g:tcommentBlockXML = { + \ 'commentstring': "<!--%s-->\n ", + \ 'replacements': g:tcomment#replacements_xml + \ } +endif +if !exists("g:tcommentInlineXML") + " Generic xml-like comments. + " :read: let g:tcommentInlineXML = {...} "{{{2 + let g:tcommentInlineXML = { + \ 'commentstring': "<!-- %s -->", + \ 'replacements': g:tcomment#replacements_xml + \ } +endif + +let s:typesDirty = 1 + +let s:definitions = {} + +" If you don't explicitly define a comment style, |:TComment| will use +" 'commentstring' instead. We override the default values here in order +" to have a blank after the comment marker. Block comments work only if +" we explicitly define the markup. +" +" NAME usually is a 'filetype'. You can use special suffixes to define +" special comment types. E.g. the name "FILETYPE_block" is used for +" block comments for 'filetype'. The name "FILETYPE_inline" is used for +" inline comments. If no specialized comment definition exists, the +" normal one with name "FILETYPE" is used. +" +" The comment definition can be either a string or a dictionary. +" +" If it is a string: +" The format for block comments is similar to 'commentstrings' with the +" exception that the format strings for blocks can contain a second line +" that defines how "middle lines" (see :h format-comments) should be +" displayed. +" +" Example: If the string is "--%s--\n-- ", lines will be commented as +" "--%s--" but the middle lines in block comments will be commented as +" "--%s". +" +" If it is a dictionary: +" See the help on the args argument of |tcomment#Comment| (see item 1, +" args is a list of key=value pairs) to find out which fields can be +" used. +" :display: tcomment#DefineType(name, commentdef, ?cdef={}, ?anyway=0) +function! tcomment#DefineType(name, commentdef, ...) + let use = a:0 >= 2 ? a:2 : !has_key(s:definitions, a:name) + if use + if type(a:commentdef) == 4 + let cdef = copy(a:commentdef) + else + let cdef = a:0 >= 1 ? a:1 : {} + let cdef.commentstring = a:commentdef + endif + let s:definitions[a:name] = cdef + endif + let s:typesDirty = 1 +endf + +" :nodoc: +" Return comment definition +function! tcomment#GetCommentDef(name) + return get(s:definitions, a:name, "") +endf + +" :nodoc: +" Return 1 if a comment type is defined. +function! tcomment#TypeExists(name) + return has_key(s:definitions, a:name) +endf + +" :doc: +" A dictionary of NAME => COMMENT DEFINITION (see |tcomment#DefineType|) +" that can be set in vimrc to override tcomment's default comment +" styles. +" :read: let g:tcomment_types = {} "{{{2 +if exists('g:tcomment_types') + for [s:name, s:def] in items(g:tcomment_types) + call tcomment#DefineType(s:name, s:def) + endfor + unlet! s:name s:def +endif + +call tcomment#DefineType('aap', '# %s' ) +call tcomment#DefineType('ada', '-- %s' ) +call tcomment#DefineType('apache', '# %s' ) +call tcomment#DefineType('autoit', '; %s' ) +call tcomment#DefineType('asm', '; %s' ) +call tcomment#DefineType('awk', '# %s' ) +call tcomment#DefineType('catalog', '-- %s --' ) +call tcomment#DefineType('catalog_block', "--%s--\n " ) +call tcomment#DefineType('cpp', '// %s' ) +call tcomment#DefineType('cpp_inline', g:tcommentInlineC ) +call tcomment#DefineType('cpp_block', g:tcommentBlockC ) +call tcomment#DefineType('css', '/* %s */' ) +call tcomment#DefineType('css_inline', g:tcommentInlineC ) +call tcomment#DefineType('css_block', g:tcommentBlockC ) +call tcomment#DefineType('c', g:tcommentLineC ) +call tcomment#DefineType('c_inline', g:tcommentInlineC ) +call tcomment#DefineType('c_block', g:tcommentBlockC ) +call tcomment#DefineType('cfg', '# %s' ) +call tcomment#DefineType('chromemanifest', '# %s' ) +call tcomment#DefineType('clojure', {'commentstring': '; %s', 'count': 2}) +call tcomment#DefineType('clojure_inline', '; %s' ) +call tcomment#DefineType('clojurescript', ';; %s' ) +call tcomment#DefineType('clojurescript_inline', '; %s' ) +call tcomment#DefineType('cmake', '# %s' ) +call tcomment#DefineType('coffee', '# %s' ) +call tcomment#DefineType('conf', '# %s' ) +call tcomment#DefineType('conkyrc', '# %s' ) +call tcomment#DefineType('crontab', '# %s' ) +call tcomment#DefineType('cs', '// %s' ) +call tcomment#DefineType('cs_inline', g:tcommentInlineC ) +call tcomment#DefineType('cs_block', g:tcommentBlockC ) +call tcomment#DefineType('debsources', '# %s' ) +call tcomment#DefineType('debcontrol', '# %s' ) +call tcomment#DefineType('desktop', '# %s' ) +call tcomment#DefineType('dnsmasq', '# %s' ) +call tcomment#DefineType('docbk', g:tcommentInlineXML) +call tcomment#DefineType('docbk_inline', g:tcommentInlineXML) +call tcomment#DefineType('docbk_block', g:tcommentBlockXML ) +call tcomment#DefineType('dosbatch', 'rem %s' ) +call tcomment#DefineType('dosini', '; %s' ) +call tcomment#DefineType('dsl', '; %s' ) +call tcomment#DefineType('dylan', '// %s' ) +call tcomment#DefineType('eiffel', '-- %s' ) +call tcomment#DefineType('erlang', '%%%% %s' ) +call tcomment#DefineType('eruby', '<%%# %s' ) +call tcomment#DefineType('esmtprc', '# %s' ) +call tcomment#DefineType('fstab', '# %s' ) +call tcomment#DefineType('gitcommit', '# %s' ) +call tcomment#DefineType('gitignore', '# %s' ) +call tcomment#DefineType('gnuplot', '# %s' ) +call tcomment#DefineType('gtkrc', '# %s' ) +call tcomment#DefineType('go', '// %s' ) +call tcomment#DefineType('go_inline', g:tcommentInlineC ) +call tcomment#DefineType('go_block', g:tcommentBlockC ) +call tcomment#DefineType('groovy', '// %s' ) +call tcomment#DefineType('groovy_inline', g:tcommentInlineC ) +call tcomment#DefineType('groovy_block', g:tcommentBlockC ) +call tcomment#DefineType('groovy_doc_block', g:tcommentBlockC2 ) +call tcomment#DefineType('haml', '-# %s' ) +call tcomment#DefineType('haskell', '-- %s' ) +call tcomment#DefineType('haskell_block', "{-%s-}\n " ) +call tcomment#DefineType('haskell_inline', '{- %s -}' ) +call tcomment#DefineType('html', g:tcommentInlineXML) +call tcomment#DefineType('html_inline', g:tcommentInlineXML) +call tcomment#DefineType('html_block', g:tcommentBlockXML ) +call tcomment#DefineType('htmldjango', '{# %s #}' ) +call tcomment#DefineType('htmldjango_block', "{%% comment %%}%s{%% endcomment %%}\n ") +call tcomment#DefineType('ini', '; %s' ) " php ini (/etc/php5/...) +call tcomment#DefineType('io', '// %s' ) +call tcomment#DefineType('jasmine', '# %s' ) +call tcomment#DefineType('javaScript', '// %s' ) +call tcomment#DefineType('javaScript_inline', g:tcommentInlineC ) +call tcomment#DefineType('javaScript_block', g:tcommentBlockC ) +call tcomment#DefineType('javascript', '// %s' ) +call tcomment#DefineType('javascript_inline', g:tcommentInlineC ) +call tcomment#DefineType('javascript_block', g:tcommentBlockC ) +call tcomment#DefineType('java', '/* %s */' ) +call tcomment#DefineType('java_inline', g:tcommentInlineC ) +call tcomment#DefineType('java_block', g:tcommentBlockC ) +call tcomment#DefineType('java_doc_block', g:tcommentBlockC2 ) +call tcomment#DefineType('jproperties', '# %s' ) +call tcomment#DefineType('lisp', '; %s' ) +call tcomment#DefineType('lynx', '# %s' ) +call tcomment#DefineType('matlab', '%% %s' ) +call tcomment#DefineType('m4', 'dnl %s' ) +call tcomment#DefineType('mail', '> %s' ) +call tcomment#DefineType('monkey', ''' %s' ) +call tcomment#DefineType('msidl', '// %s' ) +call tcomment#DefineType('msidl_block', g:tcommentBlockC ) +call tcomment#DefineType('nginx', '# %s' ) +call tcomment#DefineType('nroff', '.\\" %s' ) +call tcomment#DefineType('nsis', '# %s' ) +call tcomment#DefineType('objc', '/* %s */' ) +call tcomment#DefineType('objc_inline', g:tcommentInlineC ) +call tcomment#DefineType('objc_block', g:tcommentBlockC ) +call tcomment#DefineType('ocaml', '(* %s *)' ) +call tcomment#DefineType('ocaml_inline', '(* %s *)' ) +call tcomment#DefineType('ocaml_block', "(*%s*)\n " ) +call tcomment#DefineType('pac', '// %s' ) +call tcomment#DefineType('pascal', '(* %s *)' ) +call tcomment#DefineType('pascal_inline', '(* %s *)' ) +call tcomment#DefineType('pascal_block', "(*%s*)\n " ) +call tcomment#DefineType('perl', '# %s' ) +call tcomment#DefineType('perl_block', "=cut%s=cut" ) +call tcomment#DefineType('pfmain', '# %s' ) +call tcomment#DefineType('php', {'commentstring_rx': '\%%(//\|#\) %s', 'commentstring': '// %s'}) +call tcomment#DefineType('php_inline', g:tcommentInlineC ) +call tcomment#DefineType('php_block', g:tcommentBlockC ) +call tcomment#DefineType('php_2_block', g:tcommentBlockC2 ) +call tcomment#DefineType('po', '# %s' ) +call tcomment#DefineType('prolog', '%% %s' ) +call tcomment#DefineType('puppet', '# %s' ) +call tcomment#DefineType('python', '# %s' ) +call tcomment#DefineType('racket', '; %s' ) +call tcomment#DefineType('racket_block', '#|%s|#' ) +call tcomment#DefineType('rc', '// %s' ) +call tcomment#DefineType('readline', '# %s' ) +call tcomment#DefineType('resolv', '# %s' ) +call tcomment#DefineType('robots', '# %s' ) +call tcomment#DefineType('ruby', '# %s' ) +call tcomment#DefineType('ruby_3', '### %s' ) +call tcomment#DefineType('ruby_block', "=begin rdoc%s=end") +call tcomment#DefineType('ruby_nodoc_block', "=begin%s=end" ) +call tcomment#DefineType('r', '# %s' ) +call tcomment#DefineType('samba', '# %s' ) +call tcomment#DefineType('sbs', "' %s" ) +call tcomment#DefineType('scala', '// %s' ) +call tcomment#DefineType('scala_inline', g:tcommentInlineC ) +call tcomment#DefineType('scala_block', g:tcommentBlockC ) +call tcomment#DefineType('scheme', '; %s' ) +call tcomment#DefineType('scheme_block', '#|%s|#' ) +" call tcomment#DefineType('scheme_s', '#;%s' ) +call tcomment#DefineType('scss', '// %s' ) +call tcomment#DefineType('scss_inline', g:tcommentInlineC ) +call tcomment#DefineType('scss_block', g:tcommentBlockC ) +call tcomment#DefineType('sed', '# %s' ) +call tcomment#DefineType('sgml', g:tcommentInlineXML) +call tcomment#DefineType('sgml_inline', g:tcommentInlineXML) +call tcomment#DefineType('sgml_block', g:tcommentBlockXML ) +call tcomment#DefineType('sh', '# %s' ) +call tcomment#DefineType('slim', '/%s' ) +call tcomment#DefineType('smarty', '{* %s *}' ) +call tcomment#DefineType('spec', '# %s' ) +call tcomment#DefineType('sps', '* %s.' ) +call tcomment#DefineType('sps_block', "* %s." ) +call tcomment#DefineType('spss', '* %s.' ) +call tcomment#DefineType('spss_block', "* %s." ) +call tcomment#DefineType('sql', '-- %s' ) +call tcomment#DefineType('squid', '# %s' ) +call tcomment#DefineType('sshconfig', '# %s' ) +call tcomment#DefineType('sshdconfig', '# %s' ) +call tcomment#DefineType('st', '" %s "' ) +call tcomment#DefineType('tcl', '# %s' ) +call tcomment#DefineType('tex', '%% %s' ) +call tcomment#DefineType('tpl', '<!-- %s -->' ) +call tcomment#DefineType('typoscript', '# %s' ) +call tcomment#DefineType('upstart', '# %s' ) +call tcomment#DefineType('vhdl', '-- %s' ) +call tcomment#DefineType('viki', '%% %s' ) +call tcomment#DefineType('viki_3', '%%%%%% %s' ) +call tcomment#DefineType('viki_inline', '{cmt: %s}' ) +call tcomment#DefineType('vim', '" %s' ) +call tcomment#DefineType('vim_3', '""" %s' ) +call tcomment#DefineType('websec', '# %s' ) +call tcomment#DefineType('x86conf', '# %s' ) +call tcomment#DefineType('xml', g:tcommentInlineXML) +call tcomment#DefineType('xml_inline', g:tcommentInlineXML) +call tcomment#DefineType('xml_block', g:tcommentBlockXML ) +call tcomment#DefineType('xs', '// %s' ) +call tcomment#DefineType('xs_block', g:tcommentBlockC ) +call tcomment#DefineType('xslt', g:tcommentInlineXML) +call tcomment#DefineType('xslt_inline', g:tcommentInlineXML) +call tcomment#DefineType('xslt_block', g:tcommentBlockXML ) +call tcomment#DefineType('yaml', '# %s' ) + + +function! s:DefaultValue(option) + exec 'let '. a:option .' = &'. a:option + exec 'set '. a:option .'&' + exec 'let default = &'. a:option + exec 'let &'. a:option .' = '. a:option + return default +endf + +let s:defaultComments = s:DefaultValue('comments') +let s:defaultCommentString = s:DefaultValue('commentstring') +let s:nullCommentString = '%s' + +" tcomment#Comment(line1, line2, ?commentMode, ?commentAnyway, ?args...) +" args... are either: +" 1. a list of key=value pairs where known keys are (see also +" |g:tcommentOptions|): +" as=STRING ... Use a specific comment definition +" count=N ... Repeat the comment string N times +" col=N ... Start the comment at column N (in block +" mode; must be smaller than |indent()|) +" mode=STRING ... See the notes below on the "commentMode" argument +" mode_extra=STRING ... Add to commentMode +" begin=STRING ... Comment prefix +" end=STRING ... Comment postfix +" middle=STRING ... Middle line comments in block mode +" rxbeg=N ... Regexp to find the substring of "begin" +" that should be multiplied by "count" +" rxend=N ... The above for "end" +" rxmid=N ... The above for "middle" +" mixedindent=BOOL ... If true, allow use of mixed +" characters for indentation +" commentstring_rx ... A regexp format string that matches +" commented lines (no new groups may be +" introduced, the |regexp| is |\V|; % have +" to be doubled); "commentstring", "begin" +" and optionally "end" must be defined or +" deducible. +" whitespace ... Define whether commented text is +" surrounded with whitespace; if +" both ... surround with whitespace (default) +" no ... don't use whitespace +" strip_whitespace ... Strip trailing whitespace: if 1, strip +" from empty lines only, if 2, always strip +" whitespace +" 2. 1-2 values for: ?commentPrefix, ?commentPostfix +" 3. a dictionary (internal use only) +" +" commentMode (see also ¦g:tcommentModeExtra¦): +" G ... guess the value of commentMode +" B ... block (use extra lines for the comment markers) +" i ... maybe inline, guess +" I ... inline +" R ... right (comment the line right of the cursor) +" v ... visual +" o ... operator +" By default, each line in range will be commented by adding the comment +" prefix and postfix. +function! tcomment#Comment(beg, end, ...) + let commentMode = s:AddModeExtra((a:0 >= 1 ? a:1 : 'G'), g:tcommentModeExtra, a:beg, a:end) + let commentAnyway = a:0 >= 2 ? (a:2 == '!') : 0 + " TLogVAR a:beg, a:end, commentMode, commentAnyway + " save the cursor position + if exists('w:tcommentPos') + let s:current_pos = copy(w:tcommentPos) + else + let s:current_pos = getpos('.') + endif + " echom "DBG current_pos=" string(s:current_pos) + let cursor_pos = getpos("'>") + " TLogVAR cursor_pos + let s:cursor_pos = [] + if commentMode =~# 'i' + let commentMode = substitute(commentMode, '\Ci', line("'<") == line("'>") ? 'I' : 'G', 'g') + " TLogVAR 1, commentMode + endif + let [lbeg, cbeg, lend, cend] = s:GetStartEnd(a:beg, a:end, commentMode) + if exists('s:temp_options') && has_key(s:temp_options, 'mode_extra') + let commentMode = s:AddModeExtra(commentMode, s:temp_options.mode_extra, lbeg, lend) + unlet s:temp_options.mode_extra + endif + " TLogVAR commentMode, lbeg, cbeg, lend, cend + " get the correct commentstring + let cdef = copy(g:tcommentOptions) + " TLogVAR 1, cdef + if exists('b:tcommentOptions') + let cdef = extend(cdef, copy(b:tcommentOptions)) + " TLogVAR 2, cdef + endif + if a:0 >= 3 && type(a:3) == 4 + call extend(cdef, a:3) + " TLogVAR 3, cdef + else + let cdef0 = s:GetCommentDefinition(lbeg, lend, commentMode) + " TLogVAR 4.1, cdef, cdef0 + call extend(cdef, cdef0) + " TLogVAR 4.2, cdef + let ax = 3 + if a:0 >= 3 && a:3 != '' && stridx(a:3, '=') == -1 + let ax = 4 + let cdef.begin = a:3 + if a:0 >= 4 && a:4 != '' && stridx(a:4, '=') == -1 + let ax = 5 + let cdef.end = a:4 + endif + endif + " TLogVAR ax, a:0, a:000 + if a:0 >= ax + let cdef = extend(cdef, s:ParseArgs(lbeg, lend, commentMode, a:000[ax - 1 : -1])) + " TLogVAR 5, cdef + endif + if !empty(get(cdef, 'begin', '')) || !empty(get(cdef, 'end', '')) + let cdef.commentstring = s:EncodeCommentPart(get(cdef, 'begin', '')) + \ . '%s' + \ . s:EncodeCommentPart(get(cdef, 'end', '')) + endif + let commentMode = cdef.mode + " TLogVAR 2, commentMode + endif + if exists('s:temp_options') + let cdef = s:ExtendCDef(lbeg, lend, commentMode, cdef, s:temp_options) + " TLogVAR 6, cdef + " echom "DBG s:temp_options" string(s:temp_options) + unlet s:temp_options + endif + " TLogVAR 7, cdef + if has_key(cdef, 'whitespace') + call s:SetWhitespaceMode(cdef) + endif + if !empty(filter(['count', 'cbeg', 'cend', 'cmid'], 'has_key(cdef, v:val)')) + call s:RepeatCommentstring(cdef) + endif + " echom "DBG" string(a:000) + let cms0 = s:BlockGetCommentRx(cdef) + " TLogVAR cms0 + " make whitespace optional; this conflicts with comments that require some + " whitespace + let cmtCheck = substitute(cms0, '\([ ]\)', '\1\\?', 'g') + " turn commentstring into a search pattern + " TLogVAR cmtCheck + let cmtCheck = printf(cmtCheck, '\(\_.\{-}\)') + " TLogVAR cdef, cmtCheck + let s:cdef = cdef + " set commentMode and indentStr + let [lbeg, lend, indentStr, uncomment] = s:CommentDef(lbeg, lend, cmtCheck, commentMode, cbeg, cend) + " TLogVAR lbeg, lend, indentStr, uncomment + let col = get(s:cdef, 'col', -1) + if col >= 0 + let col -= 1 + let indent = len(indentStr) + if col > indent + let cms0 = repeat(' ', col - indent) . cms0 + " TLogVAR cms0 + else + let indentStr = repeat(' ', col) + endif + endif + if commentAnyway + let uncomment = 0 + endif + " go + " TLogVAR commentMode + if commentMode =~# 'B' + " We want a comment block + call s:CommentBlock(lbeg, lend, commentMode, uncomment, cmtCheck, s:cdef, indentStr) + else + " call s:CommentLines(lbeg, lend, cbeg, cend, uncomment, cmtCheck, cms0, indentStr) + " We want commented lines + " final search pattern for uncommenting + let cmtCheck = escape('\V\^\(\s\{-}\)'. cmtCheck .'\$', '"/\') + " final pattern for commenting + let cmtReplace = s:GetCommentReplace(s:cdef, cms0) + " TLogVAR cmtReplace + if get(s:cdef, 'mixedindent', 0) && !empty(indentStr) + let cbeg = strdisplaywidth(indentStr, cbeg) + let indentStr = '' + endif + " TLogVAR commentMode, lbeg, cbeg, lend, cend + let s:processline_lnum = lbeg + let cmd = lbeg .','. lend .'s/\V'. + \ s:StartPosRx(commentMode, lbeg, cbeg) . indentStr .'\zs\(\_.\{-}\)'. s:EndPosRx(commentMode, lend, cend) .'/'. + \ '\=s:ProcessLine('. uncomment .', submatch(0), "'. cmtCheck .'", "'. cmtReplace .'")/ge' + " TLogVAR cmd + exec cmd + call histdel('search', -1) + endif + " reposition cursor + " TLogVAR 3, commentMode + " echom "DBG s:cursor_pos" string(s:cursor_pos) + if !empty(s:cursor_pos) + let cursor_pos = s:cursor_pos + endif + if commentMode =~ '>' + call setpos('.', cursor_pos) + if commentMode !~ 'i' && commentMode =~ '>>' + norm! l^ + endif + elseif commentMode =~ '#' + call setpos('.', cursor_pos) + if exists('w:tcommentPos') + let w:tcommentPos = cursor_pos + endif + else + call setpos('.', s:current_pos) + endif + unlet! s:cursor_pos s:current_pos s:cdef +endf + + +function! tcomment#SetOption(name, arg) "{{{3 + " TLogVAR a:name, a:arg + if !exists('s:temp_options') + let s:temp_options = {} + endif + " if index(['count', 'as'], a:name) != -1 + if empty(a:arg) + if has_key(s:temp_options, a:name) + call remove(s:temp_options, a:name) + endif + else + let s:temp_options[a:name] = a:arg + endif + " endif +endf + + +function! s:GetStartEnd(beg, end, commentMode) "{{{3 + " TLogVAR a:beg, a:end, a:commentMode + if type(a:beg) == 3 + let [lbeg, cbeg] = a:beg + let [lend, cend] = a:end + else + let lbeg = a:beg + let lend = a:end + let commentMode = a:commentMode + " TLogVAR commentMode + if commentMode =~# 'R' + let cbeg = col('.') + let cend = 0 + let commentMode = substitute(commentMode, '\CR', 'G', 'g') + elseif commentMode =~# 'I' + let cbeg = col("'<") + if cbeg == 0 + let cbeg = col('.') + endif + let cend = col("'>") + if cend < col('$') && (commentMode =~# 'o' || &selection == 'inclusive') + let cend += 1 + " TLogVAR cend, col('$') + endif + else + let cbeg = 0 + let cend = 0 + endif + endif + " TLogVAR lbeg, cbeg, lend, cend + return [lbeg, cbeg, lend, cend] +endf + + +function! s:SetWhitespaceMode(cdef) "{{{3 + let mode = a:cdef.whitespace + let cms = s:BlockGetCommentString(a:cdef) + let mid = s:BlockGetMiddleString(a:cdef) + let cms0 = cms + let mid0 = mid + " TLogVAR mode, cms, mid + if mode =~ '^\(n\%[o]\|l\%[eft]\|r\%[ight]\)$' + if mode == 'no' || mode == 'right' + let cms = substitute(cms, '\s\+\ze%\@<!%s', '', 'g') + let mid = substitute(mid, '\s\+\ze%\@<!%s', '', 'g') + endif + if mode == 'no' || mode == 'left' + let cms = substitute(cms, '%\@<!%s\zs\s\+', '', 'g') + let mid = substitute(mid, '%\@<!%s\zs\s\+', '', 'g') + endif + elseif mode =~ '^\(b\%[oth]\)$' + let cms = substitute(cms, '\S\zs\ze%\@<!%s', ' ', 'g') + let mid = substitute(mid, '\S\zs\ze%\@<!%s', ' ', 'g') + let cms = substitute(cms, '%\@<!%s\zs\ze\S', ' ', 'g') + let mid = substitute(mid, '%\@<!%s\zs\ze\S', ' ', 'g') + endif + if cms != cms0 + " TLogVAR cms + let a:cdef.commentstring = cms + endif + if mid != mid0 + " TLogVAR mid + let a:cdef.middle = mid + endif + return a:cdef +endf + + +function! s:RepeatCommentstring(cdef) "{{{3 + " TLogVAR a:cdef + let cms = s:BlockGetCommentString(a:cdef) + let mid = s:BlockGetMiddleString(a:cdef) + let cms_fbeg = match(cms, '\s*%\@<!%s') + let cms_fend = matchend(cms, '%\@<!%s\s*') + let rxbeg = get(a:cdef, 'rxbeg', '^.*$') + let rxend = get(a:cdef, 'rxend', '^.*$') + let rpbeg = repeat('&', get(a:cdef, 'cbeg', get(a:cdef, 'count', 1))) + let rpend = repeat('&', get(a:cdef, 'cend', get(a:cdef, 'count', 1))) + let a:cdef.commentstring = substitute(cms[0 : cms_fbeg - 1], rxbeg, rpbeg, '') + \. cms[cms_fbeg : cms_fend - 1] + \. substitute(cms[cms_fend : -1], rxend, rpend, '') + " TLogVAR cms, a:cdef.commentstring + if !empty(mid) + let rxmid = get(a:cdef, 'rxmid', '^.*$') + let rpmid = repeat('&', get(a:cdef, 'cmid', get(a:cdef, 'count', 1))) + let a:cdef.middle = substitute(mid, rxmid, rpmid, '') + " TLogVAR mid, a:cdef.middle + endif + return a:cdef +endf + + +function! s:ParseArgs(beg, end, commentMode, arglist) "{{{3 + let args = {} + for arg in a:arglist + let key = matchstr(arg, '^[^=]\+') + let value = matchstr(arg, '=\zs.*$') + if !empty(key) + let args[key] = value + endif + endfor + return s:ExtendCDef(a:beg, a:end, a:commentMode, {}, args) +endf + + +function! s:ExtendCDef(beg, end, commentMode, cdef, args) + for [key, value] in items(a:args) + if key == 'as' + call extend(a:cdef, s:GetCommentDefinitionForType(a:beg, a:end, a:commentMode, value)) + elseif key == 'mode' + let a:cdef[key] = a:commentMode . value + elseif key == 'count' + let a:cdef[key] = str2nr(value) + else + let a:cdef[key] = value + endif + endfor + return a:cdef +endf + + +function! tcomment#Operator(type, ...) "{{{3 + let commentMode = a:0 >= 1 ? a:1 : '' + let bang = a:0 >= 2 ? a:2 : '' + " TLogVAR a:type, commentMode, bang + if !exists('w:tcommentPos') + let w:tcommentPos = getpos(".") + endif + let sel_save = &selection + set selection=inclusive + let reg_save = @@ + try + if a:type == 'line' + silent exe "normal! '[V']" + let commentMode1 = 'G' + elseif a:type == 'block' + silent exe "normal! `[\<C-V>`]" + let commentMode1 = 'I' + elseif a:type == 'char' && !g:tcomment#ignore_char_type + silent exe "normal! `[v`]" + let commentMode1 = 'I' + else + silent exe "normal! `[v`]" + let commentMode1 = 'i' + endif + if empty(commentMode) + let commentMode = commentMode1 + endif + let lbeg = line("'[") + let lend = line("']") + let cbeg = col("'[") + let cend = col("']") + " TLogVAR lbeg, lend, cbeg, cend + " echom "DBG tcomment#Operator" lbeg col("'[") col("'<") lend col("']") col("'>") + norm!  + let commentMode = s:AddModeExtra(commentMode, g:tcommentOpModeExtra, lbeg, lend) + if a:type =~ 'line\|block' || g:tcomment#ignore_char_type + call tcomment#Comment(lbeg, lend, commentMode.'o', bang) + else + call tcomment#Comment([lbeg, cbeg], [lend, cend], commentMode.'o', bang) + endif + finally + let &selection = sel_save + let @@ = reg_save + " TLogVAR g:tcommentOpModeExtra + if g:tcommentOpModeExtra !~ '[#>]' + if exists('w:tcommentPos') + " TLogVAR w:tcommentPos + if w:tcommentPos != getpos('.') + call setpos('.', w:tcommentPos) + endif + unlet! w:tcommentPos + else + echohl WarningMsg + echom "TComment: w:tcommentPos wasn't set. Please report this to the plugin author" + echohl NONE + endif + endif + endtry +endf + + +function! tcomment#OperatorLine(type) "{{{3 + call tcomment#Operator(a:type, 'G') +endf + + +function! tcomment#OperatorAnyway(type) "{{{3 + call tcomment#Operator(a:type, '', '!') +endf + + +function! tcomment#OperatorLineAnyway(type) "{{{3 + call tcomment#Operator(a:type, 'G', '!') +endf + + +" :display: tcomment#CommentAs(beg, end, commentAnyway, filetype, ?args...) +" Where args is either: +" 1. A count NUMBER +" 2. An args list (see the notes on the "args" argument of +" |tcomment#Comment()|) +" comment text as if it were of a specific filetype +function! tcomment#CommentAs(beg, end, commentAnyway, filetype, ...) + if a:filetype =~ '_block$' + let commentMode = 'B' + let ft = substitute(a:filetype, '_block$', '', '') + elseif a:filetype =~ '_inline$' + let commentMode = 'I' + let ft = substitute(a:filetype, '_inline$', '', '') + else + let commentMode = 'G' + let ft = a:filetype + endif + if a:0 >= 1 + if type(a:1) == 0 + let cdef = {'count': a:0 >= 1 ? a:1 : 1} + else + let cdef = s:ParseArgs(a:beg, a:end, commentMode, a:000) + endif + else + let cdef = {} + endif + " echom "DBG" string(cdef) + call extend(cdef, s:GetCommentDefinitionForType(a:beg, a:end, commentMode, ft)) + keepjumps call tcomment#Comment(a:beg, a:end, commentMode, a:commentAnyway, cdef) +endf + + +" collect all known comment types +" :nodoc: +function! tcomment#CollectFileTypes() + if s:typesDirty + let s:types = keys(s:definitions) + let s:typesRx = '\V\^\('. join(s:types, '\|') .'\)\(\u\.\*\)\?\$' + let s:typesDirty = 0 + endif +endf + +call tcomment#CollectFileTypes() + + +" return a list of filetypes for which a tcomment_{&ft} is defined +" :nodoc: +function! tcomment#Complete(ArgLead, CmdLine, CursorPos) "{{{3 + call tcomment#CollectFileTypes() + let completions = copy(s:types) + let filetype = s:Filetype() + if index(completions, filetype) != -1 + " TLogVAR filetype + call insert(completions, filetype) + endif + if !empty(a:ArgLead) + call filter(completions, 'v:val =~ ''\V\^''.a:ArgLead') + endif + let completions += tcomment#CompleteArgs(a:ArgLead, a:CmdLine, a:CursorPos) + return completions +endf + + +let s:first_completion = 0 + +" :nodoc: +function! tcomment#CompleteArgs(ArgLead, CmdLine, CursorPos) "{{{3 + if v:version < 703 && !s:first_completion + redraw + let s:first_completion = 1 + endif + let completions = ['as=', 'col=', 'count=', 'mode=', 'begin=', 'end=', 'rxbeg=', 'rxend=', 'rxmid='] + if !empty(a:ArgLead) + if a:ArgLead =~ '^as=' + call tcomment#CollectFileTypes() + let completions += map(copy(s:types), '"as=". v:val') + endif + call filter(completions, 'v:val =~ ''\V\^''.a:ArgLead') + endif + return completions +endf + + +function! s:EncodeCommentPart(string) + return substitute(a:string, '%', '%%', 'g') +endf + + +function! s:GetCommentDefinitionForType(beg, end, commentMode, filetype) "{{{3 + let cdef = s:GetCommentDefinition(a:beg, a:end, a:commentMode, a:filetype) + " TLogVAR cdef + let cms = cdef.commentstring + let commentMode = cdef.mode + let pre = substitute(cms, '%\@<!%s.*$', '', '') + let pre = substitute(pre, '%%', '%', 'g') + let post = substitute(cms, '^.\{-}%\@<!%s', '', '') + let post = substitute(post, '%%', '%', 'g') + let cdef.begin = pre + let cdef.end = post + return cdef +endf + + +" s:GetCommentDefinition(beg, end, commentMode, ?filetype="") +function! s:GetCommentDefinition(beg, end, commentMode, ...) + let ft = a:0 >= 1 ? a:1 : '' + " TLogVAR ft + if ft != '' + let cdef = s:GetCustomCommentString(ft, a:commentMode) + else + let cdef = {'mode': a:commentMode} + endif + " TLogVAR cdef + let cms = get(cdef, 'commentstring', '') + if empty(cms) + let filetype = s:Filetype(ft) + if exists('b:commentstring') + let cms = b:commentstring + " TLogVAR 1, cms + return s:GetCustomCommentString(filetype, a:commentMode, cms) + elseif exists('b:commentStart') && b:commentStart != '' + let cms = s:EncodeCommentPart(b:commentStart) .' %s' + " TLogVAR 2, cms + if exists('b:commentEnd') && b:commentEnd != '' + let cms = cms .' '. s:EncodeCommentPart(b:commentEnd) + endif + return s:GetCustomCommentString(filetype, a:commentMode, cms) + else + let [use_guess_ft, altFiletype] = s:AltFiletype(ft) + " TLogVAR use_guess_ft, altFiletype + if use_guess_ft + return s:GuessFileType(a:beg, a:end, a:commentMode, filetype, altFiletype) + else + return s:GetCustomCommentString(filetype, a:commentMode, s:GuessCurrentCommentString(a:commentMode)) + endif + endif + let cdef.commentstring = cms + endif + return cdef +endf + +function! s:StartPosRx(mode, line, col) + " TLogVAR a:mode, a:line, a:col + if a:mode =~# 'I' + let col = get(s:cdef, 'mixedindent', 0) ? a:col - 1 : a:col + return s:StartLineRx(a:line) . s:StartColRx(col) + else + return s:StartColRx(a:col) + endif +endf + +function! s:EndPosRx(mode, line, col) + if a:mode =~# 'I' + return s:EndLineRx(a:line) . s:EndColRx(a:col) + else + return s:EndColRx(a:col) + endif +endf + +function! s:StartLineRx(pos) + return '\%'. a:pos .'l' +endf + +function! s:EndLineRx(pos) + return '\%'. a:pos .'l' +endf + +function! s:StartColRx(pos) + if a:pos <= 1 + return '\^' + elseif get(s:cdef, 'mixedindent', 0) + return '\%>'. a:pos .'v' + else + return '\%'. a:pos .'c' + endif +endf + +function! s:EndColRx(pos) + if a:pos == 0 + return '\$' + else + return '\%'. a:pos .'c' + endif +endf + +function! s:GetIndentString(line, start) + let start = a:start > 0 ? a:start - 1 : 0 + return substitute(strpart(getline(a:line), start), '\V\^\s\*\zs\.\*\$', '', '') +endf + +function! s:CommentDef(beg, end, checkRx, commentMode, cstart, cend) + " TLogVAR a:beg, a:end, a:checkRx, a:commentMode, a:cstart, a:cend + let beg = a:beg + let end = a:end + let mdrx = '\V'. s:StartColRx(a:cstart) .'\s\*'. a:checkRx .'\s\*'. s:EndColRx(0) + " let mdrx = '\V'. s:StartPosRx(a:commentMode, beg, a:cstart) .'\s\*'. a:checkRx .'\s\*'. s:EndPosRx(a:commentMode, end, 0) + let line = getline(beg) + if a:cstart != 0 && a:cend != 0 + let line = strpart(line, 0, a:cend - 1) + endif + let uncomment = (line =~ mdrx) + " TLogVAR 1, uncomment + let indentStr = s:GetIndentString(beg, a:cstart) + let il = indent(beg) + let n = beg + 1 + while n <= end + if getline(n) =~ '\S' + let jl = indent(n) + if jl < il + let indentStr = s:GetIndentString(n, a:cstart) + let il = jl + endif + if a:commentMode =~# 'G' + if !(getline(n) =~ mdrx) + let uncomment = 0 + " TLogVAR 2, uncomment + endif + endif + endif + let n = n + 1 + endwh + if a:commentMode =~# 'B' + let t = @t + try + silent exec 'norm! '. beg.'G1|v'.end.'G$"ty' + if &selection == 'inclusive' && @t =~ '\n$' && len(@t) > 1 + let @t = @t[0 : -2] + endif + " TLogVAR @t, mdrx + let uncomment = (@t =~ mdrx) + " TLogVAR 3, uncomment + if !uncomment && a:commentMode =~ 'o' + let mdrx1 = substitute(mdrx, '\\$$', '\\n\\$', '') + " TLogVAR mdrx1 + if @t =~ mdrx1 + let uncomment = 1 + " TLogVAR 4, uncomment + " let end -= 1 + endif + endif + finally + let @t = t + endtry + endif + " TLogVAR 5, uncomment + return [beg, end, indentStr, uncomment] +endf + +function! s:ProcessLine(uncomment, match, checkRx, replace) + " TLogVAR a:uncomment, a:match, a:checkRx, a:replace + try + if !(a:match =~ '\S' || g:tcommentBlankLines) + return a:match + endif + let ml = len(a:match) + if a:uncomment + let rv = substitute(a:match, a:checkRx, '\1\2', '') + let rv = s:UnreplaceInLine(rv) + else + let rv = s:ReplaceInLine(a:match) + let rv = printf(a:replace, rv) + let strip_whitespace = get(s:cdef, 'strip_whitespace', 0) + if strip_whitespace == 2 || (strip_whitespace == 1 && ml == 0) + let rv = substitute(rv, '\s\+$', '', '') + endif + endif + " TLogVAR rv + " echom "DBG s:cdef.mode=" string(s:cdef.mode) "s:cursor_pos=" string(s:cursor_pos) + " let md = len(rv) - ml + if s:cdef.mode =~ '>' + let s:cursor_pos = getpos('.') + let s:cursor_pos[2] += len(rv) + elseif s:cdef.mode =~ '#' + if empty(s:cursor_pos) || s:current_pos[1] == s:processline_lnum + let prefix = matchstr(a:replace, '^.*%\@<!\ze%s') + let prefix = substitute(prefix, '%\(.\)', '\1', 'g') + let prefix_len = strdisplaywidth(prefix) + " TLogVAR a:replace, prefix_len + if prefix_len != -1 + let s:cursor_pos = copy(s:current_pos) + if a:uncomment + let s:cursor_pos[2] -= prefix_len + if s:cursor_pos[2] < 1 + let s:cursor_pos[2] = 1 + endif + else + let s:cursor_pos[2] += prefix_len + endif + " echom "DBG s:current_pos=" string(s:current_pos) "s:cursor_pos=" string(s:cursor_pos) + endif + endif + endif + " TLogVAR pe, md, a:match + " TLogVAR rv + if v:version > 702 || (v:version == 702 && has('patch407')) + let rv = escape(rv, "\r") + else + let rv = escape(rv, "\\r") + endif + " TLogVAR rv + " let rv = substitute(rv, '\n', '\\\n', 'g') + " TLogVAR rv + return rv + finally + let s:processline_lnum += 1 + endtry +endf + + +function! s:ReplaceInLine(text) "{{{3 + if has_key(s:cdef, 'replacements') + let replacements = s:cdef.replacements + return s:DoReplacements(a:text, keys(replacements), values(replacements)) + else + return a:text + endif +endf + + +function! s:UnreplaceInLine(text) "{{{3 + if has_key(s:cdef, 'replacements') + let replacements = s:cdef.replacements + return s:DoReplacements(a:text, values(replacements), keys(replacements)) + else + return a:text + endif +endf + + +function! s:DoReplacements(text, tokens, replacements) "{{{3 + if empty(a:tokens) + return a:text + else + let rx = '\V\('. join(map(a:tokens, 'escape(v:val, ''\'')'), '\|') .'\)' + let texts = split(a:text, rx .'\zs', 1) + let texts = map(texts, 's:InlineReplacement(v:val, rx, a:tokens, a:replacements)') + let text = join(texts, '') + return text + endif +endf + + +function! s:InlineReplacement(text, rx, tokens, replacements) "{{{3 + " TLogVAR a:text, a:rx, a:replacements + let matches = split(a:text, '\ze'. a:rx .'\$', 1) + if len(matches) == 1 + return a:text + else + let match = matches[-1] + let idx = index(a:tokens, match) + " TLogVAR matches, match, idx + if idx != -1 + let matches[-1] = a:replacements[idx] + " TLogVAR matches + return join(matches, '') + else + throw 'TComment: Internal error: cannot find '. string(match) .' in '. string(a:tokens) + endif + endif +endf + + +function! s:CommentBlock(beg, end, commentMode, uncomment, checkRx, cdef, indentStr) + " TLogVAR a:beg, a:end, a:uncomment, a:checkRx, a:cdef, a:indentStr + let t = @t + let sel_save = &selection + set selection=exclusive + try + silent exec 'norm! '. a:beg.'G1|v'.a:end.'G$"td' + " TLogVAR @t + let ms = s:BlockGetMiddleString(a:cdef) + let mx = escape(ms, '\') + let cs = s:BlockGetCommentString(a:cdef) + let prefix = substitute(matchstr(cs, '^.*%\@<!\ze%s'), '%\(.\)', '\1', 'g') + let postfix = substitute(matchstr(cs, '%\@<!%s\zs.*$'), '%\(.\)', '\1', 'g') + if a:uncomment + let @t = substitute(@t, '\V\^\s\*'. a:checkRx .'\$', '\1', '') + " TLogVAR 1, @t + if ms != '' + let @t = substitute(@t, '\V\n'. a:indentStr . mx, '\n'. a:indentStr, 'g') + " TLogVAR 2, @t + endif + let @t = substitute(@t, '^\n', '', '') + let @t = substitute(@t, '\n\s*$', '', '') + if a:commentMode =~ '#' + let s:cursor_pos = copy(s:current_pos) + let prefix_lines = len(substitute(prefix, "[^\n]", '', 'g')) + 1 + let postfix_lines = len(substitute(postfix, "[^\n]", '', 'g')) + 1 + " TODO: more precise solution (when cursor is placed on + " postfix or prefix + if s:cursor_pos[1] > a:beg + let s:cursor_pos[1] -= prefix_lines + if s:cursor_pos[1] > a:end - postfix_lines + let s:cursor_pos[1] -= postfix_lines + endif + if s:cursor_pos[1] < 1 + let s:cursor_pos[1] = 1 + endif + endif + let prefix_len = strdisplaywidth(mx) + let s:cursor_pos[2] -= prefix_len + if s:cursor_pos[2] < 1 + let s:cursor_pos[2] = 1 + endif + endif + else + let cs = a:indentStr . substitute(cs, '%\@<!%s', '%s'. a:indentStr, '') + if ms != '' + let ms = a:indentStr . ms + let mx = a:indentStr . mx + let @t = substitute(@t, '^'. a:indentStr, '', 'g') + let @t = ms . substitute(@t, '\n'. a:indentStr, '\n'. mx, 'g') + endif + let @t = printf(cs, "\n". @t ."\n") + if a:commentMode =~ '#' + let s:cursor_pos = copy(s:current_pos) + let s:cursor_pos[1] += len(substitute(prefix, "[^\n]", '', 'g')) + 1 + let prefix_len = strdisplaywidth(mx) + let s:cursor_pos[2] += prefix_len + " echom "DBG s:current_pos=" string(s:current_pos) "s:cursor_pos=" string(s:cursor_pos) + endif + endif + silent norm! "tP + finally + let &selection = sel_save + let @t = t + endtry +endf + + +function! s:Filetype(...) "{{{3 + let ft = a:0 >= 1 && !empty(a:1) ? a:1 : &filetype + let pos = a:0 >= 2 ? a:2 : 0 + " TLogVAR ft, pos + let fts = split(ft, '^\@!\.') + " TLogVAR fts + " let ft = substitute(ft, '\..*$', '', '') + let rv = get(fts, pos, ft) + " TLogVAR fts, rv + if !exists('s:filetype_map_rx') + let fts_rx = '^'. join(map(keys(g:tcomment#filetype_map), 'escape(v:val, ''\'')'), '\|') .'$' + endif + " TLogVAR fts_rx + if rv =~ fts_rx + for [ft_rx, ftrv] in items(g:tcomment#filetype_map) + " TLogVAR ft_rx, ftrv + if rv =~ ft_rx + let rv = substitute(rv, ft_rx, ftrv, '') + " TLogVAR rv + break + endif + endfor + endif + return rv +endf + + +function! s:AltFiletype(filetype) "{{{3 + let filetype = empty(a:filetype) ? &filetype : a:filetype + " TLogVAR a:filetype, filetype + if g:tcommentGuessFileType || (exists('g:tcommentGuessFileType_'. filetype) + \ && g:tcommentGuessFileType_{filetype} =~ '[^0]') + if g:tcommentGuessFileType_{filetype} == 1 + if filetype =~ '^.\{-}\..\+$' + let altFiletype = s:Filetype(filetype, 1) + else + let altFiletype = '' + endif + else + let altFiletype = g:tcommentGuessFileType_{filetype} + endif + " TLogVAR 1, altFiletype + return [1, altFiletype] + elseif filetype =~ '^.\{-}\..\+$' + let altFiletype = s:Filetype(filetype, 1) + " TLogVAR 2, altFiletype + return [1, altFiletype] + else + " TLogVAR 3, '' + return [0, ''] + endif +endf + + +" A function that makes the s:GuessFileType() function usable for other +" library developers. +" +" The argument is a dictionary with the following keys: +" +" beg ................ (default = line(".")) +" end ................ (default = line(".")) +" commentMode ........ (default = "G") +" filetype ........... (default = &filetype) +" fallbackFiletype ... (default = "") +" +" This function return a dictionary that contains information about how +" to make comments. The information about the filetype of the text +" between lines "beg" and "end" is in the "filetype" key of the return +" value. It returns the first discernible filetype it encounters. +" :display: tcomment#GuessFileType(?options={}) +function! tcomment#GuessCommentType(...) "{{{3 + let options = a:0 >= 1 ? a:1 : {} + let beg = get(options, 'beg', line('.')) + let end = get(options, 'end', line('.')) + let commentMode = get(options, 'commentMode', '') + let filetype = get(options, 'filetype', &filetype) + let fallbackFiletype = get(options, 'filetype', '') + return s:GuessFileType(beg, end, commentMode, filetype, fallbackFiletype) +endf + + +" inspired by Meikel Brandmeyer's EnhancedCommentify.vim +" this requires that a syntax names are prefixed by the filetype name +" s:GuessFileType(beg, end, commentMode, filetype, ?fallbackFiletype) +function! s:GuessFileType(beg, end, commentMode, filetype, ...) + " TLogVAR a:beg, a:end, a:commentMode, a:filetype, a:000 + " TLogVAR cdef + let cdef0 = s:GetCustomCommentString(a:filetype, a:commentMode) + if a:0 >= 1 && a:1 != '' + let cdef = s:GetCustomCommentString(a:1, a:commentMode) + " TLogVAR 0, cdef + let cdef = extend(cdef, cdef0, 'keep') + " TLogVAR 1, cdef + if empty(get(cdef, 'commentstring', '')) + let cdef.commentstring = s:GuessCurrentCommentString(a:commentMode) + endif + " TLogVAR 2, cdef + else + let cdef = cdef0 + if !has_key(cdef, 'commentstring') + let cdef = {'commentstring': s:GuessCurrentCommentString(0), 'mode': s:GuessCommentMode(a:commentMode)} + endif + endif + let beg = a:beg + let end = nextnonblank(a:end) + if end == 0 + let end = a:end + let beg = prevnonblank(a:beg) + if beg == 0 + let beg = a:beg + endif + endif + let n = beg + " TLogVAR n, beg, end + while n <= end + let m = indent(n) + 1 + let text = getline(n) + let le = len(text) + " TLogVAR m, le + while m <= le + let syntaxName = s:GetSyntaxName(n, m) + " TLogVAR syntaxName, n, m + let ftypeMap = get(g:tcommentSyntaxMap, syntaxName, '') + " TLogVAR ftypeMap + if !empty(ftypeMap) && type(ftypeMap) == 4 + if n < a:beg + let key = 'prevnonblank' + elseif n > a:end + let key = 'nextnonblank' + else + let key = '' + endif + if empty(key) || !has_key(ftypeMap, key) + let ftypeftype = get(ftypeMap, 'filetype', {}) + " TLogVAR ftypeMap, ftypeftype + unlet! ftypeMap + let ftypeMap = get(ftypeftype, a:filetype, '') + else + let mapft = '' + for mapdef in ftypeMap[key] + if strpart(text, m - 1) =~ '^'. mapdef.match + let mapft = mapdef.filetype + break + endif + endfor + unlet! ftypeMap + if empty(mapft) + let ftypeMap = '' + else + let ftypeMap = mapft + endif + endif + endif + if !empty(ftypeMap) + " TLogVAR ftypeMap + return s:GetCustomCommentString(ftypeMap, a:commentMode, cdef.commentstring) + elseif syntaxName =~ s:typesRx + let ft = substitute(syntaxName, s:typesRx, '\1', '') + " TLogVAR ft + if exists('g:tcommentIgnoreTypes_'. a:filetype) && g:tcommentIgnoreTypes_{a:filetype} =~ '\<'.ft.'\>' + let m += 1 + else + return s:GetCustomCommentString(ft, a:commentMode, cdef.commentstring) + endif + elseif syntaxName == '' || syntaxName == 'None' || syntaxName =~ '^\u\+$' || syntaxName =~ '^\u\U*$' + let m += 1 + else + break + endif + endwh + let n += 1 + endwh + " TLogVAR cdef + return cdef +endf + + +function! s:GetSyntaxName(lnum, col) "{{{3 + let syntaxName = synIDattr(synID(a:lnum, a:col, 1), 'name') + if !empty(g:tcomment#syntax_substitute) + for [rx, subdef] in items(g:tcomment#syntax_substitute) + if !has_key(subdef, 'if') || eval(subdef.if) + let syntaxName = substitute(syntaxName, rx, subdef.sub, 'g') + endif + endfor + endif + " TLogVAR syntaxName + return syntaxName +endf + + +function! s:AddModeExtra(mode, extra, beg, end) "{{{3 + if a:beg == a:end + let extra = substitute(a:extra, '\C[B]', '', 'g') + else + let extra = substitute(a:extra, '\C[IR]', '', 'g') + endif + let mode = a:mode + if extra =~# 'B' + let mode = substitute(mode, '\c[gir]', '', 'g') + endif + if extra =~# '[IR]' + let mode = substitute(mode, '\c[gb]', '', 'g') + endif + let rv = mode . extra + " TLogVAR a:mode, a:extra, mode, extra, rv + return rv +endf + + +function! s:GuessCommentMode(commentMode) "{{{3 + if a:commentMode =~# '[IRB]' + return a:commentMode + else + return substitute(a:commentMode, '\w\+', 'G', 'g') + endif +endf + +function! s:GuessCurrentCommentString(commentMode) + " TLogVAR a:commentMode + let valid_cms = (match(&commentstring, '%\@<!%s') != -1) + if &commentstring != s:defaultCommentString && valid_cms + " The &commentstring appears to have been set and to be valid + return &commentstring + endif + if &comments != s:defaultComments + " the commentstring is the default one, so we assume that it wasn't + " explicitly set; we then try to reconstruct &cms from &comments + let cms = s:ConstructFromComments(a:commentMode) + if cms != s:nullCommentString + return cms + endif + endif + if valid_cms + " Before &commentstring appeared not to be set. As we don't know + " better we return it anyway if it is valid + return &commentstring + else + " &commentstring is invalid. So we return the identity string. + return s:nullCommentString + endif +endf + +function! s:ConstructFromComments(commentMode) + exec s:ExtractCommentsPart('') + if a:commentMode =~# 'G' && line != '' + return line .' %s' + endif + exec s:ExtractCommentsPart('s') + if s != '' + exec s:ExtractCommentsPart('e') + return s.' %s '.e + endif + if line != '' + return line .' %s' + else + return s:nullCommentString + endif +endf + +function! s:ExtractCommentsPart(key) + " let key = a:key != "" ? a:key .'[^:]*' : "" + let key = a:key . '[bnflrxO0-9-]*' + let val = substitute(&comments, '^\(.\{-},\)\{-}'. key .':\([^,]\+\).*$', '\2', '') + if val == &comments + let val = '' + else + let val = substitute(val, '%', '%%', 'g') + endif + let var = a:key == '' ? 'line' : a:key + return 'let '. var .'="'. escape(val, '"') .'"' +endf + +" s:GetCustomCommentString(ft, commentMode, ?default="") +function! s:GetCustomCommentString(ft, commentMode, ...) + " TLogVAR a:ft, a:commentMode, a:000 + let commentMode = a:commentMode + let customComment = tcomment#TypeExists(a:ft) + if commentMode =~# 'B' && tcomment#TypeExists(a:ft .'_block') + let def = s:definitions[a:ft .'_block'] + " TLogVAR 1, def + elseif commentMode =~? 'I' && tcomment#TypeExists(a:ft .'_inline') + let def = s:definitions[a:ft .'_inline'] + " TLogVAR 2, def + elseif customComment + let def = s:definitions[a:ft] + let commentMode = s:GuessCommentMode(commentMode) + " TLogVAR 3, def + elseif a:0 >= 1 + let def = {'commentstring': a:1} + let commentMode = s:GuessCommentMode(commentMode) + " TLogVAR 4, def + else + let def = {} + let commentMode = s:GuessCommentMode(commentMode) + " TLogVAR 5, def + endif + let cdef = copy(def) + let cdef.mode = commentMode + let cdef.filetype = a:ft + " TLogVAR cdef + return cdef +endf + +function! s:GetCommentReplace(cdef, cms0) + if has_key(a:cdef, 'commentstring_rx') + let rs = s:BlockGetCommentString(a:cdef) + else + let rs = a:cms0 + endif + return escape(rs, '"/') +endf + +function! s:BlockGetCommentRx(cdef) + if has_key(a:cdef, 'commentstring_rx') + return a:cdef.commentstring_rx + else + let cms0 = s:BlockGetCommentString(a:cdef) + let cms0 = escape(cms0, '\') + return cms0 + endif +endf + +function! s:BlockGetCommentString(cdef) + if has_key(a:cdef, 'middle') + return a:cdef.commentstring + else + return matchstr(a:cdef.commentstring, '^.\{-}\ze\(\n\|$\)') + endif +endf + +function! s:BlockGetMiddleString(cdef) + if has_key(a:cdef, 'middle') + return a:cdef.middle + else + return matchstr(a:cdef.commentstring, '\n\zs.*') + endif +endf + + +function! tcomment#TextObjectInlineComment() "{{{3 + let cdef = tcomment#GuessCommentType({'commentMode': 'I'}) + let cms = escape(cdef.commentstring, '\') + let pos = getpos('.') + let lnum = pos[1] + let col = pos[2] + let cmtf = '\V'. printf(cms, '\.\{-}\%'. lnum .'l\%'. col .'c\.\{-}') + " TLogVAR cmtf, search(cmtf,'cwn') + if search(cmtf, 'cw') > 0 + let pos0 = getpos('.') + if search(cmtf, 'cwe') > 0 + let pos1 = getpos('.') + exec 'norm!' + \ pos0[1].'gg'.pos0[2].'|v'. + \ pos1[1].'gg'.pos1[2].'|'. + \ (&sel == 'exclusive' ? 'l' : '') + endif + endif +endf + + +" vi: ft=vim:tw=72:ts=4:fo=w2croql diff --git a/vim/bundle/tcomment/doc/tcomment.txt b/vim/bundle/tcomment/doc/tcomment.txt @@ -0,0 +1,495 @@ +*tcomment.txt* An easily extensible & universal comment plugin + Author: Thomas Link, micathom AT gmail com?subject=vim + +tcomment provides easy to use, file-type sensible comments for Vim. It +can handle embedded syntax. + +TComment works like a toggle, i.e., it will comment out text that +contains uncommented lines, and it will remove comment markup for +already commented text (i.e. text that contains no uncommented lines). + +If the file-type is properly defined, TComment will figure out which +comment string to use. Otherwise you use |tcomment#DefineType()| to +override the default choice. + +TComment can properly handle an embedded syntax, e.g., ruby/python/perl +regions in vim scripts, HTML or JavaScript in php code etc. + +tcomment favours the use of line-wise comment styles. This implies that usually +whole line will be commented out. tcomment also knows block-style and inline +comments that can be used via special maps (see below) or the |:TCommentAs| +command. + +Demo: +http://vimsomnia.blogspot.com/2010/11/tcomment-vim-plugin.html + + + *tcomment-maps* +Key bindings~ + +Most of the time the default toggle keys will do what you want (or to be +more precise: what I think you want it to do ;-). + + *tcomment-operator* +As operator (the prefix can be customized via |g:tcommentMapLeaderOp1| +and |g:tcommentMapLeaderOp2|): + + gc{motion} :: Toggle comments (for small comments within one line + the &filetype_inline style will be used, if + defined) + gc<Count>c{motion} :: Toggle comment text with count argument + (see |tcomment#Comment()|) + gcc :: Toggle comment for the current line + gC{motion} :: Comment region + gCc :: Comment the current line + +In visual mode: + + gc :: Toggle comments + gC :: Comment selected text + +CAVEAT: If you visually select text within a line, the visual mode map will +comment out the selected text. If you selected text across several lines, the +visual mode map will assume though that you wanted to comment out lines -- +since this is how many vim maps work. In order to make tcomment use e.g. inline +comments anyway, use the <c-_>i map -- see below. + +By default the cursor stays put. If you want the cursor to the end of +the commented text, set |g:tcommentOpModeExtra| to '>' (but this may not +work properly with exclusive motions). + +Primary key maps for normal and insert mode: + + <c-_><c-_> :: :TComment + <c-_><space> :: :TComment <QUERY COMMENT-BEGIN ?COMMENT-END> + <c-_>b :: :TCommentBlock + <c-_>a :: :TCommentAs <QUERY COMMENT TYPE> + <c-_>n :: :TCommentAs &filetype <QUERY COUNT> + <c-_>s :: :TCommentAs &filetype_<QUERY COMMENT SUBTYPE> + <c-_>i :: :TCommentInline (in normal and insert mode, this map will + create an empty inline comment, which isn't suitable for + all filetypes though) + <c-_>r :: :TCommentRight + <c-_>p :: Comment the current inner paragraph + <c-_><Count> :: :TComment with count argument (a number from 1 to 9) + (see |tcomment#Comment()|) + +Primary key maps for visual mode: + + <c-_><c-_> :: :TComment + <c-_>i :: :TCommentInline + <c-_><Count> :: :TComment with count argument (a number from 1 to 9) + (see |tcomment#Comment()|) + +A secondary set of key maps is defined for normal and insert mode: + + <Leader>__ :: :TComment + <Leader>_p :: Comment the current inner paragraph + <Leader>_<space> :: :TComment <QUERY COMMENT-BEGIN ?COMMENT-END> + <Leader>_i :: :TCommentInline + <Leader>_r :: :TCommentRight + <Leader>_b :: :TCommentBlock + <Leader>_a :: :TCommentAs <QUERY COMMENT TYPE> + <Leader>_n :: :TCommentAs &filetype <QUERY COUNT> + <Leader>_s :: :TCommentAs &filetype_<QUERY COMMENT SUBTYPE> + +... and for select mode: + + <Leader>__ :: :TComment + <Leader>_i :: :TCommentInline + + +----------------------------------------------------------------------- +Install~ + +Edit the vba file and type: > + + :so % + +See :help vimball for details. If you have difficulties or use vim 7.0, +please make sure, you have the current version of vimball (vimscript +#1502) installed or update your runtime. + + +======================================================================== +Contents~ + + g:tcommentMaps ...................... |g:tcommentMaps| + g:tcommentMapLeader1 ................ |g:tcommentMapLeader1| + g:tcommentMapLeader2 ................ |g:tcommentMapLeader2| + g:tcommentMapLeaderOp1 .............. |g:tcommentMapLeaderOp1| + g:tcommentMapLeaderOp2 .............. |g:tcommentMapLeaderOp2| + :TComment ........................... |:TComment| + :TCommentAs ......................... |:TCommentAs| + :TCommentRight ...................... |:TCommentRight| + :TCommentBlock ...................... |:TCommentBlock| + :TCommentInline ..................... |:TCommentInline| + :TCommentMaybeInline ................ |:TCommentMaybeInline| + g:tcommentBlankLines ................ |g:tcommentBlankLines| + g:tcommentModeExtra ................. |g:tcommentModeExtra| + g:tcommentOpModeExtra ............... |g:tcommentOpModeExtra| + g:tcommentOptions ................... |g:tcommentOptions| + g:tcomment#ignore_char_type ......... |g:tcomment#ignore_char_type| + g:tcommentGuessFileType ............. |g:tcommentGuessFileType| + g:tcommentGuessFileType_dsl ......... |g:tcommentGuessFileType_dsl| + g:tcommentGuessFileType_php ......... |g:tcommentGuessFileType_php| + g:tcommentGuessFileType_html ........ |g:tcommentGuessFileType_html| + g:tcommentGuessFileType_tskeleton ... |g:tcommentGuessFileType_tskeleton| + g:tcommentGuessFileType_vim ......... |g:tcommentGuessFileType_vim| + g:tcommentGuessFileType_django ...... |g:tcommentGuessFileType_django| + g:tcommentGuessFileType_eruby ....... |g:tcommentGuessFileType_eruby| + g:tcommentGuessFileType_smarty ...... |g:tcommentGuessFileType_smarty| + g:tcommentIgnoreTypes_php ........... |g:tcommentIgnoreTypes_php| + g:tcomment#syntax_substitute ........ |g:tcomment#syntax_substitute| + g:tcommentSyntaxMap ................. |g:tcommentSyntaxMap| + g:tcomment#replacements_c ........... |g:tcomment#replacements_c| + g:tcommentInlineC ................... |g:tcommentInlineC| + g:tcommentBlockC2 ................... |g:tcommentBlockC2| + g:tcomment#replacements_xml ......... |g:tcomment#replacements_xml| + g:tcommentBlockXML .................. |g:tcommentBlockXML| + g:tcommentInlineXML ................. |g:tcommentInlineXML| + tcomment#DefineType ................. |tcomment#DefineType()| + g:tcomment_types .................... |g:tcomment_types| + tcomment#Comment .................... |tcomment#Comment()| + tcomment#SetOption .................. |tcomment#SetOption()| + tcomment#Operator ................... |tcomment#Operator()| + tcomment#OperatorLine ............... |tcomment#OperatorLine()| + tcomment#OperatorAnyway ............. |tcomment#OperatorAnyway()| + tcomment#OperatorLineAnyway ......... |tcomment#OperatorLineAnyway()| + tcomment#CommentAs .................. |tcomment#CommentAs()| + tcomment#GuessCommentType ........... |tcomment#GuessCommentType()| + + +======================================================================== +plugin/tcomment.vim~ + + *g:tcommentMaps* +g:tcommentMaps (default: 1) + If true, set maps. + + *g:tcommentMapLeader1* +g:tcommentMapLeader1 (default: '<c-_>') + g:tcommentMapLeader1 should be a shortcut that can be used with + map, imap, vmap. + + *g:tcommentMapLeader2* +g:tcommentMapLeader2 (default: '<Leader>_') + g:tcommentMapLeader2 should be a shortcut that can be used with + map, xmap. + + *g:tcommentMapLeaderOp1* +g:tcommentMapLeaderOp1 (default: 'gc') + See |tcomment-operator|. + + *g:tcommentMapLeaderOp2* +g:tcommentMapLeaderOp2 (default: 'gC') + See |tcomment-operator|. + + *:TComment* +:[range]TComment[!] ?ARGS... + If there is a visual selection that begins and ends in the same line, + then |:TCommentInline| is used instead. + The optional range defaults to the current line. With a bang '!', + always comment the line. + + ARGS... are either (see also |tcomment#Comment()|): + 1. a list of key=value pairs + 2. 1-2 values for: ?commentBegin, ?commentEnd + + *:TCommentAs* +:[range]TCommentAs[!] commenttype ?ARGS... + TCommentAs requires g:tcomment_{filetype} to be defined. + With a bang '!', always comment the line. + + ARGS... are either (see also |tcomment#Comment()|): + 1. a list of key=value pairs + 2. 1-2 values for: ?commentBegin, ?commentEnd + + *:TCommentRight* +:[range]TCommentRight[!] ?ARGS... + Comment the text to the right of the cursor. If a visual selection was + made (be it block-wise or not), all lines are commented out at from + the current cursor position downwards. + With a bang '!', always comment the line. + + ARGS... are either (see also |tcomment#Comment()|): + 1. a list of key=value pairs + 2. 1-2 values for: ?commentBegin, ?commentEnd + + *:TCommentBlock* +:[range]TCommentBlock[!] ?ARGS... + Comment as "block", e.g. use the {&ft}_block comment style. The + commented text isn't indented or reformated. + With a bang '!', always comment the line. + + ARGS... are either (see also |tcomment#Comment()|): + 1. a list of key=value pairs + 2. 1-2 values for: ?commentBegin, ?commentEnd + + *:TCommentInline* +:[range]TCommentInline[!] ?ARGS... + Use the {&ft}_inline comment style. + With a bang '!', always comment the line. + + ARGS... are either (see also |tcomment#Comment()|): + 1. a list of key=value pairs + 2. 1-2 values for: ?commentBegin, ?commentEnd + + *:TCommentMaybeInline* +:[range]TCommentMaybeInline[!] ?ARGS... + With a bang '!', always comment the line. + + ARGS... are either (see also |tcomment#Comment()|): + 1. a list of key=value pairs + 2. 1-2 values for: ?commentBegin, ?commentEnd + + +======================================================================== +autoload/tcomment.vim~ + + *g:tcommentBlankLines* +g:tcommentBlankLines (default: 1) + If true, comment blank lines too + + *g:tcommentModeExtra* +g:tcommentModeExtra (default: '') + Modifies how commenting works. + > ... Move the cursor to the end of the comment + >> ... Like above but move the cursor to the next line + # ... Move the cursor to the position of the commented text + (NOTE: this only works when creating empty comments using + |:TCommentInline| from normal or insert mode and should + not be set here as a global option.) + + *g:tcommentOpModeExtra* +g:tcommentOpModeExtra (default: '') + Modifies how the operator works. + See |g:tcommentModeExtra| for a list of possible values. + + *g:tcommentOptions* +g:tcommentOptions (default: {}) + Other key-value options used by |tcomment#Comment()|. + + Example: If you want to put the opening comment marker always in + the first column regardless of the block's indentation, put this + into your |vimrc| file: > + let g:tcommentOptions = {'col': 1} +< + + *g:tcomment#ignore_char_type* +g:tcomment#ignore_char_type (default: 1) + |text-objects| for use with |tcomment#Operator| can have different + types: line, block, char etc. Text objects like aB, it, at etc. + have type char but this may not work reliably. By default, + tcomment handles those text objects most often as if they were of + type line. Set this variable to 0 in order to change this + behaviour. Be prepared that the result may not always match your + intentions. + + *g:tcommentGuessFileType* +g:tcommentGuessFileType (default: 0) + Guess the file type based on syntax names always or for some fileformat only + If non-zero, try to guess filetypes. + tcomment also checks g:tcommentGuessFileType_{&filetype} for + filetype specific values. + + Values: + 0 ... don't guess + 1 ... guess + FILETYPE ... assume this filetype + + *g:tcommentGuessFileType_dsl* +g:tcommentGuessFileType_dsl (default: 'xml') + For dsl documents, assume filetype = xml. + + *g:tcommentGuessFileType_php* +g:tcommentGuessFileType_php (default: 'html') + In php documents, the php part is usually marked as phpRegion. We + thus assume that the buffers default comment style isn't php but + html. + + *g:tcommentGuessFileType_html* +g:tcommentGuessFileType_html (default: 1) + + *g:tcommentGuessFileType_tskeleton* +g:tcommentGuessFileType_tskeleton (default: 1) + + *g:tcommentGuessFileType_vim* +g:tcommentGuessFileType_vim (default: 1) + + *g:tcommentGuessFileType_django* +g:tcommentGuessFileType_django (default: 1) + + *g:tcommentGuessFileType_eruby* +g:tcommentGuessFileType_eruby (default: 1) + + *g:tcommentGuessFileType_smarty* +g:tcommentGuessFileType_smarty (default: 1) + + *g:tcommentIgnoreTypes_php* +g:tcommentIgnoreTypes_php (default: 'sql') + In php files, some syntax regions are wrongly highlighted as sql + markup. We thus ignore sql syntax when guessing the filetype in + php files. + + *g:tcomment#syntax_substitute* +g:tcomment#syntax_substitute (default: {...}) + + *g:tcommentSyntaxMap* +g:tcommentSyntaxMap (default: {...}) + tcomment guesses filetypes based on the name of the current syntax + region. This works well if the syntax names match + /filetypeSomeName/. Other syntax names have to be explicitly + mapped onto the corresponding filetype. + + *g:tcomment#replacements_c* +g:tcomment#replacements_c (default: {...}) + Replacements for c filetype. + + *g:tcommentInlineC* +g:tcommentInlineC (default: {...}) + Generic c-like comments. + + *g:tcommentBlockC2* +g:tcommentBlockC2 (default: {...}) + Generic c-like block comments. + Generic c-like block comments (alternative markup). + + *g:tcomment#replacements_xml* +g:tcomment#replacements_xml (default: {...}) + Replacements for xml filetype. + + *g:tcommentBlockXML* +g:tcommentBlockXML (default: {...}) + Generic xml-like block comments. + + *g:tcommentInlineXML* +g:tcommentInlineXML (default: {...}) + Generic xml-like comments. + + *tcomment#DefineType()* +tcomment#DefineType(name, commentdef) + If you don't explicitly define a comment style, |:TComment| will use + 'commentstring' instead. We override the default values here in order + to have a blank after the comment marker. Block comments work only if + we explicitly define the markup. + + NAME usually is a 'filetype'. You can use special suffixes to define + special comment types. E.g. the name "FILETYPE_block" is used for + block comments for 'filetype'. The name "FILETYPE_inline" is used for + inline comments. If no specialized comment definition exists, the + normal one with name "FILETYPE" is used. + + The comment definition can be either a string or a dictionary. + + If it is a string: + The format for block comments is similar to 'commentstrings' with the + exception that the format strings for blocks can contain a second line + that defines how "middle lines" (see :h format-comments) should be + displayed. + + Example: If the string is "--%s--\n-- ", lines will be commented as + "--%s--" but the middle lines in block comments will be commented as + "--%s". + + If it is a dictionary: + See the help on the args argument of |tcomment#Comment| (see item 1, + args is a list of key=value pairs) to find out which fields can be + used. + + *g:tcomment_types* +g:tcomment_types (default: {}) + A dictionary of NAME => COMMENT DEFINITION (see |tcomment#DefineType|) + that can be set in vimrc to override tcomment's default comment + styles. + + + + *tcomment#Comment()* +tcomment#Comment(beg, end, ...) + tcomment#Comment(line1, line2, ?commentMode, ?commentAnyway, ?args...) + args... are either: + 1. a list of key=value pairs where known keys are (see also + |g:tcommentOptions|): + as=STRING ... Use a specific comment definition + count=N ... Repeat the comment string N times + col=N ... Start the comment at column N (in block + mode; must be smaller than |indent()|) + mode=STRING ... See the notes below on the "commentMode" argument + mode_extra=STRING ... Add to commentMode + begin=STRING ... Comment prefix + end=STRING ... Comment postfix + middle=STRING ... Middle line comments in block mode + rxbeg=N ... Regexp to find the substring of "begin" + that should be multiplied by "count" + rxend=N ... The above for "end" + rxmid=N ... The above for "middle" + mixedindent=BOOL ... If true, allow use of mixed + characters for indentation + commentstring_rx ... A regexp format string that matches + commented lines (no new groups may be + introduced, the |regexp| is |\V|; % have + to be doubled); "commentstring", "begin" + and optionally "end" must be defined or + deducible. + strip_whitespace ... Strip trailing whitespace: if 1, strip + from empty lines only, if 2, always strip + whitespace + 2. 1-2 values for: ?commentPrefix, ?commentPostfix + 3. a dictionary (internal use only) + + commentMode (see also ¦g:tcommentModeExtra¦): + G ... guess the value of commentMode + B ... block (use extra lines for the comment markers) + i ... maybe inline, guess + I ... inline + R ... right (comment the line right of the cursor) + v ... visual + o ... operator + By default, each line in range will be commented by adding the comment + prefix and postfix. + + *tcomment#SetOption()* +tcomment#SetOption(name, arg) + + *tcomment#Operator()* +tcomment#Operator(type, ...) + + *tcomment#OperatorLine()* +tcomment#OperatorLine(type) + + *tcomment#OperatorAnyway()* +tcomment#OperatorAnyway(type) + + *tcomment#OperatorLineAnyway()* +tcomment#OperatorLineAnyway(type) + + *tcomment#CommentAs()* +tcomment#CommentAs(beg, end, commentAnyway, filetype, ?args...) + Where args is either: + 1. A count NUMBER + 2. An args list (see the notes on the "args" argument of + |tcomment#Comment()|) + comment text as if it were of a specific filetype + + *tcomment#GuessCommentType()* +tcomment#GuessFileType(?options={}) + A function that makes the s:GuessFileType() function usable for other + library developers. + + The argument is a dictionary with the following keys: + + beg ................ (default = line(".")) + end ................ (default = line(".")) + commentMode ........ (default = "G") + filetype ........... (default = &filetype) + fallbackFiletype ... (default = "") + + This function return a dictionary that contains information about how + to make comments. The information about the filetype of the text + between lines "beg" and "end" is in the "filetype" key of the return + value. It returns the first discernible filetype it encounters. + + + +vim:tw=78:fo=tcq2:isk=!-~,^*,^|,^":ts=8:ft=help:norl: diff --git a/vim/bundle/tcomment/plugin/tcomment.vim b/vim/bundle/tcomment/plugin/tcomment.vim @@ -0,0 +1,177 @@ +" tComment.vim -- An easily extensible & universal comment plugin +" @Author: Tom Link (micathom AT gmail com) +" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) +" @Created: 27-Dez-2004. +" @Last Change: 2012-11-26. +" @Revision: 777 +" GetLatestVimScripts: 1173 1 tcomment.vim + +if &cp || exists('loaded_tcomment') + finish +endif +let loaded_tcomment = 208 + +if !exists('g:tcommentMaps') + " If true, set maps. + let g:tcommentMaps = 1 "{{{2 +endif + +if !exists("g:tcommentMapLeader1") + " g:tcommentMapLeader1 should be a shortcut that can be used with + " map, imap, vmap. + let g:tcommentMapLeader1 = '<c-_>' "{{{2 +endif + +if !exists("g:tcommentMapLeader2") + " g:tcommentMapLeader2 should be a shortcut that can be used with + " map, xmap. + let g:tcommentMapLeader2 = '<Leader>_' "{{{2 +endif + +if !exists("g:tcommentMapLeaderOp1") + " See |tcomment-operator|. + let g:tcommentMapLeaderOp1 = 'gc' "{{{2 +endif + +if !exists("g:tcommentMapLeaderOp2") + " See |tcomment-operator|. + let g:tcommentMapLeaderOp2 = 'gC' "{{{2 +endif + +if !exists('g:tcommentTextObjectInlineComment') + let g:tcommentTextObjectInlineComment = 'ic' "{{{2 +endif + + +" :display: :[range]TComment[!] ?ARGS... +" If there is a visual selection that begins and ends in the same line, +" then |:TCommentInline| is used instead. +" The optional range defaults to the current line. With a bang '!', +" always comment the line. +" +" ARGS... are either (see also |tcomment#Comment()|): +" 1. a list of key=value pairs +" 2. 1-2 values for: ?commentBegin, ?commentEnd +command! -bang -range -nargs=* -complete=customlist,tcomment#CompleteArgs TComment + \ keepjumps call tcomment#Comment(<line1>, <line2>, 'G', "<bang>", <f-args>) + +" :display: :[range]TCommentAs[!] commenttype ?ARGS... +" TCommentAs requires g:tcomment_{filetype} to be defined. +" With a bang '!', always comment the line. +" +" ARGS... are either (see also |tcomment#Comment()|): +" 1. a list of key=value pairs +" 2. 1-2 values for: ?commentBegin, ?commentEnd +command! -bang -complete=customlist,tcomment#Complete -range -nargs=+ TCommentAs + \ call tcomment#CommentAs(<line1>, <line2>, "<bang>", <f-args>) + +" :display: :[range]TCommentRight[!] ?ARGS... +" Comment the text to the right of the cursor. If a visual selection was +" made (be it block-wise or not), all lines are commented out at from +" the current cursor position downwards. +" With a bang '!', always comment the line. +" +" ARGS... are either (see also |tcomment#Comment()|): +" 1. a list of key=value pairs +" 2. 1-2 values for: ?commentBegin, ?commentEnd +command! -bang -range -nargs=* -complete=customlist,tcomment#CompleteArgs TCommentRight + \ keepjumps call tcomment#Comment(<line1>, <line2>, 'R', "<bang>", <f-args>) + +" :display: :[range]TCommentBlock[!] ?ARGS... +" Comment as "block", e.g. use the {&ft}_block comment style. The +" commented text isn't indented or reformated. +" With a bang '!', always comment the line. +" +" ARGS... are either (see also |tcomment#Comment()|): +" 1. a list of key=value pairs +" 2. 1-2 values for: ?commentBegin, ?commentEnd +command! -bang -range -nargs=* -complete=customlist,tcomment#CompleteArgs TCommentBlock + \ keepjumps call tcomment#Comment(<line1>, <line2>, 'B', "<bang>", <f-args>) + +" :display: :[range]TCommentInline[!] ?ARGS... +" Use the {&ft}_inline comment style. +" With a bang '!', always comment the line. +" +" ARGS... are either (see also |tcomment#Comment()|): +" 1. a list of key=value pairs +" 2. 1-2 values for: ?commentBegin, ?commentEnd +command! -bang -range -nargs=* -complete=customlist,tcomment#CompleteArgs TCommentInline + \ keepjumps call tcomment#Comment(<line1>, <line2>, 'I', "<bang>", <f-args>) + +" :display: :[range]TCommentMaybeInline[!] ?ARGS... +" With a bang '!', always comment the line. +" +" ARGS... are either (see also |tcomment#Comment()|): +" 1. a list of key=value pairs +" 2. 1-2 values for: ?commentBegin, ?commentEnd +command! -bang -range -nargs=* -complete=customlist,tcomment#CompleteArgs TCommentMaybeInline + \ keepjumps call tcomment#Comment(<line1>, <line2>, 'i', "<bang>", <f-args>) + + + +if g:tcommentMaps + if g:tcommentMapLeader1 != '' + exec 'noremap <silent> '. g:tcommentMapLeader1 . g:tcommentMapLeader1 .' :TComment<cr>' + exec 'vnoremap <silent> '. g:tcommentMapLeader1 . g:tcommentMapLeader1 .' :TCommentMaybeInline<cr>' + exec 'inoremap <silent> '. g:tcommentMapLeader1 . g:tcommentMapLeader1 .' <c-o>:TComment<cr>' + exec 'noremap <silent> '. g:tcommentMapLeader1 .'p m`vip:TComment<cr>``' + exec 'inoremap <silent> '. g:tcommentMapLeader1 .'p <c-o>:norm! m`vip<cr>:TComment<cr><c-o>``' + exec 'noremap '. g:tcommentMapLeader1 .'<space> :TComment ' + exec 'inoremap '. g:tcommentMapLeader1 .'<space> <c-o>:TComment ' + exec 'inoremap <silent> '. g:tcommentMapLeader1 .'r <c-o>:TCommentRight<cr>' + exec 'noremap <silent> '. g:tcommentMapLeader1 .'r :TCommentRight<cr>' + exec 'vnoremap <silent> '. g:tcommentMapLeader1 .'i :TCommentInline<cr>' + exec 'noremap <silent> '. g:tcommentMapLeader1 .'i v:TCommentInline mode=I#<cr>' + exec 'inoremap <silent> '. g:tcommentMapLeader1 .'i <c-\><c-o>v:TCommentInline mode=#<cr>' + exec 'noremap '. g:tcommentMapLeader1 .'b :TCommentBlock<cr>' + exec 'inoremap '. g:tcommentMapLeader1 .'b <c-o>:TCommentBlock<cr>' + exec 'noremap '. g:tcommentMapLeader1 .'a :TCommentAs ' + exec 'inoremap '. g:tcommentMapLeader1 .'a <c-o>:TCommentAs ' + exec 'noremap '. g:tcommentMapLeader1 .'n :TCommentAs <c-r>=&ft<cr> ' + exec 'inoremap '. g:tcommentMapLeader1 .'n <c-o>:TCommentAs <c-r>=&ft<cr> ' + exec 'noremap '. g:tcommentMapLeader1 .'s :TCommentAs <c-r>=&ft<cr>_' + exec 'inoremap '. g:tcommentMapLeader1 .'s <c-o>:TCommentAs <c-r>=&ft<cr>_' + exec 'noremap <silent> '. g:tcommentMapLeader1 .'cc :<c-u>call tcomment#SetOption("count", v:count1)<cr>' + exec 'noremap '. g:tcommentMapLeader1 .'ca :<c-u>call tcomment#SetOption("as", input("Comment as: ", &filetype, "customlist,tcomment#Complete"))<cr>' + for s:i in range(1, 9) + exec 'noremap <silent> '. g:tcommentMapLeader1 . s:i .' :TComment count='. s:i .'<cr>' + exec 'inoremap <silent> '. g:tcommentMapLeader1 . s:i .' <c-\><c-o>:TComment count='. s:i .'<cr>' + exec 'vnoremap <silent> '. g:tcommentMapLeader1 . s:i .' :TCommentMaybeInline count='. s:i .'<cr>' + endfor + unlet s:i + endif + if g:tcommentMapLeader2 != '' + exec 'noremap <silent> '. g:tcommentMapLeader2 .'_ :TComment<cr>' + exec 'xnoremap <silent> '. g:tcommentMapLeader2 .'_ :TCommentMaybeInline<cr>' + exec 'noremap <silent> '. g:tcommentMapLeader2 .'p vip:TComment<cr>' + exec 'noremap '. g:tcommentMapLeader2 .'<space> :TComment ' + exec 'xnoremap <silent> '. g:tcommentMapLeader2 .'i :TCommentInline<cr>' + exec 'noremap <silent> '. g:tcommentMapLeader2 .'r :TCommentRight<cr>' + exec 'noremap '. g:tcommentMapLeader2 .'b :TCommentBlock<cr>' + exec 'noremap '. g:tcommentMapLeader2 .'a :TCommentAs ' + exec 'noremap '. g:tcommentMapLeader2 .'n :TCommentAs <c-r>=&ft<cr> ' + exec 'noremap '. g:tcommentMapLeader2 .'s :TCommentAs <c-r>=&ft<cr>_' + endif + if g:tcommentMapLeaderOp1 != '' + exec 'nnoremap <silent> '. g:tcommentMapLeaderOp1 .' :<c-u>if v:count > 0 \| call tcomment#SetOption("count", v:count) \| endif \| let w:tcommentPos = getpos(".") \| set opfunc=tcomment#Operator<cr>g@' + for s:i in range(1, 9) + exec 'nnoremap <silent> '. g:tcommentMapLeaderOp1 . s:i .'c :let w:tcommentPos = getpos(".") \| call tcomment#SetOption("count", '. s:i .') \| set opfunc=tcomment#Operator<cr>g@' + endfor + unlet s:i + exec 'nnoremap <silent> '. g:tcommentMapLeaderOp1 .'c :let w:tcommentPos = getpos(".") \| set opfunc=tcomment#OperatorLine<cr>g@$' + exec 'nnoremap <silent> '. g:tcommentMapLeaderOp1 .'b :let w:tcommentPos = getpos(".") \| call tcomment#SetOption("mode_extra", "B") \| set opfunc=tcomment#OperatorLine<cr>g@' + exec 'xnoremap <silent> '. g:tcommentMapLeaderOp1 .' :TCommentMaybeInline<cr>' + endif + if g:tcommentMapLeaderOp2 != '' + exec 'nnoremap <silent> '. g:tcommentMapLeaderOp2 .' :let w:tcommentPos = getpos(".") \| set opfunc=tcomment#OperatorAnyway<cr>g@' + exec 'nnoremap <silent> '. g:tcommentMapLeaderOp2 .'c :let w:tcommentPos = getpos(".") \| set opfunc=tcomment#OperatorLineAnyway<cr>g@$' + exec 'nnoremap <silent> '. g:tcommentMapLeaderOp2 .'b :let w:tcommentPos = getpos(".") \| call tcomment#SetOption("mode_extra", "B") \| set opfunc=tcomment#OperatorLine<cr>g@' + exec 'xnoremap <silent> '. g:tcommentMapLeaderOp2 .' :TCommentMaybeInline!<cr>' + endif + if g:tcommentTextObjectInlineComment != '' + exec 'vnoremap' g:tcommentTextObjectInlineComment ':<c-U>silent call tcomment#TextObjectInlineComment()<cr>' + exec 'omap' g:tcommentTextObjectInlineComment ':normal v'. g:tcommentTextObjectInlineComment .'<cr>' + endif +endif + +" vi: ft=vim:tw=72:ts=4:fo=w2croql diff --git a/vim/bundle/tcomment/spec/tcomment/issue30.vim b/vim/bundle/tcomment/spec/tcomment/issue30.vim @@ -0,0 +1,12 @@ +" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) +" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) +" @Revision: 32 + + +SpecBegin 'title': 'issue30' + \, 'options': ['vim', {'&selection': 'inclusive'}, {'&selection': 'exclusive'}] + \, 'scratch': 'issue30_test.c' + +It should block comment a single line with <c-_>b. +Should yield Buffer ':norm 2ggb', 'issue30_test_1.c' + diff --git a/vim/bundle/tcomment/spec/tcomment/issue30_sel=exclusive.vim b/vim/bundle/tcomment/spec/tcomment/issue30_sel=exclusive.vim @@ -0,0 +1,14 @@ +" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) +" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) +" @Revision: 11 + +SpecBegin 'title': 'issue30 - bug 2 exclusive' + \, 'options': [{'&selection': 'exclusive'}] + \, 'scratch': 'issue30_test.c' + +It should comment last character selected by v$ with gc. +Should yield Buffer ':norm 3gg$v$gc', 'issue30_test_2.c' + +It should not comment empty space after typing v with gc. +Should yield Buffer ':norm 3gg$vgc', 'issue30_test_3.c' + diff --git a/vim/bundle/tcomment/spec/tcomment/issue30_sel=inclusive.vim b/vim/bundle/tcomment/spec/tcomment/issue30_sel=inclusive.vim @@ -0,0 +1,11 @@ +" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) +" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) +" @Revision: 10 + +SpecBegin 'title': 'issue30 - bug 2 inclusive' + \, 'options': [{'&selection': 'inclusive'}] + \, 'scratch': 'issue30_test.c' + +It should comment last character with gc. +Should yield Buffer ':norm 3gg$vgc', 'issue30_test_2.c' + diff --git a/vim/bundle/tcomment/spec/tcomment/issue30_test.c b/vim/bundle/tcomment/spec/tcomment/issue30_test.c @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} diff --git a/vim/bundle/tcomment/spec/tcomment/issue30_test_1.c b/vim/bundle/tcomment/spec/tcomment/issue30_test_1.c @@ -0,0 +1,6 @@ +int main() +/* + * { + */ + return 0; +} diff --git a/vim/bundle/tcomment/spec/tcomment/issue30_test_2.c b/vim/bundle/tcomment/spec/tcomment/issue30_test_2.c @@ -0,0 +1,4 @@ +int main() +{ + return 0/* ; */ +} diff --git a/vim/bundle/tcomment/spec/tcomment/issue30_test_3.c b/vim/bundle/tcomment/spec/tcomment/issue30_test_3.c @@ -0,0 +1,4 @@ +int main() +{ + return 0/* */; +} diff --git a/vimrc b/vimrc @@ -0,0 +1,382 @@ +" ====================================================================== +" +" Maintainer : Willy Goiffon +" +" +" Version : 1.5 - 01-01-2013 +" +" +" Section : +" > General +" > Interface +" > Colors & more +" > Files +" > Text Formatting +" > Moving within file, buffers, windows & co. +" > Status line +" > Mapping +" > Filetype commands +" > Plugin settings +" > Functions +" > Misc +" +" ====================================================================== + + +" > General =========================================================== +" ====================================================================== + + " Define <leader> key + let mapleader = "!" + + " How many lines Vim use for history + set history=100 + + " Re-read file if changed outside + set autoread + + " Automatically save before commands like :next and :make + set autowrite + + " enable pathogen to manage plugins + exe pathogen#infect() + + " Enable filetype plugins + filetype plugin on + filetype indent on + + +" > Interface ========================================================= +" ====================================================================== + +" Use Vim default instead of 100% vi compatibility +set nocompatible + +" Show (partial) command in status line. +set showcmd + +" Enable code indentation +set autoindent + +" Show matching brackets. +set showmatch + +" Search options +set ignorecase " Ignore case in search +set smartcase " Do smart case matching +set incsearch " Incremental search +set magic " Use magic for regular expressions + +" Enable mouse usage (all modes) +set mouse=a + +" Show the line number on the left +set number + +" Show the cursor position at anytime +set ruler + +" Make <BACKSPACE> do what it should do +set backspace=indent,eol,start + +" Improve display +set ttyfast + +" Define the offset with the cursor when moving vertically +set so=7 + +" Turn on the WildMenu (for cmdline completion) +set wildmenu + +" Files to ignore with it +set wildignore=*.o,*~ + +" Always show cursor position +set ruler + +" Height of the cmdline window +set cmdheight=