Dernière activité 2 weeks ago

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

README.md Brut

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 Brut
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 Brut
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 Brut
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 Brut
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 Brut
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 Brut
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 Brut
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 Brut
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 Brut
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)
74 brew update || warn "Homebrew update failed; continuing installer"
75 ;;
76 ubuntu|debian)
77 sudo apt-get update -y
78 if ! sudo apt-get upgrade -y; then
79 warn "System upgrade did not complete. This can happen when apt wants to downgrade a package."
80 warn "Continuing because the Zsh setup does not require OS package upgrades to finish."
81 fi
82 ;;
83 fedora)
84 sudo dnf upgrade -y || warn "System upgrade failed; continuing installer"
85 ;;
86 arch)
87 sudo pacman -Syu --noconfirm || warn "System upgrade failed; continuing installer"
88 ;;
89 *) warn "Auto-update not supported for OS: $os" ;;
90 esac
91 ok "System update step finished"
92}
93
94install_packages() {
95 $SKIP_PACKAGES && return
96 log "Installing core packages..."
97 local os=$(detect_os)
98
99 case "$os" in
100 macos) brew install zsh git vim curl wget unzip xz ;;
101 ubuntu|debian) sudo apt-get install -y zsh git vim curl wget unzip zip build-essential xz-utils ;;
102 fedora) sudo dnf install -y zsh git vim curl wget unzip zip @development-tools xz ;;
103 arch) sudo pacman -S --noconfirm zsh git vim curl wget unzip zip base-devel xz ;;
104 *) warn "Auto-install not supported for OS: $os. Please install zsh, git, vim, curl manually." ;;
105 esac
106 ok "Packages installed"
107}
108
109set_timezone() {
110 log "Setting timezone to Asia/Singapore..."
111 local os=$(detect_os)
112 if [[ "$os" == "macos" ]]; then
113 sudo systemsetup -settimezone Asia/Singapore >/dev/null
114 else
115 sudo timedatectl set-timezone Asia/Singapore
116 fi
117 ok "Timezone set to Asia/Singapore"
118}
119
120install_homebrew() {
121 ! $INSTALL_HOMEBREW && return
122 command -v brew >/dev/null 2>&1 && ok "Homebrew already installed" && return
123 log "Installing Homebrew..."
124 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
125 ok "Homebrew installed"
126}
127
128configure_shell() {
129 $SKIP_SHELL_CHANGE && return
130 log "Changing default shell to zsh..."
131 local zsh_path
132 zsh_path="$(command -v zsh)"
133
134 if ! grep -qx "$zsh_path" /etc/shells; then
135 echo "$zsh_path" | sudo tee -a /etc/shells >/dev/null
136 fi
137 chsh -s "$zsh_path"
138 ok "Shell changed (requires logout/login to take effect)"
139}
140
141install_oh_my_zsh() {
142 log "Installing Oh My Zsh and plugins..."
143 export RUNZSH=no
144 export CHSH=no
145 export KEEP_ZSHRC=yes
146
147 if [[ ! -d "$HOME/.oh-my-zsh" ]]; then
148 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" --unattended
149 else
150 ok "Oh My Zsh already installed"
151 fi
152
153 local custom="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
154 local plugin_dir="$custom/plugins"
155 mkdir -p "$plugin_dir"
156
157 [[ -d "$plugin_dir/zsh-autosuggestions" ]] || git clone https://github.com/zsh-users/zsh-autosuggestions "$plugin_dir/zsh-autosuggestions"
158 [[ -d "$plugin_dir/zsh-syntax-highlighting" ]] || git clone https://github.com/zsh-users/zsh-syntax-highlighting "$plugin_dir/zsh-syntax-highlighting"
159
160 ok "Oh My Zsh plugins installed to $plugin_dir"
161}
162
163install_starship() {
164 if command -v starship >/dev/null 2>&1 || [[ -f "$HOME/.local/bin/starship" ]]; then
165 ok "Starship already installed"
166 else
167 log "Installing Starship prompt..."
168 if command -v brew >/dev/null 2>&1; then
169 brew install starship
170 else
171 mkdir -p "$HOME/.local/bin"
172 curl -fsSL https://starship.rs/install.sh | sh -s -- -y -b "$HOME/.local/bin"
173 fi
174 ok "Starship installed"
175 fi
176}
177
178download_configs() {
179 log "Downloading custom config files from OpenGist..."
180 local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)"
181 mkdir -p "$backup"
182
183 for f in "${CONFIG_FILES[@]}"; do
184 local remote_file="${f#.}"
185 [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml"
186 local url="$GIST_RAW_BASE/$remote_file"
187 local target="$HOME/$f"
188 local tmp="${target}.tmp.$$"
189
190 mkdir -p "$(dirname "$target")"
191
192 if [[ -f "$target" ]]; then
193 cp "$target" "$backup/"
194 fi
195
196 log "Fetching $remote_file -> $f ..."
197 if curl -fsSL "$url" -o "$tmp"; then
198 mv "$tmp" "$target"
199 else
200 rm -f "$tmp"
201 warn "Failed to download $remote_file"
202 fi
203 done
204
205 ok "Configs downloaded (Backup at $backup)"
206}
207
208configure_zshrc() {
209 local zshrc="$HOME/.zshrc"
210 log "Configuring .zshrc for Oh My Zsh and Starship..."
211
212 touch "$zshrc"
213 cp "$zshrc" "$HOME/.zshrc.backup_$(date +%Y%m%d_%H%M%S)"
214
215 cat > "$zshrc" <<'EOF'
216# =============================================================================
217# 1. HELPER FUNCTIONS & PATH
218# =============================================================================
219source_if_readable() {
220 local file="$1"
221 if [[ -f "$file" && -r "$file" ]]; then
222 source "$file"
223 fi
224}
225
226export PATH="$HOME/.local/bin:$PATH"
227
228# =============================================================================
229# 2. OH MY ZSH FRAMEWORK
230# =============================================================================
231export ZSH="${ZSH:-$HOME/.oh-my-zsh}"
232ZSH_THEME=""
233
234plugins=(
235 git
236 zsh-autosuggestions
237 zsh-syntax-highlighting
238)
239
240source_if_readable "$ZSH/oh-my-zsh.sh"
241
242# =============================================================================
243# 3. THIRD-PARTY INITIALIZATION & CUSTOM CONFIGS
244# =============================================================================
245source_if_readable "$HOME/.sourcerc"
246source_if_readable "$HOME/.func"
247source_if_readable "$HOME/.pathrc"
248source_if_readable "$HOME/.alias"
249
250# =============================================================================
251# 4. STARSHIP PROMPT
252# =============================================================================
253if [[ -z "${STARSHIP_CONFIG:-}" && -f "$HOME/.config/starship.toml" ]]; then
254 export STARSHIP_CONFIG="$HOME/.config/starship.toml"
255fi
256
257if command -v starship >/dev/null 2>&1; then
258 eval "$(starship init zsh)"
259elif [[ -x "$HOME/.local/bin/starship" ]]; then
260 eval "$("$HOME/.local/bin/starship" init zsh)"
261fi
262EOF
263
264 ok ".zshrc configured for Oh My Zsh framework with Starship prompt"
265}
266
267switch_shell() {
268 log "Starting Zsh session..."
269 echo -e "${YELLOW}Type 'exit' to return to this installer menu.${NC}"
270 echo "----------------------------------------"
271 zsh -l
272 echo "----------------------------------------"
273 ok "Returned from Zsh session"
274}
275
276# =============================
277# INTERACTIVE MENU
278# =============================
279show_menu() {
280 echo "==========================================="
281 echo "Minimal Zsh Installer - Choose what to do"
282 echo "==========================================="
283 echo " 0) Run ALL steps (1-10)"
284 echo " 1) Update system packages"
285 echo " 2) Install core packages (zsh, git, vim, etc.)"
286 echo " 3) Set Timezone (Asia/Singapore)"
287 echo " 4) Install Homebrew"
288 echo " 5) Configure shell (chsh - sets default shell)"
289 echo " 6) Install Oh My Zsh + plugins"
290 echo " 7) Install Starship prompt"
291 echo " 8) Download custom configs (from OpenGist)"
292 echo " 9) Configure ~/.zshrc (Oh My Zsh + Starship)"
293 echo "10) Switch to Zsh (Temporary Sub-shell)"
294 echo "11) Quit"
295 echo "==========================================="
296}
297
298run_choices() {
299 local input
300 read -p "Select: " input
301 input="${input//,/ }"
302
303 local -a to_run=()
304 local -a to_exclude=()
305
306 for item in $input; do
307 if [[ "$item" == !* ]]; then
308 to_exclude+=("${item:1}")
309 elif [[ "$item" == "0" ]]; then
310 to_run+=(1 2 3 4 5 6 7 8 9 10)
311 else
312 to_run+=("$item")
313 fi
314 done
315
316 for choice in "${to_run[@]}"; do
317 local skip=false
318
319 for ex in "${to_exclude[@]}"; do
320 if [[ "$choice" == "$ex" ]]; then
321 skip=true
322 break
323 fi
324 done
325
326 $skip && continue
327
328 case "$choice" in
329 1) update_system ;;
330 2) install_packages ;;
331 3) set_timezone ;;
332 4) install_homebrew ;;
333 5) configure_shell ;;
334 6) install_oh_my_zsh ;;
335 7) install_starship ;;
336 8) download_configs ;;
337 9) configure_zshrc ;;
338 10) switch_shell ;;
339 11) log "Exiting..."; exit 0 ;;
340 *) warn "Skipping invalid option: $choice" ;;
341 esac
342 echo
343 done
344}
345
346# =============================
347# MAIN
348# =============================
349main() {
350 check_requirements
351 while true; do
352 show_menu
353 run_choices
354 read -p "Do you want to run more options? (y/n): " again
355 [[ "$again" =~ ^[Yy]$ ]] || break
356 done
357 ok "Zsh installation/configuration complete!"
358}
359
360main "$@"
361
zsh_wsl.sh Brut
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)
80 sudo apt-get update -y
81 if ! sudo apt-get upgrade -y; then
82 warn "System upgrade did not complete. This can happen when apt wants to downgrade a package."
83 warn "Continuing because the Zsh setup does not require OS package upgrades to finish."
84 fi
85 ;;
86 fedora)
87 sudo dnf upgrade -y || warn "System upgrade failed; continuing installer"
88 ;;
89 arch)
90 sudo pacman -Syu --noconfirm || warn "System upgrade failed; continuing installer"
91 ;;
92 *) warn "Auto-update not supported for OS: $os" ;;
93 esac
94 ok "System update step finished"
95}
96
97install_packages() {
98 $SKIP_PACKAGES && return
99 log "Installing core packages..."
100 local os=$(detect_os)
101
102 case "$os" in
103 ubuntu|debian) sudo apt-get install -y zsh git vim curl wget unzip zip build-essential xz-utils ;;
104 fedora) sudo dnf install -y zsh git vim curl wget unzip zip @development-tools xz ;;
105 arch) sudo pacman -S --noconfirm zsh git vim curl wget unzip zip base-devel xz ;;
106 *) warn "Auto-install not supported for OS: $os. Please install zsh, git, vim, curl manually." ;;
107 esac
108 ok "Packages installed"
109}
110
111set_timezone() {
112 log "Checking timezone configuration..."
113 if command -v timedatectl >/dev/null 2>&1 && timedatectl status >/dev/null 2>&1; then
114 sudo timedatectl set-timezone Asia/Singapore
115 ok "Timezone set to Asia/Singapore"
116 return
117 fi
118
119 warn "Skipping timezone change: timedatectl is not available in this WSL environment"
120}
121
122install_homebrew() {
123 ! $INSTALL_HOMEBREW && return
124 command -v brew >/dev/null 2>&1 && ok "Homebrew already installed" && return
125 log "Installing Homebrew..."
126 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
127 ok "Homebrew installed"
128}
129
130configure_shell() {
131 $SKIP_SHELL_CHANGE && return
132 log "Changing default shell to zsh..."
133 local zsh_path
134 zsh_path="$(command -v zsh)"
135
136 if ! grep -qx "$zsh_path" /etc/shells; then
137 echo "$zsh_path" | sudo tee -a /etc/shells >/dev/null
138 fi
139 chsh -s "$zsh_path"
140 ok "Shell changed (open a new WSL session for it to take effect)"
141}
142
143install_oh_my_zsh() {
144 log "Installing Oh My Zsh and plugins..."
145 export RUNZSH=no
146 export CHSH=no
147 export KEEP_ZSHRC=yes
148
149 if [[ ! -d "$HOME/.oh-my-zsh" ]]; then
150 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" --unattended
151 else
152 ok "Oh My Zsh already installed"
153 fi
154
155 local custom="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
156 local plugin_dir="$custom/plugins"
157 mkdir -p "$plugin_dir"
158
159 [[ -d "$plugin_dir/zsh-autosuggestions" ]] || git clone https://github.com/zsh-users/zsh-autosuggestions "$plugin_dir/zsh-autosuggestions"
160 [[ -d "$plugin_dir/zsh-syntax-highlighting" ]] || git clone https://github.com/zsh-users/zsh-syntax-highlighting "$plugin_dir/zsh-syntax-highlighting"
161
162 ok "Oh My Zsh plugins installed to $plugin_dir"
163}
164
165install_starship() {
166 if command -v starship >/dev/null 2>&1 || [[ -f "$HOME/.local/bin/starship" ]]; then
167 ok "Starship already installed"
168 else
169 log "Installing Starship prompt..."
170 if command -v brew >/dev/null 2>&1; then
171 brew install starship
172 else
173 mkdir -p "$HOME/.local/bin"
174 curl -fsSL https://starship.rs/install.sh | sh -s -- -y -b "$HOME/.local/bin"
175 fi
176 ok "Starship installed"
177 fi
178}
179
180download_configs() {
181 log "Downloading custom config files from OpenGist..."
182 local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)"
183 mkdir -p "$backup"
184
185 for f in "${CONFIG_FILES[@]}"; do
186 local remote_file="${f#.}"
187 [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml"
188 local url="$GIST_RAW_BASE/$remote_file"
189 local target="$HOME/$f"
190 local tmp="${target}.tmp.$$"
191
192 mkdir -p "$(dirname "$target")"
193
194 if [[ -f "$target" ]]; then
195 cp "$target" "$backup/"
196 fi
197
198 log "Fetching $remote_file -> $f ..."
199 if curl -fsSL "$url" -o "$tmp"; then
200 mv "$tmp" "$target"
201 else
202 rm -f "$tmp"
203 warn "Failed to download $remote_file"
204 fi
205 done
206
207 ok "Configs downloaded (Backup at $backup)"
208}
209
210configure_zshrc() {
211 local zshrc="$HOME/.zshrc"
212 log "Configuring .zshrc for Oh My Zsh and Starship..."
213
214 touch "$zshrc"
215 cp "$zshrc" "$HOME/.zshrc.backup_$(date +%Y%m%d_%H%M%S)"
216
217 cat > "$zshrc" <<'EOF'
218# =============================================================================
219# 1. HELPER FUNCTIONS & PATH
220# =============================================================================
221source_if_readable() {
222 local file="$1"
223 if [[ -f "$file" && -r "$file" ]]; then
224 source "$file"
225 fi
226}
227
228export PATH="$HOME/.local/bin:$PATH"
229
230# =============================================================================
231# 2. OH MY ZSH FRAMEWORK
232# =============================================================================
233export ZSH="${ZSH:-$HOME/.oh-my-zsh}"
234ZSH_THEME=""
235
236plugins=(
237 git
238 zsh-autosuggestions
239 zsh-syntax-highlighting
240)
241
242source_if_readable "$ZSH/oh-my-zsh.sh"
243
244# =============================================================================
245# 3. THIRD-PARTY INITIALIZATION & CUSTOM CONFIGS
246# =============================================================================
247source_if_readable "$HOME/.sourcerc"
248source_if_readable "$HOME/.func"
249source_if_readable "$HOME/.pathrc"
250source_if_readable "$HOME/.alias"
251
252# =============================================================================
253# 4. STARSHIP PROMPT
254# =============================================================================
255if [[ -z "${STARSHIP_CONFIG:-}" && -f "$HOME/.config/starship.toml" ]]; then
256 export STARSHIP_CONFIG="$HOME/.config/starship.toml"
257fi
258
259if command -v starship >/dev/null 2>&1; then
260 eval "$(starship init zsh)"
261elif [[ -x "$HOME/.local/bin/starship" ]]; then
262 eval "$("$HOME/.local/bin/starship" init zsh)"
263fi
264EOF
265
266 ok ".zshrc configured for Oh My Zsh framework with Starship prompt"
267}
268
269switch_shell() {
270 log "Starting Zsh session..."
271 echo -e "${YELLOW}Type 'exit' to return to this installer menu.${NC}"
272 echo "----------------------------------------"
273 zsh -l
274 echo "----------------------------------------"
275 ok "Returned from Zsh session"
276}
277
278# =============================
279# INTERACTIVE MENU
280# =============================
281show_menu() {
282 echo "==========================================="
283 echo "WSL Minimal Zsh Installer - Choose what to do"
284 echo "==========================================="
285 echo " 0) Run ALL steps (1-10)"
286 echo " 1) Update system packages"
287 echo " 2) Install core packages (zsh, git, vim, etc.)"
288 echo " 3) Set Timezone (best effort)"
289 echo " 4) Install Homebrew"
290 echo " 5) Configure shell (chsh - sets default shell)"
291 echo " 6) Install Oh My Zsh + plugins"
292 echo " 7) Install Starship prompt"
293 echo " 8) Download custom configs (from OpenGist)"
294 echo " 9) Configure ~/.zshrc (Oh My Zsh + Starship)"
295 echo "10) Switch to Zsh (Temporary Sub-shell)"
296 echo "11) Quit"
297 echo "==========================================="
298}
299
300run_choices() {
301 local input
302 read -p "Select: " input
303 input="${input//,/ }"
304
305 local -a to_run=()
306 local -a to_exclude=()
307
308 for item in $input; do
309 if [[ "$item" == !* ]]; then
310 to_exclude+=("${item:1}")
311 elif [[ "$item" == "0" ]]; then
312 to_run+=(1 2 3 4 5 6 7 8 9 10)
313 else
314 to_run+=("$item")
315 fi
316 done
317
318 for choice in "${to_run[@]}"; do
319 local skip=false
320
321 for ex in "${to_exclude[@]}"; do
322 if [[ "$choice" == "$ex" ]]; then
323 skip=true
324 break
325 fi
326 done
327
328 $skip && continue
329
330 case "$choice" in
331 1) update_system ;;
332 2) install_packages ;;
333 3) set_timezone ;;
334 4) install_homebrew ;;
335 5) configure_shell ;;
336 6) install_oh_my_zsh ;;
337 7) install_starship ;;
338 8) download_configs ;;
339 9) configure_zshrc ;;
340 10) switch_shell ;;
341 11) log "Exiting..."; exit 0 ;;
342 *) warn "Skipping invalid option: $choice" ;;
343 esac
344 echo
345 done
346}
347
348# =============================
349# MAIN
350# =============================
351main() {
352 check_requirements
353 while true; do
354 show_menu
355 run_choices
356 read -p "Do you want to run more options? (y/n): " again
357 [[ "$again" =~ ^[Yy]$ ]] || break
358 done
359 ok "WSL Zsh installation/configuration complete!"
360}
361
362main "$@"
363
zshrc Brut
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