From 687bc3b60836ce529dddc0c5112453825d378c6b Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Fri, 12 Oct 2012 13:22:57 -0500 Subject: [PATCH 01/22] Ignoring log files with gitignore now --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 232a316..32d451c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.log vim/.netrwhist vim/bundle/* !vim/bundle/vundle/* From d8595932d6d1dc83f2ea224f1819ff256c7f0eee Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Fri, 12 Oct 2012 13:26:47 -0500 Subject: [PATCH 02/22] Putting solarized back in --- vimrc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/vimrc b/vimrc index a883e09..b2c216b 100644 --- a/vimrc +++ b/vimrc @@ -25,7 +25,7 @@ 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/gundo.vim' " Bundle 'sjl/clam.vim' @@ -141,18 +141,18 @@ endif 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 n :NERDTreeToggle From 82be3685e7f57a765b790b8db7a75892a24e8681 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Fri, 12 Oct 2012 17:28:16 -0500 Subject: [PATCH 03/22] Adding more muttrc stuff from The Homely Mutt.. Thanks slosh --- muttrc | 35 +++++++++++++++++++++++------------ oh-my-zsh | 2 +- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/muttrc b/muttrc index fc9d4de..d13617b 100644 --- a/muttrc +++ b/muttrc @@ -1,21 +1,32 @@ source "gpg -dq ~/.my-pwds.gpg |" -set imap_user = dustinswan@gmail.com - +set realname = "Dustin Swan" +set imap_user = "dustinswan@gmail.com" set imap_pass = $my_pw_personal - -set folder = imaps://imap.gmail.com/ - +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 = 120 -set header_cache = ~/.mutt/hcache - -set postponed = +[Gmail]/Drafts +# Sorting +set sort = threads +set sort_aux = reverse-last-date-received -unset imap_passive +# Sidebar +set sidebar_delim = ' │' +set sidebar_visible = yes +set sidebar_width = 24 +#color sidebar_new color221 color233 -set imap_keepalive = 300 +bind index sidebar-next +bind index sidebar-prev +bind index sidebar-open -set mail_check = 120 +# 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 )?---"" diff --git a/oh-my-zsh b/oh-my-zsh index 73f7770..c2ae9e0 160000 --- a/oh-my-zsh +++ b/oh-my-zsh @@ -1 +1 @@ -Subproject commit 73f777053725ce61d6fada67ff3f174130dd8c94 +Subproject commit c2ae9e09ca1f33ff1e13e629a0b2e6bdd19f83a9 From a04dbbd34738f193fbb1e93bf0da04f03e0a99ce Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Tue, 16 Oct 2012 10:30:50 -0500 Subject: [PATCH 04/22] Updating browser to luakit and increasing opacity in urxvt --- Xresources | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Xresources b/Xresources index 9f6e32c..0b93725 100644 --- a/Xresources +++ b/Xresources @@ -5,7 +5,7 @@ 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 @@ -25,7 +25,7 @@ urxvt*depth: 32 !urxvt*cursorColor: #DCDCCC !urxvt*background: #000000 urxvt*foreground: #FFFFFF -urxvt*background: rgba:0000/0000/0000/dddd +urxvt*background: rgba:0000/0000/0000/ee00 *color0: #1c1c1c *color8: #3d3a3a From 861bdfea3481f03424099b0a9f77c6779f891bb9 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Tue, 16 Oct 2012 10:31:24 -0500 Subject: [PATCH 05/22] Adding battery widget to Awesome --- awesome/rc.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/awesome/rc.lua b/awesome/rc.lua index 67adf72..673478d 100644 --- a/awesome/rc.lua +++ b/awesome/rc.lua @@ -118,6 +118,10 @@ vicious.register(datewidget, vicious.widgets.date, '$1% [$2/$3]', 13) +-- Battery +batwidget = widget({ type = "textbox" }) +vicious.register(batwidget, vicious.widgets.bat, 'bat $2%', 60, 'BAT0') + -- Memory Graph --memgraphwidget = awful.widget.progressbar() --memgraphwidget:set_width(8) @@ -227,6 +231,8 @@ for s = 1, screen.count() do --separator, datewidget, separator, + batwidget, + separator, netwidget, separator, --memgraphwidget.widget, From 2fb0e113ac7b12c018afc14c621bad6ea607f965 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Tue, 16 Oct 2012 10:34:35 -0500 Subject: [PATCH 06/22] Mapping caps to control in X. Removing auto launch of urxvt from xinitrc --- xinitrc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xinitrc b/xinitrc index 0a341e2..96f797f 100644 --- a/xinitrc +++ b/xinitrc @@ -1,5 +1,7 @@ [[ -f ~/.Xresources ]] && xrdb -merge ~/.Xresources +setxkbmap -option ctrl:nocaps + #transparency and shadows xcompmgr -c -C -t-5 -l-5 -r4.2 -o.55 & @@ -12,6 +14,6 @@ do sleep 1m done & -urxvt & +# urxvt & exec awesome From b824669f1c8a4c78e4f3931a7d798753de79f1ab Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Tue, 16 Oct 2012 10:52:19 -0500 Subject: [PATCH 07/22] Adding weechat logs to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 32d451c..a22be3e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.log +weechat/logs/* vim/.netrwhist vim/bundle/* !vim/bundle/vundle/* From 21eea8a2a39de169f1d0d36062e3bf0c2f58140b Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Fri, 19 Oct 2012 11:24:10 -0500 Subject: [PATCH 08/22] Adding smtp to mutt config --- muttrc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/muttrc b/muttrc index d13617b..dcc5a06 100644 --- a/muttrc +++ b/muttrc @@ -11,7 +11,9 @@ set record = "+[Gmail]/Sent Mail" set postponed = "+[Gmail]/Drafts" unset imap_passive set imap_keepalive = 300 -set mail_check = 120 +set mail_check = 60 +set smtp_url = "smtp://dustinswan@smtp.gmail.com:587/" +set smtp_pass = $my_pw_personal # Sorting set sort = threads From 0b9d90c0b4c505dbcbe3338a3a81292207ed5d9d Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sat, 27 Oct 2012 12:56:41 -0500 Subject: [PATCH 09/22] Switching to Terminus for urxvt --- Xresources | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Xresources b/Xresources index 0b93725..ef705c6 100644 --- a/Xresources +++ b/Xresources @@ -11,14 +11,15 @@ urxvt*urlLauncher: /usr/bin/luakit urxvt*termName: rxvt-unicode ! 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 From 682083c18247f3780f323e27589aebb185f7e09e Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sat, 27 Oct 2012 13:02:03 -0500 Subject: [PATCH 10/22] Switching to compton for X and adding dvorak to xinitrc instead of xorg configs --- xinitrc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/xinitrc b/xinitrc index 96f797f..2c22b6a 100644 --- a/xinitrc +++ b/xinitrc @@ -1,19 +1,17 @@ [[ -f ~/.Xresources ]] && xrdb -merge ~/.Xresources +setxkbmap dvorak setxkbmap -option ctrl:nocaps -#transparency and shadows -xcompmgr -c -C -t-5 -l-5 -r4.2 -o.55 & +compton -cGb dropboxd & -# random background + random background while true; do awsetbg -c -r ~/Dropbox/Photos/wallpaper sleep 1m done & -# urxvt & - exec awesome From 4fa5208e0a3269f1bc59a0cc51a3ed9f4686d134 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sat, 27 Oct 2012 13:02:54 -0500 Subject: [PATCH 11/22] Fixing typo in xinitrc --- xinitrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xinitrc b/xinitrc index 2c22b6a..c0ac2bc 100644 --- a/xinitrc +++ b/xinitrc @@ -7,7 +7,7 @@ compton -cGb dropboxd & - random background +# random background while true; do awsetbg -c -r ~/Dropbox/Photos/wallpaper From 8969fc787972db8185a4d9b51b6074a8360e741c Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sat, 27 Oct 2012 13:04:05 -0500 Subject: [PATCH 12/22] Adding luakit configs. Updating Awesome theme colors and font to use terminus --- awesome/rc.lua | 2 +- awesome/themes/dustin/theme.lua | 12 +- luakit/binds.lua | 588 ++++++++++++++++++++++ luakit/globals.lua | 85 ++++ luakit/modes.lua | 163 ++++++ luakit/rc.lua | 181 +++++++ luakit/theme.lua | 74 +++ luakit/webview.lua | 350 +++++++++++++ luakit/window.lua | 859 ++++++++++++++++++++++++++++++++ 9 files changed, 2309 insertions(+), 5 deletions(-) create mode 100644 luakit/binds.lua create mode 100644 luakit/globals.lua create mode 100644 luakit/modes.lua create mode 100644 luakit/rc.lua create mode 100644 luakit/theme.lua create mode 100644 luakit/webview.lua create mode 100644 luakit/window.lua diff --git a/awesome/rc.lua b/awesome/rc.lua index 673478d..4eb3550 100644 --- a/awesome/rc.lua +++ b/awesome/rc.lua @@ -108,7 +108,7 @@ vicious.register(uptimewidget, vicious.widgets.uptime, "uptime ${eth0 down_kb} up ${eth0 up_kb}', 3) +vicious.register(netwidget, vicious.widgets.net, "down ${wifi0 down_kb} up ${wifi0 up_kb}", 3) -- Date datewidget = widget({ type = "textbox" }) diff --git a/awesome/themes/dustin/theme.lua b/awesome/themes/dustin/theme.lua index 472226a..786ca78 100644 --- a/awesome/themes/dustin/theme.lua +++ b/awesome/themes/dustin/theme.lua @@ -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 diff --git a/luakit/binds.lua b/luakit/binds.lua new file mode 100644 index 0000000..4fc718c --- /dev/null +++ b/luakit/binds.lua @@ -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 diff --git a/luakit/globals.lua b/luakit/globals.lua new file mode 100644 index 0000000..b8b4a25 --- /dev/null +++ b/luakit/globals.lua @@ -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 diff --git a/luakit/modes.lua b/luakit/modes.lua new file mode 100644 index 0000000..bd15c67 --- /dev/null +++ b/luakit/modes.lua @@ -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}, +}) diff --git a/luakit/rc.lua b/luakit/rc.lua new file mode 100644 index 0000000..c03a6bd --- /dev/null +++ b/luakit/rc.lua @@ -0,0 +1,181 @@ +----------------------------------------------------------------------- +-- 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 + +-- vim: et:sw=4:ts=8:sts=4:tw=80 diff --git a/luakit/theme.lua b/luakit/theme.lua new file mode 100644 index 0000000..e53390b --- /dev/null +++ b/luakit/theme.lua @@ -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 diff --git a/luakit/webview.lua b/luakit/webview.lua new file mode 100644 index 0000000..a7a7a59 --- /dev/null +++ b/luakit/webview.lua @@ -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 diff --git a/luakit/window.lua b/luakit/window.lua new file mode 100644 index 0000000..5e921d6 --- /dev/null +++ b/luakit/window.lua @@ -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 = {}, ' %s %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 From a44fcd5269b196a9e403c38eddf998a96e0552c6 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sat, 27 Oct 2012 18:10:37 -0500 Subject: [PATCH 13/22] Adding a bunch of vicious widgets to my AwesomeWM status bar. On a saturday night. --- awesome/rc.lua | 64 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/awesome/rc.lua b/awesome/rc.lua index 4eb3550..d689d2d 100644 --- a/awesome/rc.lua +++ b/awesome/rc.lua @@ -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,8 +103,8 @@ 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 $2.$3'") +--uptimewidget = widget({ type = "textbox" }) +--vicious.register(uptimewidget, vicious.widgets.uptime, "uptime $2.$3'") -- Network netwidget = widget({ type = "textbox" }) @@ -112,11 +112,18 @@ vicious.register(netwidget, vicious.widgets.net, "down %a %F, %T ', 1) +vicious.register(datewidget, vicious.widgets.date, '%a %m-%d, %T ', 1) -- Memory memwidget = widget({ type = "textbox"}) -vicious.register(memwidget, vicious.widgets.mem, 'mem $1% [$2/$3]', 13) +--vicious.register(memwidget, vicious.widgets.mem, 'mem $1% [$2/$3]', 13) +vicious.register(memwidget, vicious.widgets.mem, 'mem $1%', 13) + +-- Filesystem +fswidget = widget({ type = "textbox"}) +vicious.register(fswidget, vicious.widgets.fs, function (widget, args) + return 'fs ' .. args["{/ used_gb}"] .. "/" .. args["{/ size_gb}"] .. 'GB' +end, 20) -- Battery batwidget = widget({ type = "textbox" }) @@ -148,7 +155,33 @@ vicious.register(cpuwidget, vicious.widgets.cpu, 'cpu $1°C', 9, "thermal_zone0") +vicious.register(tempwidget, vicious.widgets.thermal, ' @ $1°C', 9, { "coretemp.0", "core" }) + +volumewidget = widget({ type = "textbox" }) +vicious.register(volumewidget, vicious.widgets.volume, '$2 $1%', 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 $1', 120, "ORD") + +-- Wifi +wifiwidget = widget({ type = "textbox" }) +vicious.register(wifiwidget, vicious.widgets.wifi, + function (widget, args) + --return string.format("%s %i%%", args["{ssid}"], args["{link}"]/70*100) + return args["{ssid}"] .. " " .. math.floor(args["{link}"] / 70 * 100) .. "%" + end, 10, "wifi0" ) + +-- Package widget +--packagewidget = widget({ type = "textbox" }) +--vicious.register(packagewidget, vicious.widgets.pkg, 'pkgs $1', 60, "Arch") -- Create a systray mysystray = widget({ type = "systray" }) @@ -236,15 +269,24 @@ for s = 1, screen.count() do netwidget, separator, --memgraphwidget.widget, + fswidget, + separator, memwidget, separator, --cpugraphwidget.widget, + tempwidget, cpuwidget, separator, - uptimewidget, + --uptimewidget, + --separator, + volumewidget, + separator, + --weatherwidget, + --separator, + wifiwidget, separator, - -- tempwidget, - -- separator, + --packagewidget, + --separator, s == 1 and mysystray or nil, mytasklist[s], layout = awful.widget.layout.horizontal.rightleft @@ -262,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 ), From e43c8e0f36a8795cb5c70c483013a79548eeda97 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sun, 28 Oct 2012 10:56:41 -0500 Subject: [PATCH 14/22] Adding luakit scripts, creating a mutt folder instead of just .muttrc, and adding urlview config --- luakit/multisession.lua | 216 ++++++++ luakit/nscript_widget.lua | 66 +++ luakit/policy.lua | 969 ++++++++++++++++++++++++++++++++++++ luakit/private_browsing.lua | 89 ++++ luakit/rc.lua | 5 + luakit/useragent.lua | 343 +++++++++++++ luakit/useragentmenu | 10 + mutt/hcache | Bin 0 -> 114688 bytes mutt/macros | 1 + mutt/mailcap | 1 + mutt/muttrc | 39 ++ urlview | 2 + 12 files changed, 1741 insertions(+) create mode 100644 luakit/multisession.lua create mode 100644 luakit/nscript_widget.lua create mode 100644 luakit/policy.lua create mode 100644 luakit/private_browsing.lua create mode 100644 luakit/useragent.lua create mode 100644 luakit/useragentmenu create mode 100644 mutt/hcache create mode 100644 mutt/macros create mode 100644 mutt/mailcap create mode 100644 mutt/muttrc create mode 100644 urlview diff --git a/luakit/multisession.lua b/luakit/multisession.lua new file mode 100644 index 0000000..9ac989f --- /dev/null +++ b/luakit/multisession.lua @@ -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 diff --git a/luakit/nscript_widget.lua b/luakit/nscript_widget.lua new file mode 100644 index 0000000..218eb61 --- /dev/null +++ b/luakit/nscript_widget.lua @@ -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 = '%s %s' + 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 diff --git a/luakit/policy.lua b/luakit/policy.lua new file mode 100644 index 0000000..1bf57b2 --- /dev/null +++ b/luakit/policy.lua @@ -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: %2d Blocked: %2d %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, "" .. domain .. "") + 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("A%d B%d", acc, rej) + end + text = text .. "]" + end + pw.text = text + pw:show() + else + pw:hide() + end +end +-- Call load() +load() diff --git a/luakit/private_browsing.lua b/luakit/private_browsing.lua new file mode 100644 index 0000000..a6cd850 --- /dev/null +++ b/luakit/private_browsing.lua @@ -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) diff --git a/luakit/rc.lua b/luakit/rc.lua index c03a6bd..a53aabe 100644 --- a/luakit/rc.lua +++ b/luakit/rc.lua @@ -178,4 +178,9 @@ if unique then end) end +-- Some plugins I found +-- require "nscript_widget" +-- require "private_browsing" +require "useragent" + -- vim: et:sw=4:ts=8:sts=4:tw=80 diff --git a/luakit/useragent.lua b/luakit/useragent.lua new file mode 100644 index 0000000..e714c10 --- /dev/null +++ b/luakit/useragent.lua @@ -0,0 +1,343 @@ +------------------------------------------------------------ +-- Dynamic useragent settings -- +-- Written by lokichaos based upon proxy.lua by: -- +-- +-- Copyright © Piotr Husiatyński -- +------------------------------------------------------------ + +-- 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 \"\"") + 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 diff --git a/luakit/useragentmenu b/luakit/useragentmenu new file mode 100644 index 0000000..4723638 --- /dev/null +++ b/luakit/useragentmenu @@ -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" diff --git a/mutt/hcache b/mutt/hcache new file mode 100644 index 0000000000000000000000000000000000000000..727a02074f21e5cfd7581c75a4a4f216c64db286 GIT binary patch literal 114688 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%0D<){br%-YMJXRV4tASs|ptTdE z7KU=1J}S)X(q3Aanaj>??@y)n&9QlFZG3%pG06^%iSkarF|t!;TkW`!72Jk01Pwr% zM)2kwFCW2=3!ZfR(O@~#$nS(_p`;^r_tSy|4r*91`(f?0#M>Nn^OG<~m`wAoVNi2H z!gu$-miIaJrSJXj9YUk{;ewlna{X!^Y6#GzJa0;KM6%4 z@iPaD6sYogp;!cqME^XeWkI*jkI)oFlBlrhWousX#6kY;$OxQfQ@U{cXcLH_{=c4VVoXd{S z@M3={aK5EEJo;G|`r%J@$BrjiV~e%flcBdeAtPi;qma*(>`E0@N5cy9@>%L`Y7`Wu zg6pt722X(!;JT91OM7W6zFo>_2g1mn8ecQ)glWjmOlBlr-JIGZvCKQI>n+Y z?axhBgzcG~X(lBrma|kIHI0x=Pq#{vI&+43JAPp;obj0Qi6bcF-#q60 z`~F(W-o~Ms(_J?Ni+*`na45kL54v_s*aGNR!Oi(en6s^Sh@iIe`309bZ}(z9K;P%T z@Xo2vxlH-QmrgNrV*do)x>fdx;XZi&w>Qh=1N{uSImV7;hDy_kMX`TkXfnITPp-sv z7Bee)cB8b}Z*!}2vrI)}mn^ka6UE%xFeI-GGR@=QSnrdmpPB=-1OqGDIS%|d68eVbr&m)yvJy%c{Jt;kkZ$oyyx0#3j=eSq z>Z>l;*E~9J{{1-DSRXgE@u_Kqtu&6tx_%lTvL~jM>3L^iKM^Zurw+u`Au(m`BomsX zSC&RA>YS!5X=B>nl-}C&L@X%ybJwo2KI=aQoSh9a&EuE#Rwt&$z%WRXcvfIxg2_@X zPOvNvY!G23oM;~Mz3(q=R~(78LKM<4Z-+GXaM=@impkt$kPwj{leU;n^MUU_L3^W0VftooxOtcG;~Tx$UkdaX)EqATqYL)T*E@sW zoX&rZ^>GINY8JSj%`I6kmfKo)4RnX=?%qjKOw$uZ@Bzq(tebJ>v&l_ZNq+%$N&Kkrt zT>7W(xTuGgt)UqVTaObO<$kA)Vv&~X=BbN16CYigU0xV1t{&{ntmLG%>f|QRltg_} zT#9Y-aWS5d*O%rF+PAP|Ee`mtuiMvyIRy+xxA>2V%qhs$bG2E|Zr0oT>+n=h*M+gH z@ym@%|KZ9C=6`pV8DH@P*WV=lse5-GN`f~Aq+tXs4USAwYEne|Gw{Qxq#Zl3SmBi( zl?`RZn|T8XwjXF7`a)`r!C!6I zt*ahT=>CNN&0Y6q{F!z2830E;T)g=U zV$g?IQjiiV*Qn_ldP2nAJhxZLML|Ikft-2D4-u1^u$=cbK0xwMvD zNG-tLAIA6?_zS4^FOC&v(wo-u*c`7E)C~~f>qBGhHKRbb=UWZtZvpTKx9X-Qa+<{R zF_RNuvp)rlr@(D1Z}OHTTVSo#I!Esg&vzrFdd8_YR^WsN@DRm5+oS4dbf)fic!K5m z!6Sx;vOLMf2?dKghyp%;L7upRCCNF#D$hyuiBN-@k3G-TCqC}Qei(4#sX1J}#f7|h zYiH=2)A_GYkzmPJ*pX6VDW2OAMkg1>(~7iGs^%qoWFfPbfD!!UinKc7r1|om9z2sq z!G{M57OB-gNqy^5g<~v6g#B1_O@iSWNe4R=9#&Pup0|<+Mq}*+OIKnrG)MX+QCE7G zKclXck0*gh3sZG|o_Od5EL*i@UM#=!g) zuI>FT*gf-ZYNdexC+)i^k~iv5uw#M3@QT0;0H5=`4LcTyNtGcx7J!wWJTNjj7qnBs z-H_Iu+EaYJY6h1kkby_AC_2W5x0h~n>w)rOQmlZ(YY=n@58dU)y*`GLkvJ%Gc+Y|% z25N<6V7u;~?NuOxn=JUG`-540HQ71W((rM!~9Wc87~|>X^8apDT(7 zQ`;-qjg8$>IeuVGET>nsDRydOa=gs1jqaA)_Z!LHu&~8meMB8xO>nT8bMtPMk15SVo+R(4!^OK@0I$5TGmy{0kA^Uw32JQJ-?};aY4}#isKbsK90MlhjLfDO zSxGqQ1c+mxUX^E3HqMZ@h7(Y)+IAW?$OG;Nvp++q_kVh^zX(Ci7;}#c_C=~Q=>B|~ z&#^vmTz`V>aztzh$SzAad`G1rC{*i?O3;l?p>tfr*>VzK2n$BAWS{RE^PvrdNt~RK z54`|K*h^c44YwId5C&A4PCCgFAMpD2S2Nqdtg2>SpuUj$<=!*)= zHopmLF!XmpntFKjewXYX^5XgrO(zrHnDuV3RbA85;V=E%f20)?>M=emCQ+qnnBQO- zk>`8lIvBXV?o!}=uX8`A(}JuQyw~OSzx>lyu0I!m#x>T3oq74wmFpEjfz_kBOap1_ z!1WAR`x&s$iv`nF9PIxM4p7ZzYDXX`_-o~Q*lY^A?aiLGZ-r+GcUVje_L*W0URMpl zvl!RC-SGU5+4`QpDUAgjAFRtCk_=o%#-uXq|g_{vN z!yb^dehb?cbcf;@6W=KRz9{U=Fc3q5PyVt)RO@1)41IWhL zUCEXe&zrf89cd*a$7dGGbRt`w%k3oAW+&;HR7Tx3?6RX}Qso0{JZqTk#|m9P5TZ|w z1_KkM`zAjSNKB-ei-F$(PSaq`tq%LqvKBa0P&8T5R6~P3Zw1b;+jrNrv8#Ae|eTJ|6(Z`L?Lj)8A#%|OR(ny#CQ zWlG@EO#){Qrf|qJkpInjUSFJ)`D#2^IY={Ccb1K-*xBX@%Ur8r;Hdjc^$#G*r-rU>R)z;S* zr_->X&h*AkVR}E48l9c!-|MiFGz{W(vW1h2hD-Hl)XvoZQLh2M6PI&bhv1h}1O@z6H0MOiah;W)>$FSNGDf?diFd zZ7Ij*!RCGeJO=G>t5RilVfP@PPqY_8WZySfwd3#0!<+@%>=~B4z3K4iunY0! zBcK+%mRCn%ejP%1D)-itqMbs@R-FWhwj@khCdIT9SiX}`ITxmR{gpp-sr*e|>@UT= z{tNH?nn&fAFPvg3zXLu72e4Ww9ThaM86ifJLlX&k# zlVj`SQ~lFMa=I|FxhIRI)@B3|qu{TV(nP1A&>aHhdS zzgbYgnW)4`(D1c4=^W~YFOgM3za7%l!?g*QB8pmP%J`bcltWJzCkC#eHEi%DCempb zEF?RZC&9|j7Pf^^<@yvt?EcY3k^#9dl^$m&d!j;D!MaD41KgcG*WEX=~G30Nk~q;1khE4HfiP7@6^$@KQW zbj88IU%0U!r62ZRc;{!PJ#pa00goJc3&lb3>eQ(V@whfjjuYCHISGHU_=StievimaPvPz08yB~<|56ub~T z!E=%pu5R%U;}$vib7~`;K`q=5e8nZ@gD8xZ#dRk#runGux__ zzMOR(-I90ojHJ=!F>0PJS!3fu$Xbb6pz^6PI;Md0RRP94Xc*~WXbv_ZVoY6C4OKkS zM|~?<3xgtfUT*GD)%DDnXfl$;ONz;uf-VX=t4pvyjA9rvD4Wuur9<6wA7V(_voNnE z=zE7J=3N@Nb_5N4!ehO62N9A#!xNr&#d@&GwWP?fM;#+Gf$tB`da#pSm>%C>f7NBV zzwu&!Dem)Mc;}D*s0;fO%bg`&K+^gxtdY~9Ty9pkm-{!Y8FPPqbY!f&$I&B&jU9G* zZq!N7m8|W;d^)zdGPb;=FSQQe;rCMT*UE{oc2^kW<)#Ma7I@aLv2~@{65a}F zRY&*6YN`Iu=n6onjCzN8aR?OZ?*cs1+;fF|#_8 zTv7B5HML&c6|6~XIkCCPje*Fq<+1*1m=Pusci9q~EhOq|`@j^+U}P}K1@D;9@sSLu0F(`4M5M-?72edt-)Q)>p#J4oRp%G0j^Q z;6}!TEm+IcO{*k23A%)#fsqHvlBhNhN@4s+TK&vhk#Lo=jb1a_rq`ZMZE>3Leq z(lA7Gh(pURLtk_{%hES`QpK4+l)7gZepz}e7-|8r!1y%zhQx!-@`onQ7qpV{gRdO*_pEtH}d&=d4lVFOHThBJjiX3NQx z3e{ry(BfAdw==UDuxp2z@MN}_1;c^zkts3vS~%|8YR_Yf`y+0#evI;7orYDgZAwbf z6iZDyFld!=(A=J-<_oozS2!$u-d$kCNs`1VNeDbHkArP1lL=1rz8k-|F)->bBJ}&5 zf-MeVF9h`%)^JS0t(I#?RL_S!RPMPx>#zF!JaMGu39kKwWv~)2$!S$c2nn8HV1EHw zNP(|sDR}m;R$Ed0R7Bte-C?$^@)!ir2Of0AUM==N6Eq_D#IDO%Gai5WpFi$7vfOR( zH$r3`wOGK#|2QeIgJ*Qj1%N9G4+%kh15V5y%L717-l50VBrdQ<&%lXl1*~_Q_szn5 zF`)W^D@RE|aITh0mkK$GEYHT&WQjIqS195FYi5!pBEpRU555e`gH)4*ge;^voTf`L z>9mqeA5XY(un)C#OjF+-Pq-aX31c1v8#vf`9YQGKMmkSTD6tKcl7Zzr3H_7FOb435NW$;K*?hV%U?-D>Y92O+ zgB=&TaGHT7yA%HI>hQw5`fwE~tanN|YD$I~s{M3!Cz-YR%~WA`-^P$gY;OooDYcs^ zWHz?ld!5P&`H_Hg?%))pMEq|Yi41Ho0q#6y4&On(fp608UsC<3*? zdhwDd4w%(kF}_}?46tp=?P@8AmAg#b=feXQ1Hmdl&{AS%XGQz+t2|j+bz|}w0f$$6 zqq-Ur^>qlL*!VmYK+_EqHqs4A0d&k784WD{Nw~bNAA~+!zuOcx{@ms6O)vKU9Hdq~ z@k+NwEroYs76 z#d;Z>%)uI#EhkxVQWQL%&FA5Sr3z_ugi``H3HdU48kZS?w$8#}JqOD{p`w`qSf?g% z1F*xGG+f+=f`iZc0Vl};&*VWjZPMGTc~}?g=Lm_6|1vP&1ff=PoKLr7|pIz7@`^l{DR}b)T@|fY(Kb zjNMRcyMlZ-z2xRMk}hj4uBE{^s26?d)h@O(uj`Jg(GX{}P(3)H7K$kl!DX@|Y1KU+ zUdLZfPS*a9xE(I$VV6@_y6tRI;M#z^l{}%s@jQbYZlw4WSfVP4H0Rh7*y!7;opxkf zN-50nRv~F`t;2$?0dkfqfPl~YI+!hl3VNLaTY3SZg2k)9C@trgUhjeF#VrqbH}3QZ zHS;#_q}_ujydO$'urlview' 'Follow links with urlview' diff --git a/mutt/mailcap b/mutt/mailcap new file mode 100644 index 0000000..8603537 --- /dev/null +++ b/mutt/mailcap @@ -0,0 +1 @@ +text/html; w3m -I %{charset} -T text/html; copiousoutput; diff --git a/mutt/muttrc b/mutt/muttrc new file mode 100644 index 0000000..c2053df --- /dev/null +++ b/mutt/muttrc @@ -0,0 +1,39 @@ +source "gpg -dq ~/.my-pwds.gpg |" + +set realname = "Dustin Swan" +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 +set smtp_url = "smtp://dustinswan@smtp.gmail.com:587/" +set smtp_pass = $my_pw_personal + +# 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 sidebar-next +bind index sidebar-prev +bind index 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 + diff --git a/urlview b/urlview new file mode 100644 index 0000000..6da1012 --- /dev/null +++ b/urlview @@ -0,0 +1,2 @@ +REGEXP (((http|https|ftp|gopher)|mailto)[.:][^ >"\t]*|www\.[-a-z0-9.]+)[^ .,;\t>">\):] +COMMAND luakit -n %s 2>/dev/null From 8498e280cae8605e43f0231450ad187e1b042619 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Mon, 29 Oct 2012 14:14:32 -0500 Subject: [PATCH 15/22] Adding xprofile because arch under vmware doesn't work well with my imac monitor. Temporary until I figure this out better --- xprofile | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 xprofile diff --git a/xprofile b/xprofile new file mode 100644 index 0000000..e07d802 --- /dev/null +++ b/xprofile @@ -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 From 903190bfd9c45ec2882c928fc214e17e4204ae31 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Tue, 30 Oct 2012 11:25:39 -0500 Subject: [PATCH 16/22] Adding vim-signature plugin --- vimrc | 1 + 1 file changed, 1 insertion(+) diff --git a/vimrc b/vimrc index b2c216b..eea57d0 100644 --- a/vimrc +++ b/vimrc @@ -43,6 +43,7 @@ Bundle 'coderifous/textobj-word-column.vim' Bundle 'lukaszkorecki/workflowish' Bundle 'searchfold.vim' Bundle 'godlygeek/tabular' +Bundle 'kshenoy/vim-signature' " Snipmate " Bundle 'MarcWeber/vim-addon-mw-utils' From 0082054c52fe9f338c0d72c680f8a57e3c3134ef Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Wed, 31 Oct 2012 07:38:38 -0500 Subject: [PATCH 17/22] Adding a bunch more mutt stuff to dotfiles. Small updates to vimrc, zshrc. Adding urlview. --- .gitignore | 1 + Xresources | 120 +++++++++++++--- mutt/macros | 3 +- mutt/mailcap | 1 + mutt/mutt-colors-solarized-dark-16.muttrc | 151 +++++++++++++++++++++ mutt/mutt-colors-solarized-dark-256.muttrc | 151 +++++++++++++++++++++ mutt/muttrc | 18 +++ muttrc | 34 ----- tmux.conf | 13 +- urlview | 2 - vimrc | 3 +- zshrc | 3 + 12 files changed, 441 insertions(+), 59 deletions(-) create mode 100644 mutt/mutt-colors-solarized-dark-16.muttrc create mode 100644 mutt/mutt-colors-solarized-dark-256.muttrc delete mode 100644 muttrc delete mode 100644 urlview diff --git a/.gitignore b/.gitignore index a22be3e..67524c4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ weechat/logs/* vim/.netrwhist vim/bundle/* !vim/bundle/vundle/* +mutt/hcache diff --git a/Xresources b/Xresources index ef705c6..cad42e4 100644 --- a/Xresources +++ b/Xresources @@ -1,4 +1,6 @@ ! General + +! Urxvt urxvt*loginShell: true urxvt*scrollBar: false urxvt*secondaryScroll: true @@ -8,7 +10,7 @@ urxvt*urgentOnBell: true 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: xft:DejaVu Sans Mono:pixelsize=10:antialias=true:hinting=true @@ -28,20 +30,104 @@ urxvt*depth: 32 urxvt*foreground: #FFFFFF 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 +!*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 diff --git a/mutt/macros b/mutt/macros index 3f6ec6b..bc61815 100644 --- a/mutt/macros +++ b/mutt/macros @@ -1 +1,2 @@ -macro pager \cb 'urlview' 'Follow links with urlview' +macro index,pager \cb 'urlscan' 'Follow links with urlview' +macro attach,compose \cb 'urlscan' 'Follow links with urlview' diff --git a/mutt/mailcap b/mutt/mailcap index 8603537..e845299 100644 --- a/mutt/mailcap +++ b/mutt/mailcap @@ -1 +1,2 @@ +text/html; luakit %s &; test=test -n "%DISPLAY"; needsterminal; text/html; w3m -I %{charset} -T text/html; copiousoutput; diff --git a/mutt/mutt-colors-solarized-dark-16.muttrc b/mutt/mutt-colors-solarized-dark-16.muttrc new file mode 100644 index 0000000..e9d6def --- /dev/null +++ b/mutt/mutt-colors-solarized-dark-16.muttrc @@ -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]>" # +#color body brightwhite default "<[Bb][Gg]>" # +#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 " + diff --git a/mutt/mutt-colors-solarized-dark-256.muttrc b/mutt/mutt-colors-solarized-dark-256.muttrc new file mode 100644 index 0000000..b318651 --- /dev/null +++ b/mutt/mutt-colors-solarized-dark-256.muttrc @@ -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]>" # +#color body color230 color234 "<[Bb][Gg]>" # +#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 " + diff --git a/mutt/muttrc b/mutt/muttrc index c2053df..b3294ba 100644 --- a/mutt/muttrc +++ b/mutt/muttrc @@ -1,6 +1,10 @@ +# 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/" @@ -12,8 +16,20 @@ 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 @@ -37,3 +53,5 @@ bind index sidebar-open auto_view text/html alternative_order text/plain text/enriched text/html +# Colors +source ~/.mutt/mutt-colors-solarized-dark-256.muttrc diff --git a/muttrc b/muttrc deleted file mode 100644 index dcc5a06..0000000 --- a/muttrc +++ /dev/null @@ -1,34 +0,0 @@ -source "gpg -dq ~/.my-pwds.gpg |" - -set realname = "Dustin Swan" -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 -set smtp_url = "smtp://dustinswan@smtp.gmail.com:587/" -set smtp_pass = $my_pw_personal - -# 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 sidebar-next -bind index sidebar-prev -bind index 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 )?---"" diff --git a/tmux.conf b/tmux.conf index 7eae20c..16ca30e 100644 --- a/tmux.conf +++ b/tmux.conf @@ -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]" diff --git a/urlview b/urlview deleted file mode 100644 index 6da1012..0000000 --- a/urlview +++ /dev/null @@ -1,2 +0,0 @@ -REGEXP (((http|https|ftp|gopher)|mailto)[.:][^ >"\t]*|www\.[-a-z0-9.]+)[^ .,;\t>">\):] -COMMAND luakit -n %s 2>/dev/null diff --git a/vimrc b/vimrc index b2c216b..602df72 100644 --- a/vimrc +++ b/vimrc @@ -134,11 +134,12 @@ 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 diff --git a/zshrc b/zshrc index 1d8c41e..3e18bd2 100644 --- a/zshrc +++ b/zshrc @@ -31,7 +31,10 @@ 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 From 9c3f43663a2966db65aacea6a98ab6bd29b604d9 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Wed, 31 Oct 2012 13:18:38 -0500 Subject: [PATCH 18/22] Adding ultisnips to vimrc --- vimrc | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/vimrc b/vimrc index 3c27d7d..8c7c2be 100644 --- a/vimrc +++ b/vimrc @@ -17,7 +17,7 @@ Bundle 'tpope/vim-repeat' Bundle 'tpope/vim-surround' Bundle 'tpope/vim-fugitive' Bundle 'tpope/vim-endwise' -Bundle 'mileszs/ack.vim' +Bundle 'mileszs/ack' Bundle 'Lokaltog/vim-powerline' Bundle 'Lokaltog/vim-easymotion' Bundle 'bkad/CamelCaseMotion' @@ -27,29 +27,24 @@ Bundle 'scrooloose/nerdcommenter' " Bundle 'scrooloose/nerdtree' Bundle 'altercation/vim-colors-solarized' " Bundle 'ervandew/supertab' -" Bundle 'sjl/gundo.vim' -" Bundle 'sjl/clam.vim' -Bundle 'kien/ctrlp.vim' +" Bundle 'sjl/gundo' +" Bundle 'sjl/clam' +Bundle 'kien/ctrlp' Bundle 'gregsexton/MatchTag' -" Bundle 'closetag.vim' +" Bundle 'closetag' Bundle 'kana/vim-smartinput' Bundle 'rstacruz/sparkup', {'rtp': 'vim/'} Bundle 'mbbill/undotree' " Bundle 'Shougo/neocomplcache' -Bundle 'coderifous/textobj-word-column.vim' +Bundle 'coderifous/textobj-word-column' " Bundle 'myusuf3/numbers' " Bundle 'benmills/vimux' -" Bundle 'kikijump/tslime.vim' +" Bundle 'kikijump/tslime' Bundle 'lukaszkorecki/workflowish' -Bundle 'searchfold.vim' +Bundle 'searchfold' Bundle 'godlygeek/tabular' Bundle 'kshenoy/vim-signature' - -" Snipmate -" Bundle 'MarcWeber/vim-addon-mw-utils' -" Bundle 'tomtom/tlib_vim' -" Bundle 'snipmate-snippets' -" Bundle 'garbas/vim-snipmate' +Bundle 'SirVer/ultisnips' filetype plugin indent on " last Vundle requirement @@ -181,6 +176,10 @@ nnoremap s :SyntasticToggleMode " Supertab " let g:SuperTabDefaultCompletionType="context" +" UltiSnpis +let g:UltiSnipsJumpForwardTrigger="" +let g:UltiSnipsJumpBackwardTrigger="" + " open the current file for edit in Perforce nnoremap 4 :! p4 edit % From 91811e7d7196ec5e4a9f2378c840940ba818e710 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Thu, 1 Nov 2012 15:26:40 -0500 Subject: [PATCH 19/22] Disabling Ack for now --- vimrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vimrc b/vimrc index 8c7c2be..b9748bd 100644 --- a/vimrc +++ b/vimrc @@ -17,7 +17,7 @@ Bundle 'tpope/vim-repeat' Bundle 'tpope/vim-surround' Bundle 'tpope/vim-fugitive' Bundle 'tpope/vim-endwise' -Bundle 'mileszs/ack' +" Bundle 'mileszs/ack' Bundle 'Lokaltog/vim-powerline' Bundle 'Lokaltog/vim-easymotion' Bundle 'bkad/CamelCaseMotion' @@ -190,7 +190,7 @@ nnoremap v vl nnoremap w :%s/\s\+$//e " open Ack -nnoremap a :Ack +" nnoremap a :Ack " Marked nnoremap m :silent !open -a Marked.app '%:p' From 67c34f9507432e8c91cce548a59eff7003020ee9 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Thu, 1 Nov 2012 15:31:15 -0500 Subject: [PATCH 20/22] Adding .vim to some vundle packages. --- vimrc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vimrc b/vimrc index b9748bd..7ca7287 100644 --- a/vimrc +++ b/vimrc @@ -18,7 +18,7 @@ Bundle 'tpope/vim-surround' Bundle 'tpope/vim-fugitive' Bundle 'tpope/vim-endwise' " Bundle 'mileszs/ack' -Bundle 'Lokaltog/vim-powerline' +Bundle 'Lokaltog/vim-powerline.git' Bundle 'Lokaltog/vim-easymotion' Bundle 'bkad/CamelCaseMotion' Bundle 'majutsushi/tagbar' @@ -29,19 +29,19 @@ Bundle 'altercation/vim-colors-solarized' " Bundle 'ervandew/supertab' " Bundle 'sjl/gundo' " Bundle 'sjl/clam' -Bundle 'kien/ctrlp' +Bundle 'kien/ctrlp.vim' Bundle 'gregsexton/MatchTag' " Bundle 'closetag' Bundle 'kana/vim-smartinput' Bundle 'rstacruz/sparkup', {'rtp': 'vim/'} Bundle 'mbbill/undotree' " Bundle 'Shougo/neocomplcache' -Bundle 'coderifous/textobj-word-column' +Bundle 'coderifous/textobj-word-column.vim' " Bundle 'myusuf3/numbers' " Bundle 'benmills/vimux' " Bundle 'kikijump/tslime' Bundle 'lukaszkorecki/workflowish' -Bundle 'searchfold' +Bundle 'searchfold.vim' Bundle 'godlygeek/tabular' Bundle 'kshenoy/vim-signature' Bundle 'SirVer/ultisnips' From 54a8db05096497f609bdcc2aadc3d0a99bdcf2fd Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Thu, 1 Nov 2012 16:32:40 -0500 Subject: [PATCH 21/22] Adding vim-ruby --- vimrc | 1 + 1 file changed, 1 insertion(+) diff --git a/vimrc b/vimrc index 7ca7287..03b6e08 100644 --- a/vimrc +++ b/vimrc @@ -12,6 +12,7 @@ Bundle 'pangloss/vim-javascript' Bundle 'kchmck/vim-coffee-script' Bundle 'spf13/PIV' Bundle 'jQuery' +Bundle 'vim-ruby/vim-ruby' Bundle 'tpope/vim-rails' Bundle 'tpope/vim-repeat' Bundle 'tpope/vim-surround' From a52e90fe5d64adb6781a99f6573aec1b16c10fad Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sun, 4 Nov 2012 22:45:56 -0600 Subject: [PATCH 22/22] Adding rbenv and ruby to path, adding some more oh-my-zsh plugins --- zshrc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zshrc b/zshrc index 3e18bd2..73d94f7 100644 --- a/zshrc +++ b/zshrc @@ -25,11 +25,10 @@ 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 @@ -47,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