My setup

Hardware

Keyboard: Microsoft Sculpt Keyboard

I've experimented with various mechanical keyboards featuring different switches, but the tall keycaps make them feel cumbersome. Even the ergonomic designs like the ErgoDox or Kinesis suffer from this issue. The keycaps impose an unwieldy form factor, requiring excessive travel, space, and effort to actuate.

I prefer the low-profile keys of the Microsoft Sculpt. Its design offers a more ergonomic shape and a built-in palm rest, unlike most mechanical keyboards that force awkward wrist angles due to their height.

The ten keyless design, aka no numpad, had a bigger impact than I expected. It sounds a bit crazy, but reducing the distance your right arm has to move to reach the mouse feels noticeably less strenuous.

The Microsoft Sculpt is much lighter than your average mechanical keyboard too.

For games like Dota 2 or Diablo, I still enjoy the satisfying click of a blue switch mechanical keyboard. It provides great feedback and confidence with each key press.

Mouse: Pulsar X2 v1 Medium

Ideal for claw grip. And weighing at only 56 grams, this mouse is considerably easier to handle than the commonly recommended MX Master weighing at 142 grams, despite thinking I'd prefer the MX Master's shape.

Headphones: AirPods Pro

The active noise cancellation on the AirPods Pro is the kind of thing that seems trivial until you experience its effects over time. For me, it's been transformative.

Noise is a constant drain on mental energy. Even in relatively quiet settings, ambient sound takes a small toll on your cognitive resources. By cutting out this background noise, the AirPods Pro offer a kind of mental relief that accumulates throughout the day. It's like the difference between living in a cluttered room versus a tidy one. The clutter might not seem like a big deal until you clean it up and suddenly feel the mental space open up.

In environments where noise is overwhelmingly brutal like concerts or cinemas-the benefit is even more pronounced. These places often exceed 85 dB, a level at which sustained exposure can be harmful. With noise cancellation, it's like turning down the volume to something more manageable.

Social norms haven't quite caught up yet. Wearing noise-canceling earphones in these settings might earn you a few puzzled looks. But it's a small price to pay for the comfort it brings. The technology isn't perfect; I'd love to have more control over the intensity of the noise cancellation. But even as it stands, it's a game-changer.

We haven't yet made it normal to ask, "Can you repeat that?" when we're wearing earphones, and people often think you're being rude if you do. For smoother social interactions, earphone technology needs to get better at being aware of conversations. Imagine if the hearing aid feature advanced to the point where just by looking at someone, their speech would get louder, making it easier to hear in loud environments.

Desk: Jarvis Bamboo Standing Desk - 72x30 3 Stage Low

I've never cared for standing desks but the ability to adjust the desk height to your ideal sitting height is great.

Strongly recommend the larger 72x30 option if possible, more space feels great.

KVM: TESmart 4 PCs 1 Monitor

KVM was a late purchase for me, it makes it a breeze to switch my monitor, keyboard and mouse from personal to work in one click.

I once relied on an Anker USB switcher for my keyboard and mouse dongles, but it still left me having to manually switch the monitor input.

Laptop Work: Apple M1 Pro, 14-inch, 32GB, 2TB
Laptop Personal: Apple M1 Pro, 14-inch, 32GB, 2TB

The Apple M chips are incredible. Software developers take the manufacturing and fabrication of chips, and really all hardware, for granted but our whole industry is built on top of it.

Monitor: LG 27GL83A 27" 144hz
Chair: Colamy Ergonomic Mesh Office Chair
Wallet: Thread Elastic Wallet

Software

# Macbook setup script

ln -s ~/Drive/Settings/dotfiles/.zshrc ~/.zshrc
ln -s ~/Drive/Settings/dotfiles/nvim .config/nvim
ln -s ~/Drive/Settings/dotfiles/kitty .config/kitty
ln -s ~/Drive/Settings/dotfiles/karabiner ~/.config/karabiner
ln -s ~/Drive/Settings/dotfiles/Alfred ~/Library/Application\ Support/Alfred/Alfred
ln -s ~/Drive/Settings/dotfiles/direnv .config/direnv

bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

brew install --cask \
    alfred \
    alt-tab \
    betterdisplay \
    bruno \
    figma \
    fork \
    github \
    google-chrome \
    istat-menus \
    jetbrains-toolbox \
    karabiner-elements \
    keycastr \
    kitty \
    linearmouse \
    monodraw \
    notunes \
    numi \
    rectangle \
    shifty \
    sublime-text \
    visual-studio-code \
    # \
    # vlc \
    # utm \
    # mullvadvpn \
    # signal \
    # spotify \
    # discord \
    # transmission \
    # keepassxc \

brew install \
    ag \
    awscli \
    btop \
    cfn-lint \
    direnv \
    docker \
    fd \
    fzf \
    gh \
    git \
    hey \
    hyperfine \
    imagemagick \
    jq \
    lazydocker \
    lazygit \
    neovim \
    oha \
    ripgrep \
    ripgrep-all \
    thefuck \
    tldr \
    tree \
    wget \
    yq \
    zsh-autosuggestions

brew tap hashicorp/tap && brew install hashicorp/tap/terraform

git config --global --add --bool push.autoSetupRemote true
git config --global --add core.hooksPath /Users/ross/Drive/Settings/dotfiles/scripts/hooks
# .zshrc

## Aliases

alias ..='cd ..'
alias ...='cd ../..'
function mkcd() { mkdir $1 && cd $1; }

alias ll='ls -roAhtG'
alias copy="tr -d '\n' | pbcopy"
alias pf="fzf --preview='less {}' --bind shift-up:preview-page-up,shift-down:preview-page-down"

alias lg="lazygit"

alias g="git"
alias ghub="open_github"
alias gce="clone_cd_vim"
alias gc="clone_cd"
alias gcam="git add . && git commit -am"
alias gcp="git add . && git commit --allow-empty-message -m '' && git push"
alias deploy="make deploy"
alias gs="git status"
alias gsw="git switch"
alias gp="git push"
alias gpe="git commit --amend --no-edit && git push —force-with-lease"
alias gpu="git pull"
alias gm="git merge"
alias gpur='git pull --rebase'
alias gl="git log --pretty=oneline"
alias gfe='git fetch'
alias gre='git rebase'
alias glr='git l -30'
alias gcdr='cd $(git rev-parse --show-toplevel)' # cd to git Root
alias ghs='git rev-parse --short HEAD'
alias ghm='git log --format=%B -n 1 HEAD'
alias gaa='git add -A'
alias gcm="git commit -m"
alias gcm='git checkout main'
alias gd='git diff'
alias gdc='git diff --cached'
alias gco='git checkout'
function gfo() { git branch --no-color --sort=-committerdate --format='%(refname:short)' | fzf --header 'git checkout' | xargs git checkout }
function gpo() { gh pr list --author "@me" | fzf --header 'checkout PR' | awk '{print $(NF-5)}' | xargs git checkout }

alias r="rails"
alias rs="bundle exec foreman start -f Procfile.dev "$@""
alias be="bundle exec"

alias m="make"
alias v="nvim"
alias vi="nvim"
alias vim="nvim"
alias ld="lazydocker"
alias tf="terraform"

alias ezsh="nvim ~/.zshrc && source ~/.zshrc"
alias evim="nvim ~/.config/nvim/init.vim"
alias ekitty="nvim ~/.config/kitty/kitty.conf"
alias ekari="nvim ~/.config/karabiner/karabiner.json"
alias esetup="nvim ~/Drive/Settings/dotfiles/setup"
alias dotfiles="cd ~/Drive/Settings/dotfiles"

alias dev="cd ~/dev"
alias scratch="cd ~/dev/scratch"
alias expers="cd ~/dev/scratch/experiments"
alias repos="cd ~/dev/repos"
alias courses="cd ~/dev/courses"
alias references="cd ~/dev/refrences"
alias drive="cd ~/Drive"
alias notes="cd ~/Notes"
alias todo="vim ~/Notes/todo.txt"
alias down="cd ~/Downloads"
alias docs="cd ~/Documents"
alias scripts="cd ~/dev/scripts"
alias me="cd ~/dev/repos/roscrl.com"
alias posts="cd ~/dev/repos/roscrl.com/posts && nvim"
alias secrets="nvim ~/Drive/settings/dotfiles/.secrets && source ~/.zshrc"
alias llm="cd ~/dev/scratch/llm"

alias diff="kitty +kitten diff"
alias icat="kitty +kitten icat"
alias ssh="kitty +kitten ssh"
alias out="kitty @ set-window-title \"Output\""

function killport() { lsof -i tcp:$1 | awk 'NR!=1 {print $2}' | xargs kill -9 }

## Exports

source ~/Drive/settings/dotfiles/.secrets

## Options

SAVEHIST=100000
HISTSIZE=100000
setopt EXTENDED_HISTORY
setopt HIST_VERIFY
setopt SHARE_HISTORY	    # share history between all sessions
setopt HIST_IGNORE_DUPS	    # do not record an entry that was just recorded again
setopt HIST_IGNORE_ALL_DUPS # delete old recorded entry if new entry is a duplicate
setopt HIST_IGNORE_SPACE    # do not record an entry starting with a space
setopt HIST_FIND_NO_DUPS    # do not display a line previously found.
setopt HIST_SAVE_NO_DUPS    # do not write duplicate entries in the history file.
setopt AUTO_CD              # cd by typing directory name if it's not a command
unsetopt CORRECT_ALL

unsetopt flowcontrol
setopt auto_menu
setopt complete_in_word
setopt always_to_end
setopt auto_pushd

zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'

. /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh

## Misc

function myip() { curl -s https://api.ipify.org; printf "\n" }

function clone_cd_vim() {
    local url="$1";
    local dir_name=$(basename "$url" .git);

    if [[ $url =~ ^(https|git|ssh)://.+\.git$ || $url =~ ^git@.+:.+\.git$ ]]; then
        git clone "$url" && cd "$dir_name" && vim .;
    else
        echo "Invalid Git URL";
    fi
}

function clone_cd() {
    local url="$1";
    local dir_name=$(basename "$url" .git);

    if [[ $url =~ ^(https|git|ssh)://.+\.git$ || $url =~ ^git@.+:.+\.git$ ]]; then
        git clone "$url" && cd "$dir_name";
    else
        echo "Invalid Git URL";
    fi
}

function fcd() {
    local dir;
    while true; do
        # exit with ^D
        dir="$(ls -a1F | grep '[/@]$' | grep -v '^./$' | sed 's/@$//' | fzf --height 40% --reverse --no-multi --preview 'pwd' --preview-window=up,1,border-none --no-info)"
        if [[ -z "${dir}" ]]; then
            break
        elif [[ -d "${dir}" ]]; then
            cd "${dir}"
        fi
    done
}

function pbfilter() {
    if [ $# -gt 0 ]; then
        pbpaste | "$@" | pbcopy
    else
        pbpaste | pbcopy
    fi
}

open_github() {
    local remote_url=$(git config --get remote.origin.url)
    if [[ -z "$remote_url" ]]; then
        echo "Not a git repository or no remote.origin.url set"
        return 1
    fi

    # Convert SSH URL to HTTPS if necessary
    if [[ $remote_url == [email protected]:* ]]; then
        remote_url=${remote_url/[email protected]:/https://github.com/}
    fi

    # Remove .git suffix if present
    remote_url=${remote_url%.git}

    # Open the URL in the default browser
    if [[ "$OSTYPE" == "darwin"* ]]; then
        open "$remote_url"
    elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
        xdg-open "$remote_url"
    else
        echo "Unsupported operating system"
        return 1
    fi
}

# fzf
if [ -e /opt/homebrew/opt/fzf/shell/completion.zsh ]; then
    source /opt/homebrew/opt/fzf/shell/key-bindings.zsh
    source /opt/homebrew/opt/fzf/shell/completion.zsh
elif [ -e /usr/local/opt/fzf/shell/completion.zsh ]; then
    source /usr/local/opt/fzf/shell/key-bindings.zsh
    source /usr/local/opt/fzf/shell/completion.zsh
else
    # fzf via local installation
    if [ -e ~/.fzf ]; then
        source ~/.fzf/shell/key-bindings.zsh
        source ~/.fzf/shell/completion.zsh
        if [[ ! "$PATH" == *$HOME.fzf/bin* ]]; then
            export PATH="$PATH:$HOME/.fzf/bin"
        fi
    fi
fi

if type fzf &> /dev/null && type rg &> /dev/null; then
    export FZF_DEFAULT_COMMAND='rg --files --hidden --follow --glob "!.git/*" --glob "!vendor/*"'
    export FZF_CTRL_T_COMMAND='rg --files --hidden --follow --glob "!.git/*" --glob "!vendor/*"'
    export FZF_ALT_C_COMMAND="$FZF_DEFAULT_COMMAND"
    bindkey "ç" fzf-cd-widget
fi

# Prompt with git branch on right when in git folder https://scriptingosx.com/2019/07/moving-to-zsh-06-customizing-the-zsh-prompt/
PROMPT='%B%F{blue}%2~%f%b %# '
autoload -Uz vcs_info
precmd_vcs_info() { vcs_info }
precmd_functions+=( precmd_vcs_info )
setopt prompt_subst
RPROMPT=\$vcs_info_msg_0_
zstyle ':vcs_info:git:*' formats '%F{240}%b%f'
zstyle ':vcs_info:*' enable git

if type direnv &> /dev/null; then
    eval "$(direnv hook zsh)"
fi

# Macbook setup checklist

Link/Copy dotfiles

dotfiles/nvim
dotfiles/kitty
dotfiles/.ideavimrc
dotfiles/jetbrains-ide-settings.zip
dotfiles/scripts/hooks

Copy over dev/references/ folder for codebases to learn from

Remove unnecessary apps from Dock

Keyboard/Shortcuts

Plug keyboard in on its own, go through keyboard wizard on its own and hit \ . Check that correct GUI form is done in keyboard sources.
Delete plist file if not
https://apple.stackexchange.com/questions/335400/how-switch-mac-uk-pc-keyboard-layout-backslash-and-backtick-to-match-normal

Microsoft Receiver shortcuts
 Option    -> Command Key
 Caps Lock -> Escape

If keyboard messes up its | and \ ` and ¬ keys increment and decrement the karabiner elements keys

Shortcuts -> App Shortcuts -> Paste and Match Style -> Command + Shift + V
Use Keyboard Navigation (better tabs in apps)
Turn off keyboard auto correction in System Preferences Mac
Change Press globe to do nothing
Backlight off in 10 seconds
Key Repeat -> Fastest
Delay Until Repeat -> Shortest

Keyboard -> Shortcuts -> Mission Control -> Hyper + 1 to Desktop 1
Keyboard -> Shortcuts -> Mission Control -> Hyper + 2 to Desktop 2
Keyboard -> Shortcuts -> Mission Control -> Hyper + 3 to Desktop 3
Keyboard -> Shortcuts -> Mission Control -> Hyper + 5 to Mission Control

Trackpad
Lightest click and 5th notch from left for speed

Enable Secondary click for mouse
Tap to click enable
Force Silent Clicking off
Enable Light click
Accessibility -> Pointer Control -> Trackpad Options -> 3 Finger Drag  -- Allow easy movement of windows with trackpage
Accessibility -> Zoom -> Use Keyboard Shortcuts to zoom

Misc

Stop default ‘Last login at X’ msg on every terminal opening
touch ~/.hushlogin

Mission Control -> Hot Corners -> Bottom left desktop, top right notifications
Display -> Slightly dim when on battery off
Terminal -> Preferences -> New windows open with same working directory
Accessibility -> Display -> Show window titles (for finder ability to drag folder)
Alert sound effect volume slider to 0
Drag sound from mission control to menubar
Night Shift under display
Modify Notifications - Turn most off?
Set computer name
System Preferences -> Sound. Sound Effects -> Sound on startup off
Turn off font smoothing -- test first, turn OFF “Font smoothing” in System Preferences → General: https://tonsky.me/blog/monitors/
Turn off Siri -> Settings -> Siri -> Listen for Hey Siri off
Settings AppleID -> iCloud Drive Options -> Turn off desktop and documents folder
App Store -> cmd + , -> turn off in app ratings and reviews
Mail App -> Settings -> Turn off sounds
		Up font size
		Discarded messages to archive
		When Quoting text in replies or forwards include all of original text
Terminal App -> cmd + , -> Basic Profile -> Font 18 SF Mono
			  -> Advanced Audible bell off
iMessage App -> cmd + , -> Sound effects off -> Increase text size
Remove Siri from top right
Accessibility -> Reduced Motion

Dock + Menu

Change from genie effect to scale effect
Show suggested and recent apps in Dock -> off
Enable auto hiding
Animate opening windows off

Make Dock fast to hide and unhide
defaults write com.apple.dock autohide-delay -int 0
defaults write com.apple.dock autohide-time-modifier -float 0.25
killall Dock

Disable showing of Spotlight in menubar search settings

Defaults to run

# Enable the expand save panel by default for images/files
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true

# Disable the “Are you sure you want to open this application?”
defaults write com.apple.LaunchServices LSQuarantine -bool false

# Disable Screenshot shadow (requires restart) - requires killall SystemUIServer
defaults write com.apple.screencapture disable-shadow -bool true

# Set a blazingly fast keyboard repeat rate
defaults write NSGlobalDomain KeyRepeat -int 1
defaults write NSGlobalDomain InitialKeyRepeat -int 10

# Disable accent bar when holding key
defaults write -g ApplePressAndHoldEnabled -bool false

# Disable mouse acceleration
defaults write .GlobalPreferences com.apple.mouse.scaling -1

# Finder: allow quitting via ⌘ + Q; doing so will also hide desktop icons
defaults write com.apple.Finder QuitMenuItem 1

# Disable audible chime when plugging into power
defaults write com.apple.PowerChime ChimeOnNoHardware -bool true && killall PowerChime

# Disable font smoothing, 0 disable, 1 light, 2 medium, 3 strong
defaults -currentHost write -g AppleFontSmoothing -int 1

https://mmazzarolo.com/blog/2022-04-16-drag-window-by-clicking-anywhere-on-macos/
defaults write -g NSWindowShouldDragOnGesture -bool true

Finder
Finder Preferences -> 	Show path bar at bottom
		Uncheck Recent Tags within finder
		Sidebar -> Uncheck Recent Folder
		                -> Home Directory drag to top
		Advanced -> Show all filename extensions
			 Show warning before changing an extension off
			 Show warning before removing from iCloud Drive
			 Remove items from Trash after 30 days
			 Search this current folder ticked
		New Folder windows show Downloads
		Search Current Folder
Go Menu -> Hold Alt -> Click Library -> File -> Add to Sidebar

Safari

Customise Safari Start page to show only whats necessary bottom right on Safari
Customise Safari status bar -> Safari -> View -> Show status bar
General ->
	Opens with previous tabs
	Remove History items after few months
Advanced -> Show full website address

Privacy / Battery

Turn off locations for as much apps as possible under Security and Privacy (battery saver)
Go to bottom of Security & Privacy within Location Services. Turn Off all but Find My Mac
Scroll down in Privacy to Analytics, do not share anything
Advertising Setting -> Limit Ad Tracking
Turn off all Extensions not necessary

Linear Mouse

800 DPI - 0 ACCEL, 0.5 SPEED
1600 DPI - 0 ACCEL, 0.2625 SPEED
Trackpad 0.875 accel, 0.069 speed
By Lines -> 10
Enable Universal Back and Forward

BetterDisplay

2048x1152
2416x1359

Alfred

Import UI settings
Hyper + C Clipboard History
cmd+l to make text you type in super big on screen
Security & Privacy Full Disk Access, Accessibility, Automation - tick all
Workflows Installed - Search Notes, TimeZones, Numi, Agenda
Features - Universal Actions - Show Actions - Only Right Arrow Ticked

Add applications to startup
https://apple.stackexchange.com/questions/310495/can-login-items-be-added-via-the-command-line-in-high-sierra to add

Vim

copy ~/nvim/init.nvm to home
Installl VimPlug
:PluginInstall / :PlugSnapshot snapshot.vim
:CocInstall coc-tsserver coc-java coc-go coc-phpls coc-html coc-json coc-pyright coc-clangd coc-yaml coc-eslint coc-prettier coc-cfn-lint coc-docker coc-groovy
brew install cfn-lint
:TSInstall java typescript javascript php ruby python c html svelte yaml jsdoc vim tsx css scss json graphql dockerfile regex go

/.vim/plugged/Paper.vim
hi! link TSMethod Keyword
highlight CocMenuSel guibg=#d8d5c7
highlight CocFloating guibg=#f7f3e3
highlight CocSearch guibg=#000
hi! link CocInfoVirtualText Todo

Terminal
Settings -> Profiles -> Keyboard -> Check Use Option as Meta Key
Settings -> Profiles -> Window -> Uncheck Dimensions

IntelliJ
Unzip and import settings from jetbrains-ide-settings.zip in dotfiles drive
Compare ideavim keybind settings with personal and copy (does not save in settings.zip)
Need to look at installed.txt when importing settings + place .ideavimrc in ~
14/16 fontsize
Editor -> General -> Editor Tabs none

Shortcuts
Hyper + R  -> Run
Hyper + Enter -> Start New Line
Hyper + W -> Expand selection
Format on Save, Optimise Imports on Save
Hyper + D -> Debug
Hyper + T -> Refactor This
Hyper + E -> Rename
Hyper + G -> Go to Declaration or Usages
Hyper + Tab -> Iterate Switcher Forward
Hyper + S -> Search Everywhere
Hyper + ‘ -> Local History

IBM Plex Mono Font Size 16, 1.2 Line Height

On Save Actions
Auto-import enable
Auto-format on save
Auto-optimise on save

Code Style
Properties -> Keep Blank Lines Checked
Code Style -> Hard Wrap -> 400

Java
Blank Line Formatting
Keep Maximum blank lines
In declarations - 1,
In Code - 1,
before } - 0,
Before header package - 0

Keep Minimum blank lines
After class header - 1
Before class end - 1
Before method body - 0
Around method -1

Ruby
Wrapping and Braces -> Align when multiline - off
Wrapping and Braces -> Align right parts - on

Inspections
Control flow issues -> Negative condition in control flow statement -> Disabled
Redundant Code -> Redundant ‘return’ statement -> Disabled
Naming Conventions -> Unconventional local variable name -> Max Length 80
# .ideavimrc

set multiple-cursors
set surround
set matchpairs
set ideajoin
set easymotion
set NERDTree
set ideastatusicon=gray

set clipboard=unnamedplus " share clipboard with system
set scrolloff=8           " reaching top or bottom of screen is offset by

set hlsearch   " dont keep highlighting after searching
set incsearch  " while typing search command, incrementally show highlighted results
set ignorecase " ignore case when searching with /
set smartcase  " dont ignore case if a caps letter is used while searching

let mapleader = " "

map , :action ActivateProjectToolWindow<cr>
imap <Right> <Action>(copilot.applyInlays)

" Empty line above/below
nnoremap <M-A-C-S-K> O<esc>j
nnoremap <M-A-C-S-j> o<esc>k

" Search
nnoremap s /

" Tab to tab lines in visual mode
vnoremap <Tab> >gv
vnoremap <S-Tab> <gv

" Insert mode quick remove one char ahead
inoremap <c-x> <c-o>x

" Insert mode quick delete line
inoremap <c-d> <c-o>dd

" Switch between open editor tabs
" nnoremap <S-Tab> :action PreviousTab<cr>
" nnoremap <Tab> :action NextTab<cr>

" Window navigation
nnoremap <Left> <C-w>h
" nnoremap <Right> <C-w>l
nnoremap <Down> <C-w>j
nnoremap <Up> <C-w>k
nnoremap <silent> <M-A-C-S-U> :vsplit<cr>
nnoremap <silent> <M-A-C-S-N> :split<cr>

nmap S <Plug>(easymotion-s2)
omap f <Plug>(easymotion-fl)
omap F <Plug>(easymotion-Fl)
vmap f <Plug>(easymotion-fl)
vmap F <Plug>(easymotion-Fl)
omap t <Plug>(easymotion-tl)
omap T <Plug>(easymotion-Tl)
vmap t <Plug>(easymotion-tl)
vmap T <Plug>(easymotion-Tl)

" Select all
nnoremap <C-a> gg<S-v>G

" Swap dd to D
nnoremap D "_dd
nnoremap dd "_D

" Selecting to end of line should not include new line char
vnoremap $ $h

" Delete to not override paste clipboard using leader, keep paste clipboard on multiple paste.
nnoremap x "_x
vnoremap x "_x
nnoremap d "_d
vnoremap d "_d
nnoremap C "_C
vnoremap C "_C
nnoremap c "_c
vnoremap c "_c

" Allow paste in visual mode without losing paste again
xnoremap p pgvy
xnoremap P Pgvy

" Swap gg and G
nnoremap gg G
nnoremap G gg

" Jump around with screen in center
nnoremap <C-d> <C-d>zz
nnoremap <C-u> <C-u>zz

" Line movement on multi select up and down
vnoremap J :action MoveStatementDown<cr>
vnoremap K :action MoveStatementUp<cr>

" Yank full line to Y
nnoremap Y yy

" Make j and k move to the next row, not file line useful for when line wrapping occurs
nnoremap j gj
nnoremap k gk

" Disable highlighted search upon escape
nnoremap <silent> <esc> :noh<return><esc>

" Quit
nnoremap <silent> <C-x> :x<CR>
nnoremap <silent> <C-q> :qa<CR>

" dont use zt or zb so make common case on centering easier
nnoremap z zz

" Jump around searches while keeping screen centered
nnoremap n nzzzv
nnoremap N Nzzzv

" Cut
vnoremap X ygvd

map m <Action>(FileStructurePopup)
nnoremap <leader>po :action ManageRecentProjects<CR>
nnoremap <leader>pc :action CloseProject<CR>
nnoremap <leader>mr :action MoveElementRight<CR>
nnoremap <leader>ml :action MoveElementLeft<CR>
nnoremap <leader>fn :action ShowNavBar<CR>
nnoremap <leader>rr :action Refactorings.QuickListPopupAction<CR>
nnoremap <leader>t :action RerunTests<CR>
nnoremap <leader>gb :action Git.Branches<CR>
nnoremap <leader>ga :action Annotate<CR>
nnoremap <leader>gp :action Git.Pull<CR>
nnoremap \c :action CollapseRegion<CR>
nnoremap \o :action ExpandRegion<CR>
nnoremap <c-o> :action Back<cr>
nnoremap <c-i> :action Forward<cr>
map <M-z> <Action>(ToggleDistractionFreeMode)

" Grep everywhere
nnoremap F :action FindInPath<cr>
nnoremap f :action GotoFile<cr>

map R <Action>(RenameElement)
map <leader>b <Action>(ToggleLineBreakpoint)
map <c-d> <Action>(EditorPageDown)
map <c-u> <Action>(EditorPageUp)
map <leader>rt :action TestTreePopupMenu<CR>
map gc :action CommentByLineComment<CR>
map gd <Action>(GotoDeclaration)
map gi <Action>(GotoImplementation)
map ga <Action>(ShowIntentionActions)
map gf <Action>(AnalyzeMenu)
map gt <Action>(GotoTest)
map gr <Action>(FindUsages)
map gh <Action>(QuickJavaDoc)
map ge <Action>(GotoNextError)
map gE <Action>(GotoPreviousError)
map gv <Action>(IntroduceVariable)
map gm <Action>(ExtractMethod)
map gw <Action>(SurroundWith)
map gu <Action>(Unwrap)
map gn <Action>(Inline)
map gs <Action>(GotoRelated)

nnoremap <leader>l :action QuickChangeScheme<cr>

" Reload ideavimrc
nnoremap <leader><space> :e ~/.ideavimrc<CR>
nnoremap <leader><cr> :action IdeaVim.ReloadVimRc.reload<CR>