diff --git a/.config/awesome/lanxu/ip.lua b/.config/awesome/lanxu/ip.lua new file mode 100644 index 0000000..0a4fcb2 --- /dev/null +++ b/.config/awesome/lanxu/ip.lua @@ -0,0 +1,53 @@ +local naughty = require("naughty") +local wibox = require("wibox") +local json = require("lanxu/dkjson") +local gears = require("gears") +local focused = require("awful.screen").focused +local easy_async = require("awful.spawn").easy_async + +local function factory(args) + local args = args or {} + local calluri = args.uri or "https://api.ipify.org" + local settings = args.settings or function() end + local homeaddress = args.homeaddress or nil + + local ip = { widget = wibox.widget.textbox() } + ip.widget:set_markup("N/A") + + function ip.attach(obj) + obj:connect_signal("button::press", function() + ip.update() + end) + end + + function ip.update() + local cmd = string.format("curl -s " .. "'" .. calluri .. "'") + + address = "N/A" + settings() + + easy_async(cmd, function(response, stderr, reason, exit_code) + address = response + address = string.gsub(address, "[^0-9.]", "") + if address == homeaddress then + address = "Home" + end + + ip.address = address + widget = ip.widget + + settings() + end) + end + + ip.attach(ip.widget) + + address = "N/A" + settings() + + ip.update() + + return ip +end + +return factory diff --git a/.config/awesome/rc.lua b/.config/awesome/rc.lua index 33013d7..da14620 100644 --- a/.config/awesome/rc.lua +++ b/.config/awesome/rc.lua @@ -116,8 +116,13 @@ myawesomemenu = { { "quit", function() awesome.quit() end} } lock = function() + -- Sync disks before lock (just in case) awful.util.spawn("sync") - awful.util.spawn("xautolock -locknow") + + -- Lock screen + awful.util.spawn("xdg-screensaver lock") + --awful.util.spawn("xautolock -locknow") + --awful.util.spawn("xlock") end mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon }, { "open terminal", terminal }, @@ -260,8 +265,8 @@ awful.screen.connect_for_each_screen(function(s) spacer, mydpmsstatus, spacer, - mycloudstatus, - spacer, + --mycloudstatus, + --spacer, mycpu, spacer, mymem, @@ -269,11 +274,8 @@ awful.screen.connect_for_each_screen(function(s) myweather, spacer, mycputemp, - spacer, mygputemp, - spacer, mytextclock, - spacer, s.mylayoutbox, } -- Only show everything on the first screen @@ -283,7 +285,7 @@ awful.screen.connect_for_each_screen(function(s) s.mylayoutbox, } end - + -- Add widgets to the wibox s.mywibox:setup { layout = wibox.layout.align.horizontal, @@ -350,7 +352,7 @@ globalkeys = awful.util.table.join( function () awful.client.focus.history.previous() if client.focus then - client.focus:raise() +client.focus:raise() end end, {description = "go back", group = "client"}), @@ -407,8 +409,15 @@ globalkeys = awful.util.table.join( {description = "lua execute prompt", group = "awesome"}), -- Menubar awful.key({ modkey }, "p", function() menubar.show() end, + {description = "show the menubar", group = "launcher"}), + -- Menubar (dmenu) + awful.key({ modkey }, "d", + function() + --awful.spawn(string.format("dmenu_run -i -b -l 20 -fn 'Fura Code Nerd Font:size=10:style=Regular'")) + awful.spawn(string.format("rofi -show combi -combi-modi 'window,run,ssh' -modi combi")) + end, {description = "show the menubar", group = "launcher"}) -) + ) clientkeys = awful.util.table.join( awful.key({ modkey, }, "f", @@ -508,29 +517,46 @@ for i = 1, 9 do volume.update() end, {description = "Lower audio volume", group = "audio"}), - awful.key({ any }, "XF86AudioMute", + awful.key({ any }, "XF86AudioMute", function() awful.spawn(string.format("pactl set-sink-mute %s 1", volume.device)) volume.update() end, {description = "mute audio", group = "audio"}), - awful.key({ 'Shift' }, "XF86AudioMute", + awful.key({ 'Shift' }, "XF86AudioMute", function() awful.spawn(string.format("pactl set-sink-mute %s 0", volume.device)) volume.update() end, {description = "unmute audio", group = "audio"}), - awful.key({ modkey }, "Print", - function () - local command = [[bash -c 'escrotum "$(xdg-user-dir PICTURES)/%Y-%m-%d_%T_screenshot.png"']] - awful.spawn.easy_async(command, function(stdout, stderr) - naughty.notify { - title = "Screenshot saved!", - text = stdout, - } - end) + awful.key({ }, "Print", + function () + --local command = [[bash -c 'escrotum "$(xdg-user-dir PICTURES)/%Y-%m-%d_%T_screenshot.png"']] + for i=1,screen:count() do + local command = "bash -c 'flameshot screen -n ".. i-1 .." -p \"$(xdg-user-dir PICTURES)/\"'" + awful.spawn.easy_async(command, function(stdout, stderr) + --naughty.notify { + -- title = "Screenshot saved!", + -- text = stdout, + --} + end) + end end, - {description = "Take screenshot", group = "audio"}) + {description = "Take screenshot", group = "video"}), + awful.key({ 'Shift' }, "Print", + function () + --local command = [[bash -c 'escrotum "$(xdg-user-dir PICTURES)/%Y-%m-%d_%T_screenshot.png"']] + for i=1,screen:count() do + local command = "bash -c 'flameshot gui -p \"$(xdg-user-dir PICTURES)/\"'" + awful.spawn.easy_async(command, function(stdout, stderr) + --naughty.notify { + -- title = "Screenshot saved!", + -- text = stdout, + --} + end) + end + end, + {description = "Take screenshot", group = "video"}) ) clientbuttons = awful.util.table.join( @@ -595,7 +621,7 @@ awful.rules.rules = { role = { "pop-up", -- e.g. Google Chrome's (detached) Developer Tools. } - }, properties = { + }, properties = { floating = true } }, @@ -699,12 +725,13 @@ local function remove_client(tabl, c) if index then table.remove(tabl, index) if #tabl == 0 then + awful.util.spawn("xset s blank") awful.util.spawn("xset s on") awful.util.spawn("xset +dpms") naughty.notify({ preset = naughty.config.presets.low, title = "DPMS information", text = "Display power management is now back ON"}) - end + end end end @@ -712,9 +739,10 @@ client.connect_signal("property::fullscreen", function(c) if c.fullscreen then table.insert(fullscreened_clients, c) if #fullscreened_clients == 1 then + awful.util.spawn("xset s noblank") awful.util.spawn("xset s off") awful.util.spawn("xset -dpms") - naughty.notify({ + naughty.notify({ preset = naughty.config.presets.low, title = "DPMS information", text = "Display power management is now OFF" @@ -733,10 +761,13 @@ end) awful.util.spawn_with_shell("run-once pasystray") awful.util.spawn_with_shell("run-once blueman-applet") +awful.util.spawn_with_shell("run-once nm-applet") +awful.util.spawn_with_shell("run-once 'nextcloud --background'") +awful.util.spawn_with_shell("run-once 'udiskie --tray --notify --automount'") +awful.util.spawn_with_shell("run-once 'mpd /home/lanxu/.config/mpd/mpd.conf'") +awful.util.spawn_with_shell("run-once 'xscreensaver -no-splash'") --awful.util.spawn_with_shell("run-once conky") ---awful.util.spawn_with_shell("run-once dropboxd") --awful.util.spawn_with_shell("run-once light-locker") ---awful.util.spawn_with_shell("run-once xscreensaver -no-splash") --awful.util.spawn_with_shell("run-once firefox-developer-edition") --awful.util.spawn_with_shell("run-once firefox") diff --git a/.config/awesome/themes/lanxu/icons/ac.png b/.config/awesome/themes/lanxu/icons/ac.png deleted file mode 100644 index 96efcb4..0000000 Binary files a/.config/awesome/themes/lanxu/icons/ac.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/battery.png b/.config/awesome/themes/lanxu/icons/battery.png deleted file mode 100644 index 8c85596..0000000 Binary files a/.config/awesome/themes/lanxu/icons/battery.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/battery_empty.png b/.config/awesome/themes/lanxu/icons/battery_empty.png deleted file mode 100644 index 00821c9..0000000 Binary files a/.config/awesome/themes/lanxu/icons/battery_empty.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/battery_low.png b/.config/awesome/themes/lanxu/icons/battery_low.png deleted file mode 100644 index 29f3fc5..0000000 Binary files a/.config/awesome/themes/lanxu/icons/battery_low.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/centerfair.png b/.config/awesome/themes/lanxu/icons/centerfair.png deleted file mode 100644 index c4f64b0..0000000 Binary files a/.config/awesome/themes/lanxu/icons/centerfair.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/centerwork.png b/.config/awesome/themes/lanxu/icons/centerwork.png deleted file mode 100644 index 9071516..0000000 Binary files a/.config/awesome/themes/lanxu/icons/centerwork.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/centerworkh.png b/.config/awesome/themes/lanxu/icons/centerworkh.png deleted file mode 100644 index b1d1379..0000000 Binary files a/.config/awesome/themes/lanxu/icons/centerworkh.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/cpu.png b/.config/awesome/themes/lanxu/icons/cpu.png index 35af1c3..b9891e3 100644 Binary files a/.config/awesome/themes/lanxu/icons/cpu.png and b/.config/awesome/themes/lanxu/icons/cpu.png differ diff --git a/.config/awesome/themes/lanxu/icons/dwindle.png b/.config/awesome/themes/lanxu/icons/dwindle.png deleted file mode 100644 index 649ea99..0000000 Binary files a/.config/awesome/themes/lanxu/icons/dwindle.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/fairh.png b/.config/awesome/themes/lanxu/icons/fairh.png deleted file mode 100644 index 62d3d99..0000000 Binary files a/.config/awesome/themes/lanxu/icons/fairh.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/fairv.png b/.config/awesome/themes/lanxu/icons/fairv.png deleted file mode 100644 index 131dd0f..0000000 Binary files a/.config/awesome/themes/lanxu/icons/fairv.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/floating.png b/.config/awesome/themes/lanxu/icons/floating.png deleted file mode 100644 index d25c47b..0000000 Binary files a/.config/awesome/themes/lanxu/icons/floating.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/gpu.png b/.config/awesome/themes/lanxu/icons/gpu.png new file mode 100644 index 0000000..4926699 Binary files /dev/null and b/.config/awesome/themes/lanxu/icons/gpu.png differ diff --git a/.config/awesome/themes/lanxu/icons/hdd.png b/.config/awesome/themes/lanxu/icons/hdd.png deleted file mode 100644 index 0fb6833..0000000 Binary files a/.config/awesome/themes/lanxu/icons/hdd.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/magnifier.png b/.config/awesome/themes/lanxu/icons/magnifier.png deleted file mode 100644 index 60d3e0d..0000000 Binary files a/.config/awesome/themes/lanxu/icons/magnifier.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/mail.png b/.config/awesome/themes/lanxu/icons/mail.png deleted file mode 100644 index 474e602..0000000 Binary files a/.config/awesome/themes/lanxu/icons/mail.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/mail_on.png b/.config/awesome/themes/lanxu/icons/mail_on.png deleted file mode 100644 index 19106d7..0000000 Binary files a/.config/awesome/themes/lanxu/icons/mail_on.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/max.png b/.config/awesome/themes/lanxu/icons/max.png deleted file mode 100644 index 5b0a5b7..0000000 Binary files a/.config/awesome/themes/lanxu/icons/max.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/mem.png b/.config/awesome/themes/lanxu/icons/mem.png deleted file mode 100644 index 7860a1a..0000000 Binary files a/.config/awesome/themes/lanxu/icons/mem.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/net.png b/.config/awesome/themes/lanxu/icons/net.png deleted file mode 100644 index bc42fdc..0000000 Binary files a/.config/awesome/themes/lanxu/icons/net.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/net_wired.png b/.config/awesome/themes/lanxu/icons/net_wired.png deleted file mode 100644 index e8cc2bd..0000000 Binary files a/.config/awesome/themes/lanxu/icons/net_wired.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/note.png b/.config/awesome/themes/lanxu/icons/note.png deleted file mode 100644 index baa29c3..0000000 Binary files a/.config/awesome/themes/lanxu/icons/note.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/note_on.png b/.config/awesome/themes/lanxu/icons/note_on.png deleted file mode 100644 index 1a7ab94..0000000 Binary files a/.config/awesome/themes/lanxu/icons/note_on.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/ram.png b/.config/awesome/themes/lanxu/icons/ram.png new file mode 100644 index 0000000..7f61ac2 Binary files /dev/null and b/.config/awesome/themes/lanxu/icons/ram.png differ diff --git a/.config/awesome/themes/lanxu/icons/scissors.png b/.config/awesome/themes/lanxu/icons/scissors.png deleted file mode 100644 index f8c700d..0000000 Binary files a/.config/awesome/themes/lanxu/icons/scissors.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/spiral.png b/.config/awesome/themes/lanxu/icons/spiral.png deleted file mode 100644 index d9ee0f6..0000000 Binary files a/.config/awesome/themes/lanxu/icons/spiral.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/square_sel.png b/.config/awesome/themes/lanxu/icons/square_sel.png deleted file mode 100644 index 1102a9f..0000000 Binary files a/.config/awesome/themes/lanxu/icons/square_sel.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/square_unsel.png b/.config/awesome/themes/lanxu/icons/square_unsel.png deleted file mode 100644 index 7386b85..0000000 Binary files a/.config/awesome/themes/lanxu/icons/square_unsel.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/submenu.png b/.config/awesome/themes/lanxu/icons/submenu.png deleted file mode 100644 index b55ebce..0000000 Binary files a/.config/awesome/themes/lanxu/icons/submenu.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/task.png b/.config/awesome/themes/lanxu/icons/task.png deleted file mode 100644 index 9701b68..0000000 Binary files a/.config/awesome/themes/lanxu/icons/task.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/temp.png b/.config/awesome/themes/lanxu/icons/temp.png deleted file mode 100644 index 6793a9f..0000000 Binary files a/.config/awesome/themes/lanxu/icons/temp.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/termfair.png b/.config/awesome/themes/lanxu/icons/termfair.png deleted file mode 100644 index 3e06023..0000000 Binary files a/.config/awesome/themes/lanxu/icons/termfair.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/tile.png b/.config/awesome/themes/lanxu/icons/tile.png deleted file mode 100644 index 922c05c..0000000 Binary files a/.config/awesome/themes/lanxu/icons/tile.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/tilebottom.png b/.config/awesome/themes/lanxu/icons/tilebottom.png deleted file mode 100644 index 6ec9cb8..0000000 Binary files a/.config/awesome/themes/lanxu/icons/tilebottom.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/tileleft.png b/.config/awesome/themes/lanxu/icons/tileleft.png deleted file mode 100644 index 8e3d2d6..0000000 Binary files a/.config/awesome/themes/lanxu/icons/tileleft.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/tiletop.png b/.config/awesome/themes/lanxu/icons/tiletop.png deleted file mode 100644 index 3da75a1..0000000 Binary files a/.config/awesome/themes/lanxu/icons/tiletop.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/vol.png b/.config/awesome/themes/lanxu/icons/vol.png deleted file mode 100644 index bbf33d4..0000000 Binary files a/.config/awesome/themes/lanxu/icons/vol.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/vol_low.png b/.config/awesome/themes/lanxu/icons/vol_low.png deleted file mode 100644 index aa3ce4d..0000000 Binary files a/.config/awesome/themes/lanxu/icons/vol_low.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/vol_mute.png b/.config/awesome/themes/lanxu/icons/vol_mute.png deleted file mode 100644 index e855fd2..0000000 Binary files a/.config/awesome/themes/lanxu/icons/vol_mute.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/vol_no.png b/.config/awesome/themes/lanxu/icons/vol_no.png deleted file mode 100644 index bbe917b..0000000 Binary files a/.config/awesome/themes/lanxu/icons/vol_no.png and /dev/null differ diff --git a/.config/awesome/themes/lanxu/icons/wall-clock.png b/.config/awesome/themes/lanxu/icons/wall-clock.png new file mode 100644 index 0000000..6b262ad Binary files /dev/null and b/.config/awesome/themes/lanxu/icons/wall-clock.png differ diff --git a/.config/awesome/themes/lanxu/titlebar/minimize_focus.png b/.config/awesome/themes/lanxu/titlebar/minimize_focus.png new file mode 100644 index 0000000..ff427b3 Binary files /dev/null and b/.config/awesome/themes/lanxu/titlebar/minimize_focus.png differ diff --git a/.config/awesome/themes/lanxu/titlebar/minimize_normal.png b/.config/awesome/themes/lanxu/titlebar/minimize_normal.png new file mode 100644 index 0000000..aa47447 Binary files /dev/null and b/.config/awesome/themes/lanxu/titlebar/minimize_normal.png differ diff --git a/.config/awesome/widgets.lua b/.config/awesome/widgets.lua index 6532dc4..e05f882 100644 --- a/.config/awesome/widgets.lua +++ b/.config/awesome/widgets.lua @@ -5,10 +5,16 @@ local lain = require("lain") local vicious = require("vicious") -- Custom local beautiful = require("beautiful") -- CPU temp local wibox = require("wibox") +local gears = require("gears") -- Variables local valuecolor = "white" +icons_dir = os.getenv("HOME") .. "/.config/awesome/themes/lanxu/icons/" +cpuicon = wibox.widget.imagebox() +cpuicon.image = icons_dir .. "cpu.png" +cpuicon.resize = false + -- Helpers function file_exists(name) local f = io.open(name,"r") @@ -39,8 +45,18 @@ mymem = lain.widget.mem({ }) -- GPU -mygputemp = wibox.widget.textbox() -vicious.register(mygputemp, gputemp, create_markup("GPU", "$0", "℃", valuecolor), 15, "AMD") +mygputemp_text = wibox.widget.textbox() +mygputemp_text.align = "center" +vicious.register(mygputemp_text, gputemp, +function(widget, args) + temp = string.format("%.0f", tonumber(args[0])) + return create_markup("", temp, "℃", valuecolor) +end, 15, "AMD") +mygputemp = wibox.container.background() +mygputemp.forced_width = 70 +mygputemp:set_widget(mygputemp_text) +--mytextclock:set_shape(gears.shape.hexagon) +mygputemp:set_bg('#5e35b1') -- Hubic myhubic = wibox.widget.textbox() @@ -62,27 +78,40 @@ volume = lain.widget.pulse({ }) -- Text clock -mytextclock = wibox.widget.textclock(create_markup("Date","%Y-%m-%d %H:%M","", valuecolor)) - -lain.widget.calendar({ +mytextclock_text = wibox.widget.textclock(create_markup("","%Y-%m-%d %H:%M","", valuecolor)) +mytextclock_text.align = "center" +lain.widget.cal({ followtag = true, - attach_to = {mytextclock} + attach_to = {mytextclock_text}, + notification_preset = { + font = "Monospace 11", fg = "#FFFFFF", bg = "#000000" + } }) --- CPU temperature -local tempfile = "/sys/bus/pci/drivers/k10temp/0000:00:18.3/hwmon/hwmon2/temp1_input" +mytextclock = wibox.container.background() +mytextclock.forced_width = 130 +mytextclock:set_widget(mytextclock_text) +mytextclock:set_bg('#512da8') +-- CPU temperature +local tempfile = "/sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon1/temp1_input" if file_exists(tempfile) == false then tempfile = "/sys/class/thermal/thermal_zone0/temp" end -mycputemp = lain.widget.temp({ +mycputemp_text = lain.widget.temp({ tempfile = tempfile, settings = function() - widget.markup = create_markup("CPU", coretemp_now, "℃", valuecolor) + temp = string.format("%.0f", tonumber(coretemp_now)) + widget.markup = create_markup("", temp, "℃", valuecolor) end }) +mycputemp_text.widget.align = "center" +mycputemp = wibox.container.background() +mycputemp.forced_width = 70 +mycputemp:set_widget(mycputemp_text.widget) +mycputemp:set_bg('#9575cd') -- Weather Widget myweather = lain.widget.weather({ city_id = 634963, @@ -90,11 +119,19 @@ myweather = lain.widget.weather({ followtag = true, settings = function() widget.markup = create_markup("Tampere", weather_now.main.temp, "℃", valuecolor) - end + end, + notification_preset = { + font = "Monospace 11", fg = "#FFFFFF", bg = "#000000" + } }) -- DPMS mydpmsstatus = wibox.widget.textbox() +-- mydpmsstatus.container.background.bg = '#ff0000' +--mydpmsstatus = { +-- widget = wibox.widget.textbox +--} + vicious.register(mydpmsstatus, dpmsstatus, function(widget, args) color = valuecolor if args[0] == "Enabled" then @@ -109,21 +146,21 @@ local notification = { font = "Monospace 10" } -- Servers -local mcstatus = require("lanxu/mcstatus") -myserverstatus = mcstatus({ - notification_preset = notification, - settings = function() - widget.markup = create_markup("PLAYERS", totalplayers, "", valuecolor) - end -}) +--local mcstatus = require("lanxu/mcstatus") +--myserverstatus = mcstatus({ + --notification_preset = notification, + --settings = function() + --widget.markup = create_markup("PLAYERS", totalplayers, "", valuecolor) + --end +--}) -local cloudstatus = require("lanxu/cloudstatus") -mycloudstatus = cloudstatus({ - notification_preset = notification, - settings = function() - widget.markup = create_markup("CLOUD", currentstatus, "", valuecolor) - end -}) +--local cloudstatus = require("lanxu/cloudstatus") +--mycloudstatus = cloudstatus({ + --notification_preset = notification, + --settings = function() + --widget.markup = create_markup("CLOUD", currentstatus, "", valuecolor) + --end +--}) local ip = require("lanxu/ip") ipaddress = ip({ @@ -132,3 +169,4 @@ ipaddress = ip({ widget.markup = create_markup("IP", address, "", valuecolor) end }) + diff --git a/.config/compton/compton.conf b/.config/compton/compton.conf new file mode 100644 index 0000000..6dbb71e --- /dev/null +++ b/.config/compton/compton.conf @@ -0,0 +1,9 @@ +# menu = { shadow = false; }; +dropdown_menu = { shadow = false; }; +popup_menu = { shadow = false; }; +utility = { shadow = false; }; + +opacity-rule = [ + "95:class_g = 'kitty' && focused", + "80:class_g = 'kitty' && !focused" +]; diff --git a/.config/dunst/dunstrc b/.config/dunst/dunstrc new file mode 100644 index 0000000..53a1ba3 --- /dev/null +++ b/.config/dunst/dunstrc @@ -0,0 +1,422 @@ +[global] + ### Display ### + + # Which monitor should the notifications be displayed on. + monitor = 0 + + # Display notification on focused monitor. Possible modes are: + # mouse: follow mouse pointer + # keyboard: follow window with keyboard focus + # none: don't follow anything + # + # "keyboard" needs a window manager that exports the + # _NET_ACTIVE_WINDOW property. + # This should be the case for almost all modern window managers. + # + # If this option is set to mouse or keyboard, the monitor option + # will be ignored. + follow = mouse + + # The geometry of the window: + # [{width}]x{height}[+/-{x}+/-{y}] + # The geometry of the message window. + # The height is measured in number of notifications everything else + # in pixels. If the width is omitted but the height is given + # ("-geometry x2"), the message window expands over the whole screen + # (dmenu-like). If width is 0, the window expands to the longest + # message displayed. A positive x is measured from the left, a + # negative from the right side of the screen. Y is measured from + # the top and down respectively. + # The width can be negative. In this case the actual width is the + # screen width minus the width defined in within the geometry option. + geometry = "300x5-30+20" + + # Show how many messages are currently hidden (because of geometry). + indicate_hidden = yes + + # Shrink window if it's smaller than the width. Will be ignored if + # width is 0. + shrink = no + + # The transparency of the window. Range: [0; 100]. + # This option will only work if a compositing window manager is + # present (e.g. xcompmgr, compiz, etc.). + transparency = 5 + + # The height of the entire notification. If the height is smaller + # than the font height and padding combined, it will be raised + # to the font height and padding. + notification_height = 0 + + # Draw a line of "separator_height" pixel height between two + # notifications. + # Set to 0 to disable. + separator_height = 2 + + # Padding between text and separator. + padding = 10 + + # Horizontal padding. + horizontal_padding = 8 + + # Defines width in pixels of frame around the notification window. + # Set to 0 to disable. + frame_width = 3 + + # Defines color of the frame around the notification window. + #frame_color = "#aaaaaa" + frame_color = foreground + + # Define a color for the separator. + # possible values are: + # * auto: dunst tries to find a color fitting to the background; + # * foreground: use the same color as the foreground; + # * frame: use the same color as the frame; + # * anything else will be interpreted as a X color. + separator_color = frame + + # Sort messages by urgency. + sort = yes + + # Don't remove messages, if the user is idle (no mouse or keyboard input) + # for longer than idle_threshold seconds. + # Set to 0 to disable. + # A client can set the 'transient' hint to bypass this. See the rules + # section for how to disable this if necessary + idle_threshold = 120 + + ### Text ### + + font = Monospace 10 + + # The spacing between lines. If the height is smaller than the + # font height, it will get raised to the font height. + line_height = 0 + + # Possible values are: + # full: Allow a small subset of html markup in notifications: + # bold + # italic + # strikethrough + # underline + # + # For a complete reference see + # . + # + # strip: This setting is provided for compatibility with some broken + # clients that send markup even though it's not enabled on the + # server. Dunst will try to strip the markup but the parsing is + # simplistic so using this option outside of matching rules for + # specific applications *IS GREATLY DISCOURAGED*. + # + # no: Disable markup parsing, incoming notifications will be treated as + # plain text. Dunst will not advertise that it has the body-markup + # capability if this is set as a global setting. + # + # It's important to note that markup inside the format option will be parsed + # regardless of what this is set to. + markup = full + + # The format of the message. Possible variables are: + # %a appname + # %s summary + # %b body + # %i iconname (including its path) + # %I iconname (without its path) + # %p progress value if set ([ 0%] to [100%]) or nothing + # %n progress value if set without any extra characters + # %% Literal % + # Markup is allowed + format = "%s\n%b" + + # Alignment of message text. + # Possible values are "left", "center" and "right". + alignment = left + + # Show age of message if message is older than show_age_threshold + # seconds. + # Set to -1 to disable. + show_age_threshold = 60 + + # Split notifications into multiple lines if they don't fit into + # geometry. + word_wrap = yes + + # When word_wrap is set to no, specify where to make an ellipsis in long lines. + # Possible values are "start", "middle" and "end". + ellipsize = middle + + # Ignore newlines '\n' in notifications. + ignore_newline = no + + # Stack together notifications with the same content + stack_duplicates = true + + # Hide the count of stacked notifications with the same content + hide_duplicate_count = false + + # Display indicators for URLs (U) and actions (A). + show_indicators = yes + + ### Icons ### + + # Align icons left/right/off + icon_position = left + + # Scale larger icons down to this size, set to 0 to disable + max_icon_size = 32 + + # Paths to default icons. + icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/ + + ### History ### + + # Should a notification popped up from history be sticky or timeout + # as if it would normally do. + sticky_history = yes + + # Maximum amount of notifications kept in history + history_length = 20 + + ### Misc/Advanced ### + + # dmenu path. + dmenu = /usr/bin/rofi -p dunst: + + # Browser for opening urls in context menu. + browser = /usr/bin/firefox -new-tab + + # Always run rule-defined scripts, even if the notification is suppressed + always_run_script = true + + # Define the title of the windows spawned by dunst + title = Dunst + + # Define the class of the windows spawned by dunst + class = Dunst + + # Print a notification on startup. + # This is mainly for error detection, since dbus (re-)starts dunst + # automatically after a crash. + startup_notification = false + + # Manage dunst's desire for talking + # Can be one of the following values: + # crit: Critical features. Dunst aborts + # warn: Only non-fatal warnings + # mesg: Important Messages + # info: all unimportant stuff + # debug: all less than unimportant stuff + verbosity = mesg + + # Define the corner radius of the notification window + # in pixel size. If the radius is 0, you have no rounded + # corners. + # The radius will be automatically lowered if it exceeds half of the + # notification height to avoid clipping text and/or icons. + corner_radius = 0 + + ### Legacy + + # Use the Xinerama extension instead of RandR for multi-monitor support. + # This setting is provided for compatibility with older nVidia drivers that + # do not support RandR and using it on systems that support RandR is highly + # discouraged. + # + # By enabling this setting dunst will not be able to detect when a monitor + # is connected or disconnected which might break follow mode if the screen + # layout changes. + force_xinerama = false + + ### mouse + + # Defines action of mouse event + # Possible values are: + # * none: Don't do anything. + # * do_action: If the notification has exactly one action, or one is marked as default, + # invoke it. If there are multiple and no default, open the context menu. + # * close_current: Close current notification. + # * close_all: Close all notifications. + mouse_left_click = close_current + mouse_middle_click = do_action + mouse_right_click = close_all + +# Experimental features that may or may not work correctly. Do not expect them +# to have a consistent behaviour across releases. +[experimental] + # Calculate the dpi to use on a per-monitor basis. + # If this setting is enabled the Xft.dpi value will be ignored and instead + # dunst will attempt to calculate an appropriate dpi value for each monitor + # using the resolution and physical size. This might be useful in setups + # where there are multiple screens with very different dpi values. + per_monitor_dpi = false + +[shortcuts] + + # Shortcuts are specified as [modifier+][modifier+]...key + # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2", + # "mod3" and "mod4" (windows-key). + # Xev might be helpful to find names for keys. + + # Close notification. + close = ctrl+space + + # Close all notifications. + close_all = ctrl+shift+space + + # Redisplay last message(s). + # On the US keyboard layout "grave" is normally above TAB and left + # of "1". Make sure this key actually exists on your keyboard layout, + # e.g. check output of 'xmodmap -pke' + history = ctrl+grave + + # Context menu. + context = ctrl+shift+period + +[urgency_low] + # IMPORTANT: colors have to be defined in quotation marks. + # Otherwise the "#" and following would be interpreted as a comment. + # background = "#222222" + # foreground = "#888888" + background = "#fdf6e3" + foreground = "#93a1a1" + frame_color = "#93a1a1" + timeout = 10 + # Icon for notifications with low urgency, uncomment to enable + #icon = /path/to/icon + +[urgency_normal] + background = "#fdf6e3" + foreground = "#002b36" + frame_color = "#002b36" + timeout = 10 + # Icon for notifications with normal urgency, uncomment to enable + #icon = /path/to/icon + +[urgency_critical] + #background = "#900000" + #foreground = "#ffffff" + #frame_color = "#ff0000" + background = "#dc322f" + foreground = "#eee8d5" + frame_color = "#cb4b16" + timeout = 0 + # Icon for notifications with critical urgency, uncomment to enable + #icon = /path/to/icon + +# Every section that isn't one of the above is interpreted as a rules to +# override settings for certain messages. +# +# Messages can be matched by +# appname (discouraged, see desktop_entry) +# body +# category +# desktop_entry +# icon +# match_transient +# msg_urgency +# stack_tag +# summary +# +# and you can override the +# background +# foreground +# format +# frame_color +# fullscreen +# new_icon +# set_stack_tag +# set_transient +# timeout +# urgency +# +# Shell-like globbing will get expanded. +# +# Instead of the appname filter, it's recommended to use the desktop_entry filter. +# GLib based applications export their desktop-entry name. In comparison to the appname, +# the desktop-entry won't get localized. +# +# SCRIPTING +# You can specify a script that gets run when the rule matches by +# setting the "script" option. +# The script will be called as follows: +# script appname summary body icon urgency +# where urgency can be "LOW", "NORMAL" or "CRITICAL". +# +# NOTE: if you don't want a notification to be displayed, set the format +# to "". +# NOTE: It might be helpful to run dunst -print in a terminal in order +# to find fitting options for rules. + +# Disable the transient hint so that idle_threshold cannot be bypassed from the +# client +#[transient_disable] +# match_transient = yes +# set_transient = no +# +# Make the handling of transient notifications more strict by making them not +# be placed in history. +#[transient_history_ignore] +# match_transient = yes +# history_ignore = yes + +# fullscreen values +# show: show the notifications, regardless if there is a fullscreen window opened +# delay: displays the new notification, if there is no fullscreen window active +# If the notification is already drawn, it won't get undrawn. +# pushback: same as delay, but when switching into fullscreen, the notification will get +# withdrawn from screen again and will get delayed like a new notification +#[fullscreen_delay_everything] +# fullscreen = delay +#[fullscreen_show_critical] +# msg_urgency = critical +# fullscreen = show + +#[espeak] +# summary = "*" +# script = dunst_espeak.sh + +#[script-test] +# summary = "*script*" +# script = dunst_test.sh + +#[ignore] +# # This notification will not be displayed +# summary = "foobar" +# format = "" + +#[history-ignore] +# # This notification will not be saved in history +# summary = "foobar" +# history_ignore = yes + +#[skip-display] +# # This notification will not be displayed, but will be included in the history +# summary = "foobar" +# skip_display = yes + +#[signed_on] +# appname = Pidgin +# summary = "*signed on*" +# urgency = low +# +#[signed_off] +# appname = Pidgin +# summary = *signed off* +# urgency = low +# +#[says] +# appname = Pidgin +# summary = *says* +# urgency = critical +# +#[twitter] +# appname = Pidgin +# summary = *twitter.com* +# urgency = normal +# +#[stack-volumes] +# appname = "some_volume_notifiers" +# set_stack_tag = "volume" +# +# vim: ft=cfg diff --git a/.config/fontconfig/avail/01-noto.conf b/.config/fontconfig/avail/01-noto.conf new file mode 100644 index 0000000..84c8b03 --- /dev/null +++ b/.config/fontconfig/avail/01-noto.conf @@ -0,0 +1,112 @@ + + + + + Bitstream Vera Serif + + + + Bitstream Vera Serif + + + + serif + + + + + + + serif + + + + Bitstream Vera Serif + + + + Noto Color Emoji + + + + + + + Bitstream Vera Sans + + + + Bitstream Vera Sans + + + + sans-serif + + + + + + + sans-serif + + + + Bitstream Vera Sans + + + + Noto Color Emoji + + + + + + + Bitstream Vera Sans Mono + + + + Bitstream Vera Sans Mono + + + + monospace + + + + + + + monospace + + + + Bitstream Vera Sans Mono + + + + Noto Color Emoji + + + + + + emoji + Noto Color Emoji + + + + + Apple Color Emoji + Noto Color Emoji + sans-serif + + + Segoe UI Emoji + Noto Color Emoji + sans-serif + + diff --git a/.config/fontconfig/conf.d/10-autohint.conf b/.config/fontconfig/conf.d/10-autohint.conf new file mode 120000 index 0000000..a17cc75 --- /dev/null +++ b/.config/fontconfig/conf.d/10-autohint.conf @@ -0,0 +1 @@ +/etc/fonts/conf.avail/10-autohint.conf \ No newline at end of file diff --git a/.config/fontconfig/conf.d/10-sub-pixel-rgb.conf b/.config/fontconfig/conf.d/10-sub-pixel-rgb.conf new file mode 120000 index 0000000..c90d3b7 --- /dev/null +++ b/.config/fontconfig/conf.d/10-sub-pixel-rgb.conf @@ -0,0 +1 @@ +/etc/fonts/conf.avail/10-sub-pixel-rgb.conf \ No newline at end of file diff --git a/.config/fontconfig/conf.d/11-lcdfilter-default.conf b/.config/fontconfig/conf.d/11-lcdfilter-default.conf new file mode 120000 index 0000000..07413bc --- /dev/null +++ b/.config/fontconfig/conf.d/11-lcdfilter-default.conf @@ -0,0 +1 @@ +/etc/fonts/conf.avail/11-lcdfilter-default.conf \ No newline at end of file diff --git a/.config/fontconfig/conf.d/30-win32-aliases.conf b/.config/fontconfig/conf.d/30-win32-aliases.conf new file mode 120000 index 0000000..af14b6c --- /dev/null +++ b/.config/fontconfig/conf.d/30-win32-aliases.conf @@ -0,0 +1 @@ +/etc/fonts/conf.avail/30-win32-aliases.conf \ No newline at end of file diff --git a/.config/fontconfig/conf.d/70-no-bitmaps.conf b/.config/fontconfig/conf.d/70-no-bitmaps.conf new file mode 120000 index 0000000..d6c7fc1 --- /dev/null +++ b/.config/fontconfig/conf.d/70-no-bitmaps.conf @@ -0,0 +1 @@ +/etc/fonts/conf.avail/70-no-bitmaps.conf \ No newline at end of file diff --git a/.config/fontconfig/fonts.conf b/.config/fontconfig/fonts.conf new file mode 100644 index 0000000..402ad78 --- /dev/null +++ b/.config/fontconfig/fonts.conf @@ -0,0 +1,32 @@ + + + + + true + true + lcddefault + hintnone + + + rgb + + + + 15 + hintnone + lcdlight + + + + 12 + medium + hintnone + lcdlight + + + + 0 + hintnone + lcdlight + + diff --git a/.config/gallery-dl/config.json b/.config/gallery-dl/config.json new file mode 100644 index 0000000..42ea904 --- /dev/null +++ b/.config/gallery-dl/config.json @@ -0,0 +1,49 @@ +{ + "extractor": { + "base-directory": "~/Lataukset/gallery-dl/", + "archive": "~/Lataukset/gallery-dl/archive.sqlite3", + "exhentai": + { + "filename": "{num:>04}_{name}.{extension}", + "directory": ["{category!c}", "{title}"], + "postprocessors": [ + { + "name": "zip", + "compression": "store", + "extension": "cbz" + } + ], + "wait-min": 1.0, + "wait-max": 5.0 + } + }, + "downloader": { + "part-directory": "/tmp/.download/", + "rate": "1M", + "retries": 3, + "timeout": 8.5 + }, + "output": + { + "mode": "terminal", + "log": { + "format": "{name}: {message}", + "level": "info" + }, + "logfile": { + "path": "~/Lataukset/gallery-dl/log.txt", + "mode": "w", + "level": "debug" + }, + "unsupportedfile": { + "path": "~/Lataukset/gallery-dl/unsupported.txt", + "mode": "a", + "format": "{asctime} {message}", + "format-date": "%Y-%m-%d-%H-%M-%S" + } + }, + + "cache": { + "file": "~/Lataukset/gallery-dl/cache.sqlite3" + } +} diff --git a/.config/i3/background.png b/.config/i3/background.png new file mode 100644 index 0000000..28d5059 Binary files /dev/null and b/.config/i3/background.png differ diff --git a/.config/i3/config b/.config/i3/config new file mode 100644 index 0000000..df8be57 --- /dev/null +++ b/.config/i3/config @@ -0,0 +1,305 @@ +# i3 config file (v4) +# +# Please see https://i3wm.org/docs/userguide.html for a complete reference! +# +# This config file uses keycodes (bindsym) and was written for the QWERTY +# layout. +# +# To get a config file with the same key positions, but for your current +# layout, use the i3-config-wizard +# + +# Font for window titles. Will also be used by the bar unless a different font +# is used in the bar {} block below. +font pango:DejaVu Sans Mono 11 + +default_border pixel 1 +for_window [class=".*"] border pixel 0 + +# This font is widely installed, provides lots of unicode glyphs, right-to-left +# text rendering and scalability on retina/hidpi displays (thanks to pango). +#font pango:DejaVu Sans Mono 8 + +# The combination of xss-lock, nm-applet and pactl is a popular choice, so +# they are included here as an example. Modify as you see fit. + +# xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the +# screen before suspend. Use loginctl lock-session to lock your screen. +#exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork + +# NetworkManager is the most popular way to manage wireless networks on Linux, +# and nm-applet is a desktop environment-independent system tray GUI for it. +#exec --no-startup-id "dunst" # in case multiple daemons are installed + +#exec --no-startup-id "nm-applet" +#exec --no-startup-id "pasystray" +#exec --no-startup-id "blueman-applet" +#exec --no-startup-id "udiskie --tray --notify --automount" + +# Services +exec --no-startup-id "mpd /home/lanxu/.config/mpd/mpd.conf" # Music Player Daemon +exec --no-startup-id "xscreensaver -no-splash" # Screensaver +exec --no-startup-id "./Scripts/xscreensaverstopper.sh" # Screensaver inhibitor +exec --no-startup-id "compton -b" # Compositor +exec --no-startup-id "nitrogen --restore" # Wallpaper + +# Applications +exec --no-startup-id "nextcloud --background" +exec --no-startup-id "telegram-desktop" +exec --no-startup-id "cantata" + +set $refresh_i3status killall -SIGUSR1 i3status +bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +10% && $refresh_i3status +bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status +bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status +bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status +bindsym XF86AudioStop exec --no-startup-id mpc stop +bindsym XF86AudioPlay exec --no-startup-id mpc play +bindsym XF86AudioPause exec --no-startup-id mpc pause +bindsym XF86AudioNext exec --no-startup-id mpc next +bindsym XF86AudioPrev exec --no-startup-id mpc prev + +# Print screen +bindsym Print exec --no-startup-id flameshot gui +# use these keys for focus, movement, and resize directions when reaching for +# the arrows is not convenient +set $up l +set $down k +set $left j +set $right semicolon + +# use Mouse+Mod4 to drag floating windows to their wanted position +floating_modifier Mod4 + +# start a terminal +bindsym Mod4+Return exec i3-sensible-terminal + +# kill focused window +bindsym Mod4+Shift+q kill + +# start dmenu (a program launcher) +bindsym Mod4+d exec --no-startup-id "rofi -theme Arc -modi power:'/home/lanxu/.config/rofi/scripts/powermenu.sh',combi -combi-modi 'window,power,run,ssh' -show combi" +bindsym Mod4+F12 exec --no-startup-id "xscreensaver-command -lock" +# There also is the (new) i3-dmenu-desktop which only displays applications +# shipping a .desktop file. It is a wrapper around dmenu, so you need that +# installed. +# bindsym Mod4+d exec --no-startup-id i3-dmenu-desktop + +# change focus +bindsym Mod4+$left focus left +bindsym Mod4+$down focus down +bindsym Mod4+$up focus up +bindsym Mod4+$right focus right + +# alternatively, you can use the cursor keys: +bindsym Mod4+Left focus left +bindsym Mod4+Down focus down +bindsym Mod4+Up focus up +bindsym Mod4+Right focus right + +# move focused window +bindsym Mod4+Shift+$left move left +bindsym Mod4+Shift+$down move down +bindsym Mod4+Shift+$up move up +bindsym Mod4+Shift+$right move right + +# alternatively, you can use the cursor keys: +bindsym Mod4+Shift+Left move left +bindsym Mod4+Shift+Down move down +bindsym Mod4+Shift+Up move up +bindsym Mod4+Shift+Right move right + +# split in horizontal orientation +bindsym Mod4+h split h + +# split in vertical orientation +bindsym Mod4+v split v + +# enter fullscreen mode for the focused container +bindsym Mod4+f fullscreen toggle + +# change container layout (stacked, tabbed, toggle split) +bindsym Mod4+s layout stacking +bindsym Mod4+w layout tabbed +bindsym Mod4+e layout toggle split + +# toggle tiling / floating +bindsym Mod4+Shift+space floating toggle + +# change focus between tiling / floating windows +bindsym Mod4+space focus mode_toggle + +# focus the parent container +bindsym Mod4+a focus parent + +# focus the child container +#bindsym Mod4+d focus child + +# move the currently focused window to the scratchpad +bindsym Mod4+Shift+minus move scratchpad + +# Show the next scratchpad window or hide the focused scratchpad window. +# If there are multiple scratchpad windows, this command cycles through them. +bindsym Mod4+minus scratchpad show + +# Define names for default workspaces for which we configure key bindings later on. +# We use variables to avoid repeating the names in multiple places. +set $ws1 "1:term" +set $ws2 "2:irc" +set $ws3 "3:net" +set $ws4 "4:gfx" +set $ws5 "5:steam" +set $ws6 "6:lutris" +set $ws7 "7" +set $ws8 "8" +set $ws9 "9" +set $ws10 "10" + +# switch to workspace +bindsym Mod4+1 workspace $ws1 +bindsym Mod4+2 workspace $ws2 +bindsym Mod4+3 workspace $ws3 +bindsym Mod4+4 workspace $ws4 +bindsym Mod4+5 workspace $ws5 +bindsym Mod4+6 workspace $ws6 +bindsym Mod4+7 workspace $ws7 +bindsym Mod4+8 workspace $ws8 +bindsym Mod4+9 workspace $ws9 +bindsym Mod4+0 workspace $ws10 + +# move focused container to workspace +bindsym Mod4+Shift+1 move container to workspace $ws1 +bindsym Mod4+Shift+2 move container to workspace $ws2 +bindsym Mod4+Shift+3 move container to workspace $ws3 +bindsym Mod4+Shift+4 move container to workspace $ws4 +bindsym Mod4+Shift+5 move container to workspace $ws5 +bindsym Mod4+Shift+6 move container to workspace $ws6 +bindsym Mod4+Shift+7 move container to workspace $ws7 +bindsym Mod4+Shift+8 move container to workspace $ws8 +bindsym Mod4+Shift+9 move container to workspace $ws9 +bindsym Mod4+Shift+0 move container to workspace $ws10 + +# reload the configuration file +bindsym Mod4+Shift+c reload +# restart i3 inplace (preserves your layout/session, can be used to upgrade i3) +bindsym Mod4+Shift+r restart +# exit i3 (logs you out of your X session) +bindsym Mod4+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'" + +# resize window (you can also use the mouse for that) +mode "resize" { +# These bindings trigger as soon as you enter the resize mode + +# Pressing left will shrink the window’s width. +# Pressing right will grow the window’s width. +# Pressing up will shrink the window’s height. +# Pressing down will grow the window’s height. + bindsym $left resize shrink width 10 px or 10 ppt + bindsym $down resize grow height 10 px or 10 ppt + bindsym $up resize shrink height 10 px or 10 ppt + bindsym $right resize grow width 10 px or 10 ppt + +# same bindings, but for the arrow keys + bindsym Left resize shrink width 10 px or 10 ppt + bindsym Down resize grow height 10 px or 10 ppt + bindsym Up resize shrink height 10 px or 10 ppt + bindsym Right resize grow width 10 px or 10 ppt + +# back to normal: Enter or Escape or Mod4+r + bindsym Return mode "default" + bindsym Escape mode "default" + bindsym Mod4+r mode "default" +} + +bindsym Mod4+r mode "resize" + +bindsym Mod4+o move workspace to output left +####################################################################### +# automatically start i3-config-wizard to offer the user to create a +# keysym-based config which used their favorite modifier (alt or windows) +# + +# in ~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set) or +# ~/.i3/config. +# +# Please remove the following exec line: +####################################################################### +#exec i3-config-wizard +for_window [class="Arandr"] floating enable +for_window [class="cantata"] floating enable, move scratchpad +for_window [class="TelegramDesktop"] floating enable, move scratchpad +for_window [class="itch"] floating enable +# for_window [class="Wine"] floating enable +for_window [class="mpv"] floating enabler, move position center +for_window [class="vlc"] floating enable +for_window [class="Sxiv"] floating enable +for_window [class="Steam"] move container to workspace $ws5 +for_window [title="Steam"] move container to workspace $ws5 +for_window [title="Friends List"] move container to workspace $ws5, resize set width 400px +for_window [class="Lutris"] move container to workspace $ws6 +for_window [class="Gimp"] move container to workspace $ws4 +for_window [class="Blender"] move container to workspace $ws4 +for_window [class="firefox"] move container to workspace $ws3 + +mouse_warping none + +# gaps +smart_borders on +smart_gaps on +gaps outer 0 +gaps inner 10 + +## Base16 Solarized Light +# Author: Ethan Schoonover (modified by aramisgithub) +# +# You can use these variables anywhere in the i3 configuration file. + +set $base00 #fdf6e3 +set $base01 #eee8d5 +set $base02 #93a1a1 +set $base03 #839496 +set $base04 #657b83 +set $base05 #586e75 +set $base06 #073642 +set $base07 #002b36 +set $base08 #dc322f +set $base09 #cb4b16 +set $base0A #b58900 +set $base0B #859900 +set $base0C #2aa198 +set $base0D #268bd2 +set $base0E #6c71c4 +set $base0F #d33682 + +# Basic bar configuration using the Base16 variables. +bar { + font pango: DejaVu Sans Mono Bold 11 + mode dock + status_command py3status + position top + i3bar_command i3bar -t + tray_output none + separator_symbol ❰ + + colors { + background $base00 + separator $base03 + statusline $base04 + + # State Border BG Text + focused_workspace $base05 $base0D $base00 + active_workspace $base05 $base03 $base00 + inactive_workspace $base03 $base01 $base05 + urgent_workspace $base08 $base08 $base00 + binding_mode $base00 $base0A $base00 + } +} + +# Basic color configuration using the Base16 variables for windows and borders. +# Property Name Border BG Text Indicator Child Border +client.focused $base05 $base0D $base00 $base0D $base0C +client.focused_inactive $base01 $base01 $base05 $base03 $base01 +client.unfocused $base01 $base00 $base05 $base01 $base01 +client.urgent $base08 $base08 $base00 $base08 $base08 +client.placeholder $base00 $base00 $base05 $base00 $base00 +client.background $base07 diff --git a/.config/i3/i3status.conf b/.config/i3/i3status.conf new file mode 100644 index 0000000..d8c9f59 --- /dev/null +++ b/.config/i3/i3status.conf @@ -0,0 +1,47 @@ +general { + # These will be used if not supplied by a module + # Solarized + color = '#073642' + color_good = '#859900' + color_degraded = '#b58900' + color_bad = '#dc322f' +} +py3status { + align = 'center' + markup = 'pango' + min_width = 50 + separator = True + separator_block_width = 20 + # border = '#4c7899' + border = '#073642' + border_bottom = 0 + border_left = 0 + border_right = 0 + border_top = 0 +} + +time { + format = "%Y-%m-%d %H:%M " +} + +mpd_status { + format = "{name} [[[{artist} - ]{title}]|[{file}]]" +} + +volume_status { + command = "pactl" +} + +weather_owm { + api_key = "4e3b7bbd3da07052c4fed6d342e48707" + city = "Tampere" + unit_temperature = "C" + format = "{city} {icon} {temperature}" +} +order += "dpms" +order += "volume_status" +order += "sysdata" +order += "gpu_temp" +order += "weather_owm" +order += "mpd_status" +order += "time" diff --git a/.config/i3/py3status/gpu_temp.py b/.config/i3/py3status/gpu_temp.py new file mode 100644 index 0000000..eabb678 --- /dev/null +++ b/.config/i3/py3status/gpu_temp.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +""" +This module produces GPU temperature + +""" +import sys +sys.path.insert(1, '/home/lanxu/Scripts/') +from gputemp import get_temperature + +class Py3status: + format = 'GPU: {temp}℃' + thresholds = [ + (0, "good"), + (45, "degraded"), + (60, "bad") + ] + + def gpu_temp(self): + temp = float(get_temperature()) + + full_text = self.py3.safe_format(self.format, { 'temp': temp}) + color = self.py3.threshold_get_color(temp) + + return { + 'full_text': full_text, + 'color': color, + 'cached_until': self.py3.time_in(15) + } diff --git a/.config/kitty/kitty.conf b/.config/kitty/kitty.conf new file mode 100644 index 0000000..8b5e446 --- /dev/null +++ b/.config/kitty/kitty.conf @@ -0,0 +1,50 @@ +font_family Fira Mono Medium +bold_font Fira Mono Bold +italic_font Fira Mono Italic +bold_italic_font auto +font_size 11.0 +window_padding_width 10.0 +window_padding_height 10.0 + +# Base16 Solarized Light - kitty color config +# Scheme by Ethan Schoonover (modified by aramisgithub) +background #fdf6e3 +foreground #586e75 +selection_background #586e75 +selection_foreground #fdf6e3 +url_color #657b83 +cursor #586e75 +active_border_color #839496 +inactive_border_color #eee8d5 +active_tab_background #fdf6e3 +active_tab_foreground #586e75 +inactive_tab_background #eee8d5 +inactive_tab_foreground #657b83 + +# normal +color0 #fdf6e3 +color1 #dc322f +color2 #859900 +color3 #b58900 +color4 #268bd2 +color5 #6c71c4 +color6 #2aa198 +color7 #586e75 + +# bright +color8 #839496 +color9 #dc322f +color10 #859900 +color11 #b58900 +color12 #268bd2 +color13 #6c71c4 +color14 #2aa198 +color15 #586e75 + +# extended base16 colors +color16 #cb4b16 +color17 #d33682 +color18 #eee8d5 +color19 #93a1a1 +color20 #657b83 +color21 #073642 diff --git a/.config/mimeapps.list b/.config/mimeapps.list new file mode 100644 index 0000000..9eeef82 --- /dev/null +++ b/.config/mimeapps.list @@ -0,0 +1,32 @@ +[Default Applications] +application/vnd.comicbook+rar=mcomix.desktop +application/vnd.comicbook+zip=mcomix.desktop +application/vnd.rar=xarchiver.desktop +application/x-cbr=mcomix.desktop +application/x-cbz=mcomix.desktop +application/zip=xarchiver.desktop +application/epub+zip=mcomix.desktop; +application/octet-stream=gvim.desktop; +application/pdf=org.pwmt.zathura-pdf-mupdf.desktop; +application/pgp-signature=gvim.desktop; +application/vnd.ms-publisher=gvim.desktop; +application/vnd.rar=mcomix.desktop;xarchiver.desktop; +application/x-alz=xarchiver.desktop; +image/gif=sxiv_browser.desktop +image/jpeg=sxiv_browser.desktop +image/png=sxiv_browser.desktop +image/svg+xml=inkscape.desktop +inode/directory=ranger_terminal.desktop +video/mp4=mpv.desktop +video/quicktime=mpv.desktop +video/x-msvideo=mpv.desktop +video/x-flv=mpv.desktop +video/x-matroska=mpv.desktop +text/plain=gvim.desktop +x-scheme-handler/itchio=io.itch.itch.desktop +x-terminal-emulator=urxvt.desktop +x-scheme-handler/discord-378483863044882443=discord-378483863044882443.desktop +x-scheme-handler/http=firefox.desktop + +[Added Associations] +application/x-blender=blender.desktop; diff --git a/.config/nitrogen/bg-saved.cfg b/.config/nitrogen/bg-saved.cfg new file mode 100644 index 0000000..4825b11 --- /dev/null +++ b/.config/nitrogen/bg-saved.cfg @@ -0,0 +1,9 @@ +[xin_0] +file=/home/lanxu/.config/i3/background.png +mode=2 +bgcolor=#000000 + +[xin_1] +file=/home/lanxu/.config/i3/background.png +mode=2 +bgcolor=#000000 diff --git a/.config/nitrogen/nitrogen.cfg b/.config/nitrogen/nitrogen.cfg new file mode 100644 index 0000000..70ca314 --- /dev/null +++ b/.config/nitrogen/nitrogen.cfg @@ -0,0 +1,12 @@ +[geometry] +posx=616 +posy=19 +sizex=638 +sizey=1059 + +[nitrogen] +view=icon +recurse=true +sort=alpha +icon_caps=false +dirs= diff --git a/.config/ranger/rc.conf b/.config/ranger/rc.conf index dd8bc42..e6de18c 100644 --- a/.config/ranger/rc.conf +++ b/.config/ranger/rc.conf @@ -1,7 +1,8 @@ # =================================================================== # This file contains the default startup commands for ranger. -# To change them, it is recommended to create the file -# ~/.config/ranger/rc.conf and add your custom commands there. +# To change them, it is recommended to create either /etc/ranger/rc.conf +# (system-wide) or ~/.config/ranger/rc.conf (per user) and add your custom +# commands there. # # If you copy this whole file there, you may want to set the environment # variable RANGER_LOAD_DEFAULT_RC to FALSE to avoid loading it twice. @@ -67,7 +68,7 @@ set vcs_backend_bzr disabled set vcs_backend_svn disabled # Use one of the supported image preview protocols -set preview_images true +set preview_images false # Set the preview image method. Supported methods: # @@ -85,6 +86,10 @@ set preview_images true # width of 8 and height of 11 are used. To use other values, set the options # iterm2_font_width and iterm2_font_height to the desired values. # +# * terminology: +# Previews images in full color in the terminology terminal emulator. +# Supports a wide variety of formats, even vector graphics like svg. +# # * urxvt: # Preview images in full color using urxvt image backgrounds. This # requires using urxvt compiled with pixbuf support. @@ -92,7 +97,20 @@ set preview_images true # * urxvt-full: # The same as urxvt but utilizing not only the preview pane but the # whole terminal window. -set preview_images_method w3m +# +# * kitty: +# Preview images in full color using kitty image protocol. +# Requires python PIL or pillow library. +# If ranger does not share the local filesystem with kitty +# the transfer method is changed to encode the whole image; +# while slower, this allows remote previews, +# for example during an ssh session. +# Tmux is unsupported. +set preview_images_method kitty + +# Delay in seconds before displaying an image with the w3m method. +# Increase it in case of experiencing display corruption. +set w3m_delay 0.02 # Default iTerm2 font size (see: preview_images_method: iterm2) set iterm2_font_width 8 @@ -101,6 +119,10 @@ set iterm2_font_height 11 # Use a unicode "..." character to mark cut-off filenames? set unicode_ellipsis false +# BIDI support - try to properly display file names in RTL languages (Hebrew, Arabic). +# Requires the python-bidi pip package +set bidi_support false + # Show dotfiles in the bookmark preview box? set show_hidden_bookmarks true @@ -124,8 +146,11 @@ set status_bar_on_top false # currently running tasks which support progress bars? set draw_progress_bar_in_status_bar true -# Draw borders around columns? -set draw_borders false +# Draw borders around columns? (separators, outline, both, or none) +# Separators are vertical lines between columns. +# Outline draws a box around all the columns. +# Both combines the two. +set draw_borders none # Display the directory name in tabs? set dirname_in_tabs false @@ -137,6 +162,9 @@ set mouse_enabled true set display_size_in_main_column true set display_size_in_status_bar true +# Display the free disk space in the status bar? +set display_free_space_in_status_bar true + # Display files tags in all columns or only in main column? set display_tags_in_all_columns true @@ -144,7 +172,7 @@ set display_tags_in_all_columns true set update_title false # Set the title to "ranger" in the tmux program? -set update_tmux_title false +set update_tmux_title true # Shorten the title if it gets long? The number defines how many # directories are displayed at once, 0 turns off this feature. @@ -216,6 +244,10 @@ set cd_tab_fuzzy false # disable this feature. set preview_max_size 0 +# The key hint lists up to this size have their sublists expanded. +# Otherwise the submaps are replaced with "...". +set hint_collapse_threshold 10 + # Add the highlighted file to the path in the titlebar set show_selection_in_titlebar true @@ -232,9 +264,14 @@ set metadata_deep_search false # Clear all existing filters when leaving a directory set clear_filters_on_dir_change false -# Disable displaying line numbers in main column +# Disable displaying line numbers in main column. +# Possible values: false, absolute, relative. set line_numbers false +# When line_numbers=relative show the absolute line number in the +# current line. +set relative_current_zero false + # Start line numbers from 1 instead of 0 set one_indexed false @@ -249,6 +286,10 @@ set wrap_scroll false # directories, files and symlinks respectively. set global_inode_type_filter +# This setting allows to freeze the list of files to save I/O bandwidth. It +# should be 'false' during start-up, but you can toggle it by pressing F. +set freeze_files false + # =================================================================== # == Local Options # =================================================================== @@ -270,8 +311,8 @@ alias qall quitall alias qall! quitall! alias setl setlocal -alias filter scout -prt -alias find scout -aeit +alias filter scout -prts +alias find scout -aets alias mark scout -mr alias unmark scout -Mr alias search scout -rs @@ -311,6 +352,8 @@ map r chain draw_possible_programs; console open_with%%space map f console find%space map cd console cd%space +map chain console; eval fm.ui.console.history_move(-1) + # Change the line mode map Mf linemode filename map Mi linemode fileinfo @@ -374,6 +417,7 @@ map L history_go 1 map ] move_parent 1 map [ move_parent -1 map } traverse +map { traverse_backwards map ) jump_non map gh cd ~ @@ -385,9 +429,10 @@ map gL cd -r %f map go cd /opt map gv cd /var map gm cd /media +map gi eval fm.cd('/run/media/' + os.getenv('USER')) map gM cd /mnt map gs cd /srv -map gt cd /tmp +map gp cd /tmp map gr cd / map gR eval fm.cd(ranger.RANGERDIR) map g/ cd / @@ -400,6 +445,7 @@ map dU shell -p du --max-depth=1 -h --apparent-size | sort -rh map yp yank path map yd yank dir map yn yank name +map y. yank name_without_extension # Filesystem Operations map = chmod @@ -474,6 +520,8 @@ map tab_open 6 map tab_open 7 map tab_open 8 map tab_open 9 +map tab_shift 1 +map tab_shift -1 # Sorting map or set sort_reverse! @@ -503,6 +551,8 @@ map zc set collapse_preview! map zd set sort_directories_first! map zh set show_hidden! map set show_hidden! +copymap +copymap map zI set flushinput! map zi set preview_images! map zm set mouse_enabled! @@ -514,6 +564,21 @@ map zv set use_preview_script! map zf console filter%space copymap zf zz +# Filter stack +map .n console filter_stack add name%space +map .m console filter_stack add mime%space +map .d filter_stack add type d +map .f filter_stack add type f +map .l filter_stack add type l +map .| filter_stack add or +map .& filter_stack add and +map .! filter_stack add not +map .r console filter_stack rotate +map .c filter_stack clear +map .* filter_stack decompose +map .p filter_stack pop +map .. filter_stack show + # Bookmarks map ` enter_bookmark %any map ' enter_bookmark %any @@ -558,8 +623,11 @@ cmap eval fm.ui.console.move(left=1) cmap eval fm.ui.console.move(right=1) cmap eval fm.ui.console.move(right=0, absolute=True) cmap eval fm.ui.console.move(right=-1, absolute=True) -cmap eval fm.ui.console.move_word(left=1) -cmap eval fm.ui.console.move_word(right=1) +cmap eval fm.ui.console.move_word(left=1) +cmap eval fm.ui.console.move_word(right=1) + +copycmap +copycmap # Line Editing cmap eval fm.ui.console.delete(-1) @@ -571,6 +639,7 @@ cmap eval fm.ui.console.delete_rest(-1) cmap eval fm.ui.console.paste() # And of course the emacs way +copycmap copycmap copycmap copycmap diff --git a/.config/ranger/rifle.conf b/.config/ranger/rifle.conf index 5bc59f5..64bdea0 100644 --- a/.config/ranger/rifle.conf +++ b/.config/ranger/rifle.conf @@ -152,7 +152,7 @@ ext pdf, has atril, X, flag f = atril -- "$@" ext pdf, has okular, X, flag f = okular -- "$@" ext pdf, has epdfview, X, flag f = epdfview -- "$@" ext pdf, has qpdfview, X, flag f = qpdfview "$@" -ext pdf, has open, X, flat f = open "$@" +ext pdf, has open, X, flag f = open "$@" ext docx?, has catdoc, terminal = catdoc -- "$@" | "$PAGER" @@ -165,16 +165,18 @@ ext pptx?|od[dfgpst]|docx?|sxc|xlsx?|xlt|xlw|gnm|gnumeric, has ooffice, X, f ext djvu, has zathura,X, flag f = zathura -- "$@" ext djvu, has evince, X, flag f = evince -- "$@" ext djvu, has atril, X, flag f = atril -- "$@" +ext djvu, has djview, X, flag f = djview -- "$@" ext epub, has ebook-viewer, X, flag f = ebook-viewer -- "$@" ext mobi, has ebook-viewer, X, flag f = ebook-viewer -- "$@" #------------------------------------------- -# Image Viewing: +# Images #------------------------------------------- mime ^image/svg, has inkscape, X, flag f = inkscape -- "$@" mime ^image/svg, has display, X, flag f = display -- "$@" +mime ^image, has imv, X, flag f = imv -- "$@" mime ^image, has pqiv, X, flag f = pqiv -- "$@" mime ^image, has sxiv, X, flag f = sxiv -- "$@" mime ^image, has feh, X, flag f = feh -- "$@" @@ -183,6 +185,8 @@ mime ^image, has ristretto, X, flag f = ristretto "$@" mime ^image, has eog, X, flag f = eog -- "$@" mime ^image, has eom, X, flag f = eom -- "$@" mime ^image, has nomacs, X, flag f = nomacs -- "$@" +mime ^image, has geeqie, X, flag f = geeqie -- "$@" +mime ^image, has gwenview, X, flag f = gwenview -- "$@" mime ^image, has gimp, X, flag f = gimp -- "$@" ext xcf, X, flag f = gimp -- "$@" @@ -209,6 +213,39 @@ ext ace, has unace = for file in "$@"; do unace e "$file"; done ext rar, has unrar = unrar l "$1" | less ext rar, has unrar = for file in "$@"; do unrar x "$file"; done +#------------------------------------------- +# Fonts +#------------------------------------------- +mime ^font, has fontforge, X, flag f = fontforge "$@" + +#------------------------------------------- +# Flag t fallback terminals +#------------------------------------------- +# Rarely installed terminal emulators get higher priority; It is assumed that +# if you install a rare terminal emulator, you probably use it. +# gnome-terminal/konsole/xterm on the other hand are often installed as part of +# a desktop environment or as fallback terminal emulators. +mime ^ranger/x-terminal-emulator, has terminology = terminology -e "$@" +mime ^ranger/x-terminal-emulator, has kitty = kitty -- "$@" +mime ^ranger/x-terminal-emulator, has alacritty = alacritty -e "$@" +mime ^ranger/x-terminal-emulator, has sakura = sakura -e "$@" +mime ^ranger/x-terminal-emulator, has lilyterm = lilyterm -e "$@" +#mime ^ranger/x-terminal-emulator, has cool-retro-term = cool-retro-term -e "$@" +mime ^ranger/x-terminal-emulator, has termite = termite -x '"$@"' +#mime ^ranger/x-terminal-emulator, has yakuake = yakuake -e "$@" +mime ^ranger/x-terminal-emulator, has guake = guake -ne "$@" +mime ^ranger/x-terminal-emulator, has tilda = tilda -c "$@" +mime ^ranger/x-terminal-emulator, has st = st -e "$@" +mime ^ranger/x-terminal-emulator, has terminator = terminator -x "$@" +mime ^ranger/x-terminal-emulator, has urxvt = urxvt -e "$@" +mime ^ranger/x-terminal-emulator, has pantheon-terminal = pantheon-terminal -e "$@" +mime ^ranger/x-terminal-emulator, has lxterminal = lxterminal -e "$@" +mime ^ranger/x-terminal-emulator, has mate-terminal = mate-terminal -x "$@" +mime ^ranger/x-terminal-emulator, has xfce4-terminal = xfce4-terminal -x "$@" +mime ^ranger/x-terminal-emulator, has konsole = konsole -e "$@" +mime ^ranger/x-terminal-emulator, has gnome-terminal = gnome-terminal -- "$@" +mime ^ranger/x-terminal-emulator, has xterm = xterm -e "$@" + #------------------------------------------- # Misc #------------------------------------------- diff --git a/.config/ranger/scope.sh b/.config/ranger/scope.sh index 5af4370..998a3a2 100755 --- a/.config/ranger/scope.sh +++ b/.config/ranger/scope.sh @@ -31,13 +31,14 @@ IMAGE_CACHE_PATH="${4}" # Full path that should be used to cache image preview PV_IMAGE_ENABLED="${5}" # 'True' if image previews are enabled, 'False' otherwise. FILE_EXTENSION="${FILE_PATH##*.}" -FILE_EXTENSION_LOWER="${FILE_EXTENSION,,}" +FILE_EXTENSION_LOWER="$(printf "%s" "${FILE_EXTENSION}" | tr '[:upper:]' '[:lower:]')" # Settings HIGHLIGHT_SIZE_MAX=262143 # 256KiB -HIGHLIGHT_TABWIDTH=8 -HIGHLIGHT_STYLE='pablo' -PYGMENTIZE_STYLE='autumn' +HIGHLIGHT_TABWIDTH=${HIGHLIGHT_TABWIDTH:-8} +HIGHLIGHT_STYLE=${HIGHLIGHT_STYLE:-pablo} +HIGHLIGHT_OPTIONS="--replace-tabs=${HIGHLIGHT_TABWIDTH} --style=${HIGHLIGHT_STYLE} ${HIGHLIGHT_OPTIONS:-}" +PYGMENTIZE_STYLE=${PYGMENTIZE_STYLE:-autumn} handle_extension() { @@ -60,9 +61,10 @@ handle_extension() { # PDF #pdf) # # Preview as text conversion - # pdftotext -l 10 -nopgbrk -q -- "${FILE_PATH}" - && exit 5 + # pdftotext -l 10 -nopgbrk -q -- "${FILE_PATH}" - | fmt -w ${PV_WIDTH} && exit 5 + # mutool draw -F txt -i -- "${FILE_PATH}" 1-10 | fmt -w ${PV_WIDTH} && exit 5 # exiftool "${FILE_PATH}" && exit 5 - # exit 1;; + # exit 1;; # BitTorrent torrent) @@ -82,12 +84,22 @@ handle_extension() { lynx -dump -- "${FILE_PATH}" && exit 5 elinks -dump "${FILE_PATH}" && exit 5 ;; # Continue with next handler on failure + + # JSON + json) + jq --color-output . "${FILE_PATH}" && exit 5 + python -m json.tool -- "${FILE_PATH}" && exit 5 +;; esac } handle_image() { + # Size of the preview if there are multiple options or it has to be rendered + # from vector graphics. If the conversion program allows specifying only one + # dimension while keeping the aspect ratio, the width will be used. + local DEFAULT_SIZE="1920x1080" local mimetype="${1}" - + case "${FILE_EXTENSION_LOWER}" in # Comic book previews cbz|cbr|epub) @@ -97,10 +109,16 @@ handle_image() { case "${mimetype}" in # SVG - image/svg+xml) - convert "${FILE_PATH}" "${IMAGE_CACHE_PATH}" && exit 6 + image/svg+xml|image/svg) + convert -- "${FILE_PATH}" "${IMAGE_CACHE_PATH}" && exit 6 exit 1;; + # DjVu + # image/vnd.djvu) + # ddjvu -format=tiff -quality=90 -page=1 -size="${DEFAULT_SIZE}" \ + # - "${IMAGE_CACHE_PATH}" < "${FILE_PATH}" \ + # && exit 6 || exit 1;; + # Image image/*) local orientation @@ -121,16 +139,84 @@ handle_image() { # Thumbnail ffmpegthumbnailer -i "${FILE_PATH}" -o "${IMAGE_CACHE_PATH}" -s 0 && exit 6 exit 1;; - + # PDF application/pdf) pdftoppm -f 1 -l 1 \ - -scale-to-x 1920 \ + -scale-to-x "${DEFAULT_SIZE%x*}" \ -scale-to-y -1 \ -singlefile \ -jpeg -tiffcompression jpeg \ -- "${FILE_PATH}" "${IMAGE_CACHE_PATH%.*}" \ - && exit 6 || exit 1;; + && exit 6 || exit 1;; + # ePub, MOBI, FB2 (using Calibre) + # application/epub+zip|application/x-mobipocket-ebook|application/x-fictionbook+xml) + # ebook-meta --get-cover="${IMAGE_CACHE_PATH}" -- "${FILE_PATH}" > /dev/null \ + # && exit 6 || exit 1;; + + # ePub (using ) + # application/epub+zip) + # epub-thumbnailer \ + # "${FILE_PATH}" "${IMAGE_CACHE_PATH}" "${DEFAULT_SIZE%x*}" \ + # && exit 6 || exit 1;; + + # Font + application/font*|application/*opentype) + preview_png="/tmp/$(basename "${IMAGE_CACHE_PATH%.*}").png" + if fontimage -o "${preview_png}" \ + --pixelsize "120" \ + --fontname \ + --pixelsize "80" \ + --text " ABCDEFGHIJKLMNOPQRSTUVWXYZ " \ + --text " abcdefghijklmnopqrstuvwxyz " \ + --text " 0123456789.:,;(*!?') ff fl fi ffi ffl " \ + --text " The quick brown fox jumps over the lazy dog. " \ + "${FILE_PATH}"; + then + convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \ + && rm "${preview_png}" \ + && exit 6 + else + exit 1 + fi + ;; + + # Preview archives using the first image inside. + # (Very useful for comic book collections for example.) + # application/zip|application/x-rar|application/x-7z-compressed|\ + # application/x-xz|application/x-bzip2|application/x-gzip|application/x-tar) + # local fn=""; local fe="" + # local zip=""; local rar=""; local tar=""; local bsd="" + # case "${mimetype}" in + # application/zip) zip=1 ;; + # application/x-rar) rar=1 ;; + # application/x-7z-compressed) ;; + # *) tar=1 ;; + # esac + # { [ "$tar" ] && fn=$(tar --list --file "${FILE_PATH}"); } || \ + # { fn=$(bsdtar --list --file "${FILE_PATH}") && bsd=1 && tar=""; } || \ + # { [ "$rar" ] && fn=$(unrar lb -p- -- "${FILE_PATH}"); } || \ + # { [ "$zip" ] && fn=$(zipinfo -1 -- "${FILE_PATH}"); } || return + # + # fn=$(echo "$fn" | python -c "import sys; import mimetypes as m; \ + # [ print(l, end='') for l in sys.stdin if \ + # (m.guess_type(l[:-1])[0] or '').startswith('image/') ]" |\ + # sort -V | head -n 1) + # [ "$fn" = "" ] && return + # [ "$bsd" ] && fn=$(printf '%b' "$fn") + # + # [ "$tar" ] && tar --extract --to-stdout \ + # --file "${FILE_PATH}" -- "$fn" > "${IMAGE_CACHE_PATH}" && exit 6 + # fe=$(echo -n "$fn" | sed 's/[][*?\]/\\\0/g') + # [ "$bsd" ] && bsdtar --extract --to-stdout \ + # --file "${FILE_PATH}" -- "$fe" > "${IMAGE_CACHE_PATH}" && exit 6 + # [ "$bsd" ] || [ "$tar" ] && rm -- "${IMAGE_CACHE_PATH}" + # [ "$rar" ] && unrar p -p- -inul -- "${FILE_PATH}" "$fn" > \ + # "${IMAGE_CACHE_PATH}" && exit 6 + # [ "$zip" ] && unzip -pP "" -- "${FILE_PATH}" "$fe" > \ + # "${IMAGE_CACHE_PATH}" && exit 6 + # [ "$rar" ] || [ "$zip" ] && rm -- "${IMAGE_CACHE_PATH}" + # ;; esac } @@ -150,16 +236,25 @@ handle_mime() { local pygmentize_format='terminal' local highlight_format='ansi' fi - highlight --replace-tabs="${HIGHLIGHT_TABWIDTH}" --out-format="${highlight_format}" \ - --style="${HIGHLIGHT_STYLE}" --force -- "${FILE_PATH}" && exit 5 - # pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}" -- "${FILE_PATH}" && exit 5 + env HIGHLIGHT_OPTIONS="${HIGHLIGHT_OPTIONS}" highlight \ + --out-format="${highlight_format}" \ + --force -- "${FILE_PATH}" && exit 5 + pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}"\ + -- "${FILE_PATH}" && exit 5 exit 2;; + # DjVu + image/vnd.djvu) + # Preview as text conversion (requires djvulibre) + djvutxt "${FILE_PATH}" | fmt -w ${PV_WIDTH} && exit 5 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + # Image image/*) # Preview as text conversion - # img2txt --gamma=0.6 --width="${PV_WIDTH}" -- "${FILE_PATH}" && exit 4 - exiftool "${FILE_PATH}" && exit 5 + img2txt --gamma=0.6 --width="${PV_WIDTH}" -- "${FILE_PATH}" && exit 4 + #exiftool "${FILE_PATH}" && exit 5 exit 1;; # Video and audio diff --git a/.config/rofi/config b/.config/rofi/config new file mode 100644 index 0000000..ed61088 --- /dev/null +++ b/.config/rofi/config @@ -0,0 +1,4 @@ +rofi.lines: 20 +rofi.show-icons: true +rofi.width: 60 +rofi.theme: Arc-Dark diff --git a/.config/rofi/scripts/powermenu.sh b/.config/rofi/scripts/powermenu.sh new file mode 100755 index 0000000..bdab0a3 --- /dev/null +++ b/.config/rofi/scripts/powermenu.sh @@ -0,0 +1,33 @@ +OPTIONS="Reboot\nPoweroff\nSuspend\nHibernate\nLogout\nLock\n" + +lock() { + WINDOW=:0 xscreensaver-command -lock +} + +if [ "$@" ] +then + case $@ in + Exit) + i3-msg exit + ;; + Logout) + i3-msg exit + ;; + Reboot) + systemctl reboot + ;; + Poweroff) + systemctl poweroff + ;; + Suspend) + systemctl suspend + ;; + Hibernate) + systemctl hibernate + ;; + *) + ;; + esac +else + echo -en $OPTIONS +fi diff --git a/.config/zathura/zathurarc b/.config/zathura/zathurarc new file mode 100644 index 0000000..6c45001 --- /dev/null +++ b/.config/zathura/zathurarc @@ -0,0 +1,9 @@ +set pages-per-row 2 +set page-cache-size 1 +set adjust-open "best-fit" + +set render-loading "false" +set selection-clipboard clipboard +unmap f +map f toggle_fullscreen +map [fullscreen] f toggle_fullscreen diff --git a/.hgignore b/.hgignore index a3785dd..f91e3ae 100644 --- a/.hgignore +++ b/.hgignore @@ -1,11 +1,8 @@ -# do not sync lain -lain/ - -# vim -.tmp -.vim - -# ranger -ranger/bookmarks -ranger/history -ranger/tagged +.pyc +.vim/plugged +.old +.bak +.config/i3blocks +.config/awesome/lain +.config/ranger/bookmarks +.vim/view/ diff --git a/.vim/.ycm_extra_conf.py b/.vim/.ycm_extra_conf.py new file mode 100644 index 0000000..feaea0b --- /dev/null +++ b/.vim/.ycm_extra_conf.py @@ -0,0 +1,192 @@ +# This file is NOT licensed under the GPLv3, which is the license for the rest +# of YouCompleteMe. +# +# Here's the license text for this file: +# +# This is free and unencumbered software released into the public domain. +# +# Anyone is free to copy, modify, publish, use, compile, sell, or +# distribute this software, either in source code form or as a compiled +# binary, for any purpose, commercial or non-commercial, and by any +# means. +# +# In jurisdictions that recognize copyright laws, the author or authors +# of this software dedicate any and all copyright interest in the +# software to the public domain. We make this dedication for the benefit +# of the public at large and to the detriment of our heirs and +# successors. We intend this dedication to be an overt act of +# relinquishment in perpetuity of all present and future rights to this +# software under copyright law. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# For more information, please refer to + +import os +import ycm_core + +# These are the compilation flags that will be used in case there's no +# compilation database set (by default, one is not set). +# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR. +flags = [ +'-Wall', +'-Wextra', +'-Werror', +#'-Wc++98-compat', +'-Wno-long-long', +'-Wno-variadic-macros', +'-fexceptions', +'-DNDEBUG', +# You 100% do NOT need -DUSE_CLANG_COMPLETER in your flags; only the YCM +# source code needs it. +'-DUSE_CLANG_COMPLETER', +# THIS IS IMPORTANT! Without a "-std=" flag, clang won't know which +# language to use when compiling headers. So it will guess. Badly. So C++ +# headers will be compiled as C headers. You don't want that so ALWAYS specify +# a "-std=". +# For a C project, you would set this to something like 'c99' instead of +# 'c++11'. +'-std=c++11', +# ...and the same thing goes for the magic -x option which specifies the +# language that the files to be compiled are written in. This is mostly +# relevant for c++ headers. +# For a C project, you would set this to 'c' instead of 'c++'. +'-x', +'c++', +'-isystem', +'../BoostParts', +'-isystem', +# This path will only work on OS X, but extra paths that don't exist are not +# harmful +'/System/Library/Frameworks/Python.framework/Headers', +'-isystem', +'../llvm/include', +'-isystem', +'../llvm/tools/clang/include', +'-I', +'.', +'-I', +'./ClangCompleter', +'-isystem', +'./tests/gmock/gtest', +'-isystem', +'./tests/gmock/gtest/include', +'-isystem', +'./tests/gmock', +'-isystem', +'./tests/gmock/include', +'-isystem', +'/usr/include', +'-isystem', +'/usr/local/include', +'-isystem', +'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1', +'-isystem', +'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include', +] + + +# Set this to the absolute path to the folder (NOT the file!) containing the +# compile_commands.json file to use that instead of 'flags'. See here for +# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html +# +# Most projects will NOT need to set this to anything; you can just change the +# 'flags' list of compilation flags. Notice that YCM itself uses that approach. +compilation_database_folder = '' + +if os.path.exists( compilation_database_folder ): + database = ycm_core.CompilationDatabase( compilation_database_folder ) +else: + database = None + +SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] + +def DirectoryOfThisScript(): + return os.path.dirname( os.path.abspath( __file__ ) ) + + +def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): + if not working_directory: + return list( flags ) + new_flags = [] + make_next_absolute = False + path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] + for flag in flags: + new_flag = flag + + if make_next_absolute: + make_next_absolute = False + if not flag.startswith( '/' ): + new_flag = os.path.join( working_directory, flag ) + + for path_flag in path_flags: + if flag == path_flag: + make_next_absolute = True + break + + if flag.startswith( path_flag ): + path = flag[ len( path_flag ): ] + new_flag = path_flag + os.path.join( working_directory, path ) + break + + if new_flag: + new_flags.append( new_flag ) + return new_flags + + +def IsHeaderFile( filename ): + extension = os.path.splitext( filename )[ 1 ] + return extension in [ '.h', '.hxx', '.hpp', '.hh' ] + + +def GetCompilationInfoForFile( filename ): + # The compilation_commands.json file generated by CMake does not have entries + # for header files. So we do our best by asking the db for flags for a + # corresponding source file, if any. If one exists, the flags for that file + # should be good enough. + if IsHeaderFile( filename ): + basename = os.path.splitext( filename )[ 0 ] + for extension in SOURCE_EXTENSIONS: + replacement_file = basename + extension + if os.path.exists( replacement_file ): + compilation_info = database.GetCompilationInfoForFile( + replacement_file ) + if compilation_info.compiler_flags_: + return compilation_info + return None + return database.GetCompilationInfoForFile( filename ) + + +def FlagsForFile( filename, **kwargs ): + if database: + # Bear in mind that compilation_info.compiler_flags_ does NOT return a + # python list, but a "list-like" StringVec object + compilation_info = GetCompilationInfoForFile( filename ) + if not compilation_info: + return None + + final_flags = MakeRelativePathsInFlagsAbsolute( + compilation_info.compiler_flags_, + compilation_info.compiler_working_dir_ ) + + # NOTE: This is just for YouCompleteMe; it's highly likely that your project + # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR + # ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT. + try: + final_flags.remove( '-stdlib=libc++' ) + except ValueError: + pass + else: + relative_to = DirectoryOfThisScript() + final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) + + return { + 'flags': final_flags, + 'do_cache': True + } diff --git a/.vim/autoload/plug.vim b/.vim/autoload/plug.vim new file mode 100644 index 0000000..db1f615 --- /dev/null +++ b/.vim/autoload/plug.vim @@ -0,0 +1,2522 @@ +" vim-plug: Vim plugin manager +" ============================ +" +" Download plug.vim and put it in ~/.vim/autoload +" +" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ +" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim +" +" Edit your .vimrc +" +" call plug#begin('~/.vim/plugged') +" +" " Make sure you use single quotes +" +" " Shorthand notation; fetches https://github.com/junegunn/vim-easy-align +" Plug 'junegunn/vim-easy-align' +" +" " Any valid git URL is allowed +" Plug 'https://github.com/junegunn/vim-github-dashboard.git' +" +" " Multiple Plug commands can be written in a single line using | separators +" Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' +" +" " On-demand loading +" Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } +" Plug 'tpope/vim-fireplace', { 'for': 'clojure' } +" +" " Using a non-master branch +" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } +" +" " Using a tagged release; wildcard allowed (requires git 1.9.2 or above) +" Plug 'fatih/vim-go', { 'tag': '*' } +" +" " Plugin options +" Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } +" +" " Plugin outside ~/.vim/plugged with post-update hook +" Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } +" +" " Unmanaged plugin (manually installed and updated) +" Plug '~/my-prototype-plugin' +" +" " Initialize plugin system +" call plug#end() +" +" Then reload .vimrc and :PlugInstall to install plugins. +" +" Plug options: +" +"| Option | Description | +"| ----------------------- | ------------------------------------------------ | +"| `branch`/`tag`/`commit` | Branch/tag/commit of the repository to use | +"| `rtp` | Subdirectory that contains Vim plugin | +"| `dir` | Custom directory for the plugin | +"| `as` | Use different name for the plugin | +"| `do` | Post-update hook (string or funcref) | +"| `on` | On-demand loading: Commands or ``-mappings | +"| `for` | On-demand loading: File types | +"| `frozen` | Do not update unless explicitly specified | +" +" More information: https://github.com/junegunn/vim-plug +" +" +" Copyright (c) 2017 Junegunn Choi +" +" MIT License +" +" Permission is hereby granted, free of charge, to any person obtaining +" a copy of this software and associated documentation files (the +" "Software"), to deal in the Software without restriction, including +" without limitation the rights to use, copy, modify, merge, publish, +" distribute, sublicense, and/or sell copies of the Software, and to +" permit persons to whom the Software is furnished to do so, subject to +" the following conditions: +" +" The above copyright notice and this permission notice shall be +" included in all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +if exists('g:loaded_plug') + finish +endif +let g:loaded_plug = 1 + +let s:cpo_save = &cpo +set cpo&vim + +let s:plug_src = 'https://github.com/junegunn/vim-plug.git' +let s:plug_tab = get(s:, 'plug_tab', -1) +let s:plug_buf = get(s:, 'plug_buf', -1) +let s:mac_gui = has('gui_macvim') && has('gui_running') +let s:is_win = has('win32') +let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait') && !s:is_win) +let s:vim8 = has('patch-8.0.0039') && exists('*job_start') +let s:me = resolve(expand(':p')) +let s:base_spec = { 'branch': 'master', 'frozen': 0 } +let s:TYPE = { +\ 'string': type(''), +\ 'list': type([]), +\ 'dict': type({}), +\ 'funcref': type(function('call')) +\ } +let s:loaded = get(s:, 'loaded', {}) +let s:triggers = get(s:, 'triggers', {}) + +function! plug#begin(...) + if a:0 > 0 + let s:plug_home_org = a:1 + let home = s:path(fnamemodify(expand(a:1), ':p')) + elseif exists('g:plug_home') + let home = s:path(g:plug_home) + elseif !empty(&rtp) + let home = s:path(split(&rtp, ',')[0]) . '/plugged' + else + return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.') + endif + if fnamemodify(home, ':t') ==# 'plugin' && fnamemodify(home, ':h') ==# s:first_rtp + return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.') + endif + + let g:plug_home = home + let g:plugs = {} + let g:plugs_order = [] + let s:triggers = {} + + call s:define_commands() + return 1 +endfunction + +function! s:define_commands() + command! -nargs=+ -bar Plug call plug#() + if !executable('git') + return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.') + endif + command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(0, []) + command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(0, []) + command! -nargs=0 -bar -bang PlugClean call s:clean(0) + command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif + command! -nargs=0 -bar PlugStatus call s:status() + command! -nargs=0 -bar PlugDiff call s:diff() + command! -nargs=? -bar -bang -complete=file PlugSnapshot call s:snapshot(0, ) +endfunction + +function! s:to_a(v) + return type(a:v) == s:TYPE.list ? a:v : [a:v] +endfunction + +function! s:to_s(v) + return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n" +endfunction + +function! s:glob(from, pattern) + return s:lines(globpath(a:from, a:pattern)) +endfunction + +function! s:source(from, ...) + let found = 0 + for pattern in a:000 + for vim in s:glob(a:from, pattern) + execute 'source' s:esc(vim) + let found = 1 + endfor + endfor + return found +endfunction + +function! s:assoc(dict, key, val) + let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) +endfunction + +function! s:ask(message, ...) + call inputsave() + echohl WarningMsg + let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) ')) + echohl None + call inputrestore() + echo "\r" + return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0 +endfunction + +function! s:ask_no_interrupt(...) + try + return call('s:ask', a:000) + catch + return 0 + endtry +endfunction + +function! s:lazy(plug, opt) + return has_key(a:plug, a:opt) && + \ (empty(s:to_a(a:plug[a:opt])) || + \ !isdirectory(a:plug.dir) || + \ len(s:glob(s:rtp(a:plug), 'plugin')) || + \ len(s:glob(s:rtp(a:plug), 'after/plugin'))) +endfunction + +function! plug#end() + if !exists('g:plugs') + return s:err('Call plug#begin() first') + endif + + if exists('#PlugLOD') + augroup PlugLOD + autocmd! + augroup END + augroup! PlugLOD + endif + let lod = { 'ft': {}, 'map': {}, 'cmd': {} } + + if exists('g:did_load_filetypes') + filetype off + endif + for name in g:plugs_order + if !has_key(g:plugs, name) + continue + endif + let plug = g:plugs[name] + if get(s:loaded, name, 0) || !s:lazy(plug, 'on') && !s:lazy(plug, 'for') + let s:loaded[name] = 1 + continue + endif + + if has_key(plug, 'on') + let s:triggers[name] = { 'map': [], 'cmd': [] } + for cmd in s:to_a(plug.on) + if cmd =~? '^.\+' + if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i')) + call s:assoc(lod.map, cmd, name) + endif + call add(s:triggers[name].map, cmd) + elseif cmd =~# '^[A-Z]' + let cmd = substitute(cmd, '!*$', '', '') + if exists(':'.cmd) != 2 + call s:assoc(lod.cmd, cmd, name) + endif + call add(s:triggers[name].cmd, cmd) + else + call s:err('Invalid `on` option: '.cmd. + \ '. Should start with an uppercase letter or ``.') + endif + endfor + endif + + if has_key(plug, 'for') + let types = s:to_a(plug.for) + if !empty(types) + augroup filetypedetect + call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') + augroup END + endif + for type in types + call s:assoc(lod.ft, type, name) + endfor + endif + endfor + + for [cmd, names] in items(lod.cmd) + execute printf( + \ 'command! -nargs=* -range -bang -complete=file %s call s:lod_cmd(%s, "", , , , %s)', + \ cmd, string(cmd), string(names)) + endfor + + for [map, names] in items(lod.map) + for [mode, map_prefix, key_prefix] in + \ [['i', '', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] + execute printf( + \ '%snoremap %s %s:call lod_map(%s, %s, %s, "%s")', + \ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix) + endfor + endfor + + for [ft, names] in items(lod.ft) + augroup PlugLOD + execute printf('autocmd FileType %s call lod_ft(%s, %s)', + \ ft, string(ft), string(names)) + augroup END + endfor + + call s:reorg_rtp() + filetype plugin indent on + if has('vim_starting') + if has('syntax') && !exists('g:syntax_on') + syntax enable + end + else + call s:reload_plugins() + endif +endfunction + +function! s:loaded_names() + return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') +endfunction + +function! s:load_plugin(spec) + call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim') +endfunction + +function! s:reload_plugins() + for name in s:loaded_names() + call s:load_plugin(g:plugs[name]) + endfor +endfunction + +function! s:trim(str) + return substitute(a:str, '[\/]\+$', '', '') +endfunction + +function! s:version_requirement(val, min) + for idx in range(0, len(a:min) - 1) + let v = get(a:val, idx, 0) + if v < a:min[idx] | return 0 + elseif v > a:min[idx] | return 1 + endif + endfor + return 1 +endfunction + +function! s:git_version_requirement(...) + if !exists('s:git_version') + let s:git_version = map(split(split(s:system('git --version'))[2], '\.'), 'str2nr(v:val)') + endif + return s:version_requirement(s:git_version, a:000) +endfunction + +function! s:progress_opt(base) + return a:base && !s:is_win && + \ s:git_version_requirement(1, 7, 1) ? '--progress' : '' +endfunction + +if s:is_win + function! s:rtp(spec) + return s:path(a:spec.dir . get(a:spec, 'rtp', '')) + endfunction + + function! s:path(path) + return s:trim(substitute(a:path, '/', '\', 'g')) + endfunction + + function! s:dirpath(path) + return s:path(a:path) . '\' + endfunction + + function! s:is_local_plug(repo) + return a:repo =~? '^[a-z]:\|^[%~]' + endfunction +else + function! s:rtp(spec) + return s:dirpath(a:spec.dir . get(a:spec, 'rtp', '')) + endfunction + + function! s:path(path) + return s:trim(a:path) + endfunction + + function! s:dirpath(path) + return substitute(a:path, '[/\\]*$', '/', '') + endfunction + + function! s:is_local_plug(repo) + return a:repo[0] =~ '[/$~]' + endfunction +endif + +function! s:err(msg) + echohl ErrorMsg + echom '[vim-plug] '.a:msg + echohl None +endfunction + +function! s:warn(cmd, msg) + echohl WarningMsg + execute a:cmd 'a:msg' + echohl None +endfunction + +function! s:esc(path) + return escape(a:path, ' ') +endfunction + +function! s:escrtp(path) + return escape(a:path, ' ,') +endfunction + +function! s:remove_rtp() + for name in s:loaded_names() + let rtp = s:rtp(g:plugs[name]) + execute 'set rtp-='.s:escrtp(rtp) + let after = globpath(rtp, 'after') + if isdirectory(after) + execute 'set rtp-='.s:escrtp(after) + endif + endfor +endfunction + +function! s:reorg_rtp() + if !empty(s:first_rtp) + execute 'set rtp-='.s:first_rtp + execute 'set rtp-='.s:last_rtp + endif + + " &rtp is modified from outside + if exists('s:prtp') && s:prtp !=# &rtp + call s:remove_rtp() + unlet! s:middle + endif + + let s:middle = get(s:, 'middle', &rtp) + let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])') + let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), '!empty(v:val)') + let rtp = join(map(rtps, 'escape(v:val, ",")'), ',') + \ . ','.s:middle.',' + \ . join(map(afters, 'escape(v:val, ",")'), ',') + let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g') + let s:prtp = &rtp + + if !empty(s:first_rtp) + execute 'set rtp^='.s:first_rtp + execute 'set rtp+='.s:last_rtp + endif +endfunction + +function! s:doautocmd(...) + if exists('#'.join(a:000, '#')) + execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '' : '') join(a:000) + endif +endfunction + +function! s:dobufread(names) + for name in a:names + let path = s:rtp(g:plugs[name]).'/**' + for dir in ['ftdetect', 'ftplugin'] + if len(finddir(dir, path)) + if exists('#BufRead') + doautocmd BufRead + endif + return + endif + endfor + endfor +endfunction + +function! plug#load(...) + if a:0 == 0 + return s:err('Argument missing: plugin name(s) required') + endif + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + let names = a:0 == 1 && type(a:1) == s:TYPE.list ? a:1 : a:000 + let unknowns = filter(copy(names), '!has_key(g:plugs, v:val)') + if !empty(unknowns) + let s = len(unknowns) > 1 ? 's' : '' + return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', '))) + end + let unloaded = filter(copy(names), '!get(s:loaded, v:val, 0)') + if !empty(unloaded) + for name in unloaded + call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + endfor + call s:dobufread(unloaded) + return 1 + end + return 0 +endfunction + +function! s:remove_triggers(name) + if !has_key(s:triggers, a:name) + return + endif + for cmd in s:triggers[a:name].cmd + execute 'silent! delc' cmd + endfor + for map in s:triggers[a:name].map + execute 'silent! unmap' map + execute 'silent! iunmap' map + endfor + call remove(s:triggers, a:name) +endfunction + +function! s:lod(names, types, ...) + for name in a:names + call s:remove_triggers(name) + let s:loaded[name] = 1 + endfor + call s:reorg_rtp() + + for name in a:names + let rtp = s:rtp(g:plugs[name]) + for dir in a:types + call s:source(rtp, dir.'/**/*.vim') + endfor + if a:0 + if !s:source(rtp, a:1) && !empty(s:glob(rtp, a:2)) + execute 'runtime' a:1 + endif + call s:source(rtp, a:2) + endif + call s:doautocmd('User', name) + endfor +endfunction + +function! s:lod_ft(pat, names) + let syn = 'syntax/'.a:pat.'.vim' + call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn) + execute 'autocmd! PlugLOD FileType' a:pat + call s:doautocmd('filetypeplugin', 'FileType') + call s:doautocmd('filetypeindent', 'FileType') +endfunction + +function! s:lod_cmd(cmd, bang, l1, l2, args, names) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + call s:dobufread(a:names) + execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) +endfunction + +function! s:lod_map(map, names, with_prefix, prefix) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + call s:dobufread(a:names) + let extra = '' + while 1 + let c = getchar(0) + if c == 0 + break + endif + let extra .= nr2char(c) + endwhile + + if a:with_prefix + let prefix = v:count ? v:count : '' + let prefix .= '"'.v:register.a:prefix + if mode(1) == 'no' + if v:operator == 'c' + let prefix = "\" . prefix + endif + let prefix .= v:operator + endif + call feedkeys(prefix, 'n') + endif + call feedkeys(substitute(a:map, '^', "\", '') . extra) +endfunction + +function! plug#(repo, ...) + if a:0 > 1 + return s:err('Invalid number of arguments (1..2)') + endif + + try + let repo = s:trim(a:repo) + let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec + let name = get(opts, 'as', fnamemodify(repo, ':t:s?\.git$??')) + let spec = extend(s:infer_properties(name, repo), opts) + if !has_key(g:plugs, name) + call add(g:plugs_order, name) + endif + let g:plugs[name] = spec + let s:loaded[name] = get(s:loaded, name, 0) + catch + return s:err(v:exception) + endtry +endfunction + +function! s:parse_options(arg) + let opts = copy(s:base_spec) + let type = type(a:arg) + if type == s:TYPE.string + let opts.tag = a:arg + elseif type == s:TYPE.dict + call extend(opts, a:arg) + if has_key(opts, 'dir') + let opts.dir = s:dirpath(expand(opts.dir)) + endif + else + throw 'Invalid argument type (expected: string or dictionary)' + endif + return opts +endfunction + +function! s:infer_properties(name, repo) + let repo = a:repo + if s:is_local_plug(repo) + return { 'dir': s:dirpath(expand(repo)) } + else + if repo =~ ':' + let uri = repo + else + if repo !~ '/' + throw printf('Invalid argument: %s (implicit `vim-scripts'' expansion is deprecated)', repo) + endif + let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git') + let uri = printf(fmt, repo) + endif + return { 'dir': s:dirpath(g:plug_home.'/'.a:name), 'uri': uri } + endif +endfunction + +function! s:install(force, names) + call s:update_impl(0, a:force, a:names) +endfunction + +function! s:update(force, names) + call s:update_impl(1, a:force, a:names) +endfunction + +function! plug#helptags() + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + for spec in values(g:plugs) + let docd = join([s:rtp(spec), 'doc'], '/') + if isdirectory(docd) + silent! execute 'helptags' s:esc(docd) + endif + endfor + return 1 +endfunction + +function! s:syntax() + syntax clear + syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber + syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX + syn match plugNumber /[0-9]\+[0-9.]*/ contained + syn match plugBracket /[[\]]/ contained + syn match plugX /x/ contained + syn match plugDash /^-/ + syn match plugPlus /^+/ + syn match plugStar /^*/ + syn match plugMessage /\(^- \)\@<=.*/ + syn match plugName /\(^- \)\@<=[^ ]*:/ + syn match plugSha /\%(: \)\@<=[0-9a-f]\{4,}$/ + syn match plugTag /(tag: [^)]\+)/ + syn match plugInstall /\(^+ \)\@<=[^:]*/ + syn match plugUpdate /\(^* \)\@<=[^:]*/ + syn match plugCommit /^ \X*[0-9a-f]\{7,9} .*/ contains=plugRelDate,plugEdge,plugTag + syn match plugEdge /^ \X\+$/ + syn match plugEdge /^ \X*/ contained nextgroup=plugSha + syn match plugSha /[0-9a-f]\{7,9}/ contained + syn match plugRelDate /([^)]*)$/ contained + syn match plugNotLoaded /(not loaded)$/ + syn match plugError /^x.*/ + syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/ + syn match plugH2 /^.*:\n-\+$/ + syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean + hi def link plug1 Title + hi def link plug2 Repeat + hi def link plugH2 Type + hi def link plugX Exception + hi def link plugBracket Structure + hi def link plugNumber Number + + hi def link plugDash Special + hi def link plugPlus Constant + hi def link plugStar Boolean + + hi def link plugMessage Function + hi def link plugName Label + hi def link plugInstall Function + hi def link plugUpdate Type + + hi def link plugError Error + hi def link plugDeleted Ignore + hi def link plugRelDate Comment + hi def link plugEdge PreProc + hi def link plugSha Identifier + hi def link plugTag Constant + + hi def link plugNotLoaded Comment +endfunction + +function! s:lpad(str, len) + return a:str . repeat(' ', a:len - len(a:str)) +endfunction + +function! s:lines(msg) + return split(a:msg, "[\r\n]") +endfunction + +function! s:lastline(msg) + return get(s:lines(a:msg), -1, '') +endfunction + +function! s:new_window() + execute get(g:, 'plug_window', 'vertical topleft new') +endfunction + +function! s:plug_window_exists() + let buflist = tabpagebuflist(s:plug_tab) + return !empty(buflist) && index(buflist, s:plug_buf) >= 0 +endfunction + +function! s:switch_in() + if !s:plug_window_exists() + return 0 + endif + + if winbufnr(0) != s:plug_buf + let s:pos = [tabpagenr(), winnr(), winsaveview()] + execute 'normal!' s:plug_tab.'gt' + let winnr = bufwinnr(s:plug_buf) + execute winnr.'wincmd w' + call add(s:pos, winsaveview()) + else + let s:pos = [winsaveview()] + endif + + setlocal modifiable + return 1 +endfunction + +function! s:switch_out(...) + call winrestview(s:pos[-1]) + setlocal nomodifiable + if a:0 > 0 + execute a:1 + endif + + if len(s:pos) > 1 + execute 'normal!' s:pos[0].'gt' + execute s:pos[1] 'wincmd w' + call winrestview(s:pos[2]) + endif +endfunction + +function! s:finish_bindings() + nnoremap R :call retry() + nnoremap D :PlugDiff + nnoremap S :PlugStatus + nnoremap U :call status_update() + xnoremap U :call status_update() + nnoremap ]] :silent! call section('') + nnoremap [[ :silent! call section('b') +endfunction + +function! s:prepare(...) + if empty(getcwd()) + throw 'Invalid current working directory. Cannot proceed.' + endif + + for evar in ['$GIT_DIR', '$GIT_WORK_TREE'] + if exists(evar) + throw evar.' detected. Cannot proceed.' + endif + endfor + + call s:job_abort() + if s:switch_in() + if b:plug_preview == 1 + pc + endif + enew + else + call s:new_window() + endif + + nnoremap q :if b:plug_preview==1pcendifbd + if a:0 == 0 + call s:finish_bindings() + endif + let b:plug_preview = -1 + let s:plug_tab = tabpagenr() + let s:plug_buf = winbufnr(0) + call s:assign_name() + + for k in ['', 'L', 'o', 'X', 'd', 'dd'] + execute 'silent! unmap ' k + endfor + setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell + if exists('+colorcolumn') + setlocal colorcolumn= + endif + setf vim-plug + if exists('g:syntax_on') + call s:syntax() + endif +endfunction + +function! s:assign_name() + " Assign buffer name + let prefix = '[Plugins]' + let name = prefix + let idx = 2 + while bufexists(name) + let name = printf('%s (%s)', prefix, idx) + let idx = idx + 1 + endwhile + silent! execute 'f' fnameescape(name) +endfunction + +function! s:chsh(swap) + let prev = [&shell, &shellcmdflag, &shellredir] + if s:is_win + set shell=cmd.exe shellcmdflag=/c shellredir=>%s\ 2>&1 + elseif a:swap + set shell=sh shellredir=>%s\ 2>&1 + endif + return prev +endfunction + +function! s:bang(cmd, ...) + try + let [sh, shellcmdflag, shrd] = s:chsh(a:0) + " FIXME: Escaping is incomplete. We could use shellescape with eval, + " but it won't work on Windows. + let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd + if s:is_win + let batchfile = tempname().'.bat' + call writefile(["@echo off\r", cmd . "\r"], batchfile) + let cmd = batchfile + endif + let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%') + execute "normal! :execute g:_plug_bang\\" + finally + unlet g:_plug_bang + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win + call delete(batchfile) + endif + endtry + return v:shell_error ? 'Exit status: ' . v:shell_error : '' +endfunction + +function! s:regress_bar() + let bar = substitute(getline(2)[1:-2], '.*\zs=', 'x', '') + call s:progress_bar(2, bar, len(bar)) +endfunction + +function! s:is_updated(dir) + return !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', a:dir)) +endfunction + +function! s:do(pull, force, todo) + for [name, spec] in items(a:todo) + if !isdirectory(spec.dir) + continue + endif + let installed = has_key(s:update.new, name) + let updated = installed ? 0 : + \ (a:pull && index(s:update.errors, name) < 0 && s:is_updated(spec.dir)) + if a:force || installed || updated + execute 'cd' s:esc(spec.dir) + call append(3, '- Post-update hook for '. name .' ... ') + let error = '' + let type = type(spec.do) + if type == s:TYPE.string + if spec.do[0] == ':' + if !get(s:loaded, name, 0) + let s:loaded[name] = 1 + call s:reorg_rtp() + endif + call s:load_plugin(spec) + try + execute spec.do[1:] + catch + let error = v:exception + endtry + if !s:plug_window_exists() + cd - + throw 'Warning: vim-plug was terminated by the post-update hook of '.name + endif + else + let error = s:bang(spec.do) + endif + elseif type == s:TYPE.funcref + try + let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') + call spec.do({ 'name': name, 'status': status, 'force': a:force }) + catch + let error = v:exception + endtry + else + let error = 'Invalid hook type' + endif + call s:switch_in() + call setline(4, empty(error) ? (getline(4) . 'OK') + \ : ('x' . getline(4)[1:] . error)) + if !empty(error) + call add(s:update.errors, name) + call s:regress_bar() + endif + cd - + endif + endfor +endfunction + +function! s:hash_match(a, b) + return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0 +endfunction + +function! s:checkout(spec) + let sha = a:spec.commit + let output = s:system('git rev-parse HEAD', a:spec.dir) + if !v:shell_error && !s:hash_match(sha, s:lines(output)[0]) + let output = s:system( + \ 'git fetch --depth 999999 && git checkout '.s:esc(sha).' --', a:spec.dir) + endif + return output +endfunction + +function! s:finish(pull) + let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen')) + if new_frozen + let s = new_frozen > 1 ? 's' : '' + call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s)) + endif + call append(3, '- Finishing ... ') | 4 + redraw + call plug#helptags() + call plug#end() + call setline(4, getline(4) . 'Done!') + redraw + let msgs = [] + if !empty(s:update.errors) + call add(msgs, "Press 'R' to retry.") + endif + if a:pull && len(s:update.new) < len(filter(getline(5, '$'), + \ "v:val =~ '^- ' && v:val !~# 'Already up.to.date'")) + call add(msgs, "Press 'D' to see the updated changes.") + endif + echo join(msgs, ' ') + call s:finish_bindings() +endfunction + +function! s:retry() + if empty(s:update.errors) + return + endif + echo + call s:update_impl(s:update.pull, s:update.force, + \ extend(copy(s:update.errors), [s:update.threads])) +endfunction + +function! s:is_managed(name) + return has_key(g:plugs[a:name], 'uri') +endfunction + +function! s:names(...) + return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)')) +endfunction + +function! s:check_ruby() + silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'") + if !exists('g:plug_ruby') + redraw! + return s:warn('echom', 'Warning: Ruby interface is broken') + endif + let ruby_version = split(g:plug_ruby, '\.') + unlet g:plug_ruby + return s:version_requirement(ruby_version, [1, 8, 7]) +endfunction + +function! s:update_impl(pull, force, args) abort + let sync = index(a:args, '--sync') >= 0 || has('vim_starting') + let args = filter(copy(a:args), 'v:val != "--sync"') + let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? + \ remove(args, -1) : get(g:, 'plug_threads', 16) + + let managed = filter(copy(g:plugs), 's:is_managed(v:key)') + let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') : + \ filter(managed, 'index(args, v:key) >= 0') + + if empty(todo) + return s:warn('echo', 'No plugin to '. (a:pull ? 'update' : 'install')) + endif + + if !s:is_win && s:git_version_requirement(2, 3) + let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : '' + let $GIT_TERMINAL_PROMPT = 0 + for plug in values(todo) + let plug.uri = substitute(plug.uri, + \ '^https://git::@github\.com', 'https://github.com', '') + endfor + endif + + if !isdirectory(g:plug_home) + try + call mkdir(g:plug_home, 'p') + catch + return s:err(printf('Invalid plug directory: %s. '. + \ 'Try to call plug#begin with a valid directory', g:plug_home)) + endtry + endif + + if has('nvim') && !exists('*jobwait') && threads > 1 + call s:warn('echom', '[vim-plug] Update Neovim for parallel installer') + endif + + let use_job = s:nvim || s:vim8 + let python = (has('python') || has('python3')) && !use_job + let ruby = has('ruby') && !use_job && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && threads > 1 && s:check_ruby() + + let s:update = { + \ 'start': reltime(), + \ 'all': todo, + \ 'todo': copy(todo), + \ 'errors': [], + \ 'pull': a:pull, + \ 'force': a:force, + \ 'new': {}, + \ 'threads': (python || ruby || use_job) ? min([len(todo), threads]) : 1, + \ 'bar': '', + \ 'fin': 0 + \ } + + call s:prepare(1) + call append(0, ['', '']) + normal! 2G + silent! redraw + + let s:clone_opt = get(g:, 'plug_shallow', 1) ? + \ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : '' + + if has('win32unix') + let s:clone_opt .= ' -c core.eol=lf -c core.autocrlf=input' + endif + + let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : '' + + " Python version requirement (>= 2.7) + if python && !has('python3') && !ruby && !use_job && s:update.threads > 1 + redir => pyv + silent python import platform; print platform.python_version() + redir END + let python = s:version_requirement( + \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6]) + endif + + if (python || ruby) && s:update.threads > 1 + try + let imd = &imd + if s:mac_gui + set noimd + endif + if ruby + call s:update_ruby() + else + call s:update_python() + endif + catch + let lines = getline(4, '$') + let printed = {} + silent! 4,$d _ + for line in lines + let name = s:extract_name(line, '.', '') + if empty(name) || !has_key(printed, name) + call append('$', line) + if !empty(name) + let printed[name] = 1 + if line[0] == 'x' && index(s:update.errors, name) < 0 + call add(s:update.errors, name) + end + endif + endif + endfor + finally + let &imd = imd + call s:update_finish() + endtry + else + call s:update_vim() + while use_job && sync + sleep 100m + if s:update.fin + break + endif + endwhile + endif +endfunction + +function! s:log4(name, msg) + call setline(4, printf('- %s (%s)', a:msg, a:name)) + redraw +endfunction + +function! s:update_finish() + if exists('s:git_terminal_prompt') + let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt + endif + if s:switch_in() + call append(3, '- Updating ...') | 4 + for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))')) + let [pos, _] = s:logpos(name) + if !pos + continue + endif + if has_key(spec, 'commit') + call s:log4(name, 'Checking out '.spec.commit) + let out = s:checkout(spec) + elseif has_key(spec, 'tag') + let tag = spec.tag + if tag =~ '\*' + let tags = s:lines(s:system('git tag --list '.s:shellesc(tag).' --sort -version:refname 2>&1', spec.dir)) + if !v:shell_error && !empty(tags) + let tag = tags[0] + call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag)) + call append(3, '') + endif + endif + call s:log4(name, 'Checking out '.tag) + let out = s:system('git checkout -q '.s:esc(tag).' -- 2>&1', spec.dir) + else + let branch = s:esc(get(spec, 'branch', 'master')) + call s:log4(name, 'Merging origin/'.branch) + let out = s:system('git checkout -q '.branch.' -- 2>&1' + \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only origin/'.branch.' 2>&1')), spec.dir) + endif + if !v:shell_error && filereadable(spec.dir.'/.gitmodules') && + \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir)) + call s:log4(name, 'Updating submodules. This may take a while.') + let out .= s:bang('git submodule update --init --recursive'.s:submodule_opt.' 2>&1', spec.dir) + endif + let msg = s:format_message(v:shell_error ? 'x': '-', name, out) + if v:shell_error + call add(s:update.errors, name) + call s:regress_bar() + silent execute pos 'd _' + call append(4, msg) | 4 + elseif !empty(out) + call setline(pos, msg[0]) + endif + redraw + endfor + silent 4 d _ + try + call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")')) + catch + call s:warn('echom', v:exception) + call s:warn('echo', '') + return + endtry + call s:finish(s:update.pull) + call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') + call s:switch_out('normal! gg') + endif +endfunction + +function! s:job_abort() + if (!s:nvim && !s:vim8) || !exists('s:jobs') + return + endif + + for [name, j] in items(s:jobs) + if s:nvim + silent! call jobstop(j.jobid) + elseif s:vim8 + silent! call job_stop(j.jobid) + endif + if j.new + call s:system('rm -rf ' . s:shellesc(g:plugs[name].dir)) + endif + endfor + let s:jobs = {} +endfunction + +function! s:last_non_empty_line(lines) + let len = len(a:lines) + for idx in range(len) + let line = a:lines[len-idx-1] + if !empty(line) + return line + endif + endfor + return '' +endfunction + +function! s:job_out_cb(self, data) abort + let self = a:self + let data = remove(self.lines, -1) . a:data + let lines = map(split(data, "\n", 1), 'split(v:val, "\r", 1)[-1]') + call extend(self.lines, lines) + " To reduce the number of buffer updates + let self.tick = get(self, 'tick', -1) + 1 + if !self.running || self.tick % len(s:jobs) == 0 + let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-') + let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines) + call s:log(bullet, self.name, result) + endif +endfunction + +function! s:job_exit_cb(self, data) abort + let a:self.running = 0 + let a:self.error = a:data != 0 + call s:reap(a:self.name) + call s:tick() +endfunction + +function! s:job_cb(fn, job, ch, data) + if !s:plug_window_exists() " plug window closed + return s:job_abort() + endif + call call(a:fn, [a:job, a:data]) +endfunction + +function! s:nvim_cb(job_id, data, event) dict abort + return a:event == 'stdout' ? + \ s:job_cb('s:job_out_cb', self, 0, join(a:data, "\n")) : + \ s:job_cb('s:job_exit_cb', self, 0, a:data) +endfunction + +function! s:spawn(name, cmd, opts) + let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''], + \ 'batchfile': (s:is_win && (s:nvim || s:vim8)) ? tempname().'.bat' : '', + \ 'new': get(a:opts, 'new', 0) } + let s:jobs[a:name] = job + let cmd = has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd + if !empty(job.batchfile) + call writefile(["@echo off\r", cmd . "\r"], job.batchfile) + let cmd = job.batchfile + endif + let argv = add(s:is_win ? ['cmd', '/c'] : ['sh', '-c'], cmd) + + if s:nvim + call extend(job, { + \ 'on_stdout': function('s:nvim_cb'), + \ 'on_exit': function('s:nvim_cb'), + \ }) + let jid = jobstart(argv, job) + if jid > 0 + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.lines = [jid < 0 ? argv[0].' is not executable' : + \ 'Invalid arguments (or job table is full)'] + endif + elseif s:vim8 + let jid = job_start(s:is_win ? join(argv, ' ') : argv, { + \ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]), + \ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]), + \ 'out_mode': 'raw' + \}) + if job_status(jid) == 'run' + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.lines = ['Failed to start job'] + endif + else + let job.lines = s:lines(call('s:system', [cmd])) + let job.error = v:shell_error != 0 + let job.running = 0 + endif +endfunction + +function! s:reap(name) + let job = s:jobs[a:name] + if job.error + call add(s:update.errors, a:name) + elseif get(job, 'new', 0) + let s:update.new[a:name] = 1 + endif + let s:update.bar .= job.error ? 'x' : '=' + + let bullet = job.error ? 'x' : '-' + let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines) + call s:log(bullet, a:name, empty(result) ? 'OK' : result) + call s:bar() + + if has_key(job, 'batchfile') && !empty(job.batchfile) + call delete(job.batchfile) + endif + call remove(s:jobs, a:name) +endfunction + +function! s:bar() + if s:switch_in() + let total = len(s:update.all) + call setline(1, (s:update.pull ? 'Updating' : 'Installing'). + \ ' plugins ('.len(s:update.bar).'/'.total.')') + call s:progress_bar(2, s:update.bar, total) + call s:switch_out() + endif +endfunction + +function! s:logpos(name) + for i in range(4, line('$')) + if getline(i) =~# '^[-+x*] '.a:name.':' + for j in range(i + 1, line('$')) + if getline(j) !~ '^ ' + return [i, j - 1] + endif + endfor + return [i, i] + endif + endfor + return [0, 0] +endfunction + +function! s:log(bullet, name, lines) + if s:switch_in() + let [b, e] = s:logpos(a:name) + if b > 0 + silent execute printf('%d,%d d _', b, e) + if b > winheight('.') + let b = 4 + endif + else + let b = 4 + endif + " FIXME For some reason, nomodifiable is set after :d in vim8 + setlocal modifiable + call append(b - 1, s:format_message(a:bullet, a:name, a:lines)) + call s:switch_out() + endif +endfunction + +function! s:update_vim() + let s:jobs = {} + + call s:bar() + call s:tick() +endfunction + +function! s:tick() + let pull = s:update.pull + let prog = s:progress_opt(s:nvim || s:vim8) +while 1 " Without TCO, Vim stack is bound to explode + if empty(s:update.todo) + if empty(s:jobs) && !s:update.fin + call s:update_finish() + let s:update.fin = 1 + endif + return + endif + + let name = keys(s:update.todo)[0] + let spec = remove(s:update.todo, name) + let new = empty(globpath(spec.dir, '.git', 1)) + + call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') + redraw + + let has_tag = has_key(spec, 'tag') + if !new + let [error, _] = s:git_validate(spec, 0) + if empty(error) + if pull + let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' + call s:spawn(name, printf('git fetch %s %s 2>&1', fetch_opt, prog), { 'dir': spec.dir }) + else + let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 } + endif + else + let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 } + endif + else + call s:spawn(name, + \ printf('git clone %s %s %s %s 2>&1', + \ has_tag ? '' : s:clone_opt, + \ prog, + \ s:shellesc(spec.uri), + \ s:shellesc(s:trim(spec.dir))), { 'new': 1 }) + endif + + if !s:jobs[name].running + call s:reap(name) + endif + if len(s:jobs) >= s:update.threads + break + endif +endwhile +endfunction + +function! s:update_python() +let py_exe = has('python') ? 'python' : 'python3' +execute py_exe "<< EOF" +import datetime +import functools +import os +try: + import queue +except ImportError: + import Queue as queue +import random +import re +import shutil +import signal +import subprocess +import tempfile +import threading as thr +import time +import traceback +import vim + +G_NVIM = vim.eval("has('nvim')") == '1' +G_PULL = vim.eval('s:update.pull') == '1' +G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1 +G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)')) +G_CLONE_OPT = vim.eval('s:clone_opt') +G_PROGRESS = vim.eval('s:progress_opt(1)') +G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) +G_STOP = thr.Event() +G_IS_WIN = vim.eval('s:is_win') == '1' + +class PlugError(Exception): + def __init__(self, msg): + self.msg = msg +class CmdTimedOut(PlugError): + pass +class CmdFailed(PlugError): + pass +class InvalidURI(PlugError): + pass +class Action(object): + INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] + +class Buffer(object): + def __init__(self, lock, num_plugs, is_pull): + self.bar = '' + self.event = 'Updating' if is_pull else 'Installing' + self.lock = lock + self.maxy = int(vim.eval('winheight(".")')) + self.num_plugs = num_plugs + + def __where(self, name): + """ Find first line with name in current buffer. Return line num. """ + found, lnum = False, 0 + matcher = re.compile('^[-+x*] {0}:'.format(name)) + for line in vim.current.buffer: + if matcher.search(line) is not None: + found = True + break + lnum += 1 + + if not found: + lnum = -1 + return lnum + + def header(self): + curbuf = vim.current.buffer + curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs) + + num_spaces = self.num_plugs - len(self.bar) + curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ') + + with self.lock: + vim.command('normal! 2G') + vim.command('redraw') + + def write(self, action, name, lines): + first, rest = lines[0], lines[1:] + msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)] + msg.extend([' ' + line for line in rest]) + + try: + if action == Action.ERROR: + self.bar += 'x' + vim.command("call add(s:update.errors, '{0}')".format(name)) + elif action == Action.DONE: + self.bar += '=' + + curbuf = vim.current.buffer + lnum = self.__where(name) + if lnum != -1: # Found matching line num + del curbuf[lnum] + if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]): + lnum = 3 + else: + lnum = 3 + curbuf.append(msg, lnum) + + self.header() + except vim.error: + pass + +class Command(object): + CD = 'cd /d' if G_IS_WIN else 'cd' + + def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None): + self.cmd = cmd + if cmd_dir: + self.cmd = '{0} {1} && {2}'.format(Command.CD, cmd_dir, self.cmd) + self.timeout = timeout + self.callback = cb if cb else (lambda msg: None) + self.clean = clean if clean else (lambda: None) + self.proc = None + + @property + def alive(self): + """ Returns true only if command still running. """ + return self.proc and self.proc.poll() is None + + def execute(self, ntries=3): + """ Execute the command with ntries if CmdTimedOut. + Returns the output of the command if no Exception. + """ + attempt, finished, limit = 0, False, self.timeout + + while not finished: + try: + attempt += 1 + result = self.try_command() + finished = True + return result + except CmdTimedOut: + if attempt != ntries: + self.notify_retry() + self.timeout += limit + else: + raise + + def notify_retry(self): + """ Retry required for command, notify user. """ + for count in range(3, 0, -1): + if G_STOP.is_set(): + raise KeyboardInterrupt + msg = 'Timeout. Will retry in {0} second{1} ...'.format( + count, 's' if count != 1 else '') + self.callback([msg]) + time.sleep(1) + self.callback(['Retrying ...']) + + def try_command(self): + """ Execute a cmd & poll for callback. Returns list of output. + Raises CmdFailed -> return code for Popen isn't 0 + Raises CmdTimedOut -> command exceeded timeout without new output + """ + first_line = True + + try: + tfile = tempfile.NamedTemporaryFile(mode='w+b') + preexec_fn = not G_IS_WIN and os.setsid or None + self.proc = subprocess.Popen(self.cmd, stdout=tfile, + stderr=subprocess.STDOUT, + stdin=subprocess.PIPE, shell=True, + preexec_fn=preexec_fn) + thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,)) + thrd.start() + + thread_not_started = True + while thread_not_started: + try: + thrd.join(0.1) + thread_not_started = False + except RuntimeError: + pass + + while self.alive: + if G_STOP.is_set(): + raise KeyboardInterrupt + + if first_line or random.random() < G_LOG_PROB: + first_line = False + line = '' if G_IS_WIN else nonblock_read(tfile.name) + if line: + self.callback([line]) + + time_diff = time.time() - os.path.getmtime(tfile.name) + if time_diff > self.timeout: + raise CmdTimedOut(['Timeout!']) + + thrd.join(0.5) + + tfile.seek(0) + result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] + + if self.proc.returncode != 0: + raise CmdFailed([''] + result) + + return result + except: + self.terminate() + raise + + def terminate(self): + """ Terminate process and cleanup. """ + if self.alive: + if G_IS_WIN: + os.kill(self.proc.pid, signal.SIGINT) + else: + os.killpg(self.proc.pid, signal.SIGTERM) + self.clean() + +class Plugin(object): + def __init__(self, name, args, buf_q, lock): + self.name = name + self.args = args + self.buf_q = buf_q + self.lock = lock + self.tag = args.get('tag', 0) + + def manage(self): + try: + if os.path.exists(self.args['dir']): + self.update() + else: + self.install() + with self.lock: + thread_vim_command("let s:update.new['{0}'] = 1".format(self.name)) + except PlugError as exc: + self.write(Action.ERROR, self.name, exc.msg) + except KeyboardInterrupt: + G_STOP.set() + self.write(Action.ERROR, self.name, ['Interrupted!']) + except: + # Any exception except those above print stack trace + msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip()) + self.write(Action.ERROR, self.name, msg.split('\n')) + raise + + def install(self): + target = self.args['dir'] + if target[-1] == '\\': + target = target[0:-1] + + def clean(target): + def _clean(): + try: + shutil.rmtree(target) + except OSError: + pass + return _clean + + self.write(Action.INSTALL, self.name, ['Installing ...']) + callback = functools.partial(self.write, Action.INSTALL, self.name) + cmd = 'git clone {0} {1} {2} {3} 2>&1'.format( + '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'], + esc(target)) + com = Command(cmd, None, G_TIMEOUT, callback, clean(target)) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + + def repo_uri(self): + cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url' + command = Command(cmd, self.args['dir'], G_TIMEOUT,) + result = command.execute(G_RETRIES) + return result[-1] + + def update(self): + actual_uri = self.repo_uri() + expect_uri = self.args['uri'] + regex = re.compile(r'^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$') + ma = regex.match(actual_uri) + mb = regex.match(expect_uri) + if ma is None or mb is None or ma.groups() != mb.groups(): + msg = ['', + 'Invalid URI: {0}'.format(actual_uri), + 'Expected {0}'.format(expect_uri), + 'PlugClean required.'] + raise InvalidURI(msg) + + if G_PULL: + self.write(Action.UPDATE, self.name, ['Updating ...']) + callback = functools.partial(self.write, Action.UPDATE, self.name) + fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else '' + cmd = 'git fetch {0} {1} 2>&1'.format(fetch_opt, G_PROGRESS) + com = Command(cmd, self.args['dir'], G_TIMEOUT, callback) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + else: + self.write(Action.DONE, self.name, ['Already installed']) + + def write(self, action, name, msg): + self.buf_q.put((action, name, msg)) + +class PlugThread(thr.Thread): + def __init__(self, tname, args): + super(PlugThread, self).__init__() + self.tname = tname + self.args = args + + def run(self): + thr.current_thread().name = self.tname + buf_q, work_q, lock = self.args + + try: + while not G_STOP.is_set(): + name, args = work_q.get_nowait() + plug = Plugin(name, args, buf_q, lock) + plug.manage() + work_q.task_done() + except queue.Empty: + pass + +class RefreshThread(thr.Thread): + def __init__(self, lock): + super(RefreshThread, self).__init__() + self.lock = lock + self.running = True + + def run(self): + while self.running: + with self.lock: + thread_vim_command('noautocmd normal! a') + time.sleep(0.33) + + def stop(self): + self.running = False + +if G_NVIM: + def thread_vim_command(cmd): + vim.session.threadsafe_call(lambda: vim.command(cmd)) +else: + def thread_vim_command(cmd): + vim.command(cmd) + +def esc(name): + return '"' + name.replace('"', '\"') + '"' + +def nonblock_read(fname): + """ Read a file with nonblock flag. Return the last line. """ + fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK) + buf = os.read(fread, 100000).decode('utf-8', 'replace') + os.close(fread) + + line = buf.rstrip('\r\n') + left = max(line.rfind('\r'), line.rfind('\n')) + if left != -1: + left += 1 + line = line[left:] + + return line + +def main(): + thr.current_thread().name = 'main' + nthreads = int(vim.eval('s:update.threads')) + plugs = vim.eval('s:update.todo') + mac_gui = vim.eval('s:mac_gui') == '1' + + lock = thr.Lock() + buf = Buffer(lock, len(plugs), G_PULL) + buf_q, work_q = queue.Queue(), queue.Queue() + for work in plugs.items(): + work_q.put(work) + + start_cnt = thr.active_count() + for num in range(nthreads): + tname = 'PlugT-{0:02}'.format(num) + thread = PlugThread(tname, (buf_q, work_q, lock)) + thread.start() + if mac_gui: + rthread = RefreshThread(lock) + rthread.start() + + while not buf_q.empty() or thr.active_count() != start_cnt: + try: + action, name, msg = buf_q.get(True, 0.25) + buf.write(action, name, ['OK'] if not msg else msg) + buf_q.task_done() + except queue.Empty: + pass + except KeyboardInterrupt: + G_STOP.set() + + if mac_gui: + rthread.stop() + rthread.join() + +main() +EOF +endfunction + +function! s:update_ruby() + ruby << EOF + module PlugStream + SEP = ["\r", "\n", nil] + def get_line + buffer = '' + loop do + char = readchar rescue return + if SEP.include? char.chr + buffer << $/ + break + else + buffer << char + end + end + buffer + end + end unless defined?(PlugStream) + + def esc arg + %["#{arg.gsub('"', '\"')}"] + end + + def killall pid + pids = [pid] + if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM + pids.each { |pid| Process.kill 'INT', pid.to_i rescue nil } + else + unless `which pgrep 2> /dev/null`.empty? + children = pids + until children.empty? + children = children.map { |pid| + `pgrep -P #{pid}`.lines.map { |l| l.chomp } + }.flatten + pids += children + end + end + pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil } + end + end + + def compare_git_uri a, b + regex = %r{^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$} + regex.match(a).to_a.drop(1) == regex.match(b).to_a.drop(1) + end + + require 'thread' + require 'fileutils' + require 'timeout' + running = true + iswin = VIM::evaluate('s:is_win').to_i == 1 + pull = VIM::evaluate('s:update.pull').to_i == 1 + base = VIM::evaluate('g:plug_home') + all = VIM::evaluate('s:update.todo') + limit = VIM::evaluate('get(g:, "plug_timeout", 60)') + tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1 + nthr = VIM::evaluate('s:update.threads').to_i + maxy = VIM::evaluate('winheight(".")').to_i + vim7 = VIM::evaluate('v:version').to_i <= 703 && RUBY_PLATFORM =~ /darwin/ + cd = iswin ? 'cd /d' : 'cd' + tot = VIM::evaluate('len(s:update.todo)') || 0 + bar = '' + skip = 'Already installed' + mtx = Mutex.new + take1 = proc { mtx.synchronize { running && all.shift } } + logh = proc { + cnt = bar.length + $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})" + $curbuf[2] = '[' + bar.ljust(tot) + ']' + VIM::command('normal! 2G') + VIM::command('redraw') + } + where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } } + log = proc { |name, result, type| + mtx.synchronize do + ing = ![true, false].include?(type) + bar += type ? '=' : 'x' unless ing + b = case type + when :install then '+' when :update then '*' + when true, nil then '-' else + VIM::command("call add(s:update.errors, '#{name}')") + 'x' + end + result = + if type || type.nil? + ["#{b} #{name}: #{result.lines.to_a.last || 'OK'}"] + elsif result =~ /^Interrupted|^Timeout/ + ["#{b} #{name}: #{result}"] + else + ["#{b} #{name}"] + result.lines.map { |l| " " << l } + end + if lnum = where.call(name) + $curbuf.delete lnum + lnum = 4 if ing && lnum > maxy + end + result.each_with_index do |line, offset| + $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp) + end + logh.call + end + } + bt = proc { |cmd, name, type, cleanup| + tried = timeout = 0 + begin + tried += 1 + timeout += limit + fd = nil + data = '' + if iswin + Timeout::timeout(timeout) do + tmp = VIM::evaluate('tempname()') + system("(#{cmd}) > #{tmp}") + data = File.read(tmp).chomp + File.unlink tmp rescue nil + end + else + fd = IO.popen(cmd).extend(PlugStream) + first_line = true + log_prob = 1.0 / nthr + while line = Timeout::timeout(timeout) { fd.get_line } + data << line + log.call name, line.chomp, type if name && (first_line || rand < log_prob) + first_line = false + end + fd.close + end + [$? == 0, data.chomp] + rescue Timeout::Error, Interrupt => e + if fd && !fd.closed? + killall fd.pid + fd.close + end + cleanup.call if cleanup + if e.is_a?(Timeout::Error) && tried < tries + 3.downto(1) do |countdown| + s = countdown > 1 ? 's' : '' + log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type + sleep 1 + end + log.call name, 'Retrying ...', type + retry + end + [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"] + end + } + main = Thread.current + threads = [] + watcher = Thread.new { + if vim7 + while VIM::evaluate('getchar(1)') + sleep 0.1 + end + else + require 'io/console' # >= Ruby 1.9 + nil until IO.console.getch == 3.chr + end + mtx.synchronize do + running = false + threads.each { |t| t.raise Interrupt } unless vim7 + end + threads.each { |t| t.join rescue nil } + main.kill + } + refresh = Thread.new { + while true + mtx.synchronize do + break unless running + VIM::command('noautocmd normal! a') + end + sleep 0.2 + end + } if VIM::evaluate('s:mac_gui') == 1 + + clone_opt = VIM::evaluate('s:clone_opt') + progress = VIM::evaluate('s:progress_opt(1)') + nthr.times do + mtx.synchronize do + threads << Thread.new { + while pair = take1.call + name = pair.first + dir, uri, tag = pair.last.values_at *%w[dir uri tag] + exists = File.directory? dir + ok, result = + if exists + chdir = "#{cd} #{iswin ? dir : esc(dir)}" + ret, data = bt.call "#{chdir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url", nil, nil, nil + current_uri = data.lines.to_a.last + if !ret + if data =~ /^Interrupted|^Timeout/ + [false, data] + else + [false, [data.chomp, "PlugClean required."].join($/)] + end + elsif !compare_git_uri(current_uri, uri) + [false, ["Invalid URI: #{current_uri}", + "Expected: #{uri}", + "PlugClean required."].join($/)] + else + if pull + log.call name, 'Updating ...', :update + fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : '' + bt.call "#{chdir} && git fetch #{fetch_opt} #{progress} 2>&1", name, :update, nil + else + [true, skip] + end + end + else + d = esc dir.sub(%r{[\\/]+$}, '') + log.call name, 'Installing ...', :install + bt.call "git clone #{clone_opt unless tag} #{progress} #{uri} #{d} 2>&1", name, :install, proc { + FileUtils.rm_rf dir + } + end + mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok + log.call name, result, ok + end + } if running + end + end + threads.each { |t| t.join rescue nil } + logh.call + refresh.kill if refresh + watcher.kill +EOF +endfunction + +function! s:shellesc_cmd(arg) + let escaped = substitute(a:arg, '[&|<>()@^]', '^&', 'g') + let escaped = substitute(escaped, '%', '%%', 'g') + let escaped = substitute(escaped, '"', '\\^&', 'g') + let escaped = substitute(escaped, '\(\\\+\)\(\\^\)', '\1\1\2', 'g') + return '^"'.substitute(escaped, '\(\\\+\)$', '\1\1', '').'^"' +endfunction + +function! s:shellesc(arg) + if &shell =~# 'cmd.exe$' + return s:shellesc_cmd(a:arg) + endif + return shellescape(a:arg) +endfunction + +function! s:glob_dir(path) + return map(filter(s:glob(a:path, '**'), 'isdirectory(v:val)'), 's:dirpath(v:val)') +endfunction + +function! s:progress_bar(line, bar, total) + call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']') +endfunction + +function! s:compare_git_uri(a, b) + " See `git help clone' + " https:// [user@] github.com[:port] / junegunn/vim-plug [.git] + " [git@] github.com[:port] : junegunn/vim-plug [.git] + " file:// / junegunn/vim-plug [/] + " / junegunn/vim-plug [/] + let pat = '^\%(\w\+://\)\='.'\%([^@/]*@\)\='.'\([^:/]*\%(:[0-9]*\)\=\)'.'[:/]'.'\(.\{-}\)'.'\%(\.git\)\=/\?$' + let ma = matchlist(a:a, pat) + let mb = matchlist(a:b, pat) + return ma[1:2] ==# mb[1:2] +endfunction + +function! s:format_message(bullet, name, message) + if a:bullet != 'x' + return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))] + else + let lines = map(s:lines(a:message), '" ".v:val') + return extend([printf('x %s:', a:name)], lines) + endif +endfunction + +function! s:with_cd(cmd, dir) + return printf('cd%s %s && %s', s:is_win ? ' /d' : '', s:shellesc(a:dir), a:cmd) +endfunction + +function! s:system(cmd, ...) + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd + if s:is_win + let batchfile = tempname().'.bat' + call writefile(["@echo off\r", cmd . "\r"], batchfile) + let cmd = batchfile + endif + return system(s:is_win ? '('.cmd.')' : cmd) + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win + call delete(batchfile) + endif + endtry +endfunction + +function! s:system_chomp(...) + let ret = call('s:system', a:000) + return v:shell_error ? '' : substitute(ret, '\n$', '', '') +endfunction + +function! s:git_validate(spec, check_branch) + let err = '' + if isdirectory(a:spec.dir) + let result = s:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url', a:spec.dir)) + let remote = result[-1] + if v:shell_error + let err = join([remote, 'PlugClean required.'], "\n") + elseif !s:compare_git_uri(remote, a:spec.uri) + let err = join(['Invalid URI: '.remote, + \ 'Expected: '.a:spec.uri, + \ 'PlugClean required.'], "\n") + elseif a:check_branch && has_key(a:spec, 'commit') + let result = s:lines(s:system('git rev-parse HEAD 2>&1', a:spec.dir)) + let sha = result[-1] + if v:shell_error + let err = join(add(result, 'PlugClean required.'), "\n") + elseif !s:hash_match(sha, a:spec.commit) + let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', + \ a:spec.commit[:6], sha[:6]), + \ 'PlugUpdate required.'], "\n") + endif + elseif a:check_branch + let branch = result[0] + " Check tag + if has_key(a:spec, 'tag') + let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) + if a:spec.tag !=# tag && a:spec.tag !~ '\*' + let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.', + \ (empty(tag) ? 'N/A' : tag), a:spec.tag) + endif + " Check branch + elseif a:spec.branch !=# branch + let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', + \ branch, a:spec.branch) + endif + if empty(err) + let [ahead, behind] = split(s:lastline(s:system(printf( + \ 'git rev-list --count --left-right HEAD...origin/%s', + \ a:spec.branch), a:spec.dir)), '\t') + if !v:shell_error && ahead + if behind + " Only mention PlugClean if diverged, otherwise it's likely to be + " pushable (and probably not that messed up). + let err = printf( + \ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n" + \ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', a:spec.branch, ahead, behind) + else + let err = printf("Ahead of origin/%s by %d commit(s).\n" + \ .'Cannot update until local changes are pushed.', + \ a:spec.branch, ahead) + endif + endif + endif + endif + else + let err = 'Not found' + endif + return [err, err =~# 'PlugClean'] +endfunction + +function! s:rm_rf(dir) + if isdirectory(a:dir) + call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . s:shellesc(a:dir)) + endif +endfunction + +function! s:clean(force) + call s:prepare() + call append(0, 'Searching for invalid plugins in '.g:plug_home) + call append(1, '') + + " List of valid directories + let dirs = [] + let errs = {} + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + if !s:is_managed(name) + call add(dirs, spec.dir) + else + let [err, clean] = s:git_validate(spec, 1) + if clean + let errs[spec.dir] = s:lines(err)[0] + else + call add(dirs, spec.dir) + endif + endif + let cnt += 1 + call s:progress_bar(2, repeat('=', cnt), total) + normal! 2G + redraw + endfor + + let allowed = {} + for dir in dirs + let allowed[s:dirpath(fnamemodify(dir, ':h:h'))] = 1 + let allowed[dir] = 1 + for child in s:glob_dir(dir) + let allowed[child] = 1 + endfor + endfor + + let todo = [] + let found = sort(s:glob_dir(g:plug_home)) + while !empty(found) + let f = remove(found, 0) + if !has_key(allowed, f) && isdirectory(f) + call add(todo, f) + call append(line('$'), '- ' . f) + if has_key(errs, f) + call append(line('$'), ' ' . errs[f]) + endif + let found = filter(found, 'stridx(v:val, f) != 0') + end + endwhile + + 4 + redraw + if empty(todo) + call append(line('$'), 'Already clean.') + else + let s:clean_count = 0 + call append(3, ['Directories to delete:', '']) + redraw! + if a:force || s:ask_no_interrupt('Delete all directories?') + call s:delete([6, line('$')], 1) + else + call setline(4, 'Cancelled.') + nnoremap d :set opfunc=delete_opg@ + nmap dd d_ + xnoremap d :call delete_op(visualmode(), 1) + echo 'Delete the lines (d{motion}) to delete the corresponding directories' + endif + endif + 4 + setlocal nomodifiable +endfunction + +function! s:delete_op(type, ...) + call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0) +endfunction + +function! s:delete(range, force) + let [l1, l2] = a:range + let force = a:force + while l1 <= l2 + let line = getline(l1) + if line =~ '^- ' && isdirectory(line[2:]) + execute l1 + redraw! + let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1) + let force = force || answer > 1 + if answer + call s:rm_rf(line[2:]) + setlocal modifiable + call setline(l1, '~'.line[1:]) + let s:clean_count += 1 + call setline(4, printf('Removed %d directories.', s:clean_count)) + setlocal nomodifiable + endif + endif + let l1 += 1 + endwhile +endfunction + +function! s:upgrade() + echo 'Downloading the latest version of vim-plug' + redraw + let tmp = tempname() + let new = tmp . '/plug.vim' + + try + let out = s:system(printf('git clone --depth 1 %s %s', s:plug_src, tmp)) + if v:shell_error + return s:err('Error upgrading vim-plug: '. out) + endif + + if readfile(s:me) ==# readfile(new) + echo 'vim-plug is already up-to-date' + return 0 + else + call rename(s:me, s:me . '.old') + call rename(new, s:me) + unlet g:loaded_plug + echo 'vim-plug has been upgraded' + return 1 + endif + finally + silent! call s:rm_rf(tmp) + endtry +endfunction + +function! s:upgrade_specs() + for spec in values(g:plugs) + let spec.frozen = get(spec, 'frozen', 0) + endfor +endfunction + +function! s:status() + call s:prepare() + call append(0, 'Checking plugins') + call append(1, '') + + let ecnt = 0 + let unloaded = 0 + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + let is_dir = isdirectory(spec.dir) + if has_key(spec, 'uri') + if is_dir + let [err, _] = s:git_validate(spec, 1) + let [valid, msg] = [empty(err), empty(err) ? 'OK' : err] + else + let [valid, msg] = [0, 'Not found. Try PlugInstall.'] + endif + else + if is_dir + let [valid, msg] = [1, 'OK'] + else + let [valid, msg] = [0, 'Not found.'] + endif + endif + let cnt += 1 + let ecnt += !valid + " `s:loaded` entry can be missing if PlugUpgraded + if is_dir && get(s:loaded, name, -1) == 0 + let unloaded = 1 + let msg .= ' (not loaded)' + endif + call s:progress_bar(2, repeat('=', cnt), total) + call append(3, s:format_message(valid ? '-' : 'x', name, msg)) + normal! 2G + redraw + endfor + call setline(1, 'Finished. '.ecnt.' error(s).') + normal! gg + setlocal nomodifiable + if unloaded + echo "Press 'L' on each line to load plugin, or 'U' to update" + nnoremap L :call status_load(line('.')) + xnoremap L :call status_load(line('.')) + end +endfunction + +function! s:extract_name(str, prefix, suffix) + return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$') +endfunction + +function! s:status_load(lnum) + let line = getline(a:lnum) + let name = s:extract_name(line, '-', '(not loaded)') + if !empty(name) + call plug#load(name) + setlocal modifiable + call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) + setlocal nomodifiable + endif +endfunction + +function! s:status_update() range + let lines = getline(a:firstline, a:lastline) + let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)') + if !empty(names) + echo + execute 'PlugUpdate' join(names) + endif +endfunction + +function! s:is_preview_window_open() + silent! wincmd P + if &previewwindow + wincmd p + return 1 + endif +endfunction + +function! s:find_name(lnum) + for lnum in reverse(range(1, a:lnum)) + let line = getline(lnum) + if empty(line) + return '' + endif + let name = s:extract_name(line, '-', '') + if !empty(name) + return name + endif + endfor + return '' +endfunction + +function! s:preview_commit() + if b:plug_preview < 0 + let b:plug_preview = !s:is_preview_window_open() + endif + + let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}') + if empty(sha) + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir) + return + endif + + if exists('g:plug_pwindow') && !s:is_preview_window_open() + execute g:plug_pwindow + execute 'e' sha + else + execute 'pedit' sha + wincmd P + endif + setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + let cmd = 'cd '.s:shellesc(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha + if s:is_win + let batchfile = tempname().'.bat' + call writefile(["@echo off\r", cmd . "\r"], batchfile) + let cmd = batchfile + endif + execute 'silent %!' cmd + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win + call delete(batchfile) + endif + endtry + setlocal nomodifiable + nnoremap q :q + wincmd p +endfunction + +function! s:section(flags) + call search('\(^[x-] \)\@<=[^:]\+:', a:flags) +endfunction + +function! s:format_git_log(line) + let indent = ' ' + let tokens = split(a:line, nr2char(1)) + if len(tokens) != 5 + return indent.substitute(a:line, '\s*$', '', '') + endif + let [graph, sha, refs, subject, date] = tokens + let tag = matchstr(refs, 'tag: [^,)]\+') + let tag = empty(tag) ? ' ' : ' ('.tag.') ' + return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date) +endfunction + +function! s:append_ul(lnum, text) + call append(a:lnum, ['', a:text, repeat('-', len(a:text))]) +endfunction + +function! s:diff() + call s:prepare() + call append(0, ['Collecting changes ...', '']) + let cnts = [0, 0] + let bar = '' + let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)') + call s:progress_bar(2, bar, len(total)) + for origin in [1, 0] + let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))')))) + if empty(plugs) + continue + endif + call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') + for [k, v] in plugs + let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..' + let diff = s:system_chomp('git log --graph --color=never '.join(map(['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range], 's:shellesc(v:val)')), v.dir) + if !empty(diff) + let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : '' + call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)'))) + let cnts[origin] += 1 + endif + let bar .= '=' + call s:progress_bar(2, bar, len(total)) + normal! 2G + redraw + endfor + if !cnts[origin] + call append(5, ['', 'N/A']) + endif + endfor + call setline(1, printf('%d plugin(s) updated.', cnts[0]) + \ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : '')) + + if cnts[0] || cnts[1] + nnoremap (plug-preview) :silent! call preview_commit() + if empty(maparg("\", 'n')) + nmap (plug-preview) + endif + if empty(maparg('o', 'n')) + nmap o (plug-preview) + endif + endif + if cnts[0] + nnoremap X :call revert() + echo "Press 'X' on each block to revert the update" + endif + normal! gg + setlocal nomodifiable +endfunction + +function! s:revert() + if search('^Pending updates', 'bnW') + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || + \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y' + return + endif + + call s:system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch).' --', g:plugs[name].dir) + setlocal modifiable + normal! "_dap + setlocal nomodifiable + echo 'Reverted' +endfunction + +function! s:snapshot(force, ...) abort + call s:prepare() + setf vim + call append(0, ['" Generated by vim-plug', + \ '" '.strftime("%c"), + \ '" :source this file in vim to restore the snapshot', + \ '" or execute: vim -S snapshot.vim', + \ '', '', 'PlugUpdate!']) + 1 + let anchor = line('$') - 3 + let names = sort(keys(filter(copy(g:plugs), + \'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)'))) + for name in reverse(names) + let sha = s:system_chomp('git rev-parse --short HEAD', g:plugs[name].dir) + if !empty(sha) + call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha)) + redraw + endif + endfor + + if a:0 > 0 + let fn = expand(a:1) + if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?')) + return + endif + call writefile(getline(1, '$'), fn) + echo 'Saved as '.a:1 + silent execute 'e' s:esc(fn) + setf vim + endif +endfunction + +function! s:split_rtp() + return split(&rtp, '\\\@ mzgg=G`z map %s @@ -142,15 +144,23 @@ let g:UltiSnipsJumpForwardTrigger="" let g:UltiSnipsJumpBackwardTrigger="" augroup lexical - autocmd! - autocmd FileType markdown,mkd call lexical#init() - autocmd FileType textile call lexical#init() - autocmd FileType text call lexical#init({ 'spell': 0 }) + autocmd! + autocmd FileType markdown,mkd call lexical#init() + autocmd FileType textile call lexical#init() + autocmd FileType text call lexical#init({ 'spell': 0 }) augroup END let g:ale_linters = { -\ 'javascript': ['standard'], -\ 'vue': ['standard --plugin html "**/*.{js,vue}"'] -\} -let g:racer_experimental_completer = 1 + \'javascript': ['standard'], + \'vue': ['standard --plugin html "**/*.{js,vue}"'], + \'jsx': ['standard --plugin html "**/*.{js,jsx}"'], + \'rust': ['cargo'] + \} +let b:ale_fixers = { + \'*': ['remove_trailing_lines', 'trim_whitespace'], + \'rust': ['rustfmt'] + \} +let g:ale_fix_on_save = 1 +let g:ale_completion_enabled = 1 + set completeopt+=preview diff --git a/.zprofile b/.zprofile index 567872c..f1300d3 100644 --- a/.zprofile +++ b/.zprofile @@ -8,7 +8,7 @@ export PATH=$ANDROID_SDK_ROOT:$PATH export PATH=$ANDROID_SDK_ROOT/tools:$PATH export PATH=$ANDROID_SDK_ROOT/platform-tools:$PATH -# Cocos and Ionic +# Cocos and Ionic export COCOS_CONSOLE_ROOT=${HOME}/Sovellukset/cocos2d-js-v3.6.1/tools/cocos2d-console/bin export IONIC_INSTALL=${HOME}/Asiakirjat/Work/Android/ionic/node_modules/.bin export PATH=$IONIC_INSTALL:$COCOS_CONSOLE_ROOT:$PATH @@ -54,3 +54,15 @@ export PATH="${HOME}/.dotnet:$PATH" # Rust export PATH="${HOME}/.cargo/bin:$PATH" + +# Caffe +export CAFFE_DIR="${HOME}/Koodit/github/caffe/build/install" + +# Terminal +export TERMINAL=kitty +#export TERMINAL=alacritty +export TERMCMD=$TERMINAL +# Start X on tty1 automatically +if systemctl -q is-active graphical.target && [[ ! $DISPLAY && $XDG_VTNR -eq 1 ]]; then + exec startx +fi diff --git a/.zshrc b/.zshrc index bfb6bde..f8b9c24 100644 --- a/.zshrc +++ b/.zshrc @@ -36,15 +36,16 @@ fi # Syntax highlighting source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh +source ~/.zplugins alias top=htop alias ll="ls -lh" alias la="ls -a" alias lp="lastpass.sh" -alias ranger="TERMCMD=termite ranger" +alias ranger="ranger" alias search="search.sh" #alias ls="ls -N --time-style=long-iso --color=auto" -alias ls="ls --time-style=long-iso --color=auto" +alias ls="ls --time-style=long-iso --color=auto --human-readable --group-directories-first --classify" alias rhc='RUBYOPT="-W0" rhc' # Other alias fixsteam='find ~/.steam/root/ \( -name "libgcc_s.so*" -o -name "libstdc++.so*" -o -name "libxcb.so*" \) -print -delete' @@ -52,15 +53,49 @@ alias runsteam="LD_PRELOAD='/usr/$LIB/libstdc++.so.6 /usr/$LIB/libgcc_s.so.1 /us alias steamgamesdir='cd ~/.local/share/Steam/SteamApps/common' alias emsdksetup='source $EMSDK/emsdk_env.sh' alias runwinesteam="MESA_GL_VERSION_OVERRIDE=3.3COMPAT PULSE_LATENCY_MSEC=60 run-desktop.py ~/.local/share/applications/wine/Programs/Steam/Steam.desktop" -alias rbackup="restic -r rclone:hubic:default/Backups/ChimeraLinux" +alias rbackup="restic -r rclone:hubic:ChimeraLinux" +alias bat="bat --theme base16" # https://github.com/chriskempson/base16-shell # git clone https://github.com/chriskempson/base16-shell.git ~/.config/base16-shell -source $HOME/.config/base16-shell/scripts/base16-default-dark.sh +#source $HOME/.config/base16-shell/scripts/base16-default-dark.sh +source $HOME/.config/base16-shell/scripts/base16-solarized-light.sh # Emscripten #source /home/lanxu/Koodit/github/emsdk/emsdk_env.sh -# TERM=xterm-256color +#TERM=xterm-256color #bindkey "${terminfo[khome]}" beginning-of-line #bindkey "${terminfo[kend]}" end-of-line -export TERMCMD=termite + + +function auradd { + pkg=$1 + aur sync --no-view --no-confirm --database custom "$pkg" >&2 + sudo pacman -Sy "$pkg" +} + +function aurrm { + pkg=$1 + rm_out=$(repo-remove /var/cache/pacman/custom/custom.db.tar "$pkg" 2>&1) + if [[ $rm_out = *"ERROR"* ]]; then + echo "not found" >&2 + else + rm -rf /var/cache/pacman/custom/"$pkg"*.pkg.* || true + echo "$pkg removed" + fi + sudo pacman -Sy + sudo pacman -Rnc "$pkg" +} + +function aurupdate { + aur sync --no-view --no-confirm --database custom -u + sudo pacman -Syu +} + +function c { + echo "scale=2; $@" | bc +} + +function aurls { + sudo pacman -Sl custom +} diff --git a/backup/backup.sh b/backup/backup.sh new file mode 100644 index 0000000..94ba61e --- /dev/null +++ b/backup/backup.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +while read line +do + echo $line + restic -r rclone:hubic:ChimeraLinux backup $line --exclude-file restic-exclude.txt --password-file /home/lanxu/restic-pass.txt +done < restic-include.txt diff --git a/backup/restic-exclude.txt b/backup/restic-exclude.txt new file mode 100644 index 0000000..2ac3cec --- /dev/null +++ b/backup/restic-exclude.txt @@ -0,0 +1,23 @@ +*.DS_Store +*.swp +*.pyc +.Trash +.Xauthority +.bash_sessions +.cache +**/.tmp +**/temp/ +**/tmp/ + +# Linux +*.part +.config/itch +.config/itch/* +.steam/* +*.tmp +*.bak +*.a +*.o +node_modules/* +*.cache +*.local/share/Trash diff --git a/backup/restic-include.txt b/backup/restic-include.txt new file mode 100644 index 0000000..b330583 --- /dev/null +++ b/backup/restic-include.txt @@ -0,0 +1,6 @@ +/home/lanxu/Asiakirjat/ +/home/lanxu/Documents/ +/home/lanxu/Kuvat/ +/home/lanxu/Koodit/ +/home/lanxu/Musiikki/ +/home/lanxu/.config/ diff --git a/setup.sh b/setup.sh index fc95289..723649b 100644 --- a/setup.sh +++ b/setup.sh @@ -1,3 +1,10 @@ +#!/bin/sh +# Vim mkdir .vim curl -fLo .vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim -git clone https://github.com/copycat-killer/lain.git $(pwd)/.config/awesome/lain + +# Awesome +# git clone https://github.com/copycat-killer/lain.git $(pwd)/.config/awesome/lain + +# i3blocks +git clone https://github.com/vivien/i3blocks-contrib $(pwd)/.config/i3blocks/