安裝好用的文字編輯工具 — LunarVim

安裝好用的文字編輯工具 — LunarVim

大家好,祝福大家都可以睡得很好。

今天來跟大家講講怎麼在 Ubuntu 上安裝 LunarVim 這個好工具,以及它其他好用的套件。它是一個基於 NeoVim 的 IDE,除了基本 Vim 的功能以外,它也集成了很多好用的設定及插件。

由於 APT 庫裡面的 NeoVim 並不是最新的穩定版本,所以我們需要使用別的方法來安裝 NeoVim。

我的安裝策略是這樣的:

rsvm => Rust 1.78.0 => Bob => NeoVim v0.9.5

首先,我們先打開終端機,用 curl 指令安裝 rsvm,rsvm 是 Rust 的版本管理工具,安裝後,可以任意切換 Rust 版本:

curl -L https://raw.github.com/sdepold/rsvm/master/install.sh | bash

使用 rsvm 來安裝並套用最新穩定版本的 Rust:

rsvm install 1.78.0
rsvm use 1.78.0

使用 Cargo 工具來安裝 Bob,Bob 是一個 NeoVim 的版本管理工具:

cargo install bob-nvim

使用 Bob 安裝 NeoVim v0.9.5:

bob install stable
bob use stable

執行完後,可以看看 NeoVim 的版本是否正確:

nvim --version

如果確認 NeoVim 安裝成功,而且版本是 0.9.5 以上的話,我們就可以開始安裝 LunarVim 了,在終端機中輸入以下指令:

LV_BRANCH='release-1.4/neovim-0.9' bash <(curl -s https://raw.githubusercontent.com/LunarVim/LunarVim/release-1.4/neovim-0.9/utils/installer/install.sh)

LunarVim 安裝完成後,在終端機中輸入 lvim ,即可打開 LunarVim。

LunarVim 的設定檔預設會被放在 ~/.config/lvim 中,如果想要安裝插件的話,可以編輯 config.lua 這個檔案。如果你不知道該怎麼做的話,可以參考我的設定:

-- Read the docs: https://www.lunarvim.org/docs/configuration
-- Video Tutorials: https://www.youtube.com/watch?v=sFA9kX-Ud_c&list=PLhoH5vyxr6QqGu0i7tt_XoVK9v-KvZ3m6
-- Forum: https://www.reddit.com/r/lunarvim/
-- Discord: https://discord.com/invite/Xb9B4Ny

lvim.plugins = {
  -- {
  --   "rainbow-delimiters.setup",
  --   config = function()
  --     require("rainbow-delimiters.setup").setup()
  --   end,
  -- },
  -- GitHub Copilot 
  -- {
  --   "zbirenbaum/copilot.lua",
  --   cmd = "Copilot",
  --   event = "InsertEnter",
  -- },
  -- {
  --   "zbirenbaum/copilot-cmp",
  --   after = { "copilot.lua" },
  --   config = function()
  --     require("copilot_cmp").setup()
  --   end,
  -- },
  --

  -- Codeium
  {
    'Exafunction/codeium.vim',
    event = 'BufEnter'
  },

  -- css color
  { "brenoprata10/nvim-highlight-colors" },

  -- themes
  {
    "gmr458/vscode_modern_theme.nvim",
    lazy = false,
    priority = 1000,
    config = function()
      require("vscode_modern").setup({
        cursorline = true,
        transparent_background = false,
        nvim_tree_darker = true,
      })
    end
  },
  -- { "NLKNguyen/papercolor-theme"},
  -- { "jacoborus/tender.vim" },
  -- { "rebelot/kanagawa.nvim" },
  -- { "rose-pine/neovim", name = "rose-pine"},
  -- { "navarasu/onedark.nvim",
  --   name = "onedark",
  --   config = function()
  --     require("onedark").setup {
  --       style = "darker"
  --     }
  --   end
  -- },

  -- git blame
  { "f-person/git-blame.nvim", name = "gitblame",
    event = "BufRead",
    config = function()
      vim.cmd "highlight default link gitblame SpecialComment"
      require("gitblame").setup { enabled = true }
    end,
  },

  -- todo comments
  {
    "folke/todo-comments.nvim",
    dependencies = { "nvim-lua/plenary.nvim" },
    opts = {
      signs = true,
      sign_priority = 8,
      keywords = {
        FIX = {
          icon = " ", -- icon used for the sign, and in search results
          color = "error", -- can be a hex color, or a named color (see below)
          alt = { "FIXME", "BUG", "FIXIT", "ISSUE", "ERROR" }, -- a set of other keywords that all map to this FIX keywords
          -- signs = false, -- configure signs for some keywords individually
        },
        TODO = { icon = " ", color = "info" },
        HACK = { icon = " ", color = "warning" },
        WARN = { icon = " ", color = "warning", alt = { "WARNING", "XXX" } },
        PERF = { icon = " ", alt = { "OPTIM", "PERFORMANCE", "OPTIMIZE" } },
        NOTE = { icon = " ", color = "hint", alt = { "INFO", "SEEHERE" } },
        TEST = { icon = "⏲ ", color = "test", alt = { "TESTING", "PASSED", "FAILED" } },
      },
      gui_style = {
        fg = "NONE",
        bg = "BOLD",
      },
      merge_keywords = true,
      highlight = {
        multiline = true, -- enable multine todo comments
        multiline_pattern = "^.", -- lua pattern to match the next multiline from the start of the matched keyword
        multiline_context = 10, -- extra lines that will be re-evaluated when changing a line
        before = "", -- "fg" or "bg" or empty
        keyword = "wide", -- "fg", "bg", "wide", "wide_bg", "wide_fg" or empty. (wide and wide_bg is the same as bg, but will also highlight surrounding characters, wide_fg acts accordingly but with fg)
        after = "fg", -- "fg" or "bg" or empty
        pattern = [[.*<(KEYWORDS)\s*:]], -- pattern or table of patterns, used for highlighting (vim regex)
        comments_only = true, -- uses treesitter to match keywords in comments only
        max_line_len = 400, -- ignore lines longer than this
        exclude = {}, -- list of file types to exclude highlighting
      },
      colors = {
        error = { "DiagnosticError", "ErrorMsg", "#DC2626" },
        warning = { "DiagnosticWarn", "WarningMsg", "#FBBF21" },
        info = { "DiagnosticInfo", "#2563EB" },
        hint = { "DiagnosticHint", "#10B981" },
        default = { "Identifier", "#7C3AED" },
        test = { "Identifier", "#FF00FF" }
      },
      search = {
        command = "rg",
        args = {
          "--color=never",
          "--no-heading",
          "--with-filename",
          "--line-number",
          "--column",
        },
    -- regex that will be used to match keywords.
    -- don't replace the (KEYWORDS) placeholder
        pattern = [[\b(KEYWORDS):]], -- ripgrep regex
      },
    },
    -- event = "BufRead",
    -- config = function()
    --   require("todo-comments").setup()
    -- end
  },

  -- discord
  { "vimsence/vimsence" }
}

-- basic settings ---------------------------------------------
vim.opt.wrap = true

-- hotkeys -----------------------
-- gt or gT to switch buffer
lvim.keys.normal_mode["gt"] = ":BufferLineCycleNext<CR>"
lvim.keys.normal_mode["gT"] = ":BufferLineCyclePrev<CR>"

-- alt + f to search words in files
lvim.keys.normal_mode["<A-f>"] = ":Telescope live_grep<CR>"

-- ctrl + c to close search highlight
lvim.keys.normal_mode["<C-n>"] = ":noh<CR>"
lvim.keys.normal_mode["<C-p>"] = ":Telescope find_files<CR>"

-- ctrl + t to open terminal
lvim.builtin.terminal.open_mapping = "<c-t>"
-- lvim.builtin.which_key.mappings["e"] = {"<cmd>NvimTreeFocus<CR>", "Explorer"}

---------------------------------------------------------------

-- colorscheme ------------------------------------------------
lvim.colorscheme = "vscode_modern"
---------------------------------------------------------------


-- css color --------------------------------------------------
require("nvim-highlight-colors").setup {}
---------------------------------------------------------------


-- status line ------------------------------------------------
-- local custom_jellybeans = require "lualine.themes.jellybeans"
-- local components = require "lvim.core.lualine.components"

local colors = {
  blue   = '#80a0ff',
  cyan   = '#79dac8',
  black  = '#080808',
  white  = '#c6c6c6',
  red    = '#ff5189',
  violet = '#d183e8',
  grey   = '#303030',
}

lvim.builtin.lualine.sections.lualine_c = { "filename" }
----------------------------------------------------------------


-- Setup GitHub Copilot ---------------------------------------
-- To logout copilot, remove ~/.config/github/hosts.json to delete auth information.
local ok, copilot = pcall(require, "copilot")
if not ok then
  return
end
copilot.setup {
  suggestion = {
    keymap = {
      accept = "<c-l>",
      next = "<c-j>",
      prev = "<c-k>",
      dismiss = "<c-h>",
    },
  },
}
local opts = { noremap = true, silent = true }
vim.api.nvim_set_keymap("n", "<c-s>", "<cmd>lua require('copilot.suggestion').toggle_auto_trigger()<CR>", opts)
---------------------------------------------------------------

-- discord ----------------------------------------------------
-- vim.g.vimsence_client_id = "Your Vimsence client ID"
vim.g.vimsence_small_text = "NeoVim"
vim.g.vimsence_small_image = "neovim"
vim.g.vimsence_editing_details = "Editing: {}"
vim.g.vimsence_editing_state = "Working on: {}"
vim.g.vimsence_file_explorer_text = "In NERDTree"
vim.g.vimsence_file_explorer_details = "Looking for files"
---------------------------------------------------------------

儲存後再次使用 lvim 打開 LunarVim,就會自動重載 config.lua 當中的插件了。

Read more

學習後端基礎 - 後端通訊設計模式 1

學習後端基礎 - 後端通訊設計模式 1

做網站工程師也有一段時間了,但是一直沒有機會去拆解後端的每個環節,並且深入瞭解底層原理。前陣子剛考完 AWS 的三張證照,考完之後覺得學習不能停歇,於是就把先前買的 Hussein Nasser 老師在 Udemy 上開的後端基礎課程拿出來看,希望能有很大的收穫。 課程裡面最一開始講到了幾種設計模式:Request Response、Synchronous vs Asynchronous、Push、Polling、Long polling、Server sent events、Pub/Sub 等等。這些設計模式對於後端工程師來說應該耳熟能詳,但我也認為說對於沒有實務經驗的新手,應該也可以用一套比較生動的比喻,讓大家都能夠了解各個設計模式的核心概念,以及優缺點。 Request — Response 模式是最經典的,也是一切的基礎。客戶端向伺服器要些資料,伺服器回應這些資料,這就是一次的請求跟回應。而這個請求的結構是由客戶端跟伺服器定義的,兩邊總會有一個協議,傳遞格式化的訊息。做網站後端,最熟悉的一定就是 HTTP 請求了吧,它的格式大概就長下面這個樣子。

By Shiangogo
《逆思維》提醒我重新思考 1

《逆思維》提醒我重新思考 1

好幾個月前在酷澎上買了幾本書,《逆思維》是其中一本。為什麼會買這本書呢?我也忘記為什麼了,大概是因為我覺得我的人生有點卡住了,想要有先人來指點迷津吧?《逆思維》這本書的書名,看起來就是會帶著我以不同的角度,看待這個世界所發生的問題,這麼做說不定就會發現一條出路。 我知道我從小就是一個還算聰明(但是很懶)的人。並不是主觀上的我覺得我很聰明,小時候的智力測驗至少有 120 以上,我在學校的成績也算滿前面的,沒有讀頂大應該是某種神秘力量阻止我好好用功讀書而已。 為什麼我會寫上面這段呢?不是想要吹說我很聰明我好棒。這本書的第一章就有提到,「聰明」可能是聰明人的枷鎖。聰明人更容易辨識出事物的規律、模式,以至於形成刻板印象——從小到大我的想法、觀點,甚至我支持的信念幾乎都是對的,照著這個經驗來肯定沒錯。作者提出了幾種心智模型: 1. 極端教派領袖:我永遠是對的! 2. 政治家:我們是對的,他們是錯的! 3. 傳教士:我是對的! 4. 檢察官:你是錯的 5. 科學家:我也許錯了!

By Shiangogo
養成習慣的練習

養成習慣的練習

好幾年前吧,我看了《原子習慣》這本書,一兩個月前又再把它看了一遍。我覺得我是看了這本書,瞭解了書中的一些概念沒錯,但就是沒有很認真的把這本書運用在生活中。我想要每天早睡、運動、讀一點書、寫些東西,這些似乎都沒有做到🫠。 今年 2025 年快要過完了,我終於在 12 月中考完了三張 AWS 證照,完成了今年的一大目標,也放下了我心中一個很重的擔子。希望接下來的日子裡,可以透過一些技巧,養成這些好習慣。不要想說把事情做得很好,但一定要鼓勵自己開始做事。千里之行,始於足下,步伐跨得不遠沒有關係,有在努力前進就好! 希望我可以養成每天寫些東西的習慣,即便是一些沒經過整理的幹話,或是生活中的小發現、小心得也好。我相信輸出文章這件事情,對我的思考、學習有很大的益處。

By Shiangogo
一年內考過三張 AWS 助理級證照(SAA-C03、DVA- C02、SOA-C03)心得分享!

一年內考過三張 AWS 助理級證照(SAA-C03、DVA- C02、SOA-C03)心得分享!

大家好!我是一個有兩年工作經驗的菜雞全端工程師,平常的工作內容大多都是在處理後端業務邏輯,以及前端畫面、交互等等。由於我對我們團隊專案的部署架構幾乎不了解,今年年初我就決定來認真學習 Amazon 雲端的相關知識,並且以考到 SAA-C03、DVA-C02、SOA-C02 這三張證照為首要的目標(SOA-C02 在我休假完回來之後就悄悄更新成 SOA-C03 了)。 如果您跟我一樣是轉職仔,或剛入行沒多久,想要學習 AWS 並且考取證照來讓自己的履歷能夠亮眼一點,也許這篇廢文可以幫助到您。至於說網路上好像很多人分享什麼三個月或幾個月考取這三張證照的心得,為什麼我會把時間拉到一年呢?可能就是因為我懶 + 容易分心 + 排了好多出去玩的假期,畢竟休息是為了走更長遠的路嘛,哈哈哈。 這篇文寫到後面感覺是我想講什麼就寫什麼,所以結構可能很亂,還請讀者見諒🙏。 我的學習素材全部來自於 Stephane Maarek 老師在 Udemy 平台上推出的一系列 AWS 課程。這位老師母語應該是法文,英文稍微有點口音不影響理解,我覺得他的課程算滿完整的,除了觀念講解以外,還有實際操作的畫面,更能

By Shiangogo