├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── conf ├── .gitignore ├── README.md ├── Xresources ├── accounts.nix ├── default.nix ├── desktop.nix ├── dircolors ├── dunstrc ├── hacking-lab-vpn.crt ├── hacking-lab.ovpn ├── nixpkgs.nix ├── patches │ ├── aspell-tex2.patch │ ├── grep-fix-splice-einval.patch │ ├── i3lock-margins.patch │ └── i3lock-ready.patch ├── services.nix └── urxvt-perl │ ├── clipboard │ ├── keyboard-select │ └── url-select ├── configuration.nix ├── default.nix ├── expr ├── README.md ├── armagetronad │ ├── coler_auto_completion.patch │ └── default.nix ├── asurocon │ └── default.nix ├── default.nix ├── esu │ └── default.nix ├── lock-suspend │ ├── default.nix │ └── inhibitor.py ├── lock │ └── default.nix ├── mfcj430w-driver │ └── default.nix ├── nixos-sync │ ├── default.nix │ └── nixos-sync.sh ├── radare2-git │ └── default.nix └── softwarechallenge-gui │ ├── 2014.nix │ ├── 2015.nix │ └── 2016.nix ├── system └── hardware-overrides-l540.nix └── vm-accounts.nix /.gitignore: -------------------------------------------------------------------------------- 1 | /hardware-configuration.nix 2 | /hardware-overrides.nix 3 | /expr/softwarechallenge-gui/plugin2015.jar 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bennofs/etc-nixos/5fe80d256d0101b1e73c9036d0a7ae6cee2c4267/.gitmodules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017 Benno Fünfstück 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NixOS configuration 2 | 3 | This is the configuration for my NixOS system. Except the hardware-configuration.nix file, this 4 | contains all files from /etc/nixos. 5 | -------------------------------------------------------------------------------- /conf/.gitignore: -------------------------------------------------------------------------------- 1 | /accounts 2 | -------------------------------------------------------------------------------- /conf/README.md: -------------------------------------------------------------------------------- 1 | conf 2 | ==== 3 | 4 | This directory contains the configuration files for my nixos system. 5 | -------------------------------------------------------------------------------- /conf/Xresources: -------------------------------------------------------------------------------- 1 | *international: true 2 | URxvt*.scrollBar: false 3 | URxvt*.depth: 32 4 | URxvt*font: xft:Source Code Pro:size=10, xft:DejaVu Sans:size=8, xft:Free Mono:size=10 5 | URxvt*perl-lib: /etc/nixos/conf/urxvt-perl 6 | URxvt*perl-ext-common: default,clipboard,url-select,keyboard-select 7 | URxvt.keysym.Control-f: perl:keyboard-select:search 8 | URxvt.keysym.Control-s: perl:keyboard-select:activate 9 | URxvt.keysym.Mod1-u: perl:url-select:select_next 10 | URxvt.keysym.Mod1-x: perl:clipboard:copy 11 | URxvt.keysym.Mod1-y: perl:clipboard:paste 12 | URxvt.url-select.launcher: xdg-open 13 | URxvt.url-select.underline: true 14 | 15 | 16 | ! Solarized color scheme for the X Window System 17 | ! 18 | ! http://ethanschoonover.com/solarized 19 | 20 | 21 | ! Common 22 | 23 | #define S_yellow #b58900 24 | #define S_orange #cb4b16 25 | #define S_red #dc322f 26 | #define S_magenta #d33682 27 | #define S_violet #6c71c4 28 | #define S_blue #268bd2 29 | #define S_cyan #2aa198 30 | #define S_green #859900 31 | 32 | 33 | ! Dark 34 | 35 | !#define S_base03 #002b36 36 | !#define S_base02 #073642 37 | !#define S_base01 #586e75 38 | !#define S_base00 #657b83 39 | !#define S_base0 #839496 40 | !#define S_base1 #93a1a1 41 | !#define S_base2 #eee8d5 42 | !#define S_base3 #fdf6e3 43 | 44 | 45 | ! Light 46 | 47 | #define S_base03 #fdf6e3 48 | #define S_base02 #eee8d5 49 | #define S_base01 #93a1a1 50 | #define S_base00 #839496 51 | #define S_base0 #657b83 52 | #define S_base1 #586e75 53 | #define S_base2 #073642 54 | #define S_base3 #002b36 55 | 56 | URxvt*background: S_base03 57 | URxvt*foreground: S_base0 58 | URxvt*cursorColor: S_base1 59 | URxvt*pointerColorBackground: S_base01 60 | URxvt*pointerColorForeground: S_base1 61 | URxvt.intensityStyles: false 62 | 63 | URxvt*color0: S_base02 64 | URxvt*color1: S_red 65 | URxvt*color2: S_green 66 | URxvt*color3: S_yellow 67 | URxvt*color4: S_blue 68 | URxvt*color5: S_magenta 69 | URxvt*color6: S_cyan 70 | URxvt*color7: S_base2 71 | URxvt*color8: S_base03 72 | URxvt*color9: S_orange 73 | URxvt*color10: S_base01 74 | URxvt*color11: S_base00 75 | URxvt*color12: S_base0 76 | URxvt*color13: S_violet 77 | URxvt*color14: S_base1 78 | URxvt*color15: S_base3 79 | -------------------------------------------------------------------------------- /conf/accounts.nix: -------------------------------------------------------------------------------- 1 | { ... }: { 2 | 3 | users.mutableUsers = false; 4 | security.sudo.enable = true; 5 | 6 | users.extraUsers.bennofs = { 7 | uid = 1000; 8 | description = "Benno Fünfstück"; 9 | isNormalUser = true; 10 | createHome = true; 11 | home = "/home"; 12 | extraGroups = ["wheel" "docker" "libvirtd" ]; 13 | passwordFile = "/etc/local/accounts/bennofs"; 14 | subGidRanges = [ { count = 1000; startGid = 100000; } ]; 15 | subUidRanges = [ { count = 1000; startUid = 100000; } ]; 16 | }; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /conf/default.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, expr, ... }: 2 | 3 | with builtins; with pkgs.lib; { 4 | 5 | imports = [ 6 | ./desktop.nix 7 | ./services.nix 8 | ./accounts.nix 9 | ]; 10 | 11 | # Available packages 12 | environment.systemPackages = with pkgs; 13 | [ # Version control / archiving 14 | git gitAndTools.hub mercurial bazaar subversion 15 | unzip zip unrar p7zip dtrx 16 | 17 | # Debugging / monitoring / analyzing 18 | htop iotop powertop 19 | ltrace strace linuxPackages.perf 20 | pciutils lshw smartmontools usbutils 21 | 22 | # Networking 23 | inetutils wireshark wget nix-prefetch-scripts 24 | 25 | # Linux shell utils 26 | pmutils psmisc which file binutils bc utillinuxCurses exfat dosfstools 27 | patchutils moreutils 28 | 29 | # Desktop utils 30 | scrot xsel xlibs.xbacklight arandr wpa_supplicant_gui expr.lock pavucontrol paprefs 31 | 32 | # Command line programs 33 | k2pdfopt ncmpcpp mpc_cli beets wpa_supplicant mp3gain mpv 34 | fish haskellPackages.themplate abcde vorbisgain dfc ripgrep 35 | aspell weechat 36 | 37 | # Man pages 38 | man man-pages posix_man_pages stdman 39 | 40 | # Development tools 41 | nix-repl llvm haskellPackages.ghc 42 | 43 | # Desktop applications 44 | xfce.thunar gimp skype libreoffice calibre emacs 45 | keepassx2 zathura rxvt_unicode chromium steam vlc 46 | 47 | # Games 48 | expr.armagetronad steam 49 | ]; 50 | 51 | boot.cleanTmpDir = true; 52 | boot.kernel.sysctl = { 53 | "kernel.dmesg_restrict" = true; 54 | "kernel.yama.ptrace_scope" = 1; 55 | }; 56 | hardware.pulseaudio.enable = true; 57 | hardware.pulseaudio.support32Bit = true; 58 | hardware.pulseaudio.package = pkgs.pulseaudioFull; 59 | hardware.bluetooth.enable = true; 60 | hardware.opengl.driSupport32Bit = true; 61 | 62 | services.udev.packages = with pkgs; [ 63 | # Enable Android udev rules 64 | # This is needed so that the android device nodes in /dev have 65 | # the correct access levels (they will be managed by systemd-logind/udevd) 66 | android-udev-rules 67 | ]; 68 | services.udev.extraRules = '' 69 | # AREXX USB-IR-Transceiver. For flashing ASURO robot 70 | SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ENV{ID_REMOTE_CONTROL}="1" 71 | 72 | # Wiko android devices 73 | ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", SYMLINK+="libmtp-%k", ENV{ID_MTP_DEVICE}="1", ENV{ID_MEDIA_PLAYER}="1" 74 | 75 | # set deadline scheduler for non-rotating disks 76 | ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="deadline" 77 | ''; 78 | 79 | # Environment variables 80 | environment.variables = { 81 | BROWSER ="${pkgs.chromium}/bin/chromium"; 82 | EDITOR="${pkgs.emacs}/bin/emacsclient -c"; 83 | SHELL = "${pkgs.fish}/bin/fish"; 84 | }; 85 | 86 | # Ugh, the default 'extraInit' has code to override ASPELL_DICTS, so we need 87 | # to set our ASPELL_DICT environment variable after that code has executed. 88 | # shellInit is executed after extraInit. 89 | environment.shellInit = 90 | let 91 | allDicts = pkgs.buildEnv { 92 | name = "all-dictionaries"; 93 | paths = builtins.attrValues pkgs.aspellDicts; 94 | pathsToLink = ["/lib"]; 95 | }; 96 | in ''export ASPELL_CONF="dict-dir ${allDicts}/lib/aspell"''; 97 | 98 | # Make SSL root certificates used by Mozilla Firefox available 99 | environment.etc."ssl/certs/mozilla.crt" = { 100 | source = pkgs.fetchurl { 101 | url = "http://curl.haxx.se/ca/cacert.pem"; 102 | sha256 = "1l4xzr16vjdxcpj1fl3qrn8srh7ni3cl5fabwrkd8as3njvqm377"; 103 | }; 104 | mode = "444"; 105 | }; 106 | 107 | environment.etc."sync" = { 108 | source = expr.nixos-sync (config.system.build.nixos-rebuild); 109 | mode = "500"; 110 | }; 111 | 112 | environment.etc."wpa_supplicant.conf" = { 113 | mode = "symlink"; 114 | source = "/etc/local/wpa_supplicant.conf"; 115 | }; 116 | 117 | # Setup /home 118 | system.activationScripts.homeUser = stringAfter [ "users" ] '' 119 | chown bennofs:users /home 120 | ''; 121 | 122 | # Make sure /run/media/bennofs exists 123 | system.activationScripts.mediaMountPoint = '' 124 | mkdir -p /run/media/bennofs 125 | chown bennofs:users /run/media/bennofs 126 | ''; 127 | 128 | 129 | # Extra environment variables 130 | environment.extraInit = '' 131 | export PATH="$HOME/.local/bin:$PATH" 132 | ''; 133 | 134 | environment.loginShellInit = '' 135 | 136 | if [ ! -d /home/.git ]; then 137 | ( 138 | cd /home 139 | git=${pkgs.git}/bin/git 140 | $git init &> /tmp/git-init 141 | $git remote add origin https://github.com/bennofs/dotfiles &> /tmp/git-remote 142 | $git fetch &> /tmp/git-fetch 143 | $git checkout -t origin/master &> /tmp/git-checkout 144 | ) || rm /home/.git -rf 145 | 146 | # Setup nix-env 147 | rm /home/.nix-defexpr/* 148 | ln -s /run/current-system/nixpkgs /home/.nix-defexpr 149 | fi 150 | ''; 151 | 152 | # Add nixpkgs link to system 153 | system.copySystemNixpkgs = true; 154 | 155 | # Select internationalisation properties. 156 | i18n = { 157 | consoleKeyMap = "de-latin1"; 158 | defaultLocale = "en_US.UTF-8"; 159 | }; 160 | time.timeZone = "Europe/Berlin"; 161 | 162 | # All the fonts! 163 | fonts.fonts = with pkgs; [ 164 | source-code-pro dejavu_fonts liberation_ttf vistafonts corefonts 165 | cantarell_fonts fira fira-mono fira-code hasklig 166 | ]; 167 | 168 | networking = { 169 | wireless.enable = true; 170 | wireless.userControlled.enable = true; 171 | }; 172 | 173 | # Tell systemd that we want to suspend even if an additional 174 | # monitor is connected. 175 | services.logind.extraConfig = '' 176 | HandleLidSwitchDocked=suspend 177 | ''; 178 | 179 | # Allow normal users to mount devices 180 | security.polkit.enable = true; 181 | security.polkit.extraConfig = '' 182 | polkit.addRule(function(action, subject) { 183 | var YES = polkit.Result.YES; 184 | var permission = { 185 | "org.freedesktop.udisks2.filesystem-mount": YES, 186 | "org.freedesktop.udisks2.filesystem-mount-system": YES, 187 | "org.freedesktop.udisks2.eject-media": YES 188 | }; 189 | return permission[action.id]; 190 | }); 191 | ''; 192 | 193 | nix = { 194 | useSandbox = "relaxed"; 195 | extraOptions = '' 196 | auto-optimise-store = true 197 | ''; 198 | binaryCaches = [ https://cache.nixos.org ]; 199 | binaryCachePublicKeys = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ]; 200 | trustedBinaryCaches = [ 201 | http://cache.nixos.org 202 | http://hydra.nixos.org 203 | http://hydra.cryp.to 204 | https://ryantrinkle.com:5443 205 | ]; 206 | daemonNiceLevel = 1; 207 | daemonIONiceLevel = 1; 208 | nixPath = [ 209 | "nixpkgs=/run/current-system/nixpkgs" 210 | "/run/current-system/nixpkgs" 211 | "nixos-config=/etc/nixos/configuration.nix" 212 | ]; 213 | buildMachines = [ 214 | { hostName = "localhost"; system = builtins.currentSystem; inherit (config.nix) maxJobs; } 215 | ]; 216 | }; 217 | 218 | } 219 | 220 | -------------------------------------------------------------------------------- /conf/desktop.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, expr, buildVM, ... }: 2 | 3 | let 4 | iconTheme = pkgs.breeze-icons.out; 5 | themeEnv = '' 6 | # QT: remove local user overrides (for determinism, causes hard to find bugs) 7 | rm -f ~/.config/Trolltech.conf 8 | 9 | # GTK3: remove local user overrides (for determinisim, causes hard to find bugs) 10 | rm -f ~/.config/gtk-3.0/settings.ini 11 | 12 | # GTK3: add breeze theme to search path for themes 13 | # (currently, we need to use gnome-breeze because the GTK3 version of kde5.breeze is broken) 14 | export XDG_DATA_DIRS="${pkgs.gnome-breeze}/share:$XDG_DATA_DIRS" 15 | 16 | # GTK3: add /etc/xdg/gtk-3.0 to search path for settings.ini 17 | # We use /etc/xdg/gtk-3.0/settings.ini to set the icon and theme name for GTK 3 18 | export XDG_CONFIG_DIRS="/etc/xdg:$XDG_CONFIG_DIRS" 19 | 20 | # GTK2 theme + icon theme 21 | export GTK2_RC_FILES=${pkgs.writeText "iconrc" ''gtk-icon-theme-name="breeze"''}:${pkgs.breeze-gtk}/share/themes/Breeze/gtk-2.0/gtkrc:$GTK2_RC_FILES 22 | 23 | # SVG loader for pixbuf (needed for GTK svg icon themes) 24 | export GDK_PIXBUF_MODULE_FILE=$(echo ${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/*/loaders.cache) 25 | 26 | # LS colors 27 | eval `${pkgs.coreutils}/bin/dircolors "${./dircolors}"` 28 | 29 | # QT5: convince it to use our preferred style 30 | export QT_STYLE_OVERRIDE=breeze 31 | ''; 32 | 33 | in { 34 | 35 | imports = []; 36 | 37 | # Required for our screen-lock-on-suspend functionality 38 | services.logind.extraConfig = '' 39 | LidSwitchIgnoreInhibited=False 40 | HandleLidSwitch=suspend 41 | HoldoffTimeoutSec=10 42 | ''; 43 | 44 | # Enable the X11 windowing system. 45 | services.xserver = { 46 | enable = true; 47 | layout = "de"; 48 | synaptics.enable = true; 49 | synaptics.accelFactor = "0.01"; 50 | synaptics.twoFingerScroll = true; 51 | synaptics.additionalOptions = '' 52 | Option "VertScrollDelta" "-112" 53 | Option "HorizScrollDelta" "-112" 54 | Option "TapButton2" "3" 55 | Option "TapButton3" "2" 56 | ''; 57 | xkbOptions = "ctrl:nocaps"; 58 | 59 | displayManager.logToJournal = true; 60 | displayManager.lightdm.enable = true; 61 | displayManager.lightdm.autoLogin = { 62 | enable = true; 63 | user = "bennofs"; 64 | }; 65 | displayManager.lightdm.greeter.enable = false; 66 | desktopManager.session = 67 | [ { name = "custom"; 68 | start = '' 69 | # Lock 70 | ${expr.lock}/bin/lock 71 | ${expr.lock-suspend}/bin/lock-on-suspend & 72 | 73 | ${pkgs.haskellPackages.xmobar}/bin/xmobar --dock --alpha 200 & 74 | ${pkgs.stalonetray}/bin/stalonetray --slot-size 22 --icon-size 20 --geometry 9x1-0 --icon-gravity NE --grow-gravity E -c /dev/null --kludges fix_window_pos,force_icons_size,use_icons_hints --transparent --tint-level 200 &> /dev/null & 75 | ${pkgs.xlibs.xrdb}/bin/xrdb -load ${./Xresources} 76 | 77 | # Autostart 78 | ${pkgs.lib.optionalString (!buildVM) '' 79 | ${pkgs.rxvt_unicode}/bin/urxvt -title "IRC bennofs" -e ${pkgs.weechat}/bin/weechat & 80 | ''} 81 | ${pkgs.rxvt_unicode}/bin/urxvtd & 82 | ${pkgs.pasystray}/bin/pasystray &> /dev/null & 83 | ${pkgs.unclutter}/bin/unclutter -idle 3 & 84 | ${pkgs.pythonPackages.udiskie}/bin/udiskie --tray & 85 | ${pkgs.wpa_supplicant_gui}/bin/wpa_gui -q -t & 86 | ${pkgs.dunst}/bin/dunst -cto 4 -nto 2 -lto 1 -config ${./dunstrc} & 87 | syndaemon -i 1 -R -K -t -d 88 | trap 'trap - SIGINT SIGTERM EXIT && kill 0 && wait' SIGINT SIGTERM EXIT 89 | ${pkgs.lib.optionalString buildVM '' ${pkgs.rxvt_unicode}/bin/urxvt '' } 90 | ''; 91 | } 92 | ]; 93 | desktopManager.default = "custom"; 94 | desktopManager.xterm.enable = false; 95 | 96 | windowManager.default = "xmonad"; 97 | windowManager.xmonad.enable = true; 98 | windowManager.xmonad.enableContribAndExtras = true; 99 | 100 | wacom.enable = true; 101 | }; 102 | 103 | environment.extraInit = '' 104 | ${themeEnv} 105 | 106 | # these are the defaults, but some applications are buggy so we set them 107 | # here anyway 108 | export XDG_CONFIG_HOME=$HOME/.config 109 | export XDG_DATA_HOME=$HOME/.local/share 110 | export XDG_CACHE_HOME=$HOME/.cache 111 | ''; 112 | 113 | # QT4/5 global theme 114 | environment.etc."xdg/Trolltech.conf" = { 115 | text = '' 116 | [Qt] 117 | style=Breeze 118 | ''; 119 | mode = "444"; 120 | }; 121 | 122 | # GTK3 global theme (widget and icon theme) 123 | environment.etc."xdg/gtk-3.0/settings.ini" = { 124 | text = '' 125 | [Settings] 126 | gtk-icon-theme-name=breeze 127 | gtk-theme-name=Breeze-gtk 128 | ''; 129 | mode = "444"; 130 | }; 131 | 132 | environment.systemPackages = with pkgs; [ 133 | # Qt theme 134 | breeze-qt5 135 | breeze-qt4 136 | 137 | # Icons (Main) 138 | iconTheme 139 | 140 | # Icons (Fallback) 141 | gnome3.adwaita-icon-theme 142 | hicolor_icon_theme 143 | 144 | # These packages are used in autostart, they need to in systemPackages 145 | # or icons won't work correctly 146 | pythonPackages.udiskie skype 147 | ]; 148 | 149 | # Make applications find files in /share 150 | environment.pathsToLink = [ "/share" ]; 151 | 152 | } 153 | -------------------------------------------------------------------------------- /conf/dircolors: -------------------------------------------------------------------------------- 1 | # Below are the color init strings for the basic file types. A color init 2 | # string consists of one or more of the following numeric codes: 3 | # Attribute codes: 4 | # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed 5 | # Text color codes: 6 | # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white 7 | # Background color codes: 8 | # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white 9 | OTHER_WRITABLE 01;32 10 | STICKY_OTHER_WRITABLE 04;01;32 11 | STICKY 04;01;34 12 | # List any file extensions like '.gz' or '.tar' that you would like ls 13 | # to colorize below. Put the extension, a space, and the color init string. 14 | # (and any comments you want to add after a '#') 15 | -------------------------------------------------------------------------------- /conf/dunstrc: -------------------------------------------------------------------------------- 1 | [global] 2 | font = Monospace 8 3 | 4 | # Allow a small subset of html markup: 5 | # bold 6 | # italic 7 | # strikethrough 8 | # underline 9 | # 10 | # For a complete reference see 11 | # . 12 | # If markup is not allowed, those tags will be stripped out of the 13 | # message. 14 | allow_markup = yes 15 | 16 | # The format of the message. Possible variables are: 17 | # %a appname 18 | # %s summary 19 | # %b body 20 | # %i iconname (including its path) 21 | # %I iconname (without its path) 22 | # %p progress value if set ([ 0%] to [100%]) or nothing 23 | # Markup is allowed 24 | format = "%s\n\n%b" 25 | 26 | # Sort messages by urgency. 27 | sort = yes 28 | 29 | # Show how many messages are currently hidden (because of geometry). 30 | indicate_hidden = yes 31 | 32 | # Alignment of message text. 33 | # Possible values are "left", "center" and "right". 34 | alignment = left 35 | 36 | # The frequency with wich text that is longer than the notification 37 | # window allows bounces back and forth. 38 | # This option conflicts with "word_wrap". 39 | # Set to 0 to disable. 40 | bounce_freq = 0 41 | 42 | # Show age of message if message is older than show_age_threshold 43 | # seconds. 44 | # Set to -1 to disable. 45 | show_age_threshold = 60 46 | 47 | # Split notifications into multiple lines if they don't fit into 48 | # geometry. 49 | word_wrap = yes 50 | 51 | # Ignore newlines '\n' in notifications. 52 | ignore_newline = no 53 | 54 | 55 | # The geometry of the window: 56 | # [{width}]x{height}[+/-{x}+/-{y}] 57 | # The geometry of the message window. 58 | # The height is measured in number of notifications everything else 59 | # in pixels. If the width is omitted but the height is given 60 | # ("-geometry x2"), the message window expands over the whole screen 61 | # (dmenu-like). If width is 0, the window expands to the longest 62 | # message displayed. A positive x is measured from the left, a 63 | # negative from the right side of the screen. Y is measured from 64 | # the top and down respectevly. 65 | # The width can be negative. In this case the actual width is the 66 | # screen width minus the width defined in within the geometry option. 67 | geometry = "300x5-7+28" 68 | 69 | # Shrink window if it's smaller than the width. Will be ignored if 70 | # width is 0. 71 | shrink = no 72 | 73 | # The transparency of the window. Range: [0; 100]. 74 | # This option will only work if a compositing windowmanager is 75 | # present (e.g. xcompmgr, compiz, etc.). 76 | transparency = 0 77 | 78 | # Don't remove messages, if the user is idle (no mouse or keyboard input) 79 | # for longer than idle_threshold seconds. 80 | # Set to 0 to disable. 81 | idle_threshold = 120 82 | 83 | # Which monitor should the notifications be displayed on. 84 | monitor = 0 85 | 86 | # Display notification on focused monitor. Possible modes are: 87 | # mouse: follow mouse pointer 88 | # keyboard: follow window with keyboard focus 89 | # none: don't follow anything 90 | # 91 | # "keyboard" needs a windowmanager that exports the 92 | # _NET_ACTIVE_WINDOW property. 93 | # This should be the case for almost all modern windowmanagers. 94 | # 95 | # If this option is set to mouse or keyboard, the monitor option 96 | # will be ignored. 97 | follow = mouse 98 | 99 | # Should a notification popped up from history be sticky or timeout 100 | # as if it would normally do. 101 | sticky_history = yes 102 | 103 | # Maximum amount of notifications kept in history 104 | history_length = 20 105 | 106 | # Display indicators for URLs (U) and actions (A). 107 | show_indicators = yes 108 | 109 | # The height of a single line. If the height is smaller than the 110 | # font height, it will get raised to the font height. 111 | # This adds empty space above and under the text. 112 | line_height = 0 113 | 114 | # Draw a line of "separatpr_height" pixel height between two 115 | # notifications. 116 | # Set to 0 to disable. 117 | separator_height = 1 118 | 119 | # Padding between text and separator. 120 | padding = 8 121 | 122 | # Horizontal padding. 123 | horizontal_padding = 8 124 | 125 | # Define a color for the separator. 126 | # possible values are: 127 | # * auto: dunst tries to find a color fitting to the background; 128 | # * foreground: use the same color as the foreground; 129 | # * frame: use the same color as the frame; 130 | # * anything else will be interpreted as a X color. 131 | separator_color = frame 132 | 133 | # Print a notification on startup. 134 | # This is mainly for error detection, since dbus (re-)starts dunst 135 | # automatically after a crash. 136 | startup_notification = false 137 | 138 | # dmenu path. 139 | dmenu = /usr/bin/dmenu -p dunst: 140 | 141 | # Browser for opening urls in context menu. 142 | browser = xdg-open 143 | 144 | # Align icons left/right/off 145 | icon_position = off 146 | 147 | # Paths to default icons. 148 | icon_folders = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/ 149 | 150 | [frame] 151 | width = 1 152 | color = "#dddddd" 153 | 154 | [shortcuts] 155 | 156 | # Shortcuts are specified as [modifier+][modifier+]...key 157 | # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2", 158 | # "mod3" and "mod4" (windows-key). 159 | # Xev might be helpful to find names for keys. 160 | 161 | # Close notification. 162 | close = mod4+Next 163 | 164 | # Close all notifications. 165 | close_all = mod4+shift+Next 166 | 167 | # Redisplay last message(s). 168 | # On the US keyboard layout "grave" is normally above TAB and left 169 | # of "1". 170 | history = mod4+Prior 171 | 172 | # Context menu. 173 | context = ctrl+mod4+Return 174 | 175 | [urgency_low] 176 | # IMPORTANT: colors have to be defined in quotation marks. 177 | # Otherwise the "#" and following would be interpreted as a comment. 178 | background = "#ffffff" 179 | foreground = "#888888" 180 | timeout = 10 181 | 182 | [urgency_normal] 183 | background = "#ffffff" 184 | foreground = "#000000" 185 | timeout = 10 186 | 187 | [urgency_critical] 188 | background = "#ffbd33" 189 | foreground = "#000000" 190 | timeout = 0 191 | 192 | 193 | # Every section that isn't one of the above is interpreted as a rules to 194 | # override settings for certain messages. 195 | # Messages can be matched by "appname", "summary", "body", "icon", "category", 196 | # "msg_urgency" and you can override the "timeout", "urgency", "foreground", 197 | # "background", "new_icon" and "format". 198 | # Shell-like globbing will get expanded. 199 | # 200 | # SCRIPTING 201 | # You can specify a script that gets run when the rule matches by 202 | # setting the "script" option. 203 | # The script will be called as follows: 204 | # script appname summary body icon urgency 205 | # where urgency can be "LOW", "NORMAL" or "CRITICAL". 206 | # 207 | # NOTE: if you don't want a notification to be displayed, set the format 208 | # to "". 209 | # NOTE: It might be helpful to run dunst -print in a terminal in order 210 | # to find fitting options for rules. 211 | 212 | #[espeak] 213 | # summary = "*" 214 | # script = dunst_espeak.sh 215 | 216 | #[script-test] 217 | # summary = "*script*" 218 | # script = dunst_test.sh 219 | 220 | #[ignore] 221 | # # This notification will not be displayed 222 | # summary = "foobar" 223 | # format = "" 224 | 225 | #[signed_on] 226 | # appname = Pidgin 227 | # summary = "*signed on*" 228 | # urgency = low 229 | # 230 | #[signed_off] 231 | # appname = Pidgin 232 | # summary = *signed off* 233 | # urgency = low 234 | # 235 | #[says] 236 | # appname = Pidgin 237 | # summary = *says* 238 | # urgency = critical 239 | # 240 | #[twitter] 241 | # appname = Pidgin 242 | # summary = *twitter.com* 243 | # urgency = normal 244 | # 245 | # vim: ft=cfg 246 | -------------------------------------------------------------------------------- /conf/hacking-lab-vpn.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIHGDCCBQCgAwIBAgIJAJ7afD1Clvn5MA0GCSqGSIb3DQEBBQUAMIG4MQswCQYD 3 | VQQGEwJDSDELMAkGA1UECBMCU0cxEzARBgNVBAcTClJhcHBlcnN3aWwxHDAaBgNV 4 | BAoTE0NvbXBhc3MgU2VjdXJpdHkgQUcxKjAoBgNVBAsTIVRlc3QgQ2VydGlmaWNh 5 | dGlvbiBBdXRob3JpdHkgVjQuMDEYMBYGA1UEAxMPdGVzdGNhNC5jc25jLmNoMSMw 6 | IQYJKoZIhvcNAQkBFhRpdmFuLmJ1ZXRsZXJAY3NuYy5jaDAeFw0wOTA5MjIwNjA1 7 | MDBaFw0xOTA5MjAwNjA1MDBaMIG4MQswCQYDVQQGEwJDSDELMAkGA1UECBMCU0cx 8 | EzARBgNVBAcTClJhcHBlcnN3aWwxHDAaBgNVBAoTE0NvbXBhc3MgU2VjdXJpdHkg 9 | QUcxKjAoBgNVBAsTIVRlc3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgVjQuMDEY 10 | MBYGA1UEAxMPdGVzdGNhNC5jc25jLmNoMSMwIQYJKoZIhvcNAQkBFhRpdmFuLmJ1 11 | ZXRsZXJAY3NuYy5jaDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMC3 12 | 2wRcWbs1b4133RahaxZApT3Lb36gZMgE6bKiMCee0rJYw47TRwG3PnqL/DOsds9c 13 | DlMUvDog+qHE87C0KnpsKfW6y+UwzrIn+ULJEphrs1NOHu9kwZun+Aq1ywKUkfpW 14 | ts9wV6xyjbrnwWWA5wRLV8fI3W59Huw0f4LF4tzNkyeYZ0bqOgkmRTsoRay8j/7R 15 | 4Q6UJRnB8kQpFzmwIVICbl7aPd85QzDTwn0Nq0+ApkVL7N7tm4Kw4monvgCS+NXM 16 | KAA3mGZK4MmiREXQo8L+9bDP/EVbsyHvK1ZPHBl0W4x94mmPmkrSkah8EJMVtzM9 17 | ZMfBkZEj49KWWnAMvRSr1NvMbntLo3eFacUWkR7084EDa9PTGx3Bdh4U2vybRHfs 18 | ei/ldyxM5QTwHCwChOp3gfRCkshxVtIMRMFOJQUxWr50vElvvh0LrllFZUjx66/R 19 | 3/BYQbMYMPp9bQRczhfHBQqH9y06FNxLZfD3nqP8xBAonbhYLka/CHJkDqiHyTVW 20 | hFyG3ADS3nL3Gzmkiaz5HEas7I/OVouueE1OzYCdX8KsiqY7ZyEP+GatZO7QkzHZ 21 | N2T2vgTu/9Y6t1D1KoJ0k1jUZdOMFogX1IR5Qz72gECZcceAlCiWsaam8pwjk+Oi 22 | dQVCf9S9SS1ozw69uEfWsSW0msKUzvoSWbGjGGBjAgMBAAGjggEhMIIBHTAdBgNV 23 | HQ4EFgQUkSLt7OJv4ZyrEWxhmLNKvLGrHa4wge0GA1UdIwSB5TCB4oAUkSLt7OJv 24 | 4ZyrEWxhmLNKvLGrHa6hgb6kgbswgbgxCzAJBgNVBAYTAkNIMQswCQYDVQQIEwJT 25 | RzETMBEGA1UEBxMKUmFwcGVyc3dpbDEcMBoGA1UEChMTQ29tcGFzcyBTZWN1cml0 26 | eSBBRzEqMCgGA1UECxMhVGVzdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBWNC4w 27 | MRgwFgYDVQQDEw90ZXN0Y2E0LmNzbmMuY2gxIzAhBgkqhkiG9w0BCQEWFGl2YW4u 28 | YnVldGxlckBjc25jLmNoggkAntp8PUKW+fkwDAYDVR0TBAUwAwEB/zANBgkqhkiG 29 | 9w0BAQUFAAOCAgEAFs6KF6t+u2HKHkbAaqbYAyBadltwrk/Q4sRSMpGRiR4cddKG 30 | HlfFUuPaK3UW0cJHVfbRrRBubvEqybfhMt3dzmzzyU66zffFcJIyT0c5WXAQlnbW 31 | AejMul8XfpzamqBTQI7C451Yp8ER2CURd3yKRNmxx/a/IUquFAV/rSNW9aw54msM 32 | g+sx/ezQmi8SQ27QitPusszac2s8znV+ockWMVozWpbCCDyy+cUIWzPOOva+GkZH 33 | i0rfBwvu5NbPoXuScR102AqT3MpwCcPwAjAY1mLbFQEhfJpiyUm/Lr06OC9vbwg7 34 | H10KgUyVu9J+ZPexZmPEYmSSwK5rhr0TamnfQKyIbWl4xVvKdyKRyLKZnxe2LZC8 35 | mn8Zi4f/Yd37s6DtZMEb8xhs5FwGKbsN+ZPF99R4nyN0BmdiaKoXHKuXPoncUlLE 36 | CTs44FZnjYT/oFzGnlW7CzAgBgjma0GnrRy/MCu3VpZnJqB5Y+YOqjI+oCQfgMhd 37 | KnoLjW7Efewoi5Vpf8evoSFeTKSDkO/44G6Rivp5mtH5J6NChgookHaxsYkqun+i 38 | aXUqAUQ0SQKtnQStqqUP9f20nSq/LGZfsJl+lhU3Cj0vFpmX+QnOGLHwRfk31eP6 39 | 7x9j2BcCLNHKAPrOEHYbFrof8oXt7WY+9CA4afFHBmYzGZ7ZnSbp4FtnnKs= 40 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /conf/hacking-lab.ovpn: -------------------------------------------------------------------------------- 1 | ############################################## 2 | # Sample client-side OpenVPN 2.0 config file # 3 | # for connecting to multi-client server. # 4 | # # 5 | # This configuration can be used by multiple # 6 | # clients, however each client should have # 7 | # its own cert and key files. # 8 | # # 9 | # On Windows, you might want to rename this # 10 | # file so it has a .ovpn extension # 11 | ############################################## 12 | 13 | # Specify that we are a client and that we 14 | # will be pulling certain config file directives 15 | # from the server. 16 | client 17 | 18 | # Use the same setting as you are using on 19 | # the server. 20 | # On most systems, the VPN will not function 21 | # unless you partially or fully disable 22 | # the firewall for the TUN/TAP interface. 23 | ; dev tap 24 | dev tun 25 | 26 | # Windows needs the TAP-Win32 adapter name 27 | # from the Network Connections panel 28 | # if you have more than one. On XP SP2, 29 | # you may need to disable the firewall 30 | # for the TAP adapter. 31 | ;dev-node MyTap 32 | 33 | # Are we connecting to a TCP or 34 | # UDP server? Use the same setting as 35 | # on the server. 36 | proto tcp 37 | ;proto udp 38 | 39 | # The hostname/IP and port of the server. 40 | # You can have multiple remote entries 41 | # to load balance between the servers. 42 | remote 212.254.246.102 443 43 | ;remote 212.254.246.102 1194 44 | 45 | # Protection against MitM Version >= 2.1 46 | #remote-cert-tls server 47 | 48 | # Protection against MitM Version >= 2.0 49 | ns-cert-type server 50 | #tls-remote 51 | 52 | # Choose a random host from the remote 53 | # list for load-balancing. Otherwise 54 | # try hosts in the order specified. 55 | ;remote-random 56 | 57 | # Keep trying indefinitely to resolve the 58 | # host name of the OpenVPN server. Very useful 59 | # on machines which are not permanently connected 60 | # to the internet such as laptops. 61 | resolv-retry infinite 62 | 63 | # Most clients don't need to bind to 64 | # a specific local port number. 65 | nobind 66 | 67 | # Downgrade privileges after initialization (non-Windows only) 68 | ;user nobody 69 | ;group nobody 70 | 71 | # Try to preserve some state across restarts. 72 | persist-key 73 | persist-tun 74 | 75 | # If you are connecting through an 76 | # HTTP proxy to reach the actual OpenVPN 77 | # server, put the proxy server/IP and 78 | # port number here. See the man page 79 | # if your proxy server requires 80 | # authentication. 81 | ;http-proxy-retry # retry on connection failures 82 | ;http-proxy [proxy server] [proxy port #] 83 | 84 | # Wireless networks often produce a lot 85 | # of duplicate packets. Set this flag 86 | # to silence duplicate packet warnings. 87 | ;mute-replay-warnings 88 | 89 | # SSL/TLS parms. 90 | # See the server config file for more 91 | # description. It's best to use 92 | # a separate .crt/.key file pair 93 | # for each client. A single ca 94 | # file can be used for all clients. 95 | auth-user-pass /etc/nixos/keys/openvpn/hacking-lab/auth 96 | 97 | # Verify server certificate by checking 98 | # that the certicate has the nsCertType 99 | # field set to "server". This is an 100 | # important precaution to protect against 101 | # a potential attack discussed here: 102 | # http://openvpn.net/howto.html#mitm 103 | # 104 | # To use this feature, you will need to generate 105 | # your server certificates with the nsCertType 106 | # field set to "server". The build-key-server 107 | # script in the easy-rsa folder will do this. 108 | ;ns-cert-type server 109 | 110 | # If a tls-auth key is used on the server 111 | # then every client must also have the key. 112 | ;tls-auth ta.key 1 113 | 114 | # Select a cryptographic cipher. 115 | # If the cipher option is used on the server 116 | # then you must also specify it here. 117 | ;cipher x 118 | 119 | # Enable compression on the VPN link. 120 | # Don't enable this unless it is also 121 | # enabled in the server config file. 122 | # comp-lzo 123 | 124 | # Set log file verbosity. 125 | verb 5 126 | 127 | # Silence repeating messages 128 | ;mute 20 129 | 130 | dhcp-option DOMAIN hacking-lab.com 131 | -------------------------------------------------------------------------------- /conf/nixpkgs.nix: -------------------------------------------------------------------------------- 1 | { 2 | allowUnfree = true; 3 | chromium.enablePepperFlash = true; 4 | chromium.enablePepperPDF = true; 5 | #chromium.enableWideVine = true; 6 | cabal.libraryProfiling = true; 7 | packageOverrides = pkgs: rec { 8 | rxvt_unicode = pkgs.rxvt_unicode.overrideDerivation (old: { 9 | preConfigure = '' 10 | ${old.preConfigure} 11 | configureFlags="$configureFlags --enable-unicode3"; 12 | ''; 13 | }); 14 | 15 | custom = import ../expr { inherit pkgs; }; 16 | 17 | i3lock = pkgs.i3lock.overrideDerivation (old: { 18 | # patches = (old.patches or []) ++ [ ./patches/i3lock-margins.patch ./patches/i3lock-ready.patch ]; 19 | }); 20 | 21 | aspell = pkgs.aspell.overrideDerivation (old: { 22 | patchPhase = (old.patchPhase or "") + '' 23 | patch -p1 < ${./patches/aspell-tex2.patch} 24 | ''; 25 | }); 26 | 27 | conkerorWrapperWithoutScrollbars = pkgs.lib.overrideDerivation pkgs.conkerorWrapper (old: rec { 28 | disableScrollbars = pkgs.writeText "conkeror-gtk2-no-scrollbars.rc" '' 29 | style "noscrollbars" { 30 | GtkScrollbar::slider-width=0 31 | GtkScrollbar::trough-border=0 32 | GtkScrollbar::has-backward-stepper=0 33 | GtkScrollbar::has-forward-stepper=0 34 | GtkScrollbar::has-secondary-backward-stepper=0 35 | GtkScrollbar::has-secondary-forward-stepper=0 36 | } 37 | widget "MozillaGtkWidget.*" style "noscrollbars" 38 | ''; 39 | buildCommand = '' 40 | ${old.buildCommand} 41 | wrapProgram $out/bin/conkeror \ 42 | --prefix GTK2_RC_FILES ":" ${disableScrollbars} 43 | ''; 44 | }); 45 | }; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /conf/patches/aspell-tex2.patch: -------------------------------------------------------------------------------- 1 | # A new TeX mode for Aspell 0.60.6 2 | # by Matthias Franz 3 | # 4 | # This patch (hopefully) improves Aspell's TeX mode. The new features 5 | # are as follows: 6 | # 7 | # 1) Aspell skips over math contents inside $...$, $$..$$, \[...\] and 8 | # common LaTeX and AMS-LaTeX environments like "equation" and "gather". 9 | # Additional environments to be skipped over can be defined via the new 10 | # "tex-ignore-env" list. 11 | # 12 | # 2) Forced spell-checking of macro arguments while skipping over 13 | # arguments or environments. This is achieved with the new 'T' option to 14 | # "add-tex-command". 15 | # 16 | # 3) Discretionary hyphens and italic corrections are ignored. For 17 | # example, "hy\-phen" and "shelf\/ful" are recognized as single words. 18 | # 19 | # 4) Spell-checking can be manually switched on and off by putting the 20 | # text "aspell:on" and "aspell:off" into the file. This allows to skip 21 | # over macro definitions and other parts of text that confuse Aspell. 22 | # 23 | # See the new Info file for more details. 24 | 25 | 26 | # Comments about the patch: 27 | # 28 | # ./modules/filter/context.cpp 29 | # It seems that the order of the context filter was undefined. Whether 30 | # one wants to have this filter before or after other filters depends on 31 | # the application in mind. I need it before the tex filter so that one 32 | # can place the "aspell:off" and "aspell:on" flags inside TeX comments. 33 | # 34 | # ./modules/filter/tex.cpp 35 | # The new code for the tex filter. 36 | # 37 | # ./modules/filter/tex-filter.info 38 | # The new default settings for the filter variables. "tex-ignore-env" is 39 | # new. Most changes to "tex-command" are related to the new 'T' option. 40 | # The new "begin" line is used internally. The rest are additions and 41 | # corrections to existing definitions. 42 | # 43 | # ./modules/filter/modes/tex.amf 44 | # Note that we enable the context filter by default. 45 | # 46 | # ./manual/aspell.1 47 | # ./manual/aspell.texi 48 | # Updated documentation. 49 | # 50 | --- ./modules/filter/context.cpp.orig 2004-06-28 20:18:18.000000000 -0400 51 | +++ ./modules/filter/context.cpp 2010-05-03 21:09:39.000000000 -0400 52 | @@ -62,6 +62,7 @@ namespace { 53 | 54 | PosibErr ContextFilter::setup(Config * config){ 55 | name_ = "context-filter"; 56 | + order_num_ = 0.15; 57 | StringList delimiters; 58 | StringEnumeration * delimiterpairs; 59 | const char * delimiterpair=NULL; 60 | --- ./modules/filter/tex.cpp.orig 2006-01-17 09:23:45.000000000 -0500 61 | +++ ./modules/filter/tex.cpp 2010-09-13 21:08:41.000000000 -0400 62 | @@ -32,17 +32,17 @@ namespace { 63 | class TexFilter : public IndividualFilter 64 | { 65 | private: 66 | - enum InWhat {Name, Opt, Parm, Other, Swallow}; 67 | + enum InWhat {Text, Name, Comment, InlineMath, DisplayMath, Scan}; 68 | struct Command { 69 | InWhat in_what; 70 | String name; 71 | - const char * do_check; 72 | + bool skip; 73 | + int size; 74 | + const char * args; 75 | Command() {} 76 | - Command(InWhat w) : in_what(w), do_check("P") {} 77 | + Command(InWhat w, bool s, const char *a) : in_what(w), skip(s), args(a), size(0) {} 78 | }; 79 | 80 | - bool in_comment; 81 | - bool prev_backslash; 82 | Vector stack; 83 | 84 | class Commands : public StringMap { 85 | @@ -53,11 +53,11 @@ namespace { 86 | 87 | Commands commands; 88 | bool check_comments; 89 | + 90 | + StringMap ignore_env; 91 | 92 | - inline void push_command(InWhat); 93 | - inline void pop_command(); 94 | - 95 | - bool end_option(char u, char l); 96 | + inline bool push_command(InWhat, bool, const char *); 97 | + inline bool pop_command(); 98 | 99 | inline bool process_char(FilterChar::Chr c); 100 | 101 | @@ -71,14 +71,17 @@ namespace { 102 | // 103 | // 104 | 105 | - inline void TexFilter::push_command(InWhat w) { 106 | - stack.push_back(Command(w)); 107 | + inline bool TexFilter::push_command(InWhat w, bool skip, const char *args = "") { 108 | + stack.push_back(Command(w, skip, args)); 109 | + return skip; 110 | } 111 | 112 | - inline void TexFilter::pop_command() { 113 | - stack.pop_back(); 114 | - if (stack.empty()) 115 | - push_command(Parm); 116 | + inline bool TexFilter::pop_command() { 117 | + bool skip = stack.back().skip; 118 | + if (stack.size() > 1) { 119 | + stack.pop_back(); 120 | + } 121 | + return skip; 122 | } 123 | 124 | // 125 | @@ -95,6 +98,8 @@ namespace { 126 | opts->retrieve_list("f-tex-command", &commands); 127 | 128 | check_comments = opts->retrieve_bool("f-tex-check-comments"); 129 | + 130 | + opts->retrieve_list("f-tex-ignore-env", &ignore_env); 131 | 132 | reset(); 133 | return true; 134 | @@ -102,127 +107,154 @@ namespace { 135 | 136 | void TexFilter::reset() 137 | { 138 | - in_comment = false; 139 | - prev_backslash = false; 140 | stack.resize(0); 141 | - push_command(Parm); 142 | + push_command(Text, false); 143 | } 144 | 145 | # define top stack.back() 146 | +# define next_arg if (*top.args) { ++top.args; if (!*top.args) pop_command(); } 147 | +# define skip_opt_args if (*top.args) { while (*top.args == 'O' || *top.args == 'o') { ++top.args; } if (!*top.args) pop_command(); } 148 | + 149 | 150 | // yes this should be inlined, it is only called once 151 | inline bool TexFilter::process_char(FilterChar::Chr c) 152 | { 153 | - // deal with comments 154 | - if (c == '%' && !prev_backslash) in_comment = true; 155 | - if (in_comment && c == '\n') in_comment = false; 156 | - 157 | - prev_backslash = false; 158 | - 159 | - if (in_comment) return !check_comments; 160 | - 161 | + top.size++; 162 | + 163 | if (top.in_what == Name) { 164 | if (asc_isalpha(c)) { 165 | 166 | top.name += c; 167 | - return true; 168 | + return top.skip; 169 | 170 | } else { 171 | - 172 | - if (top.name.empty() && (c == '@')) { 173 | - top.name += c; 174 | - return true; 175 | - } 176 | - 177 | - top.in_what = Other; 178 | + bool in_name; 179 | 180 | if (top.name.empty()) { 181 | - top.name.clear(); 182 | top.name += c; 183 | - top.do_check = commands.lookup(top.name.c_str()); 184 | - if (top.do_check == 0) top.do_check = ""; 185 | - return !asc_isspace(c); 186 | + in_name = true; 187 | + } else { 188 | + top.size--; // necessary? 189 | + in_name = false; 190 | } 191 | 192 | - top.do_check = commands.lookup(top.name.c_str()); 193 | - if (top.do_check == 0) top.do_check = ""; 194 | + String name = top.name; 195 | 196 | - if (asc_isspace(c)) { // swallow extra spaces 197 | - top.in_what = Swallow; 198 | - return true; 199 | - } else if (c == '*') { // ignore * at end of commands 200 | - return true; 201 | + pop_command(); 202 | + 203 | + const char *args = commands.lookup(name.c_str()); 204 | + 205 | + // later? 206 | + if (name == "begin") 207 | + push_command(top.in_what, top.skip); 208 | + // args = "s"; 209 | + else if (name == "end") 210 | + pop_command(); 211 | + 212 | + // we might still be waiting for arguments 213 | + skip_opt_args; 214 | + if (*top.args) { 215 | + next_arg; 216 | + } else if (name == "[") { 217 | + // \[ 218 | + push_command(DisplayMath, true); 219 | + } else if (name == "]") { 220 | + // \] 221 | + pop_command(); // pop DisplayMath 222 | + } else if (args && *args) { 223 | + push_command(top.in_what, top.skip, args); 224 | } 225 | 226 | - // continue o... 227 | + if (in_name || c == '*') // better way to deal with "*"? 228 | + return true; 229 | + else 230 | + return process_char(c); // start over 231 | + } 232 | + 233 | + } 234 | + 235 | + if (top.in_what == Comment) { 236 | + if (c == '\n') { 237 | + pop_command(); 238 | + return false; // preserve newlines 239 | + } else { 240 | + return top.skip; 241 | } 242 | - 243 | - } else if (top.in_what == Swallow) { 244 | - 245 | - if (asc_isspace(c)) 246 | - return true; 247 | - else 248 | - top.in_what = Other; 249 | } 250 | 251 | - if (c == '{') 252 | - while (*top.do_check == 'O' || *top.do_check == 'o') 253 | - ++top.do_check; 254 | - 255 | - if (*top.do_check == '\0') 256 | - pop_command(); 257 | - 258 | - if (c == '{') { 259 | - 260 | - if (top.in_what == Parm || top.in_what == Opt || top.do_check == '\0') 261 | - push_command(Parm); 262 | - 263 | - top.in_what = Parm; 264 | + if (c == '%') { 265 | + push_command(Comment, !check_comments); 266 | return true; 267 | } 268 | - 269 | - if (top.in_what == Other) { 270 | - 271 | - if (c == '[') { 272 | - 273 | - top.in_what = Opt; 274 | - return true; 275 | - 276 | - } else if (asc_isspace(c)) { 277 | - 278 | - return true; 279 | - 280 | + 281 | + if (c == '$') { 282 | + if (top.in_what != InlineMath) { 283 | + // $ begin 284 | + return push_command(InlineMath, true); 285 | + } else if (top.size > 1) { 286 | + // $ end 287 | + return pop_command(); 288 | } else { 289 | - 290 | - pop_command(); 291 | - 292 | + // $ -> $$ 293 | + pop_command(); // pop InlineMath 294 | + if (top.in_what == DisplayMath) 295 | + // $$ end 296 | + return pop_command(); 297 | + else 298 | + // $$ start 299 | + return push_command(DisplayMath, true); 300 | } 301 | - 302 | - } 303 | + } 304 | 305 | if (c == '\\') { 306 | - prev_backslash = true; 307 | - push_command(Name); 308 | - return true; 309 | + return push_command(Name, true); 310 | } 311 | 312 | - if (top.in_what == Parm) { 313 | - 314 | - if (c == '}') 315 | - return end_option('P','p'); 316 | - else 317 | - return *top.do_check == 'p'; 318 | - 319 | - } else if (top.in_what == Opt) { 320 | + if (c == '}' || c == ']') { 321 | + if (top.in_what == Scan) { 322 | + String env = top.name; 323 | + if (env.back() == '*') 324 | + env.pop_back(); 325 | + bool skip = pop_command(); 326 | + next_arg; 327 | + if (ignore_env.have(env)) { 328 | + stack[stack.size()-2].skip = true; 329 | + } 330 | + return skip; 331 | + } else { 332 | + bool skip = pop_command(); 333 | + next_arg; 334 | + return skip; 335 | + } 336 | + } 337 | 338 | - if (c == ']') 339 | - return end_option('O', 'o'); 340 | + if (c == '{') { 341 | + skip_opt_args; 342 | + if (*top.args == 'T') 343 | + return push_command(Text, false); 344 | + else if (*top.args == 's') // also do it below? 345 | + return push_command(Scan, true); 346 | else 347 | - return *top.do_check == 'o'; 348 | - 349 | + return push_command(top.in_what, top.skip || *top.args == 'p'); 350 | + } 351 | + 352 | + if (c == '[') { 353 | + if (*top.args == 'O' || *top.args == 'o' || !*top.args) { 354 | + return push_command(top.in_what, top.skip || *top.args == 'o'); 355 | + } 356 | + // else: fall-through to treat it as argument 357 | } 358 | + 359 | + if (top.in_what == Scan) 360 | + top.name += c; 361 | 362 | - return false; 363 | + // we might still be waiting for arguments 364 | + if (!asc_isspace(c)) { 365 | + skip_opt_args; 366 | + next_arg; 367 | + } 368 | + 369 | + return top.skip; 370 | } 371 | 372 | void TexFilter::process(FilterChar * & str, FilterChar * & stop) 373 | @@ -230,19 +262,24 @@ namespace { 374 | FilterChar * cur = str; 375 | 376 | while (cur != stop) { 377 | - if (process_char(*cur)) 378 | + bool hyphen = top.in_what == Name && top.size == 0 379 | + && (*cur == '-' || *cur == '/') && cur-str >= 2; 380 | + if (process_char(*cur)) { 381 | *cur = ' '; 382 | + } 383 | + if (hyphen) { 384 | + FilterChar *i = cur-2, *j = cur+1; 385 | + *i = FilterChar(*i, FilterChar::sum(i, j)); 386 | + i++; 387 | + while (j != stop) 388 | + *(i++) = *(j++); 389 | + *(stop-2) = *(stop-1) = FilterChar(0, 0); 390 | + cur--; 391 | + } 392 | ++cur; 393 | } 394 | } 395 | 396 | - bool TexFilter::end_option(char u, char l) { 397 | - top.in_what = Other; 398 | - if (*top.do_check == u || *top.do_check == l) 399 | - ++top.do_check; 400 | - return true; 401 | - } 402 | - 403 | // 404 | // TexFilter::Commands 405 | // 406 | @@ -252,14 +289,14 @@ namespace { 407 | while (!asc_isspace(value[p1])) { 408 | if (value[p1] == '\0') 409 | return make_err(bad_value, value,"", 410 | - _("a string of 'o','O','p',or 'P'")); 411 | + _("a string of 'o', 'O', 'p', 'P', 's' or 'T'")); 412 | ++p1; 413 | } 414 | int p2 = p1 + 1; 415 | while (asc_isspace(value[p2])) { 416 | if (value[p2] == '\0') 417 | return make_err(bad_value, value,"", 418 | - _("a string of 'o','O','p',or 'P'")); 419 | + _("a string of 'o', 'O', 'p', 'P', 's' or 'T'")); 420 | ++p2; 421 | } 422 | String t1; t1.assign(value,p1); 423 | --- ./modules/filter/tex-filter.info.orig 2004-06-27 00:54:00.000000000 -0400 424 | +++ ./modules/filter/tex-filter.info 2011-02-05 16:44:49.000000000 -0500 425 | @@ -16,15 +16,35 @@ DESCRIPTION check TeX comments 426 | DEFAULT false 427 | ENDOPTION 428 | 429 | +OPTION ignore-env 430 | +TYPE list 431 | +DESCRIPTION LaTeX environments to be ignored 432 | +# LaTeX 433 | +#DEFAULT thebibliography 434 | +DEFAULT equation 435 | +DEFAULT eqnarray 436 | +# AMS-LaTeX 437 | +DEFAULT gather 438 | +DEFAULT multline 439 | +DEFAULT align 440 | +DEFAULT flalign 441 | +DEFAULT alignat 442 | +# Babel 443 | +DEFAULT otherlanguage 444 | +ENDOPTION 445 | + 446 | OPTION command 447 | TYPE list 448 | DESCRIPTION TeX commands 449 | +# plain TeX / LaTeX 450 | DEFAULT addtocounter pp 451 | DEFAULT addtolength pp 452 | -DEFAULT alpha p 453 | +DEFAULT alph p 454 | +DEFAULT Alph p 455 | DEFAULT arabic p 456 | DEFAULT fnsymbol p 457 | DEFAULT roman p 458 | +DEFAULT Roman p 459 | DEFAULT stepcounter p 460 | DEFAULT setcounter pp 461 | DEFAULT usecounter p 462 | @@ -42,7 +62,8 @@ DEFAULT newtheorem poPo 463 | DEFAULT newfont pp 464 | DEFAULT documentclass op 465 | DEFAULT usepackage op 466 | -DEFAULT begin po 467 | +# Do NOT change the next line! 468 | +DEFAULT begin so 469 | DEFAULT end p 470 | DEFAULT setlength pp 471 | DEFAULT addtolength pp 472 | @@ -54,15 +75,17 @@ DEFAULT hyphenation p 473 | DEFAULT pagenumbering p 474 | DEFAULT pagestyle p 475 | DEFAULT addvspace p 476 | -DEFAULT framebox ooP 477 | +DEFAULT framebox ooT 478 | DEFAULT hspace p 479 | DEFAULT vspace p 480 | -DEFAULT makebox ooP 481 | -DEFAULT parbox ooopP 482 | -DEFAULT raisebox pooP 483 | +DEFAULT hbox T 484 | +DEFAULT vbox T 485 | +DEFAULT makebox ooT 486 | +DEFAULT parbox ooopT 487 | +DEFAULT raisebox pooT 488 | DEFAULT rule opp 489 | DEFAULT sbox pO 490 | -DEFAULT savebox pooP 491 | +DEFAULT savebox pooT 492 | DEFAULT usebox p 493 | DEFAULT include p 494 | DEFAULT includeonly p 495 | @@ -76,13 +99,30 @@ DEFAULT fontshape p 496 | DEFAULT fontsize pp 497 | DEFAULT usefont pppp 498 | DEFAULT documentstyle op 499 | -DEFAULT cite p 500 | +DEFAULT cite Op 501 | DEFAULT nocite p 502 | DEFAULT psfig p 503 | DEFAULT selectlanguage p 504 | DEFAULT includegraphics op 505 | DEFAULT bibitem op 506 | +DEFAULT bibliography p 507 | +DEFAULT bibliographystyle p 508 | DEFAULT geometry p 509 | +# AMS-LaTeX 510 | +DEFAULT address p 511 | +DEFAULT email p 512 | +DEFAULT mathbb p 513 | +DEFAULT mathfrak p 514 | +DEFAULT eqref p 515 | +DEFAULT text T 516 | +DEFAULT intertext T 517 | +DEFAULT DeclareMathOperator pp 518 | +DEFAULT DeclareMathAlphabet ppppp 519 | +# hyperref 520 | +DEFAULT href pP 521 | +DEFAULT autoref p 522 | +DEFAULT url p 523 | +DEFAULT texorpdfstring Pp 524 | ENDOPTION 525 | 526 | #OPTION multi-byte 527 | --- ./modules/filter/modes/tex.amf.orig 2004-10-30 12:00:07.000000000 -0400 528 | +++ ./modules/filter/modes/tex.amf 2010-05-30 20:49:28.000000000 -0400 529 | @@ -6,5 +6,8 @@ MAGIC /0:256:^[ \t]*\\documentclass\[[^\ 530 | 531 | DESCRIPTION mode for checking TeX/LaTeX documents 532 | 533 | -FILTER url 534 | +FILTER context 535 | +OPTION clear-context-delimiters 536 | +OPTION add-context-delimiters aspell:off aspell:on 537 | +OPTION enable-context-visible-first 538 | FILTER tex 539 | --- ./manual/aspell.1.orig 2006-12-19 05:55:08.000000000 -0500 540 | +++ ./manual/aspell.1 2011-02-05 14:30:00.000000000 -0500 541 | @@ -181,7 +181,7 @@ encoding the document is expected to be 542 | current locale. 543 | .TP 544 | \fB\-\-add-email\-quote=\fR\fI\fR, \fB\-\-rem-email\-quote=\fR\fI\fR 545 | -Add or Remove a list of email quote characters. 546 | +Add or remove a list of email quote characters. 547 | .TP 548 | \fB\-\-email\-margin=\fR\fI\fR 549 | Number of chars that can appear before the quote char. 550 | @@ -191,14 +191,14 @@ Add or remove a list of HTML attributes 551 | look inside alt= tags. 552 | .TP 553 | \fB\-\-add\-html\-skip=\fR\fI\fR, \fB\-\-rem\-html\-skip=\fR\fI\fR 554 | -Add or remove a list of HTML attributes to always skip while spell 555 | +Add or remove a list of HTML tags to always skip while spell 556 | checking. 557 | .TP 558 | \fB\-\-add\-sgml\-check=\fR\fI\fR, \fB\-\-rem\-sgml\-check=\fR\fI\fR 559 | Add or remove a list of SGML attributes to always check for spelling. 560 | .TP 561 | \fB\-\-add\-sgml\-skip=\fR\fI\fR, \fB\-\-rem\-sgml\-skip=\fR\fI\fR 562 | -Add or remove a list of SGML attributes to always skip while spell 563 | +Add or remove a list of SGML tags to always skip while spell 564 | checking. 565 | .TP 566 | \fB\-\-sgml\-extension=\fR\fI\fR 567 | @@ -208,7 +208,22 @@ SGML file extensions. 568 | Check TeX comments. 569 | .TP 570 | \fB\-\-add\-tex\-command=\fR\fI\fR, \fB\-\-rem\-tex\-command=\fR\fI\fR 571 | -Add or Remove a list of TeX commands. 572 | +Add or remove a list of TeX commands. 573 | +.TP 574 | +\fB\-\-add\-tex\-ignore\-env=\fR\fI\fR, \fB\-\-rem\-tex\-ignore\-env=\fR\fI\fR 575 | +Add or remove a list of LaTeX environments to skip while spell checking. 576 | +.TP 577 | +\fB\-\-add\-texinfo\-ignore=\fR\fI\fR, \fB\-\-rem\-texinfo\-ignore=\fR\fI\fR 578 | +Add or remove a list of Texinfo commands. 579 | +.TP 580 | +\fB\-\-add\-texinfo\-ignore\-env=\fR\fI\fR, \fB\-\-rem\-texinfo\-ignore\-env=\fR\fI\fR 581 | +Add or remove a list of Texinfo environments to ignore. 582 | +.TP 583 | +\fB\-\-context\-visible\-first, \fB\-\-dont\-context\-visible\-first 584 | +Switch the context which should be visible to Aspell. 585 | +.TP 586 | +\fB\-\-add\-context\-delimiters=\fR\fI\fR, \fB\-\-rem\-context\-delimiters=\fR\fI\fR 587 | +Add or remove pairs of delimiters. 588 | .SH RUN\-TOGETHER WORD OPTIONS 589 | These may be used to control the behavior of run\-together words. 590 | .TP 591 | --- ./manual/aspell.texi.orig 2008-04-16 01:14:36.000000000 -0400 592 | +++ ./manual/aspell.texi 2011-02-05 16:49:09.000000000 -0500 593 | @@ -1065,6 +1065,10 @@ being readable text in LaTeX output from 594 | @i{(list)} 595 | @TeX{} commands 596 | 597 | +address@hidden tex-ignore-env 598 | +address@hidden(list)} 599 | +address@hidden environments to always skip over 600 | + 601 | @item tex-check-comments 602 | @i{(boolean)} 603 | check @TeX{} comments 604 | @@ -1363,13 +1367,15 @@ all their parameters and/or options chec 605 | is 606 | 607 | @example 608 | - 609 | + 610 | @end example 611 | 612 | The first item is simply the command name. The second item controls 613 | which parameters to skip over. A 'p' skips over a parameter while a 614 | 'P' doesn't. Similarly an 'o' will skip over an optional parameter 615 | -while an 'O' doesn't. The first letter on the list will apply to the 616 | +while an 'O' doesn't. A 'T' will force spell-checking of a parameter 617 | +even if the command occurs within a parameter or an environment Aspell 618 | +is told to skipped over. The first letter on the list will apply to the 619 | first parameter, the second letter will apply to the second parameter 620 | etc. If there are more parameters than letters Aspell will simply 621 | check them as normal. For example the option 622 | @@ -1392,6 +1398,25 @@ over the next optional parameter, if it 623 | the second parameter --- even if the optional parameter is not present 624 | --- and will check any additional parameters. 625 | 626 | +address@hidden 627 | +add-tex-command foo T 628 | +address@hidden example 629 | + 630 | +address@hidden 631 | +will @emph{check} the first parameter of the @code{foo} command even 632 | +if Aspell is currently skipping over an argument or environment. For 633 | +example, if Aspell has been told to skip over the @code{bar} 634 | +environment (@pxref{Ignoring LaTeX Environments}), then in the text 635 | + 636 | +address@hidden 637 | +address@hidden@} don't check address@hidden@} don't check address@hidden@} 638 | +address@hidden example 639 | + 640 | +address@hidden 641 | +it will nevertheless @emph{check} the argument to @code{foo}. This is 642 | +useful to force checking of arguments to text-related commands like 643 | +address@hidden, @code{text} or @code{intertext} inside math environments. 644 | + 645 | A @samp{*} at the end of the command is simply ignored. For example 646 | the option 647 | 648 | @@ -1414,6 +1439,50 @@ rem-tex-command foo 649 | will remove the command foo, if present, from the list of @TeX{} 650 | commands. 651 | 652 | +address@hidden LaTeX Environments} 653 | +The option 654 | +address@hidden|rem-tex-ignore-env} 655 | +controls which @TeX{} environments are skipped over. By default, 656 | +Aspell will skip over math formulas inside @code{$...$}, @code{$$...$$} 657 | +and @code{\[...\]} and over several common LaTeX and AMS-LaTeX math 658 | +environments like @code{equation} and @code{gather}. For example, 659 | + 660 | +address@hidden 661 | +add-tex-ignore-env thebibliography 662 | +address@hidden example 663 | + 664 | +address@hidden 665 | +will tell Aspell to skip over the bibliography as well (which may or 666 | +may not be a good idea). As with commands, skipping applies to the 667 | +starred form of the environment as well. 668 | + 669 | +address@hidden 670 | +rem-tex-ignore-env equation 671 | +address@hidden example 672 | + 673 | +address@hidden 674 | +will make Aspell spell-check the contents of @code{equation} and 675 | +address@hidden environments. Skipping the contents of @code{$...$}, 676 | +address@hidden and @code{\[...\]} cannot be turned off. 677 | + 678 | +Note that one can force spell-checking of arguments to TeX commands 679 | +inside ignored environments with the 'T' parameter to the 680 | +address@hidden option. 681 | + 682 | +As a last resort, spell checking can be switched off by putting the 683 | +text @code{aspell:off} into the file. Similarly, with @code{aspell:on} 684 | +one can turn it on again. This can be useful for macro definitions, 685 | +for example 686 | + 687 | +address@hidden 688 | +% aspell:off 689 | +address@hidden@{http://dx.doi.org/address@hidden@{doi:address@hidden@} 690 | +% aspell:on 691 | +address@hidden example 692 | + 693 | +address@hidden 694 | +This feature is implemented via the @ref{Context Filter}. 695 | + 696 | The TeX filter mode is also available via @option{latex} alias name. 697 | 698 | @c The TeXfilter mode also contains a decoding and a encoding filter for 699 | @@ -1514,6 +1583,7 @@ escapes 700 | (@code{\(}) and extended (@code{\[comp1 comp2 @dots{}]}) form. 701 | @end itemize 702 | 703 | +address@hidden Filter} 704 | @subsubsection Context Filter 705 | 706 | The @emph{context} filter allows Aspell to distinguish between visible 707 | -------------------------------------------------------------------------------- /conf/patches/grep-fix-splice-einval.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/grep.c b/src/grep.c 2 | index f28f3c2..3e8e662 100644 3 | --- a/src/grep.c 4 | +++ b/src/grep.c 5 | @@ -1729,10 +1729,19 @@ drain_input (int fd, struct stat const *st) 6 | #ifdef SPLICE_F_MOVE 7 | /* Should be faster, since it need not copy data to user space. */ 8 | while ((nbytes = splice (fd, NULL, STDOUT_FILENO, NULL, 9 | - INITIAL_BUFSIZE, SPLICE_F_MOVE))) 10 | - if (nbytes < 0) 11 | - return false; 12 | - return true; 13 | + INITIAL_BUFSIZE, SPLICE_F_MOVE)) > 0) 14 | + continue; 15 | + 16 | + if(nbytes == 0) return true; 17 | + 18 | + /* STDOUT might have been opened with O_APPEND (gnumake sets this flag for example). 19 | + * In this case, splice fails with EINVAL. 20 | + * 21 | + * In that case, the safe_read still works so instead of returning with an error here, 22 | + * we just fall through to the safe_read variant. 23 | + */ 24 | + if(nbytes < 0 && errno != EINVAL) return false; 25 | + 26 | #endif 27 | } 28 | while ((nbytes = safe_read (fd, buffer, bufalloc))) 29 | -------------------------------------------------------------------------------- /conf/patches/i3lock-margins.patch: -------------------------------------------------------------------------------- 1 | diff --git a/i3lock.c b/i3lock.c 2 | index a7b54f5..cf1526d 100644 3 | --- a/i3lock.c 4 | +++ b/i3lock.c 5 | @@ -813,3 +813,7 @@ int main(int argc, char *argv[]) { 6 | struct passwd *pw; 7 | char *username; 8 | char *image_path = NULL; 9 | + int top_margin = 0; 10 | + int bottom_margin = 0; 11 | + int left_margin = 0; 12 | + int right_margin = 0; 13 | @@ -755,6 +759,10 @@ int main(int argc, char *argv[]) { 14 | {"ignore-empty-password", no_argument, NULL, 'e'}, 15 | {"inactivity-timeout", required_argument, NULL, 'I'}, 16 | {"show-failed-attempts", no_argument, NULL, 'f'}, 17 | + {"top-margin", required_argument, NULL, 'T'}, 18 | + {"bottom-margin", required_argument, NULL, 'B'}, 19 | + {"left-margin", required_argument, NULL, 'L'}, 20 | + {"right-margin", required_argument, NULL, 'R'}, 21 | {NULL, no_argument, NULL, 0}}; 22 | 23 | if ((pw = getpwuid(getuid())) == NULL) 24 | @@ -823,6 +831,22 @@ int main(int argc, char *argv[]) { 25 | case 'f': 26 | show_failed_attempts = true; 27 | break; 28 | + case 'T': 29 | + if (sscanf(optarg, "%d", &top_margin) != 1 || top_margin < 0) 30 | + errx(EXIT_FAILURE, "invalid top margin, it must be a positive integer\n"); 31 | + break; 32 | + case 'B': 33 | + if (sscanf(optarg, "%d", &bottom_margin) != 1 || bottom_margin < 0) 34 | + errx(EXIT_FAILURE, "invalid bottom margin, it must be a positive integer\n"); 35 | + break; 36 | + case 'L': 37 | + if (sscanf(optarg, "%d", &left_margin) != 1 || left_margin < 0) 38 | + errx(EXIT_FAILURE, "invalid left margin, it must be a positive integer\n"); 39 | + break; 40 | + case 'R': 41 | + if (sscanf(optarg, "%d", &right_margin) != 1 || right_margin < 0) 42 | + errx(EXIT_FAILURE, "invalid right margin, it must be a positive integer\n"); 43 | + break; 44 | default: 45 | errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]" 46 | " [-i image.png] [-t] [-e] [-I timeout] [-f]"); 47 | @@ -932,5 +956,5 @@ int main(int argc, char *argv[]) { 48 | xcb_pixmap_t bg_pixmap = draw_image(last_resolution); 49 | 50 | /* open the fullscreen window, already with the correct pixmap in place */ 51 | - win = open_fullscreen_window(conn, screen, color, bg_pixmap); 52 | + win = open_fullscreen_window(conn, screen, color, bg_pixmap, top_margin, bottom_margin, left_margin, right_margin); 53 | xcb_free_pixmap(conn, bg_pixmap); 54 | diff --git a/xcb.c b/xcb.c 55 | index f1a9a76..ca7b1e8 100644 56 | --- a/xcb.c 57 | +++ b/xcb.c 58 | @@ -97,7 +97,7 @@ xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_screen_t *scr, u_int32 59 | return bg_pixmap; 60 | } 61 | 62 | -xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color, xcb_pixmap_t pixmap) { 63 | +xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color, xcb_pixmap_t pixmap, int top_margin, int bottom_margin, int left_margin, int right_margin) { 64 | uint32_t mask = 0; 65 | uint32_t values[3]; 66 | xcb_window_t win = xcb_generate_id(conn); 67 | @@ -124,9 +124,9 @@ xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, c 68 | XCB_COPY_FROM_PARENT, 69 | win, /* the window id */ 70 | scr->root, /* parent == root */ 71 | - 0, 0, 72 | - scr->width_in_pixels, 73 | - scr->height_in_pixels, /* dimensions */ 74 | + left_margin, top_margin, 75 | + scr->width_in_pixels - left_margin - right_margin, 76 | + scr->height_in_pixels - top_margin - bottom_margin, /* dimensions */ 77 | 0, /* border = 0, we draw our own */ 78 | XCB_WINDOW_CLASS_INPUT_OUTPUT, 79 | XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */ 80 | diff --git a/xcb.h b/xcb.h 81 | index 1e0cbb1..aeffd96 100644 82 | --- a/xcb.h 83 | +++ b/xcb.h 84 | @@ -9,7 +9,7 @@ extern xcb_screen_t *screen; 85 | 86 | xcb_visualtype_t *get_root_visual_type(xcb_screen_t *s); 87 | xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_screen_t *scr, u_int32_t *resolution, char *color); 88 | -xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color, xcb_pixmap_t pixmap); 89 | +xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color, xcb_pixmap_t pixmap, int top_margin, int bottom_margin, int left_margin, int right_margin); 90 | void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor); 91 | void dpms_set_mode(xcb_connection_t *conn, xcb_dpms_dpms_mode_t mode); 92 | xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice); 93 | -------------------------------------------------------------------------------- /conf/patches/i3lock-ready.patch: -------------------------------------------------------------------------------- 1 | diff --git a/i3lock.c b/i3lock.c 2 | index cf1526d..4d2741e 100644 3 | --- a/i3lock.c 4 | +++ b/i3lock.c 5 | @@ -660,6 +660,8 @@ static void xcb_check_cb(EV_P_ ev_check *w, int revents) { 6 | 7 | ev_loop_fork(EV_DEFAULT); 8 | } 9 | + printf("ready\n"); 10 | + fflush(stdout); 11 | break; 12 | 13 | case XCB_CONFIGURE_NOTIFY: 14 | -------------------------------------------------------------------------------- /conf/services.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, ... }: 2 | 3 | let 4 | expr = import ../expr { inherit pkgs; }; 5 | in { 6 | 7 | imports = []; 8 | 9 | security.wrappers = { 10 | "dumpcap" = { 11 | source = "${pkgs.wireshark-cli}/bin/dumpcap"; 12 | owner = "root"; 13 | group = "wheel"; 14 | permissions = "550"; 15 | capabilities = "cap_net_raw,cap_net_admin=eip"; 16 | }; 17 | }; 18 | 19 | services = { 20 | 21 | # The locate service for finding files in the nix-store quickly. 22 | locate.enable = true; 23 | 24 | # Enable CUPS to print documents. 25 | printing.enable = true; 26 | 27 | # Add drivers to CUPS 28 | printing.drivers = [ expr.mfcj430w-driver ]; 29 | 30 | # Avahi is used for finding other devices on the network. 31 | avahi.enable = true; 32 | avahi.nssmdns = true; 33 | 34 | # Enable dnsmasq (required to merge VPN nameservers) 35 | dnsmasq = { 36 | enable = true; 37 | extraConfig = '' 38 | bind-interfaces 39 | interface=lo 40 | no-negcache 41 | all-servers 42 | dnssec 43 | trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 44 | server=/vm/192.168.122.1 45 | ''; 46 | }; 47 | 48 | # HackingLab openvpn config 49 | openvpn.servers.hacking-lab = { 50 | config = '' 51 | ${builtins.readFile ./hacking-lab.ovpn}; 52 | ca ${./hacking-lab-vpn.crt} 53 | ''; 54 | updateResolvConf = true; 55 | autoStart = false; 56 | }; 57 | 58 | # Enable TLP for optimal power saving 59 | tlp.enable = true; 60 | 61 | # Enable sambda for sharing files 62 | samba.enable = true; 63 | 64 | # Enable SSH service 65 | openssh = { 66 | enable = true; 67 | passwordAuthentication = false; 68 | permitRootLogin = "no"; 69 | }; 70 | 71 | # Enable Hydra 72 | hydra = { 73 | enable = true; 74 | hydraURL = "http://localhost:3000"; 75 | notificationSender = "hydra@localhost"; 76 | }; 77 | 78 | }; 79 | 80 | # Use libvirtd for managing virtual machines. 81 | # This only enables the service, but does not add users to the libvirt group. 82 | virtualisation.libvirtd.enable = true; 83 | 84 | # Set the default connection string for `virsh` etc to be the system qemu instance. 85 | environment.variables.LIBVIRT_DEFAULT_URI = "qemu:///system"; 86 | 87 | # Set the MPD host 88 | environment.variables.MPD_HOST = "pi-cube.fritz.box"; 89 | 90 | # Libvirtd needs to start after data is mounted, because the storage pool lives 91 | # on /data. 92 | systemd.services.libvirtd = { 93 | after = ["data.mount"]; 94 | requires = ["data.mount"]; 95 | }; 96 | 97 | # Enable docker for container management. 98 | # This only enables the service, but does not add users to the docker group. 99 | virtualisation.docker.enable = true; 100 | 101 | # Docker images are quite big, so we don't want to place them on the SSD. 102 | virtualisation.docker.extraOptions = "-g /data/blob/docker"; 103 | systemd.services.docker = { 104 | after = ["data.mount"]; 105 | requires = ["data.mount"]; 106 | }; 107 | 108 | # We need to choose a storage driver for docker. 109 | # "overlay2" is currently actively developed and will eventually become the default, so use it. 110 | virtualisation.docker.storageDriver = "overlay2"; 111 | 112 | networking.firewall = { 113 | # Pings are very useful for network troubleshooting. 114 | allowPing = true; 115 | 116 | allowedTCPPorts = [ 117 | 3000 # hydra 118 | 139 445 # samba 119 | 22 # ssh 120 | ]; 121 | 122 | allowedUDPPorts = [ 123 | 137 138 # samba 124 | ]; 125 | }; 126 | 127 | # Configure additional DNS servers 128 | networking.extraResolvconfConf = 129 | let 130 | extraNameServers = [ 131 | # Google IPv6 DNS servers 132 | "2001:4860:4860::8888" 133 | "2001:4860:4860::8844" 134 | # ipv6.lt NAT64 DNS server 135 | #"2001:778::37" 136 | ]; 137 | in '' 138 | name_servers="$name_servers''${name_servers:+ }${toString extraNameServers}" 139 | ''; 140 | 141 | # User services 142 | services.dbus.socketActivated = true; 143 | 144 | } 145 | 146 | -------------------------------------------------------------------------------- /conf/urxvt-perl/clipboard: -------------------------------------------------------------------------------- 1 | #! perl -w 2 | # Author: Bert Muennich 3 | # Website: http://www.github.com/muennich/urxvt-perls 4 | # License: GPLv2 5 | 6 | # Use keyboard shortcuts to copy the selection to the clipboard and to paste 7 | # the clipboard contents (optionally escaping all special characters). 8 | # Requires xsel to be installed! 9 | 10 | # Usage: put the following lines in your .Xdefaults/.Xresources: 11 | # URxvt.perl-ext-common: ...,clipboard 12 | # URxvt.keysym.M-c: perl:clipboard:copy 13 | # URxvt.keysym.M-v: perl:clipboard:paste 14 | # URxvt.keysym.M-C-v: perl:clipboard:paste_escaped 15 | 16 | # Options: 17 | # URxvt.clipboard.autocopy: If true, PRIMARY overwrites clipboard 18 | 19 | # You can also overwrite the system commands to use for copying/pasting. 20 | # The default ones are: 21 | # URxvt.clipboard.copycmd: xsel -ib 22 | # URxvt.clipboard.pastecmd: xsel -ob 23 | # If you prefer xclip, then put these lines in your .Xdefaults/.Xresources: 24 | # URxvt.clipboard.copycmd: xclip -i -selection clipboard 25 | # URxvt.clipboard.pastecmd: xclip -o -selection clipboard 26 | # On Mac OS X, put these lines in your .Xdefaults/.Xresources: 27 | # URxvt.clipboard.copycmd: pbcopy 28 | # URxvt.clipboard.pastecmd: pbpaste 29 | 30 | # The use of the functions should be self-explanatory! 31 | 32 | use strict; 33 | 34 | sub on_start { 35 | my ($self) = @_; 36 | 37 | $self->{copy_cmd} = $self->x_resource('clipboard.copycmd') || 'xsel -ib'; 38 | $self->{paste_cmd} = $self->x_resource('clipboard.pastecmd') || 'xsel -ob'; 39 | 40 | if ($self->x_resource('clipboard.autocopy') eq 'true') { 41 | $self->enable(sel_grab => \&sel_grab); 42 | } 43 | 44 | () 45 | } 46 | 47 | sub copy { 48 | my ($self) = @_; 49 | 50 | if (open(CLIPBOARD, "| $self->{copy_cmd}")) { 51 | my $sel = $self->selection(); 52 | utf8::encode($sel); 53 | print CLIPBOARD $sel; 54 | close(CLIPBOARD); 55 | } else { 56 | print STDERR "error running '$self->{copy_cmd}': $!\n"; 57 | } 58 | 59 | () 60 | } 61 | 62 | sub paste { 63 | my ($self) = @_; 64 | 65 | my $str = `$self->{paste_cmd}`; 66 | if ($? == 0) { 67 | $self->tt_paste($str); 68 | } else { 69 | print STDERR "error running '$self->{paste_cmd}': $!\n"; 70 | } 71 | 72 | () 73 | } 74 | 75 | sub paste_escaped { 76 | my ($self) = @_; 77 | 78 | my $str = `$self->{paste_cmd}`; 79 | if ($? == 0) { 80 | $str =~ s/([!#\$%&\*\(\) ='"\\\|\[\]`~,<>\?])/\\\1/g; 81 | $self->tt_paste($str); 82 | } else { 83 | print STDERR "error running '$self->{paste_cmd}': $!\n"; 84 | } 85 | 86 | () 87 | } 88 | 89 | sub on_user_command { 90 | my ($self, $cmd) = @_; 91 | 92 | if ($cmd eq "clipboard:copy") { 93 | $self->copy; 94 | } elsif ($cmd eq "clipboard:paste") { 95 | $self->paste; 96 | } elsif ($cmd eq "clipboard:paste_escaped") { 97 | $self->paste_escaped; 98 | } 99 | 100 | () 101 | } 102 | 103 | sub sel_grab { 104 | my ($self) = @_; 105 | 106 | $self->copy; 107 | 108 | () 109 | } 110 | -------------------------------------------------------------------------------- /conf/urxvt-perl/keyboard-select: -------------------------------------------------------------------------------- 1 | #! perl -w 2 | # Author: Bert Muennich 3 | # Website: http://www.github.com/muennich/urxvt-perls 4 | # License: GPLv2 5 | 6 | # Use keyboard shortcuts to select and copy text. 7 | 8 | # Usage: put the following lines in your .Xdefaults/.Xresources: 9 | # URxvt.perl-ext-common: ...,keyboard-select 10 | # URxvt.keysym.M-Escape: perl:keyboard-select:activate 11 | # The following line overwrites the default Meta-s binding and allows to 12 | # activate keyboard-select directly in backward search mode: 13 | # URxvt.keysym.M-s: perl:keyboard-select:search 14 | 15 | # Use Meta-Escape to activate selection mode, then use the following keys: 16 | # h/j/k/l: Move cursor left/down/up/right (also with arrow keys) 17 | # g/G/0/^/$/H/M/L/f/F/;/,/w/W/b/B/e/E: More vi-like cursor movement keys 18 | # '/'/?: Start forward/backward search 19 | # n/N: Repeat last search, N: in reverse direction 20 | # Ctrl-f/b: Scroll down/up one screen 21 | # Ctrl-d/u: Scroll down/up half a screen 22 | # v/V/Ctrl-v: Toggle normal/linewise/blockwise selection 23 | # y/Return: Copy selection to primary buffer, Return: deactivate afterwards 24 | # q/Escape: Deactivate keyboard selection mode 25 | 26 | 27 | use strict; 28 | 29 | sub on_start{ 30 | my ($self) = @_; 31 | 32 | $self->{patterns}{'w'} = qr/\w[^\w\s]|\W\w|\s\S/; 33 | $self->{patterns}{'W'} = qr/\s\S/; 34 | $self->{patterns}{'b'} = qr/.*(?:\w[^\w\s]|\W\w|\s\S)/; 35 | $self->{patterns}{'B'} = qr/.*\s\S/; 36 | $self->{patterns}{'e'} = qr/[^\w\s](?=\w)|\w(?=\W)|\S(?=\s|$)/; 37 | $self->{patterns}{'E'} = qr/\S(?=\s|$)/; 38 | 39 | () 40 | } 41 | 42 | 43 | sub on_user_command { 44 | my ($self, $cmd) = @_; 45 | 46 | if (not $self->{active}) { 47 | if ($cmd eq 'keyboard-select:activate') { 48 | activate($self); 49 | } elsif ($cmd eq 'keyboard-select:search') { 50 | activate($self, 1); 51 | } 52 | } 53 | 54 | () 55 | } 56 | 57 | 58 | sub key_press { 59 | my ($self, $event, $keysym, $char) = @_; 60 | my $key = chr($keysym); 61 | 62 | if (lc($key) eq 'c' && $event->{state} & urxvt::ControlMask) { 63 | deactivate($self); 64 | } elsif ($self->{search}) { 65 | if ($keysym == 0xff1b) { 66 | if ($self->{search_mode}) { 67 | deactivate($self); 68 | } else { 69 | $self->{search} = ''; 70 | status_area($self); 71 | } 72 | } elsif ($keysym == 0xff08) { 73 | $self->{search} = substr($self->{search}, 0, -1); 74 | if (not $self->{search} and $self->{search_mode}) { 75 | deactivate($self); 76 | } else { 77 | status_area($self); 78 | } 79 | } elsif ($keysym == 0xff0d) { 80 | my $txt = substr($self->{search}, 1); 81 | if ($txt) { 82 | $self->{pattern} = ($txt =~ m/[[:upper:]]/) ? qr/\Q$txt\E/ : 83 | qr/\Q$txt\E/i; 84 | } elsif ($self->{pattern}) { 85 | delete $self->{pattern}; 86 | } 87 | $self->{search} = ''; 88 | $self->screen_cur($self->{srhcr}, $self->{srhcc}); 89 | if (not find_next($self)) { 90 | if ($self->{search_mode}) { 91 | deactivate($self); 92 | } else { 93 | status_area($self); 94 | } 95 | } 96 | } elsif (length($char) > 0) { 97 | $self->{search} .= $self->locale_decode($char); 98 | my $txt = substr($self->{search}, 1); 99 | if ($txt) { 100 | $self->{pattern} = ($txt =~ m/[[:upper:]]/) ? qr/\Q$txt\E/ : 101 | qr/\Q$txt\E/i; 102 | } elsif ($self->{pattern}) { 103 | delete $self->{pattern}; 104 | } 105 | $self->screen_cur($self->{srhcr}, $self->{srhcc}); 106 | find_next($self); 107 | status_area($self); 108 | } 109 | } elsif ($self->{move_to}) { 110 | if ($keysym == 0xff1b) { 111 | $self->{move_to} = 0; 112 | status_area($self); 113 | } elsif (length($char) > 0) { 114 | $self->{move_to} = 0; 115 | $self->{patterns}{'f-1'} = qr/^.*\Q$key\E/; 116 | $self->{patterns}{'f+1'} = qr/^.+?\Q$key\E/; 117 | move_to($self, ';'); 118 | status_area($self); 119 | } 120 | } elsif ($keysym == 0xff1b || lc($key) eq 'q') { 121 | deactivate($self); 122 | } elsif ($key eq 'y' || $keysym == 0xff0d) { 123 | if ($self->{select}) { 124 | if ($self->{select} eq 'b') { 125 | $self->selection($self->{selection}); 126 | $self->selection_grab($event->{time}); 127 | } else { 128 | my ($br, $bc, $er, $ec) = calc_span($self); 129 | $ec = $self->line($er)->l if $self->{select} eq 'l'; 130 | $self->selection_beg($br, $bc); 131 | $self->selection_end($er, $ec); 132 | $self->selection_make($event->{time}); 133 | } 134 | if ($key eq 'y') { 135 | if ($self->{select} ne 'b') { 136 | $self->selection_beg(1, 0); 137 | $self->selection_end(1, 0); 138 | } 139 | $self->{select} = ''; 140 | status_area($self); 141 | $self->want_refresh(); 142 | } else { 143 | deactivate($self); 144 | } 145 | } 146 | } elsif ($key eq 'V') { 147 | toggle_select($self, 'l'); 148 | } elsif ($key eq 'v') { 149 | if ($event->{state} & urxvt::ControlMask) { 150 | toggle_select($self, 'b'); 151 | } else { 152 | toggle_select($self, 'n'); 153 | } 154 | } elsif ($key eq 'k' || $keysym == 0xff52) { 155 | move_cursor($self, 'k'); 156 | } elsif ($key eq 'j' || $keysym == 0xff54) { 157 | move_cursor($self, 'j'); 158 | } elsif ($key eq 'h' || $keysym == 0xff51) { 159 | move_cursor($self, 'h'); 160 | } elsif ($key eq 'l' || $keysym == 0xff53) { 161 | move_cursor($self, 'l'); 162 | } elsif ('gG0^$HML' =~ m/\Q$key\E/ || 163 | ('fbdu' =~ m/\Q$key\E/ && $event->{state} & urxvt::ControlMask)) { 164 | move_cursor($self, $key); 165 | } elsif (lc($key) eq 'f') { 166 | $self->{move_to} = 1; 167 | $self->{move_dir} = $key eq 'F' ? -1 : 1; 168 | status_area($self, $key); 169 | } elsif (';,wWbBeE' =~ m/\Q$key\E/) { 170 | move_to($self, $key); 171 | } elsif ($key eq '/' || $key eq '?') { 172 | $self->{search} = $key; 173 | $self->{search_dir} = $key eq '?' ? -1 : 1; 174 | ($self->{srhcr}, $self->{srhcc}) = $self->screen_cur(); 175 | status_area($self); 176 | } elsif (lc($key) eq 'n') { 177 | find_next($self, $self->{search_dir} * ($key eq 'N' ? -1 : 1)); 178 | } 179 | 180 | return 1; 181 | } 182 | 183 | 184 | sub move_cursor { 185 | my ($self, $key) = @_; 186 | my ($cr, $cc) = $self->screen_cur(); 187 | my $line = $self->line($cr); 188 | 189 | if ($key eq 'k' && $line->beg > $self->top_row) { 190 | $cr = $line->beg - 1; 191 | } elsif ($key eq 'j' && $line->end < $self->nrow - 1) { 192 | $cr = $line->end + 1; 193 | } elsif ($key eq 'h' && $self->{offset} > 0) { 194 | $self->{offset} = $line->offset_of($cr, $cc) - 1; 195 | $self->{dollar} = 0; 196 | } elsif ($key eq 'l' && $self->{offset} < $line->l - 1) { 197 | ++$self->{offset}; 198 | } elsif ($key eq 'f' || $key eq 'd') { 199 | my $vs = $self->view_start() + 200 | ($key eq 'd' ? $self->nrow / 2 : $self->nrow - 1); 201 | $vs = 0 if $vs > 0; 202 | $cr += $vs - $self->view_start($vs); 203 | } elsif ($key eq 'b' || $key eq 'u') { 204 | my $vs = $self->view_start() - 205 | ($key eq 'u' ? $self->nrow / 2 : $self->nrow - 1); 206 | $vs = $self->top_row if $vs < $self->top_row; 207 | $cr += $vs - $self->view_start($vs); 208 | } elsif ($key eq 'g') { 209 | ($cr, $self->{offset}) = ($self->top_row, 0); 210 | $self->{dollar} = 0; 211 | } elsif ($key eq 'G') { 212 | ($cr, $self->{offset}) = ($self->nrow - 1, 0); 213 | $self->{dollar} = 0; 214 | } elsif ($key eq '0') { 215 | $self->{offset} = 0; 216 | $self->{dollar} = 0; 217 | } elsif ($key eq '^') { 218 | my $ltxt = $self->special_decode($line->t); 219 | while ($ltxt =~ s/^( *)\t/$1 . " " x (8 - length($1) % 8)/e) {} 220 | $self->{offset} = $ltxt =~ m/^ +/ ? $+[0] : 0; 221 | $self->{dollar} = 0; 222 | } elsif ($key eq '$') { 223 | my $co = $line->offset_of($cr, $cc); 224 | $self->{dollar} = $co + 1; 225 | $self->{offset} = $line->l - 1; 226 | } elsif ($key eq 'H') { 227 | $cr = $self->view_start(); 228 | } elsif ($key eq 'M') { 229 | $cr = $self->view_start() + $self->nrow / 2; 230 | } elsif ($key eq 'L') { 231 | $cr = $self->view_start() + $self->nrow - 1; 232 | } 233 | 234 | $line = $self->line($cr); 235 | $cc = $self->{dollar} || $self->{offset} >= $line->l ? $line->l - 1 : 236 | $self->{offset}; 237 | $self->screen_cur($line->coord_of($cc)); 238 | 239 | status_area($self); 240 | $self->want_refresh(); 241 | 242 | () 243 | } 244 | 245 | 246 | sub move_to { 247 | my ($self, $key) = @_; 248 | my ($cr, $cc) = $self->screen_cur(); 249 | my $line = $self->line($cr); 250 | my $offset = $self->{offset}; 251 | my ($dir, $pattern); 252 | my ($wrap, $found) = (0, 0); 253 | 254 | if ($key eq ';' || $key eq ',') { 255 | $dir = $self->{move_dir} * ($key eq ',' ? -1 : 1); 256 | $pattern = $self->{patterns}{sprintf('f%+d', $dir)}; 257 | return if not $pattern; 258 | } else { 259 | if (lc($key) eq 'b') { 260 | $dir = -1; 261 | } else { 262 | $dir = 1; 263 | ++$offset if lc($key) eq 'e'; 264 | } 265 | $pattern = $self->{patterns}{$key}; 266 | $wrap = 1; 267 | } 268 | 269 | if ($dir > 0) { 270 | NEXTDOWN: my $text = substr($line->t, $offset); 271 | if ($text =~ m/$pattern/) { 272 | $offset += $+[0] - 1; 273 | $found = 1; 274 | } elsif ($wrap && $line->end + 1 < $self->nrow) { 275 | $cr = $line->end + 1; 276 | $line = $self->line($cr); 277 | $offset = 0; 278 | if (lc($key) eq 'e') { 279 | goto NEXTDOWN; 280 | } else { 281 | $found = 1; 282 | } 283 | } 284 | } elsif ($dir < 0) { 285 | NEXTUP: my $text = substr($line->t, 0, $offset); 286 | if ($text =~ m/$pattern/) { 287 | $offset += $+[0] - length($text) - 1; 288 | $found = 1; 289 | } elsif ($wrap) { 290 | if ($offset > 0) { 291 | $offset = 0; 292 | $found = 1; 293 | } elsif ($line->beg > $self->top_row) { 294 | $cr = $line->beg - 1; 295 | $line = $self->line($cr); 296 | $offset = $line->l; 297 | goto NEXTUP; 298 | } 299 | } 300 | } 301 | 302 | if ($found) { 303 | $self->{dollar} = 0; 304 | $self->{offset} = $offset; 305 | $self->screen_cur($line->coord_of($offset)); 306 | $self->want_refresh(); 307 | } 308 | 309 | () 310 | } 311 | 312 | 313 | sub find_next { 314 | my ($self, $dir) = @_; 315 | 316 | return if not $self->{pattern}; 317 | $dir = $self->{search_dir} if not $dir; 318 | 319 | my ($cr, $cc) = $self->screen_cur(); 320 | my $line = $self->line($cr); 321 | my $offset = $line->offset_of($cr, $cc); 322 | my $text; 323 | my $found = 0; 324 | 325 | ++$offset if $dir > 0; 326 | 327 | while (not $found) { 328 | if ($dir > 0) { 329 | $text = substr($line->t, $offset); 330 | if ($text =~ m/$self->{pattern}/) { 331 | $found = 1; 332 | $offset += $-[0]; 333 | } else { 334 | last if $line->end >= $self->nrow; 335 | $line = $self->line($line->end + 1); 336 | $offset = 0; 337 | } 338 | } else { 339 | $text = substr($line->t, 0, $offset); 340 | if ($text =~ m/$self->{pattern}/) { 341 | $found = 1; 342 | $offset = $-[0] while $text =~ m/$self->{pattern}/g; 343 | } else { 344 | last if $line->beg <= $self->top_row; 345 | $line = $self->line($line->beg - 1); 346 | $offset = $line->l; 347 | } 348 | } 349 | } 350 | 351 | if ($found) { 352 | $self->{dollar} = 0; 353 | $self->{offset} = $offset; 354 | $self->screen_cur($line->coord_of($offset)); 355 | status_area($self); 356 | $self->want_refresh(); 357 | } 358 | 359 | return $found; 360 | } 361 | 362 | 363 | sub tt_write { 364 | return 1; 365 | } 366 | 367 | 368 | sub refresh { 369 | my ($self) = @_; 370 | my $reverse_cursor = $self->{select} ne 'l'; 371 | my ($cr, $cc) = $self->screen_cur(); 372 | 373 | if ($self->{select}) { 374 | my ($br, $bc, $er, $ec) = calc_span($self); 375 | 376 | if ($self->{select} eq 'b') { 377 | delete $self->{selection} if $self->{selection}; 378 | my $co = $self->line($cr)->offset_of($cr, $cc); 379 | my $dollar = $self->{dollar} && $co >= $self->{dollar} - 1; 380 | 381 | my $r = $br; 382 | while ($r <= $er) { 383 | my $line = $self->line($r); 384 | if ($bc < $line->l) { 385 | $ec = $line->l if $dollar; 386 | $self->{selection} .= substr($line->t, $bc, $ec - $bc); 387 | my ($br, $bc) = $line->coord_of($bc); 388 | my ($er, $ec) = $line->coord_of($ec <= $line->l ? $ec : $line->l); 389 | $self->scr_xor_span($br, $bc, $er, $ec, urxvt::RS_RVid); 390 | } elsif ($r == $cr) { 391 | $reverse_cursor = 0; 392 | } 393 | $self->{selection} .= "\n" if $line->end < $er; 394 | $r = $line->end + 1; 395 | } 396 | } else { 397 | $self->scr_xor_span($br, $bc, $er, $ec, urxvt::RS_RVid); 398 | } 399 | 400 | if ($reverse_cursor) { 401 | # make the cursor visible again 402 | $self->scr_xor_span($cr, $cc, $cr, $cc + 1, urxvt::RS_RVid); 403 | } 404 | } 405 | 406 | # scroll the current cursor position into visible area 407 | if ($cr < $self->view_start()) { 408 | $self->view_start($cr); 409 | } elsif ($cr >= $self->view_start() + $self->nrow) { 410 | $self->view_start($cr - $self->nrow + 1); 411 | } 412 | 413 | () 414 | } 415 | 416 | 417 | sub activate { 418 | my ($self, $search) = @_; 419 | 420 | $self->{active} = 1; 421 | 422 | $self->{select} = ''; 423 | $self->{dollar} = 0; 424 | $self->{move_to} = 0; 425 | 426 | if ($search) { 427 | $self->{search} = '?'; 428 | $self->{search_dir} = -1; 429 | $self->{search_mode} = 1; 430 | } else { 431 | $self->{search} = ''; 432 | $self->{search_mode} = 0; 433 | } 434 | 435 | ($self->{oldcr}, $self->{oldcc}) = $self->screen_cur(); 436 | ($self->{srhcr}, $self->{srhcc}) = $self->screen_cur(); 437 | $self->{old_view_start} = $self->view_start(); 438 | $self->{old_pty_ev_events} = $self->pty_ev_events(urxvt::EV_NONE); 439 | 440 | my $line = $self->line($self->{oldcr}); 441 | $self->{offset} = $line->offset_of($self->{oldcr}, $self->{oldcc}); 442 | 443 | $self->selection_beg(1, 0); 444 | $self->selection_end(1, 0); 445 | 446 | $self->enable( 447 | key_press => \&key_press, 448 | refresh_begin => \&refresh, 449 | refresh_end => \&refresh, 450 | tt_write => \&tt_write, 451 | ); 452 | 453 | if ($self->{offset} >= $line->l) { 454 | $self->{offset} = $line->l > 0 ? $line->l - 1 : 0; 455 | $self->screen_cur($line->coord_of($self->{offset})); 456 | $self->want_refresh(); 457 | } 458 | 459 | $self->{overlay_len} = 0; 460 | status_area($self); 461 | 462 | () 463 | } 464 | 465 | 466 | sub deactivate { 467 | my ($self) = @_; 468 | 469 | $self->selection_beg(1, 0); 470 | $self->selection_end(1, 0); 471 | 472 | delete $self->{overlay} if $self->{overlay}; 473 | delete $self->{selection} if $self->{selection}; 474 | 475 | $self->disable("key_press", "refresh_begin", "refresh_end", "tt_write"); 476 | $self->screen_cur($self->{oldcr}, $self->{oldcc}); 477 | $self->view_start($self->{old_view_start}); 478 | $self->pty_ev_events($self->{old_pty_ev_events}); 479 | 480 | $self->want_refresh(); 481 | 482 | $self->{active} = 0; 483 | 484 | () 485 | } 486 | 487 | 488 | sub status_area { 489 | my ($self, $extra) = @_; 490 | my ($stat, $stat_len); 491 | 492 | if ($self->{search}) { 493 | $stat_len = $self->ncol; 494 | $stat = $self->{search} . ' ' x ($stat_len - length($self->{search})); 495 | } else { 496 | if ($self->{select}) { 497 | $stat = "-V" . ($self->{select} ne 'n' ? uc($self->{select}) : "") . "- "; 498 | } 499 | 500 | if ($self->top_row == 0) { 501 | $stat .= "All"; 502 | } elsif ($self->view_start() == $self->top_row) { 503 | $stat .= "Top"; 504 | } elsif ($self->view_start() == 0) { 505 | $stat .= "Bot"; 506 | } else { 507 | $stat .= sprintf("%2d%%", 508 | ($self->top_row - $self->view_start) * 100 / $self->top_row); 509 | } 510 | 511 | $stat = "$extra $stat" if $extra; 512 | $stat_len = length($stat); 513 | } 514 | 515 | if (!$self->{overlay} || $self->{overlay_len} != $stat_len) { 516 | delete $self->{overlay} if $self->{overlay}; 517 | $self->{overlay} = $self->overlay(-1, -1, $stat_len, 1, 518 | urxvt::OVERLAY_RSTYLE, 0); 519 | $self->{overlay_len} = $stat_len; 520 | } 521 | 522 | $self->{overlay}->set(0, 0, $self->special_encode($stat)); 523 | $self->{overlay}->show(); 524 | 525 | () 526 | } 527 | 528 | 529 | sub toggle_select { 530 | my ($self, $mode) = @_; 531 | 532 | if ($self->{select} eq $mode) { 533 | $self->{select} = ''; 534 | } else { 535 | if (not $self->{select}) { 536 | ($self->{ar}, $self->{ac}) = $self->screen_cur(); 537 | } 538 | $self->{select} = $mode; 539 | } 540 | 541 | status_area($self); 542 | $self->want_refresh(); 543 | 544 | () 545 | } 546 | 547 | 548 | sub calc_span { 549 | my ($self) = @_; 550 | my ($cr, $cc) = $self->screen_cur(); 551 | my ($br, $bc, $er, $ec); 552 | 553 | if ($self->{select} eq 'b') { 554 | $br = $self->line($cr)->beg; 555 | $bc = $self->line($cr)->offset_of($cr, $cc); 556 | $er = $self->line($self->{ar})->beg; 557 | $ec = $self->line($self->{ar})->offset_of($self->{ar}, $self->{ac}); 558 | ($br, $er) = ($er, $br) if $br > $er; 559 | ($bc, $ec) = ($ec, $bc) if $bc > $ec; 560 | } else { 561 | if ($cr < $self->{ar}) { 562 | ($br, $bc, $er, $ec) = ($cr, $cc, $self->{ar}, $self->{ac}); 563 | } elsif ($cr > $self->{ar}) { 564 | ($br, $bc, $er, $ec) = ($self->{ar}, $self->{ac}, $cr, $cc); 565 | } else { 566 | ($br, $er) = ($cr, $cr); 567 | ($bc, $ec) = $cc < $self->{ac} ? ($cc, $self->{ac}) : ($self->{ac}, $cc); 568 | } 569 | } 570 | 571 | if ($self->{select} eq 'l') { 572 | ($br, $er) = ($self->line($br)->beg, $self->line($er)->end); 573 | ($bc, $ec) = (0, $self->ncol); 574 | } else { 575 | ++$ec; 576 | } 577 | 578 | return ($br, $bc, $er, $ec); 579 | } 580 | -------------------------------------------------------------------------------- /conf/urxvt-perl/url-select: -------------------------------------------------------------------------------- 1 | #! perl -w 2 | # Author: Bert Muennich 3 | # Website: http://www.github.com/muennich/urxvt-perls 4 | # Based on: http://www.jukie.net/~bart/blog/urxvt-url-yank 5 | # License: GPLv2 6 | 7 | # Use keyboard shortcuts to select URLs. 8 | # This should be used as a replacement for the default matcher extension, 9 | # it also makes URLs clickable with the middle mouse button. 10 | 11 | # Usage: put the following lines in your .Xdefaults/.Xresources: 12 | # URxvt.perl-ext-common: ...,url-select 13 | # URxvt.keysym.M-u: perl:url-select:select_next 14 | 15 | # Use Meta-u to activate URL selection mode, then use the following keys: 16 | # j/k: Select next downward/upward URL (also with arrow keys) 17 | # g/G: Select first/last URL (also with home/end key) 18 | # o/Return: Open selected URL in browser, Return: deactivate afterwards 19 | # y: Copy (yank) selected URL and deactivate selection mode 20 | # q/Escape: Deactivate URL selection mode 21 | 22 | # Options: 23 | # URxvt.url-select.autocopy: If true, selected URLs are copied to PRIMARY 24 | # URvxt.url-select.button: Mouse button to click-open URLs (default: 2) 25 | # URxvt.url-select.launcher: Browser/command to open selected URL with 26 | # URxvt.url-select.underline: If set to true, all URLs get underlined 27 | 28 | use strict; 29 | 30 | sub on_start { 31 | my ($self) = @_; 32 | 33 | # read resource settings 34 | if ($self->x_resource('url-select.launcher')) { 35 | @{$self->{browser}} = split /\s+/, $self->x_resource('url-select.launcher'); 36 | } else { 37 | @{$self->{browser}} = ('x-www-browser'); 38 | } 39 | if ($self->x_resource('url-select.underline') eq 'true') { 40 | $self->enable(line_update => \&line_update); 41 | } 42 | if ($self->x_resource('url-select.autocopy') eq 'true') { 43 | $self->{autocopy} = 1; 44 | } 45 | 46 | $self->{state} = 0; 47 | 48 | for my $mod (split '', $self->x_resource("url-select.button") || 49 | $self->x_resource("matcher.button") || 2) { 50 | if ($mod =~ /^\d+$/) { 51 | $self->{button} = $mod; 52 | } elsif ($mod eq "C") { 53 | $self->{state} |= urxvt::ControlMask; 54 | } elsif ($mod eq "S") { 55 | $self->{state} |= urxvt::ShiftMask; 56 | } elsif ($mod eq "M") { 57 | $self->{state} |= $self->ModMetaMask; 58 | } elsif ($mod ne "-" && $mod ne " ") { 59 | warn("invalid button/modifier in $self->{_name}<$self->{argv}[0]>: $mod\n"); 60 | } 61 | } 62 | 63 | if ($self->x_resource('matcher.pattern')) { 64 | @{$self->{pattern}} = ($self->x_resource('matcher.pattern')); 65 | } elsif ($self->x_resource('matcher.pattern.0')) { 66 | my $current = 0; 67 | 68 | while (defined (my $res = $self->x_resource("matcher.pattern.$current"))) { 69 | $res = $self->locale_decode($res); 70 | utf8::encode $res; 71 | push @{$self->{pattern}}, qr($res)x; 72 | $current++; 73 | } 74 | } else { 75 | @{$self->{pattern}} = qr{ 76 | (?:https?://|ftp://|news://|mailto:|file://|\bwww\.) 77 | [\w\-\@;\/?:&=%\$.+!*\x27,~#]* 78 | ( 79 | \([\w\-\@;\/?:&=%\$.+!*\x27,~#]*\) # Allow a pair of matched parentheses 80 | | # 81 | [\w\-\@;\/?:&=%\$+*~] # exclude some trailing characters (heuristic) 82 | )+ 83 | }x; 84 | } 85 | 86 | () 87 | } 88 | 89 | 90 | sub line_update { 91 | my ($self, $row) = @_; 92 | 93 | my $line = $self->line($row); 94 | my $text = $line->t; 95 | my $rend = $line->r; 96 | 97 | for my $pattern (@{$self->{pattern}}) { 98 | while ($text =~ /$pattern/g) { 99 | my $url = $&; 100 | my ($beg, $end) = ($-[0], $+[0] - 1); 101 | 102 | for (@{$rend}[$beg .. $end]) { 103 | $_ |= urxvt::RS_Uline; 104 | } 105 | $line->r($rend); 106 | } 107 | } 108 | 109 | () 110 | } 111 | 112 | 113 | sub on_user_command { 114 | my ($self, $cmd) = @_; 115 | 116 | if ($cmd eq 'url-select:select_next') { 117 | if (not $self->{active}) { 118 | activate($self); 119 | } 120 | select_next($self, -1); 121 | } 122 | 123 | () 124 | } 125 | 126 | 127 | sub key_press { 128 | my ($self, $event, $keysym) = @_; 129 | my $char = chr($keysym); 130 | 131 | if ($keysym == 0xff1b || lc($char) eq 'q' || 132 | (lc($char) eq 'c' && $event->{state} & urxvt::ControlMask)) { 133 | deactivate($self); 134 | } elsif ($keysym == 0xff0d || $char eq 'o') { 135 | $self->exec_async(@{$self->{browser}}, ${$self->{found}[$self->{n}]}[4]); 136 | deactivate($self) unless $char eq 'o'; 137 | } elsif ($char eq 'y') { 138 | my $found = $self->{found}[$self->{n}]; 139 | $self->selection_beg(${$found}[0], ${$found}[1]); 140 | $self->selection_end(${$found}[2], ${$found}[3]); 141 | $self->selection_make($event->{time}); 142 | $self->selection_beg(1, 0); 143 | $self->selection_end(1, 0); 144 | deactivate($self); 145 | } elsif ($char eq 'k' || $keysym == 0xff52 || $keysym == 0xff51) { 146 | select_next($self, -1, $event); 147 | } elsif ($char eq 'j' || $keysym == 0xff54 || $keysym == 0xff53) { 148 | select_next($self, 1, $event); 149 | } elsif ($char eq 'g' || $keysym == 0xff50) { 150 | $self->{row} = $self->top_row - 1; 151 | delete $self->{found}; 152 | select_next($self, 1, $event); 153 | } elsif ($char eq 'G' || $keysym == 0xff57) { 154 | $self->{row} = $self->nrow; 155 | delete $self->{found}; 156 | select_next($self, -1, $event); 157 | } 158 | 159 | return 1; 160 | } 161 | 162 | 163 | sub on_button_press { 164 | my ($self, $event) = @_; 165 | 166 | my $mask = $self->ModLevel3Mask | $self->ModMetaMask | 167 | urxvt::ShiftMask | urxvt::ControlMask; 168 | 169 | if ($event->{button} == $self->{button} && ($event->{state} & $mask) == $self->{state}) { 170 | $self->{button_pressed} = 1; 171 | $self->{button_col} = $event->{col}; 172 | $self->{button_row} = $event->{row}; 173 | } 174 | 175 | () 176 | } 177 | 178 | sub on_button_release { 179 | my ($self, $event) = @_; 180 | 181 | if ($self->{button_pressed} && $event->{button} == $self->{button}) { 182 | my $col = $event->{col}; 183 | my $row = $event->{row}; 184 | 185 | $self->{button_pressed} = 0; 186 | 187 | if ($col == $self->{button_col} && $row == $self->{button_row}) { 188 | my $line = $self->line($row); 189 | my $text = $line->t; 190 | 191 | for my $pattern (@{$self->{pattern}}) { 192 | while ($text =~ /$pattern/g) { 193 | my ($url, $beg, $end) = ($&, $-[0], $+[0]); 194 | --$end if $url =~ s/["')]$//; 195 | 196 | if ($col >= $beg && $col <= $end) { 197 | $self->exec_async(@{$self->{browser}}, $url); 198 | return 1; 199 | } 200 | } 201 | } 202 | } 203 | } 204 | 205 | () 206 | } 207 | 208 | 209 | sub select_next { 210 | # $dir < 0: up, > 0: down 211 | my ($self, $dir, $event) = @_; 212 | my $row = $self->{row}; 213 | 214 | if (($dir < 0 && $self->{n} > 0) || 215 | ($dir > 0 && $self->{n} < $#{ $self->{found} })) { 216 | # another url on current line 217 | $self->{n} += $dir; 218 | hilight($self); 219 | if ($self->{autocopy}) { 220 | my $found = $self->{found}[$self->{n}]; 221 | $self->selection_beg(${$found}[0], ${$found}[1]); 222 | $self->selection_end(${$found}[2], ${$found}[3]); 223 | $self->selection_make($event->{time}); 224 | $self->selection_beg(1, 0); 225 | $self->selection_end(1, 0); 226 | } 227 | return; 228 | } 229 | 230 | while (($dir < 0 && $row > $self->top_row) || 231 | ($dir > 0 && $row < $self->nrow - 1)) { 232 | my $line = $self->line($row); 233 | $row = ($dir < 0 ? $line->beg : $line->end) + $dir; 234 | $line = $self->line($row); 235 | my $text = $line->t; 236 | 237 | for my $pattern (@{$self->{pattern}}) { 238 | if ($text =~ /$pattern/g) { 239 | delete $self->{found}; 240 | 241 | do { 242 | my ($beg, $end) = ($-[0], $+[0]); 243 | push @{$self->{found}}, [$line->coord_of($beg), 244 | $line->coord_of($end), substr($text, $beg, $end - $beg)]; 245 | } while ($text =~ /$pattern/g); 246 | 247 | $self->{row} = $row; 248 | $self->{n} = $dir < 0 ? $#{$self->{found}} : 0; 249 | hilight($self); 250 | if ($self->{autocopy}) { 251 | my $found = $self->{found}[$self->{n}]; 252 | $self->selection_beg(${$found}[0], ${$found}[1]); 253 | $self->selection_end(${$found}[2], ${$found}[3]); 254 | $self->selection_make($event->{time}); 255 | $self->selection_beg(1, 0); 256 | $self->selection_end(1, 0); 257 | } 258 | return; 259 | } 260 | } 261 | } 262 | 263 | deactivate($self) unless $self->{found}; 264 | 265 | () 266 | } 267 | 268 | 269 | sub hilight { 270 | my ($self) = @_; 271 | 272 | if ($self->{found}) { 273 | if ($self->{row} < $self->view_start() || 274 | $self->{row} >= $self->view_start() + $self->nrow) { 275 | # scroll selected url into visible area 276 | my $top = $self->{row} - ($self->nrow >> 1); 277 | $self->view_start($top < 0 ? $top : 0); 278 | } 279 | 280 | status_area($self); 281 | $self->want_refresh(); 282 | } 283 | 284 | () 285 | } 286 | 287 | 288 | sub refresh { 289 | my ($self) = @_; 290 | 291 | if ($self->{found}) { 292 | $self->scr_xor_span(@{$self->{found}[$self->{n}]}[0 .. 3], urxvt::RS_RVid); 293 | } 294 | 295 | () 296 | } 297 | 298 | 299 | sub status_area { 300 | my ($self) = @_; 301 | 302 | my $row = $self->{row} < 0 ? 303 | $self->{row} - $self->top_row : abs($self->top_row) + $self->{row}; 304 | my $text = sprintf("%d,%d ", $row + 1, $self->{n} + 1); 305 | 306 | if ($self->top_row == 0) { 307 | $text .= "All"; 308 | } elsif ($self->view_start() == $self->top_row) { 309 | $text .= "Top"; 310 | } elsif ($self->view_start() == 0) { 311 | $text .= "Bot"; 312 | } else { 313 | $text .= sprintf("%2d%", 314 | ($self->top_row - $self->view_start) * 100 / $self->top_row); 315 | } 316 | 317 | my $text_len = length($text); 318 | 319 | if ($self->{overlay_len} != $text_len) { 320 | delete $self->{overlay} if $self->{overlay}; 321 | $self->{overlay} = $self->overlay(-1, -1, $text_len, 1, 322 | urxvt::OVERLAY_RSTYLE, 0); 323 | $self->{overlay_len} = $text_len; 324 | } 325 | 326 | $self->{overlay}->set(0, 0, $self->special_encode($text)); 327 | $self->{overlay}->show(); 328 | 329 | () 330 | } 331 | 332 | 333 | sub tt_write { 334 | return 1; 335 | } 336 | 337 | 338 | sub activate { 339 | my ($self) = @_; 340 | 341 | $self->{active} = 1; 342 | 343 | $self->{row} = $self->view_start() + $self->nrow; 344 | $self->{n} = 0; 345 | $self->{overlay_len} = 0; 346 | $self->{button_pressed} = 0; 347 | 348 | $self->{view_start} = $self->view_start(); 349 | $self->{pty_ev_events} = $self->pty_ev_events(urxvt::EV_NONE); 350 | 351 | $self->enable( 352 | key_press => \&key_press, 353 | refresh_begin => \&refresh, 354 | refresh_end => \&refresh, 355 | tt_write => \&tt_write, 356 | ); 357 | 358 | () 359 | } 360 | 361 | 362 | sub deactivate { 363 | my ($self) = @_; 364 | 365 | $self->disable("key_press", "refresh_begin", "refresh_end", "tt_write"); 366 | $self->view_start($self->{view_start}); 367 | $self->pty_ev_events($self->{pty_ev_events}); 368 | 369 | delete $self->{overlay} if $self->{overlay}; 370 | delete $self->{found} if $self->{found}; 371 | 372 | $self->want_refresh(); 373 | 374 | $self->{active} = 0; 375 | 376 | () 377 | } 378 | -------------------------------------------------------------------------------- /configuration.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, ... }: { 2 | imports = [ ./hardware-overrides.nix ./conf/default.nix ]; 3 | nixpkgs.config = import ./conf/nixpkgs.nix; 4 | _module.args.expr = import ./expr { inherit pkgs; }; 5 | _module.args.buildVM = false; 6 | } 7 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | let 2 | configuration = { config, pkgs, ... }: { 3 | 4 | imports = [ ./conf/default.nix ./vm-accounts.nix ]; 5 | 6 | nixpkgs.config = import ./conf/nixpkgs.nix; 7 | _module.args.expr = import ./expr { inherit pkgs; }; 8 | _module.args.buildVM = true; 9 | 10 | # Set VM disk size (in MB) 11 | virtualisation.diskSize = 2048; 12 | 13 | # Set VM ram amount (in MB) 14 | virtualisation.memorySize = 1024; 15 | 16 | }; 17 | build = import { inherit configuration; }; 18 | in build.vm 19 | -------------------------------------------------------------------------------- /expr/README.md: -------------------------------------------------------------------------------- 1 | Some nixpressions that I need which are not in [nixpkgs](http://github.com/NixOS/nixpkgs), mostly because 2 | they are customized to my preferences. 3 | -------------------------------------------------------------------------------- /expr/armagetronad/coler_auto_completion.patch: -------------------------------------------------------------------------------- 1 | === modified file 'src/engine/ePlayer.cpp' 2 | --- src/engine/ePlayer.cpp 2014-01-20 22:54:25 +0000 3 | +++ src/engine/ePlayer.cpp 2014-02-18 21:17:51 +0000 4 | @@ -161,6 +161,9 @@ 5 | static bool se_enableChat = true; //flag indicating whether chat should be allowed at all (logged in players can always chat) 6 | static tSettingItem< bool > se_enaChat("ENABLE_CHAT", se_enableChat); 7 | 8 | +static bool se_autoCompleteWithColor = false; 9 | +static tSettingItem< bool > se_autoComplColor("AUTO_COMPLETE_WITH_COLOR", se_autoCompleteWithColor); 10 | + 11 | static tString se_hiddenPlayerPrefix ("0xaaaaaa"); 12 | static tConfItemLine se_hiddenPlayerPrefixConf( "PLAYER_LIST_HIDDEN_PLAYER_PREFIX", se_hiddenPlayerPrefix ); 13 | 14 | @@ -4263,7 +4266,9 @@ 15 | "/promote ", 16 | "/demote ", 17 | "/vote kick ", 18 | - "/vote suspend " 19 | + "/vote suspend ", 20 | + "/vote referee ", 21 | + "/players " 22 | }; 23 | 24 | //! Completer with the addition that it adds a : to a fully completed name if it's at the beginning of the line 25 | @@ -4274,8 +4279,12 @@ 26 | eAutoCompleterChat(std::deque &words):uAutoCompleter(words) {}; 27 | int DoFullCompletion(tString &string, int pos, int len, tString &match) { 28 | tString actualString; 29 | + tString resetColor; 30 | + 31 | + resetColor = se_autoCompleteWithColor ? "0xffff7f" : ""; 32 | + 33 | if(pos - len == 0 || ( pos - len == 6 && string.StartsWith("/team ") ) ) { 34 | - actualString = match + ": "; 35 | + actualString = match + resetColor + ": "; 36 | } else if(string.StartsWith("/admin ") || string.StartsWith("/vote shuffle ")) { 37 | actualString = Simplify(match) + " "; 38 | } else { 39 | @@ -4287,7 +4296,7 @@ 40 | } 41 | } 42 | if(i < 0) { 43 | - actualString = match + " "; 44 | + actualString = match + resetColor + " "; 45 | } 46 | } 47 | return DoCompletion(string, pos, len, actualString); 48 | @@ -4411,7 +4420,7 @@ 49 | unsigned short int max=se_PlayerNetIDs.Len(); 50 | for(unsigned short int i=0;iGetName()); 53 | + players.push_back(se_autoCompleteWithColor ? p->GetColoredName() : p->GetName()); 54 | } 55 | eAutoCompleterChat completer(players); 56 | 57 | 58 | -------------------------------------------------------------------------------- /expr/armagetronad/default.nix: -------------------------------------------------------------------------------- 1 | {stdenv, fetchbzr, gnugrep, boost, which, automake, autoconf, SDL, SDL_mixer, SDL_image, libxml2, protobuf, mesa, ftgl, glew, pkgconfig, libpng, m4, yacc, python, freetype}: 2 | 3 | stdenv.mkDerivation rec { 4 | name = "armagetronad-0.4-bzr-r${rev}"; 5 | rev = "1608"; 6 | src = fetchbzr { 7 | url = "lp:armagetronad/0.4"; 8 | inherit rev; 9 | sha256 = "1xwlay3l51nc9mc4d7kbpmi754i36gm0cx706mdg1gnajsdpjp8b"; 10 | }; 11 | buildInputs = [gnugrep stdenv boost which automake autoconf SDL SDL_mixer SDL_image libxml2 protobuf mesa ftgl glew pkgconfig libpng m4 yacc python freetype]; 12 | patchFlags = "-p0"; 13 | configureFlags = "--disable-games --disable-etc"; 14 | preConfigure = '' 15 | ./bootstrap.sh 16 | ''; 17 | preBuild = '' 18 | NIX_CFLAGS_COMPILE+="-O2 -march=native -ffast-math -msse4a -msse -mssse3 -msse2 -msse3" 19 | ''; 20 | } 21 | -------------------------------------------------------------------------------- /expr/asurocon/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, fetchurl }: 2 | stdenv.mkDerivation { 3 | name = "asurocon"; 4 | src = fetchurl { 5 | url = "http://www.arexx.nl/downloads/asuro/asuro_flash_linux_source.zip"; 6 | sha256 = "1lbpnpij2myzhgr0bsrmp19mpzpq22dwk8c1p4a8sxqmc9c3zr5f"; 7 | }; 8 | configurePhase = ":"; 9 | buildPhase = '' 10 | cd con_flash 11 | echo "#include " | cat - ./PosixSerial.cpp > x 12 | mv x ./PosixSerial.cpp 13 | g++ *.cpp -o asurocon -D_LINUX_ -D_CONSOLE -O2 14 | ''; 15 | installPhase = '' 16 | mkdir -p $out/bin 17 | cp ./asurocon $out/bin 18 | ''; 19 | } 20 | -------------------------------------------------------------------------------- /expr/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import {} }: with pkgs; 2 | 3 | rec { 4 | 5 | softwarechallenge14-gui = callPackage ./softwarechallenge-gui/2014.nix {}; 6 | 7 | softwarechallenge15-gui = callPackage ./softwarechallenge-gui/2015.nix { 8 | jre = oraclejre8; 9 | }; 10 | 11 | softwarechallenge16-gui = callPackage ./softwarechallenge-gui/2016.nix { 12 | jre = oraclejre8; 13 | }; 14 | 15 | esu = callPackage ./esu {}; 16 | 17 | armagetronad = callPackage ./armagetronad {}; 18 | 19 | nixos-sync = nixos-rebuild: callPackage ./nixos-sync { 20 | git = gitMinimal; 21 | inherit nixos-rebuild; 22 | }; 23 | 24 | lock = callPackage ./lock { 25 | inherit (xlibs) xprop; 26 | }; 27 | 28 | lock-suspend = callPackage ./lock-suspend { 29 | inherit lock; 30 | }; 31 | 32 | asurocon = callPackage ./asurocon {}; 33 | 34 | mfcj430w-driver = pkgsi686Linux.callPackage ./mfcj430w-driver { 35 | psnup = texlive.combined.scheme-minimal; 36 | }; 37 | 38 | hydra = 39 | let 40 | source = fetchgit { 41 | url = "https://github.com/mayflower/hydra"; 42 | rev = "6216eeb7d9b3de922100f2afebc2b5e11aac6726"; 43 | sha256 = "1y5zqy7y3ghizpqcph71apjkzjkczn1gb4ia301d6an6sdk2ybjz"; 44 | }; 45 | in (import "${source}/release.nix" {}).build."${system}"; 46 | 47 | radare2-git = callPackage ./radare2-git { }; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /expr/esu/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, fetchurl, jre, bash }: 2 | 3 | stdenv.mkDerivation { 4 | name = "esu"; 5 | src = fetchurl { 6 | url = "http://di188.di.informatik.tu-darmstadt.de/static/esu.jar"; 7 | sha256 = "1xrvz0iqic11afchn009nnnvhic5xr8hnc2il32gi7pwm09fx5dg"; 8 | }; 9 | phases = [ "installPhase" ]; 10 | installPhase = '' 11 | mkdir -p $out/bin $out/lib; 12 | cp $src $out/lib/esu.jar; 13 | cat > $out/bin/esu < /dev/null 15 | ) & disown) | ( 16 | while read i; do 17 | if [ "$i" = "ready" ]; then 18 | exit 0 19 | fi 20 | done 21 | echo "Error: no ready from screen locker" >&2 22 | exit 1 23 | ) 24 | '' 25 | -------------------------------------------------------------------------------- /expr/mfcj430w-driver/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, fetchurl, writeScriptBin, dpkg, findutils, patchelf, file, makeWrapper, psnup, coreutils, which, ghostscript, gnused, gawk, gnugrep, bc, a2ps, pkgsi686Linux }: 2 | 3 | let 4 | model = "mfcj430w"; 5 | stubScript = name: "${writeScriptBin name ''echo "${name}: skipping"''}/bin"; 6 | stdbin = stdenv.lib.makeBinPath [ gnused gawk coreutils gnugrep bc ghostscript ]; 7 | in 8 | 9 | stdenv.mkDerivation { 10 | name = "brother-mfcj430w"; 11 | srcs = [ 12 | (fetchurl { 13 | url = "http://www.brother.com/pub/bsc/linux/dlf/${model}lpr-3.0.1-1.i386.deb"; 14 | sha256 = "1sfmca4piqq5b0czmbgbh48jnqbqv72dlhl7c0cczhgzmr3zqbbv"; 15 | }) 16 | (fetchurl { 17 | url = "http://www.brother.com/pub/bsc/linux/dlf/${model}cupswrapper-3.0.0-1.i386.deb"; 18 | sha256 = "19an84ziakrjnmi934l0pg9l28hwzq59k252xss9nida1m6qb87q"; 19 | }) 20 | ]; 21 | phases = ["installPhase" "fixupPhase"]; 22 | buildInputs = [ dpkg findutils patchelf file makeWrapper ]; 23 | 24 | installPhase = '' 25 | echo ":: Preparing environment and files" 26 | export PATH="$PATH:${stubScript "lpadmin"}:${stubScript "lpinfo"}" 27 | for s in $srcs; do dpkg-deb -x $s $out; done 28 | mv $out/usr/* $out 29 | rmdir $out/usr 30 | mkdir -p $out/lib/cups/filter 31 | 32 | echo -e "\n:: Patching scripts" 33 | find $out -type f -executable -exec grep -Iq . {} \; -and -not -name "*.ppd" -and -print | while read file; do 34 | echo "Patching script $file ..." 35 | substituteInPlace "$file" \ 36 | --replace "/opt" "$out/opt" \ 37 | --replace /usr "$out" \ 38 | --replace /etc "$out/etc" \ 39 | --replace /var/tmp "$TMPDIR" \ 40 | --replace "share/ppd" "share/cups/model" 41 | done 42 | patchShebangs $out 43 | 44 | echo -e "\n:: Installing cupswrapper" 45 | chmod +x $out/opt/brother/Printers/${model}/cupswrapper/cupswrapper${model} 46 | $out/opt/brother/Printers/${model}/cupswrapper/cupswrapper${model} 47 | 48 | echo -e "\n:: Patching binary files" 49 | find $out -type f -executable -exec file -i '{}' \; | grep 'x-executable; charset=binary' | while read file; do 50 | file="''${file%%:*}" 51 | echo "Patching executable $file ..." 52 | patchelf --interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $file 53 | wrapProgram "$file" \ 54 | --set LD_PRELOAD "${pkgsi686Linux.libredirect}/lib/libredirect.so" \ 55 | --set NIX_REDIRECTS "/opt=$out/opt" \ 56 | --argv0 brprintconf_mfcj430w 57 | done 58 | 59 | 60 | wrapProgram "$out/lib/cups/filter/brother_lpdwrapper_${model}" \ 61 | --run 'exec 2<&-' \ 62 | --run 'exec 2<>/tmp/brother-lpdwrapper-errors' \ 63 | --prefix PATH ":" "${psnup}/bin:${stdbin}:$out/bin" 64 | wrapProgram "$out/opt/brother/Printers/${model}/lpd/filter${model}" \ 65 | --prefix PATH ":" "${file}/bin:${a2ps}/bin" 66 | wrapProgram "$out/opt/brother/Printers/${model}/lpd/psconvertij2" \ 67 | --prefix PATH ":" "${which}/bin:${a2ps}/bin" 68 | 69 | echo -e "\n:: Cleanup" 70 | cd "$out/opt/brother/Printers/${model}" 71 | rm cupswrapper/*.ppd "cupswrapper/cupswrapper${model}" 72 | rm inf/setupPrintcapij 73 | 74 | echo -e "\n:: Done" 75 | ''; 76 | } 77 | -------------------------------------------------------------------------------- /expr/nixos-sync/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, git, coreutils, less, gnused, gnugrep, systemd, nixos-rebuild }: 2 | 3 | stdenv.mkDerivation { 4 | name = "nixos-sync"; 5 | buildCommand = '' 6 | cat >$out < $out/bin/softwarechallenge14-gui < $out/bin/softwarechallenge15-gui < $out/bin/softwarechallenge16-gui <