Last active 2 weeks ago

Cross-platform Zsh setup scripts and managed dotfiles with Oh My Zsh framework, Starship prompt, aliases, functions, and path configuration.

Revision 16d18d087a501cc6f70363a224754a4b4dc7823f

README.md Raw

Bash Script Installer for Zsh

The "Bash Script Installer" simplifies the setup of Zsh.

Zsh

Ubuntu

bash -c "$(curl -fsSL https://opengist.rmrf.online/weehong/f0d940c3c1214bf5b7996195199fdc09/raw/HEAD/zsh_ubuntu.sh)"

WSL

bash -c "$(curl -fsSL https://opengist.rmrf.online/weehong/f0d940c3c1214bf5b7996195199fdc09/raw/HEAD/zsh_wsl.sh)"

MacOS

bash -c "$(curl -fsSL https://opengist.rmrf.online/weehong/f0d940c3c1214bf5b7996195199fdc09/raw/HEAD/zsh_macos.sh)"

Configuration

bash -c "$(curl -fsSL https://opengist.rmrf.online/weehong/f0d940c3c1214bf5b7996195199fdc09/raw/HEAD/config.sh)"

Shell framework and prompt

The installers use Oh My Zsh for framework features and plugins, with the OMZ theme disabled:

ZSH_THEME=""
source "$ZSH/oh-my-zsh.sh"
eval "$(starship init zsh)"

Starship owns the prompt and loads after Oh My Zsh. The managed Starship config is installed at ~/.config/starship.toml. A Nerd Font is required for the Powerline symbols.

alias Raw
1# =============================================================================
2# OS-SPECIFIC ALIASES
3# =============================================================================
4if [[ "$OSTYPE" == "linux-gnu"* ]] && command -v apt-get >/dev/null 2>&1; then
5 # Linux Only System update & cleanup
6 alias uu='sudo apt-get update && \
7 sudo apt-get upgrade -y && \
8 sudo apt-get full-upgrade -y && \
9 sudo apt-get autoremove -y && \
10 sudo apt-get autoclean -y && \
11 sudo apt-get clean'
12elif [[ "$OSTYPE" == "darwin"* ]]; then
13 # macOS Only
14 alias flushdns='sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder'
15fi
16
17# =============================================================================
18# UNIVERSAL GIT ALIASES (Fixed: Removed broken "$@" from aliases)
19# =============================================================================
20alias gph='git push'
21alias gco='git checkout'
22alias gbh='git branch'
23alias gmt='git commit'
24alias gpl='git pull'
25alias grb='git rebase'
26alias grt='git reset'
27alias gst='git status'
28alias grmrf='git checkout -- . && git clean -fd'
config.sh Raw
1#!/bin/bash
2set -euo pipefail
3
4# Configuration
5GIST_RAW_BASE="https://opengist.rmrf.online/weehong/f0d940c3c1214bf5b7996195199fdc09/raw/HEAD"
6CONFIG_FILES=(
7 ".alias"
8 ".func"
9 ".pathrc"
10 ".sourcerc"
11 ".vimrc"
12 ".zshrc"
13 ".config/starship.toml"
14)
15
16echo "Starting configuration download..."
17
18for f in "${CONFIG_FILES[@]}"; do
19 # Remove the leading dot for the URL path
20 remote_name="${f#.}"
21 [[ "$f" == ".config/starship.toml" ]] && remote_name="starship.toml"
22 url="$GIST_RAW_BASE/$remote_name"
23 target="$HOME/$f"
24
25 echo "Downloading $f..."
26 mkdir -p "$(dirname "$target")"
27
28 # Use -f to fail silently on server errors, -s for silent, -L to follow redirects
29 if curl -fsSL "$url" -o "$target"; then
30 echo "Successfully updated $target"
31 else
32 echo "Error: Failed to download $f from $url" >&2
33 fi
34done
35
36echo "Done! All configuration files have been replaced."
37
func Raw
1# =============================================================================
2# CUSTOM FUNCTIONS
3# =============================================================================
4
5# -----------------------------------------------------------------------------
6# Function: clip (Cross-platform clipboard)
7# -----------------------------------------------------------------------------
8clip() {
9 local cmd
10 local args=()
11
12 if command -v pbcopy >/dev/null 2>&1; then
13 cmd="pbcopy" # macOS
14 elif grep -qi "microsoft" /proc/version 2>/dev/null && command -v clip.exe >/dev/null 2>&1; then
15 cmd="clip.exe" # WSL
16 elif [ "$XDG_SESSION_TYPE" = "wayland" ] && command -v wl-copy >/dev/null 2>&1; then
17 cmd="wl-copy" # Linux Wayland
18 elif command -v xclip >/dev/null 2>&1; then
19 cmd="xclip" # Linux X11 (Fallback 1)
20 args=("-selection" "clipboard")
21 elif command -v xsel >/dev/null 2>&1; then
22 cmd="xsel" # Linux X11 (Fallback 2)
23 args=("--clipboard" "--input")
24 else
25 printf "Error: No supported clipboard utility found.\n" >&2
26 return 1
27 fi
28
29 if [ $# -gt 0 ]; then
30 if [ -f "$1" ]; then
31 "$cmd" "${args[@]}" < "$1"
32 echo "Copied contents of '$1' to clipboard."
33 else
34 printf "Error: File '%s' not found.\n" "$1" >&2
35 return 1
36 fi
37 else
38 "$cmd" "${args[@]}"
39 fi
40}
41
42# -----------------------------------------------------------------------------
43# Function: open_file (Cross-platform file/directory opener)
44# -----------------------------------------------------------------------------
45open_file() {
46 local target="${1:-.}"
47
48 if [[ "$OSTYPE" == "darwin"* ]]; then
49 command open "$target"
50 elif grep -qi "microsoft" /proc/version 2>/dev/null; then
51 if command -v wslpath >/dev/null 2>&1 && command -v explorer.exe >/dev/null 2>&1; then
52 explorer.exe "$(wslpath -w "$target")"
53 else
54 printf "Error: 'wslpath' or 'explorer.exe' not found.\n" >&2
55 return 1
56 fi
57 elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
58 if command -v xdg-open >/dev/null 2>&1; then
59 xdg-open "$target"
60 else
61 printf "Error: 'xdg-open' not found.\n" >&2
62 return 1
63 fi
64 fi
65}
66alias open='open_file'
67
68# -----------------------------------------------------------------------------
69# Function: clear_history (Supports shell and Claude)
70# -----------------------------------------------------------------------------
71# -----------------------------------------------------------------------------
72# Function: clear_history (Supports shell and Claude)
73# -----------------------------------------------------------------------------
74clear_history() {
75 case "$1" in
76 claude)
77 if [ -d "$HOME/.claude/projects" ]; then
78 # Use 'yes' to skip prompts and -f to ignore non-existent files
79 yes | rm -rf "$HOME/.claude/projects"/*
80 echo "Claude project history/cache cleared."
81 fi
82 ;;
83
84 *)
85 # 1. Truncate the file
86 : > "$HISTFILE"
87
88 # 2. Clear RAM by briefly setting history size to 0
89 local old_histsize=$HISTSIZE
90 HISTSIZE=0
91 HISTSIZE=$old_histsize
92
93 echo "Shell history cleared."
94 ;;
95 esac
96}
97
98# -----------------------------------------------------------------------------
99# Function: claude (Includes --yolo and clear shortcuts)
100# -----------------------------------------------------------------------------
101claude() {
102 # Shortcut for clearing cache
103 if [[ "$1" == "clear" ]]; then
104 clear_history claude
105 return 0
106 fi
107
108 # Check if binary exists
109 if ! whence -p claude >/dev/null 2>&1; then
110 printf "Error: 'claude' CLI is not installed or not in your PATH.\n" >&2
111 return 1
112 fi
113
114 # Handle --yolo mode
115 if [[ "$1" == "--yolo" ]]; then
116 shift
117 command claude --dangerously-skip-permissions "$@"
118 return $?
119 fi
120
121 command claude "$@"
122}
123
124# -----------------------------------------------------------------------------
125# Function: create (Efficiently create file + parent dirs)
126# -----------------------------------------------------------------------------
127create() {
128 if ! command -v install >/dev/null 2>&1; then
129 printf "Error: 'install' coreutil is not available.\n" >&2
130 return 1
131 fi
132
133 if [ $# -eq 0 ]; then
134 printf "Usage: create <file> [file ...]\n" >&2
135 return 2
136 fi
137
138 for p in "$@"; do
139 # Expand tilde manually if shell doesn't
140 [[ "$p" == "~/"* ]] && p="${HOME}/${p#\~/}"
141
142 if [ -z "$p" ] || [ "$p" = "/" ]; then
143 printf "create: refusing to operate on '%s'\n" "$p" >&2
144 continue
145 fi
146
147 if [ -e "$p" ]; then
148 printf "create: '%s' already exists. Skipping.\n" "$p" >&2
149 continue
150 fi
151
152 if install -D /dev/null "$p"; then
153 echo "Created '$p'"
154 fi
155 done
156}
157
158# -----------------------------------------------------------------------------
159# Function: check_port
160# -----------------------------------------------------------------------------
161check_port() {
162 local PORT=$1
163 if [ -z "$PORT" ]; then
164 printf "Usage: check_port <port_number>\n" >&2
165 return 1
166 fi
167
168 if [[ "$OSTYPE" == "darwin"* ]]; then
169 lsof -i :"$PORT" || echo "Port $PORT is FREE"
170 else
171 sudo ss -tulnp | grep ":$PORT " || echo "Port $PORT is FREE"
172 fi
173}
174
175# -----------------------------------------------------------------------------
176# Function: append_path (Adds to session PATH if exists)
177# -----------------------------------------------------------------------------
178append_path() {
179 local dir="$1"
180 if [ -d "$dir" ]; then
181 case ":$PATH:" in
182 *":$dir:"*) ;;
183 *) PATH="$PATH:$dir" ;;
184 esac
185 elif [ "${SUPPRESS_WARNINGS:-0}" -ne 1 ]; then
186 echo "Warning: $dir does not exist." >&2
187 fi
188}
189
190# -----------------------------------------------------------------------------
191# Function: add_path_to_config (Fixed awk/sed injection)
192# -----------------------------------------------------------------------------
193add_path_to_config() {
194 local new_path="$1"
195 local config_file="$HOME/.bashrc"
196 [[ "$SHELL" == *"zsh"* ]] && config_file="$HOME/.zshrc"
197
198 if [ -z "$new_path" ]; then
199 printf "Usage: add_path_to_config <directory>\n" >&2
200 return 1
201 fi
202
203 new_path="${new_path/#\~/$HOME}"
204
205 if [ ! -d "$new_path" ]; then
206 printf "Warning: '%s' does not exist. Add anyway? (y/N) " "$new_path"
207 read -r REPLY
208 [[ ! $REPLY =~ ^[Yy]$ ]] && return 1
209 fi
210
211 # Check if already exists in file
212 if grep -Fq "append_path \"$new_path\"" "$config_file"; then
213 printf "Notice: Already in %s.\n" "$config_file"
214 return 0
215 fi
216
217 # Robust Injection: Use sed to insert before export PATH or just append
218 if grep -q "^export PATH" "$config_file"; then
219 sed -i.bak "/^export PATH/i append_path \"$new_path\"" "$config_file"
220 else
221 echo "append_path \"$new_path\"" >> "$config_file"
222 echo "export PATH" >> "$config_file"
223 fi
224
225 printf "✅ Success: Added to %s\n" "$config_file"
226 append_path "$new_path" && export PATH
227}
pathrc Raw
1# =============================================================================
2# ENVIRONMENT & PATH CONFIGURATION
3# =============================================================================
4
5# 1. Source functions first
6if [[ -f "$HOME/.func" && -r "$HOME/.func" ]]; then
7 source "$HOME/.func"
8fi
9
10# 2. Define Root Variables
11export DOTNET_ROOT="$HOME/.dotnet"
12
13# 3. PATH INITIALIZATION
14# -----------------------------------------------------------------------------
15append_path "$HOME/.local/bin"
16append_path "$DOTNET_ROOT"
17append_path "$DOTNET_ROOT/tools"
18append_path "$HOME/.opencode/bin"
19append_path "$HOME/Flutter/bin"
20
21# macOS specific paths
22if [[ "$OSTYPE" == "darwin"* ]]; then
23 append_path "/Applications/Espanso.app/Contents/MacOS"
24fi
25
26# Finalize PATH
27export PATH
sourcerc Raw
1# =============================================================================
2# FILE: ~/.sourcerc
3# Description: Initializes third-party package managers and external tools.
4# =============================================================================
5
6# =============================================================================
7# GENERAL ENV
8# =============================================================================
9if [[ -f "$HOME/.local/bin/env" && -r "$HOME/.local/bin/env" ]]; then
10 source "$HOME/.local/bin/env"
11fi
12
13# =============================================================================
14# CLAUDE CODE / AI GATEWAY
15# =============================================================================
16export ANTHROPIC_BASE_URL="https://gateway.ai.cloudflare.com/v1/9a71825e3842e918e0dff9ad84f50484/claude-code-gateway/anthropic"
17
18# =============================================================================
19# SDKMAN (Java/Kotlin/Scala Version Manager)
20# =============================================================================
21export SDKMAN_DIR="$HOME/.sdkman"
22if [[ -f "$SDKMAN_DIR/bin/sdkman-init.sh" && -r "$SDKMAN_DIR/bin/sdkman-init.sh" ]]; then
23 source "$SDKMAN_DIR/bin/sdkman-init.sh"
24fi
25
26# =============================================================================
27# NVM (Node Version Manager)
28# =============================================================================
29export NVM_DIR="$HOME/.nvm"
30if [[ -f "$NVM_DIR/nvm.sh" && -r "$NVM_DIR/nvm.sh" ]]; then
31 source "$NVM_DIR/nvm.sh"
32fi
33if [[ -f "$NVM_DIR/bash_completion" && -r "$NVM_DIR/bash_completion" ]]; then
34 source "$NVM_DIR/bash_completion"
35fi
36
37# =============================================================================
38# GOOGLE CLOUD SDK
39# =============================================================================
40if [[ -f "$HOME/google-cloud-sdk/path.zsh.inc" ]]; then
41 source "$HOME/google-cloud-sdk/path.zsh.inc"
42fi
43
44if [[ -f "$HOME/google-cloud-sdk/completion.zsh.inc" ]]; then
45 source "$HOME/google-cloud-sdk/completion.zsh.inc"
46fi
starship.toml Raw
1"$schema" = 'https://starship.rs/config-schema.json'
2
3format = """
4[](red)\
5$os\
6$username\
7[](bg:peach fg:red)\
8$directory\
9[](bg:yellow fg:peach)\
10$git_branch\
11$git_status\
12[](fg:yellow bg:green)\
13$c\
14$rust\
15$golang\
16$nodejs\
17$bun\
18$php\
19$java\
20$kotlin\
21$haskell\
22$python\
23[](fg:green bg:sapphire)\
24$conda\
25[](fg:sapphire bg:lavender)\
26$time\
27[ ](fg:lavender)\
28$cmd_duration\
29$line_break\
30$character"""
31
32palette = 'catppuccin_mocha'
33
34[os]
35disabled = false
36style = "bg:red fg:crust"
37
38[os.symbols]
39Windows = ""
40Ubuntu = "󰕈"
41SUSE = ""
42Raspbian = "󰐿"
43Mint = "󰣭"
44Macos = "󰀵"
45Manjaro = ""
46Linux = "󰌽"
47Gentoo = "󰣨"
48Fedora = "󰣛"
49Alpine = ""
50Amazon = ""
51Android = ""
52AOSC = ""
53Arch = "󰣇"
54Artix = "󰣇"
55CentOS = ""
56Debian = "󰣚"
57Redhat = "󱄛"
58RedHatEnterprise = "󱄛"
59
60[username]
61show_always = true
62style_user = "bg:red fg:crust"
63style_root = "bg:red fg:crust"
64format = '[ $user]($style)'
65
66[directory]
67style = "bg:peach fg:crust"
68format = "[ $path ]($style)"
69truncation_length = 3
70truncation_symbol = "…/"
71
72[directory.substitutions]
73"Documents" = "󰈙 "
74"Downloads" = " "
75"Music" = "󰝚 "
76"Pictures" = " "
77"Developer" = "󰲋 "
78
79[git_branch]
80symbol = ""
81style = "bg:yellow"
82format = '[[ $symbol $branch ](fg:crust bg:yellow)]($style)'
83
84[git_status]
85style = "bg:yellow"
86format = '[[($all_status$ahead_behind )](fg:crust bg:yellow)]($style)'
87
88[nodejs]
89symbol = ""
90style = "bg:green"
91format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
92
93[bun]
94symbol = ""
95style = "bg:green"
96format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
97
98[c]
99symbol = " "
100style = "bg:green"
101format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
102
103[rust]
104symbol = ""
105style = "bg:green"
106format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
107
108[golang]
109symbol = ""
110style = "bg:green"
111format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
112
113[php]
114symbol = ""
115style = "bg:green"
116format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
117
118[java]
119symbol = " "
120style = "bg:green"
121format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
122
123[kotlin]
124symbol = ""
125style = "bg:green"
126format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
127
128[haskell]
129symbol = ""
130style = "bg:green"
131format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
132
133[python]
134symbol = ""
135style = "bg:green"
136format = '[[ $symbol( $version)(\(#$virtualenv\)) ](fg:crust bg:green)]($style)'
137
138[docker_context]
139symbol = ""
140style = "bg:sapphire"
141format = '[[ $symbol( $context) ](fg:crust bg:sapphire)]($style)'
142
143[conda]
144symbol = "  "
145style = "fg:crust bg:sapphire"
146format = '[$symbol$environment ]($style)'
147ignore_base = false
148
149[time]
150disabled = false
151time_format = "%R"
152style = "bg:lavender"
153format = '[[  $time ](fg:crust bg:lavender)]($style)'
154
155[line_break]
156disabled = false
157
158[character]
159disabled = false
160success_symbol = '[❯](bold fg:green)'
161error_symbol = '[❯](bold fg:red)'
162vimcmd_symbol = '[❮](bold fg:green)'
163vimcmd_replace_one_symbol = '[❮](bold fg:lavender)'
164vimcmd_replace_symbol = '[❮](bold fg:lavender)'
165vimcmd_visual_symbol = '[❮](bold fg:yellow)'
166
167[cmd_duration]
168show_milliseconds = true
169format = " in $duration "
170style = "bg:lavender"
171disabled = false
172show_notifications = true
173min_time_to_notify = 45000
174
175[palettes.catppuccin_mocha]
176rosewater = "#f5e0dc"
177flamingo = "#f2cdcd"
178pink = "#f5c2e7"
179mauve = "#cba6f7"
180red = "#f38ba8"
181maroon = "#eba0ac"
182peach = "#fab387"
183yellow = "#f9e2af"
184green = "#a6e3a1"
185teal = "#94e2d5"
186sky = "#89dceb"
187sapphire = "#74c7ec"
188blue = "#89b4fa"
189lavender = "#b4befe"
190text = "#cdd6f4"
191subtext1 = "#bac2de"
192subtext0 = "#a6adc8"
193overlay2 = "#9399b2"
194overlay1 = "#7f849c"
195overlay0 = "#6c7086"
196surface2 = "#585b70"
197surface1 = "#45475a"
198surface0 = "#313244"
199base = "#1e1e2e"
200mantle = "#181825"
201crust = "#11111b"
202
203[palettes.catppuccin_frappe]
204rosewater = "#f2d5cf"
205flamingo = "#eebebe"
206pink = "#f4b8e4"
207mauve = "#ca9ee6"
208red = "#e78284"
209maroon = "#ea999c"
210peach = "#ef9f76"
211yellow = "#e5c890"
212green = "#a6d189"
213teal = "#81c8be"
214sky = "#99d1db"
215sapphire = "#85c1dc"
216blue = "#8caaee"
217lavender = "#babbf1"
218text = "#c6d0f5"
219subtext1 = "#b5bfe2"
220subtext0 = "#a5adce"
221overlay2 = "#949cbb"
222overlay1 = "#838ba7"
223overlay0 = "#737994"
224surface2 = "#626880"
225surface1 = "#51576d"
226surface0 = "#414559"
227base = "#303446"
228mantle = "#292c3c"
229crust = "#232634"
230
231[palettes.catppuccin_latte]
232rosewater = "#dc8a78"
233flamingo = "#dd7878"
234pink = "#ea76cb"
235mauve = "#8839ef"
236red = "#d20f39"
237maroon = "#e64553"
238peach = "#fe640b"
239yellow = "#df8e1d"
240green = "#40a02b"
241teal = "#179299"
242sky = "#04a5e5"
243sapphire = "#209fb5"
244blue = "#1e66f5"
245lavender = "#7287fd"
246text = "#4c4f69"
247subtext1 = "#5c5f77"
248subtext0 = "#6c6f85"
249overlay2 = "#7c7f93"
250overlay1 = "#8c8fa1"
251overlay0 = "#9ca0b0"
252surface2 = "#acb0be"
253surface1 = "#bcc0cc"
254surface0 = "#ccd0da"
255base = "#eff1f5"
256mantle = "#e6e9ef"
257crust = "#dce0e8"
258
259[palettes.catppuccin_macchiato]
260rosewater = "#f4dbd6"
261flamingo = "#f0c6c6"
262pink = "#f5bde6"
263mauve = "#c6a0f6"
264red = "#ed8796"
265maroon = "#ee99a0"
266peach = "#f5a97f"
267yellow = "#eed49f"
268green = "#a6da95"
269teal = "#8bd5ca"
270sky = "#91d7e3"
271sapphire = "#7dc4e4"
272blue = "#8aadf4"
273lavender = "#b7bdf8"
274text = "#cad3f5"
275subtext1 = "#b8c0e0"
276subtext0 = "#a5adcb"
277overlay2 = "#939ab7"
278overlay1 = "#8087a2"
279overlay0 = "#6e738d"
280surface2 = "#5b6078"
281surface1 = "#494d64"
282surface0 = "#363a4f"
283base = "#24273a"
284mantle = "#1e2030"
285crust = "#181926"
286
vimrc Raw
1" Enable line numbers
2set number
3
4" Enable relative line numbers
5set relativenumber
6
7" Enable syntax highlighting
8syntax on
9
10" Set colorscheme
11colorscheme slate
12
13" Enable file type detection and plugins
14filetype plugin indent on
15
16" Set the tab width to 4 spaces
17set tabstop=4
18set shiftwidth=4
19set expandtab
20
21" Enable auto-indentation
22set autoindent
23set smartindent
24
25" Highlight current line
26set cursorline
27
28" Show matching parentheses
29set showmatch
30
31" Enable line wrapping
32set wrap
33
34" Enable mouse support
35set mouse=a
36
37" Enable clipboard access
38set clipboard=unnamedplus
39
40" Disable swap file
41set noswapfile
42
43" Enable incremental search
44set incsearch
45
46" Ignore case in search
47set ignorecase
48
49" Override ignorecase if search contains capital letters
50set smartcase
51
52" Display line and column number of the cursor position
53set ruler
54
55" Set the status line at the bottom
56set laststatus=2
57
58" Show command in bottom bar
59set showcmd
60
61" Set command height
62set cmdheight=2
63
64" Set history lines
65set history=1000
66
67" Disable backup file
68set nobackup
69
70" Enable persistent undo
71set undofile
72
73" Set maximum number of undo levels
74set undolevels=1000
75
76" Set undo directory
77if has("persistent_undo")
78 silent !mkdir ~/.vim/undodir > /dev/null 2>&1
79 set undodir=~/.vim/undodir
80endif
81
82" Set search highlighting
83set hlsearch
84
85" Enable visual bell
86set visualbell
87
88" Set default file encoding
89set encoding=utf-8
90
91" Set the leader key to space
92let mapleader = " "
93
94" Map <Leader>w to save the file
95nnoremap <Leader>w :w<CR>
96
97" Map <Leader>q to quit
98nnoremap <Leader>q :q<CR>
99
100" Map <Leader>x to save and quit
101nnoremap <Leader>x :wq<CR>
102
103" Enable folding
104set foldmethod=syntax
105set foldlevelstart=99
106
107" Enable line wrapping at 80 characters
108set textwidth=80
109set colorcolumn=80
110
111" Add some basic key mappings
112" Map jj to escape insert mode
113inoremap jj <Esc>
114
115" Map <Leader>n to toggle line numbers
116nnoremap <Leader>n :set number!<CR>
117
118" Map <Leader>r to toggle relative line numbers
119nnoremap <Leader>r :set relativenumber!<CR>
120
121" Configure plugins (if you use a plugin manager like vim-plug)
122" Example with vim-plug:
123" call plug#begin('~/.vim/plugged')
124" Plug 'tpope/vim-sensible'
125" Plug 'preservim/nerdtree'
126" Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
127" Plug 'airblade/vim-gitgutter'
128" call plug#end()
129
130" NERDTree key mappings
131" nnoremap <C-n> :NERDTreeToggle<CR>
132
133" Enable automatic hard wrapping at textwidth (80 chars)
134set formatoptions+=t " Auto-wrap text using textwidth
135set formatoptions+=c " Auto-wrap comments using textwidth
136set formatoptions+=r " Continue comments when pressing Enter
137set formatoptions+=o " Continue comments when using 'o' or 'O'
138set formatoptions+=q " Allow formatting of comments with 'gq'
139set formatoptions+=n " Recognize numbered lists
140set formatoptions+=l " Don't break lines that were already long
141
142" Enable syntax highlighting
143syntax on
144
145" Increase memory limit for complex syntax parsing (Prevents E363)
146set maxmempattern=20000
zsh_macos.sh Raw
1#!/bin/bash
2set -euo pipefail
3
4# =============================
5# COLORS & LOGGING
6# =============================
7RED='\033[0;31m'
8GREEN='\033[0;32m'
9YELLOW='\033[1;33m'
10BLUE='\033[0;34m'
11NC='\033[0m'
12
13log() { echo -e "${BLUE}[INFO]${NC} $*"; }
14ok() { echo -e "${GREEN}[OK]${NC} $*"; }
15warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
16err() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
17
18# =============================
19# CONFIG
20# =============================
21GIST_RAW_BASE="https://opengist.rmrf.online/weehong/f0d940c3c1214bf5b7996195199fdc09/raw/HEAD"
22
23CONFIG_FILES=(
24 ".alias"
25 ".func"
26 ".pathrc"
27 ".sourcerc"
28 ".vimrc"
29 ".zshrc"
30 ".config/starship.toml"
31)
32
33# =============================
34# REQUIREMENTS
35# =============================
36check_requirements() {
37 if [[ $EUID -eq 0 ]]; then
38 err "Do not run as root on macOS"
39 exit 1
40 fi
41}
42
43# =============================
44# INSTALLATION FUNCTIONS
45# =============================
46install_oh_my_zsh() {
47 log "Installing Oh My Zsh and plugins..."
48 export RUNZSH=no
49 export CHSH=no
50 export KEEP_ZSHRC=yes
51
52 if [[ ! -d "$HOME/.oh-my-zsh" ]]; then
53 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" --unattended
54 else
55 ok "Oh My Zsh already installed"
56 fi
57
58 local custom="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
59 local plugin_dir="$custom/plugins"
60 mkdir -p "$plugin_dir"
61
62 [[ -d "$plugin_dir/zsh-autosuggestions" ]] || \
63 git clone https://github.com/zsh-users/zsh-autosuggestions "$plugin_dir/zsh-autosuggestions"
64
65 [[ -d "$plugin_dir/zsh-syntax-highlighting" ]] || \
66 git clone https://github.com/zsh-users/zsh-syntax-highlighting "$plugin_dir/zsh-syntax-highlighting"
67
68 ok "Oh My Zsh plugins installed to $plugin_dir"
69}
70
71install_starship() {
72 if command -v starship >/dev/null 2>&1 || [[ -f "$HOME/.local/bin/starship" ]]; then
73 ok "Starship already installed"
74 elif command -v brew >/dev/null 2>&1; then
75 log "Installing Starship with Homebrew..."
76 brew install starship
77 ok "Starship installed"
78 else
79 log "Installing Starship..."
80 mkdir -p "$HOME/.local/bin"
81 curl -fsSL https://starship.rs/install.sh | sh -s -- -y -b "$HOME/.local/bin"
82 ok "Starship installed"
83 fi
84}
85
86download_configs() {
87 log "Downloading custom config files..."
88 local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)"
89 mkdir -p "$backup"
90
91 for f in "${CONFIG_FILES[@]}"; do
92 # Strip the leading dot for the download URL
93 local remote_file="${f#.}"
94 [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml"
95 local url="$GIST_RAW_BASE/$remote_file"
96 local target="$HOME/$f"
97 local tmp="${target}.tmp.$$"
98
99 mkdir -p "$(dirname "$target")"
100
101 if [[ -f "$target" ]]; then
102 cp "$target" "$backup/"
103 fi
104
105 log "Fetching $remote_file -> $f ..."
106 if curl -fsSL "$url" -o "$tmp"; then
107 mv "$tmp" "$target"
108 else
109 rm -f "$tmp"
110 warn "Failed to download $remote_file"
111 fi
112 done
113
114 ok "Configs downloaded (Backup at $backup)"
115}
116
117configure_zshrc() {
118 local zshrc="$HOME/.zshrc"
119 log "Configuring .zshrc for Oh My Zsh and Starship..."
120
121 touch "$zshrc"
122 cp "$zshrc" "$HOME/.zshrc.backup_$(date +%Y%m%d_%H%M%S)"
123
124 cat > "$zshrc" <<'EOF'
125# =============================================================================
126# 1. HELPER FUNCTIONS & PATH
127# =============================================================================
128source_if_readable() {
129 local file="$1"
130 if [[ -f "$file" && -r "$file" ]]; then
131 source "$file"
132 fi
133}
134
135export PATH="$HOME/.local/bin:$PATH"
136
137# =============================================================================
138# 2. OH MY ZSH FRAMEWORK
139# =============================================================================
140export ZSH="${ZSH:-$HOME/.oh-my-zsh}"
141ZSH_THEME=""
142
143plugins=(
144 git
145 zsh-autosuggestions
146 zsh-syntax-highlighting
147)
148
149source_if_readable "$ZSH/oh-my-zsh.sh"
150
151# =============================================================================
152# 3. THIRD-PARTY INITIALIZATION & CUSTOM CONFIGS
153# =============================================================================
154source_if_readable "$HOME/.sourcerc"
155source_if_readable "$HOME/.func"
156source_if_readable "$HOME/.pathrc"
157source_if_readable "$HOME/.alias"
158
159# =============================================================================
160# 4. STARSHIP PROMPT
161# =============================================================================
162if [[ -z "${STARSHIP_CONFIG:-}" && -f "$HOME/.config/starship.toml" ]]; then
163 export STARSHIP_CONFIG="$HOME/.config/starship.toml"
164fi
165
166if command -v starship >/dev/null 2>&1; then
167 eval "$(starship init zsh)"
168elif [[ -x "$HOME/.local/bin/starship" ]]; then
169 eval "$("$HOME/.local/bin/starship" init zsh)"
170fi
171EOF
172
173 ok ".zshrc configured for Oh My Zsh framework with Starship prompt"
174}
175
176switch_shell() {
177 log "Starting Zsh session..."
178 echo -e "${YELLOW}Type 'exit' to return to this installer menu.${NC}"
179 echo "----------------------------------------"
180 zsh -l
181 echo "----------------------------------------"
182 ok "Returned from Zsh session"
183}
184
185# =============================
186# INTERACTIVE MENU
187# =============================
188show_menu() {
189 echo "==========================================="
190 echo "macOS Minimal Zsh Setup - Choose what to do"
191 echo "==========================================="
192 echo " 0) Run ALL steps (1-5)"
193 echo " 1) Install Oh My Zsh + plugins"
194 echo " 2) Install Starship prompt"
195 echo " 3) Download custom configs (~/.alias, .func, .vimrc, etc.)"
196 echo " 4) Configure ~/.zshrc (Oh My Zsh + Starship)"
197 echo " 5) Switch to Zsh (Temporary Sub-shell)"
198 echo " 6) Quit"
199 echo "==========================================="
200}
201
202run_choices() {
203 local input
204 read -p "Select: " input
205 input="${input//,/ }"
206
207 local -a to_run=()
208 local -a to_exclude=()
209
210 for item in $input; do
211 if [[ "$item" == !* ]]; then
212 to_exclude+=("${item:1}")
213 elif [[ "$item" == "0" ]]; then
214 to_run+=(1 2 3 4 5)
215 else
216 to_run+=("$item")
217 fi
218 done
219
220 if [[ ${#to_run[@]} -gt 0 ]]; then
221 for choice in "${to_run[@]}"; do
222 local skip=false
223
224 if [[ ${#to_exclude[@]} -gt 0 ]]; then
225 for ex in "${to_exclude[@]}"; do
226 if [[ "$choice" == "$ex" ]]; then
227 skip=true
228 break
229 fi
230 done
231 fi
232
233 $skip && continue
234
235 case "$choice" in
236 1) install_oh_my_zsh ;;
237 2) install_starship ;;
238 3) download_configs ;;
239 4) configure_zshrc ;;
240 5) switch_shell ;;
241 6) exit 0 ;;
242 *) warn "Skipping invalid option: $choice" ;;
243 esac
244 echo
245 done
246 fi
247}
248
249# =============================
250# MAIN
251# =============================
252main() {
253 check_requirements
254 while true; do
255 show_menu
256 run_choices
257 read -p "Do you want to run more options? (y/n): " again
258 [[ "$again" =~ ^[Yy]$ ]] || break
259 done
260 ok "macOS minimal Zsh configuration complete!"
261}
262
263main "$@"
264
zsh_ubuntu.sh Raw
1#!/bin/bash
2set -euo pipefail
3
4# =============================
5# COLORS & LOGGING
6# =============================
7RED='\033[0;31m'
8GREEN='\033[0;32m'
9YELLOW='\033[1;33m'
10BLUE='\033[0;34m'
11NC='\033[0m'
12
13log() { echo -e "${BLUE}[INFO]${NC} $*"; }
14ok() { echo -e "${GREEN}[OK]${NC} $*"; }
15warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
16err() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
17
18# =============================
19# FLAGS & CONFIG
20# =============================
21SKIP_PACKAGES=false
22SKIP_SHELL_CHANGE=false
23INSTALL_HOMEBREW=false
24
25GIST_RAW_BASE="https://opengist.rmrf.online/weehong/f0d940c3c1214bf5b7996195199fdc09/raw/HEAD"
26CONFIG_FILES=(
27 ".alias"
28 ".func"
29 ".pathrc"
30 ".sourcerc"
31 ".vimrc"
32 ".zshrc"
33 ".config/starship.toml"
34)
35
36# =============================
37# OS DETECTION
38# =============================
39detect_os() {
40 if [[ "$OSTYPE" == "darwin"* ]]; then
41 echo "macos"
42 elif [ -f /etc/os-release ]; then
43 . /etc/os-release
44 echo "$ID"
45 else
46 echo "unknown"
47 fi
48}
49
50# =============================
51# REQUIREMENTS
52# =============================
53check_requirements() {
54 if [[ $EUID -eq 0 ]]; then
55 err "Do not run as root. The script will request sudo when necessary."
56 exit 1
57 fi
58 if [[ "$(detect_os)" != "macos" ]] && ! command -v sudo >/dev/null 2>&1; then
59 err "sudo required on Linux"
60 exit 1
61 fi
62}
63
64# =============================
65# INSTALLATION FUNCTIONS
66# =============================
67update_system() {
68 $SKIP_PACKAGES && return
69 log "Updating system..."
70 local os=$(detect_os)
71
72 case "$os" in
73 macos) brew update ;;
74 ubuntu|debian) sudo apt-get update -y && sudo apt-get upgrade -y ;;
75 fedora) sudo dnf upgrade -y ;;
76 arch) sudo pacman -Syu --noconfirm ;;
77 *) warn "Auto-update not supported for OS: $os" ;;
78 esac
79 ok "System updated"
80}
81
82install_packages() {
83 $SKIP_PACKAGES && return
84 log "Installing core packages..."
85 local os=$(detect_os)
86
87 case "$os" in
88 macos) brew install zsh git vim curl wget unzip xz ;;
89 ubuntu|debian) sudo apt-get install -y zsh git vim curl wget unzip zip build-essential xz-utils ;;
90 fedora) sudo dnf install -y zsh git vim curl wget unzip zip @development-tools xz ;;
91 arch) sudo pacman -S --noconfirm zsh git vim curl wget unzip zip base-devel xz ;;
92 *) warn "Auto-install not supported for OS: $os. Please install zsh, git, vim, curl manually." ;;
93 esac
94 ok "Packages installed"
95}
96
97set_timezone() {
98 log "Setting timezone to Asia/Singapore..."
99 local os=$(detect_os)
100 if [[ "$os" == "macos" ]]; then
101 sudo systemsetup -settimezone Asia/Singapore >/dev/null
102 else
103 sudo timedatectl set-timezone Asia/Singapore
104 fi
105 ok "Timezone set to Asia/Singapore"
106}
107
108install_homebrew() {
109 ! $INSTALL_HOMEBREW && return
110 command -v brew >/dev/null 2>&1 && ok "Homebrew already installed" && return
111 log "Installing Homebrew..."
112 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
113 ok "Homebrew installed"
114}
115
116configure_shell() {
117 $SKIP_SHELL_CHANGE && return
118 log "Changing default shell to zsh..."
119 local zsh_path
120 zsh_path="$(command -v zsh)"
121
122 if ! grep -qx "$zsh_path" /etc/shells; then
123 echo "$zsh_path" | sudo tee -a /etc/shells >/dev/null
124 fi
125 chsh -s "$zsh_path"
126 ok "Shell changed (requires logout/login to take effect)"
127}
128
129install_oh_my_zsh() {
130 log "Installing Oh My Zsh and plugins..."
131 export RUNZSH=no
132 export CHSH=no
133 export KEEP_ZSHRC=yes
134
135 if [[ ! -d "$HOME/.oh-my-zsh" ]]; then
136 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" --unattended
137 else
138 ok "Oh My Zsh already installed"
139 fi
140
141 local custom="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
142 local plugin_dir="$custom/plugins"
143 mkdir -p "$plugin_dir"
144
145 [[ -d "$plugin_dir/zsh-autosuggestions" ]] || git clone https://github.com/zsh-users/zsh-autosuggestions "$plugin_dir/zsh-autosuggestions"
146 [[ -d "$plugin_dir/zsh-syntax-highlighting" ]] || git clone https://github.com/zsh-users/zsh-syntax-highlighting "$plugin_dir/zsh-syntax-highlighting"
147
148 ok "Oh My Zsh plugins installed to $plugin_dir"
149}
150
151install_starship() {
152 if command -v starship >/dev/null 2>&1 || [[ -f "$HOME/.local/bin/starship" ]]; then
153 ok "Starship already installed"
154 else
155 log "Installing Starship prompt..."
156 if command -v brew >/dev/null 2>&1; then
157 brew install starship
158 else
159 mkdir -p "$HOME/.local/bin"
160 curl -fsSL https://starship.rs/install.sh | sh -s -- -y -b "$HOME/.local/bin"
161 fi
162 ok "Starship installed"
163 fi
164}
165
166download_configs() {
167 log "Downloading custom config files from OpenGist..."
168 local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)"
169 mkdir -p "$backup"
170
171 for f in "${CONFIG_FILES[@]}"; do
172 local remote_file="${f#.}"
173 [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml"
174 local url="$GIST_RAW_BASE/$remote_file"
175 local target="$HOME/$f"
176 local tmp="${target}.tmp.$$"
177
178 mkdir -p "$(dirname "$target")"
179
180 if [[ -f "$target" ]]; then
181 cp "$target" "$backup/"
182 fi
183
184 log "Fetching $remote_file -> $f ..."
185 if curl -fsSL "$url" -o "$tmp"; then
186 mv "$tmp" "$target"
187 else
188 rm -f "$tmp"
189 warn "Failed to download $remote_file"
190 fi
191 done
192
193 ok "Configs downloaded (Backup at $backup)"
194}
195
196configure_zshrc() {
197 local zshrc="$HOME/.zshrc"
198 log "Configuring .zshrc for Oh My Zsh and Starship..."
199
200 touch "$zshrc"
201 cp "$zshrc" "$HOME/.zshrc.backup_$(date +%Y%m%d_%H%M%S)"
202
203 cat > "$zshrc" <<'EOF'
204# =============================================================================
205# 1. HELPER FUNCTIONS & PATH
206# =============================================================================
207source_if_readable() {
208 local file="$1"
209 if [[ -f "$file" && -r "$file" ]]; then
210 source "$file"
211 fi
212}
213
214export PATH="$HOME/.local/bin:$PATH"
215
216# =============================================================================
217# 2. OH MY ZSH FRAMEWORK
218# =============================================================================
219export ZSH="${ZSH:-$HOME/.oh-my-zsh}"
220ZSH_THEME=""
221
222plugins=(
223 git
224 zsh-autosuggestions
225 zsh-syntax-highlighting
226)
227
228source_if_readable "$ZSH/oh-my-zsh.sh"
229
230# =============================================================================
231# 3. THIRD-PARTY INITIALIZATION & CUSTOM CONFIGS
232# =============================================================================
233source_if_readable "$HOME/.sourcerc"
234source_if_readable "$HOME/.func"
235source_if_readable "$HOME/.pathrc"
236source_if_readable "$HOME/.alias"
237
238# =============================================================================
239# 4. STARSHIP PROMPT
240# =============================================================================
241if [[ -z "${STARSHIP_CONFIG:-}" && -f "$HOME/.config/starship.toml" ]]; then
242 export STARSHIP_CONFIG="$HOME/.config/starship.toml"
243fi
244
245if command -v starship >/dev/null 2>&1; then
246 eval "$(starship init zsh)"
247elif [[ -x "$HOME/.local/bin/starship" ]]; then
248 eval "$("$HOME/.local/bin/starship" init zsh)"
249fi
250EOF
251
252 ok ".zshrc configured for Oh My Zsh framework with Starship prompt"
253}
254
255switch_shell() {
256 log "Starting Zsh session..."
257 echo -e "${YELLOW}Type 'exit' to return to this installer menu.${NC}"
258 echo "----------------------------------------"
259 zsh -l
260 echo "----------------------------------------"
261 ok "Returned from Zsh session"
262}
263
264# =============================
265# INTERACTIVE MENU
266# =============================
267show_menu() {
268 echo "==========================================="
269 echo "Minimal Zsh Installer - Choose what to do"
270 echo "==========================================="
271 echo " 0) Run ALL steps (1-10)"
272 echo " 1) Update system packages"
273 echo " 2) Install core packages (zsh, git, vim, etc.)"
274 echo " 3) Set Timezone (Asia/Singapore)"
275 echo " 4) Install Homebrew"
276 echo " 5) Configure shell (chsh - sets default shell)"
277 echo " 6) Install Oh My Zsh + plugins"
278 echo " 7) Install Starship prompt"
279 echo " 8) Download custom configs (from OpenGist)"
280 echo " 9) Configure ~/.zshrc (Oh My Zsh + Starship)"
281 echo "10) Switch to Zsh (Temporary Sub-shell)"
282 echo "11) Quit"
283 echo "==========================================="
284}
285
286run_choices() {
287 local input
288 read -p "Select: " input
289 input="${input//,/ }"
290
291 local -a to_run=()
292 local -a to_exclude=()
293
294 for item in $input; do
295 if [[ "$item" == !* ]]; then
296 to_exclude+=("${item:1}")
297 elif [[ "$item" == "0" ]]; then
298 to_run+=(1 2 3 4 5 6 7 8 9 10)
299 else
300 to_run+=("$item")
301 fi
302 done
303
304 for choice in "${to_run[@]}"; do
305 local skip=false
306
307 for ex in "${to_exclude[@]}"; do
308 if [[ "$choice" == "$ex" ]]; then
309 skip=true
310 break
311 fi
312 done
313
314 $skip && continue
315
316 case "$choice" in
317 1) update_system ;;
318 2) install_packages ;;
319 3) set_timezone ;;
320 4) install_homebrew ;;
321 5) configure_shell ;;
322 6) install_oh_my_zsh ;;
323 7) install_starship ;;
324 8) download_configs ;;
325 9) configure_zshrc ;;
326 10) switch_shell ;;
327 11) log "Exiting..."; exit 0 ;;
328 *) warn "Skipping invalid option: $choice" ;;
329 esac
330 echo
331 done
332}
333
334# =============================
335# MAIN
336# =============================
337main() {
338 check_requirements
339 while true; do
340 show_menu
341 run_choices
342 read -p "Do you want to run more options? (y/n): " again
343 [[ "$again" =~ ^[Yy]$ ]] || break
344 done
345 ok "Zsh installation/configuration complete!"
346}
347
348main "$@"
349
zsh_wsl.sh Raw
1#!/bin/bash
2set -euo pipefail
3
4# =============================
5# COLORS & LOGGING
6# =============================
7RED='\033[0;31m'
8GREEN='\033[0;32m'
9YELLOW='\033[1;33m'
10BLUE='\033[0;34m'
11NC='\033[0m'
12
13log() { echo -e "${BLUE}[INFO]${NC} $*"; }
14ok() { echo -e "${GREEN}[OK]${NC} $*"; }
15warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
16err() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
17
18# =============================
19# FLAGS & CONFIG
20# =============================
21SKIP_PACKAGES=false
22SKIP_SHELL_CHANGE=false
23INSTALL_HOMEBREW=false
24
25GIST_RAW_BASE="https://opengist.rmrf.online/weehong/f0d940c3c1214bf5b7996195199fdc09/raw/HEAD"
26CONFIG_FILES=(
27 ".alias"
28 ".func"
29 ".pathrc"
30 ".sourcerc"
31 ".vimrc"
32 ".zshrc"
33 ".config/starship.toml"
34)
35
36# =============================
37# PLATFORM DETECTION
38# =============================
39detect_os() {
40 if [ -f /etc/os-release ]; then
41 . /etc/os-release
42 echo "$ID"
43 else
44 echo "unknown"
45 fi
46}
47
48is_wsl() {
49 grep -qi "microsoft" /proc/version 2>/dev/null
50}
51
52# =============================
53# REQUIREMENTS
54# =============================
55check_requirements() {
56 if [[ $EUID -eq 0 ]]; then
57 err "Do not run as root. The script will request sudo when necessary."
58 exit 1
59 fi
60 if ! command -v sudo >/dev/null 2>&1; then
61 err "sudo required"
62 exit 1
63 fi
64 if ! is_wsl; then
65 err "This installer is intended for WSL"
66 exit 1
67 fi
68}
69
70# =============================
71# INSTALLATION FUNCTIONS
72# =============================
73update_system() {
74 $SKIP_PACKAGES && return
75 log "Updating system..."
76 local os=$(detect_os)
77
78 case "$os" in
79 ubuntu|debian) sudo apt-get update -y && sudo apt-get upgrade -y ;;
80 fedora) sudo dnf upgrade -y ;;
81 arch) sudo pacman -Syu --noconfirm ;;
82 *) warn "Auto-update not supported for OS: $os" ;;
83 esac
84 ok "System updated"
85}
86
87install_packages() {
88 $SKIP_PACKAGES && return
89 log "Installing core packages..."
90 local os=$(detect_os)
91
92 case "$os" in
93 ubuntu|debian) sudo apt-get install -y zsh git vim curl wget unzip zip build-essential xz-utils ;;
94 fedora) sudo dnf install -y zsh git vim curl wget unzip zip @development-tools xz ;;
95 arch) sudo pacman -S --noconfirm zsh git vim curl wget unzip zip base-devel xz ;;
96 *) warn "Auto-install not supported for OS: $os. Please install zsh, git, vim, curl manually." ;;
97 esac
98 ok "Packages installed"
99}
100
101set_timezone() {
102 log "Checking timezone configuration..."
103 if command -v timedatectl >/dev/null 2>&1 && timedatectl status >/dev/null 2>&1; then
104 sudo timedatectl set-timezone Asia/Singapore
105 ok "Timezone set to Asia/Singapore"
106 return
107 fi
108
109 warn "Skipping timezone change: timedatectl is not available in this WSL environment"
110}
111
112install_homebrew() {
113 ! $INSTALL_HOMEBREW && return
114 command -v brew >/dev/null 2>&1 && ok "Homebrew already installed" && return
115 log "Installing Homebrew..."
116 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
117 ok "Homebrew installed"
118}
119
120configure_shell() {
121 $SKIP_SHELL_CHANGE && return
122 log "Changing default shell to zsh..."
123 local zsh_path
124 zsh_path="$(command -v zsh)"
125
126 if ! grep -qx "$zsh_path" /etc/shells; then
127 echo "$zsh_path" | sudo tee -a /etc/shells >/dev/null
128 fi
129 chsh -s "$zsh_path"
130 ok "Shell changed (open a new WSL session for it to take effect)"
131}
132
133install_oh_my_zsh() {
134 log "Installing Oh My Zsh and plugins..."
135 export RUNZSH=no
136 export CHSH=no
137 export KEEP_ZSHRC=yes
138
139 if [[ ! -d "$HOME/.oh-my-zsh" ]]; then
140 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" --unattended
141 else
142 ok "Oh My Zsh already installed"
143 fi
144
145 local custom="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
146 local plugin_dir="$custom/plugins"
147 mkdir -p "$plugin_dir"
148
149 [[ -d "$plugin_dir/zsh-autosuggestions" ]] || git clone https://github.com/zsh-users/zsh-autosuggestions "$plugin_dir/zsh-autosuggestions"
150 [[ -d "$plugin_dir/zsh-syntax-highlighting" ]] || git clone https://github.com/zsh-users/zsh-syntax-highlighting "$plugin_dir/zsh-syntax-highlighting"
151
152 ok "Oh My Zsh plugins installed to $plugin_dir"
153}
154
155install_starship() {
156 if command -v starship >/dev/null 2>&1 || [[ -f "$HOME/.local/bin/starship" ]]; then
157 ok "Starship already installed"
158 else
159 log "Installing Starship prompt..."
160 if command -v brew >/dev/null 2>&1; then
161 brew install starship
162 else
163 mkdir -p "$HOME/.local/bin"
164 curl -fsSL https://starship.rs/install.sh | sh -s -- -y -b "$HOME/.local/bin"
165 fi
166 ok "Starship installed"
167 fi
168}
169
170download_configs() {
171 log "Downloading custom config files from OpenGist..."
172 local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)"
173 mkdir -p "$backup"
174
175 for f in "${CONFIG_FILES[@]}"; do
176 local remote_file="${f#.}"
177 [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml"
178 local url="$GIST_RAW_BASE/$remote_file"
179 local target="$HOME/$f"
180 local tmp="${target}.tmp.$$"
181
182 mkdir -p "$(dirname "$target")"
183
184 if [[ -f "$target" ]]; then
185 cp "$target" "$backup/"
186 fi
187
188 log "Fetching $remote_file -> $f ..."
189 if curl -fsSL "$url" -o "$tmp"; then
190 mv "$tmp" "$target"
191 else
192 rm -f "$tmp"
193 warn "Failed to download $remote_file"
194 fi
195 done
196
197 ok "Configs downloaded (Backup at $backup)"
198}
199
200configure_zshrc() {
201 local zshrc="$HOME/.zshrc"
202 log "Configuring .zshrc for Oh My Zsh and Starship..."
203
204 touch "$zshrc"
205 cp "$zshrc" "$HOME/.zshrc.backup_$(date +%Y%m%d_%H%M%S)"
206
207 cat > "$zshrc" <<'EOF'
208# =============================================================================
209# 1. HELPER FUNCTIONS & PATH
210# =============================================================================
211source_if_readable() {
212 local file="$1"
213 if [[ -f "$file" && -r "$file" ]]; then
214 source "$file"
215 fi
216}
217
218export PATH="$HOME/.local/bin:$PATH"
219
220# =============================================================================
221# 2. OH MY ZSH FRAMEWORK
222# =============================================================================
223export ZSH="${ZSH:-$HOME/.oh-my-zsh}"
224ZSH_THEME=""
225
226plugins=(
227 git
228 zsh-autosuggestions
229 zsh-syntax-highlighting
230)
231
232source_if_readable "$ZSH/oh-my-zsh.sh"
233
234# =============================================================================
235# 3. THIRD-PARTY INITIALIZATION & CUSTOM CONFIGS
236# =============================================================================
237source_if_readable "$HOME/.sourcerc"
238source_if_readable "$HOME/.func"
239source_if_readable "$HOME/.pathrc"
240source_if_readable "$HOME/.alias"
241
242# =============================================================================
243# 4. STARSHIP PROMPT
244# =============================================================================
245if [[ -z "${STARSHIP_CONFIG:-}" && -f "$HOME/.config/starship.toml" ]]; then
246 export STARSHIP_CONFIG="$HOME/.config/starship.toml"
247fi
248
249if command -v starship >/dev/null 2>&1; then
250 eval "$(starship init zsh)"
251elif [[ -x "$HOME/.local/bin/starship" ]]; then
252 eval "$("$HOME/.local/bin/starship" init zsh)"
253fi
254EOF
255
256 ok ".zshrc configured for Oh My Zsh framework with Starship prompt"
257}
258
259switch_shell() {
260 log "Starting Zsh session..."
261 echo -e "${YELLOW}Type 'exit' to return to this installer menu.${NC}"
262 echo "----------------------------------------"
263 zsh -l
264 echo "----------------------------------------"
265 ok "Returned from Zsh session"
266}
267
268# =============================
269# INTERACTIVE MENU
270# =============================
271show_menu() {
272 echo "==========================================="
273 echo "WSL Minimal Zsh Installer - Choose what to do"
274 echo "==========================================="
275 echo " 0) Run ALL steps (1-10)"
276 echo " 1) Update system packages"
277 echo " 2) Install core packages (zsh, git, vim, etc.)"
278 echo " 3) Set Timezone (best effort)"
279 echo " 4) Install Homebrew"
280 echo " 5) Configure shell (chsh - sets default shell)"
281 echo " 6) Install Oh My Zsh + plugins"
282 echo " 7) Install Starship prompt"
283 echo " 8) Download custom configs (from OpenGist)"
284 echo " 9) Configure ~/.zshrc (Oh My Zsh + Starship)"
285 echo "10) Switch to Zsh (Temporary Sub-shell)"
286 echo "11) Quit"
287 echo "==========================================="
288}
289
290run_choices() {
291 local input
292 read -p "Select: " input
293 input="${input//,/ }"
294
295 local -a to_run=()
296 local -a to_exclude=()
297
298 for item in $input; do
299 if [[ "$item" == !* ]]; then
300 to_exclude+=("${item:1}")
301 elif [[ "$item" == "0" ]]; then
302 to_run+=(1 2 3 4 5 6 7 8 9 10)
303 else
304 to_run+=("$item")
305 fi
306 done
307
308 for choice in "${to_run[@]}"; do
309 local skip=false
310
311 for ex in "${to_exclude[@]}"; do
312 if [[ "$choice" == "$ex" ]]; then
313 skip=true
314 break
315 fi
316 done
317
318 $skip && continue
319
320 case "$choice" in
321 1) update_system ;;
322 2) install_packages ;;
323 3) set_timezone ;;
324 4) install_homebrew ;;
325 5) configure_shell ;;
326 6) install_oh_my_zsh ;;
327 7) install_starship ;;
328 8) download_configs ;;
329 9) configure_zshrc ;;
330 10) switch_shell ;;
331 11) log "Exiting..."; exit 0 ;;
332 *) warn "Skipping invalid option: $choice" ;;
333 esac
334 echo
335 done
336}
337
338# =============================
339# MAIN
340# =============================
341main() {
342 check_requirements
343 while true; do
344 show_menu
345 run_choices
346 read -p "Do you want to run more options? (y/n): " again
347 [[ "$again" =~ ^[Yy]$ ]] || break
348 done
349 ok "WSL Zsh installation/configuration complete!"
350}
351
352main "$@"
353
zshrc Raw
1# =============================================================================
2# 1. HELPER FUNCTIONS & PATH
3# =============================================================================
4source_if_readable() {
5 local file="$1"
6 if [[ -f "$file" && -r "$file" ]]; then
7 source "$file"
8 fi
9}
10
11# Ensure local bin is in PATH early (catches manual Starship installations)
12export PATH="$HOME/.local/bin:$PATH"
13
14# =============================================================================
15# 2. OH MY ZSH FRAMEWORK
16# =============================================================================
17export ZSH="${ZSH:-$HOME/.oh-my-zsh}"
18ZSH_THEME=""
19
20plugins=(
21 git
22 zsh-autosuggestions
23 zsh-syntax-highlighting
24)
25
26source_if_readable "$ZSH/oh-my-zsh.sh"
27
28# =============================================================================
29# 3. THIRD-PARTY INITIALIZATION & CUSTOM CONFIGS
30# =============================================================================
31# Load external initializers (SDKMAN, NVM, etc.)
32source_if_readable "$HOME/.sourcerc"
33
34# Custom Functions (must load before Path Management)
35source_if_readable "$HOME/.func"
36
37# Path Management (Relies on append_path from .func)
38source_if_readable "$HOME/.pathrc"
39
40# Aliases (Loaded late so they override framework/system defaults)
41source_if_readable "$HOME/.alias"
42
43# =============================================================================
44# 4. STARSHIP PROMPT
45# =============================================================================
46if [[ -z "${STARSHIP_CONFIG:-}" && -f "$HOME/.config/starship.toml" ]]; then
47 export STARSHIP_CONFIG="$HOME/.config/starship.toml"
48fi
49
50# Starship owns the prompt. It must initialize after Oh My Zsh.
51if command -v starship >/dev/null 2>&1; then
52 eval "$(starship init zsh)"
53elif [[ -x "$HOME/.local/bin/starship" ]]; then
54 eval "$("$HOME/.local/bin/starship" init zsh)"
55fi
56