개발 환경 설정 (2025-2026)
OS 공통
글꼴
OS 구분 없이 설치할 글꼴 목록
Pretendard
https://github.com/orioncactus/pretendard/releases
Pretendard와 Pretendard Variable만 설치한다.
나눔바른고딕
https://hangeul.naver.com/2017/nanum
D2Coding
https://github.com/naver/d2codingfont/releases
기본 버전만 설치한다 (bold 포함).
macOS/Ubuntu 공통
macOS/Ubuntu Git 설정
~/.gitconfig를 설정한다. user.name과 user.email을 수정해야 한다.
먼저 fzf 설치가 필요하다! Interactive CLI 프로그램 이런 거 따로 설치할 필요없이, CLI에서 화살표, 탭 몇 번 눌러서 브랜치를 선택할 수 있다. (git branch | grep -v '^\*' | fzf -m | xargs git branch -D를 처음 썼을 때의 감동이란...)
[user]
name = Your Name
email = id@email.com
[core]
editor = vim
ignorecase = false
[fetch]
recurseSubmodules = on-demand
[push]
default = simple
[alias]
st = status
ci = commit
cinv = commit --no-verify
ciam = commit --amend
ciamnv = commit --amend --no-verify
br = branch
ibrs = "!f() { git branch --color=always | fzf -m --ansi | perl -pe 's/\\e\\[[0-9;]*m//g' | cut -c 3-; }; f"
brd = branch -D
ibrd = "!f() { git branch | grep -v '^[*+]' | awk '{print $NF}' | fzf -m | xargs -I{} git brd {} \"$@\"; }; f"
chp = cherry-pick
co = checkout
ico = "!f() { git branch --color=always | fzf --ansi | perl -pe 's/\\e\\[[0-9;]*m//g' | awk '{print $NF}' | xargs -I{} git checkout {} \"$@\"; }; f"
irtco = "!f() { git branch -r --color=always | fzf --ansi | perl -pe 's/\\e\\[[0-9;]*m//g' | awk '{print $NF}' | xargs -I{} git checkout {} \"$@\"; }; f"
cobr = checkout -b
fe = fetch
fep = fetch --prune
fepo = fetch --prune origin
logp = log --pretty='%C(blue)%ai %C(brightmagenta)%<(18,trunc)%an %C(brightblack)%h %C(reset)%s %C(cyan)%d'
pu = push
puu = push -u
puuo = push -u origin HEAD끔찍하게도 리눅스와 다르게, macOS에서는 Git이 기본적으로 대소문자를 구분하지 않는다. core.ignorecase = false 설정을 하지 않으면, 몇 시간을 허비할 수도 있다.
fzf -m은 상호작용 셸에서 다중 선택이 가능하다. Tab 키로 선택하고, Shift-Tab 키로 해제한다.
git puuo를 하면, 위험한 push.autoSetupRemote = true 설정 없이도 현재 HEAD 브랜치를 같은 이름으로 생성하면서 upstream 설정까지 할 수 있다.
.gitconfig에서는 backslash(\) escape를 해줘야 한다는 사실도 주의해야 함.
macOS/Ubuntu VIM 설정
~/.vimrc에 아래 문장을 추가한다.
set ruler: 줄과 칼럼 번호가 보인다.syntax on: Git commit 시 색깔이 보인다.
set nu (줄 번호가 보인다.)는 사용하지 않는다. 평소에는 터미널 너비만 줄이는 것 같다...
masOS
Git wrapper
Git을 영문으로 실행하는 wrapper임. PATH 등록 필요함.
mkdir -p ~/.local/bin
cat > ~/.local/bin/git << 'EOF'
#!/bin/sh
# Execute Git in English.
LANG=en_US.UTF-8 exec /usr/bin/git "$@"
EOF
chmod +x ~/.local/bin/git
(macOS) Shell - zsh
2023년부터 Bash 대신 zsh를 기본으로 사용한다. Login shell 기본 스크립트는 ~/.zprofile을, interactive shell 기본 스크립트는 ~/.zshrc를 수정한다.
최신 macOS의 기본 shell은 zsh이다.
~/.zshrc 일부
.bashrc와 호환되지 않는다.
# Use the simple primary prompt string.
export PS1="%1~ %# "
# Bind custom shortcuts.
# (Enable word-jump shortcuts without changing terminal program key mappings.)
bindkey "^[[1;5C" forward-word
bindkey "^[[1;5D" backward-word
# Homebrew 1
export PATH="/opt/homebrew/bin:$PATH"
# Homebrew 2
export PATH="/usr/local/bin:$PATH"
# NVM
# ('--no-use' is required to prevent slow performance! Must use 'nvm use' or 'nvm use default' only
# if needed.)
# https://github.com/nvm-sh/nvm/issues/1261
export NVM_DIR=~/.nvm
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh" --no-use
# Claude Code path
export PATH="$HOME/.local/bin:$PATH"
# Claude Code aliases
alias cld='claude'
alias cldsp='claude --dangerously-skip-permissions'
# Claude Code Switch(CCS)
# (runs with NVM default node to avoid project version conflicts.)
function ccs() {
(
if type nvm &>/dev/null; then
nvm use default
fi
command ccs "$@"
)
}
alias ccssp='ccs --dangerously-skip-permissions'
# Codex
# (runs with NVM default node to avoid project version conflicts.)
function codex() {
(
if type nvm &>/dev/null; then
nvm use default
fi
command codex "$@"
)
}
# fzf
source <(fzf --zsh)
# Git in English
alias git='LANG=en_US.UTF-8 git'
# compinit
# (It activates Git autocompletion too.)
# https://stackoverflow.com/a/58517668
autoload -Uz compinit && compinit
# Zellij shell completion
# https://github.com/zellij-org/zellij/issues/1933#issuecomment-3020581413
[ -x "$(command -v zellij)" ] \
&& . <( zellij setup --generate-completion zsh | sed -E "
/^autoload -U is-at-least/a\\
\\
_zellij_sessions() {\\
local line sessions desc; sessions=(\"\${(@f)\$(zellij ls -n)}\")\\
local -a session_names_with_desc\\
for line in \"\${sessions[@]}\"; do\\
session_name=\${line%% *}\\
desc=\${line#* }\\
session_names_with_desc+=(\"\$session_name:\$desc\")\\
done\\
_describe -t sessions 'active session' session_names_with_desc\\
}
s/^(attach)/\1|a/
s/::session-name -- Name of the session to attach to:/::session-name:_zellij_sessions/
s/^(kill-session)/\1|k/
s/::target-session -- Name of target session:/::target-session:_zellij_sessions/
s/^(delete-session)/\1|d/
s/^(_(zellij) ).*/compdef \1\2/
")
# ghq custom functions
# https://shunk031.me/post/ghq-gwq-fzf-worktree/
function ghq-path() {
ghq list --full-path | fzf
}
function cghq() {
# Must use 'local' separately to capture the return code of fzf.
local TARGET_PATH
TARGET_PATH=$(ghq list | fzf)
local RET=$?
if [[ "$RET" -ne 0 ]]; then
return $RET
fi
local TARGET_ABSOLUTE_PATH="$(ghq root)/$TARGET_PATH"
cd "$TARGET_ABSOLUTE_PATH" \
&& echo "$TARGET_PATH" \
|| exit 1
}
function cghq-rename-tab() {
cghq
local RET=$?
if [[ "$RET" -ne 0 ]]; then
return $RET
fi
local REPO_NAME="${PWD##*/}"
local TAB_NAME="${REPO_NAME//./-}"
# Rename this tab if in Zellij.
if [[ -n ${ZELLIJ} ]]; then
zellij action rename-tab "$TAB_NAME"
# Rename this window if in Tmux.
elif [[ -n ${TMUX} ]]; then
tmux rename-window "$TAB_NAME"
fi
}
# gwq shell completion
[ -x "$(command -v gwq)" ] && source <(gwq completion zsh)
# gwq custom functions
function mygwq-ls() {
local JSON
JSON=$(gwq ls --json)
local RET=$?
if [[ "$RET" -ne 0 ]]; then
return $RET
fi
local -a PATHS BRANCHES MAINS
while IFS= read -r LINE; do
PATHS+=("${LINE/#$HOME/~}")
done < <(jq -r '.[].path' <<< "$JSON")
while IFS= read -r LINE; do
BRANCHES+=("$LINE")
done < <(jq -r '.[].branch' <<< "$JSON")
while IFS= read -r LINE; do
MAINS+=("$LINE")
done < <(jq -r '.[].is_main' <<< "$JSON")
local CURRENT_TOPLEVEL=$(git rev-parse --show-toplevel 2>/dev/null)
local I PREFIX LAST_DIR_COLOR
for (( I = 1; I <= ${#PATHS[@]}; I++ )); do
if [[ "${PATHS[$I]}" == "${CURRENT_TOPLEVEL/#$HOME/~}" ]]; then
PREFIX=$'\033[92m* \033[0m'
else
PREFIX=" "
fi
if [[ "${MAINS[$I]}" == "true" ]]; then
LAST_DIR_COLOR="33"
else
LAST_DIR_COLOR="95"
fi
printf "%s\033[90m%s/\033[%sm%s\033[0m \033[36m%s\033[0m\n" \
"$PREFIX" "${PATHS[$I]%/*}" "$LAST_DIR_COLOR" "${PATHS[$I]##*/}" "${BRANCHES[$I]}"
done
}
function mygwq-irm() {
local JSON
JSON=$(gwq ls --json)
local RET=$?
if [[ "$RET" -ne 0 ]]; then
return $RET
fi
local CURRENT_TOPLEVEL=$(git rev-parse --show-toplevel 2>/dev/null)
local -a ITEMS
local DISPLAY_PATH
while IFS= read -r ENTRY_PATH; do
[[ "$ENTRY_PATH" == "$CURRENT_TOPLEVEL" ]] && continue
ENTRY_PATH="${ENTRY_PATH/#$HOME/~}"
DISPLAY_PATH=$'\033[90m'"${ENTRY_PATH%/*}/"$'\033[95m'"${ENTRY_PATH##*/}"$'\033[0m'
ITEMS+=("$DISPLAY_PATH")
done < <(jq -r '.[] | select(.is_main == false) | .path' <<< "$JSON")
if (( ${#ITEMS[@]} == 0 )); then
echo "No target non-main worktrees found."
return 0
fi
# Must use 'local' separately to capture the return code of fzf.
local SELECTED
SELECTED=$(printf '%s\n' "${ITEMS[@]}" | fzf --ansi)
local RET=$?
if [[ "$RET" -ne 0 ]]; then
return $RET
fi
local CLEAN_PATH=$(sed $'s/\033\\[[0-9;]*m//g' <<< "$SELECTED")
echo "Removing: $CLEAN_PATH"
gwq rm -f "$@" "${CLEAN_PATH/#\~/$HOME}"
}
# jenv
export PATH="$HOME/.jenv/bin:$PATH"
[ -x "$(command -v jenv)" ] && eval "$(jenv init -)"
# PNPM
# pnpm
export PNPM_HOME="$HOME/Library/pnpm"
case ":$PATH:" in
*":$PNPM_HOME:"*) ;;
*) export PATH="$PNPM_HOME:$PATH" ;;
esac
# pnpm end
# pyenv
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv > /dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
command -v pyenv > /dev/null && eval "$(pyenv init -)"
# Cargo
export PATH="$HOME/.cargo/bin:$PATH"
# pchuri Confluence CLI
# (runs with NVM default node to avoid project version conflicts.)
function confluence() {
(
if type nvm &>/dev/null; then
nvm use default
fi
command confluence "$@"
)
}
# pchuri Jira CLI
# (runs with NVM default node to avoid project version conflicts.)
function jira() {
(
if type nvm &>/dev/null; then
nvm use default
fi
command jira "$@"
)
}
# iTerm2
test -e "${HOME}/.iterm2_shell_integration.zsh" && source "${HOME}/.iterm2_shell_integration.zsh"
# Rancher Desktop
### MANAGED BY RANCHER DESKTOP START (DO NOT EDIT)
export PATH="/Users/user/.rd/bin:$PATH"
### MANAGED BY RANCHER DESKTOP END (DO NOT EDIT)
# Hadoop
export HADOOP_HOME="$HOME/apps/hadoop"터미널의 키 매핑을 바꾸지 않고도, 단어 사이의 커서 이동을 가능하게 만든다. 이걸 macOS의 셸 설정으로 해야, SSH 원격 접속 시에도 키 매핑이 어울리게끔 할 수 있는 것이다.
zsh의 Git autocompletion은 다음 웹페이지를 참고한다.
https://stackoverflow.com/a/58517668
.zshrc가 느리다고 생각이 되면, ZProf로 프로파일링해서 개선점을 찾아볼 수 있다.
(macOS) Shell - bash
Bash 단축키 변경
터미널의 키 매핑을 바꾸지 않고도, 단어 사이의 커서 이동을 가능하게 만든다. 이걸 macOS의 셸 설정으로 해야, SSH 원격 접속 시에도 키 매핑이 어울리게끔 할 수 있는 것이다.
~/.inputrc 파일을 수정한다 (Bash가 아닌 다른 셸에서도 가능).
"\e[1;5C": forward-word
"\e[1;5D": backward-word즉시 적용할 수 있다 (Bash 안에서만 수행).
bind -f ~/.inputrcmacOS 프로그램 (IDE 제외)
Homebrew 설치 이후 터미널에서 명령어를 입력한다.
Homebrew 설치
macOS의 필수 프로그램 1. (iTerm2도 HomeBrew로 설치할 것이기 때문.)
2023년에 확인했을 때는 zsh에서는 Homebrew 설치가 제대로 안 된다. 그래서 ~/.zshrc 파일을 수정한다.
export PATH=/opt/homebrew/bin:$PATH
Homebrew cask 기능이 완전히 통합돼서, 2024년부터 brew tap homebrew/cask-versions 명령어가 불필요해진 것 같다.
iTerm2 (터미널) 설치
macOS의 필수 프로그램 2.
brew install --cask iterm2설치 후 "macOS iTerm2 설정" 항목을 참고한다.
Thaw 설치
노치로 인해 좁아진 MacBook 메뉴 바 아이콘의 구원자 같은 프로그램이다. 원하는 아이콘만 보여주고, 숨길 아이콘을 선택할 수 있으며, 숨긴 아이콘을 따로 보는 것도 가능하다.
https://github.com/stonerl/Thaw
brew install thaw"Launch at login" 설정은 필수다.
Karabiner Elements 설치
우측 Command를 한/영키로 바꾸기 위해서는 필요하다.
brew install --cask karabiner-elementsjenv 설치
# Install jenv
brew install jenv.zshrc에 다음 내용을 추가한다.
# jenv
export PATH="$HOME/.jenv/bin:$PATH"
[ -x "$(command -v jenv)" ] && eval "$(jenv init -)"OpenJDK 설치
JDK 11, 17, 21, 25를 설치하고, 17을 기본으로 사용한다.
Homebrew formula 중 openjdk는 symbolic link를 직접 걸어줘야 해서 불편하다...
특히 openjdk@8은 openjdk@8: The x86_64 architecture is required for this software. 오류가 나므로, 애플 실리콘 맥 기기에 설치할 수 없다. JDK 1.8의 경우에는 Zulu OpenJDK를 이용하자.
# Install Homebrew formulas
brew install openjdk@11 openjdk@17 openjdk@21 openjdk@25
# Symlink JDKs (required for Homebrew formulas not casks)
sudo ln -sfn /opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk \
/Library/Java/JavaVirtualMachines/openjdk-11.jdk
sudo ln -sfn /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk \
/Library/Java/JavaVirtualMachines/openjdk-17.jdk
sudo ln -sfn /opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk \
/Library/Java/JavaVirtualMachines/openjdk-21.jdk
sudo ln -sfn /opt/homebrew/opt/openjdk@25/libexec/openjdk.jdk \
/Library/Java/JavaVirtualMachines/openjdk-25.jdk
# List all JDKs
/usr/libexec/java_home -V
# Add JDKs to jenv
jenv add /Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home
jenv add /Library/Java/JavaVirtualMachines/openjdk-17.jdk/Contents/Home
jenv add /Library/Java/JavaVirtualMachines/openjdk-21.jdk/Contents/Home
jenv add /Library/Java/JavaVirtualMachines/openjdk-25.jdk/Contents/Home
# List all jenv JDKs
jenv versions
# Set Java 17.0 as default
jenv global 17.0
# Check current Java version
java -versionjenv 홈페이지가 깔끔하다.
Rancher Desktop 설치
Apple Sillicon Mac 기기에서도 Docker나 Kubernetes를 가상 머신에서 실행시킬 수 있다.
Homebrew로 설치하면 좀 다르다는 썰이 보이니, 그냥 홈페이지에서 설치 파일을 받는다.
GIMP 설치
brew install --cask gimp(macOS) BetterTouchTool (유료)
외부 마우스 설정
Logitech 마우스가 아니라면, 이것으로 마우스 버튼을 mapping한다. Button 3 (좌측 위 버튼)은 "Move Left a Space", Button 4 (좌측 아래 버튼)은 "Move Right a Space"로 mapping한다.
키보드 설정
추가로 다음 단축키도 mapping한다.
control-J->down(VIM 스타일)control-K->up(VIM 스타일)fn+\-> Toogle Bluetooth (블루투스 마우스 연결로 인해 트랙패드가 잠겼을 때 대응하는 수단)
(macOS) 구름 입력기
기존 macOS 입력기는 자꾸 이상한 유니코드 문자를 남긴다. 그리고 backtick - 원화 기호 설정 변경이 편하게 안 된다.
구름 입력기 설치
brew install --cask gureumkim반드시 로그아웃을 한 번 해야 한다.
구름 입력기 설정
내부 단축키 설정
"한자 및 이모지 단축키"가 option-enter이므로, IntelliJ와 충돌한다.
단축키를 해제한다.
시스템 단축키 설정
"오른쪽 키로 언어 전환"을 해제한다. Karabiner Elements 방식보다 잘 씹힌다.
한글 입력기 설정
"한글 입력기일 때 역따옴표(`)로 원화 기호(\) 입력" 체크 상자를 해제한다.
"Esc 키로 로마자 자판으로 전환 (vi 모드)" 체크 상자를 설정한다.
우측 Command를 한/영키로 바꾸기
Karabiner Elements에서 right_command 등을 F16에 mapping한다.
https://makepluscode.tistory.com/164
하지만... 이 방식에는 문제가 있으니. 바로 UTM 같은 가상 머신 프로그램에서 오른쪽 커맨드 버튼이 전달되지 않는다는 것이다.
ChatGPT 3.5에게 다음 질문을 하여 Karabiner custom rule JSON을 생성했다.
"Give me a custom rule JSON for macOS Karabiner-Elements to map the right command key to F16 in any application except one of which bundle identifier is com.utmapp.UTM."
{
"description": "Map right command key to F16 in any application except UTM",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "right_command",
"modifiers": {
"optional": ["any"]
}
},
"to": [{ "key_code": "f16" }],
"conditions": [
{
"type": "frontmost_application_unless",
"bundle_identifiers": ["com.utmapp.UTM"]
}
]
}
]
}macOS 중요한 설정
(macOS 13 Ventura) Caps Lock으로 한/영 전환 하지 않도록 막기
환경설정 > 키보드 > 입력 소스 > 편집...
"한/영키로 key ABC 전환" 체크 상자를 해제한다.
(macOS 13 Ventura) 메뉴 바에 블루투스 아이콘 추가하기
https://www.iphonetricks.org/add-bluetooth-icon-to-menu-bar-macos-ventura/
키를 누르고 있을 때 '액센트가 있는 문자' 대신 키 반복 입력 사용하기
defaults write -g ApplePressAndHoldEnabled -bool falsehttps://macnews.tistory.com/2195
(macOS 13 Ventura) 키보드 입력 소스 설정 바꾸기
환경설정 > 키보드 > 입력 소스 > 편집...
맞춤법 자동 수정, 스페이스를 두 번 눌러 마침표 추가, 스마트 인용 부호 및 대시 사용 옵션을 모두 끈다.
큰따옴표와 작은따옴표를 곧은 것으로 고른다 (개발자 필수 옵션).
Mission Control 애니메이션 속도 올리기
Space(desktop) switching animation이 너무 느리다. 이건 꼭 필요하다.
defaults write com.apple.dock expose-animation-duration -float 0.1; killAll Finder && killAll Dockhttps://apple.stackexchange.com/a/475279
텍스트 편집기(TextEdit) 기본 창 크기 설정하기
환경설정 (command-comma) > 윈도우 크기 section
너비 165자, 높이 60줄로 설정한다.
Function key (F1~F12)를 기본으로 사용하기
System Settings > Keyboard > Keyboard Shortcuts > Function Keys
트랙패드의 "페이지 쓸어넘기기" 제스처 설정하기
환경설정 > 트랙패드 > 추가 제스처 > 페이지 쓸어넘기기
이걸 "끔"에서 "두 손가락으로 좌우로 스크롤하기"로 바꿔야, Chrome에서 터치패드 두 손가락 좌우로 쓸기를 써서, 뒤로 가기와 앞으로 가기를 할 수 있다.
맥 화면 꺼짐 시 절전이 되지 않게 막기
# 전원 어댑터 연결 시 자동 절전 금지
sudo pmset -c sleep 0
# 배터리 사용 중에도 자동 절전 금지
sudo pmset -b sleep 0(macOS) iTerm2 설정
Key
iTerm2 기본 키 설정만으로는 제대로 쓸 수가 없다. (오히려 macOS 기본 터미널 앱보다 더 불편할 수도 있다.)
Option(⌥) 키 안 먹히는 문제 고치기
iTerm2에서는 기본적으로 Zellij 같은 프로그램이 제대로 동작하지 않는다. 설정을 고쳐야, Option(⌥) 키가 전달되게 만들 수 있다. (사실 이 문제는 macOS 기본 터미널 앱에도 존재한다.)
Preferences > Profiles > Keys > General
"Left option (⌥) key"를 "Normal"에서 "Esc+"로 바꾼다.
임의의 전역 키 바인딩
나만의 키 바인딩이다.
참고로 Ignore라는 action은 터미널 내부로 키가 전달되지 않게 만든다.
내가 Previous Tab 주로 쓰는 키인 control-H는 Zellij와 충돌한다. ㅠㅠ 그런데 어차피 Cycle Tabs Forward/Backward 단축키인 control-(/shift)-tab이 있어서 쓸모가 없다.(?) 대체 왜 중복으로 존재하는 걸까?
- (+): 기존 단축키에 추가한다.
- (R): 기존 단축키를 제거하고 추가한다.
| Action | Default | My binding |
|---|---|---|
| Previous Tab | command-left |
(-) None |
| Next Tab | command-right |
(-) None |
프로필 키 바인딩 & Natural editing 키셋 설정
Preferences > Profiles > Keys > Key Bindings
"Presets..."에서 "Natural Text Editing"을 선택한다.
이걸 해야, command/option + arrow/delete 등의 조합을 사용할 수 있다.
https://superuser.com/a/1157575
하지만 Zellij를 잘 쓰려면, 여기서 또 option-left와 option-right binding들을 바꿔야 한다! alt-b와 alt-f로 변환하는 설정이기 때문에, alt-f는 Zellij의 floating pane 기능과 충돌할 수밖에 없는 운명이다.
| Default | Key |
| :-- | :-- | :-- |
| Send Escape Sequence: Esc+[1;5D | option-left |
| Send Escape Sequence: Esc+[1;5C | option-right |
텍스트 선택 시 자동 복사 끄기
Preferences > General > Selection > Copy to pasteboard on selection (selection)
위 설정을 끈다.
글꼴 변경
Prefs > Profiles > Text > Font
- 글꼴: D2Coding
- 크기: 13
색상 조정
Prefs > Profiles > Colors
- Basic Colors
- Foreground:
c7c7c7 - Background:
000000 - Brighten bold text: true
- Minimum Contrast: 0
- Foreground:
- ANSI Colors:
- Black Normal:
484848 - Black Bright:
6b6b6b - Red Normal:
c03a38 - Red Bright:
ef5350 - Green Normal:
00cc33 - Green Bright:
4eff79 - Yellow Normal:
ca9f02 - Yellow Bright:
fdcc1c - Blue Normal:
2072ac - Blue Bright:
3d99db - Magenta Normal:
ab51ba - Magenta Bright:
c792ea - Cyan Normal:
1e9094 - Cyan Bright:
27b9be - White Normal:
c7c7c7 - White Bright:
ffffff
- Black Normal:
색상 확인은 아래 Bash 스크립트로 한다.
#!/bin/bash
#
# This file echoes a bunch of color codes to the
# terminal to demonstrate what's available. Each
# line is the color code of one forground color,
# out of 17 (default + 16 escapes), followed by a
# test use of that color on all nine background
# colors (default + 8 escapes).
#
# Copied from http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
T='gYw' # The test text
echo -e "\n 40m 41m 42m 43m\
44m 45m 46m 47m";
for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' ' 32m' \
'1;32m' ' 33m' '1;33m' ' 34m' '1;34m' ' 35m' '1;35m' \
' 36m' '1;36m' ' 37m' '1;37m';
do FG=${FGs// /}
echo -en " $FGs \033[$FG $T "
for BG in 40m 41m 42m 43m 44m 45m 46m 47m;
do echo -en "$EINS \033[$FG\033[$BG $T \033[0m";
done
echo;
done
echo기타 설정
Dimming 제거
Preferences > Appearance > Dimming
"Dim inactive split panes"를 해제함.
멀티 윈도우와 멀티 pane으로 놓고, 모두 한 번씩 볼 때가 있어서, 결국 투명한 흰색으로 덮는 dimming 기능은 꺼놓는 게 나음.
macOS 팁
글꼴 렌더링을 두껍게 만들기
레티나가 아닌 외부 모니터에서 글자를 더 잘 보이게 함. 재시작 필요!
https://qldhqldh.tistory.com/m/entry/맥-외부-모니터-가독성-증가
설정
defaults -currentHost write -g AppleFontSmoothing -int 2해제
defaults -currentHost delete -g AppleFontSmoothing(macOS 10.15 Catalina~) Root 디렉터리에 디렉터리 추가하기
https://apple.stackexchange.com/a/372500
Mission Control(control-up)에서 Spaces 재정렬 방지하기
시스템 환경설정 > 데스크탑 및 Dock > Mission Control
"Spaces를 최근 사용 내역에 따라 자동으로 재정렬" 체크 상자를 해제한다.
macOS 외부 마우스 쓰기
트랙패드와 애플 매직 마우스 대신 외부 마우스를 쓰려는 노력이다.
LinearMouse 설치
macOS의 마우스 설정은 매우 불편하고 끔찍하다. 마우스 smoothing과 scroll wheel smoothing을 없애려면 외부 프로그램 설치가 유일한 희망이다. (온라인에 있는 defaults 설정들은 죄다 가속도와 관계없는 그냥 속도 변경에 불과한 듯...)
brew install --cask linearmousehttps://github.com/lujjjh/LinearMouse
(macOS) BetterTouchTool 마우스 설정 (유료)
따로 나와 있는 BetterTouchTool 항목을 참고할 것.
Logitech 마우스라면, 마우스 설정에 대해서는 굳이 BetterTouchTool이 없어도 됨.
마우스 연결 시 트랙패드 끄기
환경설정 > 손쉬운 사용 > 포인터 제어기
"마우스 또는 무선 트랙패드가 있으면 내장 트랙패드 무시하기" 옵션을 활성화한다.
macOS 단축키 변경
macOS 설정 > 키보드 > 단축키
"사용 안 함"은 체크 상자를 해제하는 것이다.
| Hierarchy | Action | Default | My binding |
|---|---|---|---|
| Mission Control | Mission Control | control-up |
command-backtick |
| Mission Control | 알림 센터 보기 | 없음 | shift-command-backtick |
| 키보드 | 다음 윈도우로 초점 이동 | command-backtick |
사용 안 함 (command-backtick) |
| 서비스 | 텍스트 > 터미널에서 man 페이지 열기 | shift-command-m |
사용 안 함 (shift-command-m) |
| 서비스 | 텍스트 > 터미널에서 man 페이지 인덱스 검색 | shift-command-a |
사용 안 함 (shift-command-a) |
macOS 버그 해결
macOS Sequoia (15)부터 MS-DOS 볼륨 자동 마운트 방지 설정이 고장남
MSI 게이밍 모니터들은 MS-DOS 유형 볼륨(volume)에 대한 자동 마운트(auto-mount)가 일어나는데, 여태까지는 /etc/fstab 파일을 수정하여, 이 현상을 방지할 수 있었음.
macOS Sequoia (15)에서 이 설정이 고장나는 끔찍한 버그가 생겼고, 해결 방법이 한참 동안 미궁속에 빠져 있었으나, 아래와 같은 야매 버그 해결법을 찾아냄. (애플은 이 버그를 언제 고치나?)
https://discussions.apple.com/thread/255831146?answerId=255831146021&sortBy=rank#255831146021
Prior to my Sequoia upgrade, my working solution was the following fstab entry created using vifs:
UUID={uuid from diskutil} none msdos rw,noauto
My solution was to change the filetype to from 'msdos' to 'auto'. This auto-detects the drive type.
UUID={uuid from diskutil} none auto rw,noauto
macOS 상용 프로그램 문제 해결
Logi Options+ 완전 삭제
Logi Options+는 툭하면 무한 로딩에 걸리는 희대의 코드 뭉치 프로그램이다. 심지어 공식적으로는 문제 해결법이 전혀 없다. 유일한 해결 방법은 완전 삭제뿐인데, 이것도 제대로 알려주지 않는다.
sudo /Library/Application\ Support/Logitech.localized/LogiOptionsPlus/logioptionsplus_agent.app/Contents/Frameworks/logioptionsplus_updater.app/Contents/MacOS/logioptionsplus_updater --full --uninstall
Windows
Windhwak
필수 모드(mod)
m417z는 Windhwak 개발사인 Ramen Software의 일원이므로 신뢰할 수 있음.
m417z- Better file sizes in Explorer details -explorer-details-better-file-sizesm417z- Cycle taskbar buttons with mouse wheel -taskbar-wheel-style- 단축키
Win-[&Win-]을 사용할 수 있음. Logi Options+에서 각각을 앞으로 버튼, 뒤로 버튼에 할당해야 함. - Taskbar Volume Control (
taskbar-volume-control)과 기능이 겹치므로, "Enable mouse wheel cycling" 설정은 해제하는 게 좋음. (어차피 우선권을 뺏기긴 함.)
- 단축키
m417z- Taskbar Volume Control -taskbar-volume-control
Node.JS
NVM 및 Node.JS 설치
VS Code의 확장 기능에서 Node.JS에 의존하는 경우가 많다. 그래서 NVM과 Node.JS를 먼저 설치한다.
macOS
https://yarisong.tistory.com/44
brew install nvm
mkdir -p ~/.nvm~/.zshrc를 수정한다.
export NVM_DIR=~/.nvm
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"터미널을 다시 열고, 사용 가능한 Node.JS 버전을 확인한다.
# Check Node.JS versions
nvm ls-remote적당한 LTS 버전을 설치하고, 해당 버전을 기본으로 설정한다. (나온 지 얼마 안 된 LTS 버전은 호환성 문제가 생길 수 있다.)
# Install Node.JS
nvm install v24
# Set default version of Node.JS
# (Not required after first Node.JS installation)
nvm alias default v24
# List installed Node.JS versions
nvm ls
# Check current Node.JS runtime version
node -v전역 모듈 설치
VS Code 확장을 위한 모듈들
npm install -g prettier eslint typescriptESLint의 플러그인 모듈들
npm install -g eslint-plugin-react eslint-plugin-prettier eslint-plugin-react-hooksRust & Cargo
Rust 설치
macOS
brew install rust셸 환경 설정
.zshrc 또는 .bash_profile에 추가돼 있어야 함.
# Cargo
export PATH="$HOME/.cargo/bin:$PATH"유용한 CLI 프로그램
어느 OS에서든 설치하기 쉬운 CLI 프로그램들임.
일반
bat
cat과 비슷한 용도. Rust로 개발됨.
https://github.com/sharkdp/bat
dust
du와 비슷한 용도. Rust로 개발됨.
https://github.com/bootandy/dust
fzf
fzf is a general-purpose command-line fuzzy finder. Go로 개발됨.
https://github.com/junegunn/fzf
Shell integration 있음. Intruction대로 진행해야 함.
# .zshrc
source <(fzf --zsh)
# .bash_profile
eval "$(fzf --bash)"Zellij
친절한 인터페이스가 아주 훌륭한 terminal multiplexer 프로그램임. Rust로 개발됨.
설치 방법:
- Cargo: https://zellij.dev/documentation/installation.html
- RHEL(DNF) & macOS(Homebrew): https://github.com/zellij-org/zellij/blob/main/docs/THIRD_PARTY_INSTALL.md
나만의 설정:
- Locked mode
- 도움말: https://zellij.dev/documentation/options.html#default_mode-locked
- 구성 파일에서
// default_mode "locked"주석 해제하기. (//제거.) - 구성 파일 위치:
.config/zellij/config.kdl
- Activating the secondary modifier in locked mode!
- 도움말: https://zellij.dev/documentation/changing-modifiers.html
- 설정돼 있는 것처럼 보여도, 한 번 더 선택해줘야, locked mode에서도 alt 계열 단축키들이 활성화됨. (매우 중요)
Git 강화
이 항목에서 GitHub을 위한 CLI 프로그램은 다루지 않음. ghq와 gwq는 필수임.
ghq
Git 저장소 디렉터리를 정돈된 디렉터리로 복제해줌.
https://github.com/x-motemen/ghq
디렉터리는 ~/ghq/<domain>/<owner>/<repo>/임.
gwq
Git worktree manager 중 하나.
Shell completion 설정이 필요하므로 주의.
설정이 복잡하므로, 별도의 항목에서 추가로 정리함.
협업 솔루션
주로 AI 에이전트를 부려먹기 위해 필요한 CLI 프로그램들임.
gh
GitHub 또는 GHES를 위한 공식 CLI 프로그램.
설치 방법:
- macOS:
brew install gh - Linux: https://github.com/cli/cli/blob/trunk/docs/install_linux.md
- Windows: https://github.com/cli/cli/blob/trunk/docs/install_windows.md
pchuri Confluence CLI
Confluence wiki를 위한 비공식 CLI 프로그램.
https://github.com/pchuri/confluence-cli
Altanssian 솔루션 체크리스트:
- Cloud 배포판 지원 여부: Y
- Server / Data Center 배포판 지원 여부: Y (PAT w. bearer auth)
설치 방법:
npm install -g confluence-cliClaude Code 플러그인 추가 (Claude Code 명령)
/plugin marketplace add pchuri/confluence-cli
/plugin install confluence@pchuri-confluence-clipchuri Jira CLI
Jira를 위한 비공식 CLI 프로그램.
https://github.com/pchuri/jira-cli
Altanssian 솔루션 체크리스트:
- Cloud 배포판 지원 여부: Y
- Server / Data Center 배포판 지원 여부: Y (PAT w. bearer auth)
설치 방법:
npm install -g @pchuri/jira-cliClaude Code 스킬 추가 (명령행):
jira install-skill --force --dest ~/.claude/skills/jiragwq 전역 설정
전역 설정 파일은 ~/.config/gwq/config.toml임.
기본 전역 설정
기본 디렉터리는 ~/worktrees/<domain>/<owner>/<repo>/<branch>/임. 브랜치 이름에서 특정 특수문자들(/, :)은 대시(-)로 대체됨.
내 디렉터리는 ~/ghq/<domain>/<owner>/<repo>[worktree]/[<repo>]<branch>/임.
이를 위해, 전역 설정 파일 앞부분을 이렇게 바꿈. 에디터 창 이름을 직관적으로 만들기 위한 조치임.
[finder]
preview = true
[naming]
template = '{{.Host}}/{{.Owner}}/{{.Repository}}[worktree]/[{{.Repository}}]{{.Branch}}'
[naming.sanitize_chars]
'/' = '_'
':' = '-'
[ui]
icons = true
tilde_home = true
[worktree]
auto_mkdir = true
basedir = '~/ghq'[[repository_settings]] 항목들은 며느리에게도 알려줄 수 없는 비밀이므로 생략함. Repo마다 (.gwq.toml을 놓는 것도 고려해 봐야겠음.)
저장소 설정
Claude Code를 사용한다는 가정으로 아래와 같이 여러 개를 추가함.
<repo-dir>에 기본 저장소 디렉터리를 넣은 설정을 만들면 됨. (당연히 기본 저장소 디렉터리는 worktree 디렉터리가 아니라, 평범하게 git clone을 한 것임.)
[[repository_settings]]
repository = "<repo-dir>"
copy_files = [
".claude/settings.local.json",
"CLAUDE.local.md"
]
setup_commands = [
# ...
]저장소 간단한 셋업 명령어
Git 하위 모듈 초기화
Git 하위 모듈을 쓰는 프로젝트에는 필수다.
"git submodule update --init --recursive"저장소 복잡한 셋업 스크립트
Gradle 프로젝트 전용 build 디렉터리 복사 스크립트
Gradle 초기 빌드 속도를 조금이나마 올려보려는 노력임. ㅠㅠ
아래처럼 셸 스크립트를 만듦.
mkdir -p ~/my-scripts/worktree/
cat <<'EOF' > ~/my-scripts/worktree/gradle-project-setup.sh
#!/usr/bin/env bash
set -euo pipefail
src="${1:?Usage: gradle-project-setup.sh <original-dir>}"
dst="$(pwd)"
copied=0
start_time=$(date +%s)
copy_dir() {
local from="$1" to="$2" label="$3"
local size t_start t_end elapsed
if du --version 2>/dev/null | grep -q GNU; then
size=$(du -sh --exclude='build' "$from" 2>/dev/null | cut -f1)
else
size=$(du -sh -I build "$from" 2>/dev/null | cut -f1)
fi
t_start=$(date +%s)
rsync -a "$from/" "$to/"
t_end=$(date +%s)
elapsed=$((t_end - t_start))
printf "[copy] %s (%s, %ds)\n" "$label" "$size" "$elapsed"
copied=$((copied + 1))
}
if [ -d "$src/.vscode" ]; then
copy_dir "$src/.vscode" "$dst/.vscode" ".vscode"
fi
if [ -d "$src/.idea" ]; then
copy_dir "$src/.idea" "$dst/.idea" ".idea"
fi
total_elapsed=$(( $(date +%s) - start_time ))
printf "Done. %d directories copied in %ds.\n" "$copied" "$total_elapsed"
EOF
chmod +x ~/my-scripts/worktree/gradle-project-setup.shgwq 버전 0.0.13 기준으로 셋업 명령어 해석 로직에 명령어 토큰 분할 버그가 있음. (그냥 스페이스로 잘라버림;) 따라서 bash -c를 못 쓰므로, 절대 경로를 써야 함.
[[repository_settings]]
repository = "<repo-dir>"
setup_commands = [
"<absolute-home-dir>/my-scripts/worktree/gradle-project-setup.sh <absolute-repo-dir>'"
]IntelliJ IDEA Community
IntelliJ 설치 (OS 공통)
JetBrains Toolbox를 이용해 설치한다.
https://www.jetbrains.com/toolbox-app/
현재 기준으로 IntelliJ IDEA Community 2025.1을 설치한다. 당연히 New UI가 기본이다.
IntelliJ 주의할 점
인코딩
Editor > File Encodings
인코딩 (UTF-8) 설정은 프로젝트별로 모두 필요하다. 최신 버전에서는 전역 설정도 생겨서 좋아졌다.
Run/debug 구성 이사하기
각 프로젝트의 run/debug configuration은 아직까지도 쉽게 이사하는 방법이 없다 (.run 디렉터리 XML 파일을 유지하고 싶지 않다면...). 즉 import/export 기능이 전무하다. 하나하나 share 체크를 한 후, .run 디렉터리 XML 파일을 만들어서 노가다로 옮기고, 옮긴 뒤에 share 체크를 하나하나 다시 푼다.
https://stackoverflow.com/a/24642246
그 다음으로 좋은 방법은 Gradle이나 Maven에서 clean task를 한 번 수행한 다음, .gradle 디렉터리를 제외한 모든 파일을 압축해서 옮기는 것이다. 정신 건강에 아주 이롭다고 할 수 있겠다.(...)
IntelliJ preferences
편집기 글꼴
Editor > Font
- Font: D2Coding
- Size: 16.0
- Line spacing: 1.21
파일 끝에 줄바꿈 문자 넣기
Editor > General > On Save (section)
"Ensure envery saved file ends with a line break" 체크 상자를 설정한다.
줄바꿈 문자 화면에 표시하기
Editor > Genereal > Appearance
"Show whitespaces" 체크 상자를 설정한다. "Inner"를 제외하고, "Leading", "Trailing", "Selection" 체크 상자를 설정한다.
IntelliJ indent guide 보기
Editor > Genereal > Appearance
"Show indent guides" 체크 상자를 설정한다. (최신 버전에서는 기본인 듯하다.)
한 줄 메서드가 접히지 않게 하기
Editor > Genereal > Code Folding > Java (section)
"One-line methods" 체크 상자를 해제한다.
IntelliJ editor tab 위쪽 대신 오른쪽에 놓기
Editor > General > Editor Tabs > Apprearance (section)
"Tab placement" 선택 상자를 "Right"로 지정한다.
Editor > General > Editor Tabs > Closing Policy (section)
덤으로 탭 개수 제한도 풀면 좋다. "Tab limit"을 20으로 조정한다.
Breadcrumbs 사용하기
Editor > General > Breadcrumbs
"Show breadcrumbs" 체크 상자를 설정하고 (최신 버전에서는 기본인 듯하다.), "Placement"를 Top으로 한다.
"Languages"에서 "Java"와 "Kotlin" 체크 상자를 설정한다.
Smooth scrolling 끄기
Appearance & Behavior > Appearance > UI Options
"Smoothing scrolling" 체크 상자를 해제한다.
IntelliJ 단축키 설정
Keymap
VIM style (HJKL)이 어느 정도 가미되었다. 그리고 IntelliJ로 VCS를 조작하지 않고, 터미널에서 Git을 조작하기 때문에, 관련 단축키는 무시했다.
macOS
IntelliJ preference에서 "Keymap"으로 가서 프로필을 "macOS"로 맞춘 다음, "Duplicate..."를 눌러 복제한다.
macOS 기본 단축키와 충돌하면 답이 없는 경우가 있으므로 꼭 확인해야 한다.
https://support.apple.com/ko-kr/HT201236
- (+): 기존 단축키에 추가한다.
- (R): 기존 단축키를 제거하고 추가한다.
- "Run", "Debug"는 자주 쓰는 VIM 단축키와 충돌하므로 바꾸었다.
- "Code Completion"의 "Basic"은 macOS 시스템 단축키와 충돌하므로 바꾸었다.
| Menu hierarchy | Action | Default | My binding |
|---|---|---|---|
| Editor Actions | Down | down |
(+) control-J |
| Editor Actions | Extend Selection | option-up |
(+) option-K |
| Editor Actions | Shrink Selection | option-down |
(+) option-J |
| Editor Actions | Scroll to Top | None | (+) command-up |
| Editor Actions | Scroll to Bottom | None | (+) command-down |
| Editor Actions | Up | up |
(+) control-K |
| Main menu > Edit > Find | Replace... | command-R |
(R) option-command-F |
| Main menu > Edit > Find | Find in Files... | shift-command-F |
(R) control-option-F |
| Main menu > Edit > Find | Replace in Files... | shift-command-R |
(R) control-option-command-F |
| Main menu > Edit > Find | Find Usages | option-F7 |
(+) command-U |
| Main menu > Code > Code Completion | Basic | control-space |
(R) control-option-space |
| Main menu > Code | Reformat Code | option-command-L |
(R) shift-command-F |
| Main menu > Code | Reformat File... | option-shift-command-L |
(R) control-shift-command-F |
| Main menu > Code | Move Line Up/Down | option-shift-up/down |
(+) option-shift-K/J |
| Main menu > Navigate | Back/Forward | option-command-left/right |
(+) control-option-H/L (Remove mouse clicks) |
| Main menu > Navigate > Goto by Reference Actions | Go to Super Method | command-U |
(R) control-command-U |
| Main menu > Navigate > Goto by Reference Actions | Go to Test | shift-command-T |
(R) control-T |
| Main menu > Navigate > Hierarchy Actions | Type Hierarchy | control-H |
(R) command-T command-T |
| Main menu > Navigate > Hierarchy Actions | Method Hierarchy | shift-command-H |
(R) command-T command-F |
| Main menu > Navigate > Hierarchy Actions | Call Hierarchy | control-option-H |
(R) command-T command-C |
| Main menu > Navigate > Navigate in File | Previous/Next Method | control-up/down |
(+) control-option-K/J |
| Main menu > Refactor | Refactor This... | control-T |
(R) control-command-R |
| Main menu > Refactor | Rename... | shift-F6 |
(+) shift-command-R |
| Main menu > Run | Run... | control-option-R |
(R) control-option-X |
| Main menu > Run | Debug... | control-option-D |
(R) control-option-G |
| Main menu > Run > Run/Debug | Run | control-R |
(R) control-X |
| Main menu > Run > Run/Debug | Debug | control-D |
(R) control-G |
| Main menu > Window > Editor Tabs | Reopen Closed Tab | None | (+) shift-command-T |
| Main menu > Window > Editor Tabs | Split Right | None | (+) command-\ |
| Main menu > Window > Editor Tabs | Select Previous/Next Tab | control-left/right |
(R) control-H/L |
| Main menu > Window > Editor Tabs | Goto Previous/Next Splitter | option-(/shift)+right |
(+) control-shift-H/L |
| Main menu > Window > Editor Tabs | Goto Move | option-(/shift)-right |
(+) control-shift-H/L |
| Other | Activate Previous/Next Window | (/shift)-command-backtick |
(R) control-option-command-H/L |
IntelliJ Plugins
- IdeaVim
- GitHub Copilot
- TabMover by Miklos Jakab
IntelliJ GitHub Copilot Plugin
IDE 기준 버전: IntelliJ IDEA 2025.1
IDE 자동 완성 충돌 방지
Tools > GitHub Copilot > Completions
"Show IDE completions side-by-side"의 체크 상자를 설정한다. 기본적으로는 해제돼 있다.
(2025년 7월 기준) 이 설정을 꼭 활성화해야 IntelliJ의 자동 완성 (패턴 및 기계 학습)이 Copilot의 자동 완성 (LLM AI)을 씹는 일을 막을 수 있다. 이 설정을 켜면 동시에 두 가지 자동 완성을 모두 볼 수 있으며 (아래에 있는 줄들이 가려지긴 함), Tab 키를 누르면 Copilot 자동 완성이 동작하고, Enter 키를 누르면 IntelliJ 자동 완성이 동작한다.
사실 VS Code로 개발할 때는 IDE 자동 완성이 그렇게 큰 도움이 되지 않다 보니 Copilot을 우선으로 해도 괜찮다. 하지만 JVM 언어는 대부분 강타입 언어이기 때문에, IntelliJ에서는 IDE 자동 완성이 Copilot보다 더 유용할 때가 많은 것 같다.
TabMover
Keymap을 조정해야 한다.
| Menu hierarchy | Action | Default | My binding |
|---|---|---|---|
| Plugins > TabMover | Move Tab to Previous/Next | option-shift-command-left/right |
(+) control-command-L/H |
IntelliJ Theme
설치
Plugin으로 "Night Owl Native" by Aradi Patrik을 설치해야 한다.
https://plugins.jetbrains.com/plugin/13448-night-owl-native
"Rainbow Brackets Lite"도 설치한다. VS Code와 다르게, bracket 종류에 상관없는 색깔 순환이 이뤄지지 않으므로, round brackets만 적용할 것이다.
https://plugins.jetbrains.com/plugin/20710-rainbow-brackets-lite
Color Scheme 조정
Java와 Kotlin 위주로 조정한다.
IntelliJ preference에서 "Editor > Color Scheme"으로 가서 "Scheme"을 "one-dark-native"로 맞춘 다음, "Duplicate..."를 눌러 복제한다.
터미널 글꼴 설정
Editor > Color Scheme > Console Font
- Font: D2Coding
- Size: 15.0
- Line spacing: 1.10
상세
macOS의 VS Code는 IntelliJ보다 실제 색깔이 덜 붉게 나오기 때문에, IntelliJ에서는 인스턴스 필드 이름 색깔을 7FDBCA 대신 88D3C3으로 쓴다. 그래야 비슷해진다. (95DBCA 쓰다가 88D3C3으로 바꿈.)
나중에 배경 색깔이 더 필요해지면, 3F001F (어두운 초록색)을 사용할 예정.
| Menu hierarchy | Section hierarchy | Changes |
|---|---|---|
| General | Code > TODO defaults | fg: FFEB95 -ErrorStripeMark -Italic |
| General | Errors and Warnings > Error | -fg -bg +Effects: B71C1C underwaved |
| General | Errors and Warnings > Warning | -fg -bg +Effects: EF7F17 underwaved |
| General | Errors and Warnings > Weak Warning | -fg -bg +Effects: 3F9F4F underwaved |
| General | Text > Folded text | fg: F3F349 bg: 0A415B |
| General | Text > Whitespaces | fg: 174F7F |
| Language Defaults | Braces and Operators > Brackets | fg: C792EA |
| Language Defaults | Braces and Operators > Brackets | fg: C792EA |
| Language Defaults | Braces and Operators > Comma | -fg |
| Language Defaults | Braces and Operators > Dot | fg: C792EA |
| Language Defaults | Braces and Operators > Parentheses | fg: 89DDF7 |
| Language Defaults | Braces and Operators > Semicolon | fg: 89DDF7 |
| Language Defaults | Classes > Class name | fg: ADDB67 |
| Language Defaults | Classes > Instance field | fg: 88D3C3 -Inherit |
| Language Defaults | Classes > Interface name | fg: 35C37F |
| Language Defaults | Classes > Static field | fg: 88D3C3 +Italic |
| Language Defaults | Classes > Static method | fg: 82AAFF +Italic |
| Language Defaults | Identifiers > Default | fg: D6DEEB -bg -Inherit |
| Language Defaults | Identifiers > Function declaration | fg: 82AAFF -Italic |
| Language Defaults | Identifiers > Label | fg: 2F4FFF -Inherit |
| Language Defaults | Identifiers > Local variable | +Inherit |
| Language Defaults | Identifiers > Parameter | +Inherit |
| Language Defaults | Inline hints > Default | fg: 707084 bg: 3B3B3B |
| Language Defaults | Inline hints > Parameters > Current | fg: D6DEEB bg: 7E57C2 |
| Language Defaults | Inline hints > Parameters > Default | fg: 1A7C7F bg: 3B3B3B |
| Language Defaults | Inline hints > Parameters > Highlighted | fg: 20999D bg: 646464 |
| Language Defaults | Inline hints > Text without background | fg: 707084 |
| Language Defaults | Keyword | fg: C792EA -Italic |
| Language Defaults | Markup > Attribute | fg: 82AAFF -Inherit |
| Language Defaults | Metadata | fg: AB51BA -Inherit |
| Language Defaults | String > Escape Sequence > Invalid | fg: B71C1C Effects: B71C1C underwaved |
| Language Defaults | String > Escape Sequence > Valid | fg: F36D75 |
| Console Colors | ANSI Colors > Black | fg: 484848 bg:same |
| Console Colors | ANSI Colors > Blue | fg: 2072AC bg:same |
| Console Colors | ANSI Colors > Bright Black | fg: 6B6B6B bg:same |
| Console Colors | ANSI Colors > Bright Blue | fg: 3D99DB bg:same |
| Console Colors | ANSI Colors > Bright Cyan | fg: 27B9BE bg:same |
| Console Colors | ANSI Colors > Bright Green | fg: 4EFF79 bg:same |
| Console Colors | ANSI Colors > Bright Magenta | fg: C792EA bg:same |
| Console Colors | ANSI Colors > Bright Red | fg: EF5350 bg:same |
| Console Colors | ANSI Colors > Bright White | fg: FFFFFF bg:same |
| Console Colors | ANSI Colors > Bright Yellow | fg: FDCC1C bg:same |
| Console Colors | ANSI Colors > Cyan | fg: 1E9094 bg:same |
| Console Colors | ANSI Colors > Green | fg: 00CC33 bg:same |
| Console Colors | ANSI Colors > Magenta | fg: AB51BA bg:same |
| Console Colors | ANSI Colors > Red | fg: C03A38 bg:same |
| Console Colors | ANSI Colors > White (Gray) | fg: C7C7C7 bg:same |
| Console Colors | ANSI Colors > Yellow | fg: CA9F02 bg:same |
| Console Colors | Console > Standard output | fg: C7C7C7 |
| Console Colors | Console > System output | fg: C7C7C7 |
| Java | Annotations > Annotation attribute name | fg: 20999D |
| Java | Annotations > Annotation name | +Inherit |
| Java | Classes and Interfaces > Abstract Class | +Inherit |
| Java | Classes and Interfaces > Class | +Inherit |
| Java | Classes and Interfaces > Interface | +Inherit |
| Java | Methods > Constructor call | fg: ADDB67 -Inherit |
| Java | Methods > Method Call | +Inherit |
| Java | Methods > Static Method | +Inherit |
| Java | Parameters > Implicit anonymous class parameter | -fg bg: 2F2F0F -Effects |
| Java | Parameters > Type parameter | fg: 20999D |
| JSON | Property key | fg: C5E478 -Inherit |
| JSON | String | +Inherit |
| Groovy | Classes and Interfaces > Class | +Inherit |
| Groovy | Methods > Static method call | +Inherit |
| Groovy | Map key/Named argument | fg: 20999D -Inherit |
| Groovy | Methods > Method declaration | +Inherit |
| Groovy | References > Static property reference | +Inherit |
| Kotlin | Braces and Operators > Arrow | -fg -Inherit |
| Kotlin | Braces and Operators > Non-null assertion | fg: FF5370 |
| Kotlin | Braces and Operators > Operator sign | +Inherit |
| Kotlin | Classes and Interfaces > Enum entry | fg: F78C6C -Italic -Inherit |
| Kotlin | Classes and Interfaces > Object | fg: ADDB67 +Italic -Inherit |
| Kotlin | Functions > Constructor call | fg: ADDB67 -Inherit |
| Kotlin | Functions > Package-level function call | +Inherit |
| Kotlin | Label | +Inherit |
| Kotlin | Named argument | fg: 20999D |
| Kotlin | Parameters > Lambda expression default parameter | fg: FFFFFF +Bold |
| Kotlin | Parameters > Type parameter | +Inherit |
| Kotlin | Properties and Variables > Backing field variable | fg: C792EA -Bold |
| Kotlin | Properties and Variables > Dynamic property | fg: ADDB67 -Bold -Italic |
| Kotlin | Properties and Variables > Extension property | fg: 53BDEC +Italic -Inherit |
| Kotlin | Properties and Variables > Synthetic extension ... | fg: 53BDEC -Italic -Inherit |
| Kotlin | Properties and Variables > ... captured in closure | -fg bg: 2F2F0F -Inherit |
| Kotlin | Smart-casts > Smart-cast implicit receiver | -fg bg: 3F001F |
| Kotlin | Smart-casts > Smart-cast value | -fg bg: 3F001F |
| Kotlin | Smart-casts > Smart constant | -fg bg: 3F001F |
| Properties | Invalid unicode code points | +Inherit |
| Properties | Key/value separator | fg: C792EA |
| Properties | Property key | fg: C5E478 |
| Properties | Valid string escape | +Inherit |
| XML | Attribute name | +Inherit |
| XML | Tag | fg: C792EA -bg -Inherit |
| XML | Tag Data | +Inherit |
| XML | Tag Name | fg: C5E478 |
| XML | Prologue | fg: C792EA -bg -Inherit |
| YAML | Key | fg: C5E478 -Inherit |
| YAML | Text | fg: ECC48D -bg -Inherit |
| Rainbow Brackets Lite | Round Brackets - Color #1 | 89DDF7 |
| Rainbow Brackets Lite | Round Brackets - Color #2 | B3A03F |
| Rainbow Brackets Lite | Round Brackets - Color #3 | 08916A |
| Rainbow Brackets Lite | Round Brackets - Color #4 | DF878F |
| Rainbow Brackets Lite | Round Brackets - Color #5 | 2F9FC3 |
Visual Studio Code (VS Code)
VS Code 설치
macOS
brew install --cask visual-studio-codeVS Code extensions
Common
NodeJS 관련 확장의 경우, NPM을 통해 필요한 모듈들을 전역에 먼저 설치한다.
- EditorConfig for VS Code (
editorconfig.editorconfig) - GitLens — Git supercharged (
eamodio.gitlens) - Multiple Formatters (
Jota0222.multi-formatter) - Vim (
vscodevim.vim)
Language
프로그래밍 언어 또는 마크업 언어를 정적으로 분석하는 확장임. ESLint 말고는 Microsoft 공식 확장을 제외함.
- Markdown
- Markdown All in One (
yzhang.markdown-all-in-one) - Markdown Extended (
jebbs.markdown-extended) - Markdown Preview GitHub Styling (
bierner.markdown-preview-github-styles) - Markdown table from CSV/TSV (
jojoco.markdownfromcsv)
- Markdown All in One (
- JavaScript/TypeScript/JSON
- ESLint (
dbaeumer.vscode-eslint) - Prettier - Code formatter (
esbenp.prettier-vscode)
- ESLint (
- Miscellaneous non-markup
- Kotlin (
fwcd.kotlin) - SQL Formatter (
adpyke.vscode-sql-formatter)
- Kotlin (
- Miscellaneous markup
- XML (
redhat.vscode-xml) - TOML
- Even Better TOML (
tamasfe.even-better-toml)
- Even Better TOML (
- XML (
다음 확장은 예외적으로 기록했다.
- Python
- Black Formatter (
ms-python.black-formatter)- Python formatting에 필요하나, VS Code가 추천해주지 않음...
- Black Formatter (
JS/TS framework
- Frontend big framework
- Svelte for VS Code (
svelte.svelte-vscode)
- Svelte for VS Code (
- Styling
- UnoCSS (
antfu.unocss)
- UnoCSS (
- Components
- shadcn/svelte (
Selemondev.vscode-shadcn-svelte)
- shadcn/svelte (
JSON
- JSON Tools (
eriklynd.json-tools) - Sort JSON objects (
richie5um2.vscode-sort-json)
Theme
- Night Owl (
sdras.night-owl)
Utils
편의성 기능들임.
- Bookmarks (
alefragnani.Bookmarks) - Escape HTML code (
raymondcamden.htmlescape-vscode-extension) - Escape-quotes (
milovidov.escape-quotes) - Go to Next/Previous Member (
mishkinf.goto-next-previous-member) - Quit Control for VSCode (
artdiniz.quitcontrol-vscode) - URL Encode (
flesler.url-encode)
VS Code settings.json
macOS 기준이므로, VIM 키 바인딩 충돌 설정은 뺐음.
{
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Claude Code ║
// ╚══════════════════════════════════════════════════════════════════════════╝
"claudeCode.hideOnboarding": true,
"claudeCode.preferredLocation": "sidebar",
"claudeCode.selectedModel": "default",
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Common settings ║
// ╚══════════════════════════════════════════════════════════════════════════╝
"breadcrumbs.enabled": true,
"chat.agent.enabled": false,
"chat.disableAIFeatures": true,
"chat.viewSessions.orientation": "stacked",
"diffEditor.ignoreTrimWhitespace": false,
"editor.bracketPairColorization.enabled": true,
"editor.fontFamily": "D2Coding, Menlo, Monaco, 'Courier New', monospace",
"editor.fontSize": 16,
"editor.quickSuggestions": {
"other": "on",
"comments": "off",
"strings": "on"
},
"editor.suggestSelection": "first",
"editor.renderFinalNewline": "on",
"editor.renderWhitespace": "boundary",
"editor.rulers": [100],
"extensions.ignoreRecommendations": false,
"git.mergeEditor": false,
"git.openRepositoryInParentFolders": "never",
"html.format.unformatted": "li, p, wbr",
"scm.repositories.selectionMode": "single",
"terminal.integrated.defaultProfile.osx": "zsh-login",
"terminal.integrated.fontSize": 14,
"terminal.integrated.inheritEnv": true,
"terminal.integrated.lineHeight": 1.072,
"terminal.integrated.minimumContrastRatio": 1.2,
"terminal.integrated.profiles.osx": {
"zsh-login": {
"path": "zsh",
// Use login shell
// https://github.com/Microsoft/vscode/issues/20265#issuecomment-278818467
"args": ["-l"]
}
},
"terminal.integrated.stickyScroll.enabled": false,
"window.title": "VC${separator}${rootName}",
"workbench.colorTheme": "Night Owl (No Italics)",
"workbench.editor.decorations.colors": true,
"workbench.editor.showTabs": "multiple",
"workbench.editor.wrapTabs": true,
"workbench.editorAssociations": {
"*.ipynb": "jupyter-notebook"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Extension (non-language) settings ║
// ╚══════════════════════════════════════════════════════════════════════════╝
"docker.extension.dockerEngineAvailabilityPrompt": false,
"gitlens.codeLens.enabled": false,
"gitlens.plusFeatures.enabled": false,
"gitlens.terminal.overrideGitEditor": false,
"gitlens.views.branches.branches.layout": "list",
"gitlens.views.searchAndCompare.files.icon": "status",
"gitlens.views.scm.grouped.views": {
"commits": true,
"branches": true,
"remotes": true,
"stashes": true,
"tags": true,
"worktrees": true,
"contributors": true,
"fileHistory": false,
"repositories": true,
"searchAndCompare": true,
"launchpad": false
},
"redhat.telemetry.enabled": false,
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Extension (language) settings ║
// ╚══════════════════════════════════════════════════════════════════════════╝
"black-formatter.args": ["--line-length", "99", "--skip-string-normalization"],
"python.analysis.typeCheckingMode": "standard",
"eslint.format.enable": true,
"eslint.trace.server": "messages",
// By default, ESLint VS Code Plugin validates JS only.
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"html",
"svelte",
"vue"
],
"kotlin.debugAdapter.enabled": false,
"kotlin.diagnostics.enabled": false,
"kotlin.indexing.enabled": false,
"kotlin.languageServer.enabled": false,
"markdown.editor.filePaste.copyIntoWorkspace": "never",
"markdown.extension.toc.updateOnSave": false,
"markdown-pdf.displayHeaderFooter": false,
// Markdown PDF uses `https://unpkg.com/mermaid/dist/mermaid.min.js`, which is broken now.
// https://github.com/yzane/vscode-markdown-pdf/issues/312
"markdown-pdf.mermaidServer": "https://unpkg.com/mermaid@11.9.0/dist/mermaid.min.js",
"markdown-preview-github-styles.darkTheme": "dark_dimmed",
"prettier.printWidth": 100,
"prettier.singleQuote": true,
"prettier.trailingComma": "all",
"svelte.enable-ts-plugin": true,
"typescript.updateImportsOnFileMove.enabled": "never",
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ File extension settings ║
// ╚══════════════════════════════════════════════════════════════════════════╝
"[Compose]": {
"editor.defaultFormatter": "docker.docker"
},
"[css]": {
"editor.defaultFormatter": "vscode.css-language-features",
"editor.formatOnSave": true,
"files.insertFinalNewline": true
},
"[dockercompose]": {
"editor.defaultFormatter": "docker.docker"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"multiFormatter.formatterList": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"multiFormatter.formatterList": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"multiFormatter.formatterList": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.quickSuggestions": {
"comments": "off",
"strings": "off",
"other": "off"
},
"editor.wordWrap": "on",
"editor.defaultFormatter": "yzhang.markdown-all-in-one"
},
"[python]": {
"editor.formatOnType": true,
"editor.defaultFormatter": "ms-python.black-formatter"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode",
"multiFormatter.formatterList": [
// Svelte VS Code Plugin formatter includes Prettier by default.
"svelte.svelte-vscode",
// Donno why, but this is not working now. Have no option other than running "Format Document
// With..." > "ESLint".
"dbaeumer.vscode-eslint"
]
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"multiFormatter.formatterList": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"vscode.typescript-language-features"
]
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"multiFormatter.formatterList": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"vscode.typescript-language-features"
]
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Theme customization ║
// ╚══════════════════════════════════════════════════════════════════════════╝
// Original: https://github.com/sdras/night-owl-vscode-theme/blob/main/themes/Night%20Owl-color-theme-noitalic.json
"workbench.colorCustomizations": {
"editorBracketHighlight.foreground1": "#89DDF7",
"editorBracketHighlight.foreground2": "#B3A03F",
"editorBracketHighlight.foreground3": "#08916A",
"editorBracketHighlight.foreground4": "#DF878F",
"editorBracketHighlight.foreground5": "#2F9FC3",
// // [Dark background start]
// "editorHoverWidget.background": "#161616",
// "editor.background": "#161616",
// "editorGutter.background": "#161616",
// "panel.background": "#161616",
// "statusBar.background": "#161616",
// "terminal.background": "#161616",
// // [Dark background end]
// // [GitHub dimmed background start]
// "editorHoverWidget.background": "#22272e",
// "editor.background": "#22272e",
// "editorGutter.background": "#22272e",
// "panel.background": "#22272e",
// "statusBar.background": "#22272e",
// "terminal.background": "#22272e",
// // [GitHub dimmed background end]
"terminal.foreground": "#C7C7C7",
"terminal.ansiBlack": "#484848",
"terminal.ansiBrightBlack": "#6B6B6B",
"terminal.ansiBlue": "#2072AC",
"terminal.ansiBrightBlue": "#3D99DB",
"terminal.ansiCyan": "#1E9094",
"terminal.ansiBrightCyan": "#27B9BE",
"terminal.ansiGreen": "#00CC33",
"terminal.ansiBrightGreen": "#4EFF79",
"terminal.ansiMagenta": "#AB51BA",
"terminal.ansiBrightMagenta": "#C792EA",
"terminal.ansiRed": "#C03A38",
"terminal.ansiBrightRed": "#EF5350",
"terminal.ansiWhite": "#C7C7C7",
"terminal.ansiBrightWhite": "#FFFFFF",
"terminal.ansiYellow": "#CA9F02",
"terminal.ansiBrightYellow": "#FDCC1C"
},
"editor.tokenColorCustomizations": {
"[Night Owl (No Italics)]": {
"variables": "#D6DEEB",
"textMateRules": [
{
"name": "Keyword Operator",
"scope": "keyword.operator",
"settings": {
"foreground": "#C792EA"
}
},
{
"name": "Keyword",
"scope": [
"constant.language",
"constant.language.boolean",
"constant.language.null",
"variable.language.this",
"keyword.operator.new",
"meta.method.declaration storage.type"
],
"settings": {
"foreground": "#C792EA"
}
},
{
"name": "Single or double quote character",
"scope": ["punctuation.definition.string"],
"settings": {
"foreground": "#ecc48d"
}
},
{
"name": "Constant Character Escape",
"scope": ["constant.character.escape"],
"settings": {
"foreground": "#F36D75"
}
},
{
"name": "Function declaration parameter",
"scope": ["variable.parameter.function"],
"settings": {
// I'm not sure whether this is the correct way or not. Anyway, this is working.
"foreground": "#D6DEEB"
}
},
{
"name": "Function Argument",
"scope": ["meta.function-call"],
"settings": {
"foreground": "#D6DEEB"
}
},
{
"name": "Object Property",
"scope": ["variable.other.object.property"],
"settings": {
"foreground": "#7FDBCA"
}
},
{
"name": "Support Function",
"scope": ["support.function"],
"settings": {
"foreground": "#82AAFF",
"fontStyle": "italic"
}
},
{
"name": "Entity Type",
"scope": [
"entity.name.type",
"entity.name.type.js",
"entity.name.type.jsx",
"entity.name.type.ts",
"entity.name.type.tsx",
"entity.name.type.module",
"entity.name.type.module.js",
"entity.name.type.module.jsx",
"entity.name.type.module.ts",
"entity.name.type.module.tsx",
"support.class",
"support.type",
"storage.type.generic.java",
"meta.definition.variable.java storage.type.java",
"meta.method.identifier.java storage.type.java"
],
"settings": {
"foreground": "#ADDB67"
}
},
{
"name": "Entity Class (Including JS/TS Interface)",
"scope": [
"meta.class entity.name.type.class",
"meta.class entity.name.type.class.js",
"meta.class entity.name.type.class.jsx",
"meta.class entity.name.type.class.ts",
"meta.class entity.name.type.class.tsx",
"entity.other.inherited-class",
"meta.interface entity.name.type.interface.js",
"meta.interface entity.name.type.interface.jsx",
"meta.interface entity.name.type.interface.ts",
"meta.interface entity.name.type.interface.tsx"
],
"settings": {
"foreground": "#ADDB67"
}
},
{
"name": "Entity Interface",
"scope": ["meta.interface entity.name.type.interface"],
"settings": {
"foreground": "#35C37F"
}
},
{
"name": "Entity Enum",
"scope": ["entity.name.type.enum"],
"settings": {
"foreground": "#ADDB67"
}
},
{
"name": "String Template",
"scope": [
"meta.template.expression.js",
"meta.template.expression.jsx",
"meta.template.expression.ts",
"meta.template.expression.tsx"
],
"settings": {
"foreground": "#F36D75"
}
},
{
"name": "HTML/XML Entity Tag Name",
"scope": ["entity.name.tag"],
"settings": {
"foreground": "#C5E478"
}
},
{
"name": "HTML/XML Entity Attribute Name",
"scope": ["entity.other.attribute-name"],
"settings": {
"foreground": "#82AAFF"
}
},
{
"name": "JavaScript/TypeScript Object Key",
"scope": ["meta.object.member"],
"settings": {
"foreground": "#7FDBCA"
}
},
{
"name": "React Tag Non-Component Name",
"scope": ["entity.name.tag.jsx", "entity.name.tag.tsx"],
"settings": {
"foreground": "#35C37F"
}
},
{
"name": "React Tag Component Name",
"scope": ["support.class.component.jsx", "support.class.component.tsx"],
"settings": {
"foreground": "#C9E290"
}
},
{
"name": "React Tag Attribute Name",
"scope": ["entity.other.attribute-name.jsx", "entity.other.attribute-name.tsx"],
"settings": {
"foreground": "#53BDEC"
}
},
{
"name": "Java/Kotlin Annotation",
"scope": [
"meta.declaration.annotation.java",
"meta.declaration.annotation.java storage.type.annotation.java",
"entity.name.type.annotation.kotlin",
"entity.name.type.annotation-site.kotlin"
],
"settings": {
"foreground": "#AB51BA"
}
},
{
"name": "Java Package/Import Statement Target",
"scope": [
"meta.package.java storage.modifier.package.java",
"meta.import.java storage.modifier.import.java"
],
"settings": {
"foreground": "#D6DEEB"
}
},
{
"name": "Java Primitive Type",
"scope": ["storage.type.primitive.java"],
"settings": {
"foreground": "#C792EA"
}
},
{
"name": "Python language constants",
"scope": ["constant.language.python"],
"settings": {
"foreground": "#C792EA"
}
},
{
"name": "Python member attribute",
"scope": ["source.python meta.member.access.python meta.attribute.python"],
"settings": {
"foreground": "#7FDBCA"
}
},
{
"name": "Python function call function name",
"scope": ["meta.function-call.generic.python"],
"settings": {
"foreground": "#82AAFF"
}
},
{
"name": "Python function call argument parameter value",
"scope": ["meta.function-call.arguments.python"],
"settings": {
// I'm not sure whether this is the correct way or not. Anyway, this is working.
"foreground": "#D6DEEB"
}
},
{
"name": "Python function call argument parameter name",
"scope": [
"source.python meta.function-call.python meta.function-call.arguments.python variable.parameter.function-call.python"
],
"settings": {
"foreground": "#20999D"
}
},
{
"name": "JSON Property Key",
"scope": ["support.type.property-name.json"],
"settings": {
"foreground": "#C5E478"
}
},
{
"name": "JSON Property Value",
"scope": ["meta.structure.dictionary.value.json string.quoted.double"],
"settings": {
"foreground": "#ECC48D"
}
},
{
"name": "JSON Property Special Value",
"scope": [
"meta.structure.dictionary.json meta.structure.dictionary.value constant.language"
],
"settings": {
"foreground": "#C792EA"
}
},
{
"name": "Properties Property Key",
"scope": ["keyword.other.definition.ini"],
"settings": {
"foreground": "#C5E478"
}
},
{
"name": "Properties Property Key-Value Separator",
"scope": ["punctuation.separator.key-value.ini"],
"settings": {
"foreground": "#89DDF7"
}
},
{
"name": "YAML Entity Name Tag",
"scope": ["entity.name.tag.yaml"],
"settings": {
"foreground": "#C5E478"
}
},
{
"name": "Markdown bold",
"scope": ["markup.bold"],
"settings": {
"foreground": "#ADDB67",
"fontStyle": "bold"
}
},
{
"name": "Markdown italic",
"scope": ["markup.italic"],
"settings": {
"foreground": "#53BDEC",
"fontStyle": "italic"
}
},
{
"name": "Markdown italic in heading",
"scope": ["markup.heading.markdown markup.italic"],
"settings": {
"foreground": "#89DDF7",
"fontStyle": "italic"
}
},
{
"name": "Markdown underline link",
"scope": ["markup.underline.link"],
"settings": {
"foreground": "#C792EA",
"fontStyle": "underline"
}
},
{
"name": "Makrdown character escape",
"scope": ["constant.character.escape.markdown"],
"settings": {
"foreground": "#DF878F"
}
},
{
"name": "Markdown code - fenced code block",
"scope": ["markup.fenced_code.block.markdown"],
"settings": {
"foreground": "#AFCFAF"
}
},
{
"name": "Markdown code - inline code",
"scope": ["markup.inline.raw.string.markdown"],
"settings": {
"foreground": "#8FBC8F"
}
}
]
}
}
}VS Code keybindings.json
macOS 기준!
[
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Claude Code Extension ║
// ╚══════════════════════════════════════════════════════════════════════════╝
// Use shift-enter for newline in `claude` CLI
// (Generated w. `/terminal-setup` in `claude` CLI)
{
"key": "shift+enter",
"command": "workbench.action.terminal.sendSequence",
"args": { "text": "\u001b\r" },
"when": "terminalFocus"
},
// Prevent intercepting alt-k by Claude Code extension
{
"key": "alt+k",
"command": "-claude-vscode.insertAtMention",
"when": "editorTextFocus"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Sidebars ║
// ╚══════════════════════════════════════════════════════════════════════════╝
// Explorer sidebar
{
"key": "ctrl+alt+e",
"command": "workbench.view.explorer"
},
// Search sidebar
{
"key": "ctrl+alt+f",
"command": "workbench.action.findInFiles"
},
{
"key": "shift+cmd+f",
"command": "-workbench.action.findInFiles"
},
// Source Control sidebar
{
"key": "ctrl+alt+s",
"command": "workbench.view.scm"
},
// Toggle sidebar
{
"key": "shift+cmd+0",
"command": "workbench.action.toggleSidebarVisibility"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Build and run ║
// ╚══════════════════════════════════════════════════════════════════════════╝
// Build task
{
"key": "ctrl+b",
"command": "workbench.action.tasks.build"
},
{
"key": "cmd+b",
"command": "-workbench.action.toggleSidebarVisibility"
},
// Run task
{
"key": "ctrl+x",
"command": "workbench.action.tasks.test"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Editor tabs and groups ║
// ╚══════════════════════════════════════════════════════════════════════════╝
// Move focus between editor tabs (VIM arrow)
{
"key": "ctrl+h",
"command": "workbench.action.previousEditor",
"when": "!terminalFocus"
},
{
"key": "ctrl+l",
"command": "workbench.action.nextEditor",
"when": "!terminalFocus"
},
// Move focus between editor groups (VIM arrow)
{
"key": "ctrl+shift+h",
"command": "workbench.action.focusLeftGroup",
"when": "!terminalFocus"
},
{
"key": "ctrl+shift+l",
"command": "workbench.action.focusRightGroup",
"when": "!terminalFocus"
},
// Move editor tabs (VIM arrow)
{
"key": "ctrl+cmd+h",
"command": "workbench.action.moveEditorLeftInGroup"
},
{
"key": "ctrl+cmd+l",
"command": "workbench.action.moveEditorRightInGroup"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Navigation ║
// ╚══════════════════════════════════════════════════════════════════════════╝
// Go back/forward
{
"key": "ctrl+alt+h",
"command": "workbench.action.navigateBack",
"when": "editorFocus"
},
{
"key": "ctrl+alt+l",
"command": "workbench.action.navigateForward",
"when": "editorFocus"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Editor text ║
// ╚══════════════════════════════════════════════════════════════════════════╝
// Auto indention
{
"key": "shift+cmd+f",
"command": "editor.action.formatDocument",
"when": "editorTextFocus && !editorReadonly"
},
{
"key": "shift+cmd+f",
"command": "-workbench.view.search",
"when": "!searchViewletVisible"
},
// Expand/shrink selection
{
"key": "alt+k",
"command": "editor.action.smartSelect.expand",
"when": "editorTextFocus"
},
{
"key": "alt+k",
"command": "-editor.action.accessibilityHelpConfigureKeybindings",
"when": "accessibilityHelpIsShown && accessibleViewHasUnassignedKeybindings"
},
{
"key": "alt+j",
"command": "editor.action.smartSelect.shrink",
"when": "editorTextFocus"
},
// Move line up/down (VIM arrow)
{
"key": "shift+alt+k",
"command": "editor.action.moveLinesUpAction",
"when": "editorTextFocus && !editorReadonly"
},
{
"key": "shift+alt+j",
"command": "editor.action.moveLinesDownAction",
"when": "editorTextFocus && !editorReadonly"
},
// Editor suggestion (select prev/next)
{
"key": "ctrl+j",
"command": "selectNextSuggestion",
"when": "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"
},
{
"key": "ctrl+j",
"command": "-editor.action.joinLines",
"when": "editorTextFocus && !editorReadonly"
},
{
"key": "ctrl+k",
"command": "selectPrevSuggestion",
"when": "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"
},
{
"key": "ctrl+k",
"command": "-deleteAllRight",
"when": "textInputFocus && !editorReadonly"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Code ║
// ╚══════════════════════════════════════════════════════════════════════════╝
// Rename
{
"key": "shift+cmd+r",
"command": "editor.action.rename",
"when": "editorHasRenameProvider && editorTextFocus && !editorReadonly"
},
// Go to next/previous problem (JenBrains style)
{
"key": "f2",
"command": "editor.action.marker.nextInFiles",
"when": "editorFocus"
},
{
"key": "f2",
"command": "-editor.action.rename",
"when": "editorHasRenameProvider && editorTextFocus && !editorReadonly"
},
{
"key": "shift+f2",
"command": "editor.action.marker.prevInFiles",
"when": "editorFocus"
},
// Go to references(usages)
{
"key": "cmd+u",
"command": "editor.action.goToReferences",
"when": "editorHasReferenceProvider && editorTextFocus && !inReferenceSearchEditor && !isInEmbeddedEditor"
},
{
"key": "cmd+u",
"command": "-cursorUndo",
"when": "textInputFocus"
},
// Quick fix (JetBrains style)
{
"key": "alt+enter",
"command": "editor.action.quickFix",
"when": "editorHasCodeActionsProvider && editorTextFocus && !editorReadonly"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Terminal ║
// ╚══════════════════════════════════════════════════════════════════════════╝
// Create integrated terminal
{
"key": "alt+shift+`",
"command": "workbench.action.terminal.new"
},
// Kill integrated terminal
{
"key": "ctrl+shift+`",
"command": "workbench.action.terminal.kill"
},
// Move between integrated terminal tabs (VIM arrow)
{
"key": "ctrl+h",
"command": "workbench.action.terminal.focusPrevious",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
{
"key": "ctrl+l",
"command": "workbench.action.terminal.focusNext",
"when": "terminalFocus && terminalHasBeenCreated && !terminalEditorFocus || terminalFocus && terminalProcessSupported && !terminalEditorFocus"
},
// Move focus between integrated terminal groups (VIM arrow)
{
"key": "ctrl+shift+h",
"command": "workbench.action.terminal.focusPreviousPane",
"when": "terminalFocus && terminalHasBeenCreated && terminalSplitPaneActive || terminalFocus && terminalProcessSupported && terminalSplitPaneActive"
},
{
"key": "ctrl+shift+l",
"command": "workbench.action.terminal.focusNextPane",
"when": "terminalFocus && terminalHasBeenCreated && terminalSplitPaneActive || terminalFocus && terminalProcessSupported && terminalSplitPaneActive"
},
// Integrated terminal creation for Python VEnv
{
"key": "cmd+ctrl+shift+`",
"command": "python.createTerminal"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Extension - Go to Next/Previous Member (VIM arrow) ║
// ╚══════════════════════════════════════════════════════════════════════════╝
{
"key": "ctrl+alt+j",
"command": "gotoNextPreviousMember.nextMember",
"when": "editorTextFocus"
},
{
"key": "ctrl+alt+k",
"command": "gotoNextPreviousMember.previousMember",
"when": "editorTextFocus"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Others ║
// ╚══════════════════════════════════════════════════════════════════════════╝
// Show definition
{
"key": "cmd+b",
"command": "editor.action.revealDefinition",
"when": "editorHasDefinitionProvider && editorTextFocus && !isInEmbeddedEditor"
},
// Show hover
{
"key": "f1",
"command": "editor.action.showHover",
"when": "editorTextFocus"
},
// Developers: Inspect Editor Tokens and Scopes
{
"key": "ctrl+shift+cmd+i",
"command": "editor.action.inspectTMScopes"
},
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Remove conflicting keybindings ║
// ╚══════════════════════════════════════════════════════════════════════════╝
{
"key": "shift+cmd+g",
"command": "-editor.action.announceCursorPosition"
}
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ Automatically added? ║
// ╚══════════════════════════════════════════════════════════════════════════╝
]DBeaver Community
DBeaver 설치
JDK가 필요하다.
macOS
brew install --cask dbeaver-communityDBeaver Preferences
Dark theme 설정
User Interface > Apperance
"Enable theming" 체크 상자를 설정하고, "Theme"을 "Dark Theme"로 둔다.
글꼴 설정
User Interface > Apperance > Colors and Fonts
"DBeaver Fonts > Monospace Font"를 "D2Coding, 15"로 설정한다.
SQL format 설정
Editors > SQL Editor > Formatting
"Settings" 영역에 있는 설정들을 바꾼다.
- "Insert spaces for tabs" 체크 상자를 설정한다.
- "Keyword case"를 "Upper"로 지정한다. (원래는 "Default")
Text editor 추가 설정
Editors > Text Editors
- "Show line numbers" 체크 상자를 설정한다.
- "Show whitespace characters" 체크 상자를 설정한다. "Configure visibility"를 눌러서 뜨는 dialog는 다음처럼 설정한다.
- Space: Leading, Trailing
- Tab: Leading, Enclosed, Trailing
- Line Feed: (None)
- Transparency level: 80 -> 63
Heap status 설정
General
"Show heap status" 체크 상자를 설정한다.
DBeaver 단축키 설정
User Interface > Keys
| Action | Category | Default | My binding |
|---|---|---|---|
| Execute SQL Query | SQL Editor | control-enter |
command-enter |
| Content Format | SQL Editor | control-shift-F |
shift-command-F |
DBeaver Plugins
Eclipse plugin을 설치한다.
Help > Install New Software...
- Vrapper (Vim)
Postman
Postman 설치
Node.JS 런타임이 필요하다 (Interceptor 때문).
macOS
brew install --cask postmanmacOS Interceptor 설치
macOS는 Chrome 라이브러리 디렉터리 권한 때문에 설치가 잘 안 된다 (~/Library/Application Support/Google/Chrome/NativeMessagingHosts).
FILE_PERMISSIONS_REQUIRED 오류로 인해 막힐 경우, 아래 웹페이지에서 직접 다운로드받아서 수작업으로 넣어본다.
https://learning.postman.com/docs/sending-requests/capturing-request-data/interceptor/#installing-interceptor
Chrome에서는 확장을 따로 설치해주면 된다.
'개발 > 개발 잡다' 카테고리의 다른 글
| 개발 환경 설정 (2023 ~ 2024) (2) | 2023.03.29 |
|---|---|
| 개발 환경 설정 (2020~2022) (2) | 2020.01.05 |
| 개발 설정 (2018~2019) (0) | 2018.01.25 |