]> git.rmz.io Git - dotfiles.git/commitdiff
Merge branch 'master' of tardis:/dotfiles
authorSamir Benmendil <samir.benmendil@gmail.com>
Sun, 18 Jan 2015 23:44:19 +0000 (23:44 +0000)
committerSamir Benmendil <samir.benmendil@gmail.com>
Sun, 18 Jan 2015 23:44:19 +0000 (23:44 +0000)
25 files changed:
awesome/bindings.lua
dwb/forms
mpv/config
qutebrowser/keys.conf [new file with mode: 0644]
qutebrowser/quickmarks [new file with mode: 0644]
qutebrowser/qutebrowser.conf [new file with mode: 0644]
vim/vimrc
weechat/alias.conf
weechat/aspell.conf
weechat/buffer_autoset.conf
weechat/buffers.conf
weechat/charset.conf
weechat/exec.conf
weechat/iset.conf
weechat/logger.conf
weechat/perl/buffers.pl
weechat/plugins.conf
weechat/python/autoload/grep.py [new symlink]
weechat/python/grep.py [new file with mode: 0644]
weechat/relay.conf
weechat/script.conf
weechat/sec.conf
weechat/trigger.conf
weechat/weechat.conf
weechat/xfer.conf

index af2426e97a21420088b5e339aacf34083d4571ee..5ff504ebf91021ab7a7cf641c0d5b78d31cd25a4 100644 (file)
@@ -70,8 +70,8 @@ globalkeys = awful.util.table.join(globalkeys,
     -- Prompt
     awful.key({ modkey }, "space", function () mypromptbox[mouse.screen]:run() end),
     -- switch layout
-    awful.key({ modkey }, "]", function () awful.layout.inc(layouts,  1) end),
-    awful.key({ modkey }, "[", function () awful.layout.inc(layouts, -1) end),
+    awful.key({ modkey }, "]", function () awful.layout.inc( 1, mouse.screen, layouts) end),
+    awful.key({ modkey }, "[", function () awful.layout.inc(-1, mouse.screen, layouts) end),
     -- resize slave
     awful.key({ modkey, "Control" }, "j",      function () awful.client.incwfact( 0.05)  end),
     awful.key({ modkey, "Control" }, "k",      function () awful.client.incwfact(-0.05)  end),
index 71841a51f896b6385d3a825e00ab70bf54544a66..14baaba2290c975c5144d00548d55f5ed7b409dc 100644 (file)
Binary files a/dwb/forms and b/dwb/forms differ
index 3c5e10180f0116cb9134e40f7267f723335c93f9..025f82b98d750212aadf740af7de228a832bf044 100644 (file)
@@ -3,6 +3,7 @@ ytdl
 cache=auto
 cache-default=50000
 cache-initial=100
+no-sub
 
 # profiles
 [mimeo]
diff --git a/qutebrowser/keys.conf b/qutebrowser/keys.conf
new file mode 100644 (file)
index 0000000..4b7e613
--- /dev/null
@@ -0,0 +1,476 @@
+# vim: ft=conf
+#
+# In this config file, qutebrowser's keybindings are configured.
+# The format looks like this:
+#
+# [keymode]
+#
+# command
+#   keychain
+#   keychain2
+#   ...
+#
+# All blank lines and lines starting with '#' are ignored.
+# Inline-comments are not permitted.
+#
+# keymode is a comma separated list of modes in which the keybinding should be
+# active. If keymode starts with !, the keybinding is active in all modes
+# except the listed modes.
+#
+# For special keys (can't be part of a keychain), enclose them in `<`...`>`.
+# For modifiers, you can use either `-` or `+` as delimiters, and these names:
+#
+#  * Control: `Control`, `Ctrl`
+#  * Meta:    `Meta`, `Windows`, `Mod4`
+#  * Alt:     `Alt`, `Mod1`
+#  * Shift:   `Shift`
+#
+# For simple keys (no `<>`-signs), a capital letter means the key is pressed
+# with Shift. For special keys (with `<>`-signs), you need to explicitely add
+# `Shift-` to match a key pressed with shift.  You can bind multiple commands
+# by separating them with `;;`.
+
+[!normal]
+
+leave-mode
+    <Escape>
+    <Ctrl-[>
+
+[normal]
+# Keybindings for normal mode.
+
+set-cmd-text ":open "
+    o
+
+set-cmd-text ":open {url}"
+    go
+
+set-cmd-text ":open -t "
+    O
+
+set-cmd-text ":open -t {url}"
+    gO
+
+set-cmd-text ":open -b "
+    xo
+
+set-cmd-text ":open -b {url}"
+    xO
+
+set-cmd-text ":open -w "
+    wo
+
+set-cmd-text ":open -w {url}"
+    wO
+
+open -t about:blank
+    <Ctrl-T>
+
+tab-close
+    d
+    <Ctrl-W>
+
+tab-close -o
+    D
+
+tab-focus
+    T
+
+tab-move
+    gm
+
+tab-move -
+    gj
+
+tab-move +
+    gk
+
+tab-next
+    K
+    gt
+
+tab-prev
+    J
+    gT
+
+tab-clone
+    gC
+
+reload
+    r
+
+reload -f
+    R
+
+back
+    H
+    <Backspace>
+
+back -t
+    th
+
+back -w
+    wh
+
+forward
+    L
+
+forward -t
+    tl
+
+forward -w
+    wl
+
+fullscreen
+    <F11>
+
+hint
+    f
+
+hint all tab
+    F
+
+hint all window
+    wf
+
+hint all tab-bg
+    ;b
+
+hint all hover
+    ;h
+
+hint images
+    ;i
+
+hint images tab
+    ;I
+
+hint images tab-bg
+    .i
+
+hint links fill ":open {hint-url}"
+    ;o
+
+hint links fill ":open -t {hint-url}"
+    ;O
+
+hint links fill ":open -b {hint-url}"
+    .o
+
+hint links yank
+    ;y
+
+hint links yank-primary
+    ;Y
+
+hint links rapid
+    ;r
+
+hint links rapid-win
+    ;R
+
+hint links download
+    ;d
+
+scroll -50 0
+    h
+
+scroll 0 50
+    j
+
+scroll 0 -50
+    k
+
+scroll 50 0
+    l
+
+undo
+    u
+    <Ctrl-Shift-T>
+
+scroll-perc 0
+    gg
+
+scroll-perc
+    G
+
+search-next
+    n
+
+search-prev
+    N
+
+enter-mode insert
+    i
+
+yank
+    yy
+
+yank -s
+    yY
+
+yank -t
+    yt
+
+yank -ts
+    yT
+
+paste
+    pp
+
+paste -s
+    pP
+
+paste -t
+    Pp
+
+paste -ts
+    PP
+
+paste -w
+    wp
+
+paste -ws
+    wP
+
+quickmark-save
+    m
+
+set-cmd-text ":quickmark-load "
+    b
+
+set-cmd-text ":quickmark-load -t "
+    B
+
+set-cmd-text ":quickmark-load -w"
+    wb
+
+save
+    sf
+
+set-cmd-text ":set "
+    ss
+
+set-cmd-text ":set -t "
+    sl
+
+set-cmd-text ":set keybind "
+    sk
+
+zoom-out
+    -
+
+zoom-in
+    +
+
+zoom
+    =
+
+navigate prev
+    [[
+
+navigate next
+    ]]
+
+navigate prev -t
+    {{
+
+navigate next -t
+    }}
+
+navigate up
+    gu
+
+navigate up -t
+    gU
+
+navigate increment
+    <Ctrl-A>
+
+navigate decrement
+    <Ctrl-X>
+
+inspector
+    wi
+
+download-page
+    gd
+
+cancel-download
+    ad
+
+view-source
+    gf
+
+tab-focus last
+    <Ctrl-Tab>
+
+enter-mode passthrough
+    <Ctrl-V>
+
+quit
+    <Ctrl-Q>
+
+scroll-page 0 1
+    <Ctrl-F>
+
+scroll-page 0 -1
+    <Ctrl-B>
+
+scroll-page 0 0.5
+    <Ctrl-D>
+
+scroll-page 0 -0.5
+    <Ctrl-U>
+
+tab-focus 1
+    <Alt-1>
+
+tab-focus 2
+    <Alt-2>
+
+tab-focus 3
+    <Alt-3>
+
+tab-focus 4
+    <Alt-4>
+
+tab-focus 5
+    <Alt-5>
+
+tab-focus 6
+    <Alt-6>
+
+tab-focus 7
+    <Alt-7>
+
+tab-focus 8
+    <Alt-8>
+
+tab-focus 9
+    <Alt-9>
+
+home
+    <Ctrl-h>
+
+stop
+    <Ctrl-s>
+
+print
+    <Ctrl-Alt-p>
+
+open qute:settings
+    Ss
+
+[insert]
+# Keybindings for insert mode.
+# Since normal keypresses are passed through, only special keys are
+# supported in this mode.
+# Useful hidden commands to map in this section:
+#  * `open-editor`: Open a texteditor with the focused field.
+
+open-editor
+    <Ctrl-E>
+
+[hint]
+# Keybindings for hint mode.
+# Since normal keypresses are passed through, only special keys are
+# supported in this mode.
+# Useful hidden commands to map in this section:
+#  * `follow-hint`: Follow the currently selected hint.
+
+follow-hint
+    <Return>
+
+[command]
+# Keybindings for command mode.
+# Since normal keypresses are passed through, only special keys are
+# supported in this mode.
+# Useful hidden commands to map in this section:
+#  * `command-history-prev`: Switch to previous command in history.
+#  * `command-history-next`: Switch to next command in history.
+#  * `completion-item-prev`: Select previous item in completion.
+#  * `completion-item-next`: Select next item in completion.
+#  * `command-accept`: Execute the command currently in the commandline.
+
+command-history-prev
+    <Ctrl-P>
+
+command-history-next
+    <Ctrl-N>
+
+completion-item-prev
+    <Shift-Tab>
+    <Up>
+
+completion-item-next
+    <Tab>
+    <Down>
+
+command-accept
+    <Return>
+    <Ctrl-J>
+    <Shift-Return>
+
+[prompt]
+# Keybindings for prompts in the status line.
+# You can bind normal keys in this mode, but they will be only active
+# when a yes/no-prompt is asked. For other prompt modes, you can only
+# bind special keys.
+# Useful hidden commands to map in this section:
+#  * `prompt-accept`: Confirm the entered value.
+#  * `prompt-yes`: Answer yes to a yes/no question.
+#  * `prompt-no`: Answer no to a yes/no question.
+
+prompt-accept
+    <Return>
+    <Ctrl-J>
+    <Shift-Return>
+
+prompt-yes
+    y
+
+prompt-no
+    n
+
+[command,prompt]
+
+rl-backward-char
+    <Ctrl-B>
+
+rl-forward-char
+    <Ctrl-F>
+
+rl-backward-word
+    <Alt-B>
+
+rl-forward-word
+    <Alt-F>
+
+rl-beginning-of-line
+    <Ctrl-A>
+
+rl-end-of-line
+    <Ctrl-E>
+
+rl-unix-line-discard
+    <Ctrl-U>
+
+rl-kill-line
+    <Ctrl-K>
+
+rl-kill-word
+    <Alt-D>
+
+rl-unix-word-rubout
+    <Ctrl-W>
+
+rl-yank
+    <Ctrl-Y>
+
+rl-delete-char
+    <Ctrl-?>
+
+rl-backward-delete-char
+    <Ctrl-H>
+
diff --git a/qutebrowser/quickmarks b/qutebrowser/quickmarks
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/qutebrowser/qutebrowser.conf b/qutebrowser/qutebrowser.conf
new file mode 100644 (file)
index 0000000..7c95f98
--- /dev/null
@@ -0,0 +1,986 @@
+# vim: ft=dosini
+
+# Configfile for qutebrowser.
+#
+# WARNING:
+#
+# This config file will be OVERWRITTEN when closing qutebrowser.
+# Close qutebrowser before changing this file, or YOUR CHANGES WILL BE LOST.
+#
+# This configfile is parsed by python's configparser in extended
+# interpolation mode. The format is very INI-like, so there are
+# categories like [general] with "key = value"-pairs.
+#
+# Note that you shouldn't add your own comments, as this file is
+# regenerated every time the config is saved.
+#
+# Interpolation looks like  ${value}  or  ${section:value} and will be
+# replaced by the respective value.
+#
+# This is the default config, so if you want to remove anything from
+# here (as opposed to change/add), for example a keybinding, set it to
+# an empty value.
+#
+# You will need to escape the following values:
+#   - # at the start of the line (at the first position of the key) (\#)
+#   - $ in a value ($$)
+
+[general]
+# General/miscellaneous options.
+#
+# ignore-case (bool):
+#     Whether to find text on a page case-insensitively.
+#         true: Search case-insensitively
+#         false: Search case-sensitively
+#         smart: Search case-sensitively if there are capital chars
+#     Default: smart
+#
+# wrap-search (bool):
+#     Whether to wrap finding text to the top when arriving at the end.
+#     Valid values: true, false
+#     Default: true
+#
+# startpage (string-list):
+#     The default page(s) to open at the start, separated by commas.
+#     Default: https://www.duckduckgo.com
+#
+# auto-search:
+#     Whether to start a search when something else than a URL is
+#     entered.
+#         naive: Use simple/naive check.
+#         dns: Use DNS requests (might be slow!).
+#         false: Never search automatically.
+#     Default: naive
+#
+# auto-save-config (bool):
+#     Whether to save the config automatically on quit.
+#     Valid values: true, false
+#     Default: true
+#
+# editor (shell-command):
+#     The editor (and arguments) to use for the `open-editor` command.
+#     Use `{}` for the filename. The value gets split like in a shell,
+#     so you can use `"` or `'` to quote arguments.
+#     Default: gvim -f "{}"
+#
+# editor-encoding (encoding):
+#     Encoding to use for editor.
+#     Default: utf-8
+#
+# private-browsing (bool):
+#     Do not record visited pages in the history or store web page
+#     icons.
+#     Valid values: true, false
+#     Default: false
+#
+# developer-extras (bool):
+#     Enable extra tools for Web developers.
+#     This needs to be enabled for `:inspector` to work and also adds an
+#     _Inspect_ entry to the context menu.
+#     Valid values: true, false
+#     Default: false
+#
+# print-element-backgrounds (bool):
+#     Whether the background color and images are also drawn when the
+#     page is printed.
+#     Valid values: true, false
+#     Default: true
+#
+# xss-auditing (bool):
+#     Whether load requests should be monitored for cross-site scripting
+#     attempts.
+#     Suspicious scripts will be blocked and reported in the inspector's
+#     JavaScript console. Enabling this feature might have an impact on
+#     performance.
+#     Valid values: true, false
+#     Default: false
+#
+# site-specific-quirks (bool):
+#     Enable workarounds for broken sites.
+#     Valid values: true, false
+#     Default: true
+#
+# default-encoding (string):
+#     Default encoding to use for websites.
+#     The encoding must be a string describing an encoding such as
+#     _utf-8_, _iso-8859-1_, etc. If left empty a default value will be
+#     used.
+#     Default:
+#
+# new-instance-open-target:
+#     How to open links in an existing instance if a new one is
+#     launched.
+#         tab: Open a new tab in the existing window and activate it.
+#         tab-silent: Open a new tab in the existing window without
+#     activating it.
+#         window: Open in a new window.
+#     Default: window
+ignore-case = smart
+wrap-search = true
+startpage = https://www.duckduckgo.com
+auto-search = naive
+auto-save-config = true
+editor = urxvt -e vim "{}"
+editor-encoding = utf-8
+private-browsing = false
+developer-extras = true
+print-element-backgrounds = true
+xss-auditing = false
+site-specific-quirks = true
+default-encoding = 
+new-instance-open-target = tab
+
+[ui]
+# General options related to the user interface.
+#
+# zoom-levels (perc-list):
+#     The available zoom levels, separated by commas.
+#     Default:
+#     25%,33%,50%,67%,75%,90%,100%,110%,125%,150%,175%,200%,250%,300%,400%,500%
+#
+# default-zoom (percentage):
+#     The default zoom level.
+#     Default: 100%
+#
+# message-timeout (int):
+#     Time (in ms) to show messages in the statusbar for.
+#     Default: 2000
+#
+# confirm-quit (string-list):
+#     Whether to confirm quitting the application.
+#         always: Always show a confirmation.
+#         multiple-tabs: Show a confirmation if multiple tabs are
+#     opened.
+#         downloads: Show a confirmation if downloads are running
+#         never: Never show a confirmation.
+#     Default: never
+#
+# display-statusbar-messages (bool):
+#     Whether to display javascript statusbar messages.
+#     Valid values: true, false
+#     Default: false
+#
+# zoom-text-only (bool):
+#     Whether the zoom factor on a frame applies only to the text or to
+#     all content.
+#     Valid values: true, false
+#     Default: false
+#
+# frame-flattening (bool):
+#     Whether to  expand each subframe to its contents.
+#     This will flatten all the frames to become one scrollable page.
+#     Valid values: true, false
+#     Default: false
+#
+# user-stylesheet (user-stylesheet):
+#     User stylesheet to use (absolute filename or CSS string).
+#     Default: ::-webkit-scrollbar { width: 0px; height: 0px; }
+#
+# css-media-type (string):
+#     Set the CSS media type.
+#     Default:
+#
+# remove-finished-downloads (bool):
+#     Whether to remove finished downloads automatically.
+#     Valid values: true, false
+#     Default: false
+zoom-levels = 25%,33%,50%,67%,75%,90%,100%,110%,125%,150%,175%,200%,250%,300%,400%,500%
+default-zoom = 100%
+message-timeout = 2000
+confirm-quit = downloads
+display-statusbar-messages = false
+zoom-text-only = false
+frame-flattening = false
+user-stylesheet = ::-webkit-scrollbar { width: 0px; height: 0px; }
+css-media-type = 
+remove-finished-downloads = false
+
+[network]
+# Settings related to the network.
+#
+# do-not-track (bool):
+#     Value to send in the `DNT` header.
+#     Valid values: true, false
+#     Default: true
+#
+# accept-language (string):
+#     Value to send in the `accept-language` header.
+#     Default: en-US,en
+#
+# user-agent (string):
+#     User agent to send. Empty to send the default.
+#     Default:
+#
+# proxy:
+#     The proxy to use.
+#     In addition to the listed values, you can use a `socks://...` or
+#     `http://...` URL.
+#         system: Use the system wide proxy.
+#         none: Don't use any proxy
+#     Default: system
+#
+# proxy-dns-requests (bool):
+#     Whether to send DNS requests over the configured proxy.
+#     Valid values: true, false
+#     Default: true
+#
+# ssl-strict (bool):
+#     Whether to validate SSL handshakes.
+#     Valid values: true, false, ask
+#     Default: ask
+#
+# dns-prefetch (bool):
+#     Whether to try to pre-fetch DNS entries to speed up browsing.
+#     Valid values: true, false
+#     Default: true
+do-not-track = true
+accept-language = en-US,en,de,fr
+user-agent = 
+proxy = system
+proxy-dns-requests = true
+ssl-strict = ask
+dns-prefetch = true
+
+[completion]
+# Options related to completion and command history.
+#
+# show (bool):
+#     Whether to show the autocompletion window.
+#     Valid values: true, false
+#     Default: true
+#
+# height (percentage-or-int):
+#     The height of the completion, in px or as percentage of the
+#     window.
+#     Default: 50%
+#
+# history-length (int):
+#     How many commands to save in the history.
+#     0: no history / -1: unlimited
+#     Default: 100
+#
+# quick-complete (bool):
+#     Whether to move on to the next part when there's only one possible
+#     completion left.
+#     Valid values: true, false
+#     Default: true
+#
+# shrink (bool):
+#     Whether to shrink the completion to be smaller than the configured
+#     size if there are no scrollbars.
+#     Valid values: true, false
+#     Default: false
+show = true
+height = 150
+history-length = 100
+quick-complete = false
+shrink = true
+
+[input]
+# Options related to input modes.
+#
+# timeout (int):
+#     Timeout for ambiguous keybindings.
+#     Default: 500
+#
+# insert-mode-on-plugins (bool):
+#     Whether to switch to insert mode when clicking flash and other
+#     plugins.
+#     Valid values: true, false
+#     Default: false
+#
+# auto-leave-insert-mode (bool):
+#     Whether to leave insert mode if a non-editable element is clicked.
+#     Valid values: true, false
+#     Default: true
+#
+# auto-insert-mode (bool):
+#     Whether to automatically enter insert mode if an editable element
+#     is focused after page load.
+#     Valid values: true, false
+#     Default: false
+#
+# forward-unbound-keys:
+#     Whether to forward unbound keys to the webview in normal mode.
+#         all: Forward all unbound keys.
+#         auto: Forward unbound non-alphanumeric keys.
+#         none: Don't forward any keys.
+#     Default: auto
+#
+# spatial-navigation (bool):
+#     Enables or disables the Spatial Navigation feature
+#     Spatial navigation consists in the ability to navigate between
+#     focusable elements in a Web page, such as hyperlinks and form
+#     controls, by using Left, Right, Up and Down arrow keys. For
+#     example, if a user presses the Right key, heuristics determine
+#     whether there is an element he might be trying to reach towards
+#     the right and which element he probably wants.
+#     Valid values: true, false
+#     Default: false
+#
+# links-included-in-focus-chain (bool):
+#     Whether hyperlinks should be included in the keyboard focus chain.
+#     Valid values: true, false
+#     Default: true
+timeout = 500
+insert-mode-on-plugins = false
+auto-leave-insert-mode = true
+auto-insert-mode = false
+forward-unbound-keys = auto
+spatial-navigation = false
+links-included-in-focus-chain = true
+
+[tabs]
+# Configuration of the tab bar.
+#
+# background-tabs (bool):
+#     Whether to open new tabs (middleclick/ctrl+click) in background.
+#     Valid values: true, false
+#     Default: false
+#
+# select-on-remove:
+#     Which tab to select when the focused tab is removed.
+#         left: Select the tab on the left.
+#         right: Select the tab on the right.
+#         previous: Select the previously selected tab.
+#     Default: right
+#
+# new-tab-position:
+#     How new tabs are positioned.
+#         left: On the left of the current tab.
+#         right: On the right of the current tab.
+#         first: At the left end.
+#         last: At the right end.
+#     Default: right
+#
+# new-tab-position-explicit:
+#     How new tabs opened explicitely are positioned.
+#         left: On the left of the current tab.
+#         right: On the right of the current tab.
+#         first: At the left end.
+#         last: At the right end.
+#     Default: last
+#
+# last-close:
+#     Behaviour when the last tab is closed.
+#         ignore: Don't do anything.
+#         blank: Load a blank page.
+#         close: Close the window.
+#     Default: ignore
+#
+# auto-hide (bool):
+#     Hide the tabbar if only one tab is open.
+#     Valid values: true, false
+#     Default: false
+#
+# wrap (bool):
+#     Whether to wrap when changing tabs.
+#     Valid values: true, false
+#     Default: true
+#
+# movable (bool):
+#     Whether tabs should be movable.
+#     Valid values: true, false
+#     Default: true
+#
+# close-mouse-button:
+#     On which mouse button to close tabs.
+#         right: Close tabs on right-click.
+#         middle: Close tabs on middle-click.
+#         none: Don't close tabs using the mouse.
+#     Default: middle
+#
+# position:
+#     The position of the tab bar.
+#     Valid values: north, south, east, west
+#     Default: north
+#
+# show-favicons (bool):
+#     Whether to show favicons in the tab bar.
+#     Valid values: true, false
+#     Default: true
+#
+# width (percentage-or-int):
+#     The width of the tab bar if it's vertical, in px or as percentage
+#     of the window.
+#     Default: 20%
+#
+# indicator-width (int):
+#     Width of the progress indicator (0 to disable).
+#     Default: 3
+#
+# indicator-space (int):
+#     Spacing between tab edge and indicator.
+#     Default: 3
+#
+# tabs-are-windows (bool):
+#     Whether to open windows instead of tabs.
+#     Valid values: true, false
+#     Default: false
+background-tabs = false
+select-on-remove = left
+new-tab-position = right
+new-tab-position-explicit = last
+last-close = ignore
+auto-hide = false
+wrap = true
+movable = true
+close-mouse-button = middle
+position = north
+show-favicons = true
+width = 20%
+indicator-width = 3
+indicator-space = 3
+tabs-are-windows = false
+
+[storage]
+# Settings related to cache and storage.
+#
+# download-directory (directory):
+#     The directory to save downloads to. An empty value selects a
+#     sensible os-specific default.
+#     Default:
+#
+# maximum-pages-in-cache (int):
+#     The maximum number of pages to hold in the memory page cache.
+#     The Page Cache allows for a nicer user experience when navigating
+#     forth or back to pages in the forward/back history, by pausing and
+#     resuming up to _n_ pages.
+#     For more information about the feature, please refer to:
+#     http://webkit.org/blog/427/webkit-page-cache-i-the-basics/
+#     Default:
+#
+# object-cache-capacities (bytes-list):
+#     The capacities for the memory cache for dead objects such as
+#     stylesheets or scripts. Syntax: cacheMinDeadCapacity,
+#     cacheMaxDead, totalCapacity.
+#     The _cacheMinDeadCapacity_ specifies the minimum number of bytes
+#     that dead objects should consume when the cache is under pressure.
+#     _cacheMaxDead_ is the maximum number of bytes that dead objects
+#     should consume when the cache is *not* under pressure.
+#     _totalCapacity_ specifies the maximum number of bytes that the
+#     cache should consume *overall*.
+#     Default:
+#
+# offline-storage-default-quota (bytes):
+#     Default quota for new offline storage databases.
+#     Default:
+#
+# offline-web-application-cache-quota (bytes):
+#     Quota for the offline web application cache.
+#     Default:
+#
+# offline-storage-database (bool):
+#     Whether support for the HTML 5 offline storage feature is enabled.
+#     Valid values: true, false
+#     Default: true
+#
+# offline-web-application-storage (bool):
+#     Whether support for the HTML 5 web application cache feature is
+#     enabled.
+#     An application cache acts like an HTTP cache in some sense. For
+#     documents that use the application cache via JavaScript, the
+#     loader engine will first ask the application cache for the
+#     contents, before hitting the network.
+#     The feature is described in details at:
+#     http://dev.w3.org/html5/spec/Overview.html#appcache
+#     Valid values: true, false
+#     Default: true
+#
+# local-storage (bool):
+#     Whether support for the HTML 5 local storage feature is enabled.
+#     Valid values: true, false
+#     Default: true
+#
+# cache-size (int):
+#     Size of the HTTP network cache.
+#     Default: 52428800
+download-directory = ~/downloads
+maximum-pages-in-cache = 
+object-cache-capacities = 
+offline-storage-default-quota = 
+offline-web-application-cache-quota = 
+offline-storage-database = true
+offline-web-application-storage = true
+local-storage = true
+cache-size = 52428800
+
+[content]
+# Loaded plugins/scripts and allowed actions.
+#
+# allow-images (bool):
+#     Whether images are automatically loaded in web pages.
+#     Valid values: true, false
+#     Default: true
+#
+# allow-javascript (bool):
+#     Enables or disables the running of JavaScript programs.
+#     Valid values: true, false
+#     Default: true
+#
+# allow-plugins (bool):
+#     Enables or disables plugins in Web pages.
+#     Qt plugins with a mimetype such as "application/x-qt-plugin" are
+#     not affected by this setting.
+#     Valid values: true, false
+#     Default: false
+#
+# javascript-can-open-windows (bool):
+#     Whether JavaScript programs can open new windows.
+#     Valid values: true, false
+#     Default: false
+#
+# javascript-can-close-windows (bool):
+#     Whether JavaScript programs can close windows.
+#     Valid values: true, false
+#     Default: false
+#
+# javascript-can-access-clipboard (bool):
+#     Whether JavaScript programs can read or write to the clipboard.
+#     Valid values: true, false
+#     Default: false
+#
+# local-content-can-access-remote-urls (bool):
+#     Whether locally loaded documents are allowed to access remote
+#     urls.
+#     Valid values: true, false
+#     Default: false
+#
+# local-content-can-access-file-urls (bool):
+#     Whether locally loaded documents are allowed to access other local
+#     urls.
+#     Valid values: true, false
+#     Default: true
+#
+# cookies-accept:
+#     Whether to accept cookies.
+#         default: Default QtWebKit behaviour.
+#         never: Don't accept cookies at all.
+#     Default: default
+#
+# cookies-store (bool):
+#     Whether to store cookies.
+#     Valid values: true, false
+#     Default: true
+#
+# host-block-lists (url-list):
+#     List of URLs of lists which contain hosts to block.
+#     The file can be in one of the following formats:
+#     - An '/etc/hosts'-like file
+#     - One host per line
+#     - A zip-file of any of the above, with either only one file, or a
+#     file named 'hosts' (with any extension).
+#     Default:
+#     http://www.malwaredomainlist.com/hostslist/hosts.txt,http://someonewhocares.org/hosts/hosts,http://winhelp2002.mvps.org/hosts.zip,http://malwaredomains.lehigh.edu/files/justdomains.zip,http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext
+allow-images = true
+allow-javascript = true
+allow-plugins = false
+javascript-can-open-windows = true
+javascript-can-close-windows = true
+javascript-can-access-clipboard = false
+local-content-can-access-remote-urls = false
+local-content-can-access-file-urls = true
+cookies-accept = default
+cookies-store = true
+host-block-lists = http://www.malwaredomainlist.com/hostslist/hosts.txt,http://someonewhocares.org/hosts/hosts,http://winhelp2002.mvps.org/hosts.zip,http://malwaredomains.lehigh.edu/files/justdomains.zip,http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext
+
+[hints]
+# Hinting settings.
+#
+# border (string):
+#     CSS border value for hints.
+#     Default: 1px solid #E3BE23
+#
+# opacity (float):
+#     Opacity for hints.
+#     Default: 0.7
+#
+# mode:
+#     Mode to use for hints.
+#         number: Use numeric hints.
+#         letter: Use the chars in the hints -> chars setting.
+#     Default: letter
+#
+# chars (string):
+#     Chars used for hint strings.
+#     Default: asdfghjkl
+#
+# uppercase (bool):
+#     Make chars in hint strings uppercase.
+#     Valid values: true, false
+#     Default: false
+#
+# auto-follow (bool):
+#     Whether to auto-follow a hint if there's only one left.
+#     Valid values: true, false
+#     Default: true
+#
+# next-regexes (regex-list):
+#     A comma-separated list of regexes to use for 'next' links.
+#     Default: \bnext\b,\bmore\b,\bnewer\b,\b[>→≫]\b,\b(>>|»)\b
+#
+# prev-regexes (regex-list):
+#     A comma-separated list of regexes to use for 'prev' links.
+#     Default: \bprev(ious)?\b,\bback\b,\bolder\b,\b[<←≪]\b,\b(<<|«)\b
+border = 1px solid #E3BE23
+opacity = 0.7
+mode = letter
+chars = aoeuidhtns
+uppercase = true
+auto-follow = true
+next-regexes = \bnext\b,\bmore\b,\bnewer\b,\b[>→≫]\b,\b(>>|»)\b
+prev-regexes = \bprev(ious)?\b,\bback\b,\bolder\b,\b[<←≪]\b,\b(<<|«)\b
+
+[searchengines]
+# Definitions of search engines which can be used via the address bar.
+# The searchengine named `DEFAULT` is used when `general -> auto-search`
+# is true and something else than a URL was entered to be opened. Other
+# search engines can be used via the bang-syntax, e.g. `:open
+# qutebrowser !google`. The string `{}` will be replaced by the search
+# term, use `{{` and `}}` for literal `{`/`}` signs.
+DEFAULT = ${duckduckgo}
+duckduckgo = https://duckduckgo.com/?q={}
+ddg = ${duckduckgo}
+google = https://encrypted.google.com/search?q={}
+g = ${google}
+wikipedia = http://en.wikipedia.org/w/index.php?title=Special:Search&search={}
+wiki = ${wikipedia}
+
+[aliases]
+# Aliases for commands.
+# By default, no aliases are defined. Example which adds a new command
+# `:qtb` to open qutebrowsers website:
+# `qtb = open http://www.qutebrowser.org/`
+
+[colors]
+# Colors used in the UI.
+# A value can be in one of the following format:
+#  * `#RGB`/`#RRGGBB`/`#RRRGGGBBB`/`#RRRRGGGGBBBB`
+#  * A SVG color name as specified in http://www.w3.org/TR/SVG/types.html#ColorKeywords[the W3C specification].
+#  * transparent (no color)
+#  * `rgb(r, g, b)` / `rgba(r, g, b, a)` (values 0-255 or percentages)
+#  * `hsv(h, s, v)` / `hsva(h, s, v, a)` (values 0-255, hue 0-359)
+#  * A gradient as explained in http://qt-project.org/doc/qt-4.8/stylesheet-reference.html#list-of-property-types[the Qt documentation] under ``Gradient''.
+# The `hints.*` values are a special case as they're real CSS colors, not Qt-CSS colors. There, for a gradient, you need to use `-webkit-gradient`, see https://www.webkit.org/blog/175/introducing-css-gradients/[the WebKit documentation].
+#
+# completion.fg (qcolor):
+#     Text color of the completion widget.
+#     Default: white
+#
+# completion.bg (qss-color):
+#     Background color of the completion widget.
+#     Default: #333333
+#
+# completion.item.bg (qss-color):
+#     Background color of completion widget items.
+#     Default: ${completion.bg}
+#
+# completion.category.fg (qcolor):
+#     Foreground color of completion widget category headers.
+#     Default: white
+#
+# completion.category.bg (qss-color):
+#     Background color of the completion widget category headers.
+#     Default: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #888888,
+#     stop:1 #505050)
+#
+# completion.category.border.top (qss-color):
+#     Top border color of the completion widget category headers.
+#     Default: black
+#
+# completion.category.border.bottom (qss-color):
+#     Bottom border color of the completion widget category headers.
+#     Default: ${completion.category.border.top}
+#
+# completion.item.selected.fg (qcolor):
+#     Foreground color of the selected completion item.
+#     Default: black
+#
+# completion.item.selected.bg (qss-color):
+#     Background color of the selected completion item.
+#     Default: #e8c000
+#
+# completion.item.selected.border.top (qss-color):
+#     Top border color of the completion widget category headers.
+#     Default: #bbbb00
+#
+# completion.item.selected.border.bottom (qss-color):
+#     Bottom border color of the selected completion item.
+#     Default: ${completion.item.selected.border.top}
+#
+# completion.match.fg (qss-color):
+#     Foreground color of the matched text in the completion.
+#     Default: #ff4444
+#
+# statusbar.bg (qss-color):
+#     Foreground color of the statusbar.
+#     Default: black
+#
+# statusbar.fg (qss-color):
+#     Foreground color of the statusbar.
+#     Default: white
+#
+# statusbar.bg.error (qss-color):
+#     Background color of the statusbar if there was an error.
+#     Default: red
+#
+# statusbar.bg.prompt (qss-color):
+#     Background color of the statusbar if there is a prompt.
+#     Default: darkblue
+#
+# statusbar.bg.insert (qss-color):
+#     Background color of the statusbar in insert mode.
+#     Default: darkgreen
+#
+# statusbar.progress.bg (qss-color):
+#     Background color of the progress bar.
+#     Default: white
+#
+# statusbar.url.fg (qss-color):
+#     Default foreground color of the URL in the statusbar.
+#     Default: ${statusbar.fg}
+#
+# statusbar.url.fg.success (qss-color):
+#     Foreground color of the URL in the statusbar on successful load.
+#     Default: lime
+#
+# statusbar.url.fg.error (qss-color):
+#     Foreground color of the URL in the statusbar on error.
+#     Default: orange
+#
+# statusbar.url.fg.warn (qss-color):
+#     Foreground color of the URL in the statusbar when there's a
+#     warning.
+#     Default: yellow
+#
+# statusbar.url.fg.hover (qss-color):
+#     Foreground color of the URL in the statusbar for hovered links.
+#     Default: aqua
+#
+# tabs.fg.odd (qcolor):
+#     Foreground color of unselected odd tabs.
+#     Default: white
+#
+# tabs.fg.even (qcolor):
+#     Foreground color of unselected even tabs.
+#     Default: white
+#
+# tabs.fg.selected (qcolor):
+#     Foreground color of selected tabs.
+#     Default: white
+#
+# tabs.bg.odd (qcolor):
+#     Background color of unselected odd tabs.
+#     Default: grey
+#
+# tabs.bg.even (qcolor):
+#     Background color of unselected even tabs.
+#     Default: darkgrey
+#
+# tabs.bg.selected (qcolor):
+#     Background color of selected tabs.
+#     Default: black
+#
+# tabs.bg.bar (qcolor):
+#     Background color of the tabbar.
+#     Default: #555555
+#
+# tabs.indicator.start (qcolor):
+#     Color gradient start for the tab indicator.
+#     Default: #0000aa
+#
+# tabs.indicator.stop (qcolor):
+#     Color gradient end for the tab indicator.
+#     Default: #00aa00
+#
+# tabs.indicator.error (qcolor):
+#     Color for the tab indicator on errors..
+#     Default: #ff0000
+#
+# tabs.indicator.system:
+#     Color gradient interpolation system for the tab indicator.
+#         rgb: Interpolate in the RGB color system.
+#         hsv: Interpolate in the HSV color system.
+#         hsl: Interpolate in the HSL color system.
+#     Default: rgb
+#
+# tabs.seperator (qss-color):
+#     Color for the tab seperator.
+#     Default: #555555
+#
+# hints.fg (css-color):
+#     Font color for hints.
+#     Default: black
+#
+# hints.fg.match (css-color):
+#     Font color for the matched part of hints.
+#     Default: green
+#
+# hints.bg (css-color):
+#     Background color for hints.
+#     Default: -webkit-gradient(linear, left top, left bottom,
+#     color-stop(0%,#FFF785), color-stop(100%,#FFC542))
+#
+# downloads.fg (qcolor):
+#     Foreground color for downloads.
+#     Default: #ffffff
+#
+# downloads.bg.bar (qss-color):
+#     Background color for the download bar.
+#     Default: black
+#
+# downloads.bg.start (qcolor):
+#     Color gradient start for downloads.
+#     Default: #0000aa
+#
+# downloads.bg.stop (qcolor):
+#     Color gradient end for downloads.
+#     Default: #00aa00
+#
+# downloads.bg.system:
+#     Color gradient interpolation system for downloads.
+#         rgb: Interpolate in the RGB color system.
+#         hsv: Interpolate in the HSV color system.
+#         hsl: Interpolate in the HSL color system.
+#     Default: rgb
+#
+# downloads.bg.error (qcolor):
+#     Background color for downloads with errors.
+#     Default: red
+completion.fg = white
+completion.bg = #333333
+completion.item.bg = ${completion.bg}
+completion.category.fg = white
+completion.category.bg = qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #888888, stop:1 #505050)
+completion.category.border.top = black
+completion.category.border.bottom = ${completion.category.border.top}
+completion.item.selected.fg = black
+completion.item.selected.bg = #e8c000
+completion.item.selected.border.top = #bbbb00
+completion.item.selected.border.bottom = ${completion.item.selected.border.top}
+completion.match.fg = #ff4444
+statusbar.bg = black
+statusbar.fg = white
+statusbar.bg.error = red
+statusbar.bg.prompt = darkblue
+statusbar.bg.insert = darkgreen
+statusbar.progress.bg = white
+statusbar.url.fg = ${statusbar.fg}
+statusbar.url.fg.success = lime
+statusbar.url.fg.error = orange
+statusbar.url.fg.warn = yellow
+statusbar.url.fg.hover = aqua
+tabs.fg.odd = white
+tabs.fg.even = white
+tabs.fg.selected = white
+tabs.bg.odd = grey
+tabs.bg.even = darkgrey
+tabs.bg.selected = black
+tabs.bg.bar = #555555
+tabs.indicator.start = #0000aa
+tabs.indicator.stop = #00aa00
+tabs.indicator.error = #ff0000
+tabs.indicator.system = rgb
+tabs.seperator = #555555
+hints.fg = black
+hints.fg.match = green
+hints.bg = -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFF785), color-stop(100%,#FFC542))
+downloads.fg = #ffffff
+downloads.bg.bar = black
+downloads.bg.start = #0000aa
+downloads.bg.stop = #00aa00
+downloads.bg.system = rgb
+downloads.bg.error = red
+
+[fonts]
+# Fonts used for the UI, with optional style/weight/size.
+#  * Style: `normal`/`italic`/`oblique`
+#  * Weight: `normal`, `bold`, `100`..`900`
+#  * Size: _number_ `px`/`pt`
+#
+# _monospace (font):
+#     Default monospace fonts.
+#     Default: Terminus, Monospace, "DejaVu Sans Mono", Monaco,
+#     "Bitstream Vera Sans Mono", "Andale Mono", "Liberation Mono",
+#     "Courier New", Courier, monospace, Fixed, Consolas, Terminal
+#
+# completion (font):
+#     Font used in the completion widget.
+#     Default: 8pt ${_monospace}
+#
+# tabbar (font):
+#     Font used in the tabbar.
+#     Default: 8pt ${_monospace}
+#
+# statusbar (font):
+#     Font used in the statusbar.
+#     Default: 8pt ${_monospace}
+#
+# downloads (font):
+#     Font used for the downloadbar.
+#     Default: 8pt ${_monospace}
+#
+# hints (font):
+#     Font used for the hints.
+#     Default: bold 12px Monospace
+#
+# debug-console (font):
+#     Font used for the debugging console.
+#     Default: 8pt ${_monospace}
+#
+# web-family-standard (string):
+#     Font family for standard fonts.
+#     Default:
+#
+# web-family-fixed (string):
+#     Font family for fixed fonts.
+#     Default:
+#
+# web-family-serif (string):
+#     Font family for serif fonts.
+#     Default:
+#
+# web-family-sans-serif (string):
+#     Font family for sans-serif fonts.
+#     Default:
+#
+# web-family-cursive (string):
+#     Font family for cursive fonts.
+#     Default:
+#
+# web-family-fantasy (string):
+#     Font family for fantasy fonts.
+#     Default:
+#
+# web-size-minimum (int):
+#     The hard minimum font size.
+#     Default:
+#
+# web-size-minimum-logical (int):
+#     The minimum logical font size that is applied when zooming out.
+#     Default:
+#
+# web-size-default (int):
+#     The default font size for regular text.
+#     Default:
+#
+# web-size-default-fixed (int):
+#     The default font size for fixed-pitch text.
+#     Default:
+_monospace = Terminus, Monospace, "DejaVu Sans Mono", Monaco, "Bitstream Vera Sans Mono", "Andale Mono", "Liberation Mono", "Courier New", Courier, monospace, Fixed, Consolas, Terminal
+completion = 8pt ${_monospace}
+tabbar = 8pt ${_monospace}
+statusbar = 8pt ${_monospace}
+downloads = 8pt ${_monospace}
+hints = bold 12px Monospace
+debug-console = 8pt ${_monospace}
+web-family-standard = 
+web-family-fixed = 
+web-family-serif = 
+web-family-sans-serif = 
+web-family-cursive = 
+web-family-fantasy = 
+web-size-minimum = 
+web-size-minimum-logical = 
+web-size-default = 
+web-size-default-fixed = 
index 17e2a1e946cc9581ffb873cd2fd45390fae8a9f0..9de1144091f5e3f033a5f2873f979c802a2c57dc 100644 (file)
--- a/vim/vimrc
+++ b/vim/vimrc
@@ -410,6 +410,7 @@ nnoremap <silent> <leader>gs :Gstatus<CR>
 nnoremap <silent> <leader>gd :Gdiff<CR>
 nnoremap <silent> <leader>gc :tab Gcommit -v<CR>
 nnoremap <silent> <leader>ga :Gwrite<cr>
+nnoremap <silent> <leader>gb :Gblame<cr>
 
 " NERDTree {{{2
 " open/close NERDTree with \e
index d1611cc3a6cd272ae055665e674cf045e4e79c40..51a5bb0dbdf10d67b0aade05d1ee1acca2a35164 100644 (file)
@@ -1,5 +1,5 @@
 #
-# alias.conf -- weechat v1.0.1
+# alias.conf -- weechat v1.1
 #
 
 [cmd]
index aa0bd00d26637c3a8d9b0db7234bf99c7addb73a..4fbeb6ee03e6f0eda3c5ac91be8f606267f93df3 100644 (file)
@@ -1,5 +1,5 @@
 #
-# aspell.conf -- weechat v1.0.1
+# aspell.conf -- weechat v1.1
 #
 
 [color]
index 23433c175e79369c9bcebfd5891bf6fdb2284d9b..301fe654e445b533c033cd451754232668ece4d4 100644 (file)
@@ -1,5 +1,5 @@
 #
-# buffer_autoset.conf -- weechat v1.0.1
+# buffer_autoset.conf -- weechat v1.1
 #
 
 [buffer]
index e62c7ec7f846aa910a159ff9c0e2d77867bf465d..d04517fd23d0976cf0448165b4da6b291f7b04c7 100644 (file)
@@ -1,5 +1,5 @@
 #
-# buffers.conf -- weechat v1.0.1
+# buffers.conf -- weechat v1.1
 #
 
 [color]
index aadbdaefb3bd11681f6af71ec7b8759585013eef..ccb87aada5cc6b05a27572a412f1b7c6b7b87689 100644 (file)
@@ -1,5 +1,5 @@
 #
-# charset.conf -- weechat v1.0.1
+# charset.conf -- weechat v1.1
 #
 
 [default]
index 0f713aaee3c9afa266fb800743bd341c8c338b95..895c99ee6c8ced148d972b8d8687a628fcbc444a 100644 (file)
@@ -1,5 +1,5 @@
 #
-# exec.conf -- weechat v1.0.1
+# exec.conf -- weechat v1.1
 #
 
 [command]
index aed2cbb148f521cc8e2cee0e2a6de9471c0cb65c..8d6e31891b93831702031305b7d6690d876e158c 100644 (file)
@@ -1,5 +1,5 @@
 #
-# iset.conf -- weechat v1.0.1
+# iset.conf -- weechat v1.1
 #
 
 [color]
index 9a9cde6f14966c0e993858eab3438188c9060ed8..c98c4a01f0e3c207ed50896757bab25ea0ebe80c 100644 (file)
@@ -1,5 +1,5 @@
 #
-# logger.conf -- weechat v1.0.1
+# logger.conf -- weechat v1.1
 #
 
 [look]
index ef21fdd88222e7d012837e535baedc7f2e0e4d8b..472f6e95df9ed315a0131880db2f2e53c1545fe7 100644 (file)
@@ -20,6 +20,8 @@
 #
 # History:
 #
+# 2014-12-12
+#     v5.0: fix cropping non-latin buffer names
 # 2014-08-29, Patrick Steinhardt <ps@pks.im>:
 #     v4.9: add support for specifying custom buffer names
 # 2014-07-19, Sebastien Helleu <flashcode@flashtux.org>:
@@ -162,7 +164,7 @@ use strict;
 use Encode qw( decode encode );
 # -----------------------------[ internal ]-------------------------------------
 my $SCRIPT_NAME = "buffers";
-my $SCRIPT_VERSION = "4.9";
+my $SCRIPT_VERSION = "5.0";
 
 my $BUFFERS_CONFIG_FILE_NAME = "buffers";
 my $buffers_config_file;
@@ -1386,7 +1388,8 @@ sub build_buffers
 
         if (weechat::config_integer($options{"name_size_max"}) >= 1)                # check max_size of buffer name
         {
-            $str .= encode("UTF-8", substr(decode("UTF-8", $name), 0, weechat::config_integer($options{"name_size_max"})));
+            $name = decode("UTF-8", $name);
+            $str .= encode("UTF-8", substr($name, 0, weechat::config_integer($options{"name_size_max"})));
             $str .= weechat::color(weechat::config_color( $options{"color_number_char"})).weechat::config_string($options{"name_crop_suffix"}) if (length($name) > weechat::config_integer($options{"name_size_max"}));
             $str .= add_inactive_parentless($buffer->{"type"}, $buffer->{"nicks_count"});
             $str .= add_hotlist_count($buffer->{"pointer"}, %hotlist);
index c4ef917918944f695ea17b2a48e08a3c529bc6ce..4d23b882319ea7118ac2b87432988119078ebab3 100644 (file)
@@ -1,5 +1,5 @@
 #
-# plugins.conf -- weechat v1.0.1
+# plugins.conf -- weechat v1.1
 #
 
 [var]
@@ -38,6 +38,13 @@ perl.highmon.nick_suffix = ">"
 perl.highmon.output = "buffer"
 perl.highmon.short_names = "on"
 python.check_license = "off"
+python.grep.clear_buffer = "off"
+python.grep.default_tail_head = "10"
+python.grep.go_to_buffer = "on"
+python.grep.log_filter = ""
+python.grep.max_lines = "4000"
+python.grep.show_summary = "on"
+python.grep.size_limit = "2048"
 ruby.check_license = "off"
 tcl.check_license = "off"
 
diff --git a/weechat/python/autoload/grep.py b/weechat/python/autoload/grep.py
new file mode 120000 (symlink)
index 0000000..87d4ca7
--- /dev/null
@@ -0,0 +1 @@
+../grep.py
\ No newline at end of file
diff --git a/weechat/python/grep.py b/weechat/python/grep.py
new file mode 100644 (file)
index 0000000..6d08ecd
--- /dev/null
@@ -0,0 +1,1718 @@
+# -*- coding: utf-8 -*-
+###
+# Copyright (c) 2009-2011 by Elián Hanisch <lambdae2@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+###
+
+###
+# Search in Weechat buffers and logs (for Weechat 0.3.*)
+#
+#   Inspired by xt's grep.py
+#   Originally I just wanted to add some fixes in grep.py, but then
+#   I got carried away and rewrote everything, so new script.
+#
+#   Commands:
+#   * /grep
+#     Search in logs or buffers, see /help grep
+#   * /logs:
+#     Lists logs in ~/.weechat/logs, see /help logs
+#
+#   Settings:
+#   * plugins.var.python.grep.clear_buffer:
+#     Clear the results buffer before each search. Valid values: on, off
+#
+#   * plugins.var.python.grep.go_to_buffer:
+#     Automatically go to grep buffer when search is over. Valid values: on, off
+#
+#   * plugins.var.python.grep.log_filter:
+#     Coma separated list of patterns that grep will use for exclude logs, e.g.
+#     if you use '*server/*' any log in the 'server' folder will be excluded
+#     when using the command '/grep log'
+#
+#   * plugins.var.python.grep.show_summary:
+#     Shows summary for each log. Valid values: on, off
+#
+#   * plugins.var.python.grep.max_lines:
+#     Grep will only print the last matched lines that don't surpass the value defined here.
+#
+#   * plugins.var.python.grep.size_limit:
+#     Size limit in KiB, is used for decide whenever grepping should run in background or not. If
+#     the logs to grep have a total size bigger than this value then grep run as a new process.
+#     It can be used for force or disable background process, using '0' forces to always grep in
+#     background, while using '' (empty string) will disable it.
+#
+#   * plugins.var.python.grep.default_tail_head:
+#     Config option for define default number of lines returned when using --head or --tail options.
+#     Can be overriden in the command with --number option.
+#
+#
+#   TODO:
+#   * try to figure out why hook_process chokes in long outputs (using a tempfile as a
+#   workaround now)
+#   * possibly add option for defining time intervals
+#
+#
+#   History:
+#   2014-03-29, Felix Eckhofer <felix@tribut.de>
+#   version 0.7.3: fix typo
+#
+#   2011-01-09
+#   version 0.7.2: bug fixes
+#
+#   2010-11-15
+#   version 0.7.1:
+#   * use TempFile so temporal files are guaranteed to be deleted.
+#   * enable Archlinux workaround.
+#
+#   2010-10-26
+#   version 0.7:
+#   * added templates.
+#   * using --only-match shows only unique strings.
+#   * fixed bug that inverted -B -A switches when used with -t
+#
+#   2010-10-14
+#   version 0.6.8: by xt <xt@bash.no>
+#   * supress highlights when printing in grep buffer
+#
+#   2010-10-06
+#   version 0.6.7: by xt <xt@bash.no> 
+#   * better temporary file:
+#    use tempfile.mkstemp. to create a temp file in log dir, 
+#    makes it safer with regards to write permission and multi user
+#
+#   2010-04-08
+#   version 0.6.6: bug fixes
+#   * use WEECHAT_LIST_POS_END in log file completion, makes completion faster
+#   * disable bytecode if using python 2.6
+#   * use single quotes in command string
+#   * fix bug that could change buffer's title when using /grep stop
+#
+#   2010-01-24
+#   version 0.6.5: disable bytecode is a 2.6 feature, instead, resort to delete the bytecode manually
+#
+#   2010-01-19
+#   version 0.6.4: bug fix
+#   version 0.6.3: added options --invert --only-match (replaces --exact, which is still available
+#   but removed from help)
+#   * use new 'irc_nick_color' info
+#   * don't generate bytecode when spawning a new process
+#   * show active options in buffer title
+#
+#   2010-01-17
+#   version 0.6.2: removed 2.6-ish code
+#   version 0.6.1: fixed bug when grepping in grep's buffer
+#
+#   2010-01-14
+#   version 0.6.0: implemented grep in background
+#   * improved context lines presentation.
+#   * grepping for big (or many) log files runs in a weechat_process.
+#   * added /grep stop.
+#   * added 'size_limit' option
+#   * fixed a infolist leak when grepping buffers
+#   * added 'default_tail_head' option
+#   * results are sort by line count
+#   * don't die if log is corrupted (has NULL chars in it)
+#   * changed presentation of /logs
+#   * log path completion doesn't suck anymore
+#   * removed all tabs, because I learned how to configure Vim so that spaces aren't annoying
+#   anymore. This was the script's original policy.
+#
+#   2010-01-05
+#   version 0.5.5: rename script to 'grep.py' (FlashCode <flashcode@flashtux.org>).
+#
+#   2010-01-04
+#   version 0.5.4.1: fix index error when using --after/before-context options.
+#
+#   2010-01-03
+#   version 0.5.4: new features
+#   * added --after-context and --before-context options.
+#   * added --context as a shortcut for using both -A -B options.
+#
+#   2009-11-06
+#   version 0.5.3: improvements for long grep output
+#   * grep buffer input accepts the same flags as /grep for repeat a search with different
+#     options.
+#   * tweaks in grep's output.
+#   * max_lines option added for limit grep's output.
+#   * code in update_buffer() optimized.
+#   * time stats in buffer title.
+#   * added go_to_buffer config option.
+#   * added --buffer for search only in buffers.
+#   * refactoring.
+#
+#   2009-10-12, omero
+#   version 0.5.2: made it python-2.4.x compliant
+#
+#   2009-08-17
+#   version 0.5.1: some refactoring, show_summary option added.
+#
+#   2009-08-13
+#   version 0.5: rewritten from xt's grep.py
+#   * fixed searching in non weechat logs, for cases like, if you're
+#     switching from irssi and rename and copy your irssi logs to %h/logs
+#   * fixed "timestamp rainbow" when you /grep in grep's buffer
+#   * allow to search in other buffers other than current or in logs
+#     of currently closed buffers with cmd 'buffer'
+#   * allow to search in any log file in %h/logs with cmd 'log'
+#   * added --count for return the number of matched lines
+#   * added --matchcase for case sensible search
+#   * added --hilight for color matches
+#   * added --head and --tail options, and --number
+#   * added command /logs for list files in %h/logs
+#   * added config option for clear the buffer before a search
+#   * added config option for filter logs we don't want to grep
+#   * added the posibility to repeat last search with another regexp by writing
+#     it in grep's buffer
+#   * changed spaces for tabs in the code, which is my preference
+#
+###
+
+from os import path
+import sys, getopt, time, os, re, tempfile
+
+try:
+    import weechat
+    from weechat import WEECHAT_RC_OK, prnt, prnt_date_tags
+    import_ok = True
+except ImportError:
+    import_ok = False
+
+SCRIPT_NAME    = "grep"
+SCRIPT_AUTHOR  = "Elián Hanisch <lambdae2@gmail.com>"
+SCRIPT_VERSION = "0.7.3"
+SCRIPT_LICENSE = "GPL3"
+SCRIPT_DESC    = "Search in buffers and logs"
+SCRIPT_COMMAND = "grep"
+
+### Default Settings ###
+settings = {
+'clear_buffer'      : 'off',
+'log_filter'        : '',
+'go_to_buffer'      : 'on',
+'max_lines'         : '4000',
+'show_summary'      : 'on',
+'size_limit'        : '2048',
+'default_tail_head' : '10',
+}
+
+### Class definitions ###
+class linesDict(dict):
+    """
+    Class for handling matched lines in more than one buffer.
+    linesDict[buffer_name] = matched_lines_list
+    """
+    def __setitem__(self, key, value):
+        assert isinstance(value, list)
+        if key not in self:
+            dict.__setitem__(self, key, value)
+        else:
+            dict.__getitem__(self, key).extend(value)
+
+    def get_matches_count(self):
+        """Return the sum of total matches stored."""
+        if dict.__len__(self):
+            return sum(map(lambda L: L.matches_count, self.itervalues()))
+        else:
+            return 0
+
+    def __len__(self):
+        """Return the sum of total lines stored."""
+        if dict.__len__(self):
+            return sum(map(len, self.itervalues()))
+        else:
+            return 0
+
+    def __str__(self):
+        """Returns buffer count or buffer name if there's just one stored."""
+        n = len(self.keys())
+        if n == 1:
+            return self.keys()[0]
+        elif n > 1:
+            return '%s logs' %n
+        else:
+            return ''
+
+    def items(self):
+        """Returns a list of items sorted by line count."""
+        items = dict.items(self)
+        items.sort(key=lambda i: len(i[1]))
+        return items
+
+    def items_count(self):
+        """Returns a list of items sorted by match count."""
+        items = dict.items(self)
+        items.sort(key=lambda i: i[1].matches_count)
+        return items
+
+    def strip_separator(self):
+        for L in self.itervalues():
+            L.strip_separator()
+
+    def get_last_lines(self, n):
+        total_lines = len(self)
+        #debug('total: %s n: %s' %(total_lines, n))
+        if n >= total_lines:
+            # nothing to do
+            return
+        for k, v in reversed(self.items()):
+            l = len(v)
+            if n > 0:
+                if l > n:
+                    del v[:l-n]
+                    v.stripped_lines = l-n
+                n -= l
+            else:
+                del v[:]
+                v.stripped_lines = l
+
+class linesList(list):
+    """Class for list of matches, since sometimes I need to add lines that aren't matches, I need an
+    independent counter."""
+    _sep = '...'
+    def __init__(self, *args):
+        list.__init__(self, *args)
+        self.matches_count = 0
+        self.stripped_lines = 0
+
+    def append(self, item):
+        """Append lines, can be a string or a list with strings."""
+        if isinstance(item, str):
+            list.append(self, item)
+        else:
+            self.extend(item)
+
+    def append_separator(self):
+        """adds a separator into the list, makes sure it doen't add two together."""
+        s = self._sep
+        if (self and self[-1] != s) or not self:
+            self.append(s)
+
+    def onlyUniq(self):
+        s = set(self)
+        del self[:]
+        self.extend(s)
+
+    def count_match(self, item=None):
+        if item is None or isinstance(item, str):
+            self.matches_count += 1
+        else:
+            self.matches_count += len(item)
+
+    def strip_separator(self):
+        """removes separators if there are first or/and last in the list."""
+        if self:
+            s = self._sep
+            if self[0] == s:
+                del self[0]
+            if self[-1] == s:
+                del self[-1]
+
+### Misc functions ###
+now = time.time
+def get_size(f):
+    try:
+        return os.stat(f).st_size
+    except OSError:
+        return 0
+
+sizeDict = {0:'b', 1:'KiB', 2:'MiB', 3:'GiB', 4:'TiB'}
+def human_readable_size(size):
+    power = 0
+    while size > 1024:
+        power += 1
+        size /= 1024.0
+    return '%.2f %s' %(size, sizeDict.get(power, ''))
+
+def color_nick(nick):
+    """Returns coloured nick, with coloured mode if any."""
+    if not nick: return ''
+    wcolor = weechat.color
+    config_string = lambda s : weechat.config_string(weechat.config_get(s))
+    config_int = lambda s : weechat.config_integer(weechat.config_get(s))
+    # prefix and suffix
+    prefix = config_string('irc.look.nick_prefix')
+    suffix = config_string('irc.look.nick_suffix')
+    prefix_c = suffix_c = wcolor(config_string('weechat.color.chat_delimiters'))
+    if nick[0] == prefix:
+        nick = nick[1:]
+    else:
+        prefix = prefix_c = ''
+    if nick[-1] == suffix:
+        nick = nick[:-1]
+        suffix = wcolor(color_delimiter) + suffix
+    else:
+        suffix = suffix_c = ''
+    # nick mode
+    modes = '@!+%'
+    if nick[0] in modes:
+        mode, nick = nick[0], nick[1:]
+        mode_color = wcolor(config_string('weechat.color.nicklist_prefix%d' \
+            %(modes.find(mode) + 1)))
+    else:
+        mode = mode_color = ''
+    # nick color
+    nick_color = weechat.info_get('irc_nick_color', nick)
+    if not nick_color:
+        # probably we're in WeeChat 0.3.0
+        #debug('no irc_nick_color')
+        color_nicks_number = config_int('weechat.look.color_nicks_number')
+        idx = (sum(map(ord, nick))%color_nicks_number) + 1
+        nick_color = wcolor(config_string('weechat.color.chat_nick_color%02d' %idx))
+    return ''.join((prefix_c, prefix, mode_color, mode, nick_color, nick, suffix_c, suffix))
+
+### Config and value validation ###
+boolDict = {'on':True, 'off':False}
+def get_config_boolean(config):
+    value = weechat.config_get_plugin(config)
+    try:
+        return boolDict[value]
+    except KeyError:
+        default = settings[config]
+        error("Error while fetching config '%s'. Using default value '%s'." %(config, default))
+        error("'%s' is invalid, allowed: 'on', 'off'" %value)
+        return boolDict[default]
+
+def get_config_int(config, allow_empty_string=False):
+    value = weechat.config_get_plugin(config)
+    try:
+        return int(value)
+    except ValueError:
+        if value == '' and allow_empty_string:
+            return value
+        default = settings[config]
+        error("Error while fetching config '%s'. Using default value '%s'." %(config, default))
+        error("'%s' is not a number." %value)
+        return int(default)
+
+def get_config_log_filter():
+    filter = weechat.config_get_plugin('log_filter')
+    if filter:
+        return filter.split(',')
+    else:
+        return []
+
+def get_home():
+    home = weechat.config_string(weechat.config_get('logger.file.path'))
+    return home.replace('%h', weechat.info_get('weechat_dir', ''))
+
+def strip_home(s, dir=''):
+    """Strips home dir from the begging of the log path, this makes them sorter."""
+    if not dir:
+        global home_dir
+        dir = home_dir
+    l = len(dir)
+    if s[:l] == dir:
+        return s[l:]
+    return s
+
+### Messages ###
+script_nick = SCRIPT_NAME
+def error(s, buffer=''):
+    """Error msg"""
+    prnt(buffer, '%s%s %s' %(weechat.prefix('error'), script_nick, s))
+    if weechat.config_get_plugin('debug'):
+        import traceback
+        if traceback.sys.exc_type:
+            trace = traceback.format_exc()
+            prnt('', trace)
+
+def say(s, buffer=''):
+    """normal msg"""
+    prnt_date_tags(buffer, 0, 'no_highlight', '%s\t%s' %(script_nick, s))
+
+
+
+### Log files and buffers ###
+cache_dir = {} # note: don't remove, needed for completion if the script was loaded recently
+def dir_list(dir, filter_list=(), filter_excludes=True, include_dir=False):
+    """Returns a list of files in 'dir' and its subdirs."""
+    global cache_dir
+    from os import walk
+    from fnmatch import fnmatch
+    #debug('dir_list: listing in %s' %dir)
+    key = (dir, include_dir)
+    try:
+        return cache_dir[key]
+    except KeyError:
+        pass
+    
+    filter_list = filter_list or get_config_log_filter()
+    dir_len = len(dir)
+    if filter_list:
+        def filter(file):
+            file = file[dir_len:] # pattern shouldn't match home dir
+            for pattern in filter_list:
+                if fnmatch(file, pattern):
+                    return filter_excludes
+            return not filter_excludes
+    else:
+        filter = lambda f : not filter_excludes
+
+    file_list = []
+    extend = file_list.extend
+    join = path.join
+    def walk_path():
+        for basedir, subdirs, files in walk(dir):
+            #if include_dir:
+            #    subdirs = map(lambda s : join(s, ''), subdirs)
+            #    files.extend(subdirs)
+            files_path = map(lambda f : join(basedir, f), files)
+            files_path = [ file for file in files_path if not filter(file) ]
+            extend(files_path)
+
+    walk_path()
+    cache_dir[key] = file_list
+    #debug('dir_list: got %s' %str(file_list))
+    return file_list
+
+def get_file_by_pattern(pattern, all=False):
+    """Returns the first log whose path matches 'pattern',
+    if all is True returns all logs that matches."""
+    if not pattern: return []
+    #debug('get_file_by_filename: searching for %s.' %pattern)
+    # do envvar expandsion and check file
+    file = path.expanduser(pattern)
+    file = path.expandvars(file)
+    if path.isfile(file):
+        return [file]
+    # lets see if there's a matching log
+    global home_dir
+    file = path.join(home_dir, pattern)
+    if path.isfile(file):
+        return [file]
+    else:
+        from fnmatch import fnmatch
+        file = []
+        file_list = dir_list(home_dir)
+        n = len(home_dir)
+        for log in file_list:
+            basename = log[n:]
+            if fnmatch(basename, pattern):
+                file.append(log)
+        #debug('get_file_by_filename: got %s.' %file)
+        if not all and file:
+            file.sort()
+            return [ file[-1] ]
+        return file
+
+def get_file_by_buffer(buffer):
+    """Given buffer pointer, finds log's path or returns None."""
+    #debug('get_file_by_buffer: searching for %s' %buffer)
+    infolist = weechat.infolist_get('logger_buffer', '', '')
+    if not infolist: return
+    try:
+        while weechat.infolist_next(infolist):
+            pointer = weechat.infolist_pointer(infolist, 'buffer')
+            if pointer == buffer:
+                file = weechat.infolist_string(infolist, 'log_filename')
+                if weechat.infolist_integer(infolist, 'log_enabled'):
+                    #debug('get_file_by_buffer: got %s' %file)
+                    return file
+                #else:
+                #    debug('get_file_by_buffer: got %s but log not enabled' %file)
+    finally:
+        #debug('infolist gets freed')
+        weechat.infolist_free(infolist)
+
+def get_file_by_name(buffer_name):
+    """Given a buffer name, returns its log path or None. buffer_name should be in 'server.#channel'
+    or '#channel' format."""
+    #debug('get_file_by_name: searching for %s' %buffer_name)
+    # common mask options
+    config_masks = ('logger.mask.irc', 'logger.file.mask')
+    # since there's no buffer pointer, we try to replace some local vars in mask, like $channel and
+    # $server, then replace the local vars left with '*', and use it as a mask for get the path with
+    # get_file_by_pattern
+    for config in config_masks:
+        mask = weechat.config_string(weechat.config_get(config))
+        #debug('get_file_by_name: mask: %s' %mask)
+        if '$name' in mask:
+            mask = mask.replace('$name', buffer_name)
+        elif '$channel' in mask or '$server' in mask:
+            if '.' in buffer_name and \
+                    '#' not in buffer_name[:buffer_name.find('.')]: # the dot isn't part of the channel name
+                #    ^ I'm asuming channel starts with #, i'm lazy.
+                server, channel = buffer_name.split('.', 1)
+            else:
+                server, channel = '*', buffer_name
+            if '$channel' in mask:
+                mask = mask.replace('$channel', channel)
+            if '$server' in mask:
+                mask = mask.replace('$server', server)
+        # change the unreplaced vars by '*'
+        from string import letters
+        if '%' in mask:
+            # vars for time formatting
+            mask = mask.replace('%', '$')
+        if '$' in mask:
+            masks = mask.split('$')
+            masks = map(lambda s: s.lstrip(letters), masks)
+            mask = '*'.join(masks)
+            if mask[0] != '*':
+                mask = '*' + mask
+        #debug('get_file_by_name: using mask %s' %mask)
+        file = get_file_by_pattern(mask)
+        #debug('get_file_by_name: got file %s' %file)
+        if file:
+            return file
+    return None
+
+def get_buffer_by_name(buffer_name):
+    """Given a buffer name returns its buffer pointer or None."""
+    #debug('get_buffer_by_name: searching for %s' %buffer_name)
+    pointer = weechat.buffer_search('', buffer_name)
+    if not pointer:
+        try:
+            infolist = weechat.infolist_get('buffer', '', '')
+            while weechat.infolist_next(infolist):
+                short_name = weechat.infolist_string(infolist, 'short_name')
+                name = weechat.infolist_string(infolist, 'name')
+                if buffer_name in (short_name, name):
+                    #debug('get_buffer_by_name: found %s' %name)
+                    pointer = weechat.buffer_search('', name)
+                    return pointer
+        finally:
+            weechat.infolist_free(infolist)
+    #debug('get_buffer_by_name: got %s' %pointer)
+    return pointer
+
+def get_all_buffers():
+    """Returns list with pointers of all open buffers."""
+    buffers = []
+    infolist = weechat.infolist_get('buffer', '', '')
+    while weechat.infolist_next(infolist):
+        buffers.append(weechat.infolist_pointer(infolist, 'pointer'))
+    weechat.infolist_free(infolist)
+    grep_buffer = weechat.buffer_search('python', SCRIPT_NAME)
+    if grep_buffer and grep_buffer in buffers:
+        # remove it from list
+        del buffers[buffers.index(grep_buffer)]
+    return buffers
+
+### Grep ###
+def make_regexp(pattern, matchcase=False):
+    """Returns a compiled regexp."""
+    if pattern in ('.', '.*', '.?', '.+'):
+        # because I don't need to use a regexp if we're going to match all lines
+        return None
+    # matching takes a lot more time if pattern starts or ends with .* and it isn't needed.
+    if pattern[:2] == '.*':
+        pattern = pattern[2:]
+    if pattern[-2:] == '.*':
+        pattern = pattern[:-2]
+    try:
+        if not matchcase:
+            regexp = re.compile(pattern, re.IGNORECASE)
+        else:
+            regexp = re.compile(pattern)
+    except Exception, e:
+        raise Exception, 'Bad pattern, %s' %e
+    return regexp
+
+def check_string(s, regexp, hilight='', exact=False):
+    """Checks 's' with a regexp and returns it if is a match."""
+    if not regexp:
+        return s
+
+    elif exact:
+        matchlist = regexp.findall(s)
+        if matchlist:
+            if isinstance(matchlist[0], tuple):
+                # join tuples (when there's more than one match group in regexp)
+                return [ ' '.join(t) for t in matchlist ]
+            return matchlist
+
+    elif hilight:
+        matchlist = regexp.findall(s)
+        if matchlist:
+            if isinstance(matchlist[0], tuple):
+                # flatten matchlist
+                matchlist = [ item for L in matchlist for item in L if item ]
+            matchlist = list(set(matchlist)) # remove duplicates if any
+            # apply hilight
+            color_hilight, color_reset = hilight.split(',', 1)
+            for m in matchlist:
+                s = s.replace(m, '%s%s%s' % (color_hilight, m, color_reset))
+            return s
+
+    # no need for findall() here
+    elif regexp.search(s):
+        return s
+
+def grep_file(file, head, tail, after_context, before_context, count, regexp, hilight, exact, invert):
+    """Return a list of lines that match 'regexp' in 'file', if no regexp returns all lines."""
+    if count:
+        tail = head = after_context = before_context = False
+        hilight = ''
+    elif exact:
+        before_context = after_context = False
+        hilight = ''
+    elif invert:
+        hilight = ''
+    #debug(' '.join(map(str, (file, head, tail, after_context, before_context))))
+
+    lines = linesList()
+    # define these locally as it makes the loop run slightly faster
+    append = lines.append
+    count_match = lines.count_match
+    separator = lines.append_separator
+    if invert:
+        def check(s):
+            if check_string(s, regexp, hilight, exact):
+                return None
+            else:
+                return s
+    else:
+        check = lambda s: check_string(s, regexp, hilight, exact)
+    
+    try:
+        file_object = open(file, 'r')
+    except IOError:
+        # file doesn't exist
+        return lines
+    if tail or before_context:
+        # for these options, I need to seek in the file, but is slower and uses a good deal of
+        # memory if the log is too big, so we do this *only* for these options.
+        file_lines = file_object.readlines()
+
+        if tail:
+            # instead of searching in the whole file and later pick the last few lines, we
+            # reverse the log, search until count reached and reverse it again, that way is a lot
+            # faster
+            file_lines.reverse()
+            # don't invert context switches
+            before_context, after_context = after_context, before_context
+
+        if before_context:
+            before_context_range = range(1, before_context + 1)
+            before_context_range.reverse()
+
+        limit = tail or head
+
+        line_idx = 0
+        while line_idx < len(file_lines):
+            line = file_lines[line_idx]
+            line = check(line)
+            if line:
+                if before_context:
+                    separator()
+                    trimmed = False
+                    for id in before_context_range:
+                        try:
+                            context_line = file_lines[line_idx - id]
+                            if check(context_line):
+                                # match in before context, that means we appended these same lines in a
+                                # previous match, so we delete them merging both paragraphs
+                                if not trimmed:
+                                    del lines[id - before_context - 1:]
+                                    trimmed = True
+                            else:
+                                append(context_line)
+                        except IndexError:
+                            pass
+                append(line)
+                count_match(line)
+                if after_context:
+                    id, offset = 0, 0
+                    while id < after_context + offset:
+                        id += 1
+                        try:
+                            context_line = file_lines[line_idx + id]
+                            _context_line = check(context_line)
+                            if _context_line:
+                                offset = id
+                                context_line = _context_line # so match is hilighted with --hilight
+                                count_match()
+                            append(context_line)
+                        except IndexError:
+                            pass
+                    separator()
+                    line_idx += id
+                if limit and lines.matches_count >= limit:
+                    break
+            line_idx += 1
+
+        if tail:
+            lines.reverse()
+    else:
+        # do a normal grep
+        limit = head
+
+        for line in file_object:
+            line = check(line)
+            if line:
+                count or append(line)
+                count_match(line)
+                if after_context:
+                    id, offset = 0, 0
+                    while id < after_context + offset:
+                        id += 1
+                        try:
+                            context_line = file_object.next()
+                            _context_line = check(context_line)
+                            if _context_line:
+                                offset = id
+                                context_line = _context_line
+                                count_match()
+                            count or append(context_line)
+                        except StopIteration:
+                            pass
+                    separator()
+                if limit and lines.matches_count >= limit:
+                    break
+
+    file_object.close()
+    return lines
+
+def grep_buffer(buffer, head, tail, after_context, before_context, count, regexp, hilight, exact,
+        invert):
+    """Return a list of lines that match 'regexp' in 'buffer', if no regexp returns all lines."""
+    lines = linesList()
+    if count:
+        tail = head = after_context = before_context = False
+        hilight = ''
+    elif exact:
+        before_context = after_context = False
+    #debug(' '.join(map(str, (tail, head, after_context, before_context, count, exact, hilight))))
+
+    # Using /grep in grep's buffer can lead to some funny effects
+    # We should take measures if that's the case
+    def make_get_line_funcion():
+        """Returns a function for get lines from the infolist, depending if the buffer is grep's or
+        not."""
+        string_remove_color = weechat.string_remove_color
+        infolist_string = weechat.infolist_string
+        grep_buffer = weechat.buffer_search('python', SCRIPT_NAME)
+        if grep_buffer and buffer == grep_buffer:
+            def function(infolist):
+                prefix = infolist_string(infolist, 'prefix')
+                message = infolist_string(infolist, 'message')
+                if prefix: # only our messages have prefix, ignore it
+                    return None
+                return message
+        else:
+            infolist_time = weechat.infolist_time
+            def function(infolist):
+                prefix = string_remove_color(infolist_string(infolist, 'prefix'), '')
+                message = string_remove_color(infolist_string(infolist, 'message'), '')
+                date = infolist_time(infolist, 'date')
+                return '%s\t%s\t%s' %(date, prefix, message)
+        return function
+    get_line = make_get_line_funcion()
+
+    infolist = weechat.infolist_get('buffer_lines', buffer, '')
+    if tail:
+        # like with grep_file() if we need the last few matching lines, we move the cursor to
+        # the end and search backwards
+        infolist_next = weechat.infolist_prev
+        infolist_prev = weechat.infolist_next
+    else:
+        infolist_next = weechat.infolist_next
+        infolist_prev = weechat.infolist_prev
+    limit = head or tail
+
+    # define these locally as it makes the loop run slightly faster
+    append = lines.append
+    count_match = lines.count_match
+    separator = lines.append_separator
+    if invert:
+        def check(s):
+            if check_string(s, regexp, hilight, exact):
+                return None
+            else:
+                return s
+    else:
+        check = lambda s: check_string(s, regexp, hilight, exact)
+
+    if before_context:
+        before_context_range = range(1, before_context + 1)
+        before_context_range.reverse()
+
+    while infolist_next(infolist):
+        line = get_line(infolist)
+        if line is None: continue
+        line = check(line)
+        if line:
+            if before_context:
+                separator()
+                trimmed = False
+                for id in before_context_range:
+                    if not infolist_prev(infolist):
+                        trimmed = True
+                for id in before_context_range:
+                    context_line = get_line(infolist)
+                    if check(context_line):
+                        if not trimmed:
+                            del lines[id - before_context - 1:]
+                            trimmed = True
+                    else:
+                        append(context_line)
+                    infolist_next(infolist)
+            count or append(line)
+            count_match(line)
+            if after_context:
+                id, offset = 0, 0
+                while id < after_context + offset:
+                    id += 1
+                    if infolist_next(infolist):
+                        context_line = get_line(infolist)
+                        _context_line = check(context_line)
+                        if _context_line:
+                            context_line = _context_line
+                            offset = id
+                            count_match()
+                        append(context_line)
+                    else:
+                        # in the main loop infolist_next will start again an cause an infinite loop
+                        # this will avoid it
+                        infolist_next = lambda x: 0
+                separator()
+            if limit and lines.matches_count >= limit:
+                break
+    weechat.infolist_free(infolist)
+
+    if tail:
+        lines.reverse()
+    return lines
+
+### this is our main grep function
+hook_file_grep = None
+def show_matching_lines():
+    """
+    Greps buffers in search_in_buffers or files in search_in_files and updates grep buffer with the
+    result.
+    """
+    global pattern, matchcase, number, count, exact, hilight, invert
+    global tail, head, after_context, before_context
+    global search_in_files, search_in_buffers, matched_lines, home_dir
+    global time_start
+    matched_lines = linesDict()
+    #debug('buffers:%s \nlogs:%s' %(search_in_buffers, search_in_files))
+    time_start = now()
+
+    # buffers
+    if search_in_buffers:
+        regexp = make_regexp(pattern, matchcase)
+        for buffer in search_in_buffers:
+            buffer_name = weechat.buffer_get_string(buffer, 'name')
+            matched_lines[buffer_name] = grep_buffer(buffer, head, tail, after_context,
+                    before_context, count, regexp, hilight, exact, invert)
+
+    # logs
+    if search_in_files:
+        size_limit = get_config_int('size_limit', allow_empty_string=True)
+        background = False
+        if size_limit or size_limit == 0:
+            size = sum(map(get_size, search_in_files))
+            if size > size_limit * 1024:
+                background = True
+        elif size_limit == '':
+            background = False
+
+        if not background:
+            # run grep normally
+            regexp = make_regexp(pattern, matchcase)
+            for log in search_in_files:
+                log_name = strip_home(log)
+                matched_lines[log_name] = grep_file(log, head, tail, after_context, before_context,
+                        count, regexp, hilight, exact, invert)
+            buffer_update()
+        else:
+            # we hook a process so grepping runs in background.
+            #debug('on background')
+            global hook_file_grep, script_path, bytecode
+            timeout = 1000*60*5 # 5 min
+
+            quotify = lambda s: '"%s"' %s
+            files_string = ', '.join(map(quotify, search_in_files))
+
+            global tmpFile
+            # we keep the file descriptor as a global var so it isn't deleted until next grep
+            tmpFile = tempfile.NamedTemporaryFile(prefix=SCRIPT_NAME,
+                    dir=weechat.info_get('weechat_dir', ''))
+            cmd = grep_process_cmd %dict(logs=files_string, head=head, pattern=pattern, tail=tail,
+                    hilight=hilight, after_context=after_context, before_context=before_context,
+                    exact=exact, matchcase=matchcase, home_dir=home_dir, script_path=script_path,
+                    count=count, invert=invert, bytecode=bytecode, filename=tmpFile.name,
+                    python=weechat.info_get('python2_bin', '') or 'python')
+
+            #debug(cmd)
+            hook_file_grep = weechat.hook_process(cmd, timeout, 'grep_file_callback', tmpFile.name)
+            global pattern_tmpl
+            if hook_file_grep:
+                buffer_create("Searching for '%s' in %s worth of data..." %(pattern_tmpl,
+                    human_readable_size(size)))
+    else:
+        buffer_update()
+
+# defined here for commodity
+grep_process_cmd = """%(python)s -%(bytecode)sc '
+import sys, cPickle, os
+sys.path.append("%(script_path)s") # add WeeChat script dir so we can import grep
+from grep import make_regexp, grep_file, strip_home
+logs = (%(logs)s, )
+try:
+    regexp = make_regexp("%(pattern)s", %(matchcase)s)
+    d = {}
+    for log in logs:
+        log_name = strip_home(log, "%(home_dir)s")
+        lines = grep_file(log, %(head)s, %(tail)s, %(after_context)s, %(before_context)s,
+        %(count)s, regexp, "%(hilight)s", %(exact)s, %(invert)s)
+        d[log_name] = lines
+    fd = open("%(filename)s", "wb")
+    cPickle.dump(d, fd, -1)
+    fd.close()
+except Exception, e:
+    print >> sys.stderr, e'
+"""
+
+grep_stdout = grep_stderr = ''
+def grep_file_callback(filename, command, rc, stdout, stderr):
+    global hook_file_grep, grep_stderr,  grep_stdout
+    global matched_lines
+    #debug("rc: %s\nstderr: %s\nstdout: %s" %(rc, repr(stderr), repr(stdout)))
+    if stdout:
+        grep_stdout += stdout
+    if stderr:
+        grep_stderr += stderr
+    if int(rc) >= 0:
+  
+        def set_buffer_error():
+            grep_buffer = buffer_create()
+            title = weechat.buffer_get_string(grep_buffer, 'title')
+            title = title + ' %serror' %color_title
+            weechat.buffer_set(grep_buffer, 'title', title)
+
+        try:
+            if grep_stderr:
+                error(grep_stderr)
+                set_buffer_error()
+            #elif grep_stdout:
+                #debug(grep_stdout)
+            elif path.exists(filename):
+                import cPickle
+                try:
+                    #debug(file)
+                    fd = open(filename, 'rb')
+                    d = cPickle.load(fd)
+                    matched_lines.update(d)
+                    fd.close()
+                except Exception, e:
+                    error(e)
+                    set_buffer_error()
+                else:
+                    buffer_update()
+            global tmpFile
+            tmpFile = None
+        finally:
+            grep_stdout = grep_stderr = ''
+            hook_file_grep = None
+    return WEECHAT_RC_OK
+
+def get_grep_file_status():
+    global search_in_files, matched_lines, time_start
+    elapsed = now() - time_start
+    if len(search_in_files) == 1:
+        log = '%s (%s)' %(strip_home(search_in_files[0]),
+                human_readable_size(get_size(search_in_files[0])))
+    else:
+        size = sum(map(get_size, search_in_files))
+        log = '%s log files (%s)' %(len(search_in_files), human_readable_size(size))
+    return 'Searching in %s, running for %.4f seconds. Interrupt it with "/grep stop" or "stop"' \
+        ' in grep buffer.' %(log, elapsed)
+
+### Grep buffer ###
+def buffer_update():
+    """Updates our buffer with new lines."""
+    global pattern_tmpl, matched_lines, pattern, count, hilight, invert, exact
+    time_grep = now()
+
+    buffer = buffer_create()
+    if get_config_boolean('clear_buffer'):
+        weechat.buffer_clear(buffer)
+    matched_lines.strip_separator() # remove first and last separators of each list
+    len_total_lines = len(matched_lines)
+    max_lines = get_config_int('max_lines')
+    if not count and len_total_lines > max_lines:
+        weechat.buffer_clear(buffer)
+
+    def _make_summary(log, lines, note):
+        return '%s matches "%s%s%s"%s in %s%s%s%s' \
+                %(lines.matches_count, color_summary, pattern_tmpl, color_info,
+                  invert and ' (inverted)' or '',
+                  color_summary, log, color_reset, note)
+
+    if count:
+        make_summary = lambda log, lines : _make_summary(log, lines, ' (not shown)')
+    else:
+        def make_summary(log, lines):
+            if lines.stripped_lines:
+                if lines:
+                    note = ' (last %s lines shown)' %len(lines)
+                else:
+                    note = ' (not shown)'
+            else:
+                note = ''
+            return _make_summary(log, lines, note)
+
+    global weechat_format
+    if hilight:
+        # we don't want colors if there's match highlighting
+        format_line = lambda s : '%s %s %s' %split_line(s)
+    else:
+        def format_line(s):
+            global nick_dict, weechat_format
+            date, nick, msg = split_line(s)
+            if weechat_format:
+                try:
+                    nick = nick_dict[nick]
+                except KeyError:
+                    # cache nick
+                    nick_c = color_nick(nick)
+                    nick_dict[nick] = nick_c
+                    nick = nick_c
+                return '%s%s %s%s %s' %(color_date, date, nick, color_reset, msg)
+            else:
+                #no formatting
+                return msg
+
+    prnt(buffer, '\n')
+    print_line('Search for "%s%s%s"%s in %s%s%s.' %(color_summary, pattern_tmpl, color_info,
+        invert and ' (inverted)' or '', color_summary, matched_lines, color_reset),
+            buffer)
+    # print last <max_lines> lines
+    if matched_lines.get_matches_count():
+        if count:
+            # with count we sort by matches lines instead of just lines.
+            matched_lines_items = matched_lines.items_count()
+        else:
+            matched_lines_items = matched_lines.items()
+
+        matched_lines.get_last_lines(max_lines)
+        for log, lines in matched_lines_items:
+            if lines.matches_count:
+                # matched lines
+                if not count:
+                    # print lines
+                    weechat_format = True
+                    if exact:
+                        lines.onlyUniq()
+                    for line in lines:
+                        #debug(repr(line))
+                        if line == linesList._sep:
+                            # separator
+                            prnt(buffer, context_sep)
+                        else:
+                            if '\x00' in line:
+                                # log was corrupted
+                                error("Found garbage in log '%s', maybe it's corrupted" %log)
+                                line = line.replace('\x00', '')
+                            prnt_date_tags(buffer, 0, 'no_highlight', format_line(line))
+
+                # summary
+                if count or get_config_boolean('show_summary'):
+                    summary = make_summary(log, lines)
+                    print_line(summary, buffer)
+
+            # separator
+            if not count and lines:
+                prnt(buffer, '\n')
+    else:
+        print_line('No matches found.', buffer)
+
+    # set title
+    global time_start
+    time_end = now()
+    # total time
+    time_total = time_end - time_start
+    # percent of the total time used for grepping
+    time_grep_pct = (time_grep - time_start)/time_total*100
+    #debug('time: %.4f seconds (%.2f%%)' %(time_total, time_grep_pct))
+    if not count and len_total_lines > max_lines:
+        note = ' (last %s lines shown)' %len(matched_lines)
+    else:
+        note = ''
+    title = "Search in %s%s%s %s matches%s | pattern \"%s%s%s\"%s %s | %.4f seconds (%.2f%%)" \
+            %(color_title, matched_lines, color_reset, matched_lines.get_matches_count(), note,
+              color_title, pattern_tmpl, color_reset, invert and ' (inverted)' or '', format_options(),
+              time_total, time_grep_pct)
+    weechat.buffer_set(buffer, 'title', title)
+
+    if get_config_boolean('go_to_buffer'):
+        weechat.buffer_set(buffer, 'display', '1')
+
+    # free matched_lines so it can be removed from memory
+    del matched_lines
+    
+def split_line(s):
+    """Splits log's line 's' in 3 parts, date, nick and msg."""
+    global weechat_format
+    if weechat_format and s.count('\t') >= 2:
+        date, nick, msg = s.split('\t', 2) # date, nick, message
+    else:
+        # looks like log isn't in weechat's format
+        weechat_format = False # incoming lines won't be formatted
+        date, nick, msg = '', '', s
+    # remove tabs
+    if '\t' in msg:
+        msg = msg.replace('\t', '    ')
+    return date, nick, msg
+
+def print_line(s, buffer=None, display=False):
+    """Prints 's' in script's buffer as 'script_nick'. For displaying search summaries."""
+    if buffer is None:
+        buffer = buffer_create()
+    say('%s%s' %(color_info, s), buffer)
+    if display and get_config_boolean('go_to_buffer'):
+        weechat.buffer_set(buffer, 'display', '1')
+
+def format_options():
+    global matchcase, number, count, exact, hilight, invert
+    global tail, head, after_context, before_context
+    options = []
+    append = options.append
+    insert = options.insert
+    chars = 'cHmov'
+    for i, flag in enumerate((count, hilight, matchcase, exact, invert)):
+        if flag:
+            append(chars[i])
+
+    if head or tail:
+        n = get_config_int('default_tail_head')
+        if head:
+            append('h')
+            if head != n:
+                insert(-1, ' -')
+                append('n')
+                append(head)
+        elif tail:
+            append('t')
+            if tail != n:
+                insert(-1, ' -')
+                append('n')
+                append(tail)
+
+    if before_context and after_context and (before_context == after_context):
+        append(' -C')
+        append(before_context)
+    else:
+        if before_context:
+            append(' -B')
+            append(before_context)
+        if after_context:
+            append(' -A')
+            append(after_context)
+
+    s = ''.join(map(str, options)).strip()
+    if s and s[0] != '-':
+        s = '-' + s
+    return s
+
+def buffer_create(title=None):
+    """Returns our buffer pointer, creates and cleans the buffer if needed."""
+    buffer = weechat.buffer_search('python', SCRIPT_NAME)
+    if not buffer:
+        buffer = weechat.buffer_new(SCRIPT_NAME, 'buffer_input', '', '', '')
+        weechat.buffer_set(buffer, 'time_for_each_line', '0')
+        weechat.buffer_set(buffer, 'nicklist', '0')
+        weechat.buffer_set(buffer, 'title', title or 'grep output buffer')
+        weechat.buffer_set(buffer, 'localvar_set_no_log', '1')
+    elif title:
+        weechat.buffer_set(buffer, 'title', title)
+    return buffer
+
+def buffer_input(data, buffer, input_data):
+    """Repeats last search with 'input_data' as regexp."""
+    try:
+        cmd_grep_stop(buffer, input_data)
+    except:
+        return WEECHAT_RC_OK
+
+    global search_in_buffers, search_in_files
+    global pattern
+    try:
+        if pattern and (search_in_files or search_in_buffers):
+            # check if the buffer pointers are still valid
+            for pointer in search_in_buffers:
+                infolist = weechat.infolist_get('buffer', pointer, '')
+                if not infolist:
+                    del search_in_buffers[search_in_buffers.index(pointer)]
+                weechat.infolist_free(infolist)
+            try:
+                cmd_grep_parsing(input_data)
+            except Exception, e:
+                error('Argument error, %s' %e, buffer=buffer)
+                return WEECHAT_RC_OK
+            try:
+                show_matching_lines()
+            except Exception, e:
+                error(e)
+    except NameError:
+        error("There isn't any previous search to repeat.", buffer=buffer)
+    return WEECHAT_RC_OK
+
+### Commands ###
+def cmd_init():
+    """Resets global vars."""
+    global home_dir, cache_dir, nick_dict
+    global pattern_tmpl, pattern, matchcase, number, count, exact, hilight, invert
+    global tail, head, after_context, before_context
+    hilight = ''
+    head = tail = after_context = before_context = invert = False
+    matchcase = count = exact = False
+    pattern_tmpl = pattern = number = None
+    home_dir = get_home()
+    cache_dir = {} # for avoid walking the dir tree more than once per command
+    nick_dict = {} # nick cache for don't calculate nick color every time
+
+def cmd_grep_parsing(args):
+    """Parses args for /grep and grep input buffer."""
+    global pattern_tmpl, pattern, matchcase, number, count, exact, hilight, invert
+    global tail, head, after_context, before_context
+    global log_name, buffer_name, only_buffers, all
+    opts, args = getopt.gnu_getopt(args.split(), 'cmHeahtivn:bA:B:C:o', ['count', 'matchcase', 'hilight',
+        'exact', 'all', 'head', 'tail', 'number=', 'buffer', 'after-context=', 'before-context=',
+        'context=', 'invert', 'only-match'])
+    #debug(opts, 'opts: '); debug(args, 'args: ')
+    if len(args) >= 2:
+        if args[0] == 'log':
+            del args[0]
+            log_name = args.pop(0)
+        elif args[0] == 'buffer':
+            del args[0]
+            buffer_name = args.pop(0)
+
+    def tmplReplacer(match):
+        """This function will replace templates with regexps"""
+        s = match.groups()[0]
+        tmpl_args = s.split()
+        tmpl_key, _, tmpl_args = s.partition(' ')
+        try:
+            template = templates[tmpl_key]
+            if callable(template):
+                r = template(tmpl_args)
+                if not r:
+                    error("Template %s returned empty string "\
+                          "(WeeChat doesn't have enough data)." %t)
+                return r
+            else:
+                return template
+        except:
+            return t
+
+    args = ' '.join(args) # join pattern for keep spaces
+    if args:
+        pattern_tmpl = args  
+        pattern = _tmplRe.sub(tmplReplacer, args)
+        debug('Using regexp: %s', pattern)
+    if not pattern:
+        raise Exception, 'No pattern for grep the logs.'
+
+    def positive_number(opt, val):
+        try:
+            number = int(val)
+            if number < 0:
+                raise ValueError
+            return number
+        except ValueError:
+            if len(opt) == 1:
+                opt = '-' + opt
+            else:
+                opt = '--' + opt
+            raise Exception, "argument for %s must be a positive integer." %opt
+
+    for opt, val in opts:
+        opt = opt.strip('-')
+        if opt in ('c', 'count'):
+            count = not count
+        elif opt in ('m', 'matchcase'):
+            matchcase = not matchcase
+        elif opt in ('H', 'hilight'):
+            # hilight must be always a string!
+            if hilight:
+                hilight = ''
+            else:
+                hilight = '%s,%s' %(color_hilight, color_reset)
+            # we pass the colors in the variable itself because check_string() must not use
+            # weechat's module when applying the colors (this is for grep in a hooked process)
+        elif opt in ('e', 'exact', 'o', 'only-match'):
+            exact = not exact
+            invert = False
+        elif opt in ('a', 'all'):
+            all = not all
+        elif opt in ('h', 'head'):
+            head = not head
+            tail = False
+        elif opt in ('t', 'tail'):
+            tail = not tail
+            head = False
+        elif opt in ('b', 'buffer'):
+            only_buffers = True
+        elif opt in ('n', 'number'):
+            number = positive_number(opt, val)
+        elif opt in ('C', 'context'):
+            n = positive_number(opt, val)
+            after_context = n
+            before_context = n
+        elif opt in ('A', 'after-context'):
+            after_context = positive_number(opt, val)
+        elif opt in ('B', 'before-context'):
+            before_context = positive_number(opt, val)
+        elif opt in ('i', 'v', 'invert'):
+            invert = not invert
+            exact = False
+    # number check
+    if number is not None:
+        if number == 0:
+            head = tail = False
+            number = None
+        elif head:
+            head = number
+        elif tail:
+            tail = number
+    else:
+        n = get_config_int('default_tail_head')
+        if head:
+            head = n
+        elif tail:
+            tail = n
+
+def cmd_grep_stop(buffer, args):
+    global hook_file_grep, pattern, matched_lines, tmpFile
+    if hook_file_grep:
+        if args == 'stop':
+            weechat.unhook(hook_file_grep)
+            hook_file_grep = None
+            s = 'Search for \'%s\' stopped.' %pattern
+            say(s, buffer)
+            grep_buffer = weechat.buffer_search('python', SCRIPT_NAME)
+            if grep_buffer:
+                weechat.buffer_set(grep_buffer, 'title', s)
+            del matched_lines
+            tmpFile = None
+        else:
+            say(get_grep_file_status(), buffer)
+        raise Exception
+
+def cmd_grep(data, buffer, args):
+    """Search in buffers and logs."""
+    global pattern, matchcase, head, tail, number, count, exact, hilight
+    try:
+        cmd_grep_stop(buffer, args)
+    except:
+        return WEECHAT_RC_OK
+
+    if not args:
+        weechat.command('', '/help %s' %SCRIPT_COMMAND)
+        return WEECHAT_RC_OK
+
+    cmd_init()
+    global log_name, buffer_name, only_buffers, all
+    log_name = buffer_name = ''
+    only_buffers = all = False
+
+    # parse
+    try:
+        cmd_grep_parsing(args)
+    except Exception, e:
+        error('Argument error, %s' %e)
+        return WEECHAT_RC_OK
+
+    # find logs
+    log_file = search_buffer = None
+    if log_name:
+        log_file = get_file_by_pattern(log_name, all)
+        if not log_file:
+            error("Couldn't find any log for %s. Try /logs" %log_name)
+            return WEECHAT_RC_OK
+    elif all:
+        search_buffer = get_all_buffers()
+    elif buffer_name:
+        search_buffer = get_buffer_by_name(buffer_name)
+        if not search_buffer:
+            # there's no buffer, try in the logs
+            log_file = get_file_by_name(buffer_name)
+            if not log_file:
+                error("Logs or buffer for '%s' not found." %buffer_name)
+                return WEECHAT_RC_OK
+        else:
+            search_buffer = [search_buffer]
+    else:
+        search_buffer = [buffer]
+
+    # make the log list
+    global search_in_files, search_in_buffers
+    search_in_files = []
+    search_in_buffers = []
+    if log_file:
+        search_in_files = log_file
+    elif not only_buffers:
+        #debug(search_buffer)
+        for pointer in search_buffer:
+            log = get_file_by_buffer(pointer)
+            #debug('buffer %s log %s' %(pointer, log))
+            if log:
+                search_in_files.append(log)
+            else:
+                search_in_buffers.append(pointer)
+    else:
+        search_in_buffers = search_buffer
+
+    # grepping
+    try:
+        show_matching_lines()
+    except Exception, e:
+        error(e)
+    return WEECHAT_RC_OK
+
+def cmd_logs(data, buffer, args):
+    """List files in Weechat's log dir."""
+    cmd_init()
+    global home_dir
+    sort_by_size = False
+    filter = []
+
+    try:
+        opts, args = getopt.gnu_getopt(args.split(), 's', ['size'])
+        if args:
+            filter = args
+        for opt, var in opts:
+            opt = opt.strip('-')
+            if opt in ('size', 's'):
+                sort_by_size = True
+    except Exception, e:
+        error('Argument error, %s' %e)
+        return WEECHAT_RC_OK
+
+    # is there's a filter, filter_excludes should be False
+    file_list = dir_list(home_dir, filter, filter_excludes=not filter)
+    if sort_by_size:
+        file_list.sort(key=get_size)
+    else:
+        file_list.sort()
+
+    file_sizes = map(lambda x: human_readable_size(get_size(x)), file_list)
+    # calculate column lenght
+    if file_list:
+        L = file_list[:]
+        L.sort(key=len)
+        bigest = L[-1]
+        column_len = len(bigest) + 3
+    else:
+        column_len = ''
+
+    buffer = buffer_create()
+    if get_config_boolean('clear_buffer'):
+        weechat.buffer_clear(buffer)
+    file_list = zip(file_list, file_sizes)
+    msg = 'Found %s logs.' %len(file_list)
+
+    print_line(msg, buffer, display=True)
+    for file, size in file_list:
+        separator = column_len and '.'*(column_len - len(file))
+        prnt(buffer, '%s %s %s' %(strip_home(file), separator, size))
+    if file_list:
+        print_line(msg, buffer)
+    return WEECHAT_RC_OK
+
+
+### Completion ###
+def completion_log_files(data, completion_item, buffer, completion):
+    #debug('completion: %s' %', '.join((data, completion_item, buffer, completion)))
+    global home_dir
+    l = len(home_dir)
+    completion_list_add = weechat.hook_completion_list_add
+    WEECHAT_LIST_POS_END = weechat.WEECHAT_LIST_POS_END
+    for log in dir_list(home_dir):
+        completion_list_add(completion, log[l:], 0, WEECHAT_LIST_POS_END)
+    return WEECHAT_RC_OK
+
+def completion_grep_args(data, completion_item, buffer, completion):
+    for arg in ('count', 'all', 'matchcase', 'hilight', 'exact', 'head', 'tail', 'number', 'buffer',
+            'after-context', 'before-context', 'context', 'invert', 'only-match'):
+        weechat.hook_completion_list_add(completion, '--' + arg, 0, weechat.WEECHAT_LIST_POS_SORT)
+    for tmpl in templates:
+        weechat.hook_completion_list_add(completion, '%{' + tmpl, 0, weechat.WEECHAT_LIST_POS_SORT)
+    return WEECHAT_RC_OK
+
+
+### Templates ###
+# template placeholder
+_tmplRe = re.compile(r'%\{(\w+.*?)(?:\}|$)')
+# will match 999.999.999.999 but I don't care
+ipAddress = r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
+domain = r'[\w-]{2,}(?:\.[\w-]{2,})*\.[a-z]{2,}'
+url = r'\w+://(?:%s|%s)(?::\d+)?(?:/[^\])>\s]*)?' % (domain, ipAddress)
+
+def make_url_regexp(args):
+    #debug('make url: %s', args)
+    if args:
+        words = r'(?:%s)' %'|'.join(map(re.escape, args.split()))
+        return r'(?:\w+://|www\.)[^\s]*%s[^\s]*(?:/[^\])>\s]*)?' %words
+    else:
+        return url
+
+def make_simple_regexp(pattern):
+    s = ''
+    for c in pattern:
+        if c == '*':
+            s += '.*'
+        elif c == '?':
+            s += '.'
+        else:
+            s += re.escape(c)
+    return s
+
+templates = {
+            'ip': ipAddress,
+           'url': make_url_regexp,
+        'escape': lambda s: re.escape(s),
+        'simple': make_simple_regexp,
+        'domain': domain,
+        }
+
+### Main ###
+def delete_bytecode():
+    global script_path
+    bytecode = path.join(script_path, SCRIPT_NAME + '.pyc')
+    if path.isfile(bytecode):
+        os.remove(bytecode)
+    return WEECHAT_RC_OK
+
+if __name__ == '__main__' and import_ok and \
+        weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, \
+        SCRIPT_DESC, 'delete_bytecode', ''):
+    home_dir = get_home()
+
+    # for import ourselves
+    global script_path
+    script_path = path.dirname(__file__)
+    sys.path.append(script_path)
+    delete_bytecode()
+
+    # check python version
+    import sys
+    global bytecode
+    if sys.version_info > (2, 6):
+        bytecode = 'B'
+    else:
+        bytecode = ''
+
+
+    weechat.hook_command(SCRIPT_COMMAND, cmd_grep.__doc__,
+            "[log <file> | buffer <name> | stop] [-a|--all] [-b|--buffer] [-c|--count] [-m|--matchcase] "
+            "[-H|--hilight] [-o|--only-match] [-i|-v|--invert] [(-h|--head)|(-t|--tail) [-n|--number <n>]] "
+            "[-A|--after-context <n>] [-B|--before-context <n>] [-C|--context <n> ] <expression>",
+# help
+"""
+     log <file>: Search in one log that matches <file> in the logger path.
+                 Use '*' and '?' as wildcards.
+  buffer <name>: Search in buffer <name>, if there's no buffer with <name> it will
+                 try to search for a log file.
+           stop: Stops a currently running search.
+       -a --all: Search in all open buffers.
+                 If used with 'log <file>' search in all logs that matches <file>.
+    -b --buffer: Search only in buffers, not in file logs.
+     -c --count: Just count the number of matched lines instead of showing them.
+ -m --matchcase: Don't do case insensible search.
+   -H --hilight: Colour exact matches in output buffer.
+-o --only-match: Print only the matching part of the line (unique matches).
+ -v -i --invert: Print lines that don't match the regular expression.
+      -t --tail: Print the last 10 matching lines.
+      -h --head: Print the first 10 matching lines.
+-n --number <n>: Overrides default number of lines for --tail or --head.
+-A --after-context <n>: Shows <n> lines of trailing context after matching lines.
+-B --before-context <n>: Shows <n> lines of leading context before matching lines.
+-C --context <n>: Same as using both --after-context and --before-context simultaneously.
+  <expression>: Expression to search.
+
+Grep buffer:
+  Input line accepts most arguments of /grep, it'll repeat last search using the new
+  arguments provided. You can't search in different logs from the buffer's input.
+  Boolean arguments like --count, --tail, --head, --hilight, ... are toggleable
+
+Python regular expression syntax:
+  See http://docs.python.org/lib/re-syntax.html
+
+Grep Templates:
+     %{url [text]}: Matches anything like an url, or an url with text.
+             %{ip}: Matches anything that looks like an ip.
+         %{domain}: Matches anything like a domain.
+    %{escape text}: Escapes text in pattern.
+ %{simple pattern}: Converts a pattern with '*' and '?' wildcards into a regexp.
+
+Examples:
+  Search for urls with the word 'weechat' said by 'nick'
+    /grep nick\\t.*%{url weechat}
+  Search for '*.*' string
+    /grep %{escape *.*}
+""",
+            # completion template
+            "buffer %(buffers_names) %(grep_arguments)|%*"
+            "||log %(grep_log_files) %(grep_arguments)|%*"
+            "||stop"
+            "||%(grep_arguments)|%*",
+            'cmd_grep' ,'')
+    weechat.hook_command('logs', cmd_logs.__doc__, "[-s|--size] [<filter>]",
+            "-s --size: Sort logs by size.\n"
+            " <filter>: Only show logs that match <filter>. Use '*' and '?' as wildcards.", '--size', 'cmd_logs', '')
+
+    weechat.hook_completion('grep_log_files', "list of log files",
+            'completion_log_files', '')
+    weechat.hook_completion('grep_arguments', "list of arguments",
+            'completion_grep_args', '')
+
+    # settings
+    for opt, val in settings.iteritems():
+        if not weechat.config_is_set_plugin(opt):
+            weechat.config_set_plugin(opt, val)
+
+    # colors
+    color_date        = weechat.color('brown')
+    color_info        = weechat.color('cyan')
+    color_hilight     = weechat.color('lightred')
+    color_reset       = weechat.color('reset')
+    color_title       = weechat.color('yellow')
+    color_summary     = weechat.color('lightcyan')
+    color_delimiter   = weechat.color('chat_delimiters')
+    color_script_nick = weechat.color('chat_nick')
+    
+    # pretty [grep]
+    script_nick = '%s[%s%s%s]%s' %(color_delimiter, color_script_nick, SCRIPT_NAME, color_delimiter,
+            color_reset)
+    script_nick_nocolor = '[%s]' %SCRIPT_NAME
+    # paragraph separator when using context options
+    context_sep = '%s\t%s--' %(script_nick, color_info)
+
+    # -------------------------------------------------------------------------
+    # Debug
+
+    if weechat.config_get_plugin('debug'):
+        try:
+            # custom debug module I use, allows me to inspect script's objects.
+            import pybuffer
+            debug = pybuffer.debugBuffer(globals(), '%s_debug' % SCRIPT_NAME)
+        except:
+            def debug(s, *args):
+                if not isinstance(s, basestring):
+                    s = str(s)
+                if args:
+                    s = s %args
+                prnt('', '%s\t%s' %(script_nick, s))
+    else:
+        def debug(*args):
+            pass
+
+# vim:set shiftwidth=4 tabstop=4 softtabstop=4 expandtab textwidth=100:
index 019f72e56cef1fbcd83b3e788d07bb0b25f6b13f..dbd6b8c44ef90b08ba8b157e8e204c6250b41a99 100644 (file)
@@ -1,5 +1,5 @@
 #
-# relay.conf -- weechat v1.0.1
+# relay.conf -- weechat v1.1
 #
 
 [look]
@@ -26,6 +26,7 @@ ipv6 = on
 max_clients = 5
 password = ""
 ssl_cert_key = "%h/ssl/relay.pem"
+ssl_priorities = "NORMAL:-VERS-SSL3.0"
 websocket_allowed_origins = ""
 
 [irc]
index a0fe5701159d05454ef7cad809718c7c999cc68a..59fc23a97fecf9ab7b38c33b31234b6a1acd7f29 100644 (file)
@@ -1,5 +1,5 @@
 #
-# script.conf -- weechat v1.0.1
+# script.conf -- weechat v1.1
 #
 
 [look]
@@ -46,3 +46,4 @@ cache_expire = 60
 dir = "%h/script"
 hold = ""
 url = "http://www.weechat.org/files/plugins.xml.gz"
+url_force_https = on
index c8a08d8098aa490805ab0f0b11c6d73fa1148a49..899f2a1c6fc8564be1a6f0ea8d759a10e6c4d3e8 100644 (file)
@@ -1,5 +1,5 @@
 #
-# sec.conf -- weechat v1.0.1
+# sec.conf -- weechat v1.1
 #
 
 [crypt]
index 3131ea2aa5ca6be5084d219a3f5c3718bfb2a083..da3156759d3db0416b9525035ca41421ae9e45eb 100644 (file)
@@ -1,5 +1,5 @@
 #
-# trigger.conf -- weechat v1.0.1
+# trigger.conf -- weechat v1.1
 #
 
 [look]
index 25f7fa81f84f6b163b15d7ced1d09d9f47690aee..a3d62880130cd1a96e3a7a3da00461e660d24737 100644 (file)
@@ -1,5 +1,5 @@
 #
-# weechat.conf -- weechat v1.0.1
+# weechat.conf -- weechat v1.1
 #
 
 [debug]
@@ -38,6 +38,7 @@ color_nick_offline = on
 color_pairs_auto_reset = 5
 color_real_white = off
 command_chars = ""
+command_incomplete = off
 confirm_quit = off
 day_change = off
 day_change_message_1date = "-- %a, %d %b %Y --"
@@ -67,6 +68,7 @@ input_share_overwrite = off
 input_undo_max = 32
 item_buffer_filter = "•"
 item_buffer_zoom = "!"
+item_mouse_status = "M"
 item_time_format = "%H:%M"
 jump_current_to_previous_buffer = on
 jump_previous_buffer_when_closing = on
@@ -173,6 +175,7 @@ status_data_other = default
 status_data_private = 121
 status_filter = green
 status_more = 229
+status_mouse = green
 status_name = 121
 status_name_ssl = 121
 status_nicklist_count = default
@@ -181,6 +184,7 @@ status_time = default
 
 [completion]
 base_word_until_cursor = on
+command_inline = off
 default_template = "%(nicks)|%(irc_channels)"
 nick_add_space = on
 nick_completer = ":"
index 6e78f2a9549d2b53dd9fcaa07d79b29a8d73f5da..43ec7b2486c5e09a7ca7bc1f0ab08ba3d92d922c 100644 (file)
@@ -1,5 +1,5 @@
 #
-# xfer.conf -- weechat v1.0.1
+# xfer.conf -- weechat v1.1
 #
 
 [look]