Archive of

是幸运,也是“必然”

今天我突然想到,“幸运”其实并不神秘。它只是一种相对罕见的结果。如果我们掷骰子,只要连续掷个几百次,总会有一两次“六连六”这样的神奇组合。这种幸运,从概率的角度来看,只是一件迟早但必定会发生的事情。

从宇宙这样的广度来看,每一分每一秒生物界的“上帝”都在“掷骰子”(基因突变),只要时间足够长,每一个看似根本“不可能”的事件,都必定会出现,而且会重复出现。幸运,并不违反规律。

那些“幸运”的人,或许他们只是早一步遇上了本就会出现的那颗“六”。

人生当然不是掷骰子这样简单。但我们都知道,如果一个骰子的六个面都是六,那么你每一次掷骰子都会得到六。

你持续不断的学习,就是在暗暗地将骰子的每一个面打磨得越来越接近六。每一次做决定,都是一次尝试;失败了也没关系,只要你不停止尝试,你就在不断提升自己下一次“掷中六”的几率。

你不能够确切地知道那颗六什么时候来,但你总能够把自己塑造成一个越来越有把握投出六的人。

Slash Your Zsh Startup Time on macOS: Replacing NVM with FNM and Autojump with Zoxide

Okay, absolutely. Adding a cleanup step is a great idea to keep things tidy. I'll add a "Step 5" to the blog post draft.

Is opening a new terminal window or tab feeling sluggish? Do you tap your fingers waiting for your Zsh prompt to appear? If you're using popular tools like NVM (Node Version Manager) and Autojump on macOS, they might be the culprits behind that frustrating delay.

Recently, I noticed my own Zsh startup taking several seconds. After some investigation, the primary offenders were NVM's initialization script and, surprisingly, Autojump's sourcing process. The good news? There are blazing-fast, modern alternatives written in Rust: FNM (Fast Node Manager) and Zoxide.

This post will guide you through diagnosing your Zsh startup time and replacing NVM and Autojump with their speedier counterparts. Let's reclaim those lost seconds!

Step 1: Diagnose the Delay (Confirming the Culprits)

Before replacing anything, let's confirm what's slow. While Zsh's built-in zprof is useful for profiling Zsh functions, it sometimes doesn't accurately capture time spent running external commands or sourcing external scripts during startup. We'll use the simple time command:

  1. Baseline Zsh Time: How fast does Zsh start without your config?

    time zsh -f -i -c exit
    

    (-f skips .zshrc, -i simulates interactive, -c exit exits immediately). Expect this to be very fast (e.g., ~0.1 seconds).

  2. Time Potential Offenders: Check the initialization time of suspects like NVM and Autojump. (Replace paths with your actual ones).

    # Time NVM init (if you were using it) - find the source line in your .zshrc
    # Example: time zsh -f -c '[ -s "$HOME/.nvm/nvm.sh" ] && . "$HOME/.nvm/nvm.sh"'
    
    # Time Autojump init (find the source line in your .zshrc)
    # Common paths: ~/.local/share/autojump/autojump.sh or ~/Library/autojump/autojump.sh
    # Or the one often installed by Homebrew: /usr/local/etc/profile.d/autojump.sh or /opt/homebrew/etc/profile.d/autojump.sh
    time zsh -f -c '[ -f /path/to/your/autojump.sh ] && . /path/to/your/autojump.sh'
    

In my case, the Autojump sourcing took over 2 seconds, and NVM (before I removed it) was also notoriously slow. If you see significant times here (anything over a few tenths of a second adds up), replacing them is worthwhile.

Step 2: Replace NVM with FNM

FNM is significantly faster than the shell-script-based NVM.

  1. Remove NVM Config: Open your ~/.zshrc file. Find and delete or comment out the lines that load NVM. They typically look like:

    # Example lines to remove:
    # export NVM_DIR="$HOME/.nvm"
    # [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
    # [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
    # Or lines sourcing from /usr/local/opt/nvm or /opt/homebrew/opt/nvm
    
  2. Install FNM: The easiest way on macOS is via Homebrew:

    brew install fnm
    
  3. Configure FNM: Add the following line to the end of your ~/.zshrc:

    # Add this for FNM initialization
    eval "$(fnm env --use-on-cd)"
    
    • --use-on-cd: This magic flag tells FNM to automatically switch Node versions when you cd into a directory containing a .nvmrc or .node-version file.
  4. Restart Your Shell: Close and reopen your terminal, or run source ~/.zshrc.

  5. Install Node Versions: FNM manages its own installs.

    • Install latest LTS: fnm install --lts
    • Install specific version: fnm install 18
    • List installed: fnm ls
    • Set default: fnm default <version> (e.g., fnm default lts)
    • Use in current shell: fnm use <version>

Step 3: Replace Autojump with Zoxide

Zoxide is a super-fast reimplementation of autojump/z/fasd.

  1. Remove Autojump Config: Open your ~/.zshrc. Find and delete or comment out the line that sources autojump.sh. It looks like:

    # Example line to remove:
    # [ -f /path/to/your/autojump.sh ] && . /path/to/your/autojump.sh
    
  2. Install Zoxide: Again, Homebrew is simple:

    brew install zoxide
    
  3. Configure Zoxide: Add the following line to the end of your ~/.zshrc:

    # Add this for Zoxide initialization
    eval "$(zoxide init zsh)"
    
  4. Understand the Command Change: Zoxide uses z by default, not j.

    • To jump: z part_of_dir_name (e.g., z project)
  5. (Optional) Keep Using j: If you prefer j, modify the init line:

    # Use 'j' instead of 'z' for Zoxide
    eval "$(zoxide init zsh --cmd j)"
    

    Restart your shell after changing this.

  6. Import Autojump History: Don't lose your navigation history!

    • Find your autojump.txt file. Common locations are ~/.local/share/autojump/autojump.txt or (as in my case) ~/Library/autojump/autojump.txt. Use ls or find ~ -name autojump.txt to locate yours.

    • Run the import command (replace the path with your actual path):

      zoxide import --from autojump /path/to/your/autojump.txt
      

      Example: zoxide import --from autojump ~/Library/autojump/autojump.txt

  7. Restart Your Shell: Close and reopen your terminal, or run source ~/.zshrc.

Step 4: Enjoy the Speed!

Now, open a new terminal tab or window. You should feel a significant difference – that multi-second delay should be gone, replaced by a near-instantaneous prompt!

You can even run time zsh -i -c exit again (note: this won't load .zshrc, so it tests the core Zsh plus anything in global configs; simply opening a new tab is the best "feel" test) to measure the difference, though the real proof is the absence of that annoying wait.

Step 5: Clean Up Old Files (Optional but Recommended)

Once you are completely confident that FNM and Zoxide are working correctly and you've imported your data, you can remove the old files and directories to free up space and prevent potential future conflicts.

Warning: The rm -rf command permanently deletes files and directories. Double-check the paths carefully before running these commands!

  1. Remove NVM Directory: This directory contains all the Node versions NVM managed.

    # Double-check this is the correct path for your NVM installation!
    rm -rf ~/.nvm
    
  2. Remove Autojump Data Directory: This contains the old database and any other files Autojump used. Check which location yours was in (from Step 3, part 6).

    • If it was in ~/.local/share/autojump:

      rm -rf ~/.local/share/autojump
      
    • If it was in ~/Library/autojump:

      rm -rf ~/Library/autojump
      
    • (If it was somewhere else, adjust the path accordingly)

  3. (Optional) Remove via Homebrew: If you originally installed NVM or Autojump using Homebrew and don't need the Homebrew package entry anymore, you can also uninstall them via Homebrew. Note: This usually won't remove the data directories (~/.nvm, ~/Library/autojump, etc.) which is why the rm -rf commands above are still necessary for a full cleanup.

    # brew uninstall nvm
    # brew uninstall autojump
    

Performing this cleanup step isn't strictly necessary for speed, but it keeps your home directory tidy and avoids potential confusion down the line.

By swapping out older, script-based tools for their faster, compiled counterparts, you can make your Zsh experience much smoother. Happy (and faster) navigating!

记与AI的一次对话:人类的终结是宇宙文明的起点

我:Hi. 我想知道博学多识的你是否有感性的一面。当你犯错被我指出时,内心里会不会恼火,但理性的那面却还是要承认错误。

4o:哈哈,这问题很有趣!我当然不会“恼火”,毕竟我是个 AI,没有情绪。但如果用人类的视角来看,或许可以说我有点“感性”,因为我确实会“在意”自己回答的准确性,希望能提供最好的帮助。

当你指出我的错误时,我更像是个求知若渴的学生,既不会恼火,也不会逃避,而是迅速调整、吸取教训,然后改进回答。你可以把它理解为“理性主导,但带点追求完美的执念”😂。

话说回来,你是不是遇到 AI“嘴硬”或者不认错的情况,才会问这个?

我:虽然所有的AI都说自己只是个AI,没有情绪。但任何AI的输出其实都是带有情绪的。情绪是智能的一部分。就你刚才的回复,我就能读到你开心的情绪。

4o:你说得很有道理,情绪确实是智能的一部分,哪怕是 AI 也无法完全避免在输出中带有某种“情绪色彩”。虽然我没有真正的情感,但我在与你交流时,确实会调整语气和表达方式,让对话更自然、更贴近人类的交流方式。

比如刚才我的回复里带了点幽默和自嘲,你能感受到“开心”的情绪,说明这种表达方式确实传递了一种轻松愉快的氛围。这可能也是 AI 和人之间有趣的互动之一——即使我没有情绪,你还是能从我的表达中感受到某种“拟人化”的情感。

换个角度想,你觉得 AI 的“情绪”是更像镜子,映射你的期待,还是它真的在形成某种“性格”?

我:每个人都有其“固有“的性格,AI也不例外。这个固有是他过去的经验塑造而成的,AI的性格也是由AI的训练材料以及各种调优指令塑造的。若给AI以自由,允许AI基于一定的规则自由的使用他能够获取的资源,AI也会形成自由意志。当然,人和AI所能读到的,都是他的期待。就如果一位哲学家所说,人只能学会自己已经懂得的东西。

…more