From 28ccec970435f9acfdecfae95848947c8b751e09 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Fri, 27 Mar 2020 23:32:13 -0400 Subject: [PATCH] Initial commit It begins... --- home/common/legacy-dotfiles.nix | 8 + home/common/solarized.nix | 18 + home/home.nix | 70 ++ home/modules/alacritty.nix | 46 ++ home/modules/alsi.nix | 41 + home/modules/emacs.nix | 45 ++ home/modules/i3.nix | 233 ++++++ home/modules/lib/cloneRepo.nix | 67 ++ home/modules/nixos-logo.txt | 26 + home/modules/pure.zsh-theme | 151 ++++ home/modules/shell.nix | 189 +++++ home/modules/vim.nix | 47 ++ home/modules/vimrc | 1121 +++++++++++++++++++++++++++ home/modules/zshrc | 371 +++++++++ install | 38 + pkgs/alsi/default.nix | 22 + system/configuration.nix | 11 + system/machines/bumblebee.nix | 21 + system/modules/common.nix | 106 +++ system/modules/emacs.nix | 23 + system/modules/reusable/README.org | 2 + system/modules/reusable/battery.nix | 32 + system/modules/sound.nix | 14 + system/modules/xserver.nix | 19 + 24 files changed, 2721 insertions(+) create mode 100644 home/common/legacy-dotfiles.nix create mode 100644 home/common/solarized.nix create mode 100644 home/home.nix create mode 100644 home/modules/alacritty.nix create mode 100644 home/modules/alsi.nix create mode 100644 home/modules/emacs.nix create mode 100644 home/modules/i3.nix create mode 100644 home/modules/lib/cloneRepo.nix create mode 100644 home/modules/nixos-logo.txt create mode 100755 home/modules/pure.zsh-theme create mode 100644 home/modules/shell.nix create mode 100644 home/modules/vim.nix create mode 100644 home/modules/vimrc create mode 100644 home/modules/zshrc create mode 100755 install create mode 100644 pkgs/alsi/default.nix create mode 100644 system/configuration.nix create mode 100644 system/machines/bumblebee.nix create mode 100644 system/modules/common.nix create mode 100644 system/modules/emacs.nix create mode 100644 system/modules/reusable/README.org create mode 100644 system/modules/reusable/battery.nix create mode 100644 system/modules/sound.nix create mode 100644 system/modules/xserver.nix diff --git a/home/common/legacy-dotfiles.nix b/home/common/legacy-dotfiles.nix new file mode 100644 index 000000000..33d9581e6 --- /dev/null +++ b/home/common/legacy-dotfiles.nix @@ -0,0 +1,8 @@ +with import {}; +fetchgit { + url = "https://github.com/glittershark/dotfiles.git"; + rev = "e0c7f2592fbc2f9942763d2146d362a1314630e9"; + # date = "2020-03-25T20:38:51-04:00"; + sha256 = "126zy4ff6nl2vma2s74waksim7j5h3n6qpaxnnn17vkc1cq0fcd9"; + fetchSubmodules = false; +} diff --git a/home/common/solarized.nix b/home/common/solarized.nix new file mode 100644 index 000000000..e94693edc --- /dev/null +++ b/home/common/solarized.nix @@ -0,0 +1,18 @@ +rec { + base03 = "#002B36"; + base02 = "#073642"; + base01 = "#586e75"; + base00 = "#657b83"; + base0 = "#839496"; + base1 = "#93a1a1"; + base2 = "#eee8d5"; + base3 = "#fdf6e3"; + yellow = "#b58900"; + orange = "#cb4b16"; + red = "#dc322f"; + magenta = "#d33682"; + violet = "#6c71c4"; + blue = "#268bd2"; + cyan = "#2aa198"; + green = "#859900"; +} diff --git a/home/home.nix b/home/home.nix new file mode 100644 index 000000000..e0ecda410 --- /dev/null +++ b/home/home.nix @@ -0,0 +1,70 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./modules/alacritty.nix + ./modules/emacs.nix + ./modules/i3.nix + ./modules/shell.nix + ./modules/vim.nix + ./modules/alsi.nix + ./modules/lib/cloneRepo.nix + + ]; + + # Let Home Manager install and manage itself. + programs.home-manager.enable = true; + xsession.enable = true; + + # This value determines the Home Manager release that your + # configuration is compatible with. This helps avoid breakage + # when a new Home Manager release introduces backwards + # incompatible changes. + # + # You can update Home Manager without changing this value. See + # the Home Manager release notes for a list of state version + # changes in each release. + home.stateVersion = "19.09"; + + home.packages = with pkgs; [ + nix-prefetch-github + htop + powertop + pass + gitAndTools.hub + shellcheck + gnupg + + # Spotify...etc + spotify + playerctl + + # games + crawl + dwarf-fortress + ]; + + nixpkgs.config.allowUnfree = true; + + programs.git = { + enable = true; + userEmail = "root@gws.fyi"; + userName = "Griffin Smith"; + }; + + services.redshift = { + enable = true; + provider = "geoclue2"; + }; + + services.pasystray.enable = true; + + impure.clonedRepos.passwordStore = { + github = "glittershark/pass"; + path = ".password-store"; + }; + + services.gpg-agent = { + enable = true; + }; +} diff --git a/home/modules/alacritty.nix b/home/modules/alacritty.nix new file mode 100644 index 000000000..ba26360fe --- /dev/null +++ b/home/modules/alacritty.nix @@ -0,0 +1,46 @@ +{ config, lib, pkgs, ... }: +{ + home.packages = with pkgs; [ + alacritty + ]; + + programs.alacritty = { + enable = true; + settings = { + font.size = 6; + + colors = with import ../common/solarized.nix; rec { + # Default colors + primary = { + background = base3; + foreground = base00; + }; + + cursor = { + text = base3; + cursor = base00; + }; + + # Normal colors + normal = { + inherit red green yellow blue magenta cyan; + black = base02; + white = base2; + }; + + # Bright colors + bright = normal; + # bright = { + # black = base03; + # red = orange; + # green = base01; + # yellow = base00; + # blue = base0; + # magenta = violet; + # cyan = base1; + # white = base3; + # }; + }; + }; + }; +} diff --git a/home/modules/alsi.nix b/home/modules/alsi.nix new file mode 100644 index 000000000..cb9802e2c --- /dev/null +++ b/home/modules/alsi.nix @@ -0,0 +1,41 @@ +{ config, lib, pkgs, ... }: +let alsi = pkgs.callPackage ../../pkgs/alsi {}; +in +{ + home.packages = [ alsi ]; + + home.file.".config/alsi/alsi.logo" = { + source = ./nixos-logo.txt; + force = true; + }; + + home.file.".config/alsi/alsi.conf" = { + text = '' + #!${pkgs.perl}/bin/perl + + scalar { + ALSI_VERSION => "0.4.8", + COLORS_FILE => "/home/grfn/.config/alsi/alsi.colors", + DE_FILE => "/home/grfn/.config/alsi/alsi.de", + DEFAULT_COLOR_BOLD => "blue", + DEFAULT_COLOR_NORMAL => "blue", + DF_COMMAND => "df -Th -x sys -x tmpfs -x devtmpfs &>/dev/stdout", + GTK2_RC_FILE => "/home/grfn/.gtkrc-2.0", + GTK3_RC_FILE => "/home/grfn/.config/gtk-3.0/settings.ini", + LOGO_FILE => "/home/grfn/.config/alsi/alsi.logo", + OUTPUT_FILE => "/home/grfn/.config/alsi/alsi.output", + # PACKAGES_PATH => "/var/lib/pacman/local/", + PS_COMMAND => "ps -A", + USAGE_COLORS => 0, + USAGE_COLORS_BOLD => 0, + USAGE_PRECENT_GREEN => 50, + USAGE_PRECENT_RED => 100, + USAGE_PRECENT_YELLOW => 85, + USE_LOGO_FROM_FILE => 1, + USE_VALUES_COLOR => 0, + WM_FILE => "/home/grfn/.config/alsi/alsi.wm", + } + ''; + force = true; + }; +} diff --git a/home/modules/emacs.nix b/home/modules/emacs.nix new file mode 100644 index 000000000..05b09ec2c --- /dev/null +++ b/home/modules/emacs.nix @@ -0,0 +1,45 @@ +{ pkgs, lib, ... }: + +let + # doom-emacs = pkgs.callPackage (builtins.fetchTarball { + # url = https://github.com/vlaci/nix-doom-emacs/archive/master.tar.gz; + # }) { + # doomPrivateDir = ./doom.d; # Directory containing your config.el init.el + # # and packages.el files + # }; +in { + imports = [ ./lib/cloneRepo.nix ]; + + # home.packages = [ doom-emacs ]; + # home.file.".emacs.d/init.el".text = '' + # (load "default.el") + # ''; + # + + home.packages = [ + # haskellPackages.Agda BROKEN + ]; + + programs.emacs.enable = true; + home.file.".doom.d".source = ./doom.d; + + impure.clonedRepos = { + orgClubhouse = { + github = "glittershark/org-clubhouse"; + path = "code/org-clubhouse"; + }; + + doomEmacs = { + github = "hlissner/org-clubhouse"; + path = ".emacs.d"; + after = ["orgClubhouse"]; + onClone = "bin/doom install"; + }; + }; + + # Notes + services.syncthing = { + enable = true; + tray = true; + }; +} diff --git a/home/modules/i3.nix b/home/modules/i3.nix new file mode 100644 index 000000000..e4820b528 --- /dev/null +++ b/home/modules/i3.nix @@ -0,0 +1,233 @@ +{ config, lib, pkgs, ... }: +let + mod = "Mod4"; + solarized = import ../common/solarized.nix; + decorationFont = "MesloLGSDZ 6"; +in { + home.packages = with pkgs; [ + maim + rofi + i3status + python38Packages.py3status + ]; + + xsession.scriptPath = ".hm-xsession"; + xsession.windowManager.i3 = { + enable = true; + config = { + modifier = mod; + keybindings = lib.mkOptionDefault { + "${mod}+h" = "focus left"; + "${mod}+j" = "focus down"; + "${mod}+k" = "focus up"; + "${mod}+l" = "focus right"; + "${mod}+semicolon" = "focus parent"; + + "${mod}+Shift+h" = "move left"; + "${mod}+Shift+j" = "move down"; + "${mod}+Shift+k" = "move up"; + "${mod}+Shift+l" = "move right"; + + "${mod}+Shift+x" = "kill"; + + "${mod}+Return" = "exec alacritty"; + + "${mod}+Shift+s" = "split h"; + "${mod}+Shift+v" = "split v"; + + "${mod}+f" = "fullscreen"; + + "${mod}+Shift+r" = "exec home-manager switch"; + + "${mod}+r" = "mode resize"; + + # Marks + "${mod}+Shift+m" = ''exec i3-input -F "mark %s" -l 1 -P 'Mark: ' ''; + "${mod}+m" = ''exec i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Go to: ' ''; + + # Screenshots + "${mod}+q" = "exec maim"; + "${mod}+Shift+q" = "exec \"maim -s | xclip -selection clipboard -t image/png\""; + + # Launching applications + "${mod}+u" = + let rofi = pkgs.writeShellScript "rofi" '' + rofi \ + -modi 'combi' \ + -combi-modi "window,drun,ssh,run" \ + -font 'MesloLGSDZ 10' \ + -show combi + ''; + in "exec ${rofi}"; + + # Media + "XF86AudioPlay" = "exec playerctl play-pause"; + "XF86AudioNext" = "exec playerctl next"; + "XF86AudioPrevious" = "exec playerctl previous"; + "XF86AudioRaiseVolume" = "exec pulseaudio-ctl up"; + "XF86AudioLowerVolume" = "exec pulseaudio-ctl down"; + "XF86AudioMute" = "exec pulseaudio-ctl mute"; + + # Screen Layout + "${mod}+Shift+t" = "exec xrandr --auto"; + # TODO + # $mod+t exec /home/griffin/.screenlayout/work.sh + # $mod+Ctrl+t exec /home/griffin/bin/fix_screen.sh + }; + + fonts = [ decorationFont ]; + + colors = with solarized; rec { + focused = { + border = base01; + background = base01; + text = base3; + indicator = red; + childBorder = base02; + }; + focusedInactive = focused // { + border = base03; + background = base03; + # text = base1; + }; + unfocused = focusedInactive; + background = base03; + }; + + modes.resize = { + l = "resize shrink width 5 px or 5 ppt"; + k = "resize grow height 5 px or 5 ppt"; + j = "resize shrink height 5 px or 5 ppt"; + h = "resize grow width 5 px or 5 ppt"; + + Return = "mode \"default\""; + }; + + bars = [{ + statusCommand = + let i3status-conf = pkgs.writeText "i3status.conf" '' + general { + output_format = i3bar + colors = true + color_good = "#859900" + + interval = 1 + } + + order += "mpd" + order += "wireless wlp3s0" + order += "ethernet enp3s0f0" + order += "cpu_usage" + order += "battery 0" + # order += "volume master" + order += "time" + + mpd { + format = "%artist - %album - %title" + } + + wireless wlp3s0 { + format_up = "W: (%quality - %essid - %bitrate) %ip" + format_down = "W: -" + } + + ethernet enp3s0f0 { + format_up = "E: %ip" + format_down = "E: -" + } + + battery 0 { + format = "%status %percentage" + path = "/sys/class/power_supply/BAT%d/uevent" + low_threshold = 10 + } + + cpu_usage { + format = "CPU: %usage" + } + + load { + format = "%5min" + } + + time { + format = " %a %h %d ⌚ %I:%M " + } + + # volume master { + # format = "☊ %volume" + # format_muted = "☊ X" + # device = "default" + # mixer_idx = 0 + # } + ''; + in "py3status -c ${i3status-conf}"; + fonts = [ decorationFont ]; + position = "top"; + colors = with solarized; rec { + background = base03; + statusline = base3; + separator = base1; + activeWorkspace = { + border = base03; + background = base1; + text = base3; + }; + focusedWorkspace = activeWorkspace; + inactiveWorkspace = activeWorkspace // { + background = base01; + }; + urgentWorkspace = activeWorkspace // { + background = red; + }; + }; + }]; + }; + }; + + services.dunst = { + enable = true; + settings = with solarized; { + global = { + font = "Meslo 6"; + allow_markup = true; + format = "%s\n%b"; + sort = true; + alignment = "left"; + geometry = "600x5-30+20"; + idle_threshold = 120; + separator_color = "frame"; + }; + + frame = { + width = 0; + color = "#aaaaaa"; + }; + + shortcuts = { + close = "ctrl+space"; + close_all = "ctrl+shift+space"; + history = "ctrl+grave"; + context = "ctrl+shift+period"; + }; + + urgency_low = { + background = base03; + foreground = base3; + timeout = 5; + }; + + urgency_normal = { + background = base02; + foreground = base3; + timeout = 7; + }; + + urgency_critical = { + background = red; + foreground = base3; + timeout = 0; + }; + }; + }; +} diff --git a/home/modules/lib/cloneRepo.nix b/home/modules/lib/cloneRepo.nix new file mode 100644 index 000000000..50f6ca2d3 --- /dev/null +++ b/home/modules/lib/cloneRepo.nix @@ -0,0 +1,67 @@ +{ lib, config, ... }: +with lib; +{ + options = { + impure.clonedRepos = mkOption { + description = "Repositories to clone"; + default = {}; + type = with types; loaOf ( + let sm = submodule { + options = { + url = mkOption { + type = nullOr str; + description = "URL of repository to clone"; + default = null; + }; + + github = mkOption { + type = nullOr str; + description = "Github owner/repo of repository to clone"; + default = null; + }; + + path = mkOption { + type = str; + description = "Path to clone to"; + }; + + onClone = mkOption { + type = str; + description = '' + Shell command to run after cloning the repo for the first time. + Runs inside the repo itself. + ''; + default = ""; + }; + + after = mkOption { + type = listOf str; + description = "Activation hooks that this repository must be cloned after"; + default = []; + }; + }; + }; + in addCheck sm (cr: (! isNull cr.url || ! isNull cr.github)) + ); + }; + }; + + config = { + home.activation = + mapAttrs + (_: { + url, path, github, onClone, after + }: + let repoURL = if isNull url then "git@github.com:${github}" else url; + in hm.dag.entryAfter (["writeBoundary"] ++ after) '' + $DRY_RUN_CMD mkdir -p $(dirname "${path}") + if [[ ! -d ${path} ]]; then + $DRY_RUN_CMD git clone "${repoURL}" "${path}" + pushd ${path} + $DRY_RUN_CMD ${onClone} + popd + fi + '') + config.impure.clonedRepos; + }; +} diff --git a/home/modules/nixos-logo.txt b/home/modules/nixos-logo.txt new file mode 100644 index 000000000..d4b16b44f --- /dev/null +++ b/home/modules/nixos-logo.txt @@ -0,0 +1,26 @@ + (((((( ###%###### ##%###/ + ,(((((((/( #%#%#%#%# .#%#%#%#%# + ((((((/// %#######%. #####%###/ + (((((/(//, /##%###%###%###### + (((////// #####%########( + .(((((((((((((((///////////////#%%%######## (( + (((((((((((((((///////////////////######### .(((( + ((((((((((((((((/(//////////////////########## (((((((( + (######### ######### ((((((((( + ######### #########/(((((((((( + *######### .#######((((((((( + ###%################### ####(//(((((((((((((((( +####%################## .#////////(((((((((((((( +%%%%%%%%%%%%%%#######(( ////////////(((((((((((( + ###%#######%#######////. ///////////////////(((( + ###%###%#///////( ///////// + .####%#### ///////// /////////, + %#%#%#%#%* /////////( ///////// + .#####%# ////////(######################%#######%#####, + %#### (////////#####################%###%###%###% + .# (//////(//((###################%#######%##% + (//((((((((((( #####%%%%( + //(/(((((((((((((( ######%## + ((((((((( ((((((((( #####%###/ + ((((((((( /((((((((( .###%####% + (((((( ((((((((( %#%#%#/ diff --git a/home/modules/pure.zsh-theme b/home/modules/pure.zsh-theme new file mode 100755 index 000000000..b4776e815 --- /dev/null +++ b/home/modules/pure.zsh-theme @@ -0,0 +1,151 @@ +#!/bin/zsh -f +# vim: ft=zsh: +# MIT License +# For my own and others sanity +# git: +# %b => current branch +# %a => current action (rebase/merge) +# prompt: +# %F => color dict +# %f => reset color +# %~ => current path +# %* => time +# %n => username +# %m => shortname host +# %(?..) => prompt conditional - %(condition.true.false) + +# turns seconds into human readable time +# 165392 => 1d 21h 56m 32s +prompt_pure_human_time() { + local tmp=$1 + local days=$(( tmp / 60 / 60 / 24 )) + local hours=$(( tmp / 60 / 60 % 24 )) + local minutes=$(( tmp / 60 % 60 )) + local seconds=$(( tmp % 60 )) + (( $days > 0 )) && echo -n "${days}d " + (( $hours > 0 )) && echo -n "${hours}h " + (( $minutes > 0 )) && echo -n "${minutes}m " + echo "${seconds}s" +} + +is_git_repo() { + command git rev-parse --is-inside-work-tree &>/dev/null + return $? +} + +# fastest possible way to check if repo is dirty +prompt_pure_git_dirty() { + # check if we're in a git repo + is_git_repo || return + # check if it's dirty + [[ "$PURE_GIT_UNTRACKED_DIRTY" == 0 ]] && local umode="-uno" || local umode="-unormal" + command test -n "$(git status --porcelain --ignore-submodules ${umode})" + + (($? == 0)) && echo '*' +} + +prompt_pure_git_wip() { + is_git_repo || return + local subject="$(command git show --pretty=%s --quiet HEAD 2>/dev/null)" + [ "$subject" == 'wip' ] && echo '[WIP]' +} + +# displays the exec time of the last command if set threshold was exceeded +prompt_pure_cmd_exec_time() { + local stop=$EPOCHSECONDS + local start=${cmd_timestamp:-$stop} + integer elapsed=$stop-$start + (($elapsed > ${PURE_CMD_MAX_EXEC_TIME:=5})) && prompt_pure_human_time $elapsed +} + +prompt_pure_preexec() { + cmd_timestamp=$EPOCHSECONDS + + # shows the current dir and executed command in the title when a process is active + print -Pn "\e]0;" + echo -nE "$PWD:t: $2" + print -Pn "\a" +} + +# string length ignoring ansi escapes +prompt_pure_string_length() { + echo ${#${(S%%)1//(\%([KF1]|)\{*\}|\%[Bbkf])}} +} + +prompt_pure_nix_info() { + local packages_info='' + if [[ -z $NIX_SHELL_PACKAGES ]]; then + packages_info='[nix-shell]' + else + packages_info="{ $NIX_SHELL_PACKAGES }" + fi + + case $IN_NIX_SHELL in + 'pure') + echo "$fg_bold[green][nix-shell] " + ;; + 'impure') + echo "$fg_bold[magenta][nix-shell] " + ;; + *) ;; + esac +} + +prompt_pure_precmd() { + # shows the full path in the title + print -Pn '\e]0;%~\a' + + # git info + vcs_info + + local prompt_pure_preprompt="\n$(prompt_pure_nix_info)$fg_bold[green]$prompt_pure_username%F{blue}%~%F{yellow}$vcs_info_msg_0_`prompt_pure_git_dirty` $fg_no_bold[red]`prompt_pure_git_wip`%f %F{yellow}`prompt_pure_cmd_exec_time`%f " + print -P $prompt_pure_preprompt + + # check async if there is anything to pull + # (( ${PURE_GIT_PULL:-1} )) && { + # # check if we're in a git repo + # command git rev-parse --is-inside-work-tree &>/dev/null && + # # make sure working tree is not $HOME + # [[ "$(command git rev-parse --show-toplevel)" != "$HOME" ]] && + # # check check if there is anything to pull + # command git fetch &>/dev/null && + # # check if there is an upstream configured for this branch + # command git rev-parse --abbrev-ref @'{u}' &>/dev/null && { + # local arrows='' + # (( $(command git rev-list --right-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows='⇣' + # (( $(command git rev-list --left-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows+='⇡' + # print -Pn "\e7\e[A\e[1G\e[`prompt_pure_string_length $prompt_pure_preprompt`C%F{cyan}${arrows}%f\e8" + # } + # } &! + + # reset value since `preexec` isn't always triggered + unset cmd_timestamp +} + + +prompt_pure_setup() { + # prevent percentage showing up + # if output doesn't end with a newline + export PROMPT_EOL_MARK='' + + prompt_opts=(cr subst percent) + + zmodload zsh/datetime + autoload -Uz add-zsh-hook + autoload -Uz vcs_info + + add-zsh-hook precmd prompt_pure_precmd + add-zsh-hook preexec prompt_pure_preexec + + zstyle ':vcs_info:*' enable git + zstyle ':vcs_info:git*' formats ' %b' + zstyle ':vcs_info:git*' actionformats ' %b|%a' + + # show username@host if logged in through SSH + [[ "$SSH_CONNECTION" != '' ]] && prompt_pure_username='%n@%m ' + + # prompt turns red if the previous command didn't exit with 0 + PROMPT='%(?.%F{green}.%F{red})❯%f ' +} + +prompt_pure_setup "$@" diff --git a/home/modules/shell.nix b/home/modules/shell.nix new file mode 100644 index 000000000..51dc0e367 --- /dev/null +++ b/home/modules/shell.nix @@ -0,0 +1,189 @@ +{ config, lib, pkgs, ... }: +{ + home.packages = with pkgs; [ + zsh + autojump + ]; + + programs.zsh = { + enable = true; + enableAutosuggestions = true; + autocd = true; + + shellAliases = rec { + # NixOS stuff + hms = "home-manager switch"; + nor = "sudo nixos-rebuild switch"; + nrs = nor; + vihome = "vim ~/.config/nixpkgs/home.nix && home-manager switch"; + virc = "vim ~/.config/nixpkgs/home/shell.nix && home-manager switch && source ~/.zshrc"; + + # Nix + ns = "nix-shell"; + + # Aliases from old config + stck = "dirs -v"; + b= "cd ~1"; + ".." = "cd .."; + "..." = "cd ../.."; + "...." = "cd ../../.."; + "....." = "cd ../../../.."; + "http" = "http --style solarized"; + "grep" = "grep $GREP_OPTIONS"; + "bak" = "~/bin/backup.sh"; + "xmm" = "xmodmap ~/.Xmodmap"; + "asdflkj" = "asdf"; + "asdf" = "asdfghjkl"; + "asdfghjkl" = "echo \"Having some trouble?\""; + "ift" = "sudo iftop -i wlp3s0"; + "rvpn" = "sudo systemctl restart openvpn@bldr-dev openvpn@lsvl-dev"; + "gne" = "gn edit"; + "gnf" = "gn find"; + "gnt" = "gn tag-list"; + "gnn" = "gn notebook-list"; + "mytl" = "t tl $TWITTER_WHOAMI"; + "first" = "awk '{print \$$1}'"; + "dcu" = "docker-compose up"; + "dc" = "docker-compose"; + "dck" = "docker"; + "dockerclean" = "dockercleancontainers && dockercleanimages"; + "dockercleanimages" = "docker images -a --no-trunc | grep none | awk '{print \$$3}' | xargs -L 1 -r docker rmi"; + "dockercleancontainers" = "docker ps -a --no-trunc| grep 'Exit' | awk '{print \$$1}' | xargs -L 1 -r docker rm"; + "cmt" = "git log --oneline | fzf-tmux | awk '{print \$$1}'"; + "workmon" = "xrandr --output DP-2 --pos 1440x900 --primary"; + "vi" = "vim"; + "awa" = "ssh aw2-admin.nomi.host"; + "dtf" = "cd ~/.dotfiles"; + "adbdev" = "adb devices"; + "adbcon" = "adb connect $GNEX_IP"; + "gwip" = "git add . && git commit -am wip"; + "gpr" = "g pull-request"; + "gcl" = "git clone"; + "grs" = "gr --soft"; + "grhh" = "grh HEAD"; + "grh" = "gr --hard"; + "gr" = "git reset"; + "gcb" = "gc -b"; + "gco" = "gc"; + "gcd" = "gc development"; + "gcm" = "gc master"; + "gc" = "git checkout"; + "gbg" = "git branch | grep"; + "gba" = "git branch -a"; + "gb" = "git branch"; + "gcv" = "git commit --verbose"; + "gci" = "git commit"; + "gm" = "git merge"; + "gdc" = "gd --cached"; + "gd" = "git diff"; + "gsl" = "git stash list"; + "gss" = "git show stash"; + "gsad" = "git stash drop"; + "gsa" = "git stash"; + "gst" = "gs"; + "gs" = "git status"; + "gg" = "gl --decorate --oneline --graph --date-order --all"; + "gl" = "git log"; + "gf" = "git fetch"; + "gur" = "gu --rebase"; + "gu" = "git pull"; + "gpf" = "gp -f"; + "gpa" = "gp --all"; + "gpu" = "git push -u origin \"$(git symbolic-ref --short HEAD)\""; + "gp" = "git push"; + "ganw" = "git diff -w --no-color | git apply --cached --ignore-whitespace"; + "ga" = "git add"; + "gnp" = "git --no-pager"; + "g" = "git"; + "git" = "hub"; + "mpalb" = "mpc search album"; + "mpart" = "mpc search artist"; + "mps" = "mpc search"; + "mpa" = "mpc add"; + "mpt" = "mpc toggle"; + "mpl" = "mpc playlist"; + "dsstore" = "find . -name '*.DS_Store' -type f -ls -delete"; + "df" = "df -h"; + "fs" = "stat -f '%z bytes'"; + "ll" = "ls -al"; + "la" = "ls -a"; + }; + + oh-my-zsh = { + enable = true; + + plugins = [ + "battery" + "colorize" + "command-not-found" + "github" + "gitignore" + "postgres" + "systemd" + "themes" + "vi-mode" + ]; + + custom = "${pkgs.stdenv.mkDerivation { + name = "oh-my-zsh-custom"; + unpackPhase = ":"; + installPhase = '' + mkdir -p $out/themes + mkdir -p $out/custom/plugins + ln -s ${./pure.zsh-theme} $out/themes/pure.zsh-theme + ''; + }}"; + + theme = "pure"; + }; + + plugins = [{ + name = "pure-theme"; + src = pkgs.fetchFromGitHub { + owner = "sindresorhus"; + repo = "pure"; + rev = "0a92b02dd4172f6c64fdc9b81fe6cd4bddb0a23b"; + sha256 = "0l8jqhmmjn7p32hdjnv121xsjnqd2c0plhzgydv2yzrmqgyvx7cc"; + }; + }]; + + initExtraBeforeCompInit = '' + zstyle ':completion:*' completer _complete _ignored _correct _approximate + zstyle ':completion:*' matcher-list \'\' 'm:{[:lower:]}={[:upper:]} m:{[:lower:][:upper:]}={[:upper:][:lower:]} r:|[._- :]=** r:|=**' 'l:|=* r:|=*' + zstyle ':completion:*' max-errors 5 + zstyle ':completion:*' use-cache yes + zstyle ':completion::complete:grunt::options:' expire 1 + zstyle ':completion:*' prompt '%e errors' + # zstyle :compinstall filename '~/.zshrc' + autoload -Uz compinit + ''; + + initExtra = '' + source ${./zshrc} + source ${pkgs.fetchFromGitHub { + owner = "zsh-users"; + repo = "zsh-syntax-highlighting"; + rev = "7678a8a22780141617f809002eeccf054bf8f448"; + sha256 = "0xh4fbd54kvwwpqvabk8lpw7m80phxdzrd75q3y874jw0xx1a9q6"; + }}/zsh-syntax-highlighting.zsh + source ${pkgs.autojump}/share/autojump/autojump.zsh + source ${pkgs.fetchFromGitHub { + owner = "chisui"; + repo = "zsh-nix-shell"; + rev = "a65382a353eaee5a98f068c330947c032a1263bb"; + sha256 = "0l41ac5b7p8yyjvpfp438kw7zl9dblrpd7icjg1v3ig3xy87zv0n"; + }}/nix-shell.plugin.zsh + + autoload -U promptinit; promptinit + prompt pure + + [[ ! $IN_NIX_SHELL ]] && alsi -l + ''; + }; + + programs.fzf = { + enable = true; + enableBashIntegration = true; + enableZshIntegration = true; + }; +} diff --git a/home/modules/vim.nix b/home/modules/vim.nix new file mode 100644 index 000000000..87d430933 --- /dev/null +++ b/home/modules/vim.nix @@ -0,0 +1,47 @@ +{ config, pkgs, ... }: +{ + programs.neovim = { + enable = true; + viAlias = true; + vimAlias = true; + plugins = with pkgs.vimPlugins; [ + ctrlp + deoplete-nvim + syntastic + vim-abolish + vim-airline + vim-airline-themes + vim-bufferline + vim-closetag + # vim-colors-solarized + # solarized + (pkgs.vimUtils.buildVimPlugin { + name = "vim-colors-solarized"; + src = pkgs.fetchFromGitHub { + owner = "glittershark"; + repo = "vim-colors-solarized"; + rev = "4857c3221ec3f2693a45855154cb61a2cefb514d"; + sha256 = "0kqp5w14g7adaiinmixm7z3x4w74lv1lcgbqjbirx760f0wivf9y"; + }; + }) + vim-commentary + vim-dispatch + vim-endwise + vim-repeat + vim-fugitive + vim-markdown + vim-nix + vim-rhubarb + vim-sexp + vim-sexp-mappings-for-regular-people + vim-sleuth + vim-startify + vim-surround + vim-unimpaired + vinegar + ]; + extraConfig = '' + source ${./vimrc} + ''; + }; +} diff --git a/home/modules/vimrc b/home/modules/vimrc new file mode 100644 index 000000000..16bc8d918 --- /dev/null +++ b/home/modules/vimrc @@ -0,0 +1,1121 @@ +" vim:set fdm=marker fmr={{{,}}} ts=2 sts=2 sw=2 expandtab: + + +" Basic Options {{{ +set nocompatible +set modeline +set modelines=10 +syntax enable +filetype plugin indent on +set ruler +set showcmd +set number +set incsearch +set smartcase +set ignorecase +set scrolloff=10 +set tabstop=4 +set shiftwidth=4 +set softtabstop=4 +set nosmartindent +set expandtab +set noerrorbells visualbell t_vb= +set laststatus=2 +set hidden +let mapleader = ',' +let maplocalleader = '\' +set undofile +" set undodir=~/.vim/undo +set wildignore=*.pyc,*.o,.git +set clipboard=unnamed +" set backupdir=$HOME/.vim/backup +" set directory=$HOME/.vim/tmp +set foldmarker={{{,}}} +set colorcolumn=+1 +set concealcursor= +set formatoptions+=j +set wildmenu +set wildmode=longest,list:full +set noincsearch +" }}} + +" GUI options {{{ +set go-=m +set go-=T +set go-=r +set go-=L +set go-=e +set guifont=Meslo\ LG\ S\ DZ\ 9 +" }}} + +" Colors {{{ +" set t_Co=256 + +fu! ReverseBackground() + if &bg=="light" + se bg=dark + else + se bg=light + endif +endf +com! BgToggle call ReverseBackground() +nm :BgToggle + +set background=light +colorscheme solarized +" }}} + +" --------------------------------------------------------------------------- + +" CtrlP {{{ +let g:ctrlp_custom_ignore = { + \ 'dir': '(node_modules|target)' + \ } +let g:ctrlp_max_files = 0 +let g:ctrlp_max_depth = 100 +" }}} + +" YouCompleteMe {{{ +let g:ycm_semantic_triggers = { + \ 'c' : ['->', '.'], + \ 'objc' : ['->', '.'], + \ 'ocaml' : ['.', '#'], + \ 'cpp,objcpp' : ['->', '.', '::'], + \ 'perl' : ['->'], + \ 'php' : ['->', '::'], + \ 'cs,java,javascript,d,python,perl6,scala,vb,elixir,go' : ['.'], + \ 'vim' : ['re![_a-zA-Z]+[_\w]*\.'], + \ 'lua' : ['.', ':'], + \ 'erlang' : [':'], + \ 'clojure' : [], + \ 'haskell' : ['re!.*', '.', ' ', '('] + \ } + " \ 'haskell' : ['.', '(', ' '] + " \ 'ruby' : ['.', '::'], + " \ 'clojure' : ['(', '.', '/', '['] +" }}} + +" Neocomplete {{{ +if !has('nvim') + " Use neocomplete. + let g:neocomplete#enable_at_startup = 1 + " Use smartcase. + let g:neocomplete#enable_smart_case = 1 + " Set minimum syntax keyword length. + let g:neocomplete#sources#syntax#min_keyword_length = 3 + let g:neocomplete#lock_buffer_name_pattern = '\*ku\*' + + " Define dictionary. + " let g:neocomplete#sources#dictionary#dictionaries = { + " \ 'default' : '', + " \ 'vimshell' : $HOME.'/.vimshell_hist', + " \ 'scheme' : $HOME.'/.gosh_completions' + " \ } + + " Define keyword. + if !exists('g:neocomplete#keyword_patterns') + let g:neocomplete#keyword_patterns = {} + endif + let g:neocomplete#keyword_patterns['default'] = '\h\w*' + + " Plugin key-mappings. + inoremap neocomplete#undo_completion() + inoremap neocomplete#complete_common_string() + + " Recommended key-mappings. + " : close popup and save indent. + inoremap =my_cr_function() + function! s:my_cr_function() + return (pumvisible() ? "\" : "" ) . "\" + " For no inserting key. + "return pumvisible() ? "\" : "\" + endfunction + " : completion. + inoremap pumvisible() ? "\" : "\" + " , : close popup and delete backword char. + inoremap neocomplete#smart_close_popup()."\" + inoremap neocomplete#smart_close_popup()."\" + " Close popup by . + "inoremap pumvisible() ? "\" : "\" + + " AutoComplPop like behavior. + "let g:neocomplete#enable_auto_select = 1 + + " Shell like behavior(not recommended). + "set completeopt+=longest + "let g:neocomplete#enable_auto_select = 1 + "let g:neocomplete#disable_auto_complete = 1 + "inoremap pumvisible() ? "\" : "\\" + + " Enable omni completion. + " autocmd FileType css setlocal omnifunc=csscomplete#CompleteCSS + " autocmd FileType html,markdown setlocal omnifunc=htmlcomplete#CompleteTags + " autocmd FileType javascript setlocal omnifunc=javascriptcomplete#CompleteJS + " autocmd FileType python setlocal omnifunc=pythoncomplete#Complete + " autocmd FileType xml setlocal omnifunc=xmlcomplete#CompleteTags + + " Enable heavy omni completion. + if !exists('g:neocomplete#sources#omni#input_patterns') + let g:neocomplete#sources#omni#input_patterns = {} + endif +endif +" }}} + +" Deoplete {{{ +if has('nvim') + let g:deoplete#enable_at_startup = 1 + + inoremap =my_cr_function() + function! s:my_cr_function() + return (pumvisible() ? "\" : "" ) . "\" + " For no inserting key. + "return pumvisible() ? "\" : "\" + endfunction + " : completion. + inoremap pumvisible() ? "\" : "\" + inoremap pumvisible() ? "\" : "\" +endif +" }}} + +" Neovim Terminal mode {{{ +if has('nvim') + tnoremap + nnoremap \\ :tabedit term://zsh + nnoremap q\ :call OpenRepl() + + if !exists('g:repl_size') + let g:repl_size=9 + endif + + function! s:OpenRepl() " {{{ + " Check if buffer exists and is open + if exists('s:repl_bufname') && bufexists(s:repl_bufname) && bufwinnr(s:repl_bufname) >=? 0 + " If so, just switch to it + execute bufwinnr(s:repl_bufname) . 'wincmd' 'w' + norm i + return + endif + + if !exists('b:console') + let b:console=$SHELL + endif + + let l:console_cmd = b:console + + execute 'bot' g:repl_size . 'new' + set winfixheight nobuflisted + call termopen(l:console_cmd) + let s:repl_bufname = bufname('%') + norm i + endfunction " }}} +endif +" }}} + +" Tagbar options {{{ +let g:tagbar_autoclose = 1 +let g:tagbar_autofocus = 1 +let g:tagbar_compact = 1 +" }}} + +" delimitMate options {{{ +let g:delimitMate_expand_cr = 1 +" }}} + +" UltiSnips options {{{ +let g:UltiSnipsExpandTrigger = '' + "g:UltiSnipsJumpForwardTrigger + "g:UltiSnipsJumpBackwardTrigger +" }}} + +" VDebug Options {{{ +let g:vdebug_options = {'server': '192.168.56.1'} +" }}} + +" Statusline {{{ +let g:airline_powerline_fonts=1 + +if !exists('g:airline_symbols') + let g:airline_symbols = {} +endif +let g:airline_symbols.space = "\ua0" + +let g:airline#extensions#tagbar#flags = 'f' +let g:airline#extensions#tabline#enabled = 1 +let g:airline#extensions#tabline#show_buffers = 0 +let g:airline#extensions#tabline#show_tabs = 1 +let g:airline#extensions#tabline#tab_min_count = 2 +let g:airline#extensions#tmuxline#enabled = 0 + +let g:tmuxline_theme = 'airline' +let g:tmuxline_preset = 'full' + +"set statusline= +"set statusline+=%2*[%n%H%M%R%W]%*\ " flags and buf no +"set statusline+=%-40f%<\ " path +"set statusline+=%=%40{fugitive#statusline()}\ " Vim status +"set statusline+=%1*%y%*%*\ " file type +"set statusline+=%10((%l,%c)%)\ " line and column +"set statusline+=%P " percentage of file +" }}} + +" Code review mode {{{ +fun! GetFontName() + return substitute(&guifont, '^\(.\{-}\)[0-9]*$', '\1', '') +endfun + +fun! CodeReviewMode() + let &guifont = GetFontName() . ' 15' +endfun +com! CodeReviewMode call CodeReviewMode() +" }}} + +" Syntastic {{{ +let g:syntastic_enable_signs = 0 + +" Python {{{ +let g:syntastic_python_checkers = ['flake8'] +let g:syntastic_python_flake8_post_args = "--ignore=E101,E223,E224,E301,E302,E303,E501,E701,W,F401,E111,E261" + +" }}} +" Javascript {{{ +let g:syntastic_javascript_checkers = ['eslint'] +let g:flow#autoclose = 1 +let g:flow#enable = 1 + +" augroup syntastic_javascript_jsx +" autocmd! +" autocmd BufReadPre,BufNewFile *.js +" autocmd BufReadPre,BufNewFile *.jsx +" \ let g:syntastic_javascript_checkers = ['jsxhint'] +" augroup END + +" }}} +" Haml {{{ +let g:syntastic_haml_checkers = ['haml_lint'] + +" }}} +" Html {{{ +let g:syntastic_html_checkers = [] + +" }}} +" Ruby {{{ +let g:syntastic_ruby_checkers = ['rubocop'] +" }}} +" SASS/SCSS {{{ +let g:syntastic_scss_checkers = ['scss_lint'] +" }}} +" Haskell {{{ +" let g:syntastic_haskell_checkers = ['ghc-mod'] +" }}} +" Elixir {{{ +let g:syntastic_elixir_checkers = ['elixir'] +let g:syntastic_enable_elixir_checker = 1 +" }}} +" }}} + +" Bufferline {{{ +let g:bufferline_echo=0 +" }}} + +" Eclim {{{ +let g:EclimCompletionMethod = 'omnifunc' +augroup eclim + au! + au FileType java call JavaSetup() + au FileType java set textwidth=120 +augroup END + +function! s:JavaSetup() abort + noremap :JavaImport + nnoremap K :JavaDocPreview + nnoremap ]d :JavaSearchContext + nnoremap [d :JavaSearchContext + nnoremap g :JUnit + nnoremap g\ :Mvn test +endfunction +" }}} + +" Signify options {{{ +let g:signify_mapping_next_hunk = ']h' +let g:signify_mapping_prev_hunk = '[h' +let g:signify_vcs_list = ['git'] +let g:signify_sign_change = '~' +let g:signify_sign_delete = '-' +" }}} + +" Simplenote {{{ +let g:SimplenoteFiletype = 'markdown' +let g:SimplenoteSortOrder = 'pinned,modifydate,tagged,createdate' +let g:SimplenoteVertical = 1 + +nnoremap nn :Simplenote -n +nnoremap nl :Simplenote -l +nnoremap nw :Simplenote -l work +nnoremap nt :Simplenote -t +" }}} + +" Emmet {{{ +" Expand abbreviation +let g:user_emmet_leader_key = '' +" }}} + +" Startify {{{ +let g:startify_bookmarks=[ '~/.vimrc', '~/.zshrc' ] +" }}} + +" Abolish {{{ +let g:abolish_save_file = expand('~/.vim/after/plugin/abolish.vim') +" }}} + +" Rails projections {{{ + +if !exists('g:rails_projections') + let g:rails_projections = {} +endif + +call extend(g:rails_projections, { + \ "config/routes.rb": { "command": "routes" }, + \ "config/structure.sql": { "command": "structure" } + \ }, 'keep') + +if !exists('g:rails_gem_projections') + let g:rails_gem_projections = {} +endif + +call extend(g:rails_gem_projections, { + \ "active_model_serializers": { + \ "app/serializers/*_serializer.rb": { + \ "command": "serializer", + \ "template": "class %SSerializer < ActiveModel::Serializer\nend", + \ "affinity": "model"}}, + \ "react-rails": { + \ "app/assets/javascripts/components/*.jsx": { + \ "command": "component", + \ "template": "var %S = window.%S = React.createClass({\n render: function() {\n }\n});", + \ "alternate": "spec/javascripts/components/%s_spec.jsx" }, + \ "spec/javascripts/components/*_spec.jsx": { + \ "alternate": "app/assets/javascripts/components/{}.jsx" }}, + \ "rspec": { + \ "spec/**/support/*.rb": { + \ "command": "support"}}, + \ "cucumber": { + \ "features/*.feature": { + \ "command": "feature", + \ "template": "Feature: %h"}, + \ "features/support/*.rb": { + \ "command": "support"}, + \ "features/support/env.rb": { + \ "command": "support"}, + \ "features/step_definitions/*_steps.rb": { + \ "command": "steps"}}, + \ "carrierwave": { + \ "app/uploaders/*_uploader.rb": { + \ "command": "uploader", + \ "template": "class %SUploader < CarrierWave::Uploader::Base\nend"}}, + \ "draper": { + \ "app/decorators/*_decorator.rb": { + \ "command": "decorator", + \ "affinity": "model", + \ "template": "class %SDecorator < Draper::Decorator\nend"}}, + \ "fabrication": { + \ "spec/fabricators/*_fabricator.rb": { + \ "command": ["fabricator", "factory"], + \ "alternate": "app/models/%s.rb", + \ "related": "db/schema.rb#%p", + \ "test": "spec/models/%s_spec.rb", + \ "template": "Fabricator :%s do\nend", + \ "affinity": "model"}}, + \ "factory_girl": { + \ "spec/factories/*.rb": { + \ "command": "factory", + \ "alternate": "app/models/%i.rb", + \ "related": "db/structure.sql#%s", + \ "test": "spec/models/%s_spec.rb", + \ "template": "FactoryGirl.define do\n factory :%i do\n end\nend", + \ "affinity": "model"}, + \ "spec/factories.rb": { + \ "command": "factory"}, + \ "test/factories.rb": { + \ "command": "factory"}} + \ }, 'keep') +" }}} + +" Other projections {{{ +let g:projectionist_heuristics = { + \ "config.ru&docker-compose.yml&app/&config/&OWNERS": { + \ "app/jobs/*.rb": { + \ "type": "job", + \ "alternate": "spec/jobs/{}_spec.rb" + \ }, + \ "app/models/*.rb": { + \ "type": "model", + \ "alternate": "spec/models/{}_spec.rb" + \ }, + \ "app/resources/*_resource.rb": { + \ "type": "resource", + \ "alternate": "spec/resources/{}_resource_spec.rb" + \ }, + \ "config/*.yml": { + \ "type": "config" + \ }, + \ "spec/*_spec.rb": { + \ "type": "spec", + \ "alternate": "app/{}.rb" + \ }, + \ "spec/factories/*.rb": { + \ "type": "factory", + \ } + \ }, + \ "svc-gateway.cabal": { + \ "src/*.hs": { + \ "type": "src", + \ "alternate": "test/{}Spec.hs" + \ }, + \ "test/*Spec.hs": { + \ "type": "spec", + \ "alternate": "src/{}.hs", + \ "template": [ + \ "module Gateway.Resource.HierarchySpec (main, spec) where", + \ "", + \ "import Prelude", + \ "import Test.Hspec", + \ "import Data.Aeson", + \ "", + \ "import Gateway.Resource.Hierarchy", + \ "", + \ "main :: IO ()", + \ "main = hspec spec", + \ "", + \ "spec :: Spec", + \ "spec = do", + \ " describe \"something\" $ undefined" + \ ] + \ }, + \ "svc-gateway.cabal": { + \ "type": "cabal" + \ } + \ }, + \ "package.json&.flowconfig": { + \ "src/*.*": { + \ "type": "src", + \ "alternate": "test/{}_spec.js" + \ } + \ }, + \ "pom.xml&src/main/clj/|src/main/cljs": { + \ "*": { + \ "start": "USE_NREPL=1 bin/run -m elephant.dev-system" , + \ "connect": "nrepl://localhost:5554", + \ "piggieback": "(figwheel-sidecar.repl-api/repl-env)" + \ }, + \ "pom.xml": { "type": "pom" }, + \ "src/main/clj/*.clj": { + \ "alternate": "src/test/clj/{}_test.clj", + \ "template": ["(ns {dot|hyphenate})"] + \ }, + \ "src/test/clj/*_test.clj": { + \ "alternate": "src/main/clj/{}.clj", + \ "dispatch": ":RunTests {dot|hyphenate}-test", + \ "template": ["(ns {dot|hyphenate}-test", + \ " (:require [clojure.test :refer :all]))"] + \ }, + \ "src/main/cljs/*.cljs": { + \ "alternate": "src/test/cljs/{}_test.cljs" + \ }, + \ "src/main/cljs/*_test.cljs": { + \ "alternate": "src/main/cljs/{}.cljs", + \ "dispatch": ":RunTests {dot|hyphenate}-test" + \ }, + \ "src/main/clj/*.cljc": { + \ "alternate": "src/test/clj/{}_test.cljc" + \ }, + \ "src/main/clj/*_test.cljc": { + \ "alternate": "src/test/clj/{}.cljc", + \ "dispatch": ":RunTests {dot|hyphenate}-test" + \ } + \ }} +" }}} + +" AutoPairs {{{ +let g:AutoPairsCenterLine = 0 +" }}} + +" Filetypes {{{ + +" Python {{{ +aug Python + au! + au FileType python set tabstop=4 shiftwidth=4 softtabstop=4 expandtab +aug END +let g:python_highlight_all=1 +" }}} + +" PHP {{{ +aug PHP + au! + "au FileType php setlocal fdm=marker fmr={{{,}}} +aug END " }}} + +" Mail {{{ +aug Mail + au FileType mail setlocal spell +aug END " }}} + +" Haskell {{{ +let g:haskell_conceal_wide = 1 +let g:haskellmode_completion_ghc = 0 +let g:necoghc_enable_detailed_browse = 1 + +augroup Haskell + autocmd! + autocmd FileType haskell setlocal textwidth=110 shiftwidth=2 + autocmd FileType haskell setlocal omnifunc=necoghc#omnifunc + autocmd FileType haskell call HaskellSetup() + autocmd FileType haskell setlocal keywordprg=hoogle\ -cie +augroup END + +function! s:HaskellSetup() + set sw=4 + " compiler cabal + " let b:start='cabal run' + " let b:console='cabal repl' + " let b:dispatch='cabal test' + compiler stack + let b:start='stack run' + let b:console='stack ghci' + let b:dispatch='stack test' + nnoremap gy :HdevtoolsType + nnoremap yu :HdevtoolsClear +endfunction +" }}} + +" Ruby {{{ + +function! s:RSpecSyntax() + syn keyword rspecMethod describe context it its specify shared_context + \ shared_examples shared_examples_for shared_context include_examples + \ include_context it_should_behave_like it_behaves_like before after + \ around fixtures controller_name helper_name scenario feature + \ background given described_class + syn match rspecMethod '\!\=' + syn match rspecMethod '\!\=' + syn keyword rspecMethod violated pending expect expect_any_instance_of allow + \ allow_any_instance_of double instance_double mock mock_model + \ stub_model xit + syn match rspecMethod '\.\@!\@!' + + call s:RSpecHiDefaults() +endfunction + +function! s:RSpecHiDefaults() + hi def link rspecMethod rubyFunction +endfunction + +augroup Ruby + au! + " au FileType ruby let b:surround_114 = "\\(module|class,def,if,unless,case,while,until,begin,do) \r end" + " au FileType ruby set fdm=syntax + au FileType ruby set tw=110 + au FileType ruby set omnifunc= + au FileType ruby nnoremap gy orequire 'pry'; binding.pry^ + au FileType ruby nnoremap gY Orequire 'pry'; binding.pry^ + au FileType ruby nnoremap yu :g/require 'pry'; binding.pry/d + au BufNewFile,BufRead *_spec.rb call RSpecSyntax() +augroup END + +let ruby_operators = 1 +let ruby_space_errors = 1 + +let g:rubycomplete_rails = 1 +command! -range ConvertHashSyntax ,s/:(\S{-})(\s{-})=> /\1:\2/ +" }}} + +" Clojure {{{ + +aug Clojure + au! + autocmd FileType clojure nnoremap :Slamhound + autocmd FileType clojure nnoremap gr :w Require e + let g:clojure_align_multiline_strings = 1 + let g:clojure_fuzzy_indent_patterns = + \ ['^with', '^def', '^let', '^fact'] + let g:clojure_special_indent_words = + \ 'deftype,defrecord,reify,proxy,extend-type,extend-protocol,letfn,html' + + autocmd FileType clojure setlocal textwidth=80 + autocmd FileType clojure setlocal lispwords+=GET,POST,PATCH,PUT,DELETE | + \ setlocal lispwords+=context,select + autocmd BufNewFile,BufReadPost *.cljx setfiletype clojure + autocmd BufNewFile,BufReadPost *.cljx setlocal omnifunc= + autocmd BufNewFile,BufReadPost *.cljs setlocal omnifunc= + autocmd FileType clojure call TangentInit() + autocmd FileType clojure call sexp_mappings() + autocmd BufRead *.cljc ClojureHighlightReferences + autocmd FileType clojure let b:AutoPairs = { + \ '"': '"', + \ '{': '}', + \ '(': ')', + \ '[': ']'} + " Don't auto-pair quote reader macros + " \'`': '`', + " \ '''': '''', + + autocmd User ProjectionistActivate call s:projectionist_connect() + + function! s:projectionist_connect() abort + let connected = !empty(fireplace#path()) + if !connected + for [root, value] in projectionist#query('connect') + try + silent execute "FireplaceConnect" value root + let connected = 1 + break + catch /.*Connection refused.*/ + endtry + endfor + endif + + " if connected && exists(':Piggieback') + " for [root, value] in projectionist#query('piggieback') + " silent execute "Piggieback" value + " break + " endfor + " endif + endfunction + + " autocmd BufNewFile,BufReadPost *.cljx setlocal omnifunc= + " autocmd BufNewFile,BufReadPost *.cljs setlocal omnifunc= + + autocmd FileType clojure let b:console='lein repl' + autocmd FileType clojure call ClojureMaps() + + function! s:ClojureMaps() abort + nnoremap [m :call search('^(def', 'Wzb') + nnoremap ]m :call search('^(def', 'Wz') + endfunction + + command! Scratch call OpenScratch() + autocmd FileType clojure nnoremap \s :Scratch + + let g:scratch_buffer_name = 'SCRATCH' + + function! s:OpenScratch() + if bufwinnr(g:scratch_buffer_name) > 0 + execute bufwinnr(g:scratch_buffer_name) . 'wincmd' 'w' + return + endif + + vsplit SCRATCH + set buftype=nofile + set filetype=clojure + let b:scratch = 1 + endfunction +aug END + +function! s:sexp_mappings() abort + if !exists('g:sexp_loaded') + return + endif + + nmap cfo (sexp_raise_list) + nmap cfO (sexp_raise_element) + nmap cfe (sexp_raise_element) +endfunction + +function! s:TangentInit() abort + set textwidth=80 + command! TReset call fireplace#session_eval('(user/reset)') + command! TGo call fireplace#session_eval('(user/go)') + command! TMigrate call fireplace#session_eval('(user/migrate)') + command! TRollback call fireplace#session_eval('(user/rollback)') + nnoremap g\ :TReset +endfunction + +" }}} + +" Go {{{ + +let g:go_highlight_functions = 1 +let g:go_highlight_methods = 1 +let g:go_highlight_structs = 1 +let g:go_highlight_operators = 1 +let g:go_highlight_build_constraints = 1 + +augroup Go + autocmd! + autocmd FileType go setlocal omnifunc=go#complete#Complete + autocmd FileType go setlocal foldmethod=syntax + autocmd FileType go setlocal foldlevel=100 + autocmd FileType go nnoremap :GoTest + autocmd FileType go inoremap :GoTesti +augroup END + +" }}} + +" RAML {{{ + +function! s:buffer_syntax() " {{{ + syn keyword ramlRAML RAML contained + syn match ramlVersionString '^#%RAML \d\.\d' contains=ramlRAML +endfunction " }}} + +augroup RAML + autocmd! + autocmd BufRead,BufNewFile *.raml set filetype=yaml + autocmd BufRead,BufNewFile *.raml call s:buffer_syntax() +augroup END + +hi def link ramlVersionString Special +hi def link ramlRAML Error +" }}} + +" Mustache/Handlebars {{{ +let g:mustache_abbreviations = 1 +" }}} + +" Netrw {{{ +augroup netrw + autocmd! + autocmd FileType netrw nnoremap Q :Rexplore + + " Hee hee, oil and vinegar + function! s:setup_oil() abort + nnoremap q + xnoremap q + endfunction +augroup END +" }}} +" }}} + +" Remove trailing whitespace {{{ +fun! StripTrailingWhitespaces() + let l = line(".") + let c = col(".") + %s/\s\+$//e + call cursor(l, c) +endfun + +augroup striptrailingwhitespaces " {{{ +autocmd FileType c,cpp,java,php,ruby,python,sql,javascript,sh,jst,less,haskell,haml,coffee,scss,clojure,objc,elixir,yaml,json,eruby + \ autocmd BufWritePre :call StripTrailingWhitespaces() +augroup END " }}} + +" }}} + +" Goyo {{{ +let g:limelight_conceal_ctermfg = "10" +let g:limelight_conceal_guifg = "#586e75" +autocmd! User GoyoEnter Limelight +autocmd! User GoyoLeave Limelight! +" }}} + +"----------------------------------------------------------------------------- + +" Commands {{{ + +" Edit temporary SQL files {{{ +let s:curr_sql = 0 +fun! EditSqlTempFile() + let l:fname = '/tmp/q' . s:curr_sql . '.sql' + execute 'edit' l:fname + let s:curr_sql = s:curr_sql + 1 +endfun +com! EditSqlTempFile call EditSqlTempFile() +" }}} + +" Double Indentation +command! -range DoubleIndentation ,s/^\(\s.\{-}\)\(\S\)/\1\1\2/ + +" Quick-and-dirty fix capitalization of sql files +command! -range FixSqlCapitalization ,v/\v(^\s*--.*$)|(TG_)/norm guu + +" VimPipe Commands {{{ +" let g:sql_type_default = 'pgsql' +command! SqlLive let b:vimpipe_command="vagrant ssh -c '~/mysql'" +command! SqlRails let b:vimpipe_command="bin/rails dbconsole" +command! SqlHeroku let b:vimpipe_command="heroku pg:psql" +command! SqlEntities let b:vimpipe_command="psql -h 127.1 entities nomi" +command! SqlUsers let b:vimpipe_command="psql -h 127.1 users nomi" +command! SqlTangent let b:vimpipe_command="psql -h local.docker tangent super" +" }}} + +" Git commands {{{ +command! -nargs=* Gpf Gpush -f +command! -nargs=* Gcv Gcommit --verbose +" }}} + +" Focus dispatch to only the last failures +command! -nargs=* FocusFailures FocusDispatch rspec --only-failures + +" }}} + +" Autocommands {{{ + +augroup fugitive " {{{ + au! + autocmd BufNewFile,BufRead fugitive://* set bufhidden=delete +augroup END " }}} + +augroup omni " {{{ + au! + " autocmd FileType javascript setlocal omnifunc=tern#Complete + "autocmd FileType python setlocal omnifunc=pythoncomplete#Complete + autocmd FileType php setlocal omnifunc= +augroup END " }}} + +augroup sql " {{{ + au! + autocmd FileType sql let b:vimpipe_command="psql -h 127.0.0.1 landlordsny_development landlordsny" + autocmd FileType sql let b:vimpipe_filetype="postgresql" + autocmd FileType sql set syntax=postgresql + autocmd FileType postgresql set nowrap + autocmd BufNewFile,BufReadPost *.sql set syntax=pgsql +augroup END " }}} + +augroup markdown " {{{ + au! + autocmd FileType markdown let b:vimpipe_command='markdown' + autocmd FileType markdown let b:vimpipe_filetype='html' + autocmd FileType markdown set tw=80 +augroup END " }}} + +augroup typescript " {{{ + au! + autocmd FileType typescript let b:vimpipe_command='tsc' + autocmd FileType typescript let b:vimpipe_filetype='javascript' + autocmd FileType typescript TSSstarthere + autocmd FileType typescript nnoremap gd :TSSdef +augroup END " }}} + +augroup jsx " {{{ + au! + " autocmd FileType jsx set syntax=javascript + autocmd FileType javascript set filetype=javascript.jsx +augroup END " }}} + +augroup nicefoldmethod " {{{ + au! + " Don't screw up folds when inserting text that might affect them, until + " leaving insert mode. Foldmethod is local to the window. Protect against + " screwing up folding when switching between windows. + autocmd InsertEnter * + \ if !exists('w:last_fdm') | + \ let w:last_fdm=&foldmethod | + \ setlocal foldmethod=manual | + \ endif + autocmd InsertLeave,WinLeave * + \ if exists('w:last_fdm') | + \ let &l:foldmethod=w:last_fdm | + \ unlet w:last_fdm | + \ endif +augroup END " }}} + +augroup visualbell " {{{ + au! + autocmd GUIEnter * set visualbell t_vb= +augroup END +" }}} + +augroup quickfix " {{{ + au! + autocmd QuickFixCmdPost grep cwindow +augroup END " }}} + +augroup php " {{{ + au! +augroup END "}}} + +augroup rubylang " {{{ + au! + autocmd FileType ruby compiler rake +augroup END " }}} + +augroup javascript "{{{ + au! + autocmd FileType javascript let &errorformat = + \ '%E%.%#%n) %s:,' . + \ '%C%.%#Error: %m,' . + \ '%C%.%#at %s (%f:%l:%c),' . + \ '%Z%.%#at %s (%f:%l:%c),' . + \ '%-G%.%#,' +augroup END " }}} + +augroup git " {{{ + autocmd! + autocmd FileType gitcommit set textwidth=72 +augroup END +" }}} +" }}} + +" Leader commands {{{ + +" Edit specific files {{{ +nnoremap ev :split $MYVIMRC +nnoremap eb :split ~/.vim_bundles +nnoremap es :UltiSnipsEdit +nnoremap ea :split ~/.vim/after/plugin/abolish.vim + +nnoremap sv :so $MYVIMRC +nnoremap sb :so ~/.vim_bundles +nnoremap sa :so ~/.vim/after/plugin/abolish.vim + +nnoremap el :EditSqlTempFile +" }}} + +" Toggle navigation panels {{{ +nnoremap l :TagbarToggle +nnoremap mb :MBEToggle +nnoremap u :GundoToggle + +nnoremap t :CtrlP +nnoremap z :FZF +nnoremap b :CtrlPBuffer +nnoremap a :CtrlPTag +nnoremap r :CtrlPGitBranch +" }}} + +" CtrlP {{{ +let g:ctrlp_custom_ignore = { + \ 'dir': 'node_modules', + \ } +" }}} + +" Git leader commands {{{ +noremap g :Git +noremap gu :Gpull +noremap gp :Gpush +noremap s :Gstatus +noremap cv :Gcommit --verbose +noremap ca :Gcommit --verbose --amend + +nnoremap dl :diffg LOCAL +nnoremap dr :diffg REMOTE +nnoremap db :diffg BASE +nnoremap du :diffu +nnoremap dg :diffg + +nnoremap d2 :diffg //2:diffu +nnoremap d3 :diffg //3:diffu + +nnoremap yt :SignifyToggle +" }}} + +" Breakpoint Leader Commands {{{ +nnoremap x :Breakpoint +nnoremap dx :BreakpointRemove * +" }}} + +" Tabularize {{{ + " Leader Commands {{{ + nnoremap t= :Tabularize /= + vmap t= :Tabularize /= + + nnoremap t> :Tabularize /=> + vmap t> :Tabularize /=> + " }}} + + " => Aligning {{{ + function! s:rocketalign() + let l:p = '^.*=>\s.*$' + echo l:p + if exists(':Tabularize') && getline('.') =~# '^.*=' && + \ (getline(line('.')-1) =~# l:p || getline(line('.')+1) =~# l:p) + let column = strlen(substitute(getline('.')[0:col('.')],'[^=>]','','g')) + let position = strlen(matchstr(getline('.')[0:col('.')],'.*=>\s*\zs.*')) + Tabularize/=>/l1 + normal! $ + call search(repeat('[^=>]*=>',column).'\s\{-\}'.repeat('.',position),'ce',line('.')) + endif + endfunction + "inoremap => =>:call rocketalign()a + " }}} + + " = Aligning {{{ + function! s:eqalign() + let l:p = '^.*=\s.*$' + if exists(':Tabularize') && getline('.') =~# '^.*=' && + \ (getline(line('.')-1) =~# l:p || getline(line('.')+1) =~# l:p) + let column = strlen(substitute(getline('.')[0:col('.')],'[^=]','','g')) + let position = strlen(matchstr(getline('.')[0:col('.')],'.*=\s*\zs.*')) + Tabularize/=/l1 + normal! $ + call search(repeat('[^=]*=',column).'\s\{-\}'.repeat('.',position),'ce',line('.')) + endif + endfunction + "inoremap = =:call eqalign()a + " }}} + + " : Aligning {{{ + function! s:colonalign() + let l:p : '^.*:\s.*$' + if exists(':Tabularize') && getline('.') :~# '^.*:' && + \ (getline(line('.')-1) :~# l:p || getline(line('.')+1) :~# l:p) + let column : strlen(substitute(getline('.')[0:col('.')],'[^:]','','g')) + let position : strlen(matchstr(getline('.')[0:col('.')],'.*:\s*\zs.*')) + Tabularize/:/l1 + normal! $ + call search(repeat('[^:]*:',column).'\s\{-\}'.repeat('.',position),'ce',line('.')) + endif + endfunction + "inoremap : ::call colonalign()a + " }}} +" }}} + +" }}} + +" Mappings {{{ +" 'delete current' +nnoremap dc 0d$ +nnoremap com :silent !tmux set status +nnoremap :Make +nnoremap g :Dispatch +nnoremap g\ :Start +inoremap :Makei + +" Navigate buffers {{{ +nnoremap gb :bn +nnoremap gB :bp +" }}} + +" Window Navigation {{{ +nnoremap w +nnoremap h h +nnoremap j j +nnoremap k k +nnoremap l l +nnoremap z z +" }}} + + +" Sort with motion {{{ +if !exists("g:sort_motion_flags") + let g:sort_motion_flags = "" +endif +function! s:sort_motion(mode) abort + if a:mode == 'line' + execute "'[,']sort " . g:sort_motion_flags + elseif a:mode == 'char' + execute "normal! `[v`]y" + let sorted = join(sort(split(@@, ', ')), ', ') + execute "normal! v`]c" . sorted + elseif a:mode == 'V' || a:mode == '' + execute "'<,'>sort " . g:sort_motion_flags + endif +endfunction + +function! s:sort_lines() + let beginning = line('.') + let end = v:count + beginning - 1 + execute beginning . ',' . end . 'sort' +endfunction + +xnoremap SortMotionVisual :call sort_motion(visualmode()) +nnoremap SortMotion :set opfunc=sort_motiong@ +nnoremap SortLines :call sort_lines() + +map go SortMotion +vmap go SortMotionVisual +map goo SortLines +" }}} +" }}} + +let g:hare_executable = 'cabal exec -- ghc-hare' diff --git a/home/modules/zshrc b/home/modules/zshrc new file mode 100644 index 000000000..95c1733e1 --- /dev/null +++ b/home/modules/zshrc @@ -0,0 +1,371 @@ +#!/usr/bin/zsh +# vim: set fdm=marker fmr={{{,}}}: + +stty -ixon + +# Compinstall {{{ +zstyle ':completion:*' completer _complete _ignored _correct _approximate +zstyle ':completion:*' matcher-list '' 'm:{[:lower:]}={[:upper:]} m:{[:lower:][:upper:]}={[:upper:][:lower:]} r:|[._- :]=** r:|=**' 'l:|=* r:|=*' +zstyle ':completion:*' max-errors 5 +zstyle ':completion:*' use-cache yes +zstyle ':completion::complete:grunt::options:' expire 1 +zstyle ':completion:*' prompt '%e errors' +zstyle :compinstall filename '~/.zshrc' +autoload -Uz compinit +compinit +# }}} + +# Zsh-newuser-install {{{ +HISTFILE=~/.histfile +HISTSIZE=1000 +SAVEHIST=1000 +setopt appendhistory autocd extendedglob notify autopushd +unsetopt beep nomatch +bindkey -v +# }}} + +# Basic options {{{ +set -o vi +umask 022 +export VIRTUAL_ENV_DISABLE_PROMPT=1 +# export PATH=~/.local/bin:~/.cabal/bin:$PATH:~/code/go/bin:~/bin:~/npm/bin:~/.gem/ruby/2.1.0/bin:~/.gem/ruby/2.0.0/bin:/home/smith/bin +# }}} + +# Zsh highlight highlighters {{{ +ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets pattern root) +# }}} + +# More basic options {{{ +setopt no_hist_verify +setopt histignorespace +# }}} + +# Utility Functions {{{ + +# Set the terminal's title bar. +function titlebar() { +echo -ne "\033]0;$*\007" +} + +function quiet() { +"$@" >/dev/null +} + +function quieter() { +"$@" >/dev/null 2>&1 +} + +# From http://stackoverflow.com/questions/370047/#370255 +function path_remove() { +IFS=: +# convert it to an array +t=($PATH) +unset IFS +# perform any array operations to remove elements from the array +t=(${t[@]%%$1}) +IFS=: +# output the new array +echo "${t[*]}" +} + +# }}} + +# Force screen to use zsh {{{ +# }}} + +# Environment {{{ +export EDITOR="/usr/bin/vim" +# }}} + +# Directory Stuff {{{ + +# Always use color output for `ls` +if [[ "$OSTYPE" =~ ^darwin ]]; then +else + export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:' +fi + +# Directory listing + +# Easier navigation: .., ..., - + +# File size + +# Recursively delete `.DS_Store` files + +# Create a new directory and enter it +function md() { + mkdir -p "$@" && cd "$@" +} + +# }}} + +# MPD/MPC stuff {{{ +function mp() { +# Test if drive is already mounted +if ! lsblk | grep /media/external >/dev/null; then + if ! sudo mount /media/external; then + echo "External drive not plugged in, or could not mount" + return 1 + fi +fi +if (mpc >/dev/null 2>&1); then + ncmpcpp +else + mpd && + (pgrep mpdscribble || mpdscribble) && + ncmpcpp +fi +} + +# kill mp +function kmp() { +killall ncmpcpp +mpd --kill + +local files + +if (files=$(lsof 2>&1 | grep -v docker | grep external)); then + echo + echo "==> Still processes using external drive:" + echo + echo $files +else + sudo umount /media/external +fi +} + + +function mppal() { +mpc search album "$1" | mpc add && + mpc play; +} +# }}} + +# Git stuff {{{ +# function ga() { git add "${@:-.}"; } # Add all files by default +# Add non-whitespace changes +# function gc() { git checkout "${@:-master}"; } # Checkout master by default + +# open all changed files (that still actually exist) in the editor +function ged() { +local files=() +for f in $(git diff --name-only "$@"); do + [[ -e "$f" ]] && files=("${files[@]}" "$f") +done +local n=${#files[@]} +echo "Opening $n $([[ "$@" ]] || echo "modified ")file$([[ $n != 1 ]] && \ + echo s)${@:+ modified in }$@" +q "${files[@]}" +} + +# git find-replace +function gfr() { +if [[ "$#" == "0" ]]; then + echo 'Usage:' + echo ' gg_replace term replacement file_mask' + echo + echo 'Example:' + echo ' gg_replace cappuchino cappuccino *.html' + echo +else + find=$1; shift + replace=$1; shift + + ORIG_GLOBIGNORE=$GLOBIGNORE + GLOBIGNORE=*.* + if [[ "$#" = "0" ]]; then + set -- ' ' $@ + fi + + while [[ "$#" -gt "0" ]]; do + for file in `git grep -l $find -- $1`; do + sed -e "s/$find/$replace/g" -i'' $file + done + shift + done + + GLOBIGNORE=$ORIG_GLOBIGNORE +fi +} + +function vconflicts() { +$EDITOR $(git status --porcelain | awk '/^UU/ { print $2 }') +} + +function fetchall() { +for repo in ~/code/nomi/gems/* ~/code/nomi/services/svc-users ~/code/nomi/services/svc-entities ~/code/go/src/github.com/getnomi/svc-gateway; do + echo -e "\x1b[34;1m=======> \x1b[37;1m$repo\x1b[0m" + git -C $repo fetch +done +} +# }}} + +# Wifi {{{ +# }}} + +# adb {{{ +export GNEX_IP='192.168.3.30' +# }}} + +# Golang {{{ +export GOPATH="/home/griffin/code/go" +# }}} + +# Tail logs {{{ +# }}} + +# Running stuff {{{ +# }}} + +# Directories {{{ + + + +export NODE_ENV='development' +# }}} + +# SSH shortcuts {{{ +# }}} + +# Editing config files {{{ +# }}} + +# XRandR {{{ +# }}} + +# fzf {{{ +v() { + local file + file=$(fzf-tmux --query="$1" --select-1 --exit-0) + [ -n "$file" ] && ${EDITOR:-vim} "$file" +} + +c() { + local dir + dir=$(find ${1:-*} -path '*/\.*' -prune -o -type d -print 2> /dev/null | fzf +m) && cd "$dir" +} + +co() { + local branch + branch=$(git branch -a | sed -s "s/\s*\**//g" | fzf --query="$1" --select-1 --exit-0) && git checkout "$branch" +} + + +# fh - repeat history +# h() { +# eval $(([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf +s | sed 's/ *[0-9]* *//') +# } + +# fkill - kill process +fkill() { + ps -ef | sed 1d | fzf-tmux -m | awk '{print $2}' | xargs kill -${1:-9} +} +# }}} + +# Tmux utils {{{ +kill_detached() { + for sess in $(tmux ls | grep -v attached | sed -s "s/:.*$//"); do + tmux kill-session -t $sess; + done +} +# }}} + +# Docker {{{ + + +# dbp foo/bar . +function dbp () { + docker build -t $1 ${@:2} && docker push $1 +} + +# }}} + +# Vagrant {{{ +# }}} + +# Twitter! {{{ +export TWITTER_WHOAMI='glittershark1' + + +# favelast +function favelast() { + t fave $(t tl -l $1 | head -n1 | first) +} + +function rtlast() { + t rt $(t tl -l $1 | head -n1 | first) +} + +function tthread() { + t reply $(t tl -l $TWITTER_WHOAMI | head -n1 | first) $@ +} +# }}} + +# Geeknote {{{ +gnc() { + gn create --title $1 --content '' && + gn find --count=1 "$1" + gn edit 1 +} +# }}} + +# Systemd aliases {{{ +# }}} + +# Misc aliases {{{ + +function fw() { # fix white + local substitution + local substitution='s/\x1b\[90m/\x1b[92m/g' + $@ > >(perl -pe "$substitution") 2> >(perl -pe "$substitution" 1>&2) +} +# }}} + +# Grep options {{{ +unset GREP_OPTIONS +export GREP_OPTIONS= +# }}} + +# Keyboard backlight {{{ + +KEYBOARD_BRIGHTNESS_FILE='/sys/devices/platform/applesmc.768/leds/smc::kbd_backlight/brightness' + +setkbd() { + echo $1 | sudo tee $KEYBOARD_BRIGHTNESS_FILE +} + +kbdup() { + curr=$(< $KEYBOARD_BRIGHTNESS_FILE) + echo $(( $curr + 15 )) | sudo tee $KEYBOARD_BRIGHTNESS_FILE +} + +kbdup() { + curr=$(< $KEYBOARD_BRIGHTNESS_FILE) + echo $(( $curr - 15 )) | sudo tee $KEYBOARD_BRIGHTNESS_FILE +} + +# }}} + +# Run docker containers {{{ + # -d \ + # -v $HOME/.pentadactyl:/home/firefox/.pentadactyl:rw \ + # -v $HOME/.pentadactylrc:/home/firefox/.pentadactylrc:rw \ + # -v $HOME/.mozilla:/home/firefox/.mozilla:rw \ + # -v $HOME/.config:/home/firefox/.config \ + # -v $HOME/Downloads:/home/firefox/Downloads:rw \ + # -v /etc/fonts:/etc/fonts \ + # -v /tmp/.X11-unix:/tmp/.X11-unix \ + # -v /dev/snd:/dev/snd \ + # --net=host \ + # -v $XDG_RUNTIME_DIR:$XDG_RUNTIME_DIR \ + # -e uid=$(id -u) \ + # -e gid=$(id -g) \ + # -e DISPLAY=$DISPLAY \ + # -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \ + # --name firefox \ + # --rm -it \ + # glittershark/firefox +# }}} + +[ -f ./.localrc ] && source ./.localrc diff --git a/install b/install new file mode 100755 index 000000000..bad60db02 --- /dev/null +++ b/install @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +set -eo pipefail + +if [[ -f /etc/nixos/.system-installed ]]; then + echo "=== System config already installed, skipping" +else + echo "==> Installing system config" + + [[ -d /etc/nixos ]] && sudo mv /etc/nixos{,.bak} + sudo mkdir -p /etc/nixos + sudo cp /etc/nixos.bak/hardware-configuration.nix /etc/nixos + + sudo cp ./configuration.nix /etc/nixos/ + sudo ln -s $(pwd)/{machines,modules,pkgs} /etc/nixos + sudo touch /etc/nixos/.system-installed + + nixos-rebuild switch + echo "==> System config installed, your old configuration is at /etc/nixos.bak" +fi +echo + +if [[ -f ~/.config/nixpkgs/system-installed ]]; then + echo "=== home-anager config already installed, skipping" +else + echo "==> Installing home-manager config" + nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager + nix-channel --update + nix-shell '' -A install + + [[ -d ~/.config/nixpkgs ]] && mv ~/.config/{nixpkgs,nixpkgs.bak} + mkdir -p ~/.config/nixpkgs + ln -s home/* ~/.config/nixpkgs + + home-manager switch + + echo "==> home-manager config installed" +fi diff --git a/pkgs/alsi/default.nix b/pkgs/alsi/default.nix new file mode 100644 index 000000000..d4da8ff38 --- /dev/null +++ b/pkgs/alsi/default.nix @@ -0,0 +1,22 @@ +{ perl, stdenv, fetchFromGitHub }: +stdenv.mkDerivation { + name = "alsi"; + pname = "alsi"; + version = "0.4.8"; + + src = fetchFromGitHub { + owner = "trizen"; + repo = "alsi"; + rev = "fe2a925caad38d4cc7afe10d74ba60c5db09ee66"; + sha256 = "060xlalfclrda5f1h3svj4v2gr19mdrsc62vrg7hgii0f3lib7j5"; + }; + + buildInputs = [ + (perl.withPackages (ps: with ps; [ DataDump ])) + ]; + + installPhase = '' + mkdir -p $out/bin + cp alsi $out/bin/alsi + ''; +} diff --git a/system/configuration.nix b/system/configuration.nix new file mode 100644 index 000000000..eae567015 --- /dev/null +++ b/system/configuration.nix @@ -0,0 +1,11 @@ +{ config, pkgs, ... }: + +let machine = throw "Pick a machine from ./machines"; in +{ + imports = + [ + /etc/nixos/hardware-configuration.nix + ./modules/common.nix + machine + ]; +} diff --git a/system/machines/bumblebee.nix b/system/machines/bumblebee.nix new file mode 100644 index 000000000..a1cd3ffa1 --- /dev/null +++ b/system/machines/bumblebee.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs, ... }: +{ + imports = [ + ../modules/reusable/battery.nix + ]; + + networking.hostName = "bumblebee"; + + powerManagement = { + enable = true; + cpuFreqGovernor = "powersave"; + powertop.enable = true; + }; + + # Hibernate on low battery + laptop.onLowBattery = { + enable = true; + action = "hibernate"; + thresholdPercentage = 5; + }; +} diff --git a/system/modules/common.nix b/system/modules/common.nix new file mode 100644 index 000000000..27f4a73f0 --- /dev/null +++ b/system/modules/common.nix @@ -0,0 +1,106 @@ +{ config, lib, pkgs, ... }: + +{ + imports = + [ + ./xserver.nix + ./emacs.nix + ./sound.nix + ]; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "bumblebee"; + networking.useDHCP = false; + networking.networkmanager.enable = true; + + # Select internationalisation properties. + # i18n = { + # consoleFont = "Lat2-Terminus16"; + # consoleKeyMap = "us"; + # defaultLocale = "en_US.UTF-8"; + # }; + + # Set your time zone. + time.timeZone = "America/New_York"; + + environment.systemPackages = with pkgs; [ + wget + vim + zsh + git + w3m + libnotify + file + ]; + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + # programs.mtr.enable = true; + # programs.gnupg.agent = { + # enable = true; + # enableSSHSupport = true; + # pinentryFlavor = "gnome3"; + # }; + + programs.nm-applet.enable = true; + + + services.openssh.enable = true; + + # Open ports in the firewall. + # networking.firewall.allowedTCPPorts = [ ... ]; + # networking.firewall.allowedUDPPorts = [ ... ]; + # Or disable the firewall altogether. + networking.firewall.enable = false; + + # Enable CUPS to print documents. + # services.printing.enable = true; + + users.mutableUsers = true; + programs.zsh.enable = true; + environment.pathsToLink = [ "/share/zsh" ]; + users.users.grfn = { + isNormalUser = true; + initialPassword = "password"; + extraGroups = [ + "wheel" # Enable ‘sudo’ for the user. + "networkmanager" + "audio" + ]; + shell = pkgs.zsh; + }; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "20.03"; # Did you read the comment? + + nixpkgs.config.allowUnfree = true; + + fonts.fonts = with pkgs; [ + nerdfonts + ]; + + services.geoclue2.enable = true; + + powerManagement = { + enable = true; + cpuFreqGovernor = "powersave"; + powertop.enable = true; + }; + # Hibernate on low battery + laptop.onLowBattery = { + enable = true; + action = "hibernate"; + thresholdPercentage = 5; + }; + + nix = { + autoOptimiseStore = true; + }; +} diff --git a/system/modules/emacs.nix b/system/modules/emacs.nix new file mode 100644 index 000000000..1cfa2b074 --- /dev/null +++ b/system/modules/emacs.nix @@ -0,0 +1,23 @@ +{ config, pkgs, lib, ... }: +with lib; +{ + options.programs.emacs.useGit = mkOption { + description = "Use emacs from git"; + type = types.bool; + default = false; + }; + + config = { + nixpkgs.overlays = if config.programs.emacs.useGit then [] else [ + (import (builtins.fetchTarball https://github.com/nix-community/emacs-overlay/archive/master.tar.gz)) + ]; + + environment.systemPackages = with pkgs; [ + (if config.programs.emacs.useGit then emacsGit else emacs) + ripgrep + coreutils + fd + clang + ]; + }; +} diff --git a/system/modules/reusable/README.org b/system/modules/reusable/README.org new file mode 100644 index 000000000..34d9bfdcb --- /dev/null +++ b/system/modules/reusable/README.org @@ -0,0 +1,2 @@ +This directory contains things I'm eventually planning on contributing upstream +to nixpkgs diff --git a/system/modules/reusable/battery.nix b/system/modules/reusable/battery.nix new file mode 100644 index 000000000..d7043bf54 --- /dev/null +++ b/system/modules/reusable/battery.nix @@ -0,0 +1,32 @@ +{ config, lib, pkgs, ... }: +with lib; +{ + options = { + laptop.onLowBattery = { + enable = mkEnableOption "Perform action on low battery"; + + thresholdPercentage = mkOption { + description = "Threshold battery percentage on which to perform the action"; + default = 5; + type = types.int; + }; + + action = mkOption { + description = "Action to perform on low battery"; + default = "hibernate"; + type = types.enum [ "hibernate" "suspend" "suspend-then-hibernate" ]; + }; + }; + }; + + config = + let cfg = config.laptop.onLowBattery; + in mkIf cfg.enable { + services.udev.extraRules = concatStrings [ + ''SUBSYSTEM=="power_supply", '' + ''ATTR{status}=="Discharging", '' + ''ATTR{capacity}=="[0-${toString cfg.thresholdPercentage}]", '' + ''RUN+="/${pkgs.systemd}/bin/systemctl ${cfg.action}"'' + ]; + }; +} diff --git a/system/modules/sound.nix b/system/modules/sound.nix new file mode 100644 index 000000000..0d5ce3e31 --- /dev/null +++ b/system/modules/sound.nix @@ -0,0 +1,14 @@ +{ config, lib, pkgs, ... }: +{ + # Enable sound. + sound.enable = true; + hardware.pulseaudio.enable = true; + nixpkgs.config.pulseaudio = true; + + environment.systemPackages = with pkgs; [ + pulseaudio-ctl + paprefs + pasystray + pavucontrol + ]; +} diff --git a/system/modules/xserver.nix b/system/modules/xserver.nix new file mode 100644 index 000000000..52f04e2e6 --- /dev/null +++ b/system/modules/xserver.nix @@ -0,0 +1,19 @@ +{ config, pkgs, ... }: +{ + # Enable the X11 windowing system. + services.xserver = { + enable = true; + layout = "us"; + xkbOptions = "caps:swapescape"; + + libinput.enable = true; + + windowManager.i3 = { + enable = true; + extraPackages = with pkgs; [ + i3status + i3lock + ]; + }; + }; +}