/etc/zshrc
を調べた時のメモ。
TL;DR
/etc/zshrc
は末尾でterminal別拡張zshrcを呼ぶ- macはデフォルトで
/etc/zshrc_Apple_Terminal
を用意しているので、それが呼び出される
/etc/zshrc
の拡張スクリプト呼び出し
/etc/zshrc
は末尾でターミナル別の拡張スクリプト /etc/zshrc_$TERM_PROGRAM
を呼び出すようになっており、ターミナルごとに独自の拡張をいれることが可能になっています。
環境変数 $TERM_PROGRAM
にはターミナル固有の値が含まれ、例えばMacのターミナルであれば $TERM_PROGRAM
の値が Apple_Terminal
となっています。
$ cat zshrc | tail -n 10 [[ -n ${key[Home]} ]] && bindkey "${key[Home]}" beginning-of-line [[ -n ${key[End]} ]] && bindkey "${key[End]}" end-of-line [[ -n ${key[Up]} ]] && bindkey "${key[Up]}" up-line-or-search [[ -n ${key[Down]} ]] && bindkey "${key[Down]}" down-line-or-search # Default prompt PS1="%n@%m %1~ %# " # Useful support for interacting with Terminal.app or other terminal programs [ -r "/etc/zshrc_$TERM_PROGRAM" ] && . "/etc/zshrc_$TERM_PROGRAM" # ここで拡張スクリプトが実行される
Macターミナルでの拡張スクリプト
Macターミナルでは /etc/zshrc_Apple_Terminal
が用意されており、これが /etc/zshrc
末尾で呼び出されます。
# Zsh support for Terminal. # Working Directory # # Tell the terminal about the current working directory at each prompt. # # Terminal uses this to display the directory in the window title bar # and tab bar, and for behaviors including creating a new terminal with # the same working directory and restoring the working directory when # restoring a terminal for Resume. See Terminal > Preferences for # additional information. if [ -z "$INSIDE_EMACS" ]; then update_terminal_cwd() { # Identify the directory using a "file:" scheme URL, including # the host name to disambiguate local vs. remote paths. # Percent-encode the pathname. local url_path='' { # Use LC_CTYPE=C to process text byte-by-byte and # LC_COLLATE=C to compare byte-for-byte. Ensure that # LC_ALL and LANG are not set so they don't interfere. local i ch hexch LC_CTYPE=C LC_COLLATE=C LC_ALL= LANG= for ((i = 1; i <= ${#PWD}; ++i)); do ch="$PWD[i]" if [[ "$ch" =~ [/._~A-Za-z0-9-] ]]; then url_path+="$ch" else printf -v hexch "%02X" "'$ch" url_path+="%$hexch" fi done } printf '\e]7;%s\a' "file://$HOST$url_path" } # Register the function so it is called at each prompt. autoload -Uz add-zsh-hook add-zsh-hook precmd update_terminal_cwd fi # Resume Support: Save/Restore Shell State # # Terminal assigns each terminal session a unique identifier and # communicates it via the TERM_SESSION_ID environment variable so that # programs running in a terminal can save/restore application-specific # state when quitting and restarting Terminal with Resume enabled. # # The following code defines a shell save/restore mechanism. Users can # add custom state by defining a `shell_session_save_user_state` function # or an array of functions `shell_session_save_user_state_functions` that # write restoration commands to the session state file at exit. The first # argument of the function is the pathname of the session state file in # which to store state. e.g., to save a variable: # # shell_session_save_user_state() { echo MY_VAR="'$MY_VAR'" >> "$1"; } # # or: # # save_my_var() { echo MY_VAR="'$MY_VAR'" >> "$1"; } # shell_session_save_user_state_functions+=(save_my_var) # # During shell startup the session file is executed and then deleted. # You may save/restore arbitrarily complex/large state by writing it # to some other file(s) and writing command(s) to the state file that # restore that data. You should typically use the TERM_SESSION_ID # as part of your file or directory names. # # The default behavior arranges to save and restore the shell command # history independently for each restored terminal session. It also # merges commands into the global history for new sessions. Because of # this it is recommended that you set HISTSIZE and SAVEHIST to larger # values. # # You may disable this behavior and share a single history by setting # SHELL_SESSION_HISTORY to 0. The shell options INC_APPEND_HISTORY, # INC_APPEND_HISTORY_TIME and SHARE_HISTORY are used to share new # commands among running shells; therefore, if any of these is enabled, # per-session history is disabled by default. You may explicitly enable # it by setting SHELL_SESSION_HISTORY to 1. # # Note that this uses the precmd hook to enable per-session history the # first time for each new session; if that doesn't run, the per-session # history won't take effect until the first restore. # # The save/restore mechanism as a whole can be disabled by setting an # environment variable (typically in `${ZDOTDIR:-$HOME}/.zshenv`): # # SHELL_SESSIONS_DISABLE=1 if [ ${SHELL_SESSION_DID_INIT:-0} -eq 0 ] && [ -n "$TERM_SESSION_ID" ] && [ ${SHELL_SESSIONS_DISABLE:-0} -eq 0 ]; then # Do not perform this setup more than once. SHELL_SESSION_DID_INIT=1 # Set up the session directory/file. SHELL_SESSION_DIR="${ZDOTDIR:-$HOME}/.zsh_sessions" SHELL_SESSION_FILE="$SHELL_SESSION_DIR/$TERM_SESSION_ID.session" mkdir -m 700 -p "$SHELL_SESSION_DIR" # # Restore previous session state. # if [ -r "$SHELL_SESSION_FILE" ]; then . "$SHELL_SESSION_FILE" /bin/rm "$SHELL_SESSION_FILE" fi # # Note: Use absolute paths to invoke commands in the exit code and # anything else that runs after user startup files, because the # search path may have been modified. # # # Arrange for per-session shell command history. # shell_session_history_allowed() { # Return whether per-session history should be enabled. if [ -n "$HISTFILE" ]; then # If this defaults to off, leave it unset so that we can # check again later. If it defaults to on, make it stick. local allowed=0 if [[ -o INC_APPEND_HISTORY ]] || [[ -o INC_APPEND_HISTORY_TIME ]] || [[ -o SHARE_HISTORY ]]; then allowed=${SHELL_SESSION_HISTORY:-0} else allowed=${SHELL_SESSION_HISTORY:=1} fi if [ $allowed -eq 1 ]; then return 0 fi fi return 1 } if [ ${SHELL_SESSION_HISTORY:-1} -eq 1 ]; then SHELL_SESSION_HISTFILE="$SHELL_SESSION_DIR/$TERM_SESSION_ID.history" SHELL_SESSION_HISTFILE_NEW="$SHELL_SESSION_DIR/$TERM_SESSION_ID.historynew" SHELL_SESSION_HISTFILE_SHARED="$HISTFILE" shell_session_history_enable() { (umask 077; /usr/bin/touch "$SHELL_SESSION_HISTFILE_NEW") HISTFILE="$SHELL_SESSION_HISTFILE_NEW" SHELL_SESSION_HISTORY=1 } # If the session history already exists and isn't empty, start # using it now; otherwise, we'll use the shared history until # we've determined whether users have enabled/disabled this. if [ -s "$SHELL_SESSION_HISTFILE" ]; then fc -R "$SHELL_SESSION_HISTFILE" shell_session_history_enable else # At the first prompt, check whether per-session history should # be enabled. Delaying until after user scripts have run allows # users to opt in or out. If this doesn't get executed (probably # because a user script inadvertently removed the hook), we'll # check at shell exit; that works, but doesn't start the per- # session history until the first restore. shell_session_history_check() { if [ ${SHELL_SESSION_DID_HISTORY_CHECK:-0} -eq 0 ]; then SHELL_SESSION_DID_HISTORY_CHECK=1 shell_session_history_allowed && shell_session_history_enable # Uninstall this check. autoload -Uz add-zsh-hook add-zsh-hook -d precmd shell_session_history_check fi } autoload -Uz add-zsh-hook add-zsh-hook precmd shell_session_history_check fi shell_session_save_history() { shell_session_history_enable # Save new history to an intermediate file so we can copy it. fc -AI # If the session history doesn't exist yet, copy the shared history. if [ -f "$SHELL_SESSION_HISTFILE_SHARED" ] && [ ! -s "$SHELL_SESSION_HISTFILE" ]; then echo -ne '\n...copying shared history...' >&2 (umask 077; /bin/cp "$SHELL_SESSION_HISTFILE_SHARED" "$SHELL_SESSION_HISTFILE") fi # Save new history to the per-session and shared files. echo -ne '\n...saving history...' >&2 (umask 077; /bin/cat "$SHELL_SESSION_HISTFILE_NEW" >> "$SHELL_SESSION_HISTFILE_SHARED") (umask 077; /bin/cat "$SHELL_SESSION_HISTFILE_NEW" >> "$SHELL_SESSION_HISTFILE") /bin/rm "$SHELL_SESSION_HISTFILE_NEW" # If there is a history file size limit, apply it to the files. if [ -n "$SAVEHIST" ]; then echo -n 'truncating history files...' >&2 fc -p "$SHELL_SESSION_HISTFILE_SHARED" && fc -P fc -p "$SHELL_SESSION_HISTFILE" && fc -P fi echo -ne '\n...' >&2 } fi # # Arrange to save session state when exiting the shell. # shell_session_save() { # Save the current state. if [ -n "$SHELL_SESSION_FILE" ]; then echo -ne '\nSaving session...' >&2 (umask 077; echo 'echo Restored session: "$(/bin/date -r '$(/bin/date +%s)')"' >| "$SHELL_SESSION_FILE") # Call user-supplied hook functions to let them save state. whence shell_session_save_user_state >/dev/null && shell_session_save_user_state "$SHELL_SESSION_FILE" local f for f in $shell_session_save_user_state_functions; do $f "$SHELL_SESSION_FILE" done shell_session_history_allowed && shell_session_save_history echo 'completed.' >&2 fi } # Delete old session files. (Not more than once a day.) SHELL_SESSION_TIMESTAMP_FILE="$SHELL_SESSION_DIR/_expiration_check_timestamp" shell_session_delete_expired() { if [ ! -e "$SHELL_SESSION_TIMESTAMP_FILE" ] || [ -z "$(/usr/bin/find "$SHELL_SESSION_TIMESTAMP_FILE" -mtime -1d)" ]; then local expiration_lock_file="$SHELL_SESSION_DIR/_expiration_lockfile" if /usr/bin/shlock -f "$expiration_lock_file" -p $$; then echo -n 'Deleting expired sessions...' >&2 local delete_count=$(/usr/bin/find "$SHELL_SESSION_DIR" -type f -mtime +2w -print -delete | /usr/bin/wc -l) [ "$delete_count" -gt 0 ] && echo $delete_count' completed.' >&2 || echo 'none found.' >&2 (umask 077; /usr/bin/touch "$SHELL_SESSION_TIMESTAMP_FILE") /bin/rm "$expiration_lock_file" fi fi } # Update saved session state when exiting. shell_session_update() { shell_session_save && shell_session_delete_expired } autoload -Uz add-zsh-hook add-zsh-hook zshexit shell_session_update fi