diff options
author | jakobst1n <jakob.stendahl@outlook.com> | 2021-04-28 14:36:31 +0200 |
---|---|---|
committer | jakobst1n <jakob.stendahl@outlook.com> | 2021-04-28 14:36:31 +0200 |
commit | 82e7ae32867c9f46576d99fdc78bc0185410fe47 (patch) | |
tree | fd8764e91741f90967801e0e254aafeeb847d031 /Common/i3 | |
parent | 045c955f835fdb11983117ca6e27aa4543de4109 (diff) | |
download | dotfiles-82e7ae32867c9f46576d99fdc78bc0185410fe47.tar.gz dotfiles-82e7ae32867c9f46576d99fdc78bc0185410fe47.zip |
Do some mods and add i3 things
Diffstat (limited to 'Common/i3')
-rwxr-xr-x | Common/i3/Xresources | 130 | ||||
-rwxr-xr-x | Common/i3/config/compton.conf | 59 | ||||
-rwxr-xr-x | Common/i3/config/dunst/dunstrc | 52 | ||||
-rw-r--r-- | Common/i3/config/i3/config | 186 | ||||
-rw-r--r-- | Common/i3/config/i3status/config | 73 | ||||
-rwxr-xr-x | Common/i3/urxvt/ext/clipboard | 115 | ||||
-rwxr-xr-x | Common/i3/urxvt/ext/keyboard-select | 597 | ||||
-rwxr-xr-x | Common/i3/urxvt/ext/url-select | 408 | ||||
l--------- | Common/i3/urxvt/urxvt | 1 | ||||
-rwxr-xr-x | Common/i3/xsettingsd | 4 |
10 files changed, 1625 insertions, 0 deletions
diff --git a/Common/i3/Xresources b/Common/i3/Xresources new file mode 100755 index 0000000..043fa85 --- /dev/null +++ b/Common/i3/Xresources @@ -0,0 +1,130 @@ +! ------------------------------------------------------------------------------ +! Colour Configuration +! ------------------------------------------------------------------------------ + +! special +*.foreground: #d8dee8 +*.background: #2f343f +*.cursorColor: #b48ead + +! black +*.color0 : #4b5262 +*.color8 : #434a5a + +! red +*.color1 : #bf616a +*.color9 : #b3555e + +! green +*.color2 : #a3be8c +*.color10 : #93ae7c + +! yellow +*.color3 : #ebcb8b +*.color11 : #dbbb7b + +! blue +*.color4 : #81a1c1 +*.color12 : #7191b1 + +! magenta +*.color5 : #b48ead +*.color13 : #a6809f + +! cyan +*.color6 : #89d0bA +*.color14 : #7dbba8 + +! white +*.color7 : #e5e9f0 +*.color15 : #d1d5dc + +! ------------------------------------------------------------------------------ +! Font configuration +! ------------------------------------------------------------------------------ + +URxvt*font: xft:RobotoMono\ Nerd\ Font\ Mono:size=10 +URxvt*boldFont: xft:RobotoMono\ Nerd\ Font\ Mono:size=10 +URxvt*italicFont: xft:RobotoMono\ Nerd\ Font\ Mono:size=10 +URxvt*boldItalicFont: xft:RobotoMono\ Nerd\ Font\ Mono:size=10 + +! ------------------------------------------------------------------------------ +! Xft Font Configuration +! ------------------------------------------------------------------------------ + +Xft.autohint: 0 +Xft.lcdfilter: lcddefault +Xft.hintstyle: hintslight +Xft.hinting: 1 +Xft.antialias: 1 +Xft.rgba: rgb + +! ------------------------------------------------------------------------------ +! URxvt configs +! ------------------------------------------------------------------------------ + +! font spacing +URxvt*letterSpace: 0 +URxvt.lineSpace: 0 + +! general settings +URxvt*saveline: 15000 +URxvt*termName: rxvt-256color +URxvt*iso14755: false +URxvt*urgentOnBell: true + +! appearance +URxvt*depth: 0 +URxvt*scrollBar: false +URxvt*scrollBar_right: false +URxvt*internalBorder: 0 +URxvt*externalBorder: 0 +URxvt.geometry: 84x22 + +! perl extensions +URxvt.perl-ext-common: default,clipboard,url-select,keyboard-select + +! macros for clipboard and selection +URxvt.copyCommand: xclip -i -selection clipboard +URxvt.pasteCommand: xclip -o -selection clipboard +URxvt.keysym.M-c: perl:clipboard:copy +URxvt.keysym.M-v: perl:clipboard:paste +URxvt.keysym.M-C-v: perl:clipboard:paste_escaped +URxvt.keysym.M-Escape: perl:keyboard-select:activate +URxvt.keysym.M-s: perl:keyboard-select:search +URxvt.keysym.M-u: perl:url-select:select_next +URxvt.urlLauncher: firefox +URxvt.underlineURLs: true +URxvt.urlButton: 1 + +! scroll one line +URxvt.keysym.Shift-Up: command:\033]720;1\007 +URxvt.keysym.Shift-Down: command:\033]721;1\007 + +! control arrow +URxvt.keysym.Control-Up: \033[1;5A +URxvt.keysym.Control-Down: \033[1;5B +URxvt.keysym.Control-Right: \033[1;5C +URxvt.keysym.Control-Left: \033[1;5D + +! ------------------------------------------------------------------------------ +! Rofi configs +! ------------------------------------------------------------------------------ + +rofi.color-enabled: true +rofi.color-window: #2e3440, #f0d48b, #2e3440 +rofi.color-normal: #2e3440, #d8dee9, #2e3440, #2e3440, #bf616a +rofi.color-active: #2e3440, #b48ead, #2e3440, #2e3440, #93e5cc +rofi.color-urgent: #2e3440, #ebcb8b, #2e3440, #2e3440, #ebcb8b +rofi.bw: 2 +rofi.modi: run,drun,window + +! ------------------------------------------------------------------------------ +! Dmenu configs +! ------------------------------------------------------------------------------ + +dmenu.selforeground: #d8dee9 +dmenu.background: #2e3440 +dmenu.selbackground: #bf616a +dmenu.foreground: #d8dee9 + diff --git a/Common/i3/config/compton.conf b/Common/i3/config/compton.conf new file mode 100755 index 0000000..1062499 --- /dev/null +++ b/Common/i3/config/compton.conf @@ -0,0 +1,59 @@ +## shadow +#shadow = true; +#no-dnd-shadow = true; +#no-dock-shadow = true; +#clear-shadow = true; +#shadow-radius = 12; +#shadow-offset-x = -12; +#shadow-offset-y = -12; +#shadow-opacity = 0.95; +#shadow-red = 0.18; +#shadow-green = 0.20; +#shadow-blue = 0.25; +#shadow-exclude = [ "class_g = 'Cairo-clock'" , +# "class_g = 'CoverGloobus'", +# "class_g = 'Tilda'", +# "class_g = 'Conky'", +# "class_g ?= 'Notify-osd'", +# "class_g = 'Firefox'", +# "class_g = 'Firefox-esr'", +# "class_g = 'Dmenu'", +# "name = 'Notification'", +# "_GTK_FRAME_EXTENTS@:c" +#]; + +## fading +#fading = true; +#fade-delta = 0.25; +#fade-in-step = 0.02; +#fade-out-step = 0.02; +#fade-exclude = [ +#]; + +## other +#backend = "xrender"; +backend = "glx"; +vsync = "opengl-swc"; +glx-no-stencil = true; +mark-wmwin-focused = true; +mark-ovredir-focused = true; +detect-rounded-corners = true; +#detect-client-opacity = true; +refresh-rate = 0; +dbe = false; +paint-on-overlay = true; +#focus-exclude = [ "class_g = 'Cairo-clock'" , +# "class_g = 'CoverGloobus'", +# "class_g = 'Tilda'", +# "class_g = 'Firefox'", +# "class_g = 'Firefox-esr'" +#]; +#detect-transient = true; +#detect-client-leader = true; +#invert-color-include = [ ]; +#glx-copy-from-front = false; +#glx-swap-method = "undefined"; +#wintypes: +#{ +# tooltip = { fade = true; shadow = true; opacity = 0.75; focus = true; }; +#}; diff --git a/Common/i3/config/dunst/dunstrc b/Common/i3/config/dunst/dunstrc new file mode 100755 index 0000000..5df67b7 --- /dev/null +++ b/Common/i3/config/dunst/dunstrc @@ -0,0 +1,52 @@ +[global] +monitor = 0 +follow = mouse +geometry = "250x50-24+24" +indicate_hidden = yes +shrink = no +separator_height = 0 +padding = 16 +horizontal_padding = 24 +frame_width = 2 +sort = no +idle_threshold = 120 +font = Noto Sans 8 +line_height = 4 +markup = full +format = "<b>%s</b>\n%b" +alignment = left +show_age_threshold = 60 +word_wrap = yes +ignore_newline = no +stack_duplicates = false +hide_duplicate_count = yes +show_indicators = no +icon_position = off +sticky_history = yes +history_length = 20 +browser = /usr/bin/firefox -new-tab +always_run_script = true +title = Dunst +class = Dunst + +[shortcuts] +close = ctrl+space +close_all = ctrl+shift+space +history = ctrl+grave +context = ctrl+shift+period + +[urgency_low] +background = "#2f343f" +foreground = "#d8dee8" +timeout = 2 + +[urgency_normal] +background = "#2f343f" +foreground = "#d8dee8" +timeout = 4 + +[urgency_critical] +background = "#2f343f" +foreground = "#d8dee8" +frame_color = "#bf616a" +timeout = 0 diff --git a/Common/i3/config/i3/config b/Common/i3/config/i3/config new file mode 100644 index 0000000..0aa62a0 --- /dev/null +++ b/Common/i3/config/i3/config @@ -0,0 +1,186 @@ +# set modifier +set $super Mod4 +set $alt Mod1 + +# set font +font pango: Noto Sans 8 + +# Use Mouse+$super to drag floating windows to their wanted position +floating_modifier $super + +#autostart +#exec --no-startup-id hsetroot -center ~/.wallpaper.png +#exec --no-startup-id feh --bg-scale ~/.wallpaper.png +exec --no-startup-id nitrogen --restore +#exec --no-startup-id xsettingsd & +exec --no-startup-id compton -b + +# Tru to run autosetup of displays +exec --not-startup-id xrandr --auto + +# start a terminal +bindsym $super+Return exec i3-sensible-terminal + +# start dmenu (a program launcher) +bindsym $super+Shift+d exec i3-dmenu-desktop --dmenu="dmenu -i -fn 'Noto Sans:size=8'" +bindsym $super+d exec rofi -lines 12 -padding 18 -width 60 -location 0 -show drun -sidebar-mode -columns 3 -font 'Noto Sans 8' + +# common apps keybinds +#bindsym Print exec scrot 'Cheese_%a-%d%b%y_%H.%M.png' -e 'viewnior ~/$f' +bindsym $super+l exec i3lock -i ~/.wallpaper.jpg +#bindsym $super+Shift+w exec firefox +#bindsym $super+Shift+f exec thunar;workspace 3;focus +#bindsym $super+Shift+g exec geany +#bindsym $mod+Control+s exec --no-startup-id systemctl suspend + +#change volume +bindsym XF86AudioRaiseVolume exec amixer -q set Master 5%+ +bindsym XF86AudioLowerVolume exec amixer -q set Master 5%- +bindsym XF86AudioMute exec amixer set Master toggle +bindsym XF86AudioMicMute exec amixer set Capture toggle + +# music control +#bindsym XF86AudioNext exec mpc next +#bindsym XF86AudioPrev exec mpc prev +#bindsym XF86AudioPlay exec mpc toggle +#bindsym XF86AudioStop exec mpc stop + +# kill focused window +bindsym $super+c kill +bindsym $alt+F4 kill + +# change focus +bindsym $super+Left focus left +bindsym $super+Down focus down +bindsym $super+Up focus up +bindsym $super+Right focus right +focus_follows_mouse no + +# move focused window +bindsym $super+Shift+Left move left +bindsym $super+Shift+Down move down +bindsym $super+Shift+Up move up +bindsym $super+Shift+Right move right + +# split in horizontal orientation +bindsym $super+h split h + +# split in vertical orientation +bindsym $super+v split v + +# enter fullscreen mode for the focused container +bindsym $super+f fullscreen toggle + +# change container layout split +bindsym $super+s layout toggle split + +# toggle tiling / floating +bindsym $super+space floating toggle + +# change focus between tiling / floating windows +bindsym $super+Shift+space focus mode_toggle + +# switch to workspace +bindsym $alt+Control+Right workspace next +bindsym $alt+Control+Left workspace prev +bindsym $super+1 workspace 1 +bindsym $super+2 workspace 2 +bindsym $super+3 workspace 3 +bindsym $super+4 workspace 4 +bindsym $super+5 workspace 5 +bindsym $super+6 workspace 6 + +# move focused container to workspace +bindsym $super+Shift+1 move container to workspace 1 +bindsym $super+Shift+2 move container to workspace 2 +bindsym $super+Shift+3 move container to workspace 3 +bindsym $super+Shift+4 move container to workspace 4 +bindsym $super+Shift+5 move container to workspace 5 +bindsym $super+Shift+6 move container to workspace 6 + +# restart i3 inplace (preserves your layout/session, can be used to upgrade i3) +bindsym $super+Shift+r restart + +# exit i3 +bindsym $super+Shift+e exec "i3-nagbar -t warning -m 'Really, exit?' -b 'Yes' 'i3-msg exit'" +bindsym $super+p exec --no-startup-id ~/.config/rofi/bin/applet_powermenu + +# resize window (you can also use the mouse for that) +mode "resize" { + bindsym Left resize shrink width 5 px or 5 ppt + bindsym Down resize grow height 5 px or 5 ppt + bindsym Up resize shrink height 5 px or 5 ppt + bindsym Right resize grow width 5 px or 5 ppt + bindsym Return mode "default" +} +bindsym $super+r mode "resize" + +# Colors +set $blue #1b1e26 +set $yellow #f0d48b +set $grey #b0b287 +set $green #789073 + +# panel +bar { + colors { + #background #2f343f + statusline #2f343f + separator #4b5262 + + background $blue + #statusline $yellow + #separator $green + + # colour of border, background, and text + #focused_workspace #2f343f #bf616a #d8dee8 + #active_workspace #2f343f #2f343f #d8dee8 + #inactive_workspace #2f343f #2f343f #d8dee8 + #urgent_workspacei #2f343f #ebcb8b #2f343f + focused_workspace $blue $blue $yellow + active_workspace $blue $blue $yellow + inactive_workspace $blue $blue $green + urgent_workspacei $blue $blue $grey + } + status_command i3status +} + +# window rules, you can find the window class using xprop +for_window [class="^.*"] border pixel 2 +#assign [class=URxvt] 1 +#assign [class=Firefox|Transmission-gtk] 2 +#assign [class=Thunar|File-roller] 3 +#assign [class=Geany|Evince|Gucharmap|Soffice|libreoffice*] 4 +#assign [class=Audacity|Vlc|mpv|Ghb|Xfburn|Gimp*|Inkscape] 5 +#assign [class=Lxappearance|System-config-printer.py|Lxtask|GParted|Pavucontrol|Exo-helper*|Lxrandr] 6 +for_window [class=Viewnior|feh|Audacious|File-roller|Lxappearance|Lxtask|Pavucontrol|Arandr|Nitrogen|Files] floating enable +for_window [class=URxvt|Firefox|Geany|Evince|Soffice|libreoffice*|mpv|Ghb|Xfburn|Gimp*|Inkscape|Vlc|Lxappearance|Audacity] focus +for_window [class=Xfburn|GParted|System-config-printer.py|Lxtask|Pavucontrol|Exo-helper*|Lxrandr|Arandr|Nitrogen] focus + +# colour of border, background, text, indicator, and child_border +#client.focused #bf616a #2f343f3 #d8dee8 #bf616a #d8dee8 +#client.focused_inactive #2f343f #2f343f #d8dee8 #2f343f #2f343f +#client.unfocused #2f343f #2f343f #d8dee8 #2f343f #2f343f +#client.urgent #2f343f #2f343f #d8dee8 #2f343f #2f343f +#client.placeholder #2f343f #2f343f #d8dee8 #2f343f #2f343f +#client.background #2f343f +client.focused #d1ae54 $blue $yellow $yellow #d1ae54 +client.focused_inactive #d1ae54 $blue $grey $yellow $yellow +client.unfocused $yellow $blue $grey $yellow $yellow +client.urgent $yellow $blue $yellow $yellow $yellow +client.placeholder $yellow $blue $yellow $yellow $yellow +client.background $blue + +# i3-gaps +gaps inner 7 + +# Keybinds for lenovo x1 carbon +#bindsym XF86MonBrightnessUp exec --no-startup-id "pkill rofi; xbacklight -inc 10; ~/.config/rofi/bin/applet_backlight > /dev/null 2>&1 &" +#bindsym XF86MonBrightnessDown exec --no-startup-id "pkill rofi; xbacklight -dec 10; ~/.config/rofi/bin/applet_backlight > /dev/null 2>&1 &" + +bindsym XF86MonBrightnessUp exec --no-startup-id "xbacklight -inc 10" +bindsym XF86MonBrightnessDown exec --no-startup-id "xbacklight -dec 10" + +bindsym XF86Display exec --no-startup-id "arandr" +#bindsym XF86WLAN exec --no-startup-id "~/.config/rofi/bin/menu_network" +bindsym Print exec --no-startup-id "gnome-screenshot --interactive" diff --git a/Common/i3/config/i3status/config b/Common/i3/config/i3status/config new file mode 100644 index 0000000..b3256a2 --- /dev/null +++ b/Common/i3/config/i3status/config @@ -0,0 +1,73 @@ +general { + output_format = "i3bar" + colors = false + markup = pango + interval = 5 + color_good = '#2f343f' + color_degraded = '#ebcb8b' + color_bad = '#ba5e57' +} + +order += "load" +order += "cpu_temperature 0" +#order += "disk /" +#order += "disk /home" +#order += "ethernet enp1s0" +order += "wireless wlp0s20f3" +order += "volume master" +order += "battery 0" +order += "tztime local" + +load { + format = "<span background='#f59335'> %5min Load </span>" +} + +cpu_temperature 0 { + format = "<span background='#bf616a'> %degrees °C </span>" + path = "/sys/class/thermal/thermal_zone0/temp" +} + +disk "/" { + format = "<span background='#fec7cd'> %free Free </span>" +} + +disk "/home" { + format = "<span background='#a1d569'> %free Free </span>" +} + +ethernet enp1s0 { + format_up = "<span background='#88c0d0'> %ip </span>" + format_down = "<span background='#88c0d0'> Disconnected </span>" +} + +wireless wlp0s20f3 { + format_up = "<span background='#b48ead'> %essid </span>" + format_down = "<span background='#b48ead'> Disconnected </span>" +} + +volume master { + format = "<span background='#ebcb8b'> %volume </span>" + format_muted = "<span background='#ebcb8b'> Muted </span>" + device = "default" + mixer = "Master" + mixer_idx = 0 +} + +battery 0 { + last_full_capacity = true + format = "<span background='#a3be8c'> %status %percentage </span>" + format_down = "No Battery" + status_chr = "Charging" + status_bat = "Battery" + status_unk = "Unknown" + status_full = "Charged" + path = "/sys/class/power_supply/BAT%d/uevent" + low_threshold = 10 + #on_click 1 = "exec --no-startup-id ~/.config/rofi/bin/applet_battery" +} + +tztime local { + format = "<span background='#81a1c1'> %time </span>" + format_time = " %a %-d %b %H:%M" +} + diff --git a/Common/i3/urxvt/ext/clipboard b/Common/i3/urxvt/ext/clipboard new file mode 100755 index 0000000..05e1601 --- /dev/null +++ b/Common/i3/urxvt/ext/clipboard @@ -0,0 +1,115 @@ +#! perl -w +# Author: Bert Muennich +# Website: http://www.github.com/muennich/urxvt-perls +# License: GPLv2 + +# Use keyboard shortcuts to copy the selection to the clipboard and to paste +# the clipboard contents (optionally escaping all special characters). +# Requires xsel to be installed! + +# Usage: put the following lines in your .Xdefaults/.Xresources: +# URxvt.perl-ext-common: ...,clipboard +# URxvt.keysym.M-c: perl:clipboard:copy +# URxvt.keysym.M-v: perl:clipboard:paste +# URxvt.keysym.M-C-v: perl:clipboard:paste_escaped + +# Options: +# URxvt.clipboard.autocopy: If true, PRIMARY overwrites clipboard + +# You can also overwrite the system commands to use for copying/pasting. +# The default ones are: +# URxvt.clipboard.copycmd: xsel -ib +# URxvt.clipboard.pastecmd: xsel -ob +# If you prefer xclip, then put these lines in your .Xdefaults/.Xresources: +# URxvt.clipboard.copycmd: xclip -i -selection clipboard +# URxvt.clipboard.pastecmd: xclip -o -selection clipboard +# On Mac OS X, put these lines in your .Xdefaults/.Xresources: +# URxvt.clipboard.copycmd: pbcopy +# URxvt.clipboard.pastecmd: pbpaste + +# The use of the functions should be self-explanatory! + +use strict; + +sub on_start { + my ($self) = @_; + + $self->{copy_cmd} = $self->x_resource('clipboard.copycmd') || 'xsel -ib'; + $self->{paste_cmd} = $self->x_resource('clipboard.pastecmd') || 'xsel -ob'; + + if ($self->x_resource('clipboard.autocopy') eq 'true') { + $self->enable(sel_grab => \&sel_grab); + } + + () +} + +sub copy { + my ($self) = @_; + + if (open(CLIPBOARD, "| $self->{copy_cmd}")) { + my $sel = $self->selection(); + utf8::encode($sel); + print CLIPBOARD $sel; + close(CLIPBOARD); + } else { + print STDERR "error running '$self->{copy_cmd}': $!\n"; + } + + () +} + +sub paste { + my ($self) = @_; + + my $str = `$self->{paste_cmd}`; + if ($? == 0) { + $self->tt_paste($str); + } else { + print STDERR "error running '$self->{paste_cmd}': $!\n"; + } + + () +} + +sub paste_escaped { + my ($self) = @_; + + my $str = `$self->{paste_cmd}`; + if ($? == 0) { + $str =~ s/([!#\$%&\*\(\) ='"\\\|\[\]`~,<>\?])/\\\1/g; + $self->tt_paste($str); + } else { + print STDERR "error running '$self->{paste_cmd}': $!\n"; + } + + () +} + +sub on_action { + my ($self, $action) = @_; + + on_user_command($self, "clipboard:" . $action); +} + +sub on_user_command { + my ($self, $cmd) = @_; + + if ($cmd eq "clipboard:copy") { + $self->copy; + } elsif ($cmd eq "clipboard:paste") { + $self->paste; + } elsif ($cmd eq "clipboard:paste_escaped") { + $self->paste_escaped; + } + + () +} + +sub sel_grab { + my ($self) = @_; + + $self->copy; + + () +} diff --git a/Common/i3/urxvt/ext/keyboard-select b/Common/i3/urxvt/ext/keyboard-select new file mode 100755 index 0000000..78d4a7f --- /dev/null +++ b/Common/i3/urxvt/ext/keyboard-select @@ -0,0 +1,597 @@ +#! perl -w +# Author: Bert Muennich +# Website: http://www.github.com/muennich/urxvt-perls +# License: GPLv2 + +# Use keyboard shortcuts to select and copy text. + +# Usage: put the following lines in your .Xdefaults/.Xresources: +# URxvt.perl-ext-common: ...,keyboard-select +# URxvt.keysym.M-Escape: perl:keyboard-select:activate +# The following line overwrites the default Meta-s binding and allows to +# activate keyboard-select directly in backward search mode: +# URxvt.keysym.M-s: perl:keyboard-select:search + +# Use Meta-Escape to activate selection mode, then use the following keys: +# h/j/k/l: Move cursor left/down/up/right (also with arrow keys) +# g/G/0/^/$/H/M/L/f/F/;/,/w/W/b/B/e/E: More vi-like cursor movement keys +# '/'/?: Start forward/backward search +# n/N: Repeat last search, N: in reverse direction +# Ctrl-f/b: Scroll down/up one screen +# Ctrl-d/u: Scroll down/up half a screen +# v/V/Ctrl-v: Toggle normal/linewise/blockwise selection +# y/Return: Copy selection to primary buffer, Return: quit afterwards +# Y: Copy selected lines to primary buffer or cursor line and quit +# q/Escape: Quit keyboard selection mode + + +use strict; + +sub on_start{ + my ($self) = @_; + + $self->{patterns}{'w'} = qr/\w[^\w\s]|\W\w|\s\S/; + $self->{patterns}{'W'} = qr/\s\S/; + $self->{patterns}{'b'} = qr/.*(?:\w[^\w\s]|\W\w|\s\S)/; + $self->{patterns}{'B'} = qr/.*\s\S/; + $self->{patterns}{'e'} = qr/[^\w\s](?=\w)|\w(?=\W)|\S(?=\s|$)/; + $self->{patterns}{'E'} = qr/\S(?=\s|$)/; + + () +} + + +sub on_action { + my ($self, $action) = @_; + + on_user_command($self, "keyboard-select:" . $action); +} + + +sub on_user_command { + my ($self, $cmd) = @_; + + if (not $self->{active}) { + if ($cmd eq 'keyboard-select:activate') { + activate($self); + } elsif ($cmd eq 'keyboard-select:search') { + activate($self, 1); + } + } + + () +} + + +sub key_press { + my ($self, $event, $keysym, $char) = @_; + my $key = chr($keysym); + + if (lc($key) eq 'c' && $event->{state} & urxvt::ControlMask) { + deactivate($self); + } elsif ($self->{search}) { + if ($keysym == 0xff1b) { + if ($self->{search_mode}) { + deactivate($self); + } else { + $self->{search} = ''; + status_area($self); + } + } elsif ($keysym == 0xff08) { + $self->{search} = substr($self->{search}, 0, -1); + if (not $self->{search} and $self->{search_mode}) { + deactivate($self); + } else { + status_area($self); + } + } elsif ($keysym == 0xff0d || + (lc($key) eq 'm' && $event->{state} & urxvt::ControlMask)) { + my $txt = substr($self->{search}, 1); + if ($txt) { + $self->{pattern} = ($txt =~ m/[[:upper:]]/) ? qr/\Q$txt\E/ : + qr/\Q$txt\E/i; + } elsif ($self->{pattern}) { + delete $self->{pattern}; + } + $self->{search} = ''; + $self->screen_cur($self->{srhcr}, $self->{srhcc}); + if (not find_next($self)) { + if ($self->{search_mode}) { + deactivate($self); + } else { + status_area($self); + } + } + } elsif (length($char) > 0) { + $self->{search} .= $self->locale_decode($char); + my $txt = substr($self->{search}, 1); + if ($txt) { + $self->{pattern} = ($txt =~ m/[[:upper:]]/) ? qr/\Q$txt\E/ : + qr/\Q$txt\E/i; + } elsif ($self->{pattern}) { + delete $self->{pattern}; + } + $self->screen_cur($self->{srhcr}, $self->{srhcc}); + find_next($self); + status_area($self); + } + } elsif ($self->{move_to}) { + if ($keysym == 0xff1b) { + $self->{move_to} = 0; + status_area($self); + } elsif (length($char) > 0) { + $self->{move_to} = 0; + $self->{patterns}{'f-1'} = qr/^.*\Q$key\E/; + $self->{patterns}{'f+1'} = qr/^.+?\Q$key\E/; + move_to($self, ';'); + status_area($self); + } + } elsif ($keysym == 0xff1b || lc($key) eq 'q') { + deactivate($self); + } elsif (lc($key) eq 'y' || $keysym == 0xff0d || + (lc($key) eq 'm' && $event->{state} & urxvt::ControlMask)) { + my $quit = 0; + if ($key eq 'Y' && $self->{select} ne 'l') { + $quit = !$self->{select}; + toggle_select($self, 'l'); + } + if ($self->{select}) { + my ($br, $bc, $er, $ec) = calc_span($self); + $ec = $self->line($er)->l if $self->{select} eq 'l'; + $self->selection_beg($br, $bc); + $self->selection_end($er, $ec); + $self->selection_make($event->{time}, $self->{select} eq 'b'); + if (lc($key) eq 'y') { + $self->selection_beg(1, 0); + $self->selection_end(1, 0); + $self->{select} = ''; + status_area($self); + $self->want_refresh(); + } else { + $quit = 1; + } + } + if ($quit) { + deactivate($self); + } + } elsif ($key eq 'V') { + toggle_select($self, 'l'); + } elsif ($key eq 'v') { + if ($event->{state} & urxvt::ControlMask) { + toggle_select($self, 'b'); + } else { + toggle_select($self, 'n'); + } + } elsif ($key eq 'k' || $keysym == 0xff52) { + move_cursor($self, 'k'); + } elsif ($key eq 'j' || $keysym == 0xff54) { + move_cursor($self, 'j'); + } elsif ($key eq 'h' || $keysym == 0xff51) { + move_cursor($self, 'h'); + } elsif ($key eq 'l' || $keysym == 0xff53) { + move_cursor($self, 'l'); + } elsif ($keysym == 0xff57) { + move_cursor($self, '$'); + } elsif ($keysym == 0xff50) { + move_cursor($self, '^'); + } elsif ('gG0^$HML' =~ m/\Q$key\E/ || + ('fbdu' =~ m/\Q$key\E/ && $event->{state} & urxvt::ControlMask)) { + move_cursor($self, $key); + } elsif (lc($key) eq 'f') { + $self->{move_to} = 1; + $self->{move_dir} = $key eq 'F' ? -1 : 1; + status_area($self, $key); + } elsif (';,wWbBeE' =~ m/\Q$key\E/) { + move_to($self, $key); + } elsif ($key eq '/' || $key eq '?') { + $self->{search} = $key; + $self->{search_dir} = $key eq '?' ? -1 : 1; + ($self->{srhcr}, $self->{srhcc}) = $self->screen_cur(); + status_area($self); + } elsif (lc($key) eq 'n') { + find_next($self, $self->{search_dir} * ($key eq 'N' ? -1 : 1)); + } + + return 1; +} + + +sub move_cursor { + my ($self, $key) = @_; + my ($cr, $cc) = $self->screen_cur(); + my $line = $self->line($cr); + + if ($key eq 'k' && $line->beg > $self->top_row) { + $cr = $line->beg - 1; + } elsif ($key eq 'j' && $line->end < $self->nrow - 1) { + $cr = $line->end + 1; + } elsif ($key eq 'h' && $self->{offset} > 0) { + $self->{offset} = $line->offset_of($cr, $cc) - 1; + $self->{dollar} = 0; + } elsif ($key eq 'l' && $self->{offset} < $line->l - 1) { + ++$self->{offset}; + } elsif ($key eq 'f' || $key eq 'd') { + my $vs = $self->view_start() + + ($key eq 'd' ? $self->nrow / 2 : $self->nrow - 1); + $vs = 0 if $vs > 0; + $cr += $vs - $self->view_start($vs); + } elsif ($key eq 'b' || $key eq 'u') { + my $vs = $self->view_start() - + ($key eq 'u' ? $self->nrow / 2 : $self->nrow - 1); + $vs = $self->top_row if $vs < $self->top_row; + $cr += $vs - $self->view_start($vs); + } elsif ($key eq 'g') { + ($cr, $self->{offset}) = ($self->top_row, 0); + $self->{dollar} = 0; + } elsif ($key eq 'G') { + ($cr, $self->{offset}) = ($self->nrow - 1, 0); + $self->{dollar} = 0; + } elsif ($key eq '0') { + $self->{offset} = 0; + $self->{dollar} = 0; + } elsif ($key eq '^') { + my $ltxt = $self->special_decode($line->t); + while ($ltxt =~ s/^( *)\t/$1 . " " x (8 - length($1) % 8)/e) {} + $self->{offset} = $ltxt =~ m/^ +/ ? $+[0] : 0; + $self->{dollar} = 0; + } elsif ($key eq '$') { + my $co = $line->offset_of($cr, $cc); + $self->{dollar} = $co + 1; + $self->{offset} = $line->l - 1; + } elsif ($key eq 'H') { + $cr = $self->view_start(); + } elsif ($key eq 'M') { + $cr = $self->view_start() + $self->nrow / 2; + } elsif ($key eq 'L') { + $cr = $self->view_start() + $self->nrow - 1; + } + + $line = $self->line($cr); + $cc = $self->{dollar} || $self->{offset} >= $line->l ? $line->l - 1 : + $self->{offset}; + $self->screen_cur($line->coord_of($cc)); + + status_area($self); + $self->want_refresh(); + + () +} + + +sub move_to { + my ($self, $key) = @_; + my ($cr, $cc) = $self->screen_cur(); + my $line = $self->line($cr); + my $offset = $self->{offset}; + my ($dir, $pattern); + my ($wrap, $found) = (0, 0); + + if ($key eq ';' || $key eq ',') { + $dir = $self->{move_dir} * ($key eq ',' ? -1 : 1); + $pattern = $self->{patterns}{sprintf('f%+d', $dir)}; + return if not $pattern; + } else { + if (lc($key) eq 'b') { + $dir = -1; + } else { + $dir = 1; + ++$offset if lc($key) eq 'e'; + } + $pattern = $self->{patterns}{$key}; + $wrap = 1; + } + + if ($dir > 0) { + NEXTDOWN: my $text = substr($line->t, $offset); + if ($text =~ m/$pattern/) { + $offset += $+[0] - 1; + $found = 1; + } elsif ($wrap && $line->end + 1 < $self->nrow) { + $cr = $line->end + 1; + $line = $self->line($cr); + $offset = 0; + if (lc($key) eq 'e') { + goto NEXTDOWN; + } else { + $found = 1; + } + } + } elsif ($dir < 0) { + NEXTUP: my $text = substr($line->t, 0, $offset); + if ($text =~ m/$pattern/) { + $offset += $+[0] - length($text) - 1; + $found = 1; + } elsif ($wrap) { + if ($offset > 0) { + $offset = 0; + $found = 1; + } elsif ($line->beg > $self->top_row) { + $cr = $line->beg - 1; + $line = $self->line($cr); + $offset = $line->l; + goto NEXTUP; + } + } + } + + if ($found) { + $self->{dollar} = 0; + $self->{offset} = $offset; + $self->screen_cur($line->coord_of($offset)); + $self->want_refresh(); + } + + () +} + + +sub find_next { + my ($self, $dir) = @_; + + return if not $self->{pattern}; + $dir = $self->{search_dir} if not $dir; + + my ($cr, $cc) = $self->screen_cur(); + my $line = $self->line($cr); + my $offset = $line->offset_of($cr, $cc); + my $text; + my $found = 0; + + ++$offset if $dir > 0; + + while (not $found) { + if ($dir > 0) { + $text = substr($line->t, $offset); + if ($text =~ m/$self->{pattern}/) { + $found = 1; + $offset += $-[0]; + } else { + last if $line->end >= $self->nrow; + $line = $self->line($line->end + 1); + $offset = 0; + } + } else { + $text = substr($line->t, 0, $offset); + if ($text =~ m/$self->{pattern}/) { + $found = 1; + $offset = $-[0] while $text =~ m/$self->{pattern}/g; + } else { + last if $line->beg <= $self->top_row; + $line = $self->line($line->beg - 1); + $offset = $line->l; + } + } + } + + if ($found) { + $self->{dollar} = 0; + $self->{offset} = $offset; + $self->screen_cur($line->coord_of($offset)); + status_area($self); + $self->want_refresh(); + } + + return $found; +} + + +sub tt_write { + return 1; +} + + +sub refresh { + my ($self) = @_; + my ($cr, $cc) = $self->screen_cur(); + + # scroll the current cursor position into visible area + if ($cr < $self->view_start()) { + $self->view_start($cr); + } elsif ($cr >= $self->view_start() + $self->nrow) { + $self->view_start($cr - $self->nrow + 1); + } + + if ($self->{select}) { + my ($hl, $reverse_cursor); + my ($br, $bc, $er, $ec) = calc_span($self); + + if ($self->x_resource('highlightColor')) { + $hl = urxvt::RS_Sel; + $reverse_cursor = 0; + } else { + $hl = urxvt::RS_RVid; + $reverse_cursor = $self->{select} ne 'l'; + } + if ($self->{select} eq 'b') { + my $co = $self->line($cr)->offset_of($cr, $cc); + my $dollar = $self->{dollar} && $co >= $self->{dollar} - 1; + + my $r = $br; + while ($r <= $er) { + my $line = $self->line($r); + if ($bc < $line->l) { + $ec = $line->l if $dollar; + my ($br, $bc) = $line->coord_of($bc); + my ($er, $ec) = $line->coord_of($ec <= $line->l ? $ec : $line->l); + $self->scr_xor_span($br, $bc, $er, $ec, $hl); + } elsif ($r == $cr) { + $reverse_cursor = 0; + } + $r = $line->end + 1; + } + } else { + $self->scr_xor_span($br, $bc, $er, $ec, $hl); + } + + if ($reverse_cursor) { + # make the cursor visible again + $self->scr_xor_span($cr, $cc, $cr, $cc + 1, $hl); + } + } + + () +} + + +sub activate { + my ($self, $search) = @_; + + $self->{active} = 1; + + $self->{select} = ''; + $self->{dollar} = 0; + $self->{move_to} = 0; + + if ($search) { + $self->{search} = '?'; + $self->{search_dir} = -1; + $self->{search_mode} = 1; + } else { + $self->{search} = ''; + $self->{search_mode} = 0; + } + + ($self->{oldcr}, $self->{oldcc}) = $self->screen_cur(); + ($self->{srhcr}, $self->{srhcc}) = $self->screen_cur(); + $self->{old_view_start} = $self->view_start(); + $self->{old_pty_ev_events} = $self->pty_ev_events(urxvt::EV_NONE); + + my $line = $self->line($self->{oldcr}); + $self->{offset} = $line->offset_of($self->{oldcr}, $self->{oldcc}); + + $self->selection_beg(1, 0); + $self->selection_end(1, 0); + + $self->enable( + key_press => \&key_press, + refresh_begin => \&refresh, + refresh_end => \&refresh, + tt_write => \&tt_write, + ); + + if ($self->{offset} >= $line->l) { + $self->{offset} = $line->l > 0 ? $line->l - 1 : 0; + $self->screen_cur($line->coord_of($self->{offset})); + $self->want_refresh(); + } + + $self->{overlay_len} = 0; + status_area($self); + + () +} + + +sub deactivate { + my ($self) = @_; + + $self->selection_beg(1, 0); + $self->selection_end(1, 0); + + delete $self->{overlay} if $self->{overlay}; + + $self->disable("key_press", "refresh_begin", "refresh_end", "tt_write"); + $self->screen_cur($self->{oldcr}, $self->{oldcc}); + $self->view_start($self->{old_view_start}); + $self->pty_ev_events($self->{old_pty_ev_events}); + + $self->want_refresh(); + + $self->{active} = 0; + + () +} + + +sub status_area { + my ($self, $extra) = @_; + my ($stat, $stat_len); + + if ($self->{search}) { + $stat_len = $self->ncol; + $stat = $self->{search} . ' ' x ($stat_len - length($self->{search})); + } else { + if ($self->{select}) { + $stat = "-V" . ($self->{select} ne 'n' ? uc($self->{select}) : "") . "- "; + } + + if ($self->top_row == 0) { + $stat .= "All"; + } elsif ($self->view_start() == $self->top_row) { + $stat .= "Top"; + } elsif ($self->view_start() == 0) { + $stat .= "Bot"; + } else { + $stat .= sprintf("%2d%%", + ($self->top_row - $self->view_start) * 100 / $self->top_row); + } + + $stat = "$extra $stat" if $extra; + $stat_len = length($stat); + } + + if (!$self->{overlay} || $self->{overlay_len} != $stat_len) { + delete $self->{overlay} if $self->{overlay}; + $self->{overlay} = $self->overlay(-1, -1, $stat_len, 1, + urxvt::OVERLAY_RSTYLE, 0); + $self->{overlay_len} = $stat_len; + } + + $self->{overlay}->set(0, 0, $self->special_encode($stat)); + $self->{overlay}->show(); + + () +} + + +sub toggle_select { + my ($self, $mode) = @_; + + if ($self->{select} eq $mode) { + $self->{select} = ''; + } else { + if (not $self->{select}) { + ($self->{ar}, $self->{ac}) = $self->screen_cur(); + } + $self->{select} = $mode; + } + + status_area($self); + $self->want_refresh(); + + () +} + + +sub calc_span { + my ($self) = @_; + my ($cr, $cc) = $self->screen_cur(); + my ($br, $bc, $er, $ec); + + if ($self->{select} eq 'b') { + $br = $self->line($cr)->beg; + $bc = $self->line($cr)->offset_of($cr, $cc); + $er = $self->line($self->{ar})->beg; + $ec = $self->line($self->{ar})->offset_of($self->{ar}, $self->{ac}); + ($br, $er) = ($er, $br) if $br > $er; + ($bc, $ec) = ($ec, $bc) if $bc > $ec; + } else { + if ($cr < $self->{ar}) { + ($br, $bc, $er, $ec) = ($cr, $cc, $self->{ar}, $self->{ac}); + } elsif ($cr > $self->{ar}) { + ($br, $bc, $er, $ec) = ($self->{ar}, $self->{ac}, $cr, $cc); + } else { + ($br, $er) = ($cr, $cr); + ($bc, $ec) = $cc < $self->{ac} ? ($cc, $self->{ac}) : ($self->{ac}, $cc); + } + } + + if ($self->{select} eq 'l') { + ($br, $er) = ($self->line($br)->beg, $self->line($er)->end); + ($bc, $ec) = (0, $self->ncol); + } else { + ++$ec; + } + + return ($br, $bc, $er, $ec); +} diff --git a/Common/i3/urxvt/ext/url-select b/Common/i3/urxvt/ext/url-select new file mode 100755 index 0000000..34637bb --- /dev/null +++ b/Common/i3/urxvt/ext/url-select @@ -0,0 +1,408 @@ +#! perl -w +# Author: Bert Muennich +# Website: http://www.github.com/muennich/urxvt-perls +# Based on: http://www.jukie.net/~bart/blog/urxvt-url-yank +# License: GPLv2 + +# Use keyboard shortcuts to select URLs. +# This should be used as a replacement for the default matcher extension, +# it also makes URLs clickable with the middle mouse button. + +# Usage: put the following lines in your .Xdefaults/.Xresources: +# URxvt.perl-ext-common: ...,url-select +# URxvt.keysym.M-u: perl:url-select:select_next + +# Use Meta-u to activate URL selection mode, then use the following keys: +# j/k: Select next downward/upward URL (also with arrow keys) +# g/G: Select first/last URL (also with home/end key) +# o/Return: Open selected URL in browser, Return: deactivate afterwards +# y: Copy (yank) selected URL and deactivate selection mode +# q/Escape: Deactivate URL selection mode + +# Options: +# URxvt.url-select.autocopy: If true, selected URLs are copied to PRIMARY +# URvxt.url-select.button: Mouse button to click-open URLs (default: 2) +# URxvt.url-select.launcher: Browser/command to open selected URL with +# URxvt.url-select.underline: If set to true, all URLs get underlined + +use strict; + +# The custom rendition bit to use for marking the cell as being underlined +# by us so we can unset it again after a line has changed. +use constant UNDERLINED => 1<<3; # arbitrarily chosen in hope of no collision + +sub on_start { + my ($self) = @_; + + # read resource settings + if ($self->x_resource('url-select.launcher')) { + @{$self->{browser}} = split /\s+/, $self->x_resource('url-select.launcher'); + } else { + @{$self->{browser}} = ('x-www-browser'); + } + if ($self->x_resource('url-select.underline') eq 'true') { + $self->enable(line_update => \&line_update); + } + if ($self->x_resource('url-select.autocopy') eq 'true') { + $self->{autocopy} = 1; + } + + $self->{state} = 0; + + for my $mod (split '', $self->x_resource("url-select.button") || + $self->x_resource("matcher.button") || 2) { + if ($mod =~ /^\d+$/) { + $self->{button} = $mod; + } elsif ($mod eq "C") { + $self->{state} |= urxvt::ControlMask; + } elsif ($mod eq "S") { + $self->{state} |= urxvt::ShiftMask; + } elsif ($mod eq "M") { + $self->{state} |= $self->ModMetaMask; + } elsif ($mod ne "-" && $mod ne " ") { + warn("invalid button/modifier in $self->{_name}<$self->{argv}[0]>: $mod\n"); + } + } + + if ($self->x_resource('matcher.pattern')) { + @{$self->{pattern}} = ($self->x_resource('matcher.pattern')); + } elsif ($self->x_resource('matcher.pattern.0')) { + my $current = 0; + + while (defined (my $res = $self->x_resource("matcher.pattern.$current"))) { + $res = $self->locale_decode($res); + utf8::encode $res; + push @{$self->{pattern}}, qr($res)x; + $current++; + } + } else { + @{$self->{pattern}} = qr{ + (?:https?://|ftp://|news://|mailto:|file://|\bwww\.) + [\w\-\@;\/?:&=%\$.+!*\x27,~#]* + ( + \([\w\-\@;\/?:&=%\$.+!*\x27,~#]*\) # Allow a pair of matched parentheses + | # + [\w\-\@;\/?:&=%\$+*~] # exclude some trailing characters (heuristic) + )+ + }x; + } + + () +} + + +sub line_update { + my ($self, $row) = @_; + + my $line = $self->line($row); + my $text = $line->t; + my $rend = $line->r; + + # clear all underlines that were set by us + for (@$rend) { + if (urxvt::GET_CUSTOM($_) & UNDERLINED) { + $_ = urxvt::SET_CUSTOM($_, urxvt::GET_CUSTOM($_) & ~UNDERLINED) & + ~urxvt::RS_Uline; + } + } + + for my $pattern (@{$self->{pattern}}) { + while ($text =~ /$pattern/g) { + my $url = $&; + my ($beg, $end) = ($-[0], $+[0] - 1); + + for (@{$rend}[$beg .. $end]) { + unless ($_ & urxvt::RS_Uline) { + $_ = urxvt::SET_CUSTOM($_, urxvt::GET_CUSTOM($_) | UNDERLINED); + $_ |= urxvt::RS_Uline; + } + } + } + } + + $line->r($rend); + + () +} + +sub on_action { + my ($self, $action) = @_; + + on_user_command($self, "url-select:" . $action); +} + + +sub on_user_command { + my ($self, $cmd) = @_; + + if ($cmd eq 'url-select:select_next') { + if (not $self->{active}) { + activate($self); + } + select_next($self, -1); + } + + () +} + + +sub key_press { + my ($self, $event, $keysym) = @_; + my $char = chr($keysym); + + if ($keysym == 0xff1b || lc($char) eq 'q' || + (lc($char) eq 'c' && $event->{state} & urxvt::ControlMask)) { + deactivate($self); + } elsif ($keysym == 0xff0d || $char eq 'o' || + (lc($char) eq 'm' && $event->{state} & urxvt::ControlMask)) { + $self->exec_async(@{$self->{browser}}, ${$self->{found}[$self->{n}]}[4]); + deactivate($self) unless $char eq 'o'; + } elsif ($char eq 'y') { + my $found = $self->{found}[$self->{n}]; + $self->selection_beg(${$found}[0], ${$found}[1]); + $self->selection_end(${$found}[2], ${$found}[3]); + $self->selection_make($event->{time}); + $self->selection_beg(1, 0); + $self->selection_end(1, 0); + deactivate($self); + } elsif ($char eq 'k' || $keysym == 0xff52 || $keysym == 0xff51) { + select_next($self, -1, $event); + } elsif ($char eq 'j' || $keysym == 0xff54 || $keysym == 0xff53) { + select_next($self, 1, $event); + } elsif ($char eq 'g' || $keysym == 0xff50) { + $self->{row} = $self->top_row - 1; + delete $self->{found}; + select_next($self, 1, $event); + } elsif ($char eq 'G' || $keysym == 0xff57) { + $self->{row} = $self->nrow; + delete $self->{found}; + select_next($self, -1, $event); + } + + return 1; +} + + +sub on_button_press { + my ($self, $event) = @_; + + my $mask = $self->ModLevel3Mask | $self->ModMetaMask | + urxvt::ShiftMask | urxvt::ControlMask; + + if ($event->{button} == $self->{button} && ($event->{state} & $mask) == $self->{state}) { + my $col = $event->{col}; + my $row = $event->{row}; + my $line = $self->line($row); + my $text = $line->t; + + for my $pattern (@{$self->{pattern}}) { + while ($text =~ /$pattern/g) { + my ($url, $beg, $end) = ($&, $-[0], $+[0]); + --$end if $url =~ s/["')]$//; + + if ($col >= $beg && $col <= $end) { + $self->{button_pressed} = 1; + $self->{button_col} = $col; + $self->{button_row} = $row; + $self->{button_url} = $url; + return 1; + } + } + } + } + + () +} + +sub on_button_release { + my ($self, $event) = @_; + + if ($self->{button_pressed} && $event->{button} == $self->{button}) { + my $col = $event->{col}; + my $row = $event->{row}; + + $self->{button_pressed} = 0; + + if ($col == $self->{button_col} && $row == $self->{button_row}) { + $self->exec_async(@{$self->{browser}}, $self->{button_url}); + return 1; + } + } + + () +} + + +sub select_next { + # $dir < 0: up, > 0: down + my ($self, $dir, $event) = @_; + my $row = $self->{row}; + + if (($dir < 0 && $self->{n} > 0) || + ($dir > 0 && $self->{n} < $#{ $self->{found} })) { + # another url on current line + $self->{n} += $dir; + hilight($self); + if ($self->{autocopy}) { + my $found = $self->{found}[$self->{n}]; + $self->selection_beg(${$found}[0], ${$found}[1]); + $self->selection_end(${$found}[2], ${$found}[3]); + $self->selection_make($event->{time}); + $self->selection_beg(1, 0); + $self->selection_end(1, 0); + } + return; + } + + while (($dir < 0 && $row > $self->top_row) || + ($dir > 0 && $row < $self->nrow - 1)) { + my $line = $self->line($row); + $row = ($dir < 0 ? $line->beg : $line->end) + $dir; + $line = $self->line($row); + my $text = $line->t; + + for my $pattern (@{$self->{pattern}}) { + if ($text =~ /$pattern/g) { + delete $self->{found}; + + do { + my ($beg, $end) = ($-[0], $+[0]); + push @{$self->{found}}, [$line->coord_of($beg), + $line->coord_of($end), substr($text, $beg, $end - $beg)]; + } while ($text =~ /$pattern/g); + + $self->{row} = $row; + $self->{n} = $dir < 0 ? $#{$self->{found}} : 0; + hilight($self); + if ($self->{autocopy}) { + my $found = $self->{found}[$self->{n}]; + $self->selection_beg(${$found}[0], ${$found}[1]); + $self->selection_end(${$found}[2], ${$found}[3]); + $self->selection_make($event->{time}); + $self->selection_beg(1, 0); + $self->selection_end(1, 0); + } + return; + } + } + } + + deactivate($self) unless $self->{found}; + + () +} + + +sub hilight { + my ($self) = @_; + + if ($self->{found}) { + if ($self->{row} < $self->view_start() || + $self->{row} >= $self->view_start() + $self->nrow) { + # scroll selected url into visible area + my $top = $self->{row} - ($self->nrow >> 1); + $self->view_start($top < 0 ? $top : 0); + } + + status_area($self); + $self->want_refresh(); + } + + () +} + + +sub refresh { + my ($self) = @_; + + if ($self->{found}) { + if ($self->x_resource('highlightColor')) { + $self->scr_xor_span(@{$self->{found}[$self->{n}]}[0 .. 3], urxvt::RS_Sel); + } else { + $self->scr_xor_span(@{$self->{found}[$self->{n}]}[0 .. 3], urxvt::RS_RVid); + } + } + + () +} + + +sub status_area { + my ($self) = @_; + + my $row = $self->{row} < 0 ? + $self->{row} - $self->top_row : abs($self->top_row) + $self->{row}; + my $text = sprintf("%d,%d ", $row + 1, $self->{n} + 1); + + if ($self->top_row == 0) { + $text .= "All"; + } elsif ($self->view_start() == $self->top_row) { + $text .= "Top"; + } elsif ($self->view_start() == 0) { + $text .= "Bot"; + } else { + $text .= sprintf("%2d%", + ($self->top_row - $self->view_start) * 100 / $self->top_row); + } + + my $text_len = length($text); + + if ($self->{overlay_len} != $text_len) { + delete $self->{overlay} if $self->{overlay}; + $self->{overlay} = $self->overlay(-1, -1, $text_len, 1, + urxvt::OVERLAY_RSTYLE, 0); + $self->{overlay_len} = $text_len; + } + + $self->{overlay}->set(0, 0, $self->special_encode($text)); + $self->{overlay}->show(); + + () +} + + +sub tt_write { + return 1; +} + + +sub activate { + my ($self) = @_; + + $self->{active} = 1; + + $self->{row} = $self->view_start() + $self->nrow; + $self->{n} = 0; + $self->{overlay_len} = 0; + $self->{button_pressed} = 0; + + $self->{view_start} = $self->view_start(); + $self->{pty_ev_events} = $self->pty_ev_events(urxvt::EV_NONE); + + $self->enable( + key_press => \&key_press, + refresh_begin => \&refresh, + refresh_end => \&refresh, + tt_write => \&tt_write, + ); + + () +} + + +sub deactivate { + my ($self) = @_; + + $self->disable("key_press", "refresh_begin", "refresh_end", "tt_write"); + $self->view_start($self->{view_start}); + $self->pty_ev_events($self->{pty_ev_events}); + + delete $self->{overlay} if $self->{overlay}; + delete $self->{found} if $self->{found}; + + $self->want_refresh(); + + $self->{active} = 0; + + () +} diff --git a/Common/i3/urxvt/urxvt b/Common/i3/urxvt/urxvt new file mode 120000 index 0000000..e98a3bb --- /dev/null +++ b/Common/i3/urxvt/urxvt @@ -0,0 +1 @@ +/home/jakob/_code/dotfiles/Common/i3/urxvt
\ No newline at end of file diff --git a/Common/i3/xsettingsd b/Common/i3/xsettingsd new file mode 100755 index 0000000..8499496 --- /dev/null +++ b/Common/i3/xsettingsd @@ -0,0 +1,4 @@ +Xft/Hinting 1 +Xft/RGBA "rgb" +Xft/HintStyle "hintslight" +Xft/Antialias 1 |