├── .gitignore ├── .gitmodules ├── LICENSE.txt ├── README.md ├── bin ├── $ ├── 256colors.pl ├── Markdown.pl ├── color-spaces.pl ├── colortest.sh ├── convert-to-twitter ├── current-branch ├── current-url ├── docker-clean ├── dokku ├── enod ├── extract-cover-art.rb ├── first-frame ├── gifsicle ├── gifv ├── hack ├── imgcat ├── is-this-dark-mode ├── itunes-feed.rb ├── killmouseaccel ├── last-commit-message ├── lock ├── map.rb ├── multizip ├── myip ├── notification ├── prep ├── prl ├── puny ├── random5 ├── random5da ├── refresh-os ├── reload-chrome ├── reload-firefox ├── reload-firefox-dev ├── reload-firefox-nightly ├── reload-safari ├── rm_dsstore ├── slug ├── sort-Xcode-project-file ├── tat ├── unecm └── untilfail ├── brew └── Brewfile.symlink ├── cursor ├── mac.sh └── settings.json ├── git ├── gitconfig.symlink └── gitignore.symlink ├── hammerspoon └── hammerspoon.symlink │ ├── .luarc.json │ ├── init.lua │ └── mouse_four_five.lua ├── karabiner ├── assets │ └── complex_modifications │ │ ├── 1699611650.json │ │ ├── 1713387616.json │ │ └── 1713387868.json ├── karabiner.json └── macos.sh ├── leader_key └── config.json ├── macos ├── DefaultKeyBinding.dict ├── macos.sh └── terminfo │ ├── macos.sh │ ├── tmux-256color.terminfo │ ├── tmux.terminfo │ └── xterm-256color-italic.terminfo ├── nvim ├── all.sh ├── autoload │ └── test │ │ └── solidity │ │ └── forge.vim ├── colors │ └── funbones.lua ├── ftplugin │ ├── markdown.lua │ └── slim.lua ├── init.lua ├── lazyvim.json ├── lua │ ├── config │ │ ├── autocmds.lua │ │ ├── commands.lua │ │ ├── keymaps.lua │ │ ├── lazy.lua │ │ └── options.lua │ └── plugins │ │ ├── ai.lua │ │ ├── coding.lua │ │ ├── colorscheme.lua │ │ ├── editor.lua │ │ ├── formatting.lua │ │ ├── lsp.lua │ │ ├── ruby.lua │ │ ├── test.lua │ │ ├── treesitter.lua │ │ └── ui.lua ├── snippets │ ├── all.json │ ├── eruby.json │ ├── html.json │ ├── javascript.json │ ├── typescript.json │ └── typescriptreact.json ├── spell │ ├── da.utf-8.spl │ ├── en.utf-8.spl │ └── en.utf-8.sug └── stylua.toml ├── other ├── gems └── npm ├── rails └── railsrc.symlink ├── ruby ├── gemrc.symlink └── irbrc.symlink ├── script └── setup ├── sprinkles.symlink ├── dashboard.simpleanalytics.com.css ├── github.com.css ├── github.com.js ├── global.css ├── global.js ├── news.ycombinator.com.css ├── youtube.com.css └── youtube.com.js ├── tmux ├── all.sh ├── tmux.conf.symlink └── tmux.symlink │ └── theme.tmux ├── vim ├── gvimrc.symlink └── vimrc.symlink ├── vscode ├── mac.sh └── settings.json ├── wezterm └── wezterm.lua.symlink ├── xterm-256color.ti └── zsh ├── aliases.zsh ├── all.sh ├── bindkeys.zsh ├── config.zsh ├── omp.toml ├── prompt.zsh ├── zfunc.symlink ├── _brew ├── _c ├── _rustup ├── abspath ├── aripb ├── bundlegrep ├── c ├── gcm ├── mkcd ├── nb ├── nw └── o └── zshrc.symlink /.gitignore: -------------------------------------------------------------------------------- 1 | doc/tags 2 | /vim/vim.symlink/bundle 3 | /tmux/tmux.symlink/plugins 4 | /vim/vim.symlink/.netrwhist 5 | nvim/plugin/packer_compiled.lua 6 | nvim/lazy-lock.json 7 | brew/Brewfile.symlink.lock.json 8 | karabiner/automatic_backups 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tmux/tmux.symlink/plugins/tpm"] 2 | path = tmux/tmux.symlink/plugins/tpm 3 | url = https://github.com/tmux-plugins/tpm 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Mikkel Malmberg 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | dot-dot-dotfiles 2 | 3 | https://github.com/MikeMcQuaid/strap 4 | 5 | ![CleanShot 2024-05-15 at 11 12 13@2x](https://github.com/mikker/dotfiles/assets/2819/262df56f-1bc8-4c03-b977-1d2b643283b2) 6 | 7 | -------------------------------------------------------------------------------- /bin/$: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | $@ 3 | -------------------------------------------------------------------------------- /bin/256colors.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # Author: Todd Larason 3 | # $XFree86: xc/programs/xterm/vttests/256colors2.pl,v 1.2 2002/03/26 01:46:43 dickey Exp $ 4 | 5 | # use the resources for colors 0-15 - usually more-or-less a 6 | # reproduction of the standard ANSI colors, but possibly more 7 | # pleasing shades 8 | 9 | # colors 16-231 are a 6x6x6 color cube 10 | for ($red = 0; $red < 6; $red++) { 11 | for ($green = 0; $green < 6; $green++) { 12 | for ($blue = 0; $blue < 6; $blue++) { 13 | printf("\x1b]4;%d;rgb:%2.2x/%2.2x/%2.2x\x1b\\", 14 | 16 + ($red * 36) + ($green * 6) + $blue, 15 | ($red ? ($red * 40 + 55) : 0), 16 | ($green ? ($green * 40 + 55) : 0), 17 | ($blue ? ($blue * 40 + 55) : 0)); 18 | } 19 | } 20 | } 21 | 22 | # colors 232-255 are a grayscale ramp, intentionally leaving out 23 | # black and white 24 | for ($gray = 0; $gray < 24; $gray++) { 25 | $level = ($gray * 10) + 8; 26 | printf("\x1b]4;%d;rgb:%2.2x/%2.2x/%2.2x\x1b\\", 27 | 232 + $gray, $level, $level, $level); 28 | } 29 | 30 | 31 | # display the colors 32 | 33 | # first the system ones: 34 | print "System colors:\n"; 35 | for ($color = 0; $color < 8; $color++) { 36 | print "\x1b[48;5;${color}m "; 37 | } 38 | print "\x1b[0m\n"; 39 | for ($color = 8; $color < 16; $color++) { 40 | print "\x1b[48;5;${color}m "; 41 | } 42 | print "\x1b[0m\n\n"; 43 | 44 | # now the color cube 45 | print "Color cube, 6x6x6:\n"; 46 | for ($green = 0; $green < 6; $green++) { 47 | for ($red = 0; $red < 6; $red++) { 48 | for ($blue = 0; $blue < 6; $blue++) { 49 | $color = 16 + ($red * 36) + ($green * 6) + $blue; 50 | print "\x1b[48;5;${color}m "; 51 | } 52 | print "\x1b[0m "; 53 | } 54 | print "\n"; 55 | } 56 | 57 | 58 | # now the grayscale ramp 59 | print "Grayscale ramp:\n"; 60 | for ($color = 232; $color < 256; $color++) { 61 | print "\x1b[48;5;${color}m "; 62 | } 63 | print "\x1b[0m\n"; 64 | -------------------------------------------------------------------------------- /bin/color-spaces.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # Author: Todd Larason 3 | # $XFree86: xc/programs/xterm/vttests/256colors2.pl,v 1.1 1999/07/11 08:49:54 dawes Exp $ 4 | 5 | print "256 color mode\n\n"; 6 | 7 | # display back ground colors 8 | 9 | for ($fgbg = 38; $fgbg <= 48; $fgbg +=10) { 10 | 11 | # first the system ones: 12 | print "System colors:\n"; 13 | for ($color = 0; $color < 8; $color++) { 14 | print "\x1b[${fgbg};5;${color}m::"; 15 | } 16 | print "\x1b[0m\n"; 17 | for ($color = 8; $color < 16; $color++) { 18 | print "\x1b[${fgbg};5;${color}m::"; 19 | } 20 | print "\x1b[0m\n\n"; 21 | 22 | # now the color cube 23 | print "Color cube, 6x6x6:\n"; 24 | for ($green = 0; $green < 6; $green++) { 25 | for ($red = 0; $red < 6; $red++) { 26 | for ($blue = 0; $blue < 6; $blue++) { 27 | $color = 16 + ($red * 36) + ($green * 6) + $blue; 28 | print "\x1b[${fgbg};5;${color}m::"; 29 | } 30 | print "\x1b[0m "; 31 | } 32 | print "\n"; 33 | } 34 | 35 | # now the grayscale ramp 36 | print "Grayscale ramp:\n"; 37 | for ($color = 232; $color < 256; $color++) { 38 | print "\x1b[${fgbg};5;${color}m::"; 39 | } 40 | print "\x1b[0m\n\n"; 41 | 42 | } 43 | 44 | print "Examples for the 3-byte color mode\n\n"; 45 | 46 | for ($fgbg = 38; $fgbg <= 48; $fgbg +=10) { 47 | 48 | # now the color cube 49 | print "Color cube\n"; 50 | for ($green = 0; $green < 256; $green+=51) { 51 | for ($red = 0; $red < 256; $red+=51) { 52 | for ($blue = 0; $blue < 256; $blue+=51) { 53 | print "\x1b[${fgbg};2;${red};${green};${blue}m::"; 54 | } 55 | print "\x1b[0m "; 56 | } 57 | print "\n"; 58 | } 59 | 60 | # now the grayscale ramp 61 | print "Grayscale ramp:\n"; 62 | for ($gray = 8; $gray < 256; $gray+=10) { 63 | print "\x1b[${fgbg};2;${gray};${gray};${gray}m::"; 64 | } 65 | print "\x1b[0m\n\n"; 66 | 67 | } 68 | 69 | -------------------------------------------------------------------------------- /bin/colortest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # This file echoes a bunch of color codes to the 4 | # terminal to demonstrate what's available. Each 5 | # line is the color code of one forground color, 6 | # out of 17 (default + 16 escapes), followed by a 7 | # test use of that color on all nine background 8 | # colors (default + 8 escapes). 9 | # 10 | 11 | T='gYw' # The test text 12 | 13 | echo -e "\n 40m 41m 42m 43m\ 14 | 44m 45m 46m 47m"; 15 | 16 | for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' ' 32m' \ 17 | '1;32m' ' 33m' '1;33m' ' 34m' '1;34m' ' 35m' '1;35m' \ 18 | ' 36m' '1;36m' ' 37m' '1;37m'; 19 | do FG=${FGs// /} 20 | echo -en " $FGs \033[$FG $T " 21 | for BG in 40m 41m 42m 43m 44m 45m 46m 47m; 22 | do echo -en "$EINS \033[$FG\033[$BG $T \033[0m"; 23 | done 24 | echo; 25 | done 26 | echo 27 | -------------------------------------------------------------------------------- /bin/convert-to-twitter: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [ $# -ne 2 ]; then 5 | echo 'Usage: convert-to-twitter [input] [output]' 6 | exit 1 7 | fi 8 | 9 | ffmpeg -i "$1" -vcodec libx264 -vf 'scale=640:trunc(ow/a/2)*2' -acodec aac -vb 1024k -minrate 1024k -maxrate 1024k -bufsize 1024k -ar 44100 -strict experimental -r 30 "$2" 10 | -------------------------------------------------------------------------------- /bin/current-branch: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git branch | grep '*' | sed -e 's/* //' | tr -d '\n' 3 | -------------------------------------------------------------------------------- /bin/current-url: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | osascript -e ' 3 | tell application "System Events" 4 | set numSafari to count (every process whose name is "Safari") 5 | set numSafariTech to count (every process whose name is "Safari Technology Preview") 6 | set numChrome to count (every process whose name is "Google Chrome") 7 | end tell 8 | 9 | if numSafari > 0 then 10 | tell application "Safari" to get URL of front document 11 | else if numSafariTech > 0 then 12 | tell application "Safari Technology Preview" to get URL of front document 13 | else if numChrome > 0 then 14 | tell application "Google Chrome" to get URL of active tab of front window 15 | end if' | tr -d '\n' 16 | -------------------------------------------------------------------------------- /bin/docker-clean: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | docker ps -aqf status=exited | xargs docker rm 4 | docker images -qf dangling=true | xargs docker rmi 5 | -------------------------------------------------------------------------------- /bin/dokku: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "No local bin/dokku, using global" 3 | ssh -t dokku@hz1 $@ 4 | -------------------------------------------------------------------------------- /bin/enod: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | current_branch=$(git branch | grep '*' | sed -e 's/* //') 5 | 6 | if git branch | grep -q master; then 7 | main_branch='master' 8 | else 9 | main_branch='main' 10 | fi 11 | 12 | if [ $current_branch == $main_branch ]; then 13 | echo "Not destroying $main_branch" 14 | exit 1 15 | fi 16 | 17 | if [[ `git status --porcelain` != '' ]]; then 18 | echo 'Dirty branch, exiting' 19 | exit 1 20 | fi 21 | 22 | git checkout $main_branch 23 | 24 | git fetch --all --prune 25 | git pull origin $main_branch --rebase --autostash 26 | 27 | git br -D $current_branch 28 | -------------------------------------------------------------------------------- /bin/extract-cover-art.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | require 'taglib' 4 | rescue LoadError 5 | puts '$ [sudo] gem install taglib-ruby' 6 | raise 7 | end 8 | 9 | input = ARGV.shift 10 | raise "Missing filename" if input.nil? 11 | 12 | output = "#{File.basename(input)}.jpg" 13 | 14 | cover = TagLib::MPEG::File.open(input) do |mp3| 15 | mp3.id3v2_tag.frame_list('APIC').first.picture 16 | end 17 | 18 | File.open(output, 'wb') { |f| f << cover } 19 | 20 | puts "Wrote #{output}" 21 | -------------------------------------------------------------------------------- /bin/first-frame: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ffmpeg -i "$1" -vframes 1 -f image2 "${1%.mp4}.png" 3 | -------------------------------------------------------------------------------- /bin/gifsicle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikker/dotfiles/90ddb8665f409762cc31e9a9cd7343e425e19cc8/bin/gifsicle -------------------------------------------------------------------------------- /bin/gifv: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function printHelpAndExit { 4 | cat < 9 )) && level=9 # OR err 114 | (( $level < 1 )) && level=1 # OR err 115 | optimize="${levels[$level]}" 116 | 117 | # Direction options (for use with convert) 118 | direction_opt= 119 | if [[ "$direction" == "reverse" ]]; then 120 | direction_opt="-coalesce -reverse" 121 | elif [[ "$direction" == "alternate" ]]; then 122 | direction_opt="-coalesce -duplicate 1,-2-1" 123 | fi 124 | 125 | # TODO: Offer further optimizations 126 | # Contrast frame rate : -crf 22 127 | # Bit rate : -b:v 1000k 128 | 129 | # Codecs: 130 | # webm: libvpx 131 | # h.264: libx264 132 | codec="-c:v libx264" 133 | 134 | # Verbosity 135 | verbosity="-loglevel panic" 136 | 137 | # Create optimized GIF-like video 138 | if [[ "$direction" == 'reverse' ]] || [[ "$direction" == 'alternate' ]]; then 139 | ffmpeg $verbosity -i "$filename" -f image2pipe -vcodec ppm - | \ 140 | convert $direction_opt - ppm:- | \ 141 | ffmpeg $verbosity -f image2pipe -vcodec ppm -r 60 -i pipe: \ 142 | $codec $filter $fps -an -pix_fmt yuv420p \ 143 | -preset "$optimize" -movflags faststart "$output" 144 | else 145 | ffmpeg $verbosity -i "$filename" $codec $filter $fps -an -pix_fmt yuv420p \ 146 | -preset "$optimize" -movflags faststart "$output" 147 | fi 148 | 149 | # Cleanup 150 | if [ $cleanup ]; then 151 | rm "$filename" 152 | fi 153 | -------------------------------------------------------------------------------- /bin/hack: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | current_branch=$(git symbolic-ref HEAD --short) 5 | 6 | if git branch | grep -q master; then 7 | main_branch='master' 8 | else 9 | main_branch='main' 10 | fi 11 | 12 | git fetch --all --prune 13 | 14 | if [ $current_branch != $main_branch ]; then 15 | git checkout $main_branch 16 | fi 17 | 18 | git pull origin $main_branch --rebase=true --autostash 19 | 20 | if [ $current_branch != $main_branch ]; then 21 | git checkout $current_branch 22 | git rebase $main_branch --autostash 23 | fi 24 | -------------------------------------------------------------------------------- /bin/imgcat: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # tmux requires unrecognized OSC sequences to be wrapped with DCS tmux; 4 | # ST, and for all ESCs in to be replaced with ESC ESC. It 5 | # only accepts ESC backslash for ST. 6 | function print_osc() { 7 | if [[ $TERM == screen* ]] ; then 8 | printf "\033Ptmux;\033\033]" 9 | else 10 | printf "\033]" 11 | fi 12 | } 13 | 14 | # More of the tmux workaround described above. 15 | function print_st() { 16 | if [[ $TERM == screen* ]] ; then 17 | printf "\a\033\\" 18 | else 19 | printf "\a" 20 | fi 21 | } 22 | 23 | # print_image filename inline base64contents 24 | # filename: Filename to convey to client 25 | # inline: 0 or 1 26 | # base64contents: Base64-encoded contents 27 | function print_image() { 28 | print_osc 29 | printf '1337;File=' 30 | if [[ -n "$1" ]]; then 31 | printf 'name='`echo -n "$1" | base64`";" 32 | fi 33 | if $(base64 --version 2>&1 | grep GNU > /dev/null) 34 | then 35 | BASE64ARG=-d 36 | else 37 | BASE64ARG=-D 38 | fi 39 | echo -n "$3" | base64 $BASE64ARG | wc -c | awk '{printf "size=%d",$1}' 40 | printf ";inline=$2" 41 | printf ":" 42 | echo -n "$3" 43 | print_st 44 | printf '\n' 45 | } 46 | 47 | function error() { 48 | echo "ERROR: $*" 1>&2 49 | } 50 | 51 | function show_help() { 52 | echo "Usage: imgcat filename ..." 1>& 2 53 | echo " or: cat filename | imgcat" 1>& 2 54 | } 55 | 56 | ## Main 57 | 58 | if [ -t 0 ]; then 59 | has_stdin=f 60 | else 61 | has_stdin=t 62 | fi 63 | 64 | # Show help if no arguments and no stdin. 65 | if [ $has_stdin = f -a $# -eq 0 ]; then 66 | show_help 67 | exit 68 | fi 69 | 70 | # Look for command line flags. 71 | while [ $# -gt 0 ]; do 72 | case "$1" in 73 | -h|--h|--help) 74 | show_help 75 | exit 76 | ;; 77 | -*) 78 | error "Unknown option flag: $1" 79 | show_help 80 | exit 1 81 | ;; 82 | *) 83 | if [ -r "$1" ] ; then 84 | print_image "$1" 1 "$(base64 < "$1")" 85 | else 86 | error "imgcat: $1: No such file or directory" 87 | exit 2 88 | fi 89 | ;; 90 | esac 91 | shift 92 | done 93 | 94 | # Read and print stdin 95 | if [ $has_stdin = t ]; then 96 | print_image "" 1 "$(cat | base64)" 97 | fi 98 | 99 | exit 0 100 | -------------------------------------------------------------------------------- /bin/is-this-dark-mode: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | darkmode=`osascript -e 'tell application "System Events" to tell appearance preferences to get dark mode'` 3 | [[ $darkmode = 'true' ]] 4 | -------------------------------------------------------------------------------- /bin/itunes-feed.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # Gets the original feed url from an iTunes podcast page 4 | # 5 | # usage: 6 | # itunes-feed.rb URL 7 | # 8 | 9 | require 'open-uri' 10 | require 'json' 11 | 12 | feed = ARGV.shift 13 | 14 | if id = feed[/id(\d+)/, 1] 15 | url = "https://itunes.apple.com/lookup?id=#{id}&entity=podcast" 16 | json = JSON.parse(URI.open(url).read) 17 | print json['results'][0]['feedUrl'] 18 | end 19 | -------------------------------------------------------------------------------- /bin/killmouseaccel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikker/dotfiles/90ddb8665f409762cc31e9a9cd7343e425e19cc8/bin/killmouseaccel -------------------------------------------------------------------------------- /bin/last-commit-message: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | git --no-pager log -1 --pretty=%B \ 3 | | sed -e "s/^ *//g" -e "s/ *$//g" \ 4 | | perl -pe 'chomp if eof' 5 | -------------------------------------------------------------------------------- /bin/lock: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | /System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend 3 | -------------------------------------------------------------------------------- /bin/map.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | require 'exifr' 4 | rescue LoadError 5 | require 'rubygems' 6 | require 'exifr' 7 | end 8 | 9 | usage = <<-USAGE 10 | usage: map.rb IMAGE_PATH 11 | USAGE 12 | 13 | path = ARGV.shift 14 | 15 | if path.nil? 16 | puts usage 17 | exit(0) 18 | end 19 | 20 | exif = EXIFR::JPEG.new(path) 21 | if coords = exif.gps 22 | system "open 'http://maps.apple.com/?q=#{coords.latitude},#{coords.longitude}'" 23 | else 24 | puts "No GPS data for #{path}" 25 | end 26 | -------------------------------------------------------------------------------- /bin/multizip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | Dir["*.zip"].each { |file| 3 | `unzip -o "#{file}" && mv "#{file}" ~/.Trash` 4 | print "." 5 | } 6 | puts "" 7 | 8 | -------------------------------------------------------------------------------- /bin/myip: -------------------------------------------------------------------------------- 1 | dig +short myip.opendns.com @resolver1.opendns.com 2 | -------------------------------------------------------------------------------- /bin/notification: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# -eq 0 ]; then 4 | while read input; do 5 | osascript -e "display notification \"$input\" with title \"term\"" 6 | done 7 | else 8 | osascript -e "display notification \"$@\" with title \"term\"" 9 | fi 10 | 11 | -------------------------------------------------------------------------------- /bin/prep: -------------------------------------------------------------------------------- 1 | #!/bin/sh -x 2 | 3 | # Interactively rebase current branch against the relevant "master". 4 | # * If you're on master rebase against origin/master. 5 | # * If you're on any other local branch rebase against master 6 | # or a branch specified as an argument. 7 | 8 | set -e 9 | 10 | CURRENT=$(git branch | grep '\*' | awk '{print $2}') 11 | 12 | if git branch | grep -q master; then 13 | main_branch='master' 14 | else 15 | main_branch='main' 16 | fi 17 | 18 | if [ "$CURRENT" = "$main_branch" ]; then 19 | git rebase -i origin/$main_branch 20 | else 21 | if [ "$1" ]; then 22 | git rebase -i "$1" 23 | else 24 | git rebase -i $main_branch 25 | fi 26 | fi 27 | 28 | -------------------------------------------------------------------------------- /bin/prl: -------------------------------------------------------------------------------- 1 | #!/bin/sh -x 2 | 3 | set -e 4 | 5 | last_msg="$(last_commit_message)" 6 | 7 | git push -u 8 | 9 | url=$(hub pull-request -m "$last_msg") 10 | 11 | open "$url" 12 | 13 | -------------------------------------------------------------------------------- /bin/puny: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | begin 4 | require 'simpleidn' 5 | rescue LoadError 6 | puts "$ gem install simpleidn" 7 | raise 8 | end 9 | 10 | print SimpleIDN.to_ascii(ARGV.any? ? ARGV.join(' ') : STDIN.read.to_s.chomp) 11 | -------------------------------------------------------------------------------- /bin/random5da: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | puts DATA.read.split.sample 4 | 5 | __END__ 6 | abbed abede abort acces adept advis aedes aende aerob afart afasi afbud afgav afhop afise afkod afkog afled aflyd afrev afryd afsat afson aftag aften aftes aftne afvej afvis agape agave agede agens agent agere agern agnat agnen agoni agora agraf agrar agtet agurk ahorn ajour akryl aksel aktie aktiv aktor alarm albue album alder alene alert algod alhus alias alibi alkyd almue alrum altan alter altid altre alvor ambra amorf amour ampel ampul anale andel anden andet andre angav anger angle anion anjon anker ankre annal annua anode anset antal antik aorta apati apeks appel april apsis areal arena arens argon argot arier arkiv armod aroma arpet arrak arrig arsen arses arsis artig asede asiat asket aspic astma atlas atlet atoni attak atten atter audit augur autor avind avler 7 | bacon badge badut bager bagom bajer bakke bakse balde balje bamle bamse banan bange banjo banke banko bantu barak barbe barde baron barre baryl baryt basal basar basis baske basse basta baste basun batat batch batik batte bebud bedre befor befri begge behag behov beige bejae bejle beryl besat besku betel betle beton betro bevar bevis biavl bibel bidet bidte bifag bifil bigot bijob bikse bilag bilde biled bille bilyd bimle bimse bingo bioer biord bippe birum bisag bisam bisol bison bisse bitre bivej bizar bjerg bjesk blade blase blege blegn blend blink blive blond blote blues bluff blund bluse bobbe boble bodel bodil boede boere bogie bojan bojar bokse bolig bolle bolte bombe bomme bonde bonus booke borde borst borte bovne bowle boxer brage bragt brand brase brask bravo break brede bredt brems briks bring brink brint brise brist brite brudt bruge brugs brugt brune bruse brusk bryde brysk bryst buggy bugne bugte buhko buket bukke bukle bulke bulme bulne bumle bumpe bumse bunde bunke burde buret burre buske buste butan butik bybud bybus bydel byder bygas bygge bynke byret byste bytte 8 | ceder celle cello cerut charm check chili cider cifre cigar cirka citar citat civil clips coate conga coupe crack crazy credo creme crepe curie cutte cykel cykle cyste 9 | dadel dadle dalbo daler dalre dampe danbo dandy daner danne danse dansk daske datid dativ david davre debat debet debil debut decca decim deger deist dejse dekan dekor delen deler deles delle delta denar denim dente depot deraf derby deres desto devon devot diare dible digel diger digte dikke dildo dille dinar dingo diode dipol dirke diset diske disse ditto divan doble dogme dokke dolce dolke dolme donna donor dorer dorge dorne dosis douce doven dovne doyen dozer drage dragt drama drapa dreje drejl dreng dress drift drink drive drone drost drude dubbe duble duede dugge dukat dukke dulle dulme dumme dummy dumpe dunke dunst dunte duplo duppe duren dusin duske dutte dvale dybde dybel dybet dynge dyppe dyret dyrke dysse dyste dytte dyvel 10 | eclat eddas edder edikt effen efter egern eksem eksil elbil elegi elgko elite eller elske elver elvte emacs emsig endda ender endnu endog enere engel enhed enige enkle enrum ensom ental entre enzym eolit episk epoke epope epoxy erika erobr esrom essay essig ester etage etape etisk ettal etter etude eunuk evert evige exces 11 | fabel fable facet facil facit facon facts fader fager fagot fagre fakir fakta falde falds falle falme false famle fandt fange farad farao farce faren farin farsi farte farve fasan faste fatte fauna favne feber fedme fejde fejle fejre femte femti fenne fenol fenyl ferie ferle ferme fersk feset feste fiber fichu ficus fidel fidus fiffe fifle figen fight figur fikse filet filme filte filur fimre fimse final finer finit finke finte firer firma firme firti fiske fisse fiste fjant fjase fjeld fjert fjols fjong fjord flage flair flane flash flere flest flige flire flirt flora flove fluat flugt fluid fluks fluor flute flyde flyer flyes flyve fnise fnyse foder fodre foged fokus folde folie folio fonde fonem fonte foran forbi force fordi forel forme forne forny forse forsk forte forum fosse foton foyer franc frank frase frede frels freon frier friet front frost frugt fryde fryse fulde fumle funke fuppe furie fusel fuser fuske futil futte fylde fylke fynbo fyrig fyrre fysik fytin 12 | gabte gades gafle galan galar galde galej galge galla galle galon galop galpe gambe gamin gamma gange garde garve gasse gauge gavne geare gebet gebis gebyr gejle gejst gekko geled gemak gemal gemme gemse gemte gemyt genbo gener genne genom genre gense genua genus gerne gevir gibbe gifte gigue gilde gimpe gipse giraf gisne gispe gitov gitre given giver gives givet givne gjald gjord gjort glade glane glans glibe glide glime glimt globe glose gnave gnejs gnide gnier gnome godte gokke golde gople goter gotik gouda grade grand grave green grene gribe grill grime grind grine grise grisk groet groft grove grube grund gruse gryde grynt guano guava gubbe guffe gufle guide gulne gumle gumme gummi gunst guppy gylle gylpe gynge gytje gyvel 13 | habil habit hacke hagle haiku hakke halet hallo halma halon halse halte halve hamit hamle hamre handy hanke hapse hapss harem harke harme harpe harpy harve haspe haste hausa havde haver havne havre heade heavy hedde hegle hegne heile hejre hejsa hejse hekse helme helse henad henna henne henry hense hente heppe heraf herme herre herse hersk herte hertz herut hetze hevet hidse hikke hilde hille hilse himle hinde hindi hindu hinke hippe hirse hisse hitte hiver hjald hjalp hjelm hjord hjort hobby hofte holde hopla hoppe hopsa horde horet horst hotel hotte house hoved hoven hovne hovsa hudre hugaf hugge hugst hulke humle humme humor humpe humus hurra husar huske husly hutle hutre hvalp hvede hvene hveps hverv hvile hvine hvori hybel hydra hygge hykle hylde hyler hylle hymen hymne hynde hyppe hyrde hysse hytte 14 | ideal ideel idiom idiot ihjel ikkun ikten ilbud ilder ildhu ildne iling ilsom iltog image imens immer indbo inden inder indre indse inert infam ingen input intet intro inuit irisk ironi irske isbod isfri ishav ising islag islam islom issyl istap ister istid istme 15 | jaden jager jaget jagte jaket jakke jambe jamen jamme jamre jante jappe jaske javel jazze jeans jenka jente jeres jeton jobbe jodle jogge joint joker jokke jolle jolre jorde joule jubel juble judas juice jumbe jumbo jumpe junge junke junta juvel jyske 16 | kabel kable kabys kadet kadre kaffe kagle kahyt kajak kakao kalas kalde kalif kalke kalla kalot kamel kamik kamin kamme kampe kamre kanal kande kanel kanin kanon kante kanut kapel kaper kapok kappe kapre kapun kaput karak karat karet kargo karma karpe karre karry karse karsk karte karve kasak kasko kasse kaste kasts kasus katar kavaj kebab kedel kefir kegle kejse kejte kelim kende kendt kerne kerte kerub ketch ketle keton khmer kigge kilde kimse kinin kinke kiosk kippe kirke kisel kiste kitin kitte kives kjole kjove klage klang klare klase klask klejn klemt klerk klima kline kling klint klire kloak klode kloge klogt klone klore klovn klump klyde klynk knark knarr knase knast knibe knirk knobe knold knort knude knuge knuse knyst koala koben koble kobra kofte kogge kogle koket kokke kokon kokos kokse kolbe kolde kolik kolli kolon kolos komet komik komma komme kondi konge konti konto konus kopar kopek kopis kopra koral koran korde korne korps korse korso korte kosak koste kraal krads kraft krage krank kravl kreol kreti krige krimi kroat kroge kroki krone krudt kruse krybe kryds krypt kubik kubus kugle kujon kukke kukur kulak kulos kulso kumme kunde kunne kunst kuple kupon kuppe kurer kurie kurre kurve kusse kutte kvaje kvark kvart kvase kvast kvide kvist kvota kvote kybel kymre kyras kyrie kysse 17 | laban labbe label laber labil lagde lagen lagre lakaj lalle lamel lamme lampe lande lange langt lanse lapin lapis lappe lapse lapsk large largo larme larve laser laset laske lasso laste lasur latex latin lease leben ledig ledte lefle legat legio lejde lejer lejre lemma lempe lemur lento leret letal lette levet levit levne levre lidse liere ligge light ligne lilje lilla lille limbo limit linde linje linse lirke lisen liste liter litra livre lobbe lobby lodse logge logik logre lokal lokke lokum lomme longe loope loppe loran loren losse lotte lotto lotus loyal lubbe luder ludes luffe lufte lugar lugte lukaf lukke lulle lumen lumpe lumre lunch lunge lunke lunte lupin luppe lupus lurer luske lutre lybsk lyden lydig lygte lykke lymfe lynne lyrik lyske lysne lyste lytte 18 | macho macon mafia mager magma magre magte major makke makro malaj maler malet malke malle malte mambo mande maner manga mange mango manke manko manna manne manus maori mappe march maren marin marsk marve maske masse maste masut match medes media medie medio megen meget mejse mekka melde melon mened merit merle mesan meson messe meste metal metan meter metra metre metro metyl mezzo miave midje midte midti milde mille mimik mimre minde minus minut miste mitra mitte mjave mobbe mobil modal model modem modne modul modus moire mokka mokke molbo moles molok monne moppe moral morel morse moske mosle moste motel motet motiv motor motto mudre muffe mufle mufti mugge mugne muhko mukke mulat mulig mulkt mulle mumie mumle munde murer murre musik muzak mynde mynte myose myrde myrra myrte mysli 19 | nabob nadir nafta nagle naive nakke nappa nappe narre narve nasal nasse natte natur naver navle nazis nedad neden nedom nedre neger negle nemme nerie nertz nerve netop nette netto nevet niche nidsk niece nikke nippe nipse nisse nital nitid nitte nobel noble nogen noget nogle nokke nomen nonne noppe nopre norne nosse nubre nudel nulre nulte numse nuppe nurse nusle nusse nutid nuvel nyere nyhed nylon nymfe nynne nysne nysyn nytid nytte 20 | oblat oblik ocean odden okapi okker oktan oktav oktet olden olymp ombud omega omegn omlyd omsat omvej onani onkel onyks opart opbud opdag opera opfej opgav ophav opiat opium oplag oplod oprik opsyn optog optur ordne ordre organ orgel orgie orkan orkis orlon orlov ornat oscar osman otium otter ounce oveni 21 | padde padle paffe pagaj paket pakis pakke palet palle palme pampa panda pande panik pante panty papil papir pappe paria parka parre parti party paryk pasha passe pasta pater patio patos patte pauke peber pebet pebre pedal pedel peget pejle pelse pence penge penis penny pensa peppe perle perse petit pette piano pible piffe pifte pigge pikke pilaf pilen pilke pille pilot pimpe pinde pinje pinol pinse pinup pippe pique pirat pirke pirog pirol pirre piske pisse piver pivot pixel pizza pjalt pjece pjevs plade plads plage plaid plane plano plebs pleje plejl pleti pligt plint plire poesi point poise pokal poker polak polar polet polio polka polyp pomet ponto poppe porno porre porte porto poste posts poten power pragt praje prale prate prent prima prime primo prior prise prosa provo prunk prust pryde psyke puden pudre pudse puffe pukke pukle pulje pulle pulse pumpe punch punge punkt pupil puppe purre purse pusle puste putte pylre pynte pyton 22 | rabat rabbi rable racen radar radio radix radon rafte rager rajah raket rakke rakle rakte ralle rally ramle ramme rampe ramte ranch rande randt range ranke rapid rapse rasle raspe raste rasur ratio rayon rebel rebus reces redde reden redte regel regne rejfe rejse rejst rekyl remse rende rense repos retor rette retur reven revet revir revle revne revse ribbe rider ridse rigel rigge rigid rigle rille rimet rimpe rimte rinde ringe rinke rippe risle rispe riste ritus rival river robot rocke rodeo rokke rolig rolle roman rombe romer rommy rondo roret rosin roste rotor rotte rouge rover rovse royal rubbe rubel rubin ruche rudel ruden rufle rugby rulam rulle rumba rumle rumme rumpe runde runge rural ruser ruske ruste ruten rutsj rutte rydde rygge rygte rykke rynke ryste rytme 23 | sabel sable sadel sadhu sadle safir safte sagde sager sagte sakke sakse salat saldo salep salig salme salon salpe salsa salto salut salve samba sambo samle samme samsk sande sanke sanse satan satin satse satte satyr sauce sauna savle savne scene scoop score sedan sedes seede seere segle segne sejle sejre sejse sekel selve semit senat sende senen sener senil sepia seraf serge serie serum serve sesam sexet sheik shiit shine shunt siben sidde sider sides sidse sifon sigel sigma signe sigte sikke sikre silde silke silur simle simre simse sinde sinke sinus sioux sippe sirat sirup sisal sitar siven sjavs sjove sjuft skabe skade skage skakt skala skalp skank skarn skarv skave skede skeje skejs skele skema skete skibe skide skidt skind skive skole skose skrab skred skreg skrev skrig skrin skrog skrud skrue skude skudt skule skure skurk skurv skvat skyde skyet skyts slags slant slave slibe slide slime slisk slude sluge slurk sluse smage smart smide smile smock smovs smule smyge snack snage snare sneet snegl snige snive snude snuse snusk snyde sober sogne soire solde solgt solur somme sonar sonde sonet sonor soppe sorte sound sovse spand spare spege spejl spelt sperm spile spind spion spire spise spore sport spove sprak sprit sprog spryd spule spurv squaw stade stage stald stamp stand stank start stase stave stavn steak stege stele stemt stene stige stile stilk stime stind sting stive stjal stola stole storm story stose stovt stred streg strik stuen stunt stuve styne styre suder sudle suger suite sujet sukat sukke sukre sulfo sulky sulte sumak summe sumpe sunde super suppe surfe surre sushi sutte sutur svada svage svaje svamp svane svang svare svede svend svide svige svime svine sving svire sydom syere sygne sylfe sylte synde synge synke synsk syren syrne sysle syver syvti 24 | tabel taber tabte tager taget tajga takke takle taksi takst talar talen talon talte tamil tampe tande tanga tange tango tanke tante tapir tappe tarif tarok tarse taske tatar tater tavle tavse taxie tazet tegne teint teist tejne tejst tekno tekop tekst tempi tempo tenor teori terme terne terpe terre tesen tesis teske teste teten thybo tiara tiere tiest tiger tigge tikke tilse tilte timid tinde tinge tinte tippe tirre tiske tisse tital titan titel titte tjald tjalk tjans tjene toast tobak tobis toddy tofte toget tolde tolke tomat tomle tomme tonal tonen toner tonic topas toppe topti torne torsk torso torve tosse totem totne totte totur toupe trake trang trave treer trema treti trias trick trind trine triol trist trivi trold trone trope truck trust trykt tryne tuben tudse tugte tukan tulle tulre tumle tumor tunge turbo turde turne tusch tuske tusse tutor tutte tutti tvang tvebo tvege tvine tvist tvivl tweed twill twist tyder tyfon tyfus tygge tykne tylle tylvt tynde tynge tyran tyren tyske tysse tyste tyvte 25 | ublid udbud udelt udfri udhus udkik udlyd udspy udsyn udtur uenig ufiks ufred ugift uheld uhyre uland ulave ulden uldne ulige ulyst umage umbra undre undse unika union unode urban urede ureel urkok urnen urrem urtid urund usand ussel utide uting utopi uvorn 26 | vabel vable vades vakle vakte valen valgt valid valke valle valme valse valsk valte vandt vange vanke vanry vante varan varde varia varig varme varpe varte varyl vasal vaske vater vatre vedet veget vegne vejen vejle vejre velan velar velin vemod vende vendt verfe verpe verve vesir vetoe viben vidde viden video vidje vidne vifte vigen vigte vikar vikke vikle vikse vilde vilje villa ville vimre vimse vinca vinde vinge vinke vinyl viola vippe virak viril virke virre virus visen viser visir visit viske visne visse viste visum vivat vlies vodka vogte voila voile vokal vokse volde voldt volfe volte volut vorde vorte votum vovse vrage vrede vride vugge vulst vunde vuppe vupti vyets 27 | wagon whist 28 | xenon 29 | yacht yatzy yngel yngle yngre yngst ypern yppig 30 | zambo zappe zebra zefyr zelot zenit zloty zobel zombi zoome zweck 31 | -------------------------------------------------------------------------------- /bin/refresh-os: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | curl -f --silent "https://api.opensea.io/api/v1/asset/$1/$2/?force_update=true" -H "X-API-KEY: $OPENSEA_API_KEY" 3 | -------------------------------------------------------------------------------- /bin/reload-chrome: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | osascript -e ' 3 | tell application "Google Chrome" 4 | tell the active tab of its first window 5 | reload 6 | end tell 7 | end tell 8 | ' 9 | -------------------------------------------------------------------------------- /bin/reload-firefox: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | osascript -e ' 3 | tell application "Firefox" 4 | activate 5 | delay 0.1 6 | tell application "System Events" to keystroke "r" using command down 7 | delay 0.1 8 | tell application "System Events" 9 | key down command 10 | keystroke tab 11 | key up command 12 | end tell 13 | end tell' 14 | -------------------------------------------------------------------------------- /bin/reload-firefox-dev: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | osascript -e ' 3 | tell application "Firefox Developer Edition" 4 | activate 5 | delay 0.5 6 | tell application "System Events" to keystroke "r" using command down 7 | end tell' 8 | -------------------------------------------------------------------------------- /bin/reload-firefox-nightly: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | osascript -e ' 3 | tell application "Firefox Nightly" 4 | activate 5 | delay 0.1 6 | tell application "System Events" to keystroke "r" using command down 7 | delay 0.1 8 | tell application "System Events" 9 | key down command 10 | keystroke tab 11 | key up command 12 | end tell 13 | end tell' 14 | -------------------------------------------------------------------------------- /bin/reload-safari: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # -- version 1 -- 4 | # Setting the current url to the itself 5 | # Has trouble with not really refreshing caches 6 | 7 | # osascript -e ' 8 | # tell application "Safari" 9 | # set sameURL to URL of current tab of front window 10 | # set URL of current tab of front window to sameURL 11 | # end tell 12 | # ' 13 | 14 | # -- version 2 -- 15 | # Activate then send cmd+r 16 | # Too slow and annoying to loose focus 17 | 18 | # osascript -e ' 19 | # tell application "Safari" 20 | # activate 21 | # delay 0.5 22 | # tell application "System Events" to keystroke "r" using command down 23 | # end tell' 24 | 25 | # version 3 - using js 26 | # Reload by sending js command 27 | osascript -e ' 28 | tell application "Safari" 29 | tell window 1 30 | do JavaScript "window.location.reload(true)" in current tab 31 | end tell 32 | end tell 33 | ' > /dev/null 34 | -------------------------------------------------------------------------------- /bin/rm_dsstore: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | find . -name .DS_Store -ls -exec rm {} \; -------------------------------------------------------------------------------- /bin/slug: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | print(ARGV.join(" ").downcase.gsub(/[^a-z0-9]/, "-")) 3 | -------------------------------------------------------------------------------- /bin/sort-Xcode-project-file: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions 7 | # are met: 8 | # 9 | # 1. Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # 2. Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15 | # its contributors may be used to endorse or promote products derived 16 | # from this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | # Script to sort "children" and "files" sections in Xcode project.pbxproj files 30 | 31 | use strict; 32 | 33 | use File::Basename; 34 | use File::Spec; 35 | use File::Temp qw(tempfile); 36 | use Getopt::Long; 37 | 38 | sub sortChildrenByFileName($$); 39 | sub sortFilesByFileName($$); 40 | 41 | # Files (or products) without extensions 42 | my %isFile = map { $_ => 1 } qw( 43 | create_hash_table 44 | jsc 45 | minidom 46 | testapi 47 | testjsglue 48 | ); 49 | 50 | my $printWarnings = 1; 51 | my $showHelp; 52 | 53 | my $getOptionsResult = GetOptions( 54 | 'h|help' => \$showHelp, 55 | 'w|warnings!' => \$printWarnings, 56 | ); 57 | 58 | if (scalar(@ARGV) == 0 && !$showHelp) { 59 | print STDERR "ERROR: No Xcode project files (project.pbxproj) listed on command-line.\n"; 60 | undef $getOptionsResult; 61 | } 62 | 63 | if (!$getOptionsResult || $showHelp) { 64 | print STDERR <<__END__; 65 | Usage: @{[ basename($0) ]} [options] path/to/project.pbxproj [path/to/project.pbxproj ...] 66 | -h|--help show this help message 67 | -w|--[no-]warnings show or suppress warnings (default: show warnings) 68 | __END__ 69 | exit 1; 70 | } 71 | 72 | for my $projectFile (@ARGV) { 73 | if (basename($projectFile) =~ /\.xcodeproj$/) { 74 | $projectFile = File::Spec->catfile($projectFile, "project.pbxproj"); 75 | } 76 | 77 | if (basename($projectFile) ne "project.pbxproj") { 78 | print STDERR "WARNING: Not an Xcode project file: $projectFile\n" if $printWarnings; 79 | next; 80 | } 81 | 82 | # Grab the mainGroup for the project file 83 | my $mainGroup = ""; 84 | open(IN, "< $projectFile") || die "Could not open $projectFile: $!"; 85 | while (my $line = ) { 86 | $mainGroup = $2 if $line =~ m#^(\s*)mainGroup = ([0-9A-F]{24} /\* .+ \*/);$#; 87 | } 88 | close(IN); 89 | 90 | my ($OUT, $tempFileName) = tempfile( 91 | basename($projectFile) . "-XXXXXXXX", 92 | DIR => dirname($projectFile), 93 | UNLINK => 0, 94 | ); 95 | 96 | # Clean up temp file in case of die() 97 | $SIG{__DIE__} = sub { 98 | close(IN); 99 | close($OUT); 100 | unlink($tempFileName); 101 | }; 102 | 103 | my @lastTwo = (); 104 | open(IN, "< $projectFile") || die "Could not open $projectFile: $!"; 105 | while (my $line = ) { 106 | if ($line =~ /^(\s*)files = \(\s*$/) { 107 | print $OUT $line; 108 | my $endMarker = $1 . ");"; 109 | my @files; 110 | while (my $fileLine = ) { 111 | if ($fileLine =~ /^\Q$endMarker\E\s*$/) { 112 | $endMarker = $fileLine; 113 | last; 114 | } 115 | push @files, $fileLine; 116 | } 117 | print $OUT sort sortFilesByFileName @files; 118 | print $OUT $endMarker; 119 | } elsif ($line =~ /^(\s*)children = \(\s*$/) { 120 | print $OUT $line; 121 | my $endMarker = $1 . ");"; 122 | my @children; 123 | while (my $childLine = ) { 124 | if ($childLine =~ /^\Q$endMarker\E\s*$/) { 125 | $endMarker = $childLine; 126 | last; 127 | } 128 | push @children, $childLine; 129 | } 130 | if ($lastTwo[0] =~ m#^\s+\Q$mainGroup\E = \{$#) { 131 | # Don't sort mainGroup 132 | print $OUT @children; 133 | } else { 134 | print $OUT sort sortChildrenByFileName @children; 135 | } 136 | print $OUT $endMarker; 137 | } else { 138 | print $OUT $line; 139 | } 140 | 141 | push @lastTwo, $line; 142 | shift @lastTwo if scalar(@lastTwo) > 2; 143 | } 144 | close(IN); 145 | close($OUT); 146 | 147 | unlink($projectFile) || die "Could not delete $projectFile: $!"; 148 | rename($tempFileName, $projectFile) || die "Could not rename $tempFileName to $projectFile: $!"; 149 | } 150 | 151 | exit 0; 152 | 153 | sub sortChildrenByFileName($$) 154 | { 155 | my ($a, $b) = @_; 156 | my $aFileName = $1 if $a =~ /^\s*[A-Z0-9]{24} \/\* (.+) \*\/,$/; 157 | my $bFileName = $1 if $b =~ /^\s*[A-Z0-9]{24} \/\* (.+) \*\/,$/; 158 | my $aSuffix = $1 if $aFileName =~ m/\.([^.]+)$/; 159 | my $bSuffix = $1 if $bFileName =~ m/\.([^.]+)$/; 160 | if ((!$aSuffix && !$isFile{$aFileName} && $bSuffix) || ($aSuffix && !$bSuffix && !$isFile{$bFileName})) { 161 | return !$aSuffix ? -1 : 1; 162 | } 163 | return lc($aFileName) cmp lc($bFileName); 164 | } 165 | 166 | sub sortFilesByFileName($$) 167 | { 168 | my ($a, $b) = @_; 169 | my $aFileName = $1 if $a =~ /^\s*[A-Z0-9]{24} \/\* (.+) in /; 170 | my $bFileName = $1 if $b =~ /^\s*[A-Z0-9]{24} \/\* (.+) in /; 171 | return lc($aFileName) cmp lc($bFileName); 172 | } 173 | -------------------------------------------------------------------------------- /bin/tat: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Attach or create tmux session named the same as current directory. 4 | 5 | path_name="$(basename "$PWD" | tr . -)" 6 | session_name=${1-$path_name} 7 | 8 | not_in_tmux() { 9 | [ -z "$TMUX" ] 10 | } 11 | 12 | session_exists() { 13 | tmux list-sessions | sed -E 's/:.*$//' | grep -q "^$session_name$" 14 | } 15 | 16 | create_detached_session() { 17 | (TMUX='' tmux new-session -Ad -s "$session_name") 18 | } 19 | 20 | create_if_needed_and_attach() { 21 | if not_in_tmux; then 22 | tmux new-session -As "$session_name" 23 | else 24 | if ! session_exists; then 25 | create_detached_session 26 | fi 27 | tmux switch-client -t "$session_name" 28 | fi 29 | } 30 | 31 | create_if_needed_and_attach 32 | -------------------------------------------------------------------------------- /bin/unecm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikker/dotfiles/90ddb8665f409762cc31e9a9cd7343e425e19cc8/bin/unecm -------------------------------------------------------------------------------- /bin/untilfail: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | while "$@"; do :; done 3 | -------------------------------------------------------------------------------- /brew/Brewfile.symlink: -------------------------------------------------------------------------------- 1 | # vim: set ft=ruby 2 | 3 | brew "asdf" 4 | brew "curl" 5 | brew "dark-mode" 6 | brew "fd" 7 | brew "ffmpeg" 8 | brew "fzf" 9 | brew "gh" 10 | brew "git" 11 | brew "jq" 12 | brew "lazygit" 13 | brew "libpq" 14 | brew "llm" 15 | brew "mas" 16 | brew "mosh" 17 | brew "node" 18 | brew "oven-sh/bun/bun" 19 | brew "pinentry-mac" 20 | brew "postgresql@16", link: true 21 | brew "qmk/qmk/qmk" 22 | brew "redis" 23 | brew "ripgrep" 24 | brew "rubyfmt" 25 | brew "s3cmd" 26 | brew "ssh-copy-id" 27 | brew "stripe/stripe-cli/stripe" 28 | brew "tmux" 29 | brew "tree" 30 | brew "vim" 31 | brew "vips" 32 | brew "wget" 33 | brew "yarn" 34 | brew "yt-dlp" 35 | brew "zsh" 36 | 37 | brew "neovim", args: ["head"] 38 | 39 | tap "homebrew/services" 40 | 41 | cask_args appdir: "/Applications" 42 | 43 | cask "acorn" 44 | cask "appzapper" 45 | cask "battery-buddy" 46 | cask "cleanshot" 47 | cask "cursor" 48 | cask "dash" 49 | cask "docker" 50 | cask "dropshare" 51 | cask "firefox" 52 | cask "google-chrome" 53 | # cask "gpg-suite" # download from https://gpgtools.org/sequoia 54 | cask "grandperspective" 55 | cask "handbrake" 56 | cask "imageoptim" 57 | cask "jordanbaird-ice" 58 | cask "monitorcontrol" 59 | cask "notion" 60 | cask "obs" 61 | cask "raycast" 62 | cask "signal" 63 | cask "sketch" 64 | cask "slack" 65 | cask "soulver" 66 | cask "superduper" 67 | cask "telegram" 68 | cask "transmission" 69 | cask "transmit" 70 | cask "vimr" 71 | cask "vlc" 72 | cask "wezterm@nightly" 73 | 74 | cask "font-fantasque-sans-mono" 75 | cask "font-fira-code" 76 | cask "font-ia-writer-mono" 77 | cask "font-ia-writer-duo" 78 | cask "font-ia-writer-quattro" 79 | cask "font-inconsolata" 80 | cask "font-input" 81 | cask "font-inter" 82 | cask "font-iosevka" 83 | cask "font-iosevka-aile" 84 | cask "font-iosevka-curly" 85 | cask "font-iosevka-curly-slab" 86 | cask "font-iosevka-etoile" 87 | cask "font-iosevka-slab" 88 | cask "font-iosevka-nerd-font" 89 | cask "font-sf-compact" 90 | cask "font-sf-mono" 91 | cask "font-sf-pro" 92 | cask "font-victor-mono" 93 | 94 | mas "1Password for Safari", id: 1569813296 95 | mas "Crouton", id: 1461650987 96 | mas "Developer", id: 640199958 97 | mas "Final Cut Pro", id: 424389933 98 | mas "Gifski", id: 1351639930 99 | mas "HEIC Converter", id: 1294126402 100 | mas "Hand Mirror", id: 1502839586 101 | mas "Hyperduck", id: 6444667067 102 | mas "JSONPeep", id: 1458969831 103 | mas "LilyView", id: 529490330 104 | mas "Logic Pro", id: 634148309 105 | mas "Marked 2", id: 890031187 106 | mas "N10", id: 6446053304 107 | mas "Numbers", id: 409203825 108 | mas "Pixelmator Pro", id: 1289583905 109 | mas "Plain Text Editor", id: 1572202501 110 | mas "Pure Paste", id: 1611378436 111 | mas "Reeder", id: 1529448980 112 | mas "Sprinkles", id: 1500209074 113 | mas "TestFlight", id: 899247664 114 | mas "Things", id: 904280696 115 | mas "Today", id: 6443714928 116 | mas "Velja", id: 1607635845 117 | mas "Xcode", id: 497799835 118 | mas "iA Writer", id: 775737590 119 | -------------------------------------------------------------------------------- /cursor/mac.sh: -------------------------------------------------------------------------------- 1 | # Copy settings.json to Cursor 2 | mkdir -p ~/Library/Application\ Support/Cursor/User 3 | ln -s ~/.dotfiles/cursor/settings.json ~/Library/Application\ Support/Cursor/User/settings.json 4 | -------------------------------------------------------------------------------- /cursor/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[typescript]": { 3 | "editor.defaultFormatter": "esbenp.prettier-vscode" 4 | }, 5 | "breadcrumbs.enabled": false, 6 | "debug.console.fontSize": 14, 7 | "editor.accessibilitySupport": "off", 8 | "editor.defaultFormatter": "esbenp.prettier-vscode", 9 | "editor.fontFamily": "\"Iosevka Nerd Font\"", 10 | "editor.fontSize": 16, 11 | "editor.fontWeight": "normal", 12 | "editor.stickyScroll.enabled": false, 13 | "editor.wordWrap": "on", 14 | "git.openRepositoryInParentFolders": "never", 15 | "github.copilot.advanced": {}, 16 | "github.copilot.enable": { 17 | "*": true, 18 | "markdown": false, 19 | "plaintext": false, 20 | "scminput": false 21 | }, 22 | "javascript.updateImportsOnFileMove.enabled": "always", 23 | "lldb.launch.expressions": "native", 24 | "lldb.library": "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB", 25 | "lldb.suppressUpdateNotifications": true, 26 | "ruby.format": "rubyfmt", 27 | "terminal.integrated.fontSize": 16, 28 | "terminal.integrated.sendKeybindingsToShell": true, 29 | "testing.followRunningTest": true, 30 | "testing.defaultGutterClickAction": "run", 31 | "testing.openTesting": "neverOpen", 32 | "testing.showTerminalWhenTestsStart": true, 33 | "testing.alwaysRevealTestOnStateChange": true, 34 | // "testing.gutterEnabled": false, 35 | "typescript.updateImportsOnFileMove.enabled": "always", 36 | "vim.leader": " ", 37 | "vim.normalModeKeyBindings": [ 38 | { 39 | "before": ["", "j"], 40 | "commands": ["workbench.action.files.save"] 41 | }, 42 | { 43 | "before": ["", "q"], 44 | "commands": ["workbench.action.togglePanel"] 45 | }, 46 | { 47 | "before": ["", "f", "f"], 48 | "commands": ["workbench.action.quickOpen"] 49 | }, 50 | { 51 | "before": ["[", "d"], 52 | "commands": ["editor.action.marker.prev"] 53 | }, 54 | { 55 | "before": ["]", "d"], 56 | "commands": ["editor.action.marker.next"] 57 | }, 58 | { 59 | "before": ["", ""], 60 | "commands": ["workbench.action.openPreviousRecentlyUsedEditor"] 61 | }, 62 | { 63 | "before": [""], 64 | "commands": ["testing.reRunLastRun"], 65 | "modes": ["normal"] 66 | }, 67 | { 68 | "before": ["", "t", "t"], 69 | "commands": ["testing.runAtCursor"] 70 | }, 71 | { 72 | "before": ["", "t", "T"], 73 | "commands": ["testing.runCurrentFile"] 74 | }, 75 | { 76 | "before": ["", "t", "a"], 77 | "commands": ["testing.runAll"] 78 | }, 79 | { 80 | "before": ["", "s", "g"], 81 | "commands": ["workbench.action.findInFiles"] 82 | }, 83 | { 84 | "before": ["", "s", "w"], 85 | "commands": ["extension.searchUnderCursor"] 86 | }, 87 | { 88 | "before": ["-"], 89 | "commands": ["workbench.view.explorer"], 90 | "modes": ["normal"] 91 | }, 92 | { 93 | "before": ["", "b", "r"], 94 | "commands": ["sweetpad.build.launch"] 95 | } 96 | ], 97 | "window.autoDetectColorScheme": true, 98 | "window.commandCenter": false, 99 | "window.customTitleBarVisibility": "never", 100 | "window.systemColorTheme": "auto", 101 | "workbench.activityBar.location": "hidden", 102 | "workbench.activityBar.orientation": "vertical", 103 | "workbench.colorTheme": "Spinel", 104 | "workbench.iconTheme": "vs-minimal", 105 | "workbench.preferredDarkColorTheme": "Zenbones Zenwritten Dark", 106 | "workbench.preferredHighContrastLightColorTheme": "Zenbones Light", 107 | "workbench.preferredLightColorTheme": "Zenbones Zenwritten Light", 108 | "rubyLsp.formatter": "rubyfmt", 109 | "rubyLsp.rubyVersionManager": { 110 | "custom": { 111 | "identifier": "mise" 112 | } 113 | }, 114 | "testing.automaticallyOpenTestResults": "neverOpen", 115 | "[ruby]": { 116 | "editor.defaultFormatter": "Shopify.ruby-lsp", // Use the Ruby LSP as the default formatter 117 | "editor.formatOnSave": true, // Format files automatically when saving 118 | "editor.tabSize": 2, // Use 2 spaces for indentation 119 | "editor.insertSpaces": true, // Use spaces and not tabs for indentation 120 | "editor.semanticHighlighting.enabled": true, // Enable semantic highlighting 121 | "editor.formatOnType": true // Enable formatting while typing 122 | }, 123 | "vim.enableNeovim": true, 124 | "vim.neovimPath": "/opt/homebrew/bin/nvim", 125 | "vim.neovimUseConfigFile": true, 126 | "[erb]": { 127 | "editor.defaultFormatter": "elia.erb-formatter" 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /git/gitconfig.symlink: -------------------------------------------------------------------------------- 1 | ; vim: set ft=gitconfig 2 | [user] 3 | name = Mikkel Malmberg 4 | email = mikkel@brnbw.com 5 | signingkey = 7B09867145A39CC3 6 | [includeIf "gitdir:~/dev/tp"] 7 | path = "~/dev/tp/.gitconfig" 8 | [color] 9 | diff = auto 10 | status = auto 11 | branch = auto 12 | ui = true 13 | [github] 14 | user = mikker 15 | [alias] 16 | br = branch 17 | ci = commit 18 | co = checkout 19 | hammer = commit --allow-empty -m 🔨 20 | last = log -1 HEAD 21 | rb = rebase 22 | st = status 23 | sw = switch 24 | tree = "log --graph --decorate --abbrev=commit" 25 | undo = reset HEAD~1 --mixed 26 | up = !git fetch --all --prune && git pull 27 | upto = "branch --set-upstream-to" 28 | wipe = !git add -A && git commit -qm 'WIPE SAVEPOINT' && git reset HEAD~1 --hard 29 | qs = "!git add -A && git commit -qm 'QuickSave'" 30 | [core] 31 | excludesfile = ~/.gitignore 32 | editor = nvim 33 | [format] 34 | pretty=format:%C(yellow)%h%Creset -%C(red)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset 35 | [push] 36 | default = current 37 | [filter "lfs"] 38 | clean = git-lfs clean -- %f 39 | smudge = git-lfs smudge -- %f 40 | required = true 41 | process = git-lfs filter-process 42 | [url "https://github.com"] 43 | insteadOf = git://github.com 44 | [stash] 45 | showPatch = true 46 | [rebase] 47 | autostash = true 48 | updateRefs = true 49 | [log] 50 | decorate = full 51 | [pull] 52 | ff = only 53 | rebase = true 54 | [credential] 55 | helper = osxkeychain 56 | [credential "https://github.com"] 57 | username = mikker 58 | [commit] 59 | gpgsign = true 60 | [merge] 61 | tool = diffconflicts 62 | [mergetool] 63 | prompt = false 64 | keepBackup = false 65 | [difftool] 66 | prompt = false 67 | [mergetool "diffconflicts"] 68 | cmd = nvim -c DiffConflictsWithHistory \"$MERGED\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" 69 | trustExitCode = true 70 | [init] 71 | defaultBranch = main 72 | -------------------------------------------------------------------------------- /git/gitignore.symlink: -------------------------------------------------------------------------------- 1 | artifacts/ 2 | cache/ 3 | .env 4 | .DS_Store 5 | node_modules/ 6 | 7 | -------------------------------------------------------------------------------- /hammerspoon/hammerspoon.symlink/.luarc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", 3 | "diagnostics.globals": ["hs"] 4 | } 5 | -------------------------------------------------------------------------------- /hammerspoon/hammerspoon.symlink/init.lua: -------------------------------------------------------------------------------- 1 | local function reload_config(_) 2 | hs.reload() 3 | end 4 | hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reload_config):start() 5 | hs.alert.show(" ✔︎") 6 | 7 | require("mouse_four_five") 8 | -------------------------------------------------------------------------------- /hammerspoon/hammerspoon.symlink/mouse_four_five.lua: -------------------------------------------------------------------------------- 1 | local mouse_four_five = hs.eventtap.new({ hs.eventtap.event.types.otherMouseDown }, function(event) 2 | if event:getButtonState(3) then 3 | hs.eventtap.keyStroke({ "cmd" }, "[") 4 | return true 5 | elseif event:getButtonState(4) then 6 | hs.eventtap.keyStroke({ "cmd" }, "]") 7 | return true 8 | else 9 | return false 10 | end 11 | end) 12 | 13 | mouse_four_five:start() 14 | -------------------------------------------------------------------------------- /karabiner/assets/complex_modifications/1699611650.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Vi Mode, left_control + hjkl. shift/option/command + arrow working.", 3 | "rules": [ 4 | { 5 | "description": "Vi Mode [left_control + hjkl]", 6 | "manipulators": [ 7 | { 8 | "from": { 9 | "key_code": "h", 10 | "modifiers": { 11 | "mandatory": [ 12 | "control" 13 | ], 14 | "optional": [ 15 | "caps_lock", 16 | "command", 17 | "option", 18 | "shift", 19 | "fn" 20 | ] 21 | } 22 | }, 23 | "to": [ 24 | { 25 | "key_code": "left_arrow" 26 | } 27 | ], 28 | "type": "basic" 29 | }, 30 | { 31 | "from": { 32 | "key_code": "j", 33 | "modifiers": { 34 | "mandatory": [ 35 | "control" 36 | ], 37 | "optional": [ 38 | "caps_lock", 39 | "command", 40 | "option", 41 | "shift", 42 | "fn" 43 | ] 44 | } 45 | }, 46 | "to": [ 47 | { 48 | "key_code": "down_arrow" 49 | } 50 | ], 51 | "type": "basic" 52 | }, 53 | { 54 | "from": { 55 | "key_code": "k", 56 | "modifiers": { 57 | "mandatory": [ 58 | "control" 59 | ], 60 | "optional": [ 61 | "caps_lock", 62 | "command", 63 | "option", 64 | "shift", 65 | "fn" 66 | ] 67 | } 68 | }, 69 | "to": [ 70 | { 71 | "key_code": "up_arrow" 72 | } 73 | ], 74 | "type": "basic" 75 | }, 76 | { 77 | "from": { 78 | "key_code": "l", 79 | "modifiers": { 80 | "mandatory": [ 81 | "control" 82 | ], 83 | "optional": [ 84 | "caps_lock", 85 | "command", 86 | "option", 87 | "shift", 88 | "fn" 89 | ] 90 | } 91 | }, 92 | "to": [ 93 | { 94 | "key_code": "right_arrow" 95 | } 96 | ], 97 | "type": "basic" 98 | } 99 | ] 100 | } 101 | ] 102 | } 103 | -------------------------------------------------------------------------------- /karabiner/assets/complex_modifications/1713387868.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ctrl Key → Hyper Key (⌃⌥⇧⌘)", 3 | "rules": [ 4 | { 5 | "description": "Ctrl Key → Hyper Key (⌃⌥⇧⌘)", 6 | "manipulators": [ 7 | { 8 | "from": { 9 | "key_code": "left_control", 10 | "modifiers": { 11 | "optional": ["caps_lock"] 12 | } 13 | }, 14 | "to": [ 15 | { 16 | "key_code": "left_shift", 17 | "modifiers": [ 18 | "left_command", 19 | "left_control", 20 | "left_option" 21 | ] 22 | } 23 | ], 24 | "type": "basic" 25 | } 26 | ] 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /karabiner/karabiner.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { "show_in_menu_bar": false }, 3 | "profiles": [ 4 | { 5 | "complex_modifications": { 6 | "rules": [ 7 | { 8 | "description": "akimbo cmd to F12", 9 | "manipulators": [ 10 | { 11 | "from": { 12 | "simultaneous": [ 13 | { "key_code": "left_command" }, 14 | { "key_code": "right_command" } 15 | ], 16 | "simultaneous_options": { 17 | "to_after_key_up": [ 18 | { 19 | "key_code": "f12", 20 | "modifiers": ["fn"] 21 | } 22 | ] 23 | } 24 | }, 25 | "to": [{ "key_code": "vk_none" }], 26 | "type": "basic" 27 | } 28 | ] 29 | }, 30 | { 31 | "description": "vi movement (left_control + hjkl)", 32 | "manipulators": [ 33 | { 34 | "from": { 35 | "key_code": "h", 36 | "modifiers": { 37 | "mandatory": ["control"], 38 | "optional": ["caps_lock", "command", "option", "shift", "fn"] 39 | } 40 | }, 41 | "to": [{ "key_code": "left_arrow" }], 42 | "type": "basic" 43 | }, 44 | { 45 | "from": { 46 | "key_code": "j", 47 | "modifiers": { 48 | "mandatory": ["control"], 49 | "optional": ["caps_lock", "command", "option", "shift", "fn"] 50 | } 51 | }, 52 | "to": [{ "key_code": "down_arrow" }], 53 | "type": "basic" 54 | }, 55 | { 56 | "from": { 57 | "key_code": "k", 58 | "modifiers": { 59 | "mandatory": ["control"], 60 | "optional": ["caps_lock", "command", "option", "shift", "fn"] 61 | } 62 | }, 63 | "to": [{ "key_code": "up_arrow" }], 64 | "type": "basic" 65 | }, 66 | { 67 | "from": { 68 | "key_code": "l", 69 | "modifiers": { 70 | "mandatory": ["control"], 71 | "optional": ["caps_lock", "command", "option", "shift", "fn"] 72 | } 73 | }, 74 | "to": [{ "key_code": "right_arrow" }], 75 | "type": "basic" 76 | } 77 | ] 78 | }, 79 | { 80 | "description": "mash f+j to esc", 81 | "manipulators": [ 82 | { 83 | "from": { 84 | "simultaneous": [ 85 | { "key_code": "f" }, 86 | { "key_code": "j" } 87 | ], 88 | "simultaneous_options": { "to_after_key_up": [{ "key_code": "escape" }] } 89 | }, 90 | "to": [{ "key_code": "vk_none" }], 91 | "type": "basic" 92 | } 93 | ] 94 | } 95 | ] 96 | }, 97 | "devices": [ 98 | { 99 | "identifiers": { 100 | "is_keyboard": true, 101 | "product_id": 834, 102 | "vendor_id": 1452 103 | }, 104 | "simple_modifications": [ 105 | { 106 | "from": { "key_code": "caps_lock" }, 107 | "to": [{ "key_code": "left_control" }] 108 | } 109 | ] 110 | }, 111 | { 112 | "identifiers": { 113 | "is_keyboard": true, 114 | "product_id": 60439, 115 | "vendor_id": 36125 116 | }, 117 | "ignore": true 118 | }, 119 | { 120 | "identifiers": { 121 | "is_keyboard": true, 122 | "product_id": 666, 123 | "vendor_id": 76 124 | }, 125 | "simple_modifications": [ 126 | { 127 | "from": { "key_code": "caps_lock" }, 128 | "to": [{ "key_code": "left_control" }] 129 | } 130 | ] 131 | }, 132 | { 133 | "fn_function_keys": [ 134 | { 135 | "from": { "key_code": "f12" }, 136 | "to": [{ "key_code": "f12" }] 137 | } 138 | ], 139 | "identifiers": { 140 | "is_keyboard": true, 141 | "product_id": 6505, 142 | "vendor_id": 12951 143 | } 144 | }, 145 | { 146 | "fn_function_keys": [ 147 | { 148 | "from": { "key_code": "f12" }, 149 | "to": [{ "key_code": "f12" }] 150 | } 151 | ], 152 | "identifiers": { 153 | "is_keyboard": true, 154 | "product_id": 260, 155 | "vendor_id": 18003 156 | } 157 | } 158 | ], 159 | "name": "Default", 160 | "selected": true, 161 | "virtual_hid_keyboard": { 162 | "country_code": 0, 163 | "keyboard_type_v2": "ansi" 164 | } 165 | }, 166 | { 167 | "name": "Off", 168 | "virtual_hid_keyboard": { "country_code": 0 } 169 | } 170 | ] 171 | } -------------------------------------------------------------------------------- /karabiner/macos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mkdir -p ~/.config 3 | ln -sf ~/.dotfiles/karabiner ~/.config/karabiner 4 | -------------------------------------------------------------------------------- /leader_key/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "actions" : [ 3 | { 4 | "actions" : [ 5 | { 6 | "key" : "g", 7 | "label" : "Gemini", 8 | "type" : "url", 9 | "value" : "https://gemini.google.com" 10 | }, 11 | { 12 | "key" : "a", 13 | "label" : "Claude", 14 | "type" : "application", 15 | "value" : "/Applications/Claude.app" 16 | }, 17 | { 18 | "key" : "c", 19 | "type" : "application", 20 | "value" : "/Applications/ChatGPT.app" 21 | }, 22 | { 23 | "key" : "m", 24 | "label" : "MidJourney", 25 | "type" : "application", 26 | "value" : "/Users/mikker/Applications/Midjourney.app" 27 | } 28 | ], 29 | "iconPath" : "sparkles", 30 | "key" : "l", 31 | "label" : "LLMs", 32 | "type" : "group" 33 | }, 34 | { 35 | "actions" : [ 36 | { 37 | "key" : "s", 38 | "type" : "application", 39 | "value" : "/Applications/Safari.app" 40 | }, 41 | { 42 | "key" : "c", 43 | "type" : "application", 44 | "value" : "/Applications/Google Chrome.app" 45 | }, 46 | { 47 | "key" : "a", 48 | "type" : "application", 49 | "value" : "/Applications/Arc.app" 50 | }, 51 | { 52 | "key" : "f", 53 | "type" : "application", 54 | "value" : "/Applications/Firefox.app" 55 | } 56 | ], 57 | "iconPath" : "safari", 58 | "key" : "b", 59 | "label" : "Browsers", 60 | "type" : "group" 61 | }, 62 | { 63 | "actions" : [ 64 | { 65 | "key" : "e", 66 | "type" : "url", 67 | "value" : "raycast://extensions/raycast/emoji-symbols/search-emoji-symbols" 68 | }, 69 | { 70 | "key" : "p", 71 | "type" : "url", 72 | "value" : "raycast://confetti" 73 | }, 74 | { 75 | "key" : "c", 76 | "type" : "url", 77 | "value" : "raycast://extensions/raycast/system/open-camera" 78 | } 79 | ], 80 | "iconPath" : "character.textbox", 81 | "key" : "r", 82 | "label" : "Raycast", 83 | "type" : "group" 84 | }, 85 | { 86 | "actions" : [ 87 | { 88 | "key" : "f", 89 | "label" : "Full screen", 90 | "type" : "url", 91 | "value" : "moves://template/maximize" 92 | }, 93 | { 94 | "key" : "h", 95 | "label" : "Left", 96 | "type" : "url", 97 | "value" : "moves://template/left-half" 98 | }, 99 | { 100 | "key" : "l", 101 | "label" : "Right", 102 | "type" : "url", 103 | "value" : "moves://template/right-half" 104 | }, 105 | { 106 | "key" : "o", 107 | "type" : "url", 108 | "value" : "moves://template/last-two-thirds" 109 | }, 110 | { 111 | "key" : "n", 112 | "type" : "url", 113 | "value" : "moves://template/first-third" 114 | }, 115 | { 116 | "key" : "2", 117 | "label" : "Comfortable", 118 | "type" : "url", 119 | "value" : "moves://custom?&name=two&position=center&relativeWidth=0.86&relativeHeight=1.0" 120 | }, 121 | { 122 | "key" : "H", 123 | "label" : "Max height", 124 | "type" : "url", 125 | "value" : "moves://template/maximize-height" 126 | }, 127 | { 128 | "actions" : [ 129 | { 130 | "key" : "h", 131 | "label" : "First third", 132 | "type" : "url", 133 | "value" : "moves://template/first-third" 134 | }, 135 | { 136 | "key" : "c", 137 | "label" : "Center third", 138 | "type" : "url", 139 | "value" : "moves://template/center-third" 140 | }, 141 | { 142 | "key" : "l", 143 | "label" : "Last third", 144 | "type" : "url", 145 | "value" : "moves://template/last-third" 146 | }, 147 | { 148 | "actions" : [ 149 | { 150 | "key" : "h", 151 | "label" : "First two thirds", 152 | "type" : "url", 153 | "value" : "moves://template/first-two-thirds" 154 | }, 155 | { 156 | "key" : "l", 157 | "label" : "Last two thirds", 158 | "type" : "url", 159 | "value" : "moves://template/last-two-thirds" 160 | } 161 | ], 162 | "key" : "2", 163 | "label" : "Two thirds", 164 | "type" : "group" 165 | } 166 | ], 167 | "key" : "3", 168 | "label" : "Thirds", 169 | "type" : "group" 170 | }, 171 | { 172 | "key" : "C", 173 | "label" : "Center", 174 | "type" : "url", 175 | "value" : "moves://template/center" 176 | }, 177 | { 178 | "key" : "s", 179 | "label" : "sssslide", 180 | "type" : "url", 181 | "value" : "moves://custom?&name=slide&position=centerRight&absoluteWidth=1400.0&absoluteHeight=1000.0&absoluteXOffset=-20.0&absoluteYOffset=0.0" 182 | } 183 | ], 184 | "iconPath" : "uiwindow.split.2x1", 185 | "key" : "w", 186 | "label" : "Window", 187 | "type" : "group" 188 | }, 189 | { 190 | "actions" : [ 191 | { 192 | "key" : "m", 193 | "type" : "application", 194 | "value" : "/System/Applications/Messages.app" 195 | }, 196 | { 197 | "key" : "t", 198 | "type" : "application", 199 | "value" : "/Applications/Telegram.app" 200 | }, 201 | { 202 | "key" : "s", 203 | "type" : "application", 204 | "value" : "/Applications/Slack.app" 205 | }, 206 | { 207 | "key" : "d", 208 | "type" : "application", 209 | "value" : "/Applications/Discord.app" 210 | }, 211 | { 212 | "key" : "f", 213 | "type" : "application", 214 | "value" : "/Applications/Messenger.app" 215 | } 216 | ], 217 | "iconPath" : "message", 218 | "key" : "m", 219 | "label" : "Messaging", 220 | "type" : "group" 221 | }, 222 | { 223 | "actions" : [ 224 | { 225 | "key" : "c", 226 | "label" : "Ceiling", 227 | "type" : "command", 228 | "value" : "shortcuts run \"Kontor-toggle\"" 229 | }, 230 | { 231 | "key" : "e", 232 | "label" : "Key Light", 233 | "type" : "url", 234 | "value" : "raycast://extensions/thomas/elgato-key-light/toggle" 235 | }, 236 | { 237 | "actions" : [ 238 | { 239 | "key" : "1", 240 | "label" : "10%", 241 | "type" : "url", 242 | "value" : "BetterDisplay://set?name=27GN950&brightness=0.2" 243 | }, 244 | { 245 | "key" : "2", 246 | "label" : "50%", 247 | "type" : "url", 248 | "value" : "BetterDisplay://set?name=27GN950&brightness=0.5" 249 | }, 250 | { 251 | "key" : "3", 252 | "label" : "100%", 253 | "type" : "url", 254 | "value" : "BetterDisplay://set?name=27GN950&brightness=1.0" 255 | } 256 | ], 257 | "key" : "m", 258 | "label" : "Monitor", 259 | "type" : "group" 260 | } 261 | ], 262 | "iconPath" : "lightbulb", 263 | "key" : "e", 264 | "label" : "Environment", 265 | "type" : "group" 266 | }, 267 | { 268 | "actions" : [ 269 | { 270 | "key" : "a", 271 | "type" : "application", 272 | "value" : "/Users/mikker/Applications/DarkMode.app" 273 | }, 274 | { 275 | "key" : "s", 276 | "type" : "url", 277 | "value" : "raycast://extensions/raycast/system/sleep" 278 | }, 279 | { 280 | "key" : "l", 281 | "type" : "url", 282 | "value" : "raycast://extensions/raycast/system/lock-screen" 283 | } 284 | ], 285 | "iconPath" : "laptopcomputer", 286 | "key" : "s", 287 | "label" : "System", 288 | "type" : "group" 289 | }, 290 | { 291 | "actions" : [ 292 | { 293 | "key" : "o", 294 | "type" : "application", 295 | "value" : "/Applications/Obsidian.app" 296 | }, 297 | { 298 | "key" : "e", 299 | "type" : "application", 300 | "value" : "/System/Applications/TextEdit.app" 301 | }, 302 | { 303 | "key" : "p", 304 | "type" : "application", 305 | "value" : "/Applications/Plain Text Editor.app" 306 | }, 307 | { 308 | "key" : "i", 309 | "type" : "application", 310 | "value" : "/System/Applications/Music.app" 311 | }, 312 | { 313 | "key" : "m", 314 | "type" : "application", 315 | "value" : "/System/Applications/Mail.app" 316 | }, 317 | { 318 | "key" : "d", 319 | "type" : "application", 320 | "value" : "/Applications/Things3.app" 321 | }, 322 | { 323 | "key" : "c", 324 | "type" : "application", 325 | "value" : "/System/Applications/Calendar.app" 326 | }, 327 | { 328 | "key" : "n", 329 | "type" : "application", 330 | "value" : "/Applications/Notion.app" 331 | } 332 | ], 333 | "iconPath" : "app", 334 | "key" : "a", 335 | "label" : "Apps", 336 | "type" : "group" 337 | }, 338 | { 339 | "actions" : [ 340 | { 341 | "key" : "g", 342 | "type" : "folder", 343 | "value" : "/Users/mikker/Library/Mobile Documents/iCloud~com~jellystyle~GIFwrapped~library/Documents" 344 | }, 345 | { 346 | "key" : "a", 347 | "type" : "folder", 348 | "value" : "/Applications" 349 | }, 350 | { 351 | "key" : "h", 352 | "type" : "folder", 353 | "value" : "/Users/mikker" 354 | }, 355 | { 356 | "key" : "l", 357 | "type" : "folder", 358 | "value" : "/Users/mikker/Downloads" 359 | } 360 | ], 361 | "iconPath" : "bookmark", 362 | "key" : "g", 363 | "label" : "Folders", 364 | "type" : "group" 365 | }, 366 | { 367 | "actions" : [ 368 | { 369 | "key" : "w", 370 | "type" : "url", 371 | "value" : "raycast://extensions/Aayush9029/cleanshotx/capture-window" 372 | }, 373 | { 374 | "key" : "f", 375 | "type" : "url", 376 | "value" : "raycast://extensions/Aayush9029/cleanshotx/capture-fullscreen" 377 | }, 378 | { 379 | "key" : "v", 380 | "type" : "url", 381 | "value" : "raycast://extensions/Aayush9029/cleanshotx/record-screen" 382 | }, 383 | { 384 | "key" : "a", 385 | "type" : "url", 386 | "value" : "raycast://extensions/Aayush9029/cleanshotx/capture-area" 387 | } 388 | ], 389 | "iconPath" : "camera.metering.center.weighted.average", 390 | "key" : "c", 391 | "label" : "Capture", 392 | "type" : "group" 393 | }, 394 | { 395 | "actions" : [ 396 | { 397 | "actions" : [ 398 | { 399 | "key" : "x", 400 | "label" : "X", 401 | "type" : "url", 402 | "value" : "https://x.com" 403 | }, 404 | { 405 | "key" : "b", 406 | "label" : "BlueSky", 407 | "type" : "url", 408 | "value" : "https://bsky.app" 409 | }, 410 | { 411 | "key" : "m", 412 | "label" : "Elk", 413 | "type" : "url", 414 | "value" : "https://elk.zone" 415 | } 416 | ], 417 | "key" : "d", 418 | "label" : "Doomscroll", 419 | "type" : "group" 420 | }, 421 | { 422 | "actions" : [ 423 | { 424 | "key" : "1", 425 | "type" : "url", 426 | "value" : "https://meta.brnbw.com/dashboard/2-10er?tab=1-tab-1" 427 | }, 428 | { 429 | "key" : "2", 430 | "type" : "url", 431 | "value" : "https://dashboard.simpleanalytics.com/10er.com" 432 | }, 433 | { 434 | "key" : "3", 435 | "type" : "url", 436 | "value" : "https://dashboard.simpleanalytics.com/funnymost.com" 437 | }, 438 | { 439 | "key" : "4", 440 | "type" : "url", 441 | "value" : "https://meta.brnbw.com/dashboard/6-funnymost" 442 | } 443 | ], 444 | "key" : "t", 445 | "label" : "10er", 446 | "type" : "group" 447 | }, 448 | { 449 | "key" : "w", 450 | "label" : "Typefully", 451 | "type" : "url", 452 | "value" : "https://typefully.com/" 453 | } 454 | ], 455 | "iconPath" : "document.on.document", 456 | "key" : "t", 457 | "label" : "Tab sets", 458 | "type" : "group" 459 | }, 460 | { 461 | "actions" : [ 462 | { 463 | "key" : "d", 464 | "label" : "Daily", 465 | "type" : "url", 466 | "value" : "obsidian://daily" 467 | }, 468 | { 469 | "key" : "w", 470 | "label" : "Weekly", 471 | "type" : "command", 472 | "value" : "open \"obsidian://open?file=02%20Calendar/Journals/`date +%Y-W%V`\"" 473 | }, 474 | { 475 | "key" : "o", 476 | "label" : "Open", 477 | "type" : "application", 478 | "value" : "/Applications/Obsidian.app" 479 | } 480 | ], 481 | "iconPath" : "diamond", 482 | "key" : "o", 483 | "label" : "Obsidian", 484 | "type" : "group" 485 | }, 486 | { 487 | "actions" : [ 488 | { 489 | "actions" : [ 490 | { 491 | "actions" : [ 492 | { 493 | "actions" : [ 494 | { 495 | "key" : "z", 496 | "label" : "🎉", 497 | "type" : "url", 498 | "value" : "raycast://confetti" 499 | } 500 | ], 501 | "key" : "z", 502 | "label" : "This", 503 | "type" : "group" 504 | } 505 | ], 506 | "key" : "z", 507 | "label" : "Is", 508 | "type" : "group" 509 | } 510 | ], 511 | "key" : "z", 512 | "label" : "Cool", 513 | "type" : "group" 514 | } 515 | ], 516 | "iconPath" : "figure.dance", 517 | "key" : "z", 518 | "label" : "How", 519 | "type" : "group" 520 | }, 521 | { 522 | "actions" : [ 523 | { 524 | "key" : "d", 525 | "type" : "application", 526 | "value" : "/Applications/Dash.app" 527 | }, 528 | { 529 | "key" : "t", 530 | "type" : "application", 531 | "value" : "/Applications/WezTerm.app" 532 | } 533 | ], 534 | "iconPath" : "hammer", 535 | "key" : "d", 536 | "label" : "Devtools", 537 | "type" : "group" 538 | }, 539 | { 540 | "actions" : [ 541 | { 542 | "key" : "m", 543 | "type" : "application", 544 | "value" : "/System/Applications/Music.app" 545 | }, 546 | { 547 | "key" : "y", 548 | "type" : "application", 549 | "value" : "/Users/mikker/Applications/YouTube.app" 550 | }, 551 | { 552 | "key" : "o", 553 | "type" : "application", 554 | "value" : "/Applications/Overcast.app" 555 | } 556 | ], 557 | "key" : "p", 558 | "type" : "group" 559 | } 560 | ], 561 | "type" : "group" 562 | } -------------------------------------------------------------------------------- /macos/DefaultKeyBinding.dict: -------------------------------------------------------------------------------- 1 | // mkdir -p ~/Library/KeyBindings && cp DefaultKeyBindings.dict ~/Library/KeyBindings/DefaultKeyBindings.dict 2 | 3 | { 4 | "^w" = (deleteWordBackward:); 5 | } 6 | -------------------------------------------------------------------------------- /macos/macos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Ask for the administrator password upfront 4 | sudo -v 5 | 6 | # Keep-alive: update existing `sudo` time stamp until `.osx` has finished 7 | while true; do 8 | sudo -n true 9 | sleep 60 10 | kill -0 "$$" || exit 11 | done 2>/dev/null & 12 | 13 | # SYSTEM {{{ 14 | 15 | echo "Requiring password immediately after sleep or screen saver begins" 16 | defaults write com.apple.screensaver askForPassword -int 1 17 | defaults write com.apple.screensaver askForPasswordDelay -int 0 18 | 19 | echo "Disabling OS X Gate Keeper - run apps from anywhere" 20 | sudo spctl --master-disable 21 | sudo defaults write /var/db/SystemPolicy-prefs.plist enabled -string no 22 | defaults write com.apple.LaunchServices LSQuarantine -bool false 23 | 24 | echo "Preventing Time Machine from prompting to use new hard drives as backup volume" defaults write com.apple.TimeMachine DoNotOfferNewDisksForBackup -bool true 25 | 26 | # echo "Disabling disk image verification" 27 | defaults write com.apple.frameworks.diskimages skip-verify -bool true 28 | defaults write com.apple.frameworks.diskimages skip-verify-locked -bool true 29 | defaults write com.apple.frameworks.diskimages skip-verify-remote -bool true 30 | 31 | # }}} 32 | # GENERAL {{{ 33 | 34 | echo 'Enable full keyboard access for all controls (e.g. enable Tab in modal dialogs)' 35 | defaults write NSGlobalDomain AppleKeyboardUIMode -int 3 36 | 37 | echo 'Increase window resize speed for Cocoa applications' 38 | defaults write NSGlobalDomain NSWindowResizeTime -float 0.001 39 | 40 | echo "Use scroll gesture with the Ctrl (^) modifier key to zoom" 41 | defaults write com.apple.universalaccess closeViewScrollWheelToggle -bool true 42 | defaults write com.apple.universalaccess HIDScrollZoomModifierMask -int 262144 43 | 44 | echo "Check for software updates daily, not just once per week" 45 | defaults write com.apple.SoftwareUpdate ScheduleFrequency -int 1 46 | 47 | echo "Saving screenshots to ~/Downloads" 48 | defaults write com.apple.screencapture location ~/Downloads 49 | 50 | # }}} 51 | # DOCK {{{ 52 | 53 | echo 'Speed up Mission Control animations' 54 | defaults write com.apple.dock expose-animation-duration -float 0.1 55 | 56 | echo "Setting Dock to auto-hide and removing the auto-hiding delay" 57 | defaults write com.apple.dock autohide -bool true 58 | defaults write com.apple.dock autohide-delay -float 0 59 | defaults write com.apple.dock autohide-time-modifier -float 0 60 | 61 | echo 'Hot corners' 62 | echo 'Top left / Bottom right screen corner → Mission Control' 63 | defaults write com.apple.dock wvous-tl-corner -int 2 64 | defaults write com.apple.dock wvous-tl-modifier -int 0 65 | defaults write com.apple.dock wvous-br-corner -int 2 66 | defaults write com.apple.dock wvous-br-modifier -int 0 67 | echo 'Bottom left screen corner → Desktop' 68 | defaults write com.apple.dock wvous-bl-corner -int 4 69 | defaults write com.apple.dock wvous-bl-modifier -int 0 70 | 71 | # }}} 72 | # DIALOGS {{{ 73 | 74 | echo 'Expand save and print panel by default' 75 | defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true 76 | defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode2 -bool true 77 | defaults write NSGlobalDomain PMPrintingExpandedStateForPrint -bool true 78 | defaults write NSGlobalDomain PMPrintingExpandedStateForPrint2 -bool true 79 | 80 | echo "Automatically quit printer app once the print jobs complete" 81 | defaults write com.apple.print.PrintingPrefs "Quit When Finished" -bool true 82 | 83 | # }}} 84 | # FINDER {{{ 85 | 86 | # echo 'Disable Desktop' 87 | # defaults write com.apple.finder CreateDesktop -bool false 88 | 89 | echo "When performing a search, search the current folder by default" 90 | defaults write com.apple.finder FXDefaultSearchScope -string "SCcf" 91 | 92 | echo "Use column view in all Finder windows by default" 93 | # Four-letter codes for the other view modes: `icnv`, `clmv`, `Flwv` 94 | defaults write com.apple.finder FXPreferredViewStyle -string "Clmv" 95 | 96 | echo "Set Default Finder location to Home" 97 | defaults write com.apple.finder NewWindowTarget -string "PfLo" && 98 | defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}" 99 | 100 | # echo "Show the ~/Library folder" 101 | # chflags nohidden ~/Library 102 | 103 | echo "Expand the following File Info panes:" 104 | echo " “General”, “Open with”, and “Sharing & Permissions”" 105 | defaults write com.apple.finder FXInfoPanesExpanded -dict \ 106 | General -bool true \ 107 | OpenWith -bool true \ 108 | Privileges -bool true 109 | 110 | echo "Showing status bar in Finder by default" 111 | defaults write com.apple.finder ShowStatusBar -bool true 112 | 113 | echo 'Finder: show all filename extensions' 114 | defaults write NSGlobalDomain AppleShowAllExtensions -bool true 115 | 116 | echo 'Disable the warning when changing a file extension' 117 | defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false 118 | 119 | echo 'Avoid creating .DS_Store files on network volumes' 120 | defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true 121 | 122 | echo 'Disable the warning before emptying the Trash' 123 | defaults write com.apple.finder WarnOnEmptyTrash -bool false 124 | 125 | # }}} 126 | # SAFARI (and Technology Preview) {{{ 127 | 128 | # echo "Prevent Safari from opening ‘safe’ files automatically after downloading" 129 | # defaults write com.apple.Safari AutoOpenSafeDownloads -bool false 130 | # defaults write com.apple.SafariTechnologyPreview AutoOpenSafeDownloads -bool false 131 | 132 | # echo "Show the full URL in the address bar (note: this still hides the scheme)" 133 | # defaults write com.apple.Safari ShowFullURLInSmartSearchField -bool true 134 | # defaults write com.apple.SafariTechnologyPreview ShowFullURLInSmartSearchField -bool true 135 | 136 | # }}} 137 | # APPS {{{ 138 | 139 | echo "TextEdit: Use plain text mode for new documents" 140 | defaults write com.apple.TextEdit RichText -int 0 141 | 142 | echo "TextEdit: Open and save files as UTF-8" 143 | defaults write com.apple.TextEdit PlainTextEncoding -int 4 144 | defaults write com.apple.TextEdit PlainTextEncodingForWrite -int 4 145 | 146 | echo "TextEdit: Start with empty doc" 147 | defaults write com.apple.TextEdit NSShowAppCentricOpenPanelInsteadOfUntitledFile -bool false 148 | 149 | # }}} 150 | 151 | echo "Installing DefaultKeyBindings" 152 | mkdir -p ~/Library/KeyBindings && cp ~/dotfiles/macos/DefaultKeyBinding.dict ~/Library/KeyBindings/DefaultKeyBinding.dict 153 | 154 | echo "Disable font smoothing" 155 | defaults -currentHost write -g AppleFontSmoothing -int 0 156 | 157 | echo "Disable Tile by dragging windows to screen edges" 158 | defaults write com.apple.WindowManager EnableTilingByEdgeDrag -int 0 159 | defaults write com.apple.WindowManager EnableTopTilingByEdgeDrag -int 0 160 | defaults write com.apple.WindowManager EnableTilingOptionAccelerator -int 0 161 | -------------------------------------------------------------------------------- /macos/terminfo/macos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | path="macos/terminfo" 4 | find $path -name '*.terminfo' -exec tic -x {} \; 5 | -------------------------------------------------------------------------------- /macos/terminfo/tmux-256color.terminfo: -------------------------------------------------------------------------------- 1 | tmux-256color|tmux with 256 colors, 2 | ritm=\E[23m, rmso=\E[27m, sitm=\E[3m, smso=\E[7m, 3 | use=xterm-256color, use=screen-256color, 4 | 5 | -------------------------------------------------------------------------------- /macos/terminfo/tmux.terminfo: -------------------------------------------------------------------------------- 1 | tmux|tmux terminal multiplexer, 2 | ritm=\E[23m, rmso=\E[27m, sitm=\E[3m, smso=\E[7m, Ms@, 3 | use=xterm, use=screen, 4 | 5 | -------------------------------------------------------------------------------- /macos/terminfo/xterm-256color-italic.terminfo: -------------------------------------------------------------------------------- 1 | xterm-256color-italic|xterm with 256 colors and italic, 2 | sitm=\E[3m, ritm=\E[23m, 3 | use=xterm-256color, 4 | 5 | -------------------------------------------------------------------------------- /nvim/all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p ~/.config 4 | [ -d ~/.config/nvim ] && mv ~/.config/nvim ~/.config/nvim.bak 5 | ln -sf ~/.dotfiles/nvim ~/.config/nvim 6 | 7 | -------------------------------------------------------------------------------- /nvim/autoload/test/solidity/forge.vim: -------------------------------------------------------------------------------- 1 | if !exists('g:test#solidity#forge#file_pattern') 2 | let g:test#solidity#forge#file_pattern = '\v(\.t\.sol)$' 3 | endif 4 | 5 | function! test#solidity#forge#test_file(file) abort 6 | return a:file =~ g:test#solidity#forge#file_pattern 7 | endfunction 8 | 9 | function! test#solidity#forge#build_position(type, position) abort 10 | let path_with_leading_asterisk = "'**/" . a:position['file'] . "'" 11 | 12 | if a:type ==# 'nearest' 13 | let nearest_test = test#base#nearest_test(a:position, g:test#solidity#patterns, {}) 14 | 15 | if !empty(nearest_test) 16 | return ["test", "--match-path", path_with_leading_asterisk, "--match-test", join(nearest_test['test'], ".")] 17 | else 18 | return ["test", "--match-path", path_with_leading_asterisk] 19 | endif 20 | elseif a:type ==# 'file' 21 | return ["test", "--match-path", path_with_leading_asterisk] 22 | else 23 | return ["test"] 24 | endif 25 | endfunction 26 | 27 | function! test#solidity#forge#build_args(args, color) abort 28 | return a:args 29 | endfunction 30 | 31 | function! test#solidity#forge#executable() abort 32 | return 'forge' 33 | endfunction 34 | -------------------------------------------------------------------------------- /nvim/colors/funbones.lua: -------------------------------------------------------------------------------- 1 | local colors_name = "funbones" 2 | vim.g.colors_name = colors_name -- Required when defining a colorscheme 3 | 4 | local lush = require("lush") 5 | local hsluv = lush.hsluv -- Human-friendly hsl 6 | local util = require("zenbones.util") 7 | 8 | local bg = vim.o.background 9 | 10 | -- Define a palette. Use `palette_extend` to fill unspecified colors 11 | -- Based on https://github.com/gruvbox-community/gruvbox#palette 12 | local palette 13 | if bg == "light" then 14 | palette = util.palette_extend({ 15 | -- bg = hsluv("#f6efe0"), 16 | -- fg = hsluv("#29285b"), 17 | }, bg) 18 | else 19 | palette = util.palette_extend({ 20 | -- bg = hsluv("#1b192e"), 21 | -- fg = hsluv("#b1bce6"), 22 | }, bg) 23 | end 24 | 25 | -- Generate the lush specs using the generator util 26 | local generator = require("zenbones.specs") 27 | local base_specs = generator.generate(palette, bg, generator.get_global_config(colors_name, bg)) 28 | 29 | -- Optionally extend specs using Lush 30 | local specs = lush.extends({ base_specs }).with(function() 31 | return { 32 | -- Statement({ base_specs.Statement, fg = palette.rose }), 33 | -- Special({ fg = palette.water }), 34 | -- Type({ fg = palette.sky, gui = "italic" }), 35 | } 36 | end) 37 | 38 | -- Pass the specs to lush to apply 39 | lush(specs) 40 | 41 | -- Optionally set term colors 42 | require("zenbones.term").apply_colors(palette) 43 | -------------------------------------------------------------------------------- /nvim/ftplugin/markdown.lua: -------------------------------------------------------------------------------- 1 | require("which-key").add({ 2 | { "p", "silent !open -a Marked\\ 2 '%'", desc = "Preview in Marked" }, 3 | }) 4 | -------------------------------------------------------------------------------- /nvim/ftplugin/slim.lua: -------------------------------------------------------------------------------- 1 | vim.opt_local.foldmethod = "indent" 2 | -------------------------------------------------------------------------------- /nvim/init.lua: -------------------------------------------------------------------------------- 1 | -- bootstrap lazy.nvim, LazyVim and your plugins 2 | require("config.lazy") 3 | require("config.commands") 4 | -------------------------------------------------------------------------------- /nvim/lazyvim.json: -------------------------------------------------------------------------------- 1 | { 2 | "extras": [ 3 | "lazyvim.plugins.extras.coding.mini-surround", 4 | "lazyvim.plugins.extras.editor.dial", 5 | "lazyvim.plugins.extras.editor.snacks_picker", 6 | "lazyvim.plugins.extras.formatting.prettier", 7 | "lazyvim.plugins.extras.lang.docker", 8 | "lazyvim.plugins.extras.lang.json", 9 | "lazyvim.plugins.extras.lang.tailwind", 10 | "lazyvim.plugins.extras.lang.toml", 11 | "lazyvim.plugins.extras.lang.typescript", 12 | "lazyvim.plugins.extras.lang.yaml", 13 | "lazyvim.plugins.extras.util.dot", 14 | "lazyvim.plugins.extras.util.mini-hipatterns" 15 | ], 16 | "install_version": 7, 17 | "news": { 18 | "NEWS.md": "10960" 19 | }, 20 | "version": 8 21 | } -------------------------------------------------------------------------------- /nvim/lua/config/autocmds.lua: -------------------------------------------------------------------------------- 1 | -- Autocmds are automatically loaded on the VeryLazy event 2 | -- Default autocmds that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua 3 | -- 4 | -- Add any additional autocmds here 5 | -- with `vim.api.nvim_create_autocmd` 6 | -- 7 | -- Or remove existing autocmds by their group name (which is prefixed with `lazyvim_` for the defaults) 8 | -- e.g. vim.api.nvim_del_augroup_by_name("lazyvim_wrap_spell") 9 | 10 | local function augroup(name) 11 | return vim.api.nvim_create_augroup("lazyvim_" .. name, { clear = true }) 12 | end 13 | 14 | vim.api.nvim_create_autocmd("TermOpen", { 15 | pattern = "*", 16 | group = augroup("term"), 17 | command = "nmap :bd!", 18 | }) 19 | 20 | local magic_markers = augroup("magic_markers") 21 | vim.api.nvim_create_autocmd("BufLeave", { 22 | pattern = "*.{erb,html,haml,slim,eex}", 23 | group = magic_markers, 24 | command = 'exe "normal! mH"', 25 | }) 26 | vim.api.nvim_create_autocmd("BufLeave", { 27 | pattern = "*.css", 28 | group = magic_markers, 29 | command = 'exe "normal! mS"', 30 | }) 31 | vim.api.nvim_create_autocmd("BufLeave", { 32 | pattern = "*.{js,jsx,ts,tsx}", 33 | group = magic_markers, 34 | command = 'exe "normal! mJ"', 35 | }) 36 | vim.api.nvim_create_autocmd("BufLeave", { 37 | pattern = "*.{rb,ex,exs}", 38 | group = magic_markers, 39 | command = 'exe "normal! mC"', 40 | }) 41 | vim.api.nvim_create_autocmd("BufLeave", { 42 | pattern = "*.yml", 43 | group = magic_markers, 44 | command = 'exe "normal! mY"', 45 | }) 46 | 47 | local grepQuickFix = augroup("grep_quickfix") 48 | vim.api.nvim_create_autocmd("QuickFixCmdPost", { 49 | pattern = "*", 50 | group = grepQuickFix, 51 | command = "cwindow | redraw", 52 | }) 53 | vim.api.nvim_create_autocmd("BufEnter", { 54 | pattern = "*", 55 | group = grepQuickFix, 56 | command = "if &buftype == 'quickfix' | nnoremap | endif", 57 | }) 58 | -------------------------------------------------------------------------------- /nvim/lua/config/commands.lua: -------------------------------------------------------------------------------- 1 | -- Run a terminal command in a new tab 2 | local function runTermInTab(args) 3 | if vim.fn.tabpagenr() > 1 then 4 | -- If there is more than one tab page, do nothing 5 | else 6 | -- Open a new tab and run the terminal command 7 | vim.cmd("-tabnew | term " .. args) 8 | vim.cmd("keepalt file TT") 9 | vim.cmd("normal I") 10 | end 11 | end 12 | 13 | -- Create the command TT that calls the runTermInTab function 14 | vim.api.nvim_create_user_command("TT", function(opts) 15 | runTermInTab(opts.args) 16 | end, { nargs = "*", complete = "file" }) 17 | 18 | -- Open current file in "Marked 2.app" 19 | vim.api.nvim_create_user_command("Marked", function() 20 | vim.system({ "open -a Marked\\ 2 " .. vim.fn.expand("%") }) 21 | end, { nargs = 0 }) 22 | 23 | vim.api.nvim_create_user_command("F", function(args) 24 | vim.bo.filetype = args 25 | end, { nargs = 1 }) 26 | 27 | -- Strip trailing whitespace 28 | function StripTrailingWhitespace() 29 | -- Save the current cursor position 30 | local current_pos = vim.api.nvim_win_get_cursor(0) 31 | local current_line = current_pos[1] 32 | local current_col = current_pos[2] 33 | 34 | -- Substitute command to remove trailing whitespace 35 | vim.cmd([[%s/\s\+$//e]]) 36 | 37 | -- Restore the cursor position 38 | vim.api.nvim_win_set_cursor(0, { current_line, current_col }) 39 | end 40 | 41 | local wk = require("which-key") 42 | -- vim.api.nvim_set_keymap("n", "S", , { noremap = true, silent = true }) 43 | wk.add({ 44 | { "S", ":lua StripTrailingWhitespace()", desc = "Strip whitespace", silent = true, noremap = true }, 45 | }) 46 | 47 | -- Load QuickFix list into argument list 48 | local function QuickfixFilenames() 49 | local buffer_numbers = {} 50 | for _, quickfix_item in ipairs(vim.fn.getqflist()) do 51 | local qf_bufnr = quickfix_item.bufnr 52 | buffer_numbers[qf_bufnr] = vim.fn.bufname(quickfix_item.bufnr) 53 | end 54 | local filenames = {} 55 | for _, filename in pairs(buffer_numbers) do 56 | table.insert(filenames, vim.fn.fnameescape(filename)) 57 | end 58 | return table.concat(filenames, " ") 59 | end 60 | 61 | vim.api.nvim_create_user_command("Qargs", function() 62 | vim.cmd("args " .. QuickfixFilenames()) 63 | end, { nargs = 0, bar = true }) 64 | -------------------------------------------------------------------------------- /nvim/lua/config/keymaps.lua: -------------------------------------------------------------------------------- 1 | -- Keymaps are automatically loaded on the VeryLazy event 2 | -- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua 3 | -- Add any additional keymaps here 4 | 5 | local function map(mode, lhs, rhs, opts) 6 | -- opts.silent = opts.silent ~= false 7 | vim.keymap.set(mode, lhs, rhs, opts) 8 | end 9 | 10 | -- support to arrows mapped keebs 11 | map("n", "", "h", { desc = "Go to right window" }) 12 | map("n", "", "j", { desc = "Go to right window" }) 13 | map("n", "", "k", { desc = "Go to right window" }) 14 | map("n", "", "l", { desc = "Go to right window" }) 15 | 16 | map("n", "", "", { desc = "Previous buffer" }) 17 | 18 | -- tabs 19 | map("n", "]w", "tabnext", { desc = "Next Tab" }) 20 | map("n", "[w", "tabprevious", { desc = "Previous Tab" }) 21 | 22 | -- quicksave 23 | map("n", "j", ":w", { desc = "Quicksave" }) 24 | 25 | -- qq to record macro, Q to apply 26 | map("n", "Q", "@q") 27 | map("v", "Q", ":normal Q") 28 | 29 | -- expand %% to dir of current buffer in cmd mode 30 | map("c", "%%", "=expand('%:h').'/'") 31 | -- open file in same dir as current buffer 32 | map("n", "e", ":e =expand('%:h').'/'", { desc = "Edit in same dir" }) 33 | 34 | -- always jump to column, not just line 35 | map("n", "'", "`") 36 | 37 | -- open work dir in Finder.app 38 | map("n", "O", ":call system('open .')", { desc = "Open cwd in Finder" }) 39 | 40 | -- close the bottom window, whatever it es 41 | map( 42 | "n", 43 | "xc", 44 | ":wincmd z|cclose|lclose|TroubleClose", 45 | { silent = true, noremap = true, desc = "Close bottom window" } 46 | ) 47 | 48 | map( 49 | "n", 50 | "ub", 51 | 'lua vim.o.bg = vim.o.bg == "dark" and "light" or "dark"', 52 | { desc = "Toggle background light/dark" } 53 | ) 54 | 55 | map("n", "\\", ":grep! ") 56 | 57 | vim.keymap.set("n", "oc", function() 58 | local file = vim.fn.shellescape(vim.fn.expand("%:p")) 59 | local line = vim.fn.line(".") 60 | vim.cmd(string.format("silent !cursor . -g %s:%s", file, line)) 61 | end, { desc = "Open file in Cursor" }) 62 | -------------------------------------------------------------------------------- /nvim/lua/config/lazy.lua: -------------------------------------------------------------------------------- 1 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 2 | if not (vim.uv or vim.loop).fs_stat(lazypath) then 3 | local lazyrepo = "https://github.com/folke/lazy.nvim.git" 4 | local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) 5 | if vim.v.shell_error ~= 0 then 6 | vim.api.nvim_echo({ 7 | { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, 8 | { out, "WarningMsg" }, 9 | { "\nPress any key to exit..." }, 10 | }, true, {}) 11 | vim.fn.getchar() 12 | os.exit(1) 13 | end 14 | end 15 | vim.opt.rtp:prepend(lazypath) 16 | 17 | require("lazy").setup({ 18 | spec = { 19 | -- add LazyVim and import its plugins 20 | { "LazyVim/LazyVim", import = "lazyvim.plugins" }, 21 | -- import/override with your plugins 22 | { import = "plugins" }, 23 | }, 24 | defaults = { 25 | -- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup. 26 | -- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default. 27 | lazy = false, 28 | -- It's recommended to leave version=false for now, since a lot the plugin that support versioning, 29 | -- have outdated releases, which may break your Neovim install. 30 | version = false, -- always use the latest git commit 31 | -- version = "*", -- try installing the latest stable version for plugins that support semver 32 | }, 33 | -- install = { colorscheme = { "zenbones" } }, 34 | checker = { 35 | enabled = true, -- check for plugin updates periodically 36 | notify = false, -- notify on update 37 | }, -- automatically check for plugin updates 38 | performance = { 39 | rtp = { 40 | -- disable some rtp plugins 41 | disabled_plugins = { 42 | "gzip", 43 | -- "matchit", 44 | -- "matchparen", 45 | -- "netrwPlugin", 46 | "tarPlugin", 47 | "tohtml", 48 | "tutor", 49 | "zipPlugin", 50 | }, 51 | }, 52 | }, 53 | dev = { 54 | path = "~/dev", 55 | patterns = { "mikker" }, 56 | fallback = true, 57 | }, 58 | }) 59 | -------------------------------------------------------------------------------- /nvim/lua/config/options.lua: -------------------------------------------------------------------------------- 1 | -- Options are automatically loaded before lazy.nvim startup 2 | -- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua 3 | -- Add any additional options here 4 | 5 | local opt = vim.opt 6 | 7 | opt.backup = false 8 | opt.clipboard = "" -- don't sync with OS 9 | opt.exrc = true -- auto-source local .nvimrc 10 | opt.history = 10000 11 | 12 | opt.relativenumber = false 13 | opt.signcolumn = "auto" 14 | opt.statuscolumn = "" 15 | opt.spell = false 16 | 17 | opt.swapfile = false 18 | opt.undodir = "~/.tmp,/tmp" 19 | 20 | opt.wrap = true 21 | opt.gdefault = true 22 | 23 | opt.listchars:append({ trail = "·", nbsp = "·" }) 24 | 25 | -- Automatic dark mode on boot 26 | if vim.fn.executable("is-this-dark-mode") then 27 | vim.fn.system("is-this-dark-mode") 28 | if vim.v.shell_error == 0 then 29 | vim.opt.background = "dark" 30 | else 31 | vim.opt.background = "light" 32 | end 33 | end 34 | 35 | if not vim.fn.has("gui_vimr") then 36 | -- vim.opt.guifont = { "Iosevka Light", ":h20" } 37 | vim.opt.guifont = "Iosevka:h20" 38 | end 39 | 40 | local is_ui = vim.fn.has("gui_vimr") == 1 or vim.g.neovide 41 | 42 | if is_ui then 43 | vim.api.nvim_set_keymap("n", "", ":term", {}) 44 | end 45 | 46 | vim.cmd([[ 47 | let g:neovide_cursor_animation_length=0.0001 48 | let g:neovide_cursor_trail_length=0.0001 49 | let g:neovide_refresh_rate=140 50 | ]]) 51 | 52 | if vim.g.neovide then 53 | vim.g.neovide_input_use_logo = 1 -- enable use of the logo (cmd) key 54 | end 55 | 56 | -- lazyvim 57 | vim.g.snacks_animate = false 58 | vim.g.trouble_lualine = false 59 | vim.g.lazyvim_prettier_needs_config = false -- always enable prettier 60 | vim.g.lazyvim_ruby_formatter = "rubyfmt" 61 | -------------------------------------------------------------------------------- /nvim/lua/plugins/ai.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "ravitemer/mcphub.nvim", 4 | dependencies = { 5 | "nvim-lua/plenary.nvim", -- Required for Job and HTTP requests 6 | }, 7 | -- uncomment the following line to load hub lazily 8 | --cmd = "MCPHub", -- lazy load 9 | build = "npm install -g mcp-hub@latest", -- Installs required mcp-hub npm module 10 | -- uncomment this if you don't want mcp-hub to be available globally or can't use -g 11 | -- build = "bundled_build.lua", -- Use this and set use_bundled_binary = true in opts (see Advanced configuration) 12 | config = function() 13 | require("mcphub").setup({ 14 | extensions = { 15 | avante = { 16 | make_slash_commands = true, 17 | }, 18 | }, 19 | }) 20 | end, 21 | }, 22 | { 23 | "yetone/avante.nvim", 24 | event = "VeryLazy", 25 | version = false, -- Never set this value to "*"! Never! 26 | opts = { 27 | -- add any opts here 28 | -- for example 29 | provider = "openai", 30 | openai = { 31 | endpoint = "https://api.openai.com/v1", 32 | model = "gpt-4o", -- your desired model (or use gpt-4o, etc.) 33 | timeout = 30000, -- Timeout in milliseconds, increase this for reasoning models 34 | temperature = 0, 35 | max_completion_tokens = 8192, -- Increase this to include reasoning tokens (for reasoning models) 36 | --reasoning_effort = "medium", -- low|medium|high, only used for reasoning models 37 | }, 38 | }, 39 | -- if you want to build from source then do `make BUILD_FROM_SOURCE=true` 40 | build = "make", 41 | -- build = "powershell -ExecutionPolicy Bypass -File Build.ps1 -BuildFromSource false" -- for windows 42 | dependencies = { 43 | "nvim-treesitter/nvim-treesitter", 44 | "stevearc/dressing.nvim", 45 | "nvim-lua/plenary.nvim", 46 | "MunifTanjim/nui.nvim", 47 | --- The below dependencies are optional, 48 | "echasnovski/mini.pick", -- for file_selector provider mini.pick 49 | "nvim-telescope/telescope.nvim", -- for file_selector provider telescope 50 | "hrsh7th/nvim-cmp", -- autocompletion for avante commands and mentions 51 | "ibhagwan/fzf-lua", -- for file_selector provider fzf 52 | "nvim-tree/nvim-web-devicons", -- or echasnovski/mini.icons 53 | "zbirenbaum/copilot.lua", -- for providers='copilot' 54 | { 55 | -- support for image pasting 56 | "HakonHarnes/img-clip.nvim", 57 | event = "VeryLazy", 58 | opts = { 59 | -- recommended settings 60 | default = { 61 | embed_image_as_base64 = false, 62 | prompt_for_file_name = false, 63 | drag_and_drop = { 64 | insert_mode = true, 65 | }, 66 | -- required for Windows users 67 | use_absolute_path = true, 68 | }, 69 | }, 70 | }, 71 | { 72 | -- Make sure to set this up properly if you have lazy=true 73 | "MeanderingProgrammer/render-markdown.nvim", 74 | opts = { 75 | file_types = { "markdown", "Avante" }, 76 | }, 77 | ft = { "markdown", "Avante" }, 78 | }, 79 | }, 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /nvim/lua/plugins/coding.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "saghen/blink.cmp", 4 | opts = { 5 | keymap = { preset = "super-tab" }, 6 | sources = { 7 | default = { "snippets", "lsp", "path", "buffer" }, 8 | }, 9 | }, 10 | }, 11 | 12 | { "rafamadriz/friendly-snippets", enabled = false }, 13 | { "echasnovski/mini.pairs", enabled = false }, 14 | 15 | "tpope/vim-abolish", -- :S smart replace 16 | "tpope/vim-eunuch", -- unix things 17 | "tpope/vim-fugitive", -- git things 18 | "tpope/vim-rhubarb", -- github things 19 | "tpope/vim-projectionist", -- project navigation 20 | 21 | { 22 | "mikker/vim-rerunner", 23 | dev = true, 24 | cmd = { "Rerun", "RerunWhat" }, 25 | keys = { 26 | { "", "Rerun", desc = "Run", mode = "n" }, 27 | }, 28 | config = function() 29 | vim.g.rerunner_focus = "TestLast" 30 | end, 31 | }, 32 | 33 | { 34 | "mattn/emmet-vim", 35 | init = function() 36 | vim.g.user_emmet_leader_key = "" 37 | end, 38 | }, 39 | } 40 | -------------------------------------------------------------------------------- /nvim/lua/plugins/colorscheme.lua: -------------------------------------------------------------------------------- 1 | return { 2 | -- list 3 | { 4 | "mcchrish/zenbones.nvim", 5 | dependencies = "rktjmp/lush.nvim", 6 | }, 7 | { 8 | "rose-pine/neovim", 9 | name = "rose-pine", 10 | }, 11 | 12 | -- set 13 | { "LazyVim/LazyVim", opts = { colorscheme = "zenwritten" } }, 14 | } 15 | -------------------------------------------------------------------------------- /nvim/lua/plugins/editor.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { "nvim-neo-tree/neo-tree.nvim", enabled = false }, 3 | 4 | { "folke/flash.nvim", enabled = false }, 5 | { "lewis6991/gitsigns.nvim", enabled = false }, 6 | 7 | { 8 | "ibhagwan/fzf-lua", 9 | keys = { 10 | { "", false }, 11 | }, 12 | }, 13 | 14 | -- extras 15 | { 16 | "razak17/tailwind-fold.nvim", 17 | opts = { 18 | enabled = false, 19 | symbol = "󱏿", 20 | }, 21 | keys = { 22 | { "ut", "TailwindFoldToggle", desc = "Toggle Tailwind Fold" }, 23 | }, 24 | dependencies = { "nvim-treesitter/nvim-treesitter" }, 25 | ft = { "html", "svelte", "astro", "vue", "typescriptreact", "php", "blade", "slim", "eruby" }, 26 | }, 27 | 28 | { 29 | "echasnovski/mini.splitjoin", 30 | init = function() 31 | require("mini.splitjoin").setup({}) 32 | end, 33 | }, 34 | 35 | { 36 | "junegunn/vim-easy-align", 37 | keys = { 38 | { "A", "EasyAlign", mode = "x", desc = "Align selection" }, 39 | }, 40 | }, 41 | 42 | -- "echasnovski/mini.bracketed", 43 | "mbbill/undotree", 44 | "whiteinge/diffconflicts", 45 | 46 | { 47 | "stevearc/oil.nvim", 48 | opts = { 49 | delete_to_trash = true, 50 | skip_confirm_for_simple_edits = true, 51 | view_options = { 52 | show_hidden = true, 53 | sort = { 54 | { "name", "asc" }, 55 | { "type", "asc" }, 56 | }, 57 | }, 58 | }, 59 | -- Optional dependencies 60 | dependencies = { "nvim-tree/nvim-web-devicons" }, 61 | keys = { 62 | { "-", "Oil" }, 63 | }, 64 | }, 65 | } 66 | -------------------------------------------------------------------------------- /nvim/lua/plugins/formatting.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "stevearc/conform.nvim", 4 | opts = { 5 | formatters_by_ft = { 6 | solidity = { "forge" }, 7 | eruby = { "erb_format", "rustywind" }, 8 | slim = { "rustywind" }, 9 | ruby = { "rubyfmt", "rustywind" }, 10 | yaml = {}, 11 | -- Disable erb_format for YAML files 12 | ["eruby.yaml"] = { "rustywind" }, 13 | }, 14 | formatters = { 15 | forge = { 16 | command = "forge", 17 | args = { "fmt", "-r", "-" }, 18 | stdin = true, 19 | }, 20 | }, 21 | }, 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /nvim/lua/plugins/lsp.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "neovim/nvim-lspconfig", 4 | init = function() 5 | local keys = require("lazyvim.plugins.lsp.keymaps").get() 6 | keys[#keys + 1] = { "[w", false } 7 | keys[#keys + 1] = { "]w", false } 8 | end, 9 | opts = { 10 | inlay_hints = { enabled = false }, 11 | servers = { 12 | tailwindcss = { 13 | filetypes_include = { "slim", "ruby", "eruby" }, 14 | settings = { 15 | tailwindCSS = { 16 | includeLanguages = { 17 | slim = "html", 18 | erb = "html", 19 | eruby = "html", 20 | ruby = "html", 21 | }, 22 | emmetCompletions = true, 23 | experimental = { 24 | classRegex = { 25 | "\\bclass:\\s*['\"]([^'\"]*)['\"]", 26 | "\\b(class_names|tokens)[\\(|\\s]\\s*['\"]([^'\"]*)['\"]", 27 | "\\b(CL|ClassList\\.new)[\\(|\\s]\\s*['\"]([^'\"]*)['\"]", 28 | }, 29 | }, 30 | }, 31 | }, 32 | }, 33 | }, 34 | }, 35 | }, 36 | 37 | { 38 | "williamboman/mason.nvim", 39 | opts = { 40 | ensure_installed = { 41 | "stylua", 42 | "shfmt", 43 | "rubyfmt", 44 | "rustywind", 45 | "tailwindcss-language-server", 46 | "typescript-language-server", 47 | "erb-formatter", 48 | "eslint-lsp", 49 | }, 50 | }, 51 | }, 52 | } 53 | -------------------------------------------------------------------------------- /nvim/lua/plugins/ruby.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "tpope/vim-rails", 4 | config = function() 5 | -- disable setting ft=eruby.yaml 6 | vim.api.nvim_create_autocmd({ "BufNewFile", "BufReadPost" }, { 7 | pattern = { "*.yml" }, 8 | callback = function() 9 | vim.bo.filetype = "yaml" 10 | end, 11 | }) 12 | end, 13 | }, 14 | "tpope/vim-rake", 15 | { 16 | "slim-template/vim-slim", 17 | dependencies = { "tpope/vim-haml" }, 18 | }, 19 | "vim-ruby/vim-ruby", 20 | "zackhsi/sorbet.vim", 21 | 22 | { 23 | "nvim-treesitter/nvim-treesitter", 24 | opts = function(_, opts) 25 | vim.list_extend(opts.ensure_installed, { 26 | "ruby", 27 | }) 28 | end, 29 | }, 30 | 31 | -- better matchup for ruby 32 | { "andymass/vim-matchup" }, 33 | { 34 | "nvim-treesitter/nvim-treesitter", 35 | config = function(_, opts) 36 | opts.matchup = { enable = true, disable = { "ruby" } } 37 | end, 38 | }, 39 | "tpope/vim-endwise", 40 | 41 | -- https://github.com/Shopify/ruby-lsp/blob/main/EDITORS.md#lazyvim-lsp 42 | -- { 43 | -- "neovim/nvim-lspconfig", 44 | -- servers = { 45 | -- ruby_lsp = { 46 | -- mason = false, 47 | -- cmd = { vim.fn.expand("~/.asdf/shims/ruby-lsp") }, 48 | -- }, 49 | -- }, 50 | -- }, 51 | } 52 | -------------------------------------------------------------------------------- /nvim/lua/plugins/test.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "janko-m/vim-test", 4 | init = function() 5 | vim.cmd([[ 6 | " Use :TT for vim-test 7 | fun! TTStrategy(cmd) 8 | execute 'TT ' . a:cmd 9 | endfun 10 | 11 | let g:test#custom_strategies = { "tt": function('TTStrategy') } 12 | 13 | let test#strategy = "tt" 14 | " let test#strategy = "vtr" 15 | 16 | let test#custom_runners = {'Solidity': ['Forge']} 17 | 18 | let test#solidity#patterns = { 19 | \ 'test': [ 20 | \ '\v^\s*function (test[^(]+)', 21 | \ ], 22 | \ 'namespace': [ 23 | \ '\v^\s*contract (\S+)', 24 | \ ] 25 | \ } 26 | ]]) 27 | end, 28 | keys = { 29 | { "tt", "TestNearest", { desc = "Test nearest", silent = true } }, 30 | { "tT", "TestFile", { desc = "Test file", silent = true } }, 31 | { "ta", "TestSuite", { desc = "Test suite", silent = true } }, 32 | { "tl", "TestLast", { desc = "Test last", silent = true } }, 33 | { "tg", "TestVisit", { dest = "Go to last tested", silent = true } }, 34 | }, 35 | }, 36 | } 37 | -------------------------------------------------------------------------------- /nvim/lua/plugins/treesitter.lua: -------------------------------------------------------------------------------- 1 | return { 2 | -- { 3 | -- "windwp/nvim-ts-autotag", 4 | -- enabled = false, 5 | -- }, 6 | } 7 | -------------------------------------------------------------------------------- /nvim/lua/plugins/ui.lua: -------------------------------------------------------------------------------- 1 | local logo = [[ 2 | .:-====--:. 3 | .-++ =++-: 4 | -++: :=+=: 5 | .-=+++====+**#*=-:. .=*- 6 | .++:. :*-:+*+-=++=-. .++ 7 | .*= :*: .=*- .:-++=: =* 8 | -# .*- -++-. :=++: *- 9 | .*- ++ .-=++-:...-++: *= 10 | .=*=:.. :#. .:-=+++***=. #- 11 | .:-=+***. .:::: :*+.=* 12 | =*=--=++- -*=-::-++-....:::--+##: 13 | .*= +*+++#= .+*=---:::-#+=+*: 14 | +* *: -# :#. -* 15 | =* =+ :#. -* :# 16 | =*-. :*. -*- .=*: ++ 17 | -=**+*= -+++++=: .++ 18 | ]] 19 | 20 | return { 21 | -- no bufferline 22 | { "akinsho/bufferline.nvim", enabled = false }, 23 | 24 | { 25 | "nvim-lualine/lualine.nvim", 26 | opts = function(_, opts) 27 | opts.options.section_separators = "" 28 | opts.options.component_separators = "" 29 | opts.sections.lualine_x = { { require("mcphub.extensions.lualine") } } 30 | opts.sections.lualine_y = {} 31 | opts.sections.lualine_z = {} 32 | return opts 33 | end, 34 | }, 35 | 36 | -- no indent guides 37 | { "lukas-reineke/indent-blankline.nvim", enabled = false }, 38 | 39 | -- no fancy ui 40 | { "folke/noice.nvim", enabled = false }, 41 | -- { "stevearc/dressing.nvim", enabled = false }, 42 | 43 | -- extend which-key legend 44 | { 45 | "folke/which-key.nvim", 46 | opts = function() 47 | local wk = require("which-key") 48 | wk.add({ 49 | { "m", group = "+rerun" }, 50 | { "t", group = "+vimtest" }, 51 | { "v", group = "+nvimrc" }, 52 | }) 53 | end, 54 | }, 55 | 56 | { 57 | "folke/snacks.nvim", 58 | opts = { 59 | dashboard = { 60 | preset = { 61 | keys = { 62 | { icon = " ", key = "f", desc = "Find File", action = ":lua Snacks.picker.files()" }, 63 | -- { icon = " ", key = "n", desc = "New File", action = ":ene | startinsert" }, 64 | -- { icon = " ", key = "g", desc = "Find Text", action = ":lua Snacks.dashboard.pick('live_grep')" }, 65 | { icon = " ", key = "r", desc = "Recent Files", action = ":lua Snacks.picker.recent()" }, 66 | { 67 | icon = " ", 68 | key = "c", 69 | desc = "Config", 70 | action = ":lua Snacks.picker.files({cwd = vim.fn.stdpath('config')})", 71 | }, 72 | -- { icon = " ", key = "s", desc = "Restore Session", section = "session" }, 73 | { icon = "󰒲 ", key = "l", desc = "Lazy", action = ":Lazy", enabled = package.loaded.lazy }, 74 | { icon = " ", key = "q", desc = "Quit", action = ":qa" }, 75 | }, 76 | header = logo, 77 | }, 78 | }, 79 | image = { 80 | enabled = false, 81 | }, 82 | }, 83 | }, 84 | } 85 | -------------------------------------------------------------------------------- /nvim/snippets/all.json: -------------------------------------------------------------------------------- 1 | { 2 | "asdf": { 3 | "prefix": "asdf", 4 | "body": ["hi, $1 asdf $0"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /nvim/snippets/html.json: -------------------------------------------------------------------------------- 1 | { 2 | "doctype": { 3 | "prefix": "doctype", 4 | "body": ["", "$1"], 5 | "description": "HTML - Defines the document type", 6 | "scope": "text.html" 7 | }, 8 | "a": { 9 | "prefix": "a", 10 | "body": "$2$3", 11 | "description": "HTML - Defines a hyperlink", 12 | "scope": "text.html" 13 | }, 14 | "abbr": { 15 | "prefix": "abbr", 16 | "body": "$2$3", 17 | "description": "HTML - Defines an abbreviation", 18 | "scope": "text.html" 19 | }, 20 | "address": { 21 | "prefix": "address", 22 | "body": ["
", "$1", "
"], 23 | "description": "HTML - Defines an address element", 24 | "scope": "text.html" 25 | }, 26 | "area": { 27 | "prefix": "area", 28 | "body": "\"$4\"$5", 29 | "description": "HTML - Defines an area inside an image map", 30 | "scope": "text.html" 31 | }, 32 | "article": { 33 | "prefix": "article", 34 | "body": ["
", "\t$1", "
"], 35 | "description": "HTML - Defines an article", 36 | "scope": "text.html" 37 | }, 38 | "aside": { 39 | "prefix": "aside", 40 | "body": ["$2"], 41 | "description": "HTML - Defines content aside from the page content", 42 | "scope": "text.html" 43 | }, 44 | "audio": { 45 | "prefix": "audio", 46 | "body": [""], 47 | "description": "HTML - Defines sounds content", 48 | "scope": "text.html" 49 | }, 50 | "b": { 51 | "prefix": "b", 52 | "body": "$1$2", 53 | "description": "HTML - Defines bold text", 54 | "scope": "text.html" 55 | }, 56 | "base": { 57 | "prefix": "base", 58 | "body": "$3", 59 | "description": "HTML - Defines a base URL for all the links in a page", 60 | "scope": "text.html" 61 | }, 62 | "bdi": { 63 | "prefix": "bdi", 64 | "body": "$1$2", 65 | "description": "HTML - Used to isolate text that is of unknown directionality", 66 | "scope": "text.html" 67 | }, 68 | "bdo": { 69 | "prefix": "bdo", 70 | "body": ["", "$2", ""], 71 | "description": "HTML - Defines the direction of text display", 72 | "scope": "text.html" 73 | }, 74 | "big": { 75 | "prefix": "big", 76 | "body": "$1$2", 77 | "description": "HTML - Used to make text bigger", 78 | "scope": "text.html" 79 | }, 80 | "blockquote": { 81 | "prefix": "blockquote", 82 | "body": ["
", "\t$1", "
"], 83 | "description": "HTML - Defines a long quotation", 84 | "scope": "text.html" 85 | }, 86 | "body": { 87 | "prefix": "body", 88 | "body": ["", "\t$0", ""], 89 | "description": "HTML - Defines the body element", 90 | "scope": "text.html" 91 | }, 92 | "br": { 93 | "prefix": "br", 94 | "body": "
", 95 | "description": "HTML - Inserts a single line break", 96 | "scope": "text.html" 97 | }, 98 | "button": { 99 | "prefix": "button", 100 | "body": "$3", 101 | "description": "HTML - Defines a push button", 102 | "scope": "text.html" 103 | }, 104 | "canvas": { 105 | "prefix": "canvas", 106 | "body": "$2$3", 107 | "description": "HTML - Defines graphics", 108 | "scope": "text.html" 109 | }, 110 | "caption": { 111 | "prefix": "caption", 112 | "body": "$1$2", 113 | "description": "HTML - Defines a table caption", 114 | "scope": "text.html" 115 | }, 116 | "cite": { 117 | "prefix": "cite", 118 | "body": "$1$2", 119 | "description": "HTML - Defines a citation", 120 | "scope": "text.html" 121 | }, 122 | "code": { 123 | "prefix": "code", 124 | "body": "$1$2", 125 | "description": "HTML - Defines computer code text", 126 | "scope": "text.html" 127 | }, 128 | "col": { 129 | "prefix": "col", 130 | "body": "$2", 131 | "description": "HTML - Defines attributes for table columns", 132 | "scope": "text.html" 133 | }, 134 | "colgroup": { 135 | "prefix": "colgroup", 136 | "body": ["", "\t$1", ""], 137 | "description": "HTML - Defines group of table columns", 138 | "scope": "text.html" 139 | }, 140 | "command": { 141 | "prefix": "command", 142 | "body": "$1$2", 143 | "description": "HTML - Defines a command button [not supported]", 144 | "scope": "text.html" 145 | }, 146 | "datalist": { 147 | "prefix": "datalist", 148 | "body": ["", "\t$1", ""], 149 | "description": "HTML - Defines a dropdown list", 150 | "scope": "text.html" 151 | }, 152 | "dd": { 153 | "prefix": "dd", 154 | "body": "
$1
$2", 155 | "description": "HTML - Defines a definition description", 156 | "scope": "text.html" 157 | }, 158 | "del": { 159 | "prefix": "del", 160 | "body": "$1$2", 161 | "description": "HTML - Defines deleted text", 162 | "scope": "text.html" 163 | }, 164 | "details": { 165 | "prefix": "details", 166 | "body": ["
", "\t$1", "
"], 167 | "description": "HTML - Defines details of an element", 168 | "scope": "text.html" 169 | }, 170 | "dialog": { 171 | "prefix": "dialog", 172 | "body": "$1$2", 173 | "description": "HTML - Defines a dialog (conversation)", 174 | "scope": "text.html" 175 | }, 176 | "dfn": { 177 | "prefix": "dfn", 178 | "body": "$1$2", 179 | "description": "HTML - Defines a definition term", 180 | "scope": "text.html" 181 | }, 182 | "div": { 183 | "prefix": "div", 184 | "body": ["
", "\t$1", "
"], 185 | "description": "HTML - Defines a section in a document", 186 | "scope": "text.html" 187 | }, 188 | "dl": { 189 | "prefix": "dl", 190 | "body": ["
", "\t$1", "
"], 191 | "description": "HTML - Defines a definition list", 192 | "scope": "text.html" 193 | }, 194 | "dt": { 195 | "prefix": "dt", 196 | "body": "
$1
$2", 197 | "description": "HTML - Defines a definition term", 198 | "scope": "text.html" 199 | }, 200 | "em": { 201 | "prefix": "em", 202 | "body": "$1$2", 203 | "description": "HTML - Defines emphasized text", 204 | "scope": "text.html" 205 | }, 206 | "embed": { 207 | "prefix": "embed", 208 | "body": "$2", 209 | "description": "HTML - Defines external interactive content ot plugin", 210 | "scope": "text.html" 211 | }, 212 | "fieldset": { 213 | "prefix": "fieldset", 214 | "body": ["
", "\t$1", "
"], 215 | "description": "HTML - Defines a fieldset", 216 | "scope": "text.html" 217 | }, 218 | "figcaption": { 219 | "prefix": "figcaption", 220 | "body": "
$1
$2", 221 | "description": "HTML - Defines a caption for a figure", 222 | "scope": "text.html" 223 | }, 224 | "figure": { 225 | "prefix": "figure", 226 | "body": ["
", "\t$1", "
"], 227 | "description": "HTML - Defines a group of media content, and their caption", 228 | "scope": "text.html" 229 | }, 230 | "footer": { 231 | "prefix": "footer", 232 | "body": ["
", "\t$1", "
"], 233 | "description": "HTML - Defines a footer for a section or page", 234 | "scope": "text.html" 235 | }, 236 | "form": { 237 | "prefix": "form", 238 | "body": ["
", "\t$1", "
"], 239 | "description": "HTML - Defines a form", 240 | "scope": "text.html" 241 | }, 242 | "h1": { 243 | "prefix": "h1", 244 | "body": "

$1

$2", 245 | "description": "HTML - Defines header 1", 246 | "scope": "text.html" 247 | }, 248 | "h2": { 249 | "prefix": "h2", 250 | "body": "

$1

$2", 251 | "description": "HTML - Defines header 2", 252 | "scope": "text.html" 253 | }, 254 | "h3": { 255 | "prefix": "h3", 256 | "body": "

$1

$2", 257 | "description": "HTML - Defines header 3", 258 | "scope": "text.html" 259 | }, 260 | "h4": { 261 | "prefix": "h4", 262 | "body": "

$1

$2", 263 | "description": "HTML - Defines header 4", 264 | "scope": "text.html" 265 | }, 266 | "h5": { 267 | "prefix": "h5", 268 | "body": "
$1
$2", 269 | "description": "HTML - Defines header 5", 270 | "scope": "text.html" 271 | }, 272 | "h6": { 273 | "prefix": "h6", 274 | "body": "
$1
$2", 275 | "description": "HTML - Defines header 6", 276 | "scope": "text.html" 277 | }, 278 | "head": { 279 | "prefix": "head", 280 | "body": ["", "\t$1", ""], 281 | "description": "HTML - Defines information about the document", 282 | "scope": "text.html" 283 | }, 284 | "header": { 285 | "prefix": "header", 286 | "body": ["
", "\t$1", "
"], 287 | "description": "HTML - Defines a header for a section of page", 288 | "scope": "text.html" 289 | }, 290 | "hgroup": { 291 | "prefix": "hgroup", 292 | "body": ["
", "\t$1", "
"], 293 | "description": "HTML - Defines information about a section in a document", 294 | "scope": "text.html" 295 | }, 296 | "hr": { 297 | "prefix": "hr", 298 | "body": "
", 299 | "description": "HTML - Defines a horizontal rule", 300 | "scope": "text.html" 301 | }, 302 | "html": { 303 | "prefix": "html", 304 | "body": ["", "\t$0", ""], 305 | "description": "HTML - Defines an html document", 306 | "scope": "text.html" 307 | }, 308 | "html5": { 309 | "prefix": "html5", 310 | "body": [ 311 | "", 312 | "", 313 | "\t", 314 | "\t\t", 315 | "\t\t", 316 | "\t\t$2", 317 | "\t\t", 318 | "\t", 319 | "\t", 320 | "\t$0", 321 | "\t", 322 | "" 323 | ], 324 | "description": "HTML - Defines a template for a html5 document", 325 | "scope": "text.html" 326 | }, 327 | "i": { 328 | "prefix": "i", 329 | "body": "$1$2", 330 | "description": "HTML - Defines italic text", 331 | "scope": "text.html" 332 | }, 333 | "iframe": { 334 | "prefix": "iframe", 335 | "body": "$3", 336 | "description": "HTML - Defines an inline sub window", 337 | "scope": "text.html" 338 | }, 339 | "img": { 340 | "prefix": "img", 341 | "body": "\"$2\"$3", 342 | "description": "HTML - Defines an image", 343 | "scope": "text.html" 344 | }, 345 | "input": { 346 | "prefix": "input", 347 | "body": "$4", 348 | "description": "HTML - Defines an input field", 349 | "scope": "text.html" 350 | }, 351 | "ins": { 352 | "prefix": "ins", 353 | "body": "$1$2", 354 | "description": "HTML - Defines inserted text", 355 | "scope": "text.html" 356 | }, 357 | "keygen": { 358 | "prefix": "keygen", 359 | "body": "$2", 360 | "description": "HTML - Defines a generated key in a form", 361 | "scope": "text.html" 362 | }, 363 | "kbd": { 364 | "prefix": "kbd", 365 | "body": "$1$2", 366 | "description": "HTML - Defines keyboard text", 367 | "scope": "text.html" 368 | }, 369 | "label": { 370 | "prefix": "label", 371 | "body": "$3", 372 | "description": "HTML - Defines an inline window", 373 | "scope": "text.html" 374 | }, 375 | "legend": { 376 | "prefix": "legend", 377 | "body": "$1$2", 378 | "description": "HTML - Defines a title in a fieldset", 379 | "scope": "text.html" 380 | }, 381 | "li": { 382 | "prefix": "li", 383 | "body": "
  • $1
  • $2", 384 | "description": "HTML - Defines a list item", 385 | "scope": "text.html" 386 | }, 387 | "link": { 388 | "prefix": "link", 389 | "body": "$4", 390 | "description": "HTML - Defines a resource reference", 391 | "scope": "text.html" 392 | }, 393 | "main": { 394 | "prefix": "main", 395 | "body": ["
    ", "\t$1", "
    "], 396 | "description": "HTML - Defines an image map", 397 | "scope": "text.html" 398 | }, 399 | "map": { 400 | "prefix": "map", 401 | "body": ["", "\t$2", ""], 402 | "description": "HTML - Defines an image map", 403 | "scope": "text.html" 404 | }, 405 | "mark": { 406 | "prefix": "mark", 407 | "body": "$1$2", 408 | "description": "HTML - Defines marked text", 409 | "scope": "text.html" 410 | }, 411 | "menu": { 412 | "prefix": "menu", 413 | "body": ["", "\t$1", ""], 414 | "description": "HTML - Defines a menu list", 415 | "scope": "text.html" 416 | }, 417 | "menuitem": { 418 | "prefix": "menuitem", 419 | "body": "$1$2", 420 | "description": "HTML - Defines a menu item [firefox only]", 421 | "scope": "text.html" 422 | }, 423 | "meta": { 424 | "prefix": "meta", 425 | "body": "$3", 426 | "description": "HTML - Defines meta information", 427 | "scope": "text.html" 428 | }, 429 | "meter": { 430 | "prefix": "meter", 431 | "body": "$2$3", 432 | "description": "HTML - Defines measurement within a predefined range", 433 | "scope": "text.html" 434 | }, 435 | "nav": { 436 | "prefix": "nav", 437 | "body": [""], 438 | "description": "HTML - Defines navigation links", 439 | "scope": "text.html" 440 | }, 441 | "noscript": { 442 | "prefix": "noscript", 443 | "body": [""], 444 | "description": "HTML - Defines a noscript section", 445 | "scope": "text.html" 446 | }, 447 | "object": { 448 | "prefix": "object", 449 | "body": "$4$5", 450 | "description": "HTML - Defines an embedded object", 451 | "scope": "text.html" 452 | }, 453 | "ol": { 454 | "prefix": "ol", 455 | "body": ["
      ", "\t$1", "
    "], 456 | "description": "HTML - Defines an ordered list", 457 | "scope": "text.html" 458 | }, 459 | "optgroup": { 460 | "prefix": "optgroup", 461 | "body": ["", "\t$1", ""], 462 | "description": "HTML - Defines an option group", 463 | "scope": "text.html" 464 | }, 465 | "option": { 466 | "prefix": "option", 467 | "body": "$3", 468 | "description": "HTML - Defines an option in a drop-down list", 469 | "scope": "text.html" 470 | }, 471 | "output": { 472 | "prefix": "output", 473 | "body": "$3$4", 474 | "description": "HTML - Defines some types of output", 475 | "scope": "text.html" 476 | }, 477 | "p": { 478 | "prefix": "p", 479 | "body": "

    $1

    $2", 480 | "description": "HTML - Defines a paragraph", 481 | "scope": "text.html" 482 | }, 483 | "param": { 484 | "prefix": "param", 485 | "body": "$3", 486 | "description": "HTML - Defines a parameter for an object", 487 | "scope": "text.html" 488 | }, 489 | "pre": { 490 | "prefix": "pre", 491 | "body": ["
    $1
    "], 492 | "description": "HTML - Defines preformatted text", 493 | "scope": "text.html" 494 | }, 495 | "progress": { 496 | "prefix": "progress", 497 | "body": "$3$4", 498 | "description": "HTML - Defines progress of a task of any kind", 499 | "scope": "text.html" 500 | }, 501 | "q": { 502 | "prefix": "q", 503 | "body": "$1$2", 504 | "description": "HTML - Defines a short quotation", 505 | "scope": "text.html" 506 | }, 507 | "rp": { 508 | "prefix": "rp", 509 | "body": "$1$2", 510 | "description": "HTML - Used in ruby annotations to define what to show browsers that do not support the ruby element", 511 | "scope": "text.html" 512 | }, 513 | "rt": { 514 | "prefix": "rt", 515 | "body": "$1$2", 516 | "description": "HTML - Defines explanation to ruby annotations", 517 | "scope": "text.html" 518 | }, 519 | "ruby": { 520 | "prefix": "ruby", 521 | "body": ["", "$1", ""], 522 | "description": "HTML - Defines ruby annotations", 523 | "scope": "text.html" 524 | }, 525 | "s": { 526 | "prefix": "s", 527 | "body": "$1$2", 528 | "description": "HTML - Used to define strikethrough text", 529 | "scope": "text.html" 530 | }, 531 | "samp": { 532 | "prefix": "samp", 533 | "body": "$1$2", 534 | "description": "HTML - Defines sample computer code", 535 | "scope": "text.html" 536 | }, 537 | "script": { 538 | "prefix": "script", 539 | "body": [""], 540 | "description": "HTML - Defines a script", 541 | "scope": "text.html" 542 | }, 543 | "section": { 544 | "prefix": "section", 545 | "body": ["
    ", "\t$1", "
    "], 546 | "description": "HTML - Defines a section", 547 | "scope": "text.html" 548 | }, 549 | "select": { 550 | "prefix": "select", 551 | "body": [""], 552 | "description": "HTML - Defines a selectable list", 553 | "scope": "text.html" 554 | }, 555 | "small": { 556 | "prefix": "small", 557 | "body": "$1$2", 558 | "description": "HTML - Defines small text", 559 | "scope": "text.html" 560 | }, 561 | "source": { 562 | "prefix": "source", 563 | "body": "$3", 564 | "description": "HTML - Defines media resource", 565 | "scope": "text.html" 566 | }, 567 | "span": { 568 | "prefix": "span", 569 | "body": "$1$2", 570 | "description": "HTML - Defines a section in a document", 571 | "scope": "text.html" 572 | }, 573 | "strong": { 574 | "prefix": "strong", 575 | "body": "$1$2", 576 | "description": "HTML - Defines strong text", 577 | "scope": "text.html" 578 | }, 579 | "style": { 580 | "prefix": "style", 581 | "body": [""], 582 | "description": "HTML - Defines a style definition", 583 | "scope": "text.html" 584 | }, 585 | "sub": { 586 | "prefix": "sub", 587 | "body": "$1$2", 588 | "description": "HTML - Defines sub-scripted text", 589 | "scope": "text.html" 590 | }, 591 | "sup": { 592 | "prefix": "sup", 593 | "body": "$1$2", 594 | "description": "HTML - Defines super-scripted text", 595 | "scope": "text.html" 596 | }, 597 | "summary": { 598 | "prefix": "summary", 599 | "body": "$1$2", 600 | "description": "HTML - Defines a visible heading for the detail element [limited support]", 601 | "scope": "text.html" 602 | }, 603 | "table": { 604 | "prefix": "table", 605 | "body": ["", "\t$1", "
    "], 606 | "description": "HTML - Defines a table", 607 | "scope": "text.html" 608 | }, 609 | "tbody": { 610 | "prefix": "tbody", 611 | "body": ["", "\t$1", ""], 612 | "description": "HTML - Defines a table body", 613 | "scope": "text.html" 614 | }, 615 | "td": { 616 | "prefix": "td", 617 | "body": "$1$2", 618 | "description": "HTML - Defines a table cell", 619 | "scope": "text.html" 620 | }, 621 | "textarea": { 622 | "prefix": "textarea", 623 | "body": "$4", 624 | "description": "HTML - Defines a text area", 625 | "scope": "text.html" 626 | }, 627 | "tfoot": { 628 | "prefix": "tfoot", 629 | "body": ["", "\t$1", ""], 630 | "description": "HTML - Defines a table footer", 631 | "scope": "text.html" 632 | }, 633 | "thead": { 634 | "prefix": "thead", 635 | "body": ["", "$1", ""], 636 | "description": "HTML - Defines a table head", 637 | "scope": "text.html" 638 | }, 639 | "th": { 640 | "prefix": "th", 641 | "body": "$1$2", 642 | "description": "HTML - Defines a table header", 643 | "scope": "text.html" 644 | }, 645 | "time": { 646 | "prefix": "time", 647 | "body": "$3", 648 | "description": "HTML - Defines a date/time", 649 | "scope": "text.html" 650 | }, 651 | "title": { 652 | "prefix": "title", 653 | "body": "$1$2", 654 | "description": "HTML - Defines the document title", 655 | "scope": "text.html" 656 | }, 657 | "tr": { 658 | "prefix": "tr", 659 | "body": "$1$2", 660 | "description": "HTML - Defines a table row", 661 | "scope": "text.html" 662 | }, 663 | "track": { 664 | "prefix": "track", 665 | "body": "$5", 666 | "description": "HTML - Defines a table row", 667 | "scope": "text.html" 668 | }, 669 | "u": { 670 | "prefix": "u", 671 | "body": "$1$2", 672 | "description": "HTML - Used to define underlined text", 673 | "scope": "text.html" 674 | }, 675 | "ul": { 676 | "prefix": "ul", 677 | "body": ["
      ", "\t$1", "
    "], 678 | "description": "HTML - Defines an unordered list", 679 | "scope": "text.html" 680 | }, 681 | "var": { 682 | "prefix": "var", 683 | "body": "$1$2", 684 | "description": "HTML - Defines a variable", 685 | "scope": "text.html" 686 | }, 687 | "video": { 688 | "prefix": "video", 689 | "body": [ 690 | "" 693 | ], 694 | "description": "HTML - Defines a video", 695 | "scope": "text.html" 696 | }, 697 | "div.": { 698 | "prefix": "div.", 699 | "body": ["
    ", "\t$2", "
    "], 700 | "description": "HTML - Defines a section in a document", 701 | "scope": "text.html" 702 | }, 703 | "div#": { 704 | "prefix": "div#", 705 | "body": ["
    ", "\t$2", "
    "], 706 | "description": "HTML - Defines a section in a document", 707 | "scope": "text.html" 708 | }, 709 | "div.#": { 710 | "prefix": "div.#", 711 | "body": ["
    ", "\t$3", "
    "], 712 | "description": "HTML - Defines a section in a document", 713 | "scope": "text.html" 714 | }, 715 | "p.": { 716 | "prefix": "p.", 717 | "body": ["

    $2

    "], 718 | "description": "HTML - Defines a paragraph", 719 | "scope": "text.html" 720 | }, 721 | "p#": { 722 | "prefix": "p#", 723 | "body": ["

    $2

    "], 724 | "description": "HTML - Defines a paragraph", 725 | "scope": "text.html" 726 | }, 727 | "p.#": { 728 | "prefix": "p.#", 729 | "body": ["

    $3

    "], 730 | "description": "HTML - Defines a paragraph", 731 | "scope": "text.html" 732 | }, 733 | "ul.": { 734 | "prefix": "ul.", 735 | "body": ["
      ", "\t$2", "
    "], 736 | "description": "HTML - Defines an unordered list", 737 | "scope": "text.html" 738 | }, 739 | "ul#": { 740 | "prefix": "ul#", 741 | "body": ["
      ", "\t$2", "
    "], 742 | "description": "HTML - Defines an unordered list", 743 | "scope": "text.html" 744 | }, 745 | "ul.#": { 746 | "prefix": "ul.#", 747 | "body": ["
      ", "\t$3", "
    "], 748 | "description": "HTML - Defines an unordered list", 749 | "scope": "text.html" 750 | }, 751 | "ol.": { 752 | "prefix": "ol.", 753 | "body": ["
      ", "\t$2", "
    "], 754 | "description": "HTML - Defines an ordered list", 755 | "scope": "text.html" 756 | }, 757 | "ol#": { 758 | "prefix": "ol#", 759 | "body": ["
      ", "\t$2", "
    "], 760 | "description": "HTML - Defines an ordered list", 761 | "scope": "text.html" 762 | }, 763 | "ol.#": { 764 | "prefix": "ol.#", 765 | "body": ["
      ", "\t$3", "
    "], 766 | "description": "HTML - Defines an ordered list", 767 | "scope": "text.html" 768 | } 769 | } 770 | -------------------------------------------------------------------------------- /nvim/snippets/javascript.json: -------------------------------------------------------------------------------- 1 | { 2 | "console.log(...)": { 3 | "prefix": "cl", 4 | "body": ["console.log($0);"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /nvim/snippets/typescript.json: -------------------------------------------------------------------------------- 1 | { 2 | "console.log(...)": { 3 | "prefix": "cl", 4 | "body": ["console.log($0);"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /nvim/snippets/typescriptreact.json: -------------------------------------------------------------------------------- 1 | { 2 | "console.log(...)": { 3 | "prefix": "cl", 4 | "body": ["console.log($0);"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /nvim/spell/da.utf-8.spl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikker/dotfiles/90ddb8665f409762cc31e9a9cd7343e425e19cc8/nvim/spell/da.utf-8.spl -------------------------------------------------------------------------------- /nvim/spell/en.utf-8.spl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikker/dotfiles/90ddb8665f409762cc31e9a9cd7343e425e19cc8/nvim/spell/en.utf-8.spl -------------------------------------------------------------------------------- /nvim/spell/en.utf-8.sug: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikker/dotfiles/90ddb8665f409762cc31e9a9cd7343e425e19cc8/nvim/spell/en.utf-8.sug -------------------------------------------------------------------------------- /nvim/stylua.toml: -------------------------------------------------------------------------------- 1 | indent_type = "Spaces" 2 | indent_width = 2 3 | column_width = 120 -------------------------------------------------------------------------------- /other/gems: -------------------------------------------------------------------------------- 1 | gem update --system 2 | gem install \ 3 | bundler \ 4 | gem-shut-the-fuck-up \ 5 | neovim \ 6 | tmuxinator 7 | -------------------------------------------------------------------------------- /other/npm: -------------------------------------------------------------------------------- 1 | npm install -g \ 2 | neovim@latest \ 3 | vercel@latest \ 4 | serve@latest 5 | -------------------------------------------------------------------------------- /rails/railsrc.symlink: -------------------------------------------------------------------------------- 1 | --database=postgresql 2 | -------------------------------------------------------------------------------- /ruby/gemrc.symlink: -------------------------------------------------------------------------------- 1 | --- 2 | :backtrace: false 3 | :bulk_threshold: 1000 4 | :sources: 5 | - https://rubygems.org 6 | :update_sources: true 7 | :verbose: true 8 | :concurrent_downloads: 8 9 | gem: --no-document 10 | -------------------------------------------------------------------------------- /ruby/irbrc.symlink: -------------------------------------------------------------------------------- 1 | IRB.conf[:PROMPT_MODE] = :SIMPLE 2 | 3 | def pbcopy(str) 4 | IO.popen("pbcopy", "w") { |f| f << str.to_s } 5 | end 6 | 7 | def pbpaste 8 | `pbpaste` 9 | end 10 | 11 | # Project-specific .irbrc 12 | # if Dir.pwd != File.expand_path("~") 13 | # local_irbrc = File.expand_path '.irbrc' 14 | # 15 | # if File.exist? local_irbrc 16 | # puts "Loading #{local_irbrc}" 17 | # load local_irbrc 18 | # end 19 | # end 20 | 21 | # vim: ft=ruby 22 | -------------------------------------------------------------------------------- /script/setup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # set -x 3 | # set -e 4 | 5 | DOTFILES_ROOT="`pwd`" 6 | 7 | echo "Install" 8 | 9 | main () { 10 | submodules 11 | symlinks 12 | platform 13 | generic 14 | } 15 | 16 | submodules () { 17 | echo "Initialising submodules" 18 | git submodule init && git submodule update 19 | } 20 | 21 | platform () { 22 | platform="unknown" 23 | if [[ "$(uname)" == "Darwin" ]]; then 24 | platform="macos" 25 | elif [[ "$(expr substr $(uname -s) 1 5)" == "Linux" ]]; then 26 | platform="linux" 27 | elif [[ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]]; then 28 | platform="windows" 29 | fi 30 | 31 | echo "Running installers for $platform" 32 | 33 | find . -name $platform.sh |\ 34 | while read installer ; do echo $installer && sh "${installer}"; done 35 | } 36 | 37 | generic () { 38 | echo "Running generic installers" 39 | 40 | find . -name all.sh |\ 41 | while read installer ; do sh -c "${installer}" > /dev/null ; done 42 | } 43 | 44 | symlinks () { 45 | echo "Create symlinks" 46 | 47 | overwrite_all=false 48 | backup_all=false 49 | skip_all=false 50 | 51 | for source in `find $DOTFILES_ROOT -maxdepth 2 -name \*.symlink`; do 52 | dest="$HOME/.`basename \"${source%.*}\"`" 53 | 54 | if [ -f $dest ] || [ -d $dest ]; then 55 | 56 | overwrite=false 57 | backup=false 58 | skip=false 59 | 60 | if [ "$overwrite_all" == "false" ] && [ "$backup_all" == "false" ] && [ "$skip_all" == "false" ]; then 61 | user "File already exists: `basename $source`, what do? [s]kip, [S]kip all, [o]verwrite, Overwrite [a]ll, [b]ackup, [B]ackup all?" 62 | read -n 1 action 63 | 64 | case "$action" in 65 | o ) 66 | overwrite=true;; 67 | a ) 68 | overwrite_all=true;; 69 | b ) 70 | backup=true;; 71 | B ) 72 | backup_all=true;; 73 | s ) 74 | skip=true;; 75 | S ) 76 | skip_all=true;; 77 | * ) 78 | ;; 79 | esac 80 | fi 81 | 82 | if [ "$overwrite" == "true" ] || [ "$overwrite_all" == "true" ]; then 83 | rm -rf $dest 84 | success "removed $dest" 85 | fi 86 | 87 | if [ "$backup" == "true" ] || [ "$backup_all" == "true" ]; then 88 | mv $dest $dest\.backup 89 | success "moved $dest to $dest.backup" 90 | fi 91 | 92 | if [ "$skip" == "false" ] && [ "$skip_all" == "false" ]; then 93 | link_files $source $dest 94 | else 95 | success "skipped $source" 96 | fi 97 | else 98 | link_files $source $dest 99 | fi 100 | done 101 | } 102 | 103 | info () { 104 | printf " [ \033[00;34m..\033[0m ] $1" 105 | } 106 | user () { 107 | printf "\r [ \033[0;33m?\033[0m ] $1 " 108 | } 109 | success () { 110 | printf "\r\033[2K [ \033[00;32mOK\033[0m ] $1\n" 111 | } 112 | fail () { 113 | printf "\r\033[2K [\033[0;31mFAIL\033[0m] $1\n" 114 | echo '' 115 | exit 116 | } 117 | 118 | link_files () { 119 | ln -s $1 $2 120 | success "Linked $1 to $2" 121 | } 122 | 123 | main 124 | 125 | # vim: fdm=indent foldlevel=0 126 | -------------------------------------------------------------------------------- /sprinkles.symlink/dashboard.simpleanalytics.com.css: -------------------------------------------------------------------------------- 1 | * { font-family: system-ui !important; } 2 | -------------------------------------------------------------------------------- /sprinkles.symlink/github.com.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* --bgColor-default: papayawhip; */ 3 | } 4 | -------------------------------------------------------------------------------- /sprinkles.symlink/github.com.js: -------------------------------------------------------------------------------- 1 | console.log("Loading github.js") 2 | 3 | // ============================================ 4 | // ctrl+r selects and clicks "Rebase and Merge" 5 | // ============================================ 6 | document.addEventListener("keydown", (event) => { 7 | if (event.ctrlKey && event.key === "r") rebase(); 8 | }); 9 | 10 | async function rebase() { 11 | const button = q('[aria-describedby*="loading-announcement"]'); 12 | console.log(button.innerText); 13 | 14 | if (button.innerText !== "Squash and merge") { 15 | // q('[aria-label="Select merge method"]').click(); 16 | // await sleep(250); 17 | // 18 | // q('.js-merge-method-menu button[value="squash"]').click(); 19 | // await sleep(250); 20 | } 21 | 22 | button.click(); 23 | await sleep(100); 24 | 25 | q('[aria-describedby*="loading-announcement"]').click(); 26 | } 27 | 28 | function sleep(delay) { 29 | return new Promise((resolve) => { 30 | setTimeout(resolve, delay); 31 | }); 32 | } 33 | 34 | function q(selector) { 35 | return document.querySelector(selector); 36 | } 37 | -------------------------------------------------------------------------------- /sprinkles.symlink/global.css: -------------------------------------------------------------------------------- 1 | /* This is global.css. 2 | * 3 | * The styles you add here will be added to every page you visit. 4 | * 5 | * To add styles specific to a single domain, create files in this directory, named 6 | * after the domain, eg. "twitter.com.css". 7 | * 8 | * For example, uncomment the line below to get an extra creamy web experience: */ 9 | 10 | /* body { background-color: papayawhip; } */ 11 | -------------------------------------------------------------------------------- /sprinkles.symlink/global.js: -------------------------------------------------------------------------------- 1 | console.log("Loading global.js") 2 | 3 | function main() { 4 | // Keyboard shortcuts 5 | document.addEventListener("keydown", handleKeyDown); 6 | document.addEventListener("keyup", handleKeyUp) 7 | 8 | // Video speed control 9 | document.addEventListener("mouseup", handleVideoSpeedClick); 10 | } 11 | 12 | function handleKeyDown(event) { 13 | // Ctrl+D and Ctrl+U for scrolling 14 | if (onlyCtrl(event)) { 15 | if (event.code === "KeyD") return scroll("down"); 16 | if (event.code === "KeyU") return scroll("up"); 17 | } 18 | 19 | // Ctrl+Alt+S for system font reset 20 | if (event.code === "KeyS" && event.ctrlKey && event.altKey) { 21 | toggleSystemFonts(); 22 | return ok(); 23 | } 24 | 25 | // Cmd+Ctrl+C to copy current URL 26 | if (event.code === "KeyC" && event.ctrlKey && event.metaKey) { 27 | event.preventDefault(); 28 | copyCurrentURL(); 29 | return ok(); 30 | } 31 | } 32 | 33 | function handleKeyUp(event) { 34 | // Key up because otherwise it inputs "/" into field 35 | if ( 36 | event.code === "Slash" && 37 | !document.querySelector("*:focus") && 38 | !event.altKey && 39 | !event.shiftKey && 40 | !event.ctrlKey && 41 | !event.metaKey 42 | ) { 43 | focusSearchField(); 44 | } 45 | } 46 | 47 | function handleVideoSpeedClick(event) { 48 | if (!event.shiftKey || event.ctrlKey || event.metaKey) return; 49 | 50 | const video = findCorrespondingVideoElement(event); 51 | if (!video) return; 52 | 53 | event.preventDefault(); 54 | cycleVideoSpeed(video); 55 | } 56 | 57 | function cycleVideoSpeed(video) { 58 | switch (video.playbackRate) { 59 | case 1: 60 | video.playbackRate = 1.25; 61 | break; 62 | case 1.25: 63 | video.playbackRate = 1.5; 64 | break; 65 | default: 66 | video.playbackRate = 1; 67 | break; 68 | } 69 | 70 | console.log(`%cplayback rate set to ${video.playbackRate}`, "color: purple"); 71 | } 72 | 73 | function scroll(direction) { 74 | const distance = (window.innerHeight / 10) * 5; 75 | const dest = 76 | direction === "up" ? window.scrollY - distance : window.scrollY + distance; 77 | 78 | animateScroll(window.scrollY, dest); 79 | } 80 | 81 | function animateScroll(start, dest) { 82 | let currentTime = 0; 83 | const change = dest - start; 84 | const increment = 20; 85 | const duration = 150; 86 | 87 | function tick() { 88 | currentTime += increment; 89 | const pos = currentTime / duration; 90 | 91 | document.scrollingElement.scrollTo( 92 | 0, 93 | start + change * EasingFunctions.easeOutQuad(pos) 94 | ); 95 | 96 | if (currentTime < duration) { 97 | requestAnimationFrame(tick); 98 | } 99 | } 100 | 101 | tick(); 102 | } 103 | 104 | function onlyCtrl(event) { 105 | return event.ctrlKey && !event.shiftKey && !event.metaKey; 106 | } 107 | 108 | function copyCurrentURL() { 109 | navigator.clipboard 110 | .writeText(window.location.href) 111 | .then(() => { 112 | console.log("%cCopied URL to clipboard", "color: purple"); 113 | }) 114 | .catch((err) => { 115 | console.error("Failed to copy URL:", err); 116 | }); 117 | } 118 | 119 | function focusSearchField() { 120 | let s = document.querySelector('input[type="search"]'); 121 | if (!s) s = document.querySelector('input[type="text"][name="q"]'); 122 | if (!s) s = document.querySelector('input[type="text"][name="search"]'); 123 | if (!s) s = document.querySelector('input[role="search"]'); 124 | if (!s) s = document.querySelector('input[role="searchbox"]'); 125 | if (!s) return; 126 | 127 | console.info("Focusing search input"); 128 | s.focus(); 129 | } 130 | 131 | function toggleSystemFonts() { 132 | console.log("toggleSystemFonts"); 133 | 134 | if (window.systemFontStyleElement) { 135 | window.systemFontStyleElement.remove(); 136 | window.systemFontStyleElement = null; 137 | return; 138 | } 139 | 140 | const s = document.createElement("style"); 141 | s.innerHTML = ` 142 | @import url('https://rsms.me/inter/inter.css'); 143 | html { font-family: 'Inter', sans-serif; } 144 | @supports (font-variation-settings: normal) { 145 | html { font-family: 'Inter var', sans-serif; } 146 | } 147 | 148 | * { 149 | font-family: "Inter var", system-ui, -apple-system, BlinkMacSystemFont, 150 | "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, 151 | "Helvetica Neue", sans-serif !important; 152 | font-weight: 400 !important; 153 | line-height: 1.5 !important; 154 | } 155 | h1, h2, h3, h4, h5, h6 { 156 | font-weight: 600 !important; 157 | } 158 | body { 159 | font-size: 16px; 160 | letter-spacing: 0; 161 | } 162 | p { 163 | max-width: 40em; 164 | } 165 | ul, ol { 166 | line-height: 1.5 !important; 167 | } 168 | pre, code, pre * { 169 | font-family: 'SF Mono', 'Menlo', monospace !important; 170 | } 171 | `; 172 | document.body.appendChild(s); 173 | window.systemFontStyleElement = s; 174 | } 175 | 176 | function setupVideoSpeedThing() { 177 | document.addEventListener("mouseup", (event) => { 178 | if (!event.shiftKey || event.ctrlKey || event.metaKey) return; 179 | 180 | const video = findCorrespondingVideoElement(event); 181 | if (!video) return; 182 | 183 | event.preventDefault(); 184 | 185 | switch (video.playbackRate) { 186 | case 1: 187 | video.playbackRate = 1.25; 188 | break; 189 | case 1.25: 190 | video.playbackRate = 1.5; 191 | break; 192 | default: 193 | video.playbackRate = 1; 194 | break; 195 | } 196 | 197 | console.log( 198 | `%cplayback rate set to ${video.playbackRate}`, 199 | "color: purple" 200 | ); 201 | }); 202 | } 203 | 204 | function setupScrollByCtrlDAndU() { 205 | document.addEventListener("keydown", (event) => { 206 | if (!onlyCtrl(event)) return; 207 | 208 | if (event.code === "KeyD") return scroll("down"); 209 | if (event.code === "KeyU") return scroll("up"); 210 | }); 211 | 212 | function scroll(direction) { 213 | const distance = (window.innerHeight / 10) * 5; 214 | 215 | let dest; 216 | if (direction === "up") { 217 | dest = window.scrollY - distance; 218 | } else { 219 | dest = window.scrollY + distance; 220 | } 221 | 222 | let start = window.scrollY; 223 | let change = dest - start; 224 | let currentTime = 0; 225 | const increment = 20; 226 | const duration = 150; 227 | 228 | function tick() { 229 | currentTime += increment; 230 | const pos = currentTime / duration; 231 | 232 | document.scrollingElement.scrollTo( 233 | 0, 234 | start + change * EasingFunctions.easeOutQuad(pos) 235 | ); 236 | 237 | if (currentTime < duration) { 238 | requestAnimationFrame(tick); 239 | } 240 | } 241 | 242 | tick(); 243 | } 244 | 245 | function onlyCtrl(event) { 246 | return event.ctrlKey && !event.shiftKey && !event.metaKey; 247 | } 248 | } 249 | 250 | function setupSystemFontResetter() { 251 | let styleElm = null; 252 | 253 | document.addEventListener("keydown", (event) => { 254 | if (event.code === "KeyS" && event.ctrlKey && event.altKey) { 255 | if (styleElm) { 256 | styleElm.remove(); 257 | styleElm = null; 258 | return; 259 | } 260 | 261 | const s = document.createElement("style"); 262 | s.innerHTML = ` 263 | @import url('https://rsms.me/inter/inter.css'); 264 | html { font-family: 'Inter', sans-serif; } 265 | @supports (font-variation-settings: normal) { 266 | html { font-family: 'Inter var', sans-serif; } 267 | } 268 | 269 | * { 270 | font-family: "Inter var", system-ui, -apple-system, BlinkMacSystemFont, 271 | "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, 272 | "Helvetica Neue", sans-serif !important; 273 | font-weight: 400 !important; 274 | line-height: 1.5 !important; 275 | } 276 | h1, h2, h3, h4, h5, h6 { 277 | font-weight: 600 !important; 278 | } 279 | body { 280 | font-size: 16px; 281 | letter-spacing: 0; 282 | } 283 | p { 284 | max-width: 40em; 285 | } 286 | ul, ol { 287 | line-height: 1.5 !important; 288 | } 289 | pre, code, pre * { 290 | font-family: 'SF Mono', 'Menlo', monospace !important; 291 | } 292 | `; 293 | document.body.appendChild(s); 294 | 295 | styleElm = s; 296 | } 297 | }); 298 | } 299 | 300 | const EasingFunctions = { 301 | // no easing, no acceleration 302 | linear: function (t) { 303 | return t; 304 | }, 305 | // accelerating from zero velocity 306 | easeInQuad: function (t) { 307 | return t * t; 308 | }, 309 | // decelerating to zero velocity 310 | easeOutQuad: function (t) { 311 | return t * (2 - t); 312 | }, 313 | // acceleration until halfway, then deceleration 314 | easeInOutQuad: function (t) { 315 | return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; 316 | }, 317 | // accelerating from zero velocity 318 | easeInCubic: function (t) { 319 | return t * t * t; 320 | }, 321 | // decelerating to zero velocity 322 | easeOutCubic: function (t) { 323 | return --t * t * t + 1; 324 | }, 325 | // acceleration until halfway, then deceleration 326 | easeInOutCubic: function (t) { 327 | return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; 328 | }, 329 | // accelerating from zero velocity 330 | easeInQuart: function (t) { 331 | return t * t * t * t; 332 | }, 333 | // decelerating to zero velocity 334 | easeOutQuart: function (t) { 335 | return 1 - --t * t * t * t; 336 | }, 337 | // acceleration until halfway, then deceleration 338 | easeInOutQuart: function (t) { 339 | return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t; 340 | }, 341 | // accelerating from zero velocity 342 | easeInQuint: function (t) { 343 | return t * t * t * t * t; 344 | }, 345 | // decelerating to zero velocity 346 | easeOutQuint: function (t) { 347 | return 1 + --t * t * t * t * t; 348 | }, 349 | // acceleration until halfway, then deceleration 350 | easeInOutQuint: function (t) { 351 | return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t; 352 | }, 353 | }; 354 | 355 | function vimeoVideo(event) { 356 | return event.target.ownerDocument.querySelector(".video video"); 357 | } 358 | 359 | function findCorrespondingVideoElement(event) { 360 | if (event.target.tagName === "VIDEO") return event.target; 361 | 362 | const vimeo = vimeoVideo(event); 363 | if (vimeo) return vimeo; 364 | 365 | return undefined; 366 | } 367 | 368 | function ok() { 369 | const div = document.createElement("div"); 370 | div.style.cssText = ` 371 | position: fixed; 372 | bottom: 20px; 373 | right: 20px; 374 | background: rgba(0, 0, 0, 0.8); 375 | backdrop-filter: blur(10px); 376 | border-radius: 50%; 377 | width: 30px; 378 | height: 30px; 379 | display: flex; 380 | align-items: center; 381 | justify-content: center; 382 | box-shadow: 0 2px 5px rgba(0,0,0,0.2); 383 | opacity: 0; 384 | transform: scale(0.5); 385 | transition: all 0.2s ease-out; 386 | `; 387 | 388 | div.innerHTML = ` 389 | 390 | 391 | 392 | `; 393 | 394 | document.body.appendChild(div); 395 | 396 | // Trigger animation 397 | requestAnimationFrame(() => { 398 | div.style.opacity = "1"; 399 | div.style.transform = "scale(1)"; 400 | }); 401 | 402 | // Remove after delay 403 | setTimeout(() => { 404 | div.style.opacity = "0"; 405 | div.style.transform = "scale(0.8)"; 406 | 407 | setTimeout(() => { 408 | div.remove(); 409 | }, 200); 410 | }, 2000); 411 | } 412 | 413 | // Run setup 414 | main(); 415 | -------------------------------------------------------------------------------- /sprinkles.symlink/news.ycombinator.com.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: system-ui !important; 3 | line-height: 1.5; 4 | } 5 | .title { 6 | font-size: 18px; 7 | font-weight: 600; 8 | } 9 | .subtext { 10 | font-size: 14px; 11 | } 12 | .comment { 13 | font-size: 16px; 14 | line-height: 1.5; 15 | max-width: 48em; 16 | } 17 | tr.spacer { 18 | height: 14px !important; 19 | } 20 | 21 | /* Make it more creeaaammmyyy */ 22 | body { 23 | background: papayawhip; 24 | } 25 | 26 | /* Why the hell not? */ 27 | #hnmain { 28 | padding: 12px; 29 | box-shadow: rgba(0, 0, 0, 0.2) 0 2px 25px; 30 | margin: 20px auto; 31 | } 32 | -------------------------------------------------------------------------------- /sprinkles.symlink/youtube.com.css: -------------------------------------------------------------------------------- 1 | body { 2 | --yt-spec-base-background: papayawhip; 3 | } 4 | 5 | @media (prefers-color-scheme: dark) { 6 | body { 7 | --yt-spec-base-background: #111; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /sprinkles.symlink/youtube.com.js: -------------------------------------------------------------------------------- 1 | let clickCount = 0 2 | 3 | const buttonText = () => 4 | `nothing is more important to me than dulling my senses with never ending content (${clickCount})` 5 | 6 | window.addEventListener("load", function () { 7 | const hours = new Date().getHours(); 8 | 9 | if (hours < 9 || hours >= 15) return; 10 | 11 | const blinds = document.createElement("div"); 12 | Object.assign(blinds.style, { 13 | position: "fixed", 14 | top: 0, 15 | left: 0, 16 | right: 0, 17 | bottom: 0, 18 | background: "rgba(255, 255, 255, 0.1)", 19 | zIndex: 9999999, 20 | WebkitBackdropFilter: "blur(20px) grayscale(0.5)", 21 | backdropFilter: "blur(20px) grayscale(0.5)", 22 | display: "flex", 23 | alignItems: "center", 24 | justifyContent: "center", 25 | }); 26 | 27 | const abort = document.createElement("button"); 28 | abort.innerHTML = buttonText(); 29 | abort.style.transform = "scale(1.25)" 30 | abort.onclick = () => { 31 | if (clickCount < 5) { 32 | clickCount += 1 33 | abort.innerHTML = buttonText() 34 | } else { 35 | blinds.remove(); 36 | } 37 | }; 38 | blinds.appendChild(abort); 39 | 40 | document.body.appendChild(blinds); 41 | }); 42 | -------------------------------------------------------------------------------- /tmux/all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | ~/.tmux/plugins/tpm/bin/install_plugins 6 | -------------------------------------------------------------------------------- /tmux/tmux.conf.symlink: -------------------------------------------------------------------------------- 1 | # vim: set ft=tmux.conf 2 | 3 | # enable true color 4 | set -ga terminal-overrides ',xterm*:Tc' 5 | 6 | # still handy 7 | set -g mouse on 8 | 9 | # Don't lose track of SSH_AGENT etc. from parent environment. 10 | set -g update-environment -r 11 | 12 | # start window numbers at 1 like keyboards do 13 | set -g base-index 1 14 | 15 | # renumber windows sequentially after closing any of them 16 | set -g renumber-windows on 17 | 18 | # no visual bell 19 | set -g visual-activity off 20 | 21 | # don't show change indicators in the status bar 22 | set -g monitor-activity off 23 | 24 | # Use vim keybindings 25 | set-window-option -g mode-keys vi 26 | bind h select-pane -L 27 | bind j select-pane -D 28 | bind k select-pane -U 29 | bind l select-pane -R 30 | 31 | # Quickly switch between windows 32 | bind ^b last-window 33 | # Quickly switch between sessions 34 | bind ^s switch-client -l 35 | 36 | # Select other pane, then zoom 37 | bind ^o select-pane -l\; resize-pane -Z 38 | 39 | # # Start new windows on current path 40 | bind c new-window -c "#{pane_current_path}" 41 | 42 | set -g @plugin 'tmux-plugins/tpm' 43 | set -g @plugin 'tmux-plugins/tmux-sensible' 44 | set -g @plugin 'tmux-plugins/tmux-pain-control' 45 | set -g @plugin 'christoomey/vim-tmux-navigator' 46 | set -g @plugin 'joshmedeski/tmux-fzf-url' 47 | set -g @plugin 'nhdaly/tmux-scroll-copy-mode' 48 | # 49 | run -b '~/.tmux/plugins/tpm/tpm' 50 | run -b "~/.tmux/theme.tmux" 51 | 52 | # set -g default-terminal "${TERM}" 53 | set -g default-terminal "screen-256color" 54 | set -as terminal-overrides ',*:Smulx=\E[4::%p1%dm' # undercurl support 55 | set -as terminal-overrides ',*:Setulc=\E[58::2::::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m' # underscore colours - needs tmux-3.0 56 | 57 | -------------------------------------------------------------------------------- /tmux/tmux.symlink/theme.tmux: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Thank you github.com/cqroot/bubbles.tmux 3 | 4 | # $1: option 5 | # $2: default value 6 | tmux_get() { 7 | local value 8 | value="$(tmux show -gqv "$1")" 9 | [ -n "$value" ] && echo "$value" || echo "$2" 10 | } 11 | 12 | color_fg=$(tmux_get @tmux_bubbles_color_active 'color0') # "black" 13 | color_bg_active=$(tmux_get @tmux_bubbles_color_grey 'colour15') # "white" 14 | color_bg_inactive=$(tmux_get @tmux_bubbles_color_grey 'colour8') # "grey" 15 | 16 | tmux set-option -gq status on 17 | tmux set-option -gq status-fg "$color_fg" 18 | tmux set-option -gq status-bg "0" 19 | tmux set-option -gq status-attr none 20 | 21 | # $1: modules 22 | # $2: fg_color 23 | # $3: bg_color 24 | make_bubble() { 25 | echo "#[fg=$3]#[bg=0]#[fg=$2]#[bg=$3]$1#[fg=$3]#[bg=0]" 26 | } 27 | 28 | # $1: modules 29 | make_activatable_bubble() { 30 | local normal_bubble 31 | local active_bubble 32 | normal_bubble="$(make_bubble "$1" "$color_fg" "$color_bg_inactive")" 33 | active_bubble="$(make_bubble "$1" "$color_fg" "$color_bg_active")" 34 | 35 | echo "#{?client_prefix,$active_bubble,$normal_bubble}" 36 | } 37 | 38 | tmux set-option -gq status-left "" 39 | tmux set-option -gq status-right "" 40 | 41 | # ********************************************************* 42 | # Window * 43 | # ********************************************************* 44 | tmux set-option -gq window-status-format "#[fg=$color_bg_active,bg=0,bold] #I #W " 45 | tmux set-option -gq window-status-current-format "$(make_bubble ' #I #W#{?window_zoomed_flag,󰁌,} ' "$color_fg" "$color_bg_active")" 46 | 47 | # ********************************************************* 48 | # Others * 49 | # ********************************************************* 50 | tmux set-option -gq mode-style "bg=$color_bg_active,fg=0" 51 | tmux set-option -gq pane-active-border-style "fg=$color_bg_active,bg=0" 52 | tmux set-option -gq clock-mode-colour "$color_bg_active" 53 | -------------------------------------------------------------------------------- /vim/gvimrc.symlink: -------------------------------------------------------------------------------- 1 | " No audible bell 2 | set vb 3 | 4 | " Looks 5 | set guioptions-=T " No toolbar 6 | set guioptions-=r " No right hand scroll bar 7 | set guioptions-=L " No left hand scroll bar 8 | set guioptions-=e " Use built-in tabs 9 | if has("gui_macvim") 10 | " Fullscreen takes up entire screen 11 | set fuoptions=maxhorz,maxvert 12 | endif 13 | -------------------------------------------------------------------------------- /vim/vimrc.symlink: -------------------------------------------------------------------------------- 1 | " vim: fdm=marker foldlevel=0 2 | scriptencoding utf-8 3 | 4 | filetype plugin indent on 5 | 6 | set nobackup 7 | set nowritebackup 8 | set noswapfile 9 | set directory=~/.vim-tmp,~/.tmp,/var/tmp,/tmp 10 | if exists('+undofile') 11 | set undofile 12 | set undodir=~/.vim-tmp,~/.tmp,~/tmp,/var/tmp,/tmp 13 | endif 14 | 15 | set history=10000 16 | set undolevels=1000 17 | 18 | set mouse=nvi 19 | set cursorline 20 | set hidden 21 | set number 22 | set listchars=tab:»·,trail:· 23 | set list 24 | 25 | " set wildmode=longest:list,full 26 | set laststatus=2 27 | set wildignorecase 28 | set ignorecase smartcase 29 | set gdefault 30 | 31 | set autoindent 32 | set expandtab 33 | set tabstop=2 34 | set shiftwidth=2 35 | set softtabstop=2 36 | set foldlevel=999 37 | 38 | set autoread 39 | 40 | set exrc 41 | set secure 42 | 43 | if exists('+termguicolors') 44 | set termguicolors 45 | endif 46 | 47 | -------------------------------------------------------------------------------- /vscode/mac.sh: -------------------------------------------------------------------------------- 1 | # Copy settings.json to vscode 2 | mkdir -p ~/Library/Application\ Support/Code/User 3 | ln -s ~/.dotfiles/vscode/settings.json ~/Library/Application\ Support/Code/User/settings.json 4 | -------------------------------------------------------------------------------- /vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.colorTheme": "Default Dark Modern" 3 | } -------------------------------------------------------------------------------- /wezterm/wezterm.lua.symlink: -------------------------------------------------------------------------------- 1 | local wezterm = require("wezterm") 2 | local config = wezterm.config_builder() 3 | 4 | local scheme_for_apperance = function(appearance) 5 | if appearance:find("Dark") then 6 | return "zenbones_dark" 7 | else 8 | return "zenbones_light" 9 | end 10 | end 11 | 12 | config.color_scheme = scheme_for_apperance(wezterm.gui.get_appearance()) 13 | 14 | config.font_size = 16.0 15 | config.font = wezterm.font("Cascadia Code NF", { weight = "DemiLight", stretch = "Normal", style = "Normal" }) 16 | -- config.font = wezterm.font("Berkeley Mono Condensed", { weight = "Regular", stretch = "Normal", style = "Normal" }) 17 | -- config.font = wezterm.font("Iosevka", { weight = "Regular", stretch = "Normal", style = "Normal" }) 18 | -- config.font = wezterm.font("IBM Plex Mono") 19 | -- config.font = wezterm.font("Martian Mono", { weight = "Light", style = "Normal" }) 20 | 21 | config.use_fancy_tab_bar = false 22 | config.hide_tab_bar_if_only_one_tab = true 23 | config.scrollback_lines = 10000 24 | 25 | config.window_padding = { 26 | left = 8, 27 | right = 8, 28 | top = 8, 29 | bottom = 4, 30 | } 31 | config.initial_rows = 38 32 | config.initial_cols = 120 33 | 34 | config.keys = { 35 | -- macOS style text jumps 36 | { key = "LeftArrow", mods = "OPT", action = wezterm.action({ SendString = "\x1bb" }) }, 37 | { key = "RightArrow", mods = "OPT", action = wezterm.action({ SendString = "\x1bf" }) }, 38 | { key = "Backspace", mods = "OPT", action = wezterm.action({ SendString = "\x17" }) }, 39 | { key = "LeftArrow", mods = "SUPER", action = wezterm.action({ SendKey = { key = "Home" } }) }, 40 | { key = "RightArrow", mods = "SUPER", action = wezterm.action({ SendKey = { key = "End" } }) }, 41 | { key = "Backspace", mods = "SUPER", action = wezterm.action({ SendString = "\x15" }) }, 42 | 43 | { key = "k", mods = "CMD", action = wezterm.action.ActivateCommandPalette }, 44 | 45 | -- Send cmd+shift+[ or ] to switch tmux windows, like browser tabs 46 | -- Remember to unbind the default keys in System Preferences > Keyboard > Shortcuts 47 | { key = "{", mods = "SUPER|SHIFT", action = wezterm.action({ SendString = "\x02p" }) }, 48 | { key = "}", mods = "SUPER|SHIFT", action = wezterm.action({ SendString = "\x02n" }) }, 49 | { key = "[", mods = "SUPER", action = wezterm.action({ SendString = "\x02b" }) }, 50 | { key = "1", mods = "SUPER", action = wezterm.action({ SendString = "\x021" }) }, 51 | { key = "2", mods = "SUPER", action = wezterm.action({ SendString = "\x022" }) }, 52 | { key = "3", mods = "SUPER", action = wezterm.action({ SendString = "\x023" }) }, 53 | { key = "4", mods = "SUPER", action = wezterm.action({ SendString = "\x024" }) }, 54 | { key = "5", mods = "SUPER", action = wezterm.action({ SendString = "\x025" }) }, 55 | { key = "6", mods = "SUPER", action = wezterm.action({ SendString = "\x026" }) }, 56 | { key = "7", mods = "SUPER", action = wezterm.action({ SendString = "\x027" }) }, 57 | { key = "8", mods = "SUPER", action = wezterm.action({ SendString = "\x028" }) }, 58 | { key = "9", mods = "SUPER", action = wezterm.action({ SendString = "\x029" }) }, 59 | } 60 | 61 | config.send_composed_key_when_left_alt_is_pressed = true 62 | config.send_composed_key_when_right_alt_is_pressed = false 63 | 64 | return config 65 | -------------------------------------------------------------------------------- /xterm-256color.ti: -------------------------------------------------------------------------------- 1 | # Reconstructed via infocmp from file: /Users/mikker/.terminfo/78/xterm-256color 2 | xterm-256color|xterm with 256 colors, 3 | am, bce, ccc, km, mc5i, mir, msgr, npc, xenl, 4 | colors#256, cols#80, it#8, lines#24, pairs#32767, 5 | acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, 6 | bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z, civis=\E[?25l, 7 | clear=\E[H\E[2J, cnorm=\E[?12l\E[?25h, cr=^M, 8 | csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H, 9 | cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C, 10 | cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A, 11 | cvvis=\E[?12;25h, dch=\E[%p1%dP, dch1=\E[P, dl=\E[%p1%dM, 12 | dl1=\E[M, ech=\E[%p1%dX, ed=\E[J, el=\E[K, el1=\E[1K, 13 | flash=\E[?5h$<100/>\E[?5l, home=\E[H, hpa=\E[%i%p1%dG, 14 | ht=^I, hts=\EH, ich=\E[%p1%d@, il=\E[%p1%dL, il1=\E[L, 15 | ind=^J, indn=\E[%p1%dS, 16 | initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\, 17 | invis=\E[8m, is2=\E[!p\E[?3;4l\E[4l\E>, kDC=\E[3;2~, 18 | kEND=\E[1;2F, kHOM=\E[1;2H, kIC=\E[2;2~, kLFT=\E[1;2D, 19 | kNXT=\E[6;2~, kPRV=\E[5;2~, kRIT=\E[1;2C, kb2=\EOE, 20 | kbs=\177, kcbt=\E[Z, kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, 21 | kcuu1=\EOA, kdch1=\E[3~, kend=\EOF, kent=\EOM, kf1=\EOP, 22 | kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[1;2P, 23 | kf14=\E[1;2Q, kf15=\E[1;2R, kf16=\E[1;2S, kf17=\E[15;2~, 24 | kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~, 25 | kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, 26 | kf24=\E[24;2~, kf25=\E[1;5P, kf26=\E[1;5Q, kf27=\E[1;5R, 27 | kf28=\E[1;5S, kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, 28 | kf31=\E[18;5~, kf32=\E[19;5~, kf33=\E[20;5~, 29 | kf34=\E[21;5~, kf35=\E[23;5~, kf36=\E[24;5~, 30 | kf37=\E[1;6P, kf38=\E[1;6Q, kf39=\E[1;6R, kf4=\EOS, 31 | kf40=\E[1;6S, kf41=\E[15;6~, kf42=\E[17;6~, 32 | kf43=\E[18;6~, kf44=\E[19;6~, kf45=\E[20;6~, 33 | kf46=\E[21;6~, kf47=\E[23;6~, kf48=\E[24;6~, 34 | kf49=\E[1;3P, kf5=\E[15~, kf50=\E[1;3Q, kf51=\E[1;3R, 35 | kf52=\E[1;3S, kf53=\E[15;3~, kf54=\E[17;3~, 36 | kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~, 37 | kf58=\E[21;3~, kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~, 38 | kf61=\E[1;4P, kf62=\E[1;4Q, kf63=\E[1;4R, kf7=\E[18~, 39 | kf8=\E[19~, kf9=\E[20~, khome=\EOH, kich1=\E[2~, 40 | kind=\E[1;2B, kmous=\E[M, knp=\E[6~, kpp=\E[5~, 41 | kri=\E[1;2A, mc0=\E[i, mc4=\E[4i, mc5=\E[5i, op=\E[39;49m, 42 | rc=\E8, rev=\E[7m, ri=\EM, rin=\E[%p1%dT, rmacs=\E(B, 43 | rmam=\E[?7l, rmcup=\E[?1049l, rmir=\E[4l, rmkx=\E[?1l\E>, 44 | rmm=\E[?1034l, rmso=\E[27m, rmul=\E[24m, rs1=\Ec, 45 | rs2=\E[!p\E[?3;4l\E[4l\E>, sc=\E7, 46 | setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, 47 | setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, 48 | sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m, 49 | sgr0=\E(B\E[m, smacs=\E(0, smam=\E[?7h, smcup=\E[?1049h, 50 | smir=\E[4h, smkx=\E[?1h\E=, smm=\E[?1034h, smso=\E[7m, 51 | smul=\E[4m, tbc=\E[3g, u6=\E[%i%d;%dR, u7=\E[6n, 52 | u8=\E[?1;2c, u9=\E[c, vpa=\E[%i%p1%dd, 53 | -------------------------------------------------------------------------------- /zsh/aliases.zsh: -------------------------------------------------------------------------------- 1 | # General 2 | alias so='source' 3 | alias l='ls' 4 | alias ll='ls -lh' 5 | alias la='ls -a' 6 | alias ddate='date +"%Y-%m-%d"' 7 | alias ytdl='cd ~/Movies && youtube-dl `pbpaste`' 8 | alias doco='docker-compose' 9 | alias mux='tmuxinator' 10 | alias rm_orig="find . -name '*.orig' -exec rm {} \;" 11 | alias json='python -mjson.tool' 12 | alias pweb='python -m SimpleHTTPServer' 13 | alias online='ping -c 1 google.com &> /dev/null' 14 | alias dsay='say -v Sara' 15 | alias doc='docker-compose' 16 | alias ruby-vers="cat Gemfile | grep '^ruby' | sed -E \"s/.*[\\\"'](.+)[\\\"']/\1/"\" 17 | alias docker-killall="docker ps | tail -n +2 | awk '{ print \$1 }' | xargs docker kill" 18 | 19 | # tmux 20 | alias tm="tmux -u" 21 | alias ta='tmux attach' 22 | alias tat='tmux new-session -As "`basename $PWD | sed -e \"s/\./-/g\"`"' 23 | alias tk='tmux kill-session' 24 | alias tkall='while true; do tk || break; done' 25 | alias tmux-set-title='tmux rename-session `basename $PWD | sed -e "s/\./-/g"`' 26 | 27 | # Git 28 | alias g='git' 29 | alias gp='git push' 30 | alias ga='git add --all' 31 | alias gd='git diff' 32 | alias gl='git log' 33 | alias gla='git log --all' 34 | alias gt='git tree' 35 | alias gta='git tree --all' 36 | alias gdt='git difftool' 37 | alias gmt='git mergetool' 38 | alias gs='git status -sb' 39 | alias gci='git commit -m' 40 | alias gdmb='git branch --merged | grep -v "\*" | xargs -n 1 git branch -d' 41 | alias gb='gh browse' 42 | 43 | # Ruby 44 | alias be='bundle exec' 45 | alias ra='rails' 46 | 47 | # JS 48 | alias yr="yarn run" 49 | alias npr="npm run" 50 | alias hh="yarn hardhat" 51 | 52 | 53 | # https://twitter.com/almonk/status/1576294814831718400 54 | alias todo='git grep -l TODO | xargs -n1 git blame -f -n -w | grep "$(git config user.name)" | grep TODO | sed "s/.\{9\}//" | sed "s/(.*)[[:space:]]*//"' 55 | 56 | -------------------------------------------------------------------------------- /zsh/all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [[ $ZSH_NAME != "zsh" ]]; then 6 | echo "Changing Default Shell to ZSH" 7 | chsh -s /bin/zsh 8 | fi 9 | -------------------------------------------------------------------------------- /zsh/bindkeys.zsh: -------------------------------------------------------------------------------- 1 | bindkey "\e[3~" delete-char 2 | 3 | # up-down searches history 4 | bindkey '^[[A' up-line-or-search 5 | bindkey '^[[B' down-line-or-search 6 | 7 | bindkey '^[b' backward-word 8 | bindkey '^[f' forward-word 9 | 10 | # use incremental search 11 | bindkey "^R" history-incremental-search-backward 12 | 13 | # edit current command in $EDITOR 14 | autoload edit-command-line 15 | zle -N edit-command-line 16 | bindkey '^F' edit-command-line 17 | 18 | -------------------------------------------------------------------------------- /zsh/config.zsh: -------------------------------------------------------------------------------- 1 | # enable colored output from ls, etc 2 | export CLICOLOR=1 3 | 4 | fpath=($HOME/.zfunc $fpath) 5 | autoload -U $HOME/.zfunc/*(:t) 6 | 7 | # makes color constants available 8 | autoload -U colors 9 | colors 10 | 11 | setopt no_beep # shut up 12 | setopt auto_cd # automatically enter directories without cd 13 | setopt multios # perform implicit tees or cats when multiple redirections are attempted 14 | 15 | # HISTORY 16 | 17 | HISTFILE=$HOME/.zsh_history 18 | HISTSIZE=10000000 19 | SAVEHIST=10000000 20 | 21 | setopt hist_ignore_all_dups # ignore duplicate history entries 22 | setopt inc_append_history # Appends every command to the history file once it is executed 23 | setopt hist_expire_dups_first # when trimming history, lose oldest duplicates first 24 | setopt hist_ignore_dups # Do not write events to history that are duplicates of previous events 25 | setopt hist_ignore_space # remove command line from history list when first character on the line is a space 26 | setopt hist_find_no_dups # When searching history don't display results already cycled through twice 27 | setopt hist_reduce_blanks # Remove extra blanks from each command line being added to history 28 | setopt hist_verify # don't execute, just expand history 29 | setopt share_history # Reloads the history whenever you use it 30 | 31 | ### COMPLETION 32 | 33 | setopt always_to_end # When completing from the middle of a word, move the cursor to the end of the word 34 | setopt auto_menu # show completion menu on successive tab press. needs unsetop menu_complete to work 35 | setopt auto_name_dirs # any parameter that is set to the absolute name of a directory immediately becomes a name for that directory 36 | setopt complete_in_word # Allow completion from within a word/phrase 37 | 38 | unsetopt menu_complete # do not autoselect the first completion entry 39 | 40 | zmodload -i zsh/complist 41 | 42 | # case-insensitive (all),partial-word and then substring completion 43 | zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' 44 | zstyle ':completion:*' list-colors '' 45 | 46 | ### PROMPT 47 | 48 | setopt prompt_subst # Enable parameter expansion, command substitution, and arithmetic expansion in the prompt 49 | setopt transient_rprompt # only show the rprompt on the current prompt 50 | 51 | setopt extendedglob 52 | -------------------------------------------------------------------------------- /zsh/omp.toml: -------------------------------------------------------------------------------- 1 | console_title_template = '{{ .Shell }} in {{ .Folder }}' 2 | version = 3 3 | final_space = true 4 | 5 | [upgrade] 6 | source = 'cdn' 7 | interval = '168h' 8 | auto = false 9 | notice = false 10 | 11 | [[blocks]] 12 | type = 'prompt' 13 | alignment = 'left' 14 | 15 | [[blocks.segments]] 16 | type = "path" 17 | style = "plain" 18 | foreground = 'blue' 19 | template = "{{ .Path }} " 20 | 21 | [blocks.segments.properties] 22 | style = "folder" 23 | 24 | [[blocks.segments]] 25 | type = "git" 26 | style = "plain" 27 | foreground = "yellow" 28 | template = "{{ .HEAD }}{{ if or (.Working.Changed) (.Staging.Changed)}}*{{end}} " 29 | 30 | [blocks.segments.properties] 31 | fetch_status = true 32 | branch_icon = '' 33 | 34 | [[blocks.segments]] 35 | type = "text" 36 | style = "plain" 37 | foreground = "magenta" 38 | template = "{{ if gt .Jobs 0 }}☆ {{ .Jobs }} {{ end }}" 39 | 40 | [[blocks.segments]] 41 | type = "text" 42 | style = "plain" 43 | foreground = "magenta" 44 | template = "→ " 45 | -------------------------------------------------------------------------------- /zsh/prompt.zsh: -------------------------------------------------------------------------------- 1 | autoload -Uz vcs_info 2 | 3 | local mark='*' 4 | 5 | zstyle ':vcs_info:*' stagedstr "%F{28}$mark" 6 | zstyle ':vcs_info:*' unstagedstr "%F{11}$mark" 7 | zstyle ':vcs_info:*' check-for-changes true 8 | zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat '%b%F{1}:%F{11}%r' 9 | zstyle ':vcs_info:*' enable git 10 | 11 | parse_ssh_connection() { 12 | [[ -n $SSH_CONNECTION ]] && echo "%n@%m " 13 | } 14 | 15 | precmd () { 16 | if [[ -z $(git ls-files --other --exclude-standard 2> /dev/null) ]] { 17 | zstyle ':vcs_info:*' formats ' %F{yellow}%b%c%u%F{blue}' 18 | } else { 19 | zstyle ':vcs_info:*' formats " %F{yellow}%b%c%u%F{red}$mark%F{blue}" 20 | } 21 | 22 | vcs_info 23 | } 24 | 25 | PROMPT=' 26 | $(parse_ssh_connection)%F{blue}%c%f%(1j.%F{magenta} %j%f.)%F{yellow} ❖ %f ' 27 | RPROMPT='%F{blue}${vcs_info_msg_0_}%f' 28 | 29 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/_brew: -------------------------------------------------------------------------------- 1 | #compdef brew 2 | 3 | # Brew ZSH completion function 4 | # Drop this somewhere in your $fpath (like /usr/share/zsh/site-functions) 5 | # and rename it _brew 6 | # 7 | # altered from _fink 8 | 9 | _brew_all_formulae() { 10 | formulae=(`brew search`) 11 | } 12 | 13 | _brew_installed_formulae() { 14 | installed_formulae=(`brew list`) 15 | } 16 | 17 | _brew_installed_taps() { 18 | installed_taps=(`brew tap`) 19 | } 20 | 21 | _brew_outdated_formulae() { 22 | outdated_formulae=(`brew outdated`) 23 | } 24 | 25 | local -a _1st_arguments 26 | _1st_arguments=( 27 | 'audit:check formulae for Homebrew coding style' 28 | 'bundle:look for a Brewfile and run each line as a brew command' 29 | 'cat:display formula file for a formula' 30 | 'cleanup:uninstall unused and old versions of packages' 31 | 'commands:show a list of commands' 32 | 'create:create a new formula' 33 | 'deps:list dependencies and dependants of a formula' 34 | 'doctor:audits your installation for common issues' 35 | 'edit:edit a formula' 36 | 'home:visit the homepage of a formula or the brew project' 37 | 'info:information about a formula' 38 | 'install:install a formula' 39 | 'reinstall:install a formula anew; re-using its current options' 40 | 'link:link a formula' 41 | 'list:list files in a formula or not-installed formulae' 42 | 'log:git commit log for a formula' 43 | 'missing:check all installed formuale for missing dependencies.' 44 | 'outdated:list formulae for which a newer version is available' 45 | 'pin:pin specified formulae' 46 | 'prune:remove dead links' 47 | 'remove:remove a formula' 48 | 'search:search for a formula (/regex/ or string)' 49 | 'server:start a local web app that lets you browse formulae (requires Sinatra)' 50 | 'tap:tap a new formula repository from GitHub, or list existing taps' 51 | 'unlink:unlink a formula' 52 | 'unpin:unpin specified formulae' 53 | 'untap:remove a tapped repository' 54 | 'update:freshen up links' 55 | 'upgrade:upgrade outdated formulae' 56 | 'uses:show formulae which depend on a formula' 57 | ) 58 | 59 | local expl 60 | local -a formulae installed_formulae installed_taps outdated_formulae 61 | 62 | _arguments \ 63 | '(-v)-v[verbose]' \ 64 | '(--cellar)--cellar[brew cellar]' \ 65 | '(--config)--config[brew configuration]' \ 66 | '(--env)--env[brew environment]' \ 67 | '(--repository)--repository[brew repository]' \ 68 | '(--version)--version[version information]' \ 69 | '(--prefix)--prefix[where brew lives on this system]' \ 70 | '(--cache)--cache[brew cache]' \ 71 | '*:: :->subcmds' && return 0 72 | 73 | if (( CURRENT == 1 )); then 74 | _describe -t commands "brew subcommand" _1st_arguments 75 | return 76 | fi 77 | 78 | case "$words[1]" in 79 | search|-S) 80 | _arguments \ 81 | '(--macports)--macports[search the macports repository]' \ 82 | '(--fink)--fink[search the fink repository]' ;; 83 | list|ls) 84 | _arguments \ 85 | '(--unbrewed)--unbrewed[files in brew --prefix not controlled by brew]' \ 86 | '(--pinned)--pinned[list all versions of pinned formulae]' \ 87 | '(--versions)--versions[list all installed versions of a formula]' \ 88 | '1: :->forms' && return 0 89 | 90 | if [[ "$state" == forms ]]; then 91 | _brew_installed_formulae 92 | _wanted installed_formulae expl 'installed formulae' compadd -a installed_formulae 93 | fi ;; 94 | install|reinstall|audit|home|homepage|log|info|abv|uses|cat|deps|edit|options) 95 | _brew_all_formulae 96 | _wanted formulae expl 'all formulae' compadd -a formulae ;; 97 | remove|rm|uninstall|unlink|cleanup|link|ln|pin|unpin) 98 | _brew_installed_formulae 99 | _wanted installed_formulae expl 'installed formulae' compadd -a installed_formulae ;; 100 | upgrade) 101 | _brew_outdated_formulae 102 | _wanted outdated_formulae expl 'outdated formulae' compadd -a outdated_formulae ;; 103 | untap) 104 | _brew_installed_taps 105 | _wanted installed_taps expl 'installed taps' compadd -a installed_taps ;; 106 | esac 107 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/_c: -------------------------------------------------------------------------------- 1 | #compdef c 2 | _files -W $PROJECTS -/ 3 | 4 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/abspath: -------------------------------------------------------------------------------- 1 | # prints the absolute path of a file 2 | abspath() { 3 | find `pwd` -name "$@" 4 | } 5 | 6 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/aripb: -------------------------------------------------------------------------------- 1 | # Download pasteboard using aria2 download thing 2 | aripb() { 3 | local pb=`pbpaste` 4 | echo $pb && aria2c "$pb" 5 | } 6 | 7 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/bundlegrep: -------------------------------------------------------------------------------- 1 | bung () { 2 | ag "$@" `bundle show --paths` 3 | } 4 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/c: -------------------------------------------------------------------------------- 1 | # Quickly navigate to a project - with autosuggest 2 | c() { 3 | local dir="$PROJECTS" 4 | 5 | if [[ $# == 0 ]]; then 6 | cd "$dir/$(find $dir -type d -maxdepth 2 ! -path '*.git*' | sed -E "s#^$dir##"| fzf)" 7 | else 8 | cd "$dir/$1"; 9 | fi 10 | } 11 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/gcm: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------------- 2 | # AI-powered Git Commit Function 3 | # Copy paste this gist into your ~/.bashrc or ~/.zshrc to gain the `gcm` command. It: 4 | # 1) gets the current staged changed diff 5 | # 2) sends them to an LLM to write the git commit message 6 | # 3) allows you to easily accept, edit, regenerate, cancel 7 | # But - just read and edit the code however you like 8 | # the `llm` CLI util is awesome, can get it here: https://llm.datasette.io/en/stable/ 9 | 10 | gcm() { 11 | # Function to generate commit message 12 | generate_commit_message() { 13 | git diff --cached | llm " 14 | Below is a diff of all staged changes, coming from the command: 15 | 16 | \`\`\` 17 | git diff --cached 18 | \`\`\` 19 | 20 | Please generate a concise, one-line commit message for these changes." 21 | } 22 | 23 | # Function to read user input compatibly with both Bash and Zsh 24 | read_input() { 25 | if [ -n "$ZSH_VERSION" ]; then 26 | echo -n "$1" 27 | read -r REPLY 28 | else 29 | read -p "$1" -r REPLY 30 | fi 31 | } 32 | 33 | # Main script 34 | echo "Generating AI-powered commit message..." 35 | commit_message=$(generate_commit_message) 36 | 37 | while true; do 38 | echo -e "\nProposed commit message:" 39 | echo "$commit_message" 40 | 41 | read_input "Do you want to (a)ccept, (e)dit, (r)egenerate, or (c)ancel? " 42 | choice=$REPLY 43 | 44 | case "$choice" in 45 | a|A ) 46 | if git commit -m "$commit_message"; then 47 | echo "Changes committed successfully!" 48 | return 0 49 | else 50 | echo "Commit failed. Please check your changes and try again." 51 | return 1 52 | fi 53 | ;; 54 | e|E ) 55 | read_input "Enter your commit message: " 56 | commit_message=$REPLY 57 | if [ -n "$commit_message" ] && git commit -m "$commit_message"; then 58 | echo "Changes committed successfully with your message!" 59 | return 0 60 | else 61 | echo "Commit failed. Please check your message and try again." 62 | return 1 63 | fi 64 | ;; 65 | r|R ) 66 | echo "Regenerating commit message..." 67 | commit_message=$(generate_commit_message) 68 | ;; 69 | c|C ) 70 | echo "Commit cancelled." 71 | return 1 72 | ;; 73 | * ) 74 | echo "Invalid choice. Please try again." 75 | ;; 76 | esac 77 | done 78 | } 79 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/mkcd: -------------------------------------------------------------------------------- 1 | # Make a new directory and cd into it 2 | 3 | mkcd() { 4 | mkdir -p "$@" && cd "$@" 5 | } 6 | 7 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/nb: -------------------------------------------------------------------------------- 1 | # nb() 2 | # Checkout new (or existing) branch of name ... 3 | 4 | nb() { 5 | if [[ $# > 0 ]]; then 6 | if [[ $(git branch | tr -d '* ' | grep "$1") != "" ]]; then 7 | git checkout $1 8 | else 9 | git checkout -b $1 10 | fi 11 | else 12 | git branch | tr -d '* ' 13 | fi 14 | } 15 | 16 | _nb() { reply=($(git branch | tr -d '* ' | xargs echo)) } 17 | compctl -K _nb nb 18 | 19 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/nw: -------------------------------------------------------------------------------- 1 | # Make a new tmux window and run $@ in it 2 | nw() { 3 | tmux new-window 4 | tmux send-keys "$*" C-m 5 | } 6 | 7 | -------------------------------------------------------------------------------- /zsh/zfunc.symlink/o: -------------------------------------------------------------------------------- 1 | # Open a file or the current directory 2 | o() { 3 | if [[ $# > 0 ]]; then 4 | open $@ 5 | else 6 | open . 7 | fi 8 | } 9 | 10 | -------------------------------------------------------------------------------- /zsh/zshrc.symlink: -------------------------------------------------------------------------------- 1 | export DOTFILES=$HOME/.dotfiles 2 | export ZSH_FILES=$DOTFILES/zsh 3 | export PROJECTS=$HOME/dev 4 | export XDG_CONFIG_HOME=$HOME/.config 5 | 6 | export PATH="$DOTFILES/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/local/sbin:$PATH" 7 | export VISUAL=vim 8 | export EDITOR=$VISUAL 9 | 10 | source $ZSH_FILES/config.zsh 11 | # source $ZSH_FILES/prompt.zsh 12 | source $ZSH_FILES/bindkeys.zsh 13 | source $ZSH_FILES/aliases.zsh 14 | 15 | export PATH="./bin:$PATH" 16 | 17 | ### Added by Zinit's installer 18 | if [[ ! -f $HOME/.local/share/zinit/zinit.git/zinit.zsh ]]; then 19 | print -P "%F{33} %F{220}Installing %F{33}ZDHARMA-CONTINUUM%F{220} Initiative Plugin Manager (%F{33}zdharma-continuum/zinit%F{220})…%f" 20 | command mkdir -p "$HOME/.local/share/zinit" && command chmod g-rwX "$HOME/.local/share/zinit" 21 | command git clone https://github.com/zdharma-continuum/zinit "$HOME/.local/share/zinit/zinit.git" && \ 22 | print -P "%F{33} %F{34}Installation successful.%f%b" || \ 23 | print -P "%F{160} The clone has failed.%f%b" 24 | fi 25 | 26 | source "$HOME/.local/share/zinit/zinit.git/zinit.zsh" 27 | autoload -Uz _zinit 28 | (( ${+_comps} )) && _comps[zinit]=_zinit 29 | 30 | # Load a few important annexes, without Turbo 31 | # (this is currently required for annexes) 32 | zinit light-mode for \ 33 | zdharma-continuum/zinit-annex-as-monitor \ 34 | zdharma-continuum/zinit-annex-bin-gem-node \ 35 | zdharma-continuum/zinit-annex-patch-dl \ 36 | zdharma-continuum/zinit-annex-rust 37 | 38 | ### End of Zinit's installer chunk 39 | 40 | zinit light zsh-users/zsh-autosuggestions 41 | zinit light zdharma-continuum/fast-syntax-highlighting 42 | 43 | zinit ice lucid wait'0' # what does this first line do? 44 | zinit light joshskidmore/zsh-fzf-history-search 45 | 46 | eval "$(oh-my-posh init zsh --config $ZSH_FILES/omp.toml)" 47 | 48 | # Local modifications 49 | [[ -f ~/.lrc ]] && . ~/.lrc 50 | 51 | # Initialize completion engine 52 | autoload -Uz compinit && compinit 53 | 54 | --------------------------------------------------------------------------------