Merging and updating vimrc

master
Dustin Swan 12 years ago
commit 2b2f8e09e5

3
.gitignore vendored

@ -1,3 +1,6 @@
*.log
weechat/logs/*
vim/.netrwhist
vim/bundle/*
!vim/bundle/vundle/*
mutt/hcache

@ -1,46 +1,133 @@
! General
! Urxvt
urxvt*loginShell: true
urxvt*scrollBar: false
urxvt*secondaryScroll: true
urxvt*saveLines: 65535
urxvt*cursorBlink: false
urxvt*urgentOnBell: true
urxvt*urlLauncher: /usr/bin/uzbl-browser
urxvt*urlLauncher: /usr/bin/luakit
!urxvt*termName: xterm-256color
!urxvt*termName: rxvt-256color
urxvt*termName: rxvt-unicode
urxvt*termName: rxvt-unicode-256color
! Font
!urxvt*font: -xos4-terminus-medium-*-*-*-12-*-*-*-*-*-*-*
!urxvt*font: xft:DejaVu Sans Mono:pixelsize=10:antialias=true:hinting=true
!urxvt*font: xft:Liberation Mono:pixelsize=10:antialias=true:hinting=true
!urxvt*boldFont: -xos4-terminus-bold-*-*-*-12-*-*-*-*-*-*-*
!urxvt*font: xft:inconsolata:size=9
!urxvt*font: xft:inconsolata:size=10
!urxvt*font: -*-ohsnapu-medium-r-normal-*-11-*-*-*-*-*-*-*
!urxvt*boldFont: -*-ohsnapu-bold-r-normal-*-11-*-*-*-*-*-*-*
urxvt*font: xft:termsyn:pixelsize=10
!urxvt*font: xft:termsyn:pixelsize=10
!urxvt*font: xft:DejaVu Sans Mono:pixelsize=10:antialias=false:hinting=true
urxvt*font: xft:terminus:size=9
urxvt*boldFont: xft:terminus:size=9
! Colors
urxvt*depth: 32
!urxvt*cursorColor: #DCDCCC
!urxvt*background: #000000
urxvt*foreground: #FFFFFF
urxvt*background: rgba:0000/0000/0000/dddd
*color0: #1c1c1c
*color8: #3d3a3a
*color1: #d770af
*color9: #d28abf
*color2 : #9acc79
*color10: #8fb676
*color3: #d0d26b
*color11: #c8bc45
*color4 : #77b6c5
*color12: #8fa7b9
*color5: #a488d9
*color13: #bd89de
*color6: #7fcab3
*color14: #6ec2a8
*color7: #8d8d8d
*color15: #dad3d3
urxvt*background: rgba:0000/0000/0000/ee00
!*color0: #1c1c1c
!*color8: #3d3a3a
!*color1: #d770af
!*color9: #d28abf
!*color2 : #9acc79
!*color10: #8fb676
!*color3: #d0d26b
!*color11: #c8bc45
!*color4 : #77b6c5
!*color12: #8fa7b9
!*color5: #a488d9
!*color13: #bd89de
!*color6: #7fcab3
!*color14: #6ec2a8
!*color7: #8d8d8d
!*color15: #dad3d3
!! drop in Solarized colorscheme for Xresources
!!
!! ## Installation
!! 1) Write to $HOME/.Xresources
!! 2) If not using Xsession, you must add the line `xrdb -merge ~/.Xresources`
!! to `.xinitrc`. See http://manpages.ubuntu.com/Xsession for more details.
!!
!!SOLARIZED HEX 16/8 TERMCOL XTERM/HEX L*A*B RGB HSB
!!--------- ------- ---- ------- ----------- ---------- ----------- -----------
!!base03 #002b36 8/4 brblack 234 #1c1c1c 15 -12 -12 0 43 54 193 100 21
!!base02 #073642 0/4 black 235 #262626 20 -12 -12 7 54 66 192 90 26
!!base01 #586e75 10/7 brgreen 240 #585858 45 -07 -07 88 110 117 194 25 46
!!base00 #657b83 11/7 bryellow 241 #626262 50 -07 -07 101 123 131 195 23 51
!!base0 #839496 12/6 brblue 244 #808080 60 -06 -03 131 148 150 186 13 59
!!base1 #93a1a1 14/4 brcyan 245 #8a8a8a 65 -05 -02 147 161 161 180 9 63
!!base2 #eee8d5 7/7 white 254 #e4e4e4 92 -00 10 238 232 213 44 11 93
!!base3 #fdf6e3 15/7 brwhite 230 #ffffd7 97 00 10 253 246 227 44 10 99
!!yellow #b58900 3/3 yellow 136 #af8700 60 10 65 181 137 0 45 100 71
!!orange #cb4b16 9/3 brred 166 #d75f00 50 50 55 203 75 22 18 89 80
!!red #dc322f 1/1 red 160 #d70000 50 65 45 220 50 47 1 79 86
!!magenta #d33682 5/5 magenta 125 #af005f 50 65 -05 211 54 130 331 74 83
!!violet #6c71c4 13/5 brmagenta 61 #5f5faf 50 15 -45 108 113 196 237 45 77
!!blue #268bd2 4/4 blue 33 #0087ff 55 -10 -45 38 139 210 205 82 82
!!cyan #2aa198 6/6 cyan 37 #00afaf 60 -35 -05 42 161 152 175 74 63
!!green #859900 2/2 green 64 #5f8700 60 -20 65 133 153 0 68 100 60
#define S_base03 #002b36
#define S_base02 #073642
#define S_base01 #586e75
#define S_base00 #657b83
#define S_base0 #839496
#define S_base1 #93a1a1
#define S_base2 #eee8d5
#define S_base3 #fdf6e3
#define S_yellow #b58900
#define S_orange #cb4b16
#define S_red #dc322f
#define S_magenta #d33682
#define S_violet #6c71c4
#define S_blue #268bd2
#define S_cyan #2aa198
#define S_green #859900
!*background: S_base03
!*foreground: S_base0
*fading: 40
*fadeColor: S_base03
*cursorColor: S_base1
*pointerColorBackground:S_base01
*pointerColorForeground:S_base1
!! black dark/light
*color0: S_base02
*color8: S_base03
!! red dark/light
*color1: S_red
*color9: S_orange
!! green dark/light
*color2: S_green
*color10: S_base01
!! yellow dark/light
*color3: S_yellow
*color11: S_base00
!! blue dark/light
*color4: S_blue
*color12: S_base0
!! magenta dark/light
*color5: S_magenta
*color13: S_violet
!! cyan dark/light
*color6: S_cyan
*color14: S_base1
!! white dark/light
*color7: S_base2
*color15: S_base3

@ -73,7 +73,7 @@ layouts =
tags = {}
for s = 1, screen.count() do
-- Each screen has its own tag table.
tags[s] = awful.tag({ "stat", "web", "mail", "chat", "dev", "media", 7, 8, 9 },
tags[s] = awful.tag({ "sys", "web", "mail", "chat", "dev", "media", "virt", 8, 9 },
s,
{ layouts[6], layouts[6], layouts[6], layouts[6], layouts[6], layouts[6], layouts[6], layouts[6], layouts[6] })
end
@ -103,20 +103,31 @@ mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon),
separator = widget({ type = "textbox" })
separator.text = " | "
uptimewidget = widget({ type = "textbox" })
vicious.register(uptimewidget, vicious.widgets.uptime, "uptime <span color='" .. beautiful.fg_focus .. "'>$2.$3</span>'")
--uptimewidget = widget({ type = "textbox" })
--vicious.register(uptimewidget, vicious.widgets.uptime, "uptime <span color='" .. beautiful.fg_focus .. "'>$2.$3</span>'")
-- Network
netwidget = widget({ type = "textbox" })
vicious.register(netwidget, vicious.widgets.net, 'down <span color="' .. beautiful.fg_focus .. '">${eth0 down_kb}</span> up <span color="' .. beautiful.fg_focus .. '">${eth0 up_kb}</span>', 3)
vicious.register(netwidget, vicious.widgets.net, "down <span color='" .. beautiful.fg_focus .. "'>${wifi0 down_kb}</span> up <span color='" .. beautiful.fg_focus .. "'>${wifi0 up_kb}</span>", 3)
-- Date
datewidget = widget({ type = "textbox" })
vicious.register(datewidget, vicious.widgets.date, '<span color="' .. beautiful.fg_focus .. '">%a %F, %T</span> ', 1)
vicious.register(datewidget, vicious.widgets.date, '<span color="' .. beautiful.fg_focus .. '">%a %m-%d, %T</span> ', 1)
-- Memory
memwidget = widget({ type = "textbox"})
vicious.register(memwidget, vicious.widgets.mem, 'mem <span color="' .. beautiful.fg_focus .. '">$1% [$2/$3]</span>', 13)
--vicious.register(memwidget, vicious.widgets.mem, 'mem <span color="' .. beautiful.fg_focus .. '">$1% [$2/$3]</span>', 13)
vicious.register(memwidget, vicious.widgets.mem, 'mem <span color="' .. beautiful.fg_focus .. '">$1%</span>', 13)
-- Filesystem
fswidget = widget({ type = "textbox"})
vicious.register(fswidget, vicious.widgets.fs, function (widget, args)
return 'fs <span color="' .. beautiful.fg_focus .. '">' .. args["{/ used_gb}"] .. "/" .. args["{/ size_gb}"] .. 'GB</span>'
end, 20)
-- Battery
batwidget = widget({ type = "textbox" })
vicious.register(batwidget, vicious.widgets.bat, 'bat <span color="' .. beautiful.fg_focus .. '">$2%</span>', 60, 'BAT0')
-- Memory Graph
--memgraphwidget = awful.widget.progressbar()
@ -144,7 +155,33 @@ vicious.register(cpuwidget, vicious.widgets.cpu, 'cpu <span color="' .. beautifu
-- Temp
tempwidget = widget({ type = "textbox" })
vicious.register(tempwidget, vicious.widgets.thermal, 'temp <span color="' .. beautiful.fg_focus .. '">$1°C</span>', 9, "thermal_zone0")
vicious.register(tempwidget, vicious.widgets.thermal, ' @ <span color="' .. beautiful.fg_focus .. '">$1°C</span>', 9, { "coretemp.0", "core" })
volumewidget = widget({ type = "textbox" })
vicious.register(volumewidget, vicious.widgets.volume, '$2 <span color="' .. beautiful.fg_focus .. '">$1%</span>', 1, "Master")
volumewidget:buttons(awful.util.table.join(
awful.button({}, 1, function () awful.util.spawn("amixer set Master toggle", false) end),
awful.button({}, 3, function () awful.util.spawn("urxvt -e alsamixer", true) end),
awful.button({}, 4, function () awful.util.spawn("amixer -q set Master 1+", true) end),
awful.button({}, 5, function () awful.util.spawn("amixer -q set Master 1-", true) end)
))
-- Weather
--weatherwidget = widget({ type = "textbox" })
--vicious.register(weatherwidget, vicious.widgets.weather, 'weather <span color="' .. beautiful.fg_focus .. '">$1</span>', 120, "ORD")
-- Wifi
wifiwidget = widget({ type = "textbox" })
vicious.register(wifiwidget, vicious.widgets.wifi,
function (widget, args)
--return string.format("<span>%s %i%%</span>", args["{ssid}"], args["{link}"]/70*100)
return args["{ssid}"] .. " <span color='" .. beautiful.fg_focus .. "'>" .. math.floor(args["{link}"] / 70 * 100) .. "%</span>"
end, 10, "wifi0" )
-- Package widget
--packagewidget = widget({ type = "textbox" })
--vicious.register(packagewidget, vicious.widgets.pkg, 'pkgs <span color="' .. beautiful.fg_focus .. '">$1</span>', 60, "Arch")
-- Create a systray
mysystray = widget({ type = "systray" })
@ -227,18 +264,29 @@ for s = 1, screen.count() do
--separator,
datewidget,
separator,
batwidget,
separator,
netwidget,
separator,
--memgraphwidget.widget,
fswidget,
separator,
memwidget,
separator,
--cpugraphwidget.widget,
tempwidget,
cpuwidget,
separator,
uptimewidget,
--uptimewidget,
--separator,
volumewidget,
separator,
-- tempwidget,
-- separator,
--weatherwidget,
--separator,
wifiwidget,
separator,
--packagewidget,
--separator,
s == 1 and mysystray or nil,
mytasklist[s],
layout = awful.widget.layout.horizontal.rightleft
@ -256,6 +304,10 @@ root.buttons(awful.util.table.join(
-- {{{ Key bindings
globalkeys = awful.util.table.join(
-- media keys
awful.key({}, "XF86AudioRaiseVolume", function () awful.util.spawn("amixer set Master 4+") end ),
awful.key({}, "XF86AudioLowerVolume", function () awful.util.spawn("amixer set Master 4-") end ),
awful.key({}, "XF86AudioMute", function () awful.util.spawn("amixer set Master toggle") end ),
awful.key({ modkey, }, "p", function() awful.util.spawn( "dmenu_run" ) end ),
awful.key({ modkey, }, "Left", awful.tag.viewprev ),
awful.key({ modkey, }, "Right", awful.tag.viewnext ),

@ -4,13 +4,16 @@
theme = {}
theme.font = "termsyn 8"
theme.font = "terminus 8"
theme.bg_normal = "#222222"
theme.bg_focus = "#535d6c"
--theme.bg_normal = "#222222"
theme.bg_normal = "#000000"
--theme.bg_focus = "#535d6c"
theme.bg_focus = "#005566"
theme.bg_urgent = "#ff0000"
theme.bg_minimize = "#444444"
--theme.fg_normal = "#aaaaaa"
theme.fg_normal = "#aaaaaa"
theme.fg_focus = "#ffffff"
theme.fg_urgent = "#ffffff"
@ -18,7 +21,8 @@ theme.fg_minimize = "#ffffff"
theme.border_width = "1"
theme.border_normal = "#000000"
theme.border_focus = "#535d6c"
--theme.border_focus = "#535d6c"
theme.border_focus = "#004466"
theme.border_marked = "#91231c"
-- There are other variable sets

@ -0,0 +1,588 @@
-----------------
-- Keybindings --
-----------------
-- Binding aliases
local key, buf, but = lousy.bind.key, lousy.bind.buf, lousy.bind.but
local cmd, any = lousy.bind.cmd, lousy.bind.any
-- Util aliases
local match, join = string.match, lousy.util.table.join
local strip, split = lousy.util.string.strip, lousy.util.string.split
-- Globals or defaults that are used in binds
local scroll_step = globals.scroll_step or 20
local zoom_step = globals.zoom_step or 0.1
-- Add binds to a mode
function add_binds(mode, binds, before)
assert(binds and type(binds) == "table", "invalid binds table type: " .. type(binds))
mode = type(mode) ~= "table" and {mode} or mode
for _, m in ipairs(mode) do
local mdata = get_mode(m)
if mdata and before then
mdata.binds = join(binds, mdata.binds or {})
elseif mdata then
mdata.binds = mdata.binds or {}
for _, b in ipairs(binds) do table.insert(mdata.binds, b) end
else
new_mode(m, { binds = binds })
end
end
end
-- Add commands to command mode
function add_cmds(cmds, before)
add_binds("command", cmds, before)
end
-- Adds the default menu widget bindings to a mode
menu_binds = {
-- Navigate items
key({}, "j", function (w) w.menu:move_down() end),
key({}, "k", function (w) w.menu:move_up() end),
key({}, "Down", function (w) w.menu:move_down() end),
key({}, "Up", function (w) w.menu:move_up() end),
key({}, "Tab", function (w) w.menu:move_down() end),
key({"Shift"}, "Tab", function (w) w.menu:move_up() end),
}
-- Add binds to special mode "all" which adds its binds to all modes.
add_binds("all", {
key({}, "Escape", "Return to `normal` mode.",
function (w) w:set_mode() end),
key({"Control"}, "[", "Return to `normal` mode.",
function (w) w:set_mode() end),
-- Mouse bindings
but({}, 8, "Go back.",
function (w) w:back() end),
but({}, 9, "Go forward.",
function (w) w:forward() end),
-- Open link in new tab or navigate to selection
but({}, 2, [[Open link under mouse cursor in new tab or navigate to the
contents of `luakit.selection.primary`.]],
function (w, m)
-- Ignore button 2 clicks in form fields
if not m.context.editable then
-- Open hovered uri in new tab
local uri = w.view.hovered_uri
if uri then
w:new_tab(uri, false)
else -- Open selection in current tab
uri = luakit.selection.primary
if uri then w:navigate(w:search_open(uri)) end
end
end
end),
-- Open link in new tab when Ctrl-clicked.
but({"Control"}, 1, "Open link under mouse cursor in new tab.",
function (w, m)
local uri = w.view.hovered_uri
if uri then
w:new_tab(uri, false)
end
end),
-- Zoom binds
but({"Control"}, 4, "Increase text zoom level.",
function (w, m) w:zoom_in() end),
but({"Control"}, 5, "Reduce text zoom level.",
function (w, m) w:zoom_out() end),
-- Horizontal mouse scroll binds
but({"Shift"}, 4, "Scroll left.",
function (w, m) w:scroll{ xrel = -scroll_step } end),
but({"Shift"}, 5, "Scroll right.",
function (w, m) w:scroll{ xrel = scroll_step } end),
})
add_binds("normal", {
-- Autoparse the `[count]` before a binding and re-call the hit function
-- with the count removed and added to the opts table.
any([[Meta-binding to detect the `^[count]` syntax. The `[count]` is parsed
and stripped from the internal buffer string and the value assigned to
`state.count`. Then `lousy.bind.hit()` is re-called with the modified
buffer string & original modifier state.
#### Example binding
lousy.bind.key({}, "%", function (w, state)
w:scroll{ ypct = state.count }
end, { count = 0 })
This binding demonstrates several concepts. Firstly that you are able to
specify per-binding default values of `count`. In this case if the user
types `"%"` the document will be scrolled vertically to `0%` (the top).
If the user types `"100%"` then the document will be scrolled to `100%`
(the bottom). All without the need to use `lousy.bind.buf` bindings
everywhere and or using a `^(%d*)` pattern prefix on every binding which
would like to make use of the `[count]` syntax.]],
function (w, m)
local count, buf
if m.buffer then
count = string.match(m.buffer, "^(%d+)")
end
if count then
buf = string.sub(m.buffer, #count + 1, (m.updated_buf and -2) or -1)
local opts = join(m, {count = tonumber(count)})
opts.buffer = (#buf > 0 and buf) or nil
if lousy.bind.hit(w, m.binds, m.mods, m.key, opts) then
return true
end
end
return false
end),
key({}, "i", "Enter `insert` mode.",
function (w) w:set_mode("insert") end),
key({}, ":", "Enter `command` mode.",
function (w) w:set_mode("command") end),
-- Scrolling
key({}, "j", "Scroll document down.",
function (w) w:scroll{ yrel = scroll_step } end),
key({}, "k", "Scroll document up.",
function (w) w:scroll{ yrel = -scroll_step } end),
key({}, "h", "Scroll document left.",
function (w) w:scroll{ xrel = -scroll_step } end),
key({}, "l", "Scroll document right.",
function (w) w:scroll{ xrel = scroll_step } end),
key({}, "Down", "Scroll document down.",
function (w) w:scroll{ yrel = scroll_step } end),
key({}, "Up", "Scroll document up.",
function (w) w:scroll{ yrel = -scroll_step } end),
key({}, "Left", "Scroll document left.",
function (w) w:scroll{ xrel = -scroll_step } end),
key({}, "Right", "Scroll document right.",
function (w) w:scroll{ xrel = scroll_step } end),
key({}, "^", "Scroll to the absolute left of the document.",
function (w) w:scroll{ x = 0 } end),
key({}, "$", "Scroll to the absolute right of the document.",
function (w) w:scroll{ x = -1 } end),
key({}, "0", "Scroll to the absolute left of the document.",
function (w, m)
if not m.count then w:scroll{ y = 0 } else return false end
end),
key({"Control"}, "e", "Scroll document down.",
function (w) w:scroll{ yrel = scroll_step } end),
key({"Control"}, "y", "Scroll document up.",
function (w) w:scroll{ yrel = -scroll_step } end),
key({"Control"}, "d", "Scroll half page down.",
function (w) w:scroll{ ypagerel = 0.5 } end),
key({"Control"}, "u", "Scroll half page up.",
function (w) w:scroll{ ypagerel = -0.5 } end),
key({"Control"}, "f", "Scroll page down.",
function (w) w:scroll{ ypagerel = 1.0 } end),
key({"Control"}, "b", "Scroll page up.",
function (w) w:scroll{ ypagerel = -1.0 } end),
key({}, "space", "Scroll page down.",
function (w) w:scroll{ ypagerel = 1.0 } end),
key({"Shift"}, "space", "Scroll page up.",
function (w) w:scroll{ ypagerel = -1.0 } end),
key({}, "BackSpace", "Scroll page up.",
function (w) w:scroll{ ypagerel = -1.0 } end),
key({}, "Page_Down", "Scroll page down.",
function (w) w:scroll{ ypagerel = 1.0 } end),
key({}, "Page_Up", "Scroll page up.",
function (w) w:scroll{ ypagerel = -1.0 } end),
key({}, "Home", "Go to the end of the document.",
function (w) w:scroll{ y = 0 } end),
key({}, "End", "Go to the top of the document.",
function (w) w:scroll{ y = -1 } end),
-- Specific scroll
buf("^gg$", "Go to the top of the document.",
function (w, b, m) w:scroll{ ypct = m.count } end, {count=0}),
buf("^G$", "Go to the bottom of the document.",
function (w, b, m) w:scroll{ ypct = m.count } end, {count=100}),
buf("^%%$", "Go to `[count]` percent of the document.",
function (w, b, m) w:scroll{ ypct = m.count } end),
-- Zooming
key({}, "+", "Enlarge text zoom of the current page.",
function (w, m) w:zoom_in(zoom_step * m.count) end, {count=1}),
key({}, "-", "Reduce text zom of the current page.",
function (w, m) w:zoom_out(zoom_step * m.count) end, {count=1}),
key({}, "=", "Reset zoom level.",
function (w, m) w:zoom_set() end),
buf("^z[iI]$", [[Enlarge text zoom of current page with `zi` or `zI` to
reduce full zoom.]],
function (w, b, m)
w:zoom_in(zoom_step * m.count, b == "zI")
end, {count=1}),
buf("^z[oO]$", [[Reduce text zoom of current page with `zo` or `zO` to
reduce full zoom.]],
function (w, b, m)
w:zoom_out(zoom_step * m.count, b == "zO")
end, {count=1}),
-- Zoom reset or specific zoom ([count]zZ for full content zoom)
buf("^z[zZ]$", [[Set current page zoom to `[count]` percent with
`[count]zz`, use `[count]zZ` to set full zoom percent.]],
function (w, b, m)
w:zoom_set(m.count/100, b == "zZ")
end, {count=100}),
-- Fullscreen
key({}, "F11", "Toggle fullscreen mode.",
function (w) w.win.fullscreen = not w.win.fullscreen end),
-- Clipboard
key({}, "p", [[Open a URL based on the current primary selection contents
in the current tab.]],
function (w)
local uri = luakit.selection.primary
if not uri then w:notify("No primary selection...") return end
w:navigate(w:search_open(uri))
end),
key({}, "P", [[Open a URL based on the current primary selection contents
in `[count=1]` new tab(s).]],
function (w, m)
local uri = luakit.selection.primary
if not uri then w:notify("No primary selection...") return end
for i = 1, m.count do w:new_tab(w:search_open(uri)) end
end, {count = 1}),
-- Yanking
key({}, "y", "Yank current URI to primary selection.",
function (w)
local uri = string.gsub(w.view.uri or "", " ", "%%20")
luakit.selection.primary = uri
w:notify("Yanked uri: " .. uri)
end),
-- Commands
key({"Control"}, "a", "Increment last number in URL.",
function (w) w:navigate(w:inc_uri(1)) end),
key({"Control"}, "x", "Decrement last number in URL.",
function (w) w:navigate(w:inc_uri(-1)) end),
key({}, "o", "Open one or more URLs.",
function (w) w:enter_cmd(":open ") end),
key({}, "t", "Open one or more URLs in a new tab.",
function (w) w:enter_cmd(":tabopen ") end),
key({}, "w", "Open one or more URLs in a new window.",
function (w) w:enter_cmd(":winopen ") end),
key({}, "O", "Open one or more URLs based on current location.",
function (w) w:enter_cmd(":open " .. (w.view.uri or "")) end),
key({}, "T",
"Open one or more URLs based on current location in a new tab.",
function (w) w:enter_cmd(":tabopen " .. (w.view.uri or "")) end),
key({}, "W",
"Open one or more URLs based on current locaton in a new window.",
function (w) w:enter_cmd(":winopen " .. (w.view.uri or "")) end),
-- History
key({}, "H", "Go back in the browser history `[count=1]` items.",
function (w, m) w:back(m.count) end),
key({}, "L", "Go forward in the browser history `[count=1]` times.",
function (w, m) w:forward(m.count) end),
key({}, "XF86Back", "Go back in the browser history.",
function (w, m) w:back(m.count) end),
key({}, "XF86Forward", "Go forward in the browser history.",
function (w, m) w:forward(m.count) end),
key({"Control"}, "o", "Go back in the browser history.",
function (w, m) w:back(m.count) end),
key({"Control"}, "i", "Go forward in the browser history.",
function (w, m) w:forward(m.count) end),
-- Tab
key({"Control"}, "Page_Up", "Go to previous tab.",
function (w) w:prev_tab() end),
key({"Control"}, "Page_Down", "Go to next tab.",
function (w) w:next_tab() end),
key({"Control"}, "Tab", "Go to next tab.",
function (w) w:next_tab() end),
key({"Shift","Control"}, "Tab", "Go to previous tab.",
function (w) w:prev_tab() end),
buf("^gT$", "Go to previous tab.",
function (w) w:prev_tab() end),
buf("^gt$", "Go to next tab (or `[count]` nth tab).",
function (w, b, m)
if not w:goto_tab(m.count) then w:next_tab() end
end, {count=0}),
buf("^g0$", "Go to first tab.",
function (w) w:goto_tab(1) end),
buf("^g$$", "Go to last tab.",
function (w) w:goto_tab(-1) end),
key({"Control"}, "t", "Open a new tab.",
function (w) w:new_tab(globals.homepage) end),
key({"Control"}, "w", "Close current tab.",
function (w) w:close_tab() end),
key({}, "d", "Close current tab (or `[count]` tabs).",
function (w, m) for i=1,m.count do w:close_tab() end end, {count=1}),
key({}, "<", "Reorder tab left `[count=1]` positions.",
function (w, m)
w.tabs:reorder(w.view, w.tabs:current() - m.count)
end, {count=1}),
key({}, ">", "Reorder tab right `[count=1]` positions.",
function (w, m)
w.tabs:reorder(w.view,
(w.tabs:current() + m.count) % w.tabs:count())
end, {count=1}),
buf("^gH$", "Open homepage in new tab.",
function (w) w:new_tab(globals.homepage) end),
buf("^gh$", "Open homepage.",
function (w) w:navigate(globals.homepage) end),
buf("^gy$", "Duplicate current tab.",
function (w) w:new_tab(w.view.history or "") end),
key({}, "r", "Reload current tab.",
function (w) w:reload() end),
key({}, "R", "Reload current tab (skipping cache).",
function (w) w:reload(true) end),
key({"Control"}, "c", "Stop loading the current tab.",
function (w) w.view:stop() end),
key({"Control", "Shift"}, "R", "Restart luakit (reloading configs).",
function (w) w:restart() end),
-- Window
buf("^ZZ$", "Quit and save the session.",
function (w) w:save_session() w:close_win() end),
buf("^ZQ$", "Quit and don't save the session.",
function (w) w:close_win() end),
buf("^D$", "Quit and don't save the session.",
function (w) w:close_win() end),
-- Enter passthrough mode
key({"Control"}, "z",
"Enter `passthrough` mode, ignores all luakit keybindings.",
function (w) w:set_mode("passthrough") end),
})
add_binds("insert", {
key({"Control"}, "z",
"Enter `passthrough` mode, ignores all luakit keybindings.",
function (w) w:set_mode("passthrough") end),
})
readline_bindings = {
key({"Shift"}, "Insert",
"Insert contents of primary selection at cursor position.",
function (w) w:insert_cmd(luakit.selection.primary) end),
key({"Control"}, "w", "Delete previous word.",
function (w) w:del_word() end),
key({"Control"}, "u", "Delete until beginning of current line.",
function (w) w:del_line() end),
key({"Control"}, "h", "Delete character to the left.",
function (w) w:del_backward_char() end),
key({"Control"}, "d", "Delete character to the right.",
function (w) w:del_forward_char() end),
key({"Control"}, "a", "Move cursor to beginning of current line.",
function (w) w:beg_line() end),
key({"Control"}, "e", "Move cursor to end of current line.",
function (w) w:end_line() end),
key({"Control"}, "f", "Move cursor forward one character.",
function (w) w:forward_char() end),
key({"Control"}, "b", "Move cursor backward one character.",
function (w) w:backward_char() end),
key({"Mod1"}, "f", "Move cursor forward one word.",
function (w) w:forward_word() end),
key({"Mod1"}, "b", "Move cursor backward one word.",
function (w) w:backward_word() end),
}
add_binds({"command", "search"}, readline_bindings)
-- Switching tabs with Mod1+{1,2,3,...}
mod1binds = {}
for i=1,10 do
table.insert(mod1binds,
key({"Mod1"}, tostring(i % 10), "Jump to tab at index "..i..".",
function (w) w.tabs:switch(i) end))
end
add_binds("normal", mod1binds)
-- Command bindings which are matched in the "command" mode from text
-- entered into the input bar.
add_cmds({
buf("^%S+!",
[[Detect bang syntax in `:command!` and recursively calls
`lousy.bind.match_cmd(..)` removing the bang from the command string
and setting `bang = true` in the bind opts table.]],
function (w, cmd, opts)
local cmd, args = string.match(cmd, "^(%S+)!+(.*)")
if cmd then
opts = join(opts, { bang = true })
return lousy.bind.match_cmd(w, opts.binds, cmd .. args, opts)
end
end),
cmd("c[lose]", "Close current tab.",
function (w) w:close_tab() end),
cmd("print", "Print current page.",
function (w) w.view:eval_js("print()") end),
cmd("stop", "Stop loading.",
function (w) w.view:stop() end),
cmd("reload", "Reload page",
function (w) w:reload() end),
cmd("restart", "Restart browser (reload config files).",
function (w) w:restart() end),
cmd("write", "Save current session.",
function (w) w:save_session() end),
cmd("noh[lsearch]", "Clear search highlighting.",
function (w) w:clear_search() end),
cmd("back", "Go back in the browser history `[count=1]` items.",
function (w, a) w:back(tonumber(a) or 1) end),
cmd("f[orward]", "Go forward in the browser history `[count=1]` items.",
function (w, a) w:forward(tonumber(a) or 1) end),
cmd("inc[rease]", "Increment last number in URL.",
function (w, a) w:navigate(w:inc_uri(tonumber(a) or 1)) end),
cmd("o[pen]", "Open one or more URLs.",
function (w, a) w:navigate(w:search_open(a)) end),
cmd("t[abopen]", "Open one or more URLs in a new tab.",
function (w, a) w:new_tab(w:search_open(a)) end),
cmd("w[inopen]", "Open one or more URLs in a new window.",
function (w, a) window.new{w:search_open(a)} end),
cmd({"javascript", "js"}, "Evaluate JavaScript snippet.",
function (w, a) w.view:eval_js(a) end),
-- Tab manipulation commands
cmd("tab", "Execute command and open result in new tab.",
function (w, a) w:new_tab() w:run_cmd(":" .. a) end),
cmd("tabd[o]", "Execute command in each tab.",
function (w, a) w:each_tab(function (v) w:run_cmd(":" .. a) end) end),
cmd("tabdu[plicate]", "Duplicate current tab.",
function (w) w:new_tab(w.view.history) end),
cmd("tabfir[st]", "Switch to first tab.",
function (w) w:goto_tab(1) end),
cmd("tabl[ast]", "Switch to last tab.",
function (w) w:goto_tab(-1) end),
cmd("tabn[ext]", "Switch to the next tab.",
function (w) w:next_tab() end),
cmd("tabp[revious]", "Switch to the previous tab.",
function (w) w:prev_tab() end),
cmd("q[uit]", "Close the current window.",
function (w, a, o) w:close_win(o.bang) end),
cmd({"viewsource", "vs"}, "View the source code of the current document.",
function (w, a, o) w:toggle_source(not o.bang and true or nil) end),
cmd({"wqall", "wq"}, "Save the session and quit.",
function (w, a, o) w:save_session() w:close_win(o.bang) end),
cmd("lua", "Evaluate Lua snippet.", function (w, a)
if a then
local ret = assert(
loadstring("return function(w) return "..a.." end"))()(w)
if ret then print(ret) end
else
w:set_mode("lua")
end
end),
cmd("dump", "Dump current tabs html to file.",
function (w, a)
local fname = string.gsub(w.win.title, '[^%w%.%-]', '_')..'.html' -- sanitize filename
local file = a or luakit.save_file("Save file", w.win, xdg.download_dir or '.', fname)
if file then
local fd = assert(io.open(file, "w"), "failed to open: " .. file)
local html = assert(w.view:eval_js("document.documentElement.outerHTML"), "Unable to get HTML")
assert(fd:write(html), "unable to save html")
io.close(fd)
w:notify("Dumped HTML to: " .. file)
end
end),
})
-- vim: et:sw=4:ts=8:sts=4:tw=80

@ -0,0 +1,85 @@
-- Global variables for luakit
globals = {
homepage = "http://luakit.org/",
-- homepage = "http://github.com/mason-larobina/luakit",
scroll_step = 40,
zoom_step = 0.1,
max_cmd_history = 100,
max_srch_history = 100,
-- http_proxy = "http://example.com:3128",
default_window_size = "800x600",
-- Disables loading of hostnames from /etc/hosts (for large host files)
-- load_etc_hosts = false,
-- Disables checking if a filepath exists in search_open function
-- check_filepath = false,
}
-- Make useragent
local _, arch = luakit.spawn_sync("uname -sm")
-- Only use the luakit version if in date format (reduces identifiability)
local lkv = string.match(luakit.version, "^(%d+.%d+.%d+)")
globals.useragent = string.format("Mozilla/5.0 (%s) AppleWebKit/%s+ (KHTML, like Gecko) WebKitGTK+/%s luakit%s",
string.sub(arch, 1, -2), luakit.webkit_user_agent_version,
luakit.webkit_version, (lkv and ("/" .. lkv)) or "")
-- Search common locations for a ca file which is used for ssl connection validation.
local ca_files = {
-- $XDG_DATA_HOME/luakit/ca-certificates.crt
luakit.data_dir .. "/ca-certificates.crt",
"/etc/certs/ca-certificates.crt",
"/etc/ssl/certs/ca-certificates.crt",
}
-- Use the first ca-file found
for _, ca_file in ipairs(ca_files) do
if os.exists(ca_file) then
soup.ssl_ca_file = ca_file
break
end
end
-- Change to stop navigation sites with invalid or expired ssl certificates
soup.ssl_strict = false
-- Set cookie acceptance policy
cookie_policy = { always = 0, never = 1, no_third_party = 2 }
soup.accept_policy = cookie_policy.always
-- List of search engines. Each item must contain a single %s which is
-- replaced by URI encoded search terms. All other occurances of the percent
-- character (%) may need to be escaped by placing another % before or after
-- it to avoid collisions with lua's string.format characters.
-- See: http://www.lua.org/manual/5.1/manual.html#pdf-string.format
search_engines = {
duckduckgo = "https://duckduckgo.com/?q=%s",
github = "https://github.com/search?q=%s",
google = "https://google.com/search?q=%s",
imdb = "http://www.imdb.com/find?s=all&q=%s",
wikipedia = "https://en.wikipedia.org/wiki/Special:Search?search=%s",
}
-- Set google as fallback search engine
search_engines.default = search_engines.google
-- Use this instead to disable auto-searching
--search_engines.default = "%s"
-- Per-domain webview properties
-- See http://webkitgtk.org/reference/webkitgtk/stable/WebKitWebSettings.html
domain_props = { --[[
["all"] = {
enable_scripts = false,
enable_plugins = false,
enable_private_browsing = false,
user_stylesheet_uri = "",
},
["youtube.com"] = {
enable_scripts = true,
enable_plugins = true,
},
["bbs.archlinux.org"] = {
user_stylesheet_uri = "file://" .. luakit.data_dir .. "/styles/dark.css",
enable_private_browsing = true,
}, ]]
}
-- vim: et:sw=4:ts=8:sts=4:tw=80

@ -0,0 +1,163 @@
-------------------------------
-- luakit mode configuration --
-------------------------------
-- Table of modes and their callback hooks
local modes = {}
local lousy = require "lousy"
local join = lousy.util.table.join
local order = 0
-- Add new mode table (optionally merges with original mode)
function new_mode(name, desc, mode, replace)
assert(string.match(name, "^[%w-_]+$"), "invalid mode name: " .. name)
-- Detect optional description
if type(desc) == "table" then
desc, mode, replace = nil, desc, mode
end
local traceback = debug.traceback("Creation traceback:", 2)
order = order + 1
modes[name] = join({ order = order, traceback = traceback },
(not replace and modes[name]) or {}, mode or {},
{ name = name, desc = desc })
end
-- Get mode table
function get_mode(name) return modes[name] end
function get_modes() return lousy.util.table.clone(modes) end
-- Attach window & input bar signals for mode hooks
window.init_funcs.modes_setup = function (w)
-- Calls the `enter` and `leave` mode hooks.
w:add_signal("mode-changed", function (_, name, ...)
local leave = (w.mode or {}).leave
-- Get new modes functions/hooks/data
local mode = assert(modes[name], "invalid mode: " .. name)
-- Call last modes leave hook.
if leave then leave(w) end
-- Create w.mode object
w.mode = mode
-- Update window binds
w:update_binds(name)
-- Call new modes enter hook.
if mode.enter then mode.enter(w, ...) end
w:emit_signal("mode-entered", mode)
end)
local input = w.ibar.input
-- Calls the changed hook on input widget changed.
input:add_signal("changed", function ()
local changed = w.mode.changed
if changed then changed(w, input.text) end
end)
input:add_signal("property::position", function ()
local move_cursor = w.mode.move_cursor
if move_cursor then move_cursor(w, input.position) end
end)
-- Calls the `activate` hook on input widget activate.
input:add_signal("activate", function ()
local mode = w.mode
if mode and mode.activate then
local text, hist = input.text, mode.history
if mode.activate(w, text) == false then return end
-- Check if last history item is identical
if hist and hist.items and hist.items[hist.len or -1] ~= text then
table.insert(hist.items, text)
end
end
end)
end
-- Add mode related window methods
window.methods.set_mode = lousy.mode.set
local mget = lousy.mode.get
window.methods.is_mode = function (w, name) return name == mget(w) end
-- Setup normal mode
new_mode("normal", [[When luakit first starts you will find yourself in this
mode.]], {
enter = function (w)
w:set_prompt()
w:set_input()
end,
})
new_mode("all", [[Special meta-mode in which the bindings for this mode are
present in all modes.]])
-- Setup insert mode
new_mode("insert", [[When clicking on form fields luakit will enter the insert
mode which allows you to enter text in form fields without accidentally
triggering normal mode bindings.]], {
enter = function (w)
w:set_prompt("-- INSERT --")
w:set_input()
w.view:focus()
end,
-- Send key events to webview
passthrough = true,
})
new_mode("passthrough", [[Luakit will pass every key event to the WebView
until the user presses Escape.]], {
enter = function (w)
w:set_prompt("-- PASS THROUGH --")
w:set_input()
end,
-- Send key events to webview
passthrough = true,
-- Don't exit mode when clicking outside of form fields
reset_on_focus = false,
-- Don't exit mode on navigation
reset_on_navigation = false,
})
-- Setup command mode
new_mode("command", [[Enter commands.]], {
enter = function (w)
w:set_prompt()
w:set_input(":")
end,
changed = function (w, text)
-- Auto-exit command mode if user backspaces ":" in the input bar.
if not string.match(text, "^:") then w:set_mode() end
end,
activate = function (w, text)
w:set_mode()
local cmd = string.sub(text, 2)
if not string.find(cmd, "%S") then return end
local success, match = xpcall(
function () return w:match_cmd(cmd) end,
function (err) w:error(debug.traceback(err, 3)) end)
if success and not match then
w:error(string.format("Not a browser command: %q", cmd))
end
end,
history = {maxlen = 50},
})
new_mode("lua", [[Execute arbitrary Lua commands within the luakit
environment.]], {
enter = function (w)
w:set_prompt(">")
w:set_input("")
end,
activate = function (w, text)
w:set_input("")
local ret = assert(loadstring("return function(w) return "..text.." end"))()(w)
if ret then print(ret) end
end,
history = {maxlen = 50},
})

@ -0,0 +1,216 @@
----------------------------------------------------------------
-- Multi-Session save/restore Plugin --
----------------------------------------------------------------
local ipairs = ipairs
local tostring = tostring
local lfs = lfs
local os = os
local io = io
local table = table
local string = string
local unpack = unpack
local lousy = require "lousy"
local util = lousy.util
local luakit = luakit
local window = window
local add_binds, add_cmds = add_binds, add_cmds
local new_mode, menu_binds = new_mode, menu_binds
local cmd = lousy.bind.cmd
local buf = lousy.bind.buf
module("plugins.multisession")
local sessions_dir = luakit.data_dir .. "/sessions"
local rm = function (file)
luakit.spawn(string.format("rm %q", file))
end
local session_save = function (w, name)
if not name then return end
local fpath = sessions_dir .. "/" .. (name or "")
-- Save all given windows uris to file.
local lines = {}
-- Save tabs from all the given window, keep the window-index to keep
-- comptability with default sessions format
local current = w.tabs:current()
for ti, tab in ipairs(w.tabs.children) do
table.insert(lines, string.format("%d\t%d\t%s\t%s", 1, ti,
tostring(current == ti), tab.uri))
end
-- Only save a non-empty session
if #lines > 0 then
local fh = io.open(fpath, "w")
fh:write(table.concat(lines, "\n"))
io.close(fh)
else
rm(session.file)
end
end
local session_load = function (name)
local fpath = sessions_dir .. "/" .. (name or "")
if not name or not os.exists(fpath) then return end
local ret = {}
-- Read file
local lines = {}
local fh = io.open(fpath, "r")
for line in fh:lines() do table.insert(lines, line) end
io.close(fh)
-- Parse session file, again, ignore the window-index, keeping for
-- compatibility
for _, line in ipairs(lines) do
local wi, ti, current, uri = unpack(util.string.split(line, "\t"))
current = (current == "true")
table.insert(ret, {uri = uri, current = current})
end
return (#ret > 0 and ret) or nil
end
-- Create a new window and open all tabs in the session in it
local session_restore = function (name)
win = session_load(name)
if not win or #win == 0 then return end
-- Spawn windows
local w
for _, item in ipairs(win) do
if not w then
w = window.new({item.uri})
else
w:new_tab(item.uri, item.current)
end
end
return w
end
-- Opens all tabs in named session in current window
local session_append = function (w, name)
ses = session_load(name)
if not ses or #ses == 0 then return false end
for _, item in ipairs(ses) do
w:new_tab(item.uri, item.current)
end
return true
end
local session_del = function (name)
if not name then return end
local fpath = sessions_dir .. "/" .. (name or "")
if not os.exists(fpath) then return false end
rm(fpath)
return true
end
local load = function ()
local curdir = lfs.currentdir()
if not lfs.chdir(sessions_dir) then
lfs.mkdir(sessions_dir)
else
lfs.chdir(curdir)
end
end
add_cmds({
cmd("session", "view list of sessions", function (w) w:set_mode("sessionmenu") end),
cmd({"session-write", "sw"}, "save a session to file",
function (w, a)
local name = util.string.strip(a) or "default"
session_save(w, name)
w:notify("Saved " .. tostring(w.tabs:count()) .. " tabs to session " .. name .. ".")
end),
cmd({"session-delete", "sd"}, "delete a saved session",
function(w, a)
local name = util.string.strip(a)
if session_del(name) then
w:notify("Deleted session " .. name .. ".")
else
w:error("No saved session named " .. name .."!")
end
end),
cmd({"session-restore", "sr"}, "load a saved session in a new window",
function(w, a)
local name = util.string.strip(a) or "default"
if not session_restore(name) then
w:error("Unable to restore session " .. name .. "!")
end
end),
cmd({"session-open", "so"}, "open a saved session in new tabs in current window",
function(w, a)
local name = util.string.strip(a) or "default"
if not session_append(w, name) then
w:error("Unable to open session " .. name .. "!")
else
w:notify("Appended session " .. name .. " to tabs.")
end
end),
})
add_binds("normal", {
buf("^sm$", "open list of saved sessions", function(w) w:set_mode("sessionmenu") end),
})
new_mode("sessionmenu", {
enter = function (w)
local rows = {{"Saved Sessions (# of tabs)", title = true}}
for filename in lfs.dir(sessions_dir) do
if not string.match(filename, "^%.-$") then
local fh = io.open(sessions_dir .. "/" .. filename)
local tabcnt = 0
for _ in fh:lines() do tabcnt = tabcnt + 1 end
io.close(fh)
table.insert(rows, {string.format(" %s (%d)", filename, tabcnt), name = filename})
end
end
if #rows == 1 then
table.insert(rows, {"No saved sessions!"})
end
w.menu:build(rows)
w:notify("Use j/k to move, d to delete a session, t to append session to current window, Enter to open session (in new window)", false)
end,
leave = function (w)
w.menu:hide()
end,
})
local key = lousy.bind.key
add_binds("sessionmenu", lousy.util.table.join({
key({}, "Return", function (w)
local row = w.menu:get()
if row and row.name then
w:set_mode()
session_restore(row.name)
end
end),
key({}, "t", function (w)
local row = w.menu:get()
if row and row.name then
w:set_mode()
session_append(w, row.name)
end
end),
key({}, "d", function (w)
local row = w.menu:get()
if row and row.name then
w.menu:del()
session_del(row.name)
end
end),
-- Exit menu
key({}, "q", function (w) w:set_mode() end),
}, menu_binds))
load()
-- vim: et:sw=4:ts=8:sts=4:tw=80

@ -0,0 +1,66 @@
-------------------------------------------------------------------------------
-- --
-- No-Scipt Status Widget --
-- Adds a simple, skinnable, widget to the status bar to indicate the --
-- current status of scripts and plugins --
-- --
-------------------------------------------------------------------------------
local string = string
local window = window
local webview = webview
local widget = widget
local theme = theme
local luakit = luakit
local domain_props = domain_props
local lousy = require("lousy")
local history = require("history")
module("plugins.nscript_widget")
-- Strings widget uses
local script_str = { enabled = "s", disabled = "!s" }
local plugin_str = { enabled = "p", disabled = "!p" }
-- Load themes, if undefined fallback
theme.nsw_enabled = theme.nsw_enabled or "#0f0"
theme.nsw_disabled = theme.nsw_disabled or "#f00"
-- Create the indictor widget on window creation
window.init_funcs.build_ns_indicator = function(w)
local i = w.sbar.r
i.noscr = widget{type="label"}
i.layout:pack(w.sbar.r.noscr)
i.layout:reorder(w.sbar.r.noscr, 2)
i.noscr.font = theme.buf_sbar_font
w:update_noscr()
-- Update indicator on tab change
w.tabs:add_signal("switch-page", function (_,view)
luakit.idle_add(function() w:update_noscr(w) return false end)
end)
end
-- Update indicator on page navigation
webview.init_funcs.noscr_update = function(view, w)
view:add_signal("load-status", function (v, status)
if status == "committed" or status == "failed" or status == "finished" then
w:update_noscr()
end
end)
end
-- Method wrapper
window.methods.update_noscr = function(w)
if not w.view then return end
local scripts = w.view.enable_scripts
local plugins = w.view.enable_plugins
local noscr = w.sbar.r.noscr
local tmpl = '<span foreground="%s">%s</span> <span foreground="%s">%s</span>'
noscr.text = string.format(tmpl,
( scripts and theme.nsw_enabled ) or theme.nsw_disabled,
( scripts and script_str.enabled ) or script_str.disabled,
( plugins and theme.nsw_enabled ) or theme.nsw_disabled,
( plugins and plugin_str.enabled ) or plugin_str.disabled)
noscr:show()
end

@ -0,0 +1,969 @@
-------------------------------------------------------------------------------
-- Advanced URI-based content filter v0.1.1a --
-- Combines functionality of AdBlock via pattern-match based blocking, --
-- domain/sub-domain matching white and black listing, --
-- a RequestPolicy-like rule system to default-deny 3rd-party requests --
-- and rough per-domain file-type filtering based on URI patterns --
-- --
-- Disclaimer: while this is intended to increase browser security and --
-- help protect privacy, there is no guarantee. Rely on it at your own risk! --
-------------------------------------------------------------------------------
local info = info
local pairs = pairs
local ipairs = ipairs
local assert = assert
local unpack = unpack
local type = type
local io = io
local os = os
local string = string
local table = table
local tostring = tostring
local tonumber = tonumber
local webview = webview
local window = window
local lousy = require("lousy")
local theme = theme
local widget = widget
local util = lousy.util
local chrome = require("chrome")
local capi = { luakit = luakit , sqlite3 = sqlite3 }
local sql_escape = lousy.util.sql_escape
local add_binds, add_cmds = add_binds, add_cmds
local new_mode, menu_binds = new_mode, menu_binds
local lfs = require("lfs")
local setmetatable = setmetatable
-- Public Suffix Lib
local tld = require("tld")
local getdomain = tld.getdomain
-- Calls modifed adblock
--local adblock = require("plugins.adblock")
module("plugins.policy")
pdebug = function (...) io.stdout:write(string.format(...) .. "\n") end
-- Settings Flags =============================================================
filtering = {
-- Flag to accept all requests (disabled all blocking)
acceptall = false,
-- Flag to enable/disable AdBlock / Pattern-Based Blocking
adblock = true,
-- Flag to enable/disable additional scrutiny of 3rd-party requests
requestpolicy = true,
-- Flag to enable/disable file-type blocking policy
typepolicy = true,
-- Flag for whether a subdomain is treated as a 3rd party relative to other subdomains or master domain
strictsubdomain = false,
-- Flas for whether to show status bar widget
widget = true
}
local policy_dir = capi.luakit.data_dir
-- Below is the actual internals of the plugin, here be dragons ---------------
-------------------------------------------------------------------------------
-- Cache to reduce sql calls
local cache = {}
setmetatable(cache, { __mode = "k" })
-- A table to store data for navigation and resource requests
-- it has per-view instances, indexed via navto[v].fields
local navto = {}
setmetatable(navto, { __mode = "k" })
-- Exception listing
local exlist = { white = {}, third = {white = {} } }
-- Makes the following more clear... eg: return codes and internal constants
-- allowing is zero so that reasons for denial can be communicated
local ALLOW = 0
local DENIED = { BLACKLIST = 1, ADBLOCK = 2, NO_WHITELIST = 3, BLACKLISTED_TP = 4 , BLOCKED_TYPE = 5 }
local ANY_PARTY, THIRD_PARTY = 1, 2
local reasonstring = {"Blacklisted", "ABP", "CDR", "Blacklisted-CDR", "F-TYPE", "Other"}
-- sqlite command stings
local create_tables = [[
PRAGMA synchronous = OFF;
PRAGMA secure_delete = 1;
CREATE TABLE IF NOT EXISTS whitelist (
id INTEGER PRIMARY KEY,
domain TEXT UNIQUE);
CREATE TABLE IF NOT EXISTS blacklist (
id INTEGER PRIMARY KEY,
domain TEXT UNIQUE);
CREATE TABLE IF NOT EXISTS tp_whitelist (
id INTEGER PRIMARY KEY,
domain TEXT,
rdomain TEXT);
CREATE TABLE IF NOT EXISTS tp_blacklist (
id INTEGER PRIMARY KEY,
domain TEXT,
rdomain TEXT);
]]
local sql_format = {
match_list = "SELECT * FROM %slist WHERE domain == %s;",
add_list = "INSERT INTO %slist VALUES (NULL, %s);",
remove_list = "DELETE FROM %slist WHERE domain == %s;",
match_tp_list = "SELECT * FROM tp_%slist WHERE domain == %s and rdomain == %s;",
add_tp_list = "INSERT INTO tp_%slist VALUES (NULL, %s, %s);",
remove_tp_list_exact = "DELETE FROM tp_%slist WHERE domain == %s and rdomain == %s;",
remove_tp_list_domain = "DELETE FROM tp_%slist WHERE domain == %s;",
remove_tp_list_rdomain = "DELETE FROM tp_%slist WHERE rdomain == %s;",
}
-- Open or create & initiaze dbi
initalize_rpdb = function()
if rpdb then return end
rpdb = capi.sqlite3{ filename = policy_dir .. "/policy.db" }
rpdb:exec(create_tables)
end
-- Helper functions that perform various utility functions ========================
-- Attempt to parse a uri for the extension of the requested file
-- return file extension in lower case or "NONE" if no extension
local getextension = function (uri)
if uri then
local puri = lousy.uri.parse(uri)
local ext = string.match(puri and puri.path or "", "%.([a-zA-Z0-9]-)$")
return ext and string.lower(ext) or "NONE"
end
return "NONE"
end
-- Check if query is domain or a subdomain of host
local subdomainmatch = function(host, query)
if host == query then
return true
else
local abits = util.string.split(string.reverse(host or ""), "%.")
local bbits = util.string.split(string.reverse(query or ""), "%.")
-- If host is an IP abort, eg: 10.8.4.1 is not a subdomain of 8.4.1
if host and string.match(host, "^%d%.%d%.%d%.%d$") then return false end
-- TODO ipv6 match
for i,s in ipairs(abits) do
if s ~= bbits[i] then
return false
end
end
return true
end
end
-- Checks domains for a match
local domainmatch = function (a, b)
-- If main uri (a) is nil, then it is always "first party"
-- If a == b then they are the same domain
-- Otherwise do a match score and make a fuzzy match
if not a or a == b then
return true
elseif not filtering.strictsubdomain then
local abits = util.string.split(string.reverse(a) or "", "%.")
local bbits = util.string.split(string.reverse(b) or "", "%.")
local matching = 0
-- If an IP, don't do partial matches, TODO ipv6 match
if string.match(a, "^%d%.%d%.%d%.%d$") then return false end
-- Count matching bits
for i,s in ipairs(abits) do
if s == bbits[i] then
matching = matching + 1
else
break
end
end
-- Check the effective tlds of a and b and use that + 1 as the minimum matching requirement
local ab = util.string.split(getdomain(a), "%.")
local bb = util.string.split(getdomain(b), "%.")
local needed_match = ( (#ab > #bb) and #ab) or #bb
if matching >= needed_match then
return true
end
end
return false
end
-- Returns whether or not rhost is whitelisted
local islisted = function (host, rhost, typ, party)
if party == THIRD_PARTY then
local host_bits = util.table.reverse(util.string.split(host or "", "%.") or {})
-- Get base domain, we do not want to match vs. just public suffixes
local n = 1
local phost = getdomain(host)
if not string.match(phost, "^[0-9%.]$") then
local pbits = util.string.split(phost, "%.")
n = #pbits + 1
else
n = #host_bits
end
local list, tlist
-- Make list to match rhost against, use cache if valid
if cache[host] and cache[host][typ] then
list = cache[host][typ]
if typ == "white" then
tlist = exlist.third.white["all"]
repeat
tlist = util.table.join(tlist, exlist.third.white[phost] or {})
phost = (host_bits[n] or "").. "." .. phost
n = n + 1
until n > #host_bits + 1
end
else
list = rpdb:exec(string.format("SELECT * FROM tp_%slist WHERE domain = %s;", typ, sql_escape("all")))
tlist = exlist.third.white["all"]
repeat
local rows = rpdb:exec(string.format("SELECT * FROM tp_%slist WHERE domain = %s;", typ, sql_escape(phost)))
list = util.table.join(list, rows or {})
if typ == "white" then
tlist = util.table.join(tlist, exlist.third.white[phost] or {})
end
phost = (host_bits[n] or "").. "." .. phost
n = n + 1
until n > #host_bits + 1
-- Save list in cache
if not cache[host] then cache[host] = {} end
cache[host][typ] = list
end
-- Match vs lists
for _,v in pairs(list) do
if subdomainmatch(v.rdomain, rhost) or v.rdomain == "all" then
return true
end
end
-- Only check exceptions if checking a whitelist
if typ == "white" then
for k,v in pairs(tlist) do
if subdomainmatch(v, rhost) or v == "all" then
return true
end
end
end
return false
else
local list
if cache[typ] then
list = cache[typ]
else
list = rpdb:exec(string.format("SELECT * FROM %slist;", typ))
cache[typ] = list
end
for _,v in pairs(list) do
if subdomainmatch(v.domain, rhost) then
return true;
end
end
-- Only check exceptions if checking a whitelist
if typ == "white" then
for k,v in pairs(exlist.white) do
if subdomainmatch(k, rhost) then
return true;
end
end
end
end
-- No match was found
return false
end
-- Check Pattern list for matches to rules (aka AdBlocking)
local patternMatch = function (req)
-- This checks that the AdBlock Module is loaded, and if so it calls the matching function
-- I originally intended to re-implement this as part of this plugin, but I decided that
-- it was better to just use a minimally modified version of the upstream AdBlock plugin
if filtering.adblock and adblock and adblock.match then
return not adblock.match(req, "none")
end
return false
end
-- Main logic checking if a request should be allowed or denied
local checkpolicy = function (host, requested, nav, firstnav)
-- A request for a nil uri is denied (should never happen)
if not requested then
return DENIED.BLACKLIST
end
-- Should always accept these
if string.match(requested, "about:blank") or filtering.acceptall then
return ACCEPT
end
-- Get host from requested uri and file-type extension
local rpuri = lousy.uri.parse(requested)
local req = { host = string.lower(rpuri and rpuri.host or ""), ftype = getextension(requested) }
-- webview.uri is nil for the first requests when loading a page (they are always first party)
local puri = lousy.uri.parse(host or "")
host = puri and puri.host or req.host
local wlisted = false
-- Skip checks for data: uris - they would be covered by the policies of whatever they were embedded in
if not string.match(requested, "^data:") then
-- Blacklisting overrides whitelist
if islisted(nil, req.host, "black", ANY_PARTY) then
return DENIED.BLACKLIST
end
-- Check if requested domain is whitelisted
wlisted = islisted(nil, req.host, "white", ANY_PARTY)
-- Whitelisting overrides AdBlocking/Pattern Block
if not wlisted and filtering.adblock then
-- If AdBlock / Pattern matching is enabled, check if requested uri matches and should be blocked
if patternMatch(requested) then
return DENIED.ADBLOCK
end
end
end
-- If RequestPolicy is disabled or this is a first party request only type-blocking is checked
-- If this is a a navigation request or the first request post-navigation, relax CDR, we likely clicked on a link
-- data: uri's are not cross-domain, however we might want to check those with file filtering
if nav or firstnav or not filtering.requestpolicy or domainmatch(host, req.host) or string.match(requested, "^data:")then
-- TODO: file-type blocking
return ACCEPT
else
-- Check if this domain is blacklised for ALL 3rd-party requests -OR-
-- blacklisted for 3rd party requests for the main domain
if islisted(host, req.host, "black", THIRD_PARTY) then
return DENIED.BLACKLISTED_TP
end
-- If requested host is whitelisted universally or for this host for this third party, set to accept
local wlistedtp = islisted(host, req.host, "white", THIRD_PARTY)
if not wlistedtp then
return DENIED.NO_WHITELIST
end
-- TODO: file-type blocking that overrides whitelisted 3rd party requrests
return ACCEPT
end
end
-- Make a table of request's hosts and keep a count of accepted and denied requests
local concatRes = function (l, uri, r)
if uri then
local puri = lousy.uri.parse(uri)
if puri and puri.host then
-- If the host doesn't have a table yet, add it
if not l[puri.host] then
l[puri.host] = {accept = 0, deny = 0, reasons = {}}
end
-- Increment counter (s)
if not r then
l[puri.host].accept = 1 + l[puri.host].accept
else
l[puri.host].deny = 1 + l[puri.host].deny
-- TODO get make this not so hacky ??
l[puri.host].reasons[reasonstring[r]] = (l[puri.host].reasons[reasonstring[r]] or 0) + 1
end
end
end
end
-- Connect signals to all webview widgets on creation
-- TODO check robustness of the firstnav system
webview.init_funcs.policu_signals = function (view, w)
view:add_signal("navigation-request",
function (v, uri)
-- Check if request should be accepted or denied
local r = checkpolicy(v.uri, uri, true , false)
-- if navto[v] does not exist set to empty table
navto[v] = navto[v] or {}
-- Only do the following if request was accepted (r = 0)
if not r then
-- Set temp navigation uri to the requested uri
navto[v].uri = uri
-- Make an empty request table if one does not exist
navto[v].res = navto[v].res or {}
-- Add request to the resource request table
--concatRes(navto[v].res, uri, r) -- TODO I don't think this is needed?
-- XXX "bug-fix" ensures uri bar gets updated on clicking intra-page links
w:update_uri()
elseif r == DENIED.BLACKLIST then
w:error("Policy: Blacklisted domain '" .. uri .. "'")
end
-- Hack to get luakit:// pages to load
local puri = lousy.uri.parse(uri or "")
if puri and puri.scheme == "luakit" then
else
return not r
end
end)
view:add_signal("resource-request-starting",
function (v, uri)
-- Check if request should be accepted or denied
local r = checkpolicy(navto[v].uri or v.uri, uri, false, (navto[v] or {}).first)
-- if w.navto[v] does not exist set to empty table
navto[v] = navto[v] or {}
-- Clear temp navigation uri
navto[v].uri = nil
-- Clear first flag
navto[v].first = false
-- Add the request to the request table
concatRes(navto[v].res, uri, r)
-- Hack to get luakit;// pages to load
local puri = lousy.uri.parse(uri or "")
if puri and puri.scheme == "luakit" then
else
return not r
end
end)
view:add_signal("load-status",
function (v, status)
--pdebug(("policy: load-status signal uri = " .. (v.uri or "") .. "status = " .. status) or "policy: load-status ???")
navto[v] = navto[v] or {}
if status == "provisional" then
-- Resets Resource requests
navto[v].res = {}
navto[v].first = true
elseif status == "committed" then
navto[v].first = false
end
end)
end
-- TODO - All the chrome stuff...
-- luakit://policy/help help page, lists commands and explains how to use plugin
-- luakit://policy displys settings status and links to other pages
-- luakit://policy/whitelist list of whitelisted domains (button to remove, search, and add new entries)
-- luakit://policy/blacklist list of blacklisted domains (button to remove, search, and add new entries)
-- luakit://policy/cdr/whitelist list of CDR whitelist entries (")
-- luakit://policy/cdr/blacklist list of CDR blacklist entries (")
-- luakit://policy/adblock redirects to luakit://adblock
load = function ()
-- Load the db with the white/black lists
initalize_rpdb()
end
-- Functions called by user commands ==========================================
local togglestrings = {
acceptall = "unconditional accepting of all requests.",
adblock = "pattern-based blocking (aka AdBlock).",
requestpolicy = "cross-domain request policy blocking.",
typepolicy = "cross-domain file-type blocking",
strictsubdomain = "strict matching for subdomains.",
widget = "visibility of status widget.",
}
local rp_setting = function (field, value, w)
-- Check that field is a valid settings field
if togglestrings[field] then
-- Check is toggling or setting value
if value == "toggle" then
filtering[field] = not filtering[field]
else
filtering[field] = value
end
-- User feedback on what setting was changed and what it was changed to
w:notify("Policy: " .. (value and "en" or "dis") .. "abled " .. togglestrings[field])
end
-- return validity of the setting
return togglestrings[field] and true
end
-- Clears Excption lists and returns the number of items they contained
local clear_exlist = function ()
local listlen = #exlist.white
for _,v in pairs(exlist.third.white) do
for _,_ in pairs(v) do
listlen = listlen + 1
end
end
exlist.white = {}
exlist.third.white = {}
return listlen or 0
end
-- Returns true if entery exists
local checkList = function (typ, hosts)
local host = hosts[1]
local rhost = hosts[2]
if rhost then
if typ == "ex" then
return exlist.third.white[host] and util.table.hasitem(exlist.third.white[host], rhost) and true
elseif typ == "white" or typ == "black" then
local row = rpdb:exec(string.format(sql_format.match_tp_list, typ, sql_escape(host), sql_escape(rhost)))
return row and row[1] and true
end
else
if typ == "ex" then
return util.table.hasitem(exlist.white, host) and true
elseif typ == "white" or typ == "black" then
local row = rpdb:exec(string.format(sql_format.match_list, typ, sql_escape(host)))
return row and row[1] and true
end
end
end
-- Return Strings, makes localization easier
local retStr = {
sucess = {
add = {
one = {
ex = "Exception added for %s",
white = "Added %s to whitelist",
black = "Added %s to blacklist"},
mul = {
ex = "Exception added for requests from %s to %s",
white = "Whitelisted requests from %s made to %s",
black = "Blacklisted requests from %s made to %s"},
},
del = {
one = {
ex = "Removed exception for %s",
white = "Removed %s from whitelist",
black = "Removed %s from blacklist"},
mul = {
ex = "Exception removed for requests from %s to %s",
white = "Removed whitelisting of requests from %s to %s",
black = "Removed blacklisting of requests from %s to %s"},
},
},
failure = {
add = {
one = {
ex = "Exception had already been granted to %s!",
white = "%s was already whitelisted!",
black = "%s was already blacklisted!"},
mul = {
ex = "Exception had already been granted to requests from %s to %s!",
white = "Requests from %s to %s were already whitelisted!",
black = "Requests from %s to %s were already blacklisted!"},
},
del = {
one = {
ex = "Exception had not been granted to %s!",
white = "%s was not whitelisted!",
black = "%s was not blacklsited!"},
mul = {
ex = "Requests from %s to %s had not been granted an exception!",
white = "Requests from %s to %s were not whitelisted!",
black = "Requests from %s to %s were not blacklisted!"},
},
}} -- end retStr
local modList = function (cmd, typ, hosts, w)
local host = hosts[1]
local rhost = hosts[2]
local listed = checkList(typ, hosts)
local num = (rhost and "mul") or "one"
local suc = "failure"
if cmd == "add" then
if not listed then
if rhost then
if typ == "white" or typ == "black" then
rpdb:exec(string.format(sql_format.add_tp_list,
typ, sql_escape(host), sql_escape(rhost)))
else
if not exlist.third.white[host] then
exlist.third.white[host] = {}
end
table.insert(exlist.third.white[host], rhost)
end
else
if typ == "white" or typ == "black" then
rpdb:exec(string.format(sql_format.add_list, typ, sql_escape(host)))
else
table.insert(exlist.white, host)
end
end
suc = "sucess"
end
elseif cmd == "del" then
if listed then
if rhost then
if typ == "white" or typ == "black" then
rpdb:exec(string.format(sql_format.remove_tp_list_exact,
typ, sql_escape(host), sql_escape(rhost)))
else
local i = util.table.hasitem(exlist.third.white[host] or {}, rhost)
if i then table.remove(exlist.third.white[host], i) end
end
else
if typ == "white" or typ == "black" then
rpdb:exec(string.format(sql_format.remove_list, typ, sql_escape(host)))
else
local i = util.table.hasitem(exlist.white, host)
if i then table.remove(exlist.white, i) end
end
end
suc = "sucess"
end
end
-- Feedback on sucess/failure
if suc == "sucess" then
-- Changed [typ]-list, clear cache
cache = {}
w:notify(string.format(retStr[suc][cmd][num][typ], host or "", rhost or ""))
else
w:error(string.format(retStr[suc][cmd][num][typ], host or "", rhost or ""))
end
end
-- Master user commands parser
local rp_command = function(command, w, a)
a = string.lower(a or "")
local args = util.string.split(util.string.strip(a or ""), " ")
if command == "set" then
-- Set request policy behaviors
local val = not string.match(args[1], "!$")
local set = string.match(args[1], "(.*)!$") or args[1]
if not rp_setting(set, val, w) then
w:error("Policy: set '" .. args[1] .. "' is not a valid setting. (adblock[!], requestpolicy[!], typepolicy[!], acceptall[!], strictsubdomain[!])")
end
elseif command == "clear" then
w:notify(string.format("Removed %d policy exceptions.", clear_exlist()))
else
-- else it's wl/bl/ex and args will be hosts and require special parsing
if #args == 0 or #args > 2 then
w:error("Policy: Wrong number of arguments!")
return
end
-- Attempt to get a host/rhost out of args
local host = args[1] and ((args[1] == "all" and "all") or (lousy.uri.parse(args[1]) or {}).host)
local rhost = args[2] and ((args[2] == "all" and "all") or (lousy.uri.parse(args[2]) or {}).host)
-- Convert empty rhost to nil
if rhost == "" then rhost = nil end
--TODO add host/rhost cheking vs public suffixes with getdomain()
if #args == 1 then
if not host then
w:error("Bad argument error. (" .. host .. ")")
return
end
else
if not host or not rhost then
w:error("Bad argument error. (" .. host .. ", " .. rhost ..")")
return
end
end
if command == "wl" or command == "whitelist" then
modList("add", "white", {host, rhost}, w)
elseif command == "bl" or comamnd == "blacklist" then
modList("add", "black", {host, rhost}, w)
elseif command == "ex" or command == "exception" then
modList("add", "ex", {host, rhost}, w)
elseif command == "wl!" or command == "whitelist!" then
modList("del", "white", {host, rhost}, w)
elseif command == "bl!" or command == "blacklist!" then
modList("del", "black", {host, rhost}, w)
elseif command == "ex!" or command == "exception!" then
modList("del", "ex", {host, rhost}, w)
else
w:error("Policy: '" .. command .. "' is not a valid request policy command!")
end
end
end
-- Add commands ===============================================================
new_mode("policymenu", {
enter = function (w)
local afg = theme.rpolicy_active_menu_fg or theme.proxy_active_menu_fg
local ifg = theme.rpolicy_inactive_menu_fg or theme.proxy_inactive_menu_fg
local abg = theme.rpolicy_active_menu_bg or theme.proxy_active_menu_bg
local ibg = theme.rpolicy_inactive_menu_bg or theme.proxy_inactive_menu_bg
local template = ' Allowed: <span foreground = "#0f0">%2d</span> Blocked: <span foreground = "#f00">%2d</span> %s'
local reason = { start = "[Reason(s):", ends = "]"}
local main = (lousy.uri.parse(w.view.uri) or {}).host or "about:config"
local rows = {}
local main_row
for host,pol in pairs(navto[w.view].res) do
-- Generate a list of reason why requests were blocked
local reasons = ""
for k,_ in pairs(pol.reasons) do
reasons = reasons .. (k and " ") .. k
end
local notcdr = domainmatch(main, host)
-- Underline the main domain of the host
local domain = string.gsub(getdomain(host), "[%.%-]", "%%%1")
local formhost = string.gsub(host, domain, "<u>" .. domain .. "</u>")
if host == main then
main_row = {
" " .. formhost .. "", string.format(template, pol.accept ,pol.deny, ((reasons ~= "") and reason.start .. reasons .. reason.ends) or ""),
host = host, pol = pol,
fg = (notcdr and afg) or ifg,
bg = ibg}
else
table.insert(rows, (notcdr and 1) or #rows +1,
{ " " .. formhost .. "", string.format(template, pol.accept ,pol.deny, ((reasons ~= "") and reason.start .. reasons .. reason.ends) or ""),
host = host, pol = pol,
fg = (notcdr and afg) or ifg,
bg = ibg,
})
end
end
-- Add main host to top of the list
if main_row then
table.insert(rows, 1, main_row)
end
-- Add title row entry
table.insert(rows, 1, { "Domains requested by " .. main, "Actions Taken", title = true })
w.menu:build(rows)
w:notify("Use j/k to move, Enter to select a host and open actions submenu, or h to open policy help (and full list of actions).", false)
end,
leave = function (w)
w.menu:hide()
end,
})
local genLine = function ( fmt, cFmt, cm, h, rh, ifg, ibg)
return {string.format(fmt, h, rh),
string.format(cFmt, cm, h, rh),
host = h, rhost = rh, cmd = cm,
fg = ifg, bg = ibg}
end
new_mode("policysubmenu", {
enter = function (w)
local ifg = theme.rpolicy_inactive_menu_fg or theme.inactive_menu_fg
local ibg = theme.rpolicy_inactive_menu_bg or theme.inactive_menu_bg
local host = navto[w.view].selectedhost or "REQ_HOST"
local main = (lousy.uri.parse(w.view.uri or "") or {}).host or "HOST"
local rows = {{ "Actions for " .. host , "Command", title = true }}
-- Any host
if checkList("white", {host, nil}) then
table.insert(rows, genLine("Remove %s from whitelist", " :rp %s %s", "wl!", host, nil, ifg, ibg))
else
table.insert(rows, genLine("Add %s to whitelist", " :rp %s %s", "wl", host, nil, ifg, ibg))
end
if checkList("black", {host, nil}) then
table.insert(rows, genLine("Remove %s from blacklist", " :rp %s %s", "bl!", host, nil, ifg, ibg))
else
table.insert(rows, genLine("Add %s to blacklist", " :rp %s %s", "bl", host, nil, ifg, ibg))
end
if checkList("ex", {host, nil}) then
table.insert(rows, genLine("Revoke exception for %s", " :rp %s %s", "ex!", host, nil, ifg, ibg))
else
table.insert(rows, genLine("Grant an exception for %s", " :rp %s %s", "ex", host, nil, ifg, ibg))
end
-- For main host
if host == main then
if checkList("white", {host, "all"}) then
table.insert(rows, genLine("Revoke complete CDR whitelisting from %s", " :rp %s %s %s", "wl!", host, "ALL", ifg, ibg))
else
table.insert(rows, genLine("Allow all CDRs from %s", " :rp %s %s %s", "wl", host, "ALL", ifg, ibg))
end
if checkList("black", {host, "all"}) then
table.insert(rows, genLine("Revoke complete CDR blacklisting from %s", " :rp %s %s %s", "bl!", host, "ALL", ifg, ibg))
else
table.insert(rows, genLine("Deny all CDRs from %s", " :rp %s %s %s", "bl", host, "ALL", ifg, ibg))
end
if checkList("ex", {host, "all"}) then
table.insert(rows, genLine("Revoke complete CDR exception from %s", " :rp %s %s %s", "ex!", host, "ALL", ifg, ibg))
else
table.insert(rows, genLine("Grant an excpetion for all CDRs from %s", " :rp %s %s %s", "ex", host, "ALL", ifg, ibg))
end
-- For other hosts
else
if checkList("white", {main, host}) then
table.insert(rows, genLine("Revoke whitelisting of CDRs from %s to %s", " :rp %s %s %s", "wl!", main, host, ifg, ibg))
else
table.insert(rows, genLine("Allow CDRs from %s to %s", " :rp %s %s %s", "wl", main, host, ifg, ibg))
end
if checkList("black", {main, host}) then
table.insert(rows, genLine("Revoke whitelisting of CDRs from %s to %s", " :rp %s %s %s", "bl!", main, host, ifg, ibg))
else
table.insert(rows, genLine("Deny CDRs from %s to %s", " :rp %s %s %s", "bl", main, host, ifg, ibg))
end
if checkList("white", {"all", host}) then
table.insert(rows, genLine("Revoke whitelisting of CDRs from %s to %s", " :rp %s %s %s", "wl!", "ALL", host, ifg, ibg))
else
table.insert(rows, genLine("Allow CDRs from %s to %s", " :rp %s %s %s", "wl", "ALL", host, ifg, ibg))
end
if checkList("black", {"all", host}) then
table.insert(rows, genLine("Revoke whitelisting of CDRs from %s to %s", " :rp %s %s %s", "bl!", "ALL", host, ifg, ibg))
else
table.insert(rows, genLine("Deny CDRs from %s to %s", " :rp %s %s %s", "bl", "ALL", host, ifg, ibg))
end
if checkList("ex", {main, host}) then
table.insert(rows, genLine("Revoke exception for CDRs from %s to %s", " :rp %s %s %s", "ex!", main, host, ifg, ibg))
else
table.insert(rows, genLine("Grant an excpetion for CDRs from %s to %s", " :rp %s %s %s", "ex", main, host, ifg, ibg))
end
if checkList("ex", {"all", host}) then
table.insert(rows, genLine("Revoke exception for CDRs from %s to %s", " :rp %s %s %s", "ex!", "ALL", host, ifg, ibg))
else
table.insert(rows, genLine("Grant an excpetion for CDRs from %s to %s", " :rp %s %s %s", "ex", "ALL", host, ifg, ibg))
end
end
w.menu:build(rows)
w:notify("Use j/k to move, Enter to execute action, S-Enter to edit command, or q to exit.", false)
end,
leave = function (w)
w.menu:hide()
end,
})
-- Adds keybindings for the policy menus
local key = lousy.bind.key
add_binds("policymenu", lousy.util.table.join({
-- Select user agent
key({}, "Return",
function (w)
local row = w.menu:get()
if row then
navto[w.view].selectedhost = row.host
w:set_mode("policysubmenu")
end
end),
-- Exit menu
key({}, "q", function (w) w:set_mode() end),
}, menu_binds))
add_binds("policysubmenu", lousy.util.table.join({
key({}, "Return",
function (w)
local row = w.menu:get()
if row and row.cmd then
w:set_mode()
rp_command(row.cmd, w, (row.host or "") .. " " .. (row.rhost or ""))
end
end),
key({"Shift"}, "Return",
function (w)
local row = w.menu:get()
if row and row[2] then
w:enter_cmd(util.string.strip(row[2]))
end
end),
-- Exit menu
key({}, "q", function (w) w:set_mode() end),
}, menu_binds))
-- Add ex-mode commands
local cmd = lousy.bind.cmd
add_cmds({
cmd({"requestpolicy", "rp"}, "view current page requests",
function (w, a)
if not a then
w:set_mode("policymenu")
else
-- if called with an argument, try to interprate the command
local args = util.string.split(util.string.strip(a or ""), " ")
local aa = string.match(a, ".- (.*)")
rp_command(args[1], w, aa)
end
end),
cmd({"rp-whitelist", "rp-wl"}, "add a whitelist entry",
function(w, a, o)
rp_command((o.bang and "wl!") or "wl", w, a)
end),
cmd({"rp-blacklist", "rp-bl"}, "add a blacklist entry",
function(w, a, o)
rp_command((o.bang and "bl!") or "bl", w, a)
end),
cmd({"rp-exception", "rp-ex"}, "grant temporary exceptions to request polices",
function(w, a, o)
rp_command((o.bang and "ex!") or "ex", w, a)
end),
cmd({"rp-set"}, "set request policy plugin behaviors",
function(w, a)
rp_command("set", w, a)
end),
cmd({"rp-clear"}, "clear request policy exceptions",
function(w, a)
rp_command("clear", w, a)
end),
})
-- Adds buffer command to invoke the policy menu and temp-allow all
-- ,pp = open policy menu
-- ,pa = allow all CDR from current host for this session
-- ,pt = toggle CDR filtering
local buf = lousy.bind.buf
add_binds("normal", {
buf("^,pp$", function (w) w:set_mode("policymenu") end),
buf("^,pa$", function(w)
if w.view and w.view.uri ~= "about:blank" then
rp_command("ex", w, w.view.uri .. " all")
end end),
buf("^,pt$", function (w) rp_setting("requestpolicy", "toggle" ,w) end),
})
-- Status Bar Widget ==========================================================
-- Create the indictor widget on window creation
window.init_funcs.build_policy_indicator = function(w)
local i = w.sbar.r
i.policy = widget{type="label"}
i.layout:pack(w.sbar.r.policy)
i.layout:reorder(w.sbar.r.policy, 1)
i.policy.fg = theme.buf_sbar_fg
i.policy.font = theme.buf_sbar_font
w:update_policy()
-- Update indicator on tab change
w.tabs:add_signal("switch-page", function (_,view)
capi.luakit.idle_add(function() w:update_policy(w) return false end)
end)
end
-- Update indicator on page navigation
webview.init_funcs.policy_update = function(view, w)
view:add_signal("load-status", function (v, status)
if status == "committed" or status == "provisional" then
w:update_policy(false)
elseif status == "failed" or status == "finished" then
w:update_policy(true)
end
end)
end
-- Update contents of request policy widget
window.methods.update_policy = function(w, fin)
if not w.view then return end
local pw = w.sbar.r.policy
if filtering.widget then
local text
if not fin then
text = "[Loading...]"
else
text = "["
if navto[w.view].res then
local acc, rej = 0, 0
for _,pol in pairs(navto[w.view].res) do
acc = acc + pol.accept
rej = rej + pol.deny
end
text = text .. string.format("<span foreground=\"#0f0\">A%d</span> <span foreground=\"#f00\">B%d</span>", acc, rej)
end
text = text .. "]"
end
pw.text = text
pw:show()
else
pw:hide()
end
end
-- Call load()
load()

@ -0,0 +1,89 @@
-------------------------------------------------------------------------------
-- --
-- Blocks Adding "Private Browsing" Hosts to History DB --
-- --
-------------------------------------------------------------------------------
local string = string
local window = window
local webview = webview
local widget = widget
local theme = theme
local luakit = luakit
local domain_props = domain_props
local lousy = require("lousy")
local util = lousy.util
local history = require("history")
local nohist = globals.history_blacklist or {}
local print = print
module("plugins.private_browsing")
local indicator = { private = "!hist", notprivate = "" }
-- Load themes, if undefined fallback
theme.pbm_font = theme.pbm_font or theme.buf_sbar_font
theme.pbm_fg = theme.pbm_fg or theme.buf_sbar_fg
theme.pbm_bg = theme.pbm_bg or theme.buf_sbar_bg
-- Create the indictor widget on window creation
window.init_funcs.build_pindicator = function(w)
local i = w.sbar.r
i.prvt = widget{type="label"}
i.layout:pack(w.sbar.r.prvt)
i.layout:reorder(w.sbar.r.prvt, 2)
i.prvt.font = theme.buf_sbar_font
i.prvt.fg = theme.buf_sbar_fg
w:update_prvt()
-- Update indicator on tab change
w.tabs:add_signal("switch-page", function (_,view)
luakit.idle_add(function() w:update_prvt(w) return false end)
end)
end
-- Update indicator on page navigation
webview.init_funcs.prvt_update = function(view, w)
view:add_signal("load-status", function (v, status)
if status == "comitted" or status == "failed" or status == "finished" then
w:update_prvt()
end
end)
end
-- Updates widget based on status
window.methods.update_prvt = function(w)
if not w.view then return end
local private_br = w.view.enable_private_browsing
local domain = (lousy.uri.parse(w.view.uri) or {}).host or ""
domain = string.match(domain, "^www%.(.+)") or domain
repeat
private_br = private_br or util.table.hasitem(nohist, domain)
domain = string.match(domain, "%.(.+)")
until not domain
local prvt = w.sbar.r.prvt
-- Set widget text based on privacy setting
prvt.text = (private_br and indicator.private) or indicator.notprivate
-- Hide blank widget
if string.len(prvt.text) then
prvt:show()
else
prvt:hide()
end
end
-- Hook to intercept history additions
history.add_signal("add", function (uri, title)
local domain = lousy.uri.parse(uri).host
domain = string.match(domain or "", "^www%.(.+)") or domain or "all"
-- Build list of domains and subdomains, pulling private browsing.
-- I.e. for luakit.org load .luakit.org, luakit.org, .org
local no_hist = domain_props.all.enable_private_browsing or (domain_props[domain] or {}).enable_private_browsing
repeat
no_hist = no_hist or (domain_props["."..domain] or {}).enable_private_browsing
no_hist = no_hist or util.table.hasitem(nohist, domain)
domain = string.match(domain, "%.(.+)")
until not domain
return not no_hist
end)

@ -0,0 +1,186 @@
-----------------------------------------------------------------------
-- luakit configuration file, more information at http://luakit.org/ --
-----------------------------------------------------------------------
require "lfs"
if unique then
unique.new("org.luakit")
-- Check for a running luakit instance
if unique.is_running() then
if uris[1] then
for _, uri in ipairs(uris) do
if lfs.attributes(uri) then uri = os.abspath(uri) end
unique.send_message("tabopen " .. uri)
end
else
unique.send_message("winopen")
end
luakit.quit()
end
end
-- Load library of useful functions for luakit
require "lousy"
-- Small util functions to print output (info prints only when luakit.verbose is true)
function warn(...) io.stderr:write(string.format(...) .. "\n") end
function info(...) if luakit.verbose then io.stdout:write(string.format(...) .. "\n") end end
-- Load users global config
-- ("$XDG_CONFIG_HOME/luakit/globals.lua" or "/etc/xdg/luakit/globals.lua")
require "globals"
-- Load users theme
-- ("$XDG_CONFIG_HOME/luakit/theme.lua" or "/etc/xdg/luakit/theme.lua")
lousy.theme.init(lousy.util.find_config("theme.lua"))
theme = assert(lousy.theme.get(), "failed to load theme")
-- Load users window class
-- ("$XDG_CONFIG_HOME/luakit/window.lua" or "/etc/xdg/luakit/window.lua")
require "window"
-- Load users webview class
-- ("$XDG_CONFIG_HOME/luakit/webview.lua" or "/etc/xdg/luakit/webview.lua")
require "webview"
-- Load users mode configuration
-- ("$XDG_CONFIG_HOME/luakit/modes.lua" or "/etc/xdg/luakit/modes.lua")
require "modes"
-- Load users keybindings
-- ("$XDG_CONFIG_HOME/luakit/binds.lua" or "/etc/xdg/luakit/binds.lua")
require "binds"
----------------------------------
-- Optional user script loading --
----------------------------------
require "webinspector"
-- Add sqlite3 cookiejar
require "cookies"
-- Cookie blocking by domain (extends cookies module)
-- Add domains to the whitelist at "$XDG_CONFIG_HOME/luakit/cookie.whitelist"
-- and blacklist at "$XDG_CONFIG_HOME/luakit/cookie.blacklist".
-- Each domain must be on it's own line and you may use "*" as a
-- wildcard character (I.e. "*google.com")
--require "cookie_blocking"
-- Block all cookies by default (unless whitelisted)
--cookies.default_allow = false
-- Add uzbl-like form filling
require "formfiller"
-- Add proxy support & manager
require "proxy"
-- Add quickmarks support & manager
require "quickmarks"
-- Add session saving/loading support
require "session"
-- Add command to list closed tabs & bind to open closed tabs
require "undoclose"
-- Add command to list tab history items
require "tabhistory"
-- Add greasemonkey-like javascript userscript support
require "userscripts"
-- Add bookmarks support
require "bookmarks"
require "bookmarks_chrome"
-- Add download support
require "downloads"
require "downloads_chrome"
-- Example using xdg-open for opening downloads / showing download folders
--downloads.add_signal("open-file", function (file, mime)
-- luakit.spawn(string.format("xdg-open %q", file))
-- return true
--end)
-- Add vimperator-like link hinting & following
require "follow"
-- Use a custom charater set for hint labels
--local s = follow.label_styles
--follow.label_maker = s.sort(s.reverse(s.charset("asdfqwerzxcv")))
-- Match only hint labels
--follow.pattern_maker = follow.pattern_styles.match_label
-- Add command history
require "cmdhist"
-- Add search mode & binds
require "search"
-- Add ordering of new tabs
require "taborder"
-- Save web history
require "history"
require "history_chrome"
require "introspector"
-- Add command completion
require "completion"
-- NoScript plugin, toggle scripts and or plugins on a per-domain basis.
-- `,ts` to toggle scripts, `,tp` to toggle plugins, `,tr` to reset.
-- Remove all "enable_scripts" & "enable_plugins" lines from your
-- domain_props table (in config/globals.lua) as this module will conflict.
--require "noscript"
require "follow_selected"
require "go_input"
require "go_next_prev"
require "go_up"
-----------------------------
-- End user script loading --
-----------------------------
-- Restore last saved session
local w = (session and session.restore())
if w then
for i, uri in ipairs(uris) do
w:new_tab(uri, i == 1)
end
else
-- Or open new window
window.new(uris)
end
-------------------------------------------
-- Open URIs from other luakit instances --
-------------------------------------------
if unique then
unique.add_signal("message", function (msg, screen)
local cmd, arg = string.match(msg, "^(%S+)%s*(.*)")
local w = lousy.util.table.values(window.bywidget)[1]
if cmd == "tabopen" then
w:new_tab(arg)
elseif cmd == "winopen" then
w = window.new((arg ~= "") and { arg } or {})
end
w.win.screen = screen
w.win.urgency_hint = true
end)
end
-- Some plugins I found
-- require "nscript_widget"
-- require "private_browsing"
require "useragent"
-- vim: et:sw=4:ts=8:sts=4:tw=80

@ -0,0 +1,74 @@
--------------------------
-- Default luakit theme --
--------------------------
local theme = {}
-- Default settings
theme.font = "terminus 8"
theme.fg = "#fff"
theme.bg = "#000"
-- Genaral colours
theme.success_fg = "#0f0"
theme.loaded_fg = "#33AADD"
theme.error_fg = "#FFF"
theme.error_bg = "#F00"
-- Warning colours
theme.warning_fg = "#F00"
theme.warning_bg = "#FFF"
-- Notification colours
theme.notif_fg = "#444"
theme.notif_bg = "#FFF"
-- Menu colours
theme.menu_fg = "#000"
theme.menu_bg = "#fff"
theme.menu_selected_fg = "#000"
theme.menu_selected_bg = "#FF0"
theme.menu_title_bg = "#fff"
theme.menu_primary_title_fg = "#f00"
theme.menu_secondary_title_fg = "#666"
-- Proxy manager
theme.proxy_active_menu_fg = '#000'
theme.proxy_active_menu_bg = '#FFF'
theme.proxy_inactive_menu_fg = '#888'
theme.proxy_inactive_menu_bg = '#FFF'
-- Statusbar specific
theme.sbar_fg = "#fff"
theme.sbar_bg = "#000"
-- Downloadbar specific
theme.dbar_fg = "#fff"
theme.dbar_bg = "#000"
theme.dbar_error_fg = "#F00"
-- Input bar specific
--theme.ibar_fg = "#000"
--theme.ibar_bg = "#fff"
theme.ibar_bg = "#000"
theme.ibar_fg = "#fff"
-- Tab label
--theme.tab_fg = "#888"
theme.tab_fg = "#aaa"
--theme.tab_bg = "#222"
theme.tab_bg = "#000"
theme.tab_ntheme = "#ddd"
theme.selected_fg = "#fff"
--theme.selected_bg = "#000"
theme.selected_bg = "#056"
theme.selected_ntheme = "#ddd"
theme.loading_fg = "#33AADD"
theme.loading_bg = "#000"
-- Trusted/untrusted ssl colours
theme.trust_fg = "#0F0"
theme.notrust_fg = "#F00"
return theme
-- vim: et:sw=4:ts=8:sts=4:tw=80

@ -0,0 +1,343 @@
------------------------------------------------------------
-- Dynamic useragent settings --
-- Written by lokichaos based upon proxy.lua by: --
--
-- Copyright © Piotr Husiatyński <phusiatynski@gmail.com> --
------------------------------------------------------------
-- TODO
-- make per-tab widget & add hooks to update it
-- save ua in table
-- clean table for GC pruning
-- set behavior: set-current, set-all, set-new
-- Grab environment we need
local io = io
local os = os
local pairs = pairs
local ipairs = ipairs
local error = error
local string = string
local lousy = require "lousy"
local theme = theme
local unpack = unpack
local table = table
local capi = { luakit = luakit, soup = soup }
local webview = webview
local widget = widget
local window = window
local util = lousy.util
local globals = globals
-- Check for mode/bind functions
local add_binds, add_cmds = add_binds, add_cmds
local new_mode, menu_binds = new_mode, menu_binds
local setmetatable = setmetatable
module("plugin.useragent")
-- Store each webview's ua-name
local uas = {}
setmetatable(uas, { __mode = "k" })
--- Module global variables
local agents_file = capi.luakit.data_dir .. '/useragentmenu'
local useragents = {}
local realagent = { name = 0, uastring = globals.useragent }
local active = realagent
local default_name = nil
-- Return ordered list of user agent names
function get_names()
return lousy.util.table.keys(useragents)
end
-- Return ua string of user agent given by name
function get(name)
return useragents[name]
end
--- Load user agents list from file
-- @param fd_name custom user agent storage of nil to use default
function load(fd_name)
local fd_name = fd_name or agents_file
if not os.exists(fd_name) then return end
local strip = lousy.util.string.strip
for line in io.lines(fd_name) do
local status, name, uastring = string.match(line, "^(.)%s(.+)%s\"(.+)\"$")
if uastring then
name, uastring = strip(name), strip(uastring)
if status == '*' then
active = { uastring = uastring, name = name }
end
useragents[name] = uastring
end
end
-- Set saved default ua string
globals.useragent = active.uastring
default_name = active.name
end
--- Save user agents list to file
-- @param fd_name custom user agent storage of nil to use default
function save(fd_name)
local fd = io.open(fd_name or agents_file, "w")
for name, uastring in pairs(useragents) do
if uastrings ~= "" then
local status = (active.name == name and '*') or ' '
fd:write(string.format("%s %s \"%s\"\n", status, name, uastring))
end
end
io.close(fd)
end
--- Add new user agent to current list
-- @param name user agent configuration name
-- @param uastring user agent string
-- @param save_file do not save configuration if false
function set(name, uastring, save_file)
local name = lousy.util.string.strip(name)
if not string.match(name, "^([%w%p]+)$") then
error("Invalid user agent name: " .. name)
end
useragents[name] = lousy.util.string.strip(uastring)
if save_file ~= false then save() end
end
--- Delete selected user agent from list
-- @param name user agent name
-- TODO check all tabs
function del(name, w)
local name = lousy.util.string.strip(name)
if useragents[name] then
-- if deleted user agent was the active one, use real/default uastring
if name == active.name then
active = realagent
end
useragents[name] = nil
save()
end
end
--- Set given user agent to active. Return true on success, else false
-- @param name user agents configuration name or nil to unset user agent.
function set_active(name)
if name ~= 0 then
local name = lousy.util.string.strip(name)
if not useragents[name] then
error("Unknown user agent: " .. name)
end
active = { name = name, uastring = useragents[name] }
else
active = realagent
end
save()
return true
end
-- Create a user agent indicator widget and add it to the status bar
window.init_funcs.build_ua_indicator = function (w)
local r = w.sbar.r
r.uai = widget{type="label"}
r.layout:pack(r.uai)
r.layout:reorder(r.uai, 2)
r.uai.fg = theme.useragenti_sbar_fg or theme.sbar_fg
r.uai.font = theme.useragenti_sbar_font or theme.sbar_font
w.tabs:add_signal("switch-page", function (nbook, view, idx)
capi.luakit.idle_add(function() w:update_ua_indicator() return false end)
end)
w:update_ua_indicator()
end
-- Helper function to update text in user agent indicator
window.methods.update_ua_indicator = function (w)
local name = uas[w.view] or (uas[w.view] == 0 and 0) or default_name
local uai = w.sbar.r.uai
if name ~= 0 then
local text = string.format("(%s)", name)
if uai.text ~= text then uai.text = text end
uai:show()
else
uai:hide()
end
end
new_mode("uagentmenu", {
enter = function (w)
-- Set all tab's uas entires
for index = 1, w.tabs:count() do
uas[w.tabs[index]] = uas[w.tabs[index]] or default_name
end
local afg = theme.useragent_active_menu_fg or theme.proxy_active_menu_fg
local ifg = theme.useragent_inactive_menu_fg or theme.proxy_inactive_menu_fg
local abg = theme.useragent_active_menu_bg or theme.proxy_active_menu_bg
local ibg = theme.useragent_inactive_menu_bg or theme.proxy_inactive_menu_bg
-- "Active" user agent, this is the one that is saved as a default between sessions
local act_ua = uas[w.view]
-- Add titlebar, and "Default" UA entry
local dname = string.format(" %s %s%s", "Default Luakit User Agent",
(active.name == 0 and "[Default]") or "",
(default_name == 0 and "[Session]") or "")
local rows = {{ "User Agent Name", " User Agent String", title = true },
{ dname, " " .. realagent.uastring or "", name = 0, uastring = '',
fg = (act_ua == 0 and afg) or ifg,
bg = (act_ua == 0 and abg) or ibg},}
for _, name in ipairs(get_names()) do
local uastring = get(name)
local uaname = string.format(" %s %s%s", name,
(active.name == name and "[Default]") or "",
(default_name == name and "[Session]") or "")
table.insert(rows, {
uaname, " " .. uastring,
name = name, uastring = lousy.util.escape(uastring),
fg = (act_ua == name and afg) or ifg,
bg = (act_ua == name and abg) or ibg,
})
end
w.menu:build(rows)
w:notify("Use j/k to move, [d]elete, [e]dit, [a]dd, [S]et default, [s]et for all tabs, [n] set for new tabs, return to set for current tab.", false)
end,
leave = function (w)
w.menu:hide()
end,
})
local cmd = lousy.bind.cmd
add_cmds({
cmd({"agent", "ua"}, "add new or select useragent",
function (w, a)
if not a then
w:set_mode("uagentmenu")
else
local name, uastring = string.match(a, "(.+)%s\"(.+)\"")
if name and uastring then
set(name, uastring)
else
w:error("Bad usage. Correct format :agent <name> \"<agent string>\"")
end
end
end),
})
local ua_set = function(mode, ua, w)
if mode == "current" then
w.view.user_agent = ua.uastring or realagent.uastring
uas[w.view] = ua.name
if ua.name ~= 0 then
w:notify(string.format("Set user agent on this tab to: %s (%s).", ua.name, ua.uastring))
else
w:notify("Set user agent for current tab to default.")
end
elseif mode == "newtabs" then
globals.useragent = ua.uastring
default_name = ua.name
if ua.name ~= 0 then
w:notify(string.format("Set user agent for all new tabs to: %s (%s).", ua.name, ua.uastring))
else
w:notify("Set user agent for all new tabs to default Luakit.")
end
elseif mode == "all" then
-- New Tabs will use this
globals.useragent = ua.uastring
default_name = ua.name
-- Set user agent for all existing tabs
for index = 1, w.tabs:count() do
w.tabs[index].user_agent = ua.uastring
uas[w.tabs[index]] = ua.name
end
if ua.name ~= 0 then
w:notify(string.format("Set user agent for all tabs to: %s (%s).", ua.name, ua.uastring))
else
w:notify("Set user agent for all tabs to default.")
end
elseif mode == "default" then
globals.useragent = ua.uastring
default_name = ua.name
set_active(ua.name)
if ua.name ~= 0 then
w:notify(string.format("Set %s as default useragent (%s)", ua.name, ua.uastring))
else
w:notify("Unset default useragent, will default to real Luakit one.")
end
end
-- Update useragent statusbar widget
w:update_ua_indicator()
end
local key = lousy.bind.key
add_binds("uagentmenu", lousy.util.table.join({
-- Select user agent
key({}, "Return",
function (w)
local row = w.menu:get()
if row then
w:set_mode()
ua_set("current", row, w)
end
end),
key({}, "S",
function (w)
local row = w.menu:get()
if row then
w:set_mode()
ua_set("default", row, w)
end
end),
key({}, "s",
function (w)
local row = w.menu:get()
if row then
w:set_mode()
ua_set("all", row, w)
end
end),
key({}, "n",
function (w)
local row = w.menu:get()
if row then
w:set_mode()
ua_set("newtabs", row, w)
end
end),
-- Delete user agent
key({}, "d",
function (w)
local row = w.menu:get()
if row and row.name then
del(row.name)
w.menu:del()
end
end),
-- Edit user agent
key({}, "e",
function (w)
local row = w.menu:get()
if row and row.name then
w:enter_cmd(string.format(":agent %s \"%s\"", row.name, row.uastring))
end
end),
-- New user agent
key({}, "a", function (w) w:enter_cmd(":agent ") end),
-- Exit menu
key({}, "q", function (w) w:set_mode() end),
}, menu_binds))
-- Initialize module
load()
-- vim: et:sw=4:ts=8:sts=4

@ -0,0 +1,10 @@
camino "Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.6; en; rv:1.9.2.14pre) Gecko/20101212 Camino/2.1a1pre (like Firefox/3.6.14pre)"
googlebot "Googlebot/2.1 ( http://www.googlebot.com/bot.html)"
firefox15 "Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120427 Firefox/15.0a1"
safari "Mozilla/5.0 (Macintosh; PPC Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10"
inferfox "Mozilla/6.0 (compatible; AppleWebKit/latest; like Gecko/20120405; };-> infernal_edition:goto-hell) Firefox/666"
firefox11 "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko Firefox/11.0"
firefox13 "Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20120403211507 Firefox/12.0"
ie10 "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
firefox14 "Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20120405 Firefox/14.0a1"
opera10 "Opera/9.80 (Macintosh; Intel Mac OS X; U; en) Presto/2.2.15 Version/10.10"

@ -0,0 +1,350 @@
--------------------------
-- WebKit WebView class --
--------------------------
-- Webview class table
webview = {}
-- Table of functions which are called on new webview widgets.
webview.init_funcs = {
-- Set useragent
set_useragent = function (view, w)
view.user_agent = globals.useragent
end,
-- Check if checking ssl certificates
checking_ssl = function (view, w)
local ca_file = soup.ssl_ca_file
if ca_file and os.exists(ca_file) then
w.checking_ssl = true
end
end,
-- Update window and tab titles
title_update = function (view, w)
view:add_signal("property::title", function (v)
w:update_tablist()
if w.view == v then
w:update_win_title()
end
end)
end,
-- Update uri label in statusbar
uri_update = function (view, w)
view:add_signal("property::uri", function (v)
w:update_tablist()
if w.view == v then
w:update_uri()
end
end)
end,
-- Update history indicator
hist_update = function (view, w)
view:add_signal("load-status", function (v, status)
if w.view == v then
w:update_hist()
end
end)
end,
-- Update tab titles
tablist_update = function (view, w)
view:add_signal("load-status", function (v, status)
if status == "provisional" or status == "finished" or status == "failed" then
w:update_tablist()
end
end)
end,
-- Update scroll widget
scroll_update = function (view, w)
view:add_signal("expose", function (v)
if w.view == v then
w:update_scroll()
end
end)
end,
-- Update progress widget
progress_update = function (view, w)
for _, sig in ipairs({"load-status", "property::progress"}) do
view:add_signal(sig, function (v)
if w.view == v then
w:update_progress()
w:update_ssl()
end
end)
end
end,
-- Display hovered link in statusbar
link_hover_display = function (view, w)
view:add_signal("link-hover", function (v, link)
if w.view == v and link then
w:update_uri(link)
end
end)
view:add_signal("link-unhover", function (v)
if w.view == v then
w:update_uri()
end
end)
end,
-- Clicking a form field automatically enters insert mode.
form_insert_mode = function (view, w)
view:add_signal("button-press", function (v, mods, button, context)
-- Clear start search marker
(w.search_state or {}).marker = nil
if button == 1 and context.editable then
view:emit_signal("form-active")
end
end)
-- Emit root-active event in button release to prevent "missing"
-- buttons or links when the input bar hides.
view:add_signal("button-release", function (v, mods, button, context)
if button == 1 and not context.editable then
view:emit_signal("root-active")
end
end)
view:add_signal("form-active", function ()
if not w.mode.passthrough then
w:set_mode("insert")
end
end)
view:add_signal("root-active", function ()
if w.mode.reset_on_focus ~= false then
w:set_mode()
end
end)
end,
-- Catch keys in non-passthrough modes
mode_key_filter = function (view, w)
view:add_signal("key-press", function ()
if not w.mode.passthrough then
return true
end
end)
end,
-- Try to match a button event to a users button binding else let the
-- press hit the webview.
button_bind_match = function (view, w)
view:add_signal("button-release", function (v, mods, button, context)
(w.search_state or {}).marker = nil
if w:hit(mods, button, { context = context }) then
return true
end
end)
end,
-- Reset the mode on navigation
mode_reset_on_nav = function (view, w)
view:add_signal("load-status", function (v, status)
if status == "provisional" and w.view == v then
if w.mode.reset_on_navigation ~= false then
w:set_mode()
end
end
end)
end,
-- Domain properties
domain_properties = function (view, w)
view:add_signal("load-status", function (v, status)
if status ~= "committed" or v.uri == "about:blank" then return end
-- Get domain
local domain = lousy.uri.parse(v.uri).host
-- Strip leading www.
domain = string.match(domain or "", "^www%.(.+)") or domain or "all"
-- Build list of domain props tables to join & load.
-- I.e. for luakit.org load .luakit.org, luakit.org, .org
local props = {domain_props.all or {}, domain_props[domain] or {}}
repeat
table.insert(props, 2, domain_props["."..domain] or {})
domain = string.match(domain, "%.(.+)")
until not domain
-- Join all property tables
for k, v in pairs(lousy.util.table.join(unpack(props))) do
info("Domain prop: %s = %s (%s)", k, tostring(v), domain)
view[k] = v
end
end)
end,
-- Action to take on mime type decision request.
mime_decision = function (view, w)
-- Return true to accept or false to reject from this signal.
view:add_signal("mime-type-decision", function (v, uri, mime)
info("Requested link: %s (%s)", uri, mime)
-- i.e. block binary files like *.exe
--if mime == "application/octet-stream" then
-- return false
--end
end)
end,
-- Action to take on window open request.
--window_decision = function (view, w)
-- view:add_signal("new-window-decision", function (v, uri, reason)
-- if reason == "link-clicked" then
-- window.new({uri})
-- else
-- w:new_tab(uri)
-- end
-- return true
-- end)
--end,
create_webview = function (view, w)
-- Return a newly created webview in a new tab
view:add_signal("create-web-view", function (v)
return w:new_tab()
end)
end,
-- Creates context menu popup from table (and nested tables).
-- Use `true` for menu separators.
--populate_popup = function (view, w)
-- view:add_signal("populate-popup", function (v)
-- return {
-- true,
-- { "_Toggle Source", function () w:toggle_source() end },
-- { "_Zoom", {
-- { "Zoom _In", function () w:zoom_in() end },
-- { "Zoom _Out", function () w:zoom_out() end },
-- true,
-- { "Zoom _Reset", function () w:zoom_set() end }, }, },
-- }
-- end)
--end,
-- Action to take on resource request.
resource_request_decision = function (view, w)
view:add_signal("resource-request-starting", function(v, uri)
info("Requesting: %s", uri)
-- Return false to cancel the request.
end)
end,
}
-- These methods are present when you index a window instance and no window
-- method is found in `window.methods`. The window then checks if there is an
-- active webview and calls the following methods with the given view instance
-- as the first argument. All methods must take `view` & `w` as the first two
-- arguments.
webview.methods = {
-- Reload with or without ignoring cache
reload = function (view, w, bypass_cache)
if bypass_cache then
view:reload_bypass_cache()
else
view:reload()
end
end,
-- Toggle source view
toggle_source = function (view, w, show)
if show == nil then
view.view_source = not view.view_source
else
view.view_source = show
end
view:reload()
end,
-- Zoom functions
zoom_in = function (view, w, step, full_zoom)
view.full_content_zoom = not not full_zoom
step = step or globals.zoom_step or 0.1
view.zoom_level = view.zoom_level + step
end,
zoom_out = function (view, w, step, full_zoom)
view.full_content_zoom = not not full_zoom
step = step or globals.zoom_step or 0.1
view.zoom_level = math.max(0.01, view.zoom_level) - step
end,
zoom_set = function (view, w, level, full_zoom)
view.full_content_zoom = not not full_zoom
view.zoom_level = level or 1.0
end,
-- History traversing functions
back = function (view, w, n)
view:go_back(n or 1)
end,
forward = function (view, w, n)
view:go_forward(n or 1)
end,
}
function webview.methods.scroll(view, w, new)
local s = view.scroll
for _, axis in ipairs{ "x", "y" } do
-- Relative px movement
if rawget(new, axis.."rel") then
s[axis] = s[axis] + new[axis.."rel"]
-- Relative page movement
elseif rawget(new, axis .. "pagerel") then
s[axis] = s[axis] + math.ceil(s[axis.."page_size"] * new[axis.."pagerel"])
-- Absolute px movement
elseif rawget(new, axis) then
local n = new[axis]
if n == -1 then
s[axis] = s[axis.."max"]
else
s[axis] = n
end
-- Absolute page movement
elseif rawget(new, axis.."page") then
s[axis] = math.ceil(s[axis.."page_size"] * new[axis.."page"])
-- Absolute percent movement
elseif rawget(new, axis .. "pct") then
s[axis] = math.ceil(s[axis.."max"] * (new[axis.."pct"]/100))
end
end
end
function webview.new(w)
local view = widget{type = "webview"}
view.show_scrollbars = false
view.enforce_96_dpi = false
-- Call webview init functions
for k, func in pairs(webview.init_funcs) do
func(view, w)
end
return view
end
-- Insert webview method lookup on window structure
table.insert(window.indexes, 1, function (w, k)
if k == "view" then
local view = w.tabs[w.tabs:current()]
if view and type(view) == "widget" and view.type == "webview" then
w.view = view
return view
end
end
-- Lookup webview method
local func = webview.methods[k]
if not func then return end
local view = w.view
if view then
return function (_, ...) return func(view, w, ...) end
end
end)
-- vim: et:sw=4:ts=8:sts=4:tw=80

@ -0,0 +1,859 @@
------------------
-- Window class --
------------------
require "lfs"
-- Window class table
window = {}
-- List of active windows by window widget
window.bywidget = setmetatable({}, { __mode = "k" })
-- Widget construction aliases
local function entry() return widget{type="entry"} end
local function eventbox() return widget{type="eventbox"} end
local function hbox() return widget{type="hbox"} end
local function label() return widget{type="label"} end
local function notebook() return widget{type="notebook"} end
local function vbox() return widget{type="vbox"} end
-- Build and pack window widgets
function window.build()
-- Create a table for widgets and state variables for a window
local w = {
win = widget{type="window"},
ebox = eventbox(),
layout = vbox(),
paned = widget{type="vpaned"},
tabs = notebook(),
-- Tablist widget
tablist = lousy.widget.tablist(),
-- Status bar widgets
sbar = {
layout = hbox(),
ebox = eventbox(),
-- Left aligned widgets
l = {
layout = hbox(),
ebox = eventbox(),
uri = label(),
hist = label(),
loaded = label(),
},
-- Fills space between the left and right aligned widgets
sep = eventbox(),
-- Right aligned widgets
r = {
layout = hbox(),
ebox = eventbox(),
buf = label(),
ssl = label(),
tabi = label(),
scroll = label(),
},
},
-- Vertical menu window widget (completion results, bookmarks, qmarks, ..)
menu = lousy.widget.menu(),
-- Input bar widgets
ibar = {
layout = hbox(),
ebox = eventbox(),
prompt = label(),
input = entry(),
},
closed_tabs = {}
}
-- Assemble window
w.ebox.child = w.paned
w.paned:pack1(w.layout)
w.win.child = w.ebox
-- Pack tablist
w.layout:pack(w.tablist.widget)
-- Pack notebook
w.layout:pack(w.tabs, { expand = true, fill = true })
-- Pack left-aligned statusbar elements
local l = w.sbar.l
l.layout:pack(l.uri)
l.layout:pack(l.hist)
l.layout:pack(l.loaded)
l.ebox.child = l.layout
-- Pack right-aligned statusbar elements
local r = w.sbar.r
r.layout:pack(r.buf)
r.layout:pack(r.ssl)
r.layout:pack(r.tabi)
r.layout:pack(r.scroll)
r.ebox.child = r.layout
-- Pack status bar elements
local s = w.sbar
s.layout:pack(l.ebox)
s.layout:pack(s.sep, { expand = true, fill = true })
s.layout:pack(r.ebox)
s.ebox.child = s.layout
w.layout:pack(s.ebox)
-- Pack menu widget
w.layout:pack(w.menu.widget)
w.menu:hide()
-- Pack input bar
local i = w.ibar
i.layout:pack(i.prompt)
i.layout:pack(i.input, { expand = true, fill = true })
i.ebox.child = i.layout
w.layout:pack(i.ebox)
-- Other settings
i.input.show_frame = false
w.tabs.show_tabs = false
l.loaded:hide()
l.hist:hide()
l.uri.selectable = true
r.ssl:hide()
-- Allows indexing of window struct by window widget
window.bywidget[w.win] = w
return w
end
-- Table of functions to call on window creation. Normally used to add signal
-- handlers to the new windows widgets.
window.init_funcs = {
-- Attach notebook widget signals
notebook_signals = function (w)
w.tabs:add_signal("page-added", function (nbook, view, idx)
luakit.idle_add(function ()
w:update_tab_count()
w:update_tablist()
return false
end)
end)
w.tabs:add_signal("switch-page", function (nbook, view, idx)
w.view = nil
w:set_mode()
-- Update widgets after tab switch
luakit.idle_add(function ()
w:update_tab_count()
w:update_win_title()
w:update_uri()
w:update_progress()
w:update_tablist()
w:update_buf()
w:update_ssl()
w:update_hist()
return false
end)
end)
w.tabs:add_signal("page-reordered", function (nbook, view, idx)
w:update_tab_count()
w:update_tablist()
end)
end,
last_win_check = function (w)
w.win:add_signal("destroy", function ()
-- call the quit function if this was the last window left
if #luakit.windows == 0 then luakit.quit() end
if w.close_win then w:close_win() end
end)
end,
key_press_match = function (w)
w.win:add_signal("key-press", function (_, mods, key)
-- Match & exec a bind
local success, match = xpcall(
function () return w:hit(mods, key) end,
function (err) w:error(debug.traceback(err, 3)) end)
if success and match then
return true
end
end)
end,
tablist_tab_click = function (w)
w.tablist:add_signal("tab-clicked", function (_, index, mods, button)
if button == 1 then
w.tabs:switch(index)
return true
elseif button == 2 then
w:close_tab(w.tabs[index])
return true
end
end)
end,
apply_window_theme = function (w)
local s, i = w.sbar, w.ibar
-- Set foregrounds
for wi, v in pairs({
[s.l.uri] = theme.uri_sbar_fg,
[s.l.hist] = theme.hist_sbar_fg,
[s.l.loaded] = theme.sbar_loaded_fg,
[s.r.buf] = theme.buf_sbar_fg,
[s.r.tabi] = theme.tabi_sbar_fg,
[s.r.scroll] = theme.scroll_sbar_fg,
[i.prompt] = theme.prompt_ibar_fg,
[i.input] = theme.input_ibar_fg,
}) do wi.fg = v end
-- Set backgrounds
for wi, v in pairs({
[s.l.ebox] = theme.sbar_bg,
[s.r.ebox] = theme.sbar_bg,
[s.sep] = theme.sbar_bg,
[s.ebox] = theme.sbar_bg,
[i.ebox] = theme.ibar_bg,
[i.input] = theme.input_ibar_bg,
}) do wi.bg = v end
-- Set fonts
for wi, v in pairs({
[s.l.uri] = theme.uri_sbar_font,
[s.l.hist] = theme.hist_sbar_font,
[s.l.loaded] = theme.sbar_loaded_font,
[s.r.buf] = theme.buf_sbar_font,
[s.r.ssl] = theme.ssl_sbar_font,
[s.r.tabi] = theme.tabi_sbar_font,
[s.r.scroll] = theme.scroll_sbar_font,
[i.prompt] = theme.prompt_ibar_font,
[i.input] = theme.input_ibar_font,
}) do wi.font = v end
end,
set_default_size = function (w)
local size = globals.default_window_size or "800x600"
if string.match(size, "^%d+x%d+$") then
w.win:set_default_size(string.match(size, "^(%d+)x(%d+)$"))
else
warn("E: window.lua: invalid window size: %q", size)
end
end,
set_window_icon = function (w)
local path = (luakit.dev_paths and os.exists("./extras/luakit.png")) or
os.exists("/usr/share/pixmaps/luakit.png")
if path then w.win.icon = path end
end,
clear_urgency_hint = function (w)
w.win:add_signal("focus", function ()
w.win.urgency_hint = false
end)
end,
}
-- Helper functions which operate on the window widgets or structure.
window.methods = {
-- Wrapper around the bind plugin's hit method
hit = function (w, mods, key, opts)
local opts = lousy.util.table.join(opts or {}, {
enable_buffer = w:is_mode("normal"),
buffer = w.buffer,
})
local caught, newbuf = lousy.bind.hit(w, w.binds, mods, key, opts)
if w.win then -- Check binding didn't cause window to exit
w.buffer = newbuf
w:update_buf()
end
return caught
end,
-- Wrapper around the bind plugin's match_cmd method
match_cmd = function (w, buffer)
return lousy.bind.match_cmd(w, get_mode("command").binds, buffer)
end,
-- enter command or characters into command line
enter_cmd = function (w, cmd, opts)
w:set_mode("command")
w:set_input(cmd, opts)
end,
-- run command as if typed into the command line
run_cmd = function (w, cmd, opts)
w:enter_cmd(cmd, opts)
w:activate()
end,
-- insert a string into the command line at the current cursor position
insert_cmd = function (w, str)
if not str then return end
local i = w.ibar.input
local text = i.text
local pos = i.position
local left, right = string.sub(text, 1, pos), string.sub(text, pos+1)
i.text = left .. str .. right
i.position = pos + #str
end,
-- Emulates pressing the Return key in input field
activate = function (w)
w.ibar.input:emit_signal("activate")
end,
del_word = function (w)
local i = w.ibar.input
local text = i.text
local pos = i.position
if text and #text > 1 and pos > 1 then
local left, right = string.sub(text, 2, pos), string.sub(text, pos+1)
if not string.find(left, "%s") then
left = ""
elseif string.find(left, "%w+%s*$") then
left = string.sub(left, 0, string.find(left, "%w+%s*$") - 1)
elseif string.find(left, "%W+%s*$") then
left = string.sub(left, 0, string.find(left, "%W+%s*$") - 1)
end
i.text = string.sub(text, 1, 1) .. left .. right
i.position = #left + 1
end
end,
del_line = function (w)
local i = w.ibar.input
if not string.match(i.text, "^[:/?]$") then
i.text = string.sub(i.text, 1, 1)
i.position = -1
end
end,
del_backward_char = function (w)
local i = w.ibar.input
local text = i.text
local pos = i.position
if pos > 1 then
i.text = string.sub(text, 0, pos - 1) .. string.sub(text, pos + 1)
i.position = pos - 1
end
end,
del_forward_char = function (w)
local i = w.ibar.input
local text = i.text
local pos = i.position
i.text = string.sub(text, 0, pos) .. string.sub(text, pos + 2)
i.position = pos
end,
beg_line = function (w)
local i = w.ibar.input
i.position = 1
end,
end_line = function (w)
local i = w.ibar.input
i.position = -1
end,
forward_char = function (w)
local i = w.ibar.input
i.position = i.position + 1
end,
backward_char = function (w)
local i = w.ibar.input
local pos = i.position
if pos > 1 then
i.position = pos - 1
end
end,
forward_word = function (w)
local i = w.ibar.input
local text = i.text
local pos = i.position
if text and #text > 1 then
local right = string.sub(text, pos+1)
if string.find(right, "%w+") then
local _, move = string.find(right, "%w+")
i.position = pos + move
end
end
end,
backward_word = function (w)
local i = w.ibar.input
local text = i.text
local pos = i.position
if text and #text > 1 and pos > 1 then
local left = string.reverse(string.sub(text, 2, pos))
if string.find(left, "%w+") then
local _, move = string.find(left, "%w+")
i.position = pos - move
end
end
end,
-- Shows a notification until the next keypress of the user.
notify = function (w, msg, set_mode)
if set_mode ~= false then w:set_mode() end
w:set_prompt(msg, { fg = theme.notif_fg, bg = theme.notif_bg })
end,
warning = function (w, msg, set_mode)
if set_mode ~= false then w:set_mode() end
w:set_prompt(msg, { fg = theme.warning_fg, bg = theme.warning_bg })
end,
error = function (w, msg, set_mode)
if set_mode ~= false then w:set_mode() end
w:set_prompt("Error: "..msg, { fg = theme.error_fg, bg = theme.error_bg })
end,
-- Set and display the prompt
set_prompt = function (w, text, opts)
local prompt, ebox, opts = w.ibar.prompt, w.ibar.ebox, opts or {}
prompt:hide()
-- Set theme
fg, bg = opts.fg or theme.ibar_fg, opts.bg or theme.ibar_bg
if prompt.fg ~= fg then prompt.fg = fg end
if ebox.bg ~= bg then ebox.bg = bg end
-- Set text or remain hidden
if text then
prompt.text = lousy.util.escape(text)
prompt:show()
end
end,
-- Set display and focus the input bar
set_input = function (w, text, opts)
local input, opts = w.ibar.input, opts or {}
input:hide()
-- Set theme
fg, bg = opts.fg or theme.ibar_fg, opts.bg or theme.ibar_bg
if input.fg ~= fg then input.fg = fg end
if input.bg ~= bg then input.bg = bg end
-- Set text or remain hidden
if text then
input.text = ""
input:show()
input:focus()
input.text = text
input.position = opts.pos or -1
end
end,
-- GUI content update functions
update_tab_count = function (w)
w.sbar.r.tabi.text = string.format("[%d/%d]", w.tabs:current(), w.tabs:count())
end,
update_win_title = function (w)
local uri, title = w.view.uri, w.view.title
title = (title or "luakit") .. ((uri and " - " .. uri) or "")
local max = globals.max_title_len or 80
if #title > max then title = string.sub(title, 1, max) .. "..." end
w.win.title = title
end,
update_uri = function (w, link)
w.sbar.l.uri.text = lousy.util.escape((link and "Link: " .. link)
or (w.view and w.view.uri) or "about:blank")
end,
update_progress = function (w)
local p = w.view.progress
local loaded = w.sbar.l.loaded
if not w.view:loading() or p == 1 then
loaded:hide()
else
loaded:show()
loaded.text = string.format("(%d%%)", p * 100)
end
end,
update_scroll = function (w)
local scroll, label = w.view.scroll, w.sbar.r.scroll
local y, max, text = scroll.y, scroll.ymax
if max == 0 then text = "All"
elseif y == 0 then text = "Top"
elseif y == max then text = "Bot"
else text = string.format("%2d%%", (y / max) * 100)
end
if label.text ~= text then label.text = text end
end,
update_ssl = function (w)
local trusted = w.view:ssl_trusted()
local ssl = w.sbar.r.ssl
if trusted ~= nil and not w.checking_ssl then
ssl.fg = theme.notrust_fg
ssl.text = "(nocheck)"
ssl:show()
elseif trusted == true then
ssl.fg = theme.trust_fg
ssl.text = "(trust)"
ssl:show()
elseif trusted == false then
ssl.fg = theme.notrust_fg
ssl.text = "(notrust)"
ssl:show()
else
ssl:hide()
end
end,
update_hist = function (w)
local hist = w.sbar.l.hist
local back, forward = w.view:can_go_back(), w.view:can_go_forward()
local s = (back and "+" or "") .. (forward and "-" or "")
if s ~= "" then
hist.text = '['..s..']'
hist:show()
else
hist:hide()
end
end,
update_buf = function (w)
local buf = w.sbar.r.buf
if w.buffer then
buf.text = lousy.util.escape(string.format(" %-3s", w.buffer))
buf:show()
else
buf:hide()
end
end,
update_binds = function (w, mode)
-- Generate the list of active key & buffer binds for this mode
w.binds = lousy.util.table.join((get_mode(mode) or {}).binds or {}, get_mode('all').binds or {})
-- Clear & hide buffer
w.buffer = nil
w:update_buf()
end,
update_tablist = function (w)
local current = w.tabs:current()
local fg, bg, nfg, snfg = theme.tab_fg, theme.tab_bg, theme.tab_ntheme, theme.selected_ntheme
local lfg, bfg, gfg = theme.tab_loading_fg, theme.tab_notrust_fg, theme.tab_trust_fg
local escape = lousy.util.escape
local tabs, tfmt = {}, ' <span foreground="%s">%s</span> %s'
for i, view in ipairs(w.tabs.children) do
-- Get tab number theme
local ntheme = nfg
if view:loading() then -- Show loading on all tabs
ntheme = lfg
elseif current == i then -- Show ssl trusted/untrusted on current tab
local trusted = view:ssl_trusted()
ntheme = snfg
if trusted == false or (trusted ~= nil and not w.checking_ssl) then
ntheme = bfg
elseif trusted then
ntheme = gfg
end
end
local title = view.title or view.uri or "(Untitled)"
tabs[i] = {
title = string.format(tfmt, ntheme or fg, i, escape(title)),
fg = (current == i and theme.tab_selected_fg) or fg,
bg = (current == i and theme.tab_selected_bg) or bg,
}
end
if #tabs < 2 then tabs, current = {}, 0 end
w.tablist:update(tabs, current)
end,
new_tab = function (w, arg, switch, order)
local view
-- Use blank tab first
if w.has_blank and w.tabs:count() == 1 and w.tabs[1].uri == "about:blank" then
view = w.tabs[1]
end
w.has_blank = nil
-- Make new webview widget
if not view then
view = webview.new(w)
-- Get tab order function
if not order and taborder then
order = (switch == false and taborder.default_bg)
or taborder.default
end
pos = w.tabs:insert((order and order(w, view)) or -1, view)
if switch ~= false then w.tabs:switch(pos) end
end
-- Load uri or webview history table
if type(arg) == "string" then view.uri = arg
elseif type(arg) == "table" then view.history = arg end
-- Update statusbar widgets
w:update_tab_count()
w:update_tablist()
return view
end,
-- close the current tab
close_tab = function (w, view, blank_last)
view = view or w.view
-- Treat a blank last tab as an empty notebook (if blank_last=true)
if blank_last ~= false and w.tabs:count() == 1 then
if not view:loading() and view.uri == "about:blank" then return end
w:new_tab("about:blank", false)
w.has_blank = true
end
-- Save tab history
local tab = {hist = view.history,}
-- And relative location
local index = w.tabs:indexof(view)
if index ~= 1 then tab.after = w.tabs[index-1] end
table.insert(w.closed_tabs, tab)
view:destroy()
w:update_tab_count()
w:update_tablist()
end,
close_win = function (w, force)
-- Ask plugins if it's OK to close last window
if not force and (#luakit.windows == 1) then
local emsg = luakit.emit_signal("can-close", w)
if emsg then
assert(type(emsg) == "string", "invalid exit error message")
w:error(string.format("Can't close luakit: %s (force close "
.. "with :q! or :wq!)", emsg))
return false
end
end
w:emit_signal("close")
-- Close all tabs
while w.tabs:count() ~= 0 do
w:close_tab(nil, false)
end
-- Destroy tablist
w.tablist:destroy()
-- Remove from window index
window.bywidget[w.win] = nil
-- Clear window struct
w = setmetatable(w, {})
-- Recursively remove widgets from window
local children = lousy.util.recursive_remove(w.win)
-- Destroy all widgets
for i, c in ipairs(lousy.util.table.join(children, {w.win})) do
if c.hide then c:hide() end
c:destroy()
end
-- Remove all window table vars
for k, _ in pairs(w) do w[k] = nil end
-- Quit if closed last window
if #luakit.windows == 0 then luakit.quit() end
end,
-- Navigate current view or open new tab
navigate = function (w, uri, view)
view = view or w.view
if view then
local js = string.match(uri, "^javascript:(.+)$")
if js then
return view:eval_js(luakit.uri_decode(js))
end
view.uri = uri
else
return w:new_tab(uri)
end
end,
-- Save, restart luakit and reload session.
restart = function (w)
-- Generate luakit launch command.
local args = {({string.gsub(luakit.execpath, " ", "\\ ")})[1]}
if luakit.verbose then table.insert(args, "-v") end
-- Relaunch without libunique bindings?
if luakit.nounique then table.insert(args, "-U") end
-- Get new config path
local conf
if luakit.confpath ~= "/etc/xdg/luakit/rc.lua" and os.exists(luakit.confpath) then
conf = luakit.confpath
table.insert(args, string.format("-c %q", conf))
end
-- Check config has valid syntax
local cmd = table.concat(args, " ")
if luakit.spawn_sync(cmd .. " -k") ~= 0 then
return w:error("Cannot restart, syntax error in configuration file"..((conf and ": "..conf) or "."))
end
-- Save session.
local wins = {}
for _, w in pairs(window.bywidget) do table.insert(wins, w) end
session.save(wins)
-- Replace current process with new luakit instance.
luakit.exec(cmd)
end,
-- Intelligent open command which can detect a uri or search argument.
search_open = function (w, arg)
local lstring = lousy.util.string
local match, find = string.match, string.find
-- Detect blank uris
if not arg or match(arg, "^%s*$") then return "about:blank" end
-- Strip whitespace and split by whitespace into args table
local args = lstring.split(lstring.strip(arg))
-- Guess if first argument is an address, search engine, file
if #args == 1 then
local uri = args[1]
if uri == "about:blank" then return uri end
-- Check if search engine name
if search_engines[uri] then
return string.format(search_engines[uri], "")
end
-- Navigate if . or / in uri (I.e. domains, IP's, scheme://)
if find(uri, "%.") or find(uri, "/") then return uri end
-- Navigate if this is a javascript-uri
if find(uri, "^javascript:") then return uri end
-- Valid hostnames to check
local hosts = { "localhost" }
if globals.load_etc_hosts ~= false then
hosts = lousy.util.get_etc_hosts()
end
-- Check hostnames
for _, h in pairs(hosts) do
if h == uri or match(uri, "^"..h..":%d+$") then return uri end
end
-- Check for file in filesystem
if globals.check_filepath ~= false then
if lfs.attributes(uri) then return "file://" .. uri end
end
end
-- Find search engine (or use search_engines.default)
local engine = "default"
if args[1] and search_engines[args[1]] then
engine = args[1]
table.remove(args, 1)
end
-- URI encode search terms
local terms = luakit.uri_encode(table.concat(args, " "))
return string.format(search_engines[engine], terms)
end,
-- Increase (or decrease) the last found number in the current uri
inc_uri = function (w, arg)
local uri = string.gsub(w.view.uri, "(%d+)([^0-9]*)$", function (num, rest)
return string.format("%0"..#num.."d", tonumber(num) + (arg or 1)) .. rest
end)
return uri
end,
-- Tab traversing functions
next_tab = function (w, n)
w.tabs:switch((((n or 1) + w.tabs:current() -1) % w.tabs:count()) + 1)
end,
prev_tab = function (w, n)
w.tabs:switch(((w.tabs:current() - (n or 1) -1) % w.tabs:count()) + 1)
end,
goto_tab = function (w, n)
if n and (n == -1 or n > 0) then
return w.tabs:switch((n <= w.tabs:count() and n) or -1)
end
end,
-- For each tab, switches to that tab and calls the given function passing
-- it the view contained in the tab.
each_tab = function (w, fn)
for index = 1, w.tabs:count() do
w:goto_tab(index)
fn(w.tabs[index])
end
end,
-- If argument is form-active or root-active, emits signal. Ignores all
-- other signals.
emit_form_root_active_signal = function (w, s)
if s == "form-active" then
w.view:emit_signal("form-active")
elseif s == "root-active" then
w.view:emit_signal("root-active")
end
end,
}
-- Ordered list of class index functions. Other classes (E.g. webview) are able
-- to add their own index functions to this list.
window.indexes = {
-- Find function in window.methods first
function (w, k) return window.methods[k] end
}
-- Create new window
function window.new(uris)
local w = window.build()
-- Set window metatable
setmetatable(w, {
__index = function (_, k)
-- Check widget structure first
local v = rawget(w, k)
if v then return v end
-- Call each window index function
for _, index in ipairs(window.indexes) do
v = index(w, k)
if v then return v end
end
end,
})
-- Setup window widget for signals
lousy.signal.setup(w)
-- Call window init functions
for _, func in pairs(window.init_funcs) do
func(w)
end
-- Populate notebook with tabs
for _, uri in ipairs(uris or {}) do
w:new_tab(w:search_open(uri), false)
end
-- Make sure something is loaded
if w.tabs:count() == 0 then
w:new_tab(w:search_open(globals.homepage), false)
end
-- Set initial mode
w:set_mode()
-- Show window
w.win:show()
return w
end
-- vim: et:sw=4:ts=8:sts=4:tw=80

Binary file not shown.

@ -0,0 +1,2 @@
macro index,pager \cb <pipe-entry>'urlscan'<enter> 'Follow links with urlview'
macro attach,compose \cb <pipe-entry>'urlscan'<enter> 'Follow links with urlview'

@ -0,0 +1,2 @@
text/html; luakit %s &; test=test -n "%DISPLAY"; needsterminal;
text/html; w3m -I %{charset} -T text/html; copiousoutput;

@ -0,0 +1,151 @@
# vim: filetype=muttrc
#
#
# make sure that you are using mutt linked against slang, not ncurses, or
# suffer the consequences of weird color issues. use "mutt -v" to check this.
# custom body highlights -----------------------------------------------
# highlight my name and other personally relevant strings
#color body yellow default "(ethan|schoonover)"
# custom index highlights ----------------------------------------------
# messages which mention my name in the body
#color index yellow default "~b \"phil(_g|\!| gregory| gold)|pgregory\" !~N !~T !~F !~p !~P"
#color index J_cream brightwhite "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~N !~T !~F !~p !~P"
#color index yellow cyan "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~T !~F !~p !~P"
#color index yellow J_magent "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~F !~p !~P"
## messages which are in reference to my mails
#color index J_magent default "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" !~N !~T !~F !~p !~P"
#color index J_magent brightwhite "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~N !~T !~F !~p !~P"
#color index J_magent cyan "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~T !~F !~p !~P"
#color index J_magent red "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~F !~p !~P"
# for background in 16 color terminal, valid background colors include:
# base03, bg, black, any of the non brights
# basic colors ---------------------------------------------------------
color normal brightyellow default
color error red default
color tilde black default
color message cyan default
color markers red white
color attachment white default
color search brightmagenta default
#color status J_black J_status
color status brightyellow black
color indicator brightblack yellow
color tree yellow default # arrow in threads
# basic monocolor screen
mono bold bold
mono underline underline
mono indicator reverse
mono error bold
# index ----------------------------------------------------------------
#color index red default "~D(!~p|~p)" # deleted
#color index black default ~F # flagged
#color index brightred default ~= # duplicate messages
#color index brightgreen default "~A!~N!~T!~p!~Q!~F!~D!~P" # the rest
#color index J_base default "~A~N!~T!~p!~Q!~F!~D" # the rest, new
color index red default "~A" # all messages
color index brightred default "~E" # expired messages
color index blue default "~N" # new messages
color index blue default "~O" # old messages
color index brightmagenta default "~Q" # messages that have been replied to
color index brightgreen default "~R" # read messages
color index blue default "~U" # unread messages
color index blue default "~U~$" # unread, unreferenced messages
color index brightyellow default "~v" # messages part of a collapsed thread
color index brightyellow default "~P" # messages from me
color index cyan default "~p!~F" # messages to me
color index cyan default "~N~p!~F" # new messages to me
color index cyan default "~U~p!~F" # unread messages to me
color index brightgreen default "~R~p!~F" # messages to me
color index red default "~F" # flagged messages
color index red default "~F~p" # flagged messages to me
color index red default "~N~F" # new flagged messages
color index red default "~N~F~p" # new flagged messages to me
color index red default "~U~F~p" # new flagged messages to me
color index black red "~D" # deleted messages
color index brightcyan default "~v~(!~N)" # collapsed thread with no unread
color index yellow default "~v~(~N)" # collapsed thread with some unread
color index green default "~N~v~(~N)" # collapsed thread with unread parent
# statusbg used to indicated flagged when foreground color shows other status
# for collapsed thread
color index red black "~v~(~F)!~N" # collapsed thread with flagged, no unread
color index yellow black "~v~(~F~N)" # collapsed thread with some unread & flagged
color index green black "~N~v~(~F~N)" # collapsed thread with unread parent & flagged
color index green black "~N~v~(~F)" # collapsed thread with unread parent, no unread inside, but some flagged
color index cyan black "~v~(~p)" # collapsed thread with unread parent, no unread inside, some to me directly
color index yellow red "~v~(~D)" # thread with deleted (doesn't differentiate between all or partial)
#color index yellow default "~(~N)" # messages in threads with some unread
#color index green default "~S" # superseded messages
#color index red default "~T" # tagged messages
#color index brightred red "~=" # duplicated messages
# message headers ------------------------------------------------------
#color header brightgreen default "^"
color hdrdefault brightgreen default
color header brightyellow default "^(From)"
color header blue default "^(Subject)"
# body -----------------------------------------------------------------
color quoted blue default
color quoted1 cyan default
color quoted2 yellow default
color quoted3 red default
color quoted4 brightred default
color signature brightgreen default
color bold black default
color underline black default
color normal default default
#
color body brightcyan default "[;:][-o][)/(|]" # emoticons
color body brightcyan default "[;:][)(|]" # emoticons
color body brightcyan default "[*]?((N)?ACK|CU|LOL|SCNR|BRB|BTW|CWYL|\
|FWIW|vbg|GD&R|HTH|HTHBE|IMHO|IMNSHO|\
|IRL|RTFM|ROTFL|ROFL|YMMV)[*]?"
color body brightcyan default "[ ][*][^*]*[*][ ]?" # more emoticon?
color body brightcyan default "[ ]?[*][^*]*[*][ ]" # more emoticon?
## pgp
color body red default "(BAD signature)"
color body cyan default "(Good signature)"
color body brightblack default "^gpg: Good signature .*"
color body brightyellow default "^gpg: "
color body brightyellow red "^gpg: BAD signature from.*"
mono body bold "^gpg: Good signature"
mono body bold "^gpg: BAD signature from.*"
# yes, an insance URL regex
color body red default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"
# and a heavy handed email regex
#color body J_magent default "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])"
# Various smilies and the like
#color body brightwhite default "<[Gg]>" # <g>
#color body brightwhite default "<[Bb][Gg]>" # <bg>
#color body yellow default " [;:]-*[})>{(<|]" # :-) etc...
# *bold*
#color body blue default "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
#mono body bold "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
# _underline_
#color body blue default "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
#mono body underline "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
# /italic/ (Sometimes gets directory names)
#color body blue default "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
#mono body underline "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
# Border lines.
#color body blue default "( *[-+=#*~_]){6,}"
#folder-hook . "color status J_black J_status "
#folder-hook gmail/inbox "color status J_black yellow "
#folder-hook gmail/important "color status J_black yellow "

@ -0,0 +1,151 @@
# vim: filetype=muttrc
#
#
# make sure that you are using mutt linked against slang, not ncurses, or
# suffer the consequences of weird color issues. use "mutt -v" to check this.
# custom body highlights -----------------------------------------------
# highlight my name and other personally relevant strings
#color body color136 color234 "(ethan|schoonover)"
# custom index highlights ----------------------------------------------
# messages which mention my name in the body
#color index color136 color234 "~b \"phil(_g|\!| gregory| gold)|pgregory\" !~N !~T !~F !~p !~P"
#color index J_cream color230 "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~N !~T !~F !~p !~P"
#color index color136 color37 "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~T !~F !~p !~P"
#color index color136 J_magent "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~F !~p !~P"
## messages which are in reference to my mails
#color index J_magent color234 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" !~N !~T !~F !~p !~P"
#color index J_magent color230 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~N !~T !~F !~p !~P"
#color index J_magent color37 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~T !~F !~p !~P"
#color index J_magent color160 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~F !~p !~P"
# for background in 16 color terminal, valid background colors include:
# base03, bg, black, any of the non brights
# basic colors ---------------------------------------------------------
color normal color241 color234
color error color160 color234
color tilde color235 color234
color message color37 color234
color markers color160 color254
color attachment color254 color234
color search color61 color234
#color status J_black J_status
color status color241 color235
color indicator color234 color136
color tree color136 color234 # arrow in threads
# basic monocolor screen
mono bold bold
mono underline underline
mono indicator reverse
mono error bold
# index ----------------------------------------------------------------
#color index color160 color234 "~D(!~p|~p)" # deleted
#color index color235 color234 ~F # flagged
#color index color166 color234 ~= # duplicate messages
#color index color240 color234 "~A!~N!~T!~p!~Q!~F!~D!~P" # the rest
#color index J_base color234 "~A~N!~T!~p!~Q!~F!~D" # the rest, new
color index color160 color234 "~A" # all messages
color index color166 color234 "~E" # expired messages
color index color33 color234 "~N" # new messages
color index color33 color234 "~O" # old messages
color index color61 color234 "~Q" # messages that have been replied to
color index color240 color234 "~R" # read messages
color index color33 color234 "~U" # unread messages
color index color33 color234 "~U~$" # unread, unreferenced messages
color index color241 color234 "~v" # messages part of a collapsed thread
color index color241 color234 "~P" # messages from me
color index color37 color234 "~p!~F" # messages to me
color index color37 color234 "~N~p!~F" # new messages to me
color index color37 color234 "~U~p!~F" # unread messages to me
color index color240 color234 "~R~p!~F" # messages to me
color index color160 color234 "~F" # flagged messages
color index color160 color234 "~F~p" # flagged messages to me
color index color160 color234 "~N~F" # new flagged messages
color index color160 color234 "~N~F~p" # new flagged messages to me
color index color160 color234 "~U~F~p" # new flagged messages to me
color index color235 color160 "~D" # deleted messages
color index color245 color234 "~v~(!~N)" # collapsed thread with no unread
color index color136 color234 "~v~(~N)" # collapsed thread with some unread
color index color64 color234 "~N~v~(~N)" # collapsed thread with unread parent
# statusbg used to indicated flagged when foreground color shows other status
# for collapsed thread
color index color160 color235 "~v~(~F)!~N" # collapsed thread with flagged, no unread
color index color136 color235 "~v~(~F~N)" # collapsed thread with some unread & flagged
color index color64 color235 "~N~v~(~F~N)" # collapsed thread with unread parent & flagged
color index color64 color235 "~N~v~(~F)" # collapsed thread with unread parent, no unread inside, but some flagged
color index color37 color235 "~v~(~p)" # collapsed thread with unread parent, no unread inside, some to me directly
color index color136 color160 "~v~(~D)" # thread with deleted (doesn't differentiate between all or partial)
#color index color136 color234 "~(~N)" # messages in threads with some unread
#color index color64 color234 "~S" # superseded messages
#color index color160 color234 "~T" # tagged messages
#color index color166 color160 "~=" # duplicated messages
# message headers ------------------------------------------------------
#color header color240 color234 "^"
color hdrdefault color240 color234
color header color241 color234 "^(From)"
color header color33 color234 "^(Subject)"
# body -----------------------------------------------------------------
color quoted color33 color234
color quoted1 color37 color234
color quoted2 color136 color234
color quoted3 color160 color234
color quoted4 color166 color234
color signature color240 color234
color bold color235 color234
color underline color235 color234
color normal color244 color234
#
color body color245 color234 "[;:][-o][)/(|]" # emoticons
color body color245 color234 "[;:][)(|]" # emoticons
color body color245 color234 "[*]?((N)?ACK|CU|LOL|SCNR|BRB|BTW|CWYL|\
|FWIW|vbg|GD&R|HTH|HTHBE|IMHO|IMNSHO|\
|IRL|RTFM|ROTFL|ROFL|YMMV)[*]?"
color body color245 color234 "[ ][*][^*]*[*][ ]?" # more emoticon?
color body color245 color234 "[ ]?[*][^*]*[*][ ]" # more emoticon?
## pgp
color body color160 color234 "(BAD signature)"
color body color37 color234 "(Good signature)"
color body color234 color234 "^gpg: Good signature .*"
color body color241 color234 "^gpg: "
color body color241 color160 "^gpg: BAD signature from.*"
mono body bold "^gpg: Good signature"
mono body bold "^gpg: BAD signature from.*"
# yes, an insance URL regex
color body color160 color234 "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"
# and a heavy handed email regex
#color body J_magent color234 "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])"
# Various smilies and the like
#color body color230 color234 "<[Gg]>" # <g>
#color body color230 color234 "<[Bb][Gg]>" # <bg>
#color body color136 color234 " [;:]-*[})>{(<|]" # :-) etc...
# *bold*
#color body color33 color234 "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
#mono body bold "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
# _underline_
#color body color33 color234 "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
#mono body underline "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
# /italic/ (Sometimes gets directory names)
#color body color33 color234 "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
#mono body underline "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
# Border lines.
#color body color33 color234 "( *[-+=#*~_]){6,}"
#folder-hook . "color status J_black J_status "
#folder-hook gmail/inbox "color status J_black color136 "
#folder-hook gmail/important "color status J_black color136 "

@ -0,0 +1,57 @@
# Get passwords from gpg'd file
source "gpg -dq ~/.my-pwds.gpg |"
# General
set realname = "Dustin Swan"
# Gmail IMAP
set imap_user = "dustinswan@gmail.com"
set imap_pass = $my_pw_personal
set folder = "imaps://imap.gmail.com/"
set spoolfile = +INBOX
set imap_check_subscribed
set header_cache = ~/.mutt/hcache
set record = "+[Gmail]/Sent Mail"
set postponed = "+[Gmail]/Drafts"
unset imap_passive
set imap_keepalive = 300
set mail_check = 60
# SMTP
set smtp_url = "smtp://dustinswan@smtp.gmail.com:587/"
set smtp_pass = $my_pw_personal
set send_charset = "utf-8"
set mailcap_path = ~/.mutt/mailcap
# Edit headers
#set edit_headers = yes
#unset use_from
#unset use_domain
#unset user_agent
#unmy_hdr *
# Sorting
set sort = threads
set sort_aux = reverse-last-date-received
# Sidebar
set sidebar_delim = ' │'
set sidebar_visible = yes
set sidebar_width = 24
#color sidebar_new color221 color233
bind index <down> sidebar-next
bind index <up> sidebar-prev
bind index <right> sidebar-open
# Status Bar
#set status_chars = " *&A"
#set status_format = "---[ Folder: %f ]---[%r%n messages%?n? (%n new)?%?d? (%d to delete)?%?t? (%t tagged)? ]---%>-%?p?( %p postponed )?---""
# Fucking html mail
auto_view text/html
alternative_order text/plain text/enriched text/html
# Colors
source ~/.mutt/mutt-colors-solarized-dark-256.muttrc

@ -1,21 +0,0 @@
source "gpg -dq ~/.my-pwds.gpg |"
set imap_user = dustinswan@gmail.com
set imap_pass = $my_pw_personal
set folder = imaps://imap.gmail.com/
set spoolfile = +INBOX
set imap_check_subscribed
set header_cache = ~/.mutt/hcache
set postponed = +[Gmail]/Drafts
unset imap_passive
set imap_keepalive = 300
set mail_check = 120

@ -36,8 +36,13 @@ set -g status-left-length 32
set -g status-right-length 150
set -g status-interval 5
set -g status-left '#[fg=colour238,bg=colour234,nobold]⮀'
set -g status-right '#[fg=colour245]⮃ %R ⮃ %d %b #[fg=colour254,bg=colour234,nobold]⮂#[fg=colour16,bg=colour254,bold] #h '
#set -g status-left '#[fg=colour238,bg=colour234,nobold]⮀'
#set -g status-right '#[fg=colour245]⮃ %R ⮃ %d %b #[fg=colour254,bg=colour234,nobold]⮂#[fg=colour16,bg=colour254,bold] #h '
#set -g window-status-format "#[fg=white,bg=colour234] #I #W "
#set -g window-status-current-format "#[fg=colour234,bg=colour39]⮀#[fg=colour16,bg=colour39,noreverse,bold] #I ⮁ #W #[fg=colour39,bg=colour234,nobold]⮀"
# No fancy chars
set -g status-left '#[fg=colour238,bg=colour234,nobold]'
set -g status-right '#[fg=colour245] %R %d %b #[fg=colour254,bg=colour234,nobold]#[fg=colour16,bg=colour254,bold] #h '
set -g window-status-format "#[fg=white,bg=colour234] #I #W "
set -g window-status-current-format "#[fg=colour234,bg=colour39]⮀#[fg=colour16,bg=colour39,noreverse,bold] #I ⮁ #W #[fg=colour39,bg=colour234,nobold]⮀"
set -g window-status-current-format "#[fg=colour234,bg=colour39]#[fg=colour16,bg=colour39,noreverse,bold] #I #W #[fg=colour39,bg=colour234,nobold]"

49
vimrc

@ -11,25 +11,27 @@ Bundle 'digitaltoad/vim-jade'
Bundle 'pangloss/vim-javascript'
Bundle 'kchmck/vim-coffee-script'
Bundle 'jQuery'
Bundle 'vim-ruby/vim-ruby'
Bundle 'tpope/vim-rails'
Bundle 'tpope/vim-repeat'
Bundle 'tpope/vim-surround'
Bundle 'tpope/vim-fugitive'
Bundle 'tpope/vim-endwise'
Bundle 'mileszs/ack.vim'
Bundle 'Lokaltog/vim-powerline'
" Bundle 'mileszs/ack'
Bundle 'Lokaltog/vim-powerline.git'
Bundle 'Lokaltog/vim-easymotion'
Bundle 'bkad/CamelCaseMotion'
Bundle 'majutsushi/tagbar'
Bundle 'scrooloose/syntastic'
Bundle 'scrooloose/nerdcommenter'
" Bundle 'scrooloose/nerdtree'
" Bundle 'altercation/vim-colors-solarized'
Bundle 'altercation/vim-colors-solarized'
" Bundle 'ervandew/supertab'
" Bundle 'sjl/clam.vim'
" Bundle 'sjl/gundo'
" Bundle 'sjl/clam'
Bundle 'kien/ctrlp.vim'
Bundle 'gregsexton/MatchTag'
" Bundle 'closetag.vim'
" Bundle 'closetag'
Bundle 'kana/vim-smartinput'
Bundle 'rstacruz/sparkup', {'rtp': 'vim/'}
Bundle 'mbbill/undotree'
@ -40,12 +42,8 @@ Bundle 'benmills/vimux'
Bundle 'lukaszkorecki/workflowish'
Bundle 'searchfold.vim'
Bundle 'godlygeek/tabular'
" Snipmate
" Bundle 'MarcWeber/vim-addon-mw-utils'
" Bundle 'tomtom/tlib_vim'
" Bundle 'snipmate-snippets'
" Bundle 'garbas/vim-snipmate'
Bundle 'kshenoy/vim-signature'
Bundle 'SirVer/ultisnips'
filetype plugin indent on " last Vundle requirement
@ -131,25 +129,26 @@ set dictionary+=/usr/share/dict/words
" hide toolbar in macvim, etc
if has("gui_running")
set gfn=Terminus\ 8
set go=-t
endif
" Powerline
let g:Powerline_symbols='fancy'
" let g:Powerline_symbols='fancy'
" Colors
set background=dark
colorscheme default
"set background=dark
" colorscheme default
" Solarized
"set background=dark
"let g:solarized_termtrans=1
"let g:solarized_termcolors=256 "default value is 16
"let g:solarized_contrast="high" "default value is normal
"let g:solarized_visibility="high" "default value is normal
"let g:solarized_diffmode="high" "default value is normal
"let g:solarized_hitrail=1 "default value is 0
"colorscheme solarized
set background=dark
let g:solarized_termtrans=1
let g:solarized_termcolors=256 "default value is 16
let g:solarized_contrast="high" "default value is normal
let g:solarized_visibility="high" "default value is normal
let g:solarized_diffmode="high" "default value is normal
let g:solarized_hitrail=1 "default value is 0
colorscheme solarized
" NERDTree
"nnoremap <silent> <leader>n :NERDTreeToggle <cr>
@ -176,6 +175,10 @@ nnoremap <leader>s :SyntasticToggleMode<cr>
" Supertab
" let g:SuperTabDefaultCompletionType="context"
" UltiSnpis
let g:UltiSnipsJumpForwardTrigger="<tab>"
let g:UltiSnipsJumpBackwardTrigger="<s-tab>"
" open the current file for edit in Perforce
nnoremap <silent><leader>4 :! p4 edit %<cr>
@ -186,7 +189,7 @@ nnoremap <leader>v <c-w>v<c-w>l
nnoremap <leader>W :%s/\s\+$//e<cr>
" open Ack
nnoremap <leader>a :Ack<space>
" nnoremap <leader>a :Ack<space>
" Marked
nnoremap <leader>m :silent !open -a Marked.app '%:p'<cr>

@ -1,7 +1,9 @@
[[ -f ~/.Xresources ]] && xrdb -merge ~/.Xresources
#transparency and shadows
xcompmgr -c -C -t-5 -l-5 -r4.2 -o.55 &
setxkbmap dvorak
setxkbmap -option ctrl:nocaps
compton -cGb
dropboxd &
@ -12,6 +14,4 @@ do
sleep 1m
done &
urxvt &
exec awesome

@ -0,0 +1,3 @@
xrandr --newmode "2560x1440_60.00" 312.25 2560 2752 3024 3488 1440 1443 1448 1493 -hsync +vsync
xrandr --addmode Virtual1 2560x1440_60.00
xrandr --output Virtual1 --mode 2560x1440_60.00

@ -25,13 +25,15 @@ COMPLETION_WAITING_DOTS="true"
# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
# Example format: plugins=(rails git textmate ruby lighthouse)
plugins=(git archlinux npm node osx ruby rails3 gem)
plugins=(git archlinux heroku npm node osx brew ruby rbenv gem bundler rake rails3 gem lein vundle)
source $ZSH/oh-my-zsh.sh
# Customize to your needs...
alias vi=vim
alias tmux="tmux -2"
export EDITOR=vim
export BROWSER=luakit
# export TERM=xterm-256color
# VCS stuff
export P4USER=dswan
@ -44,6 +46,7 @@ export SVN_EDITOR=vim
alias visidev="ssh root@visidev.iocom.com 'cd /; p4 sync'"
export PATH=/usr/local/bin:/usr/local/sbin:$PATH # Homebrew
export PATH=$HOME/.rvm/bin:$PATH # RVM
export PATH=$HOME/.rbenv/bin:$PATH # rbenv
export PATH=$HOME/.gem/ruby/1.9.1/bin:$PATH # Ruby
export PATH=/Applications/Postgres.app/Contents/MacOS/bin:$PATH # Postgres
export PATH=$HOME/Library/Haskell/bin:$PATH # Haskell

Loading…
Cancel
Save