pretty code

2025年4月28日 星期一

Add mouse menu on Windows

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\COMMAND_NAME\command]
@="C:\\ABC\\abc.exe %1"

[HKEY_CLASSES_ROOT\directory\background\shell\COMMAND_NAME\command]
@="EXE_PATH ."

2025年4月27日 星期日

My simple netrw plugin

自己寫 Netrw 果然還是有點勉強XD


上面是一個簡單針對 BufEnter Event 的函數。

為了讓他像是一個檔案總管,其實還有很多事要做。

比如說:

set nu!
set nowrap
針對檔案總管顯示顏色
原本使用者設定的 vimrc 裡面的東西要回復

族繁不及備載

至少開始有點感覺了…

2025年4月26日 星期六

快速 parsing 檔案

以前需要臨時對檔案 parsing,一般來說我都會選擇 C 語言,因為這是唯一一個我不需要 google 就可以寫完的程式。

年紀大了還要編譯有點懶,再加上需要做這件事的時候,往往還需要搭配 regex。思來想去,想用一個簡單一點,語法好記的語言,於是便決定以後就用 Tcl 了。

bash script 好是好,但是速度有點慢,不知道是不是我剛沒寫好的關係?

set input "c:\\Vim\\vim91\\autoload\\netrw.vim"

set infile [open $input r]
fconfigure $infile -encoding utf-8

set func_pattern {^fun(\s|!)+ (.*)\s*\(.*}
set end_func_pattern {^endfun}

while {[gets $infile line] >= 0} {
    if {[regexp $func_pattern $line >= null f_name]} {

    } elseif {[regexp $end_func_pattern $line]} {
    
    } elseif {[string first "winrestview" $line] != -1} {
    
    }
}

剛剛希望找到 Netrw 所有呼叫 winrestview 回復 cursor position 的地方,很可惜,確認了幾個地方,但都不是對的地方,我到現在還找不到開啟右邊視窗後,回到原本 Netrw 瀏覽視窗的地方,到底是哪個函數破壞了我自己回存 position 的意圖?


我甚至把所有的 winrestview 都註解了,還是解不掉這個行為,我開始懷疑我的方向錯了?

2025/04/26 晚上更新


想要把之前註解掉的語句回復,使用上面 Tcl 語法,遇到 UTF-8 編碼,還是有少數幾句會有問題,這個問題先記錄起來,以後有空再回來確認。

後來想到可以使用巨集來回復,只要先設定 set nowrapscan,不要讓搜尋從頭開始,這樣就可以設定下面巨集了。ˊ

01. / winrestview 先 trigger search
02. gg 回到第一列
03. qq 開始記錄
04. n^x<ESC>j
05. q 停止紀錄
06. 100@q 執行 100 次巨集,數字要比所有的 winrestview 次數還要多。

04 巨集最重要的是最後面的 j 也就是跳到下一列,這樣按下 n 才會往下一個 winrestview 前進。

2025/04/27 更新

既然 Vim 巨集這麼好用,今天一口氣在每個函數入口加上 echom function_name 的功能,但居然都不是呼叫 winrestview 的函數被觸發而是 s:NetrwInsureWinVars。

現在只能猜測是 Netrw 有去動 buffer 或是什麼我不知道的東西?

有時在想,自己寫一個 directory explorer plugin 會不會比較簡單?

Tcl global error

之前用 Go 重寫 tool 時,改由自己得到 Top module name,不再從 command line arg 取得。

覺得這樣也蠻方便的,故將 Tcl code 也比照辦理。

由於之前的 Tcl code 遞迴用很深,故我很多參數都是拉出來變成全域變數,就只是忘了在 proc 中加上 global var 宣告,害我昨天找了老半天XD

2025年4月22日 星期二

又回來 Golang 的世界了

花了兩天時間,將之前使用 Tcl + bash script + grep + sed 寫的工具,改用 Golang 重寫。

這一年來已經習慣了 script 的 free Coding 過程,突然回到編譯型語言,還真是有些彆扭XD

距離上一個使用 Golang 開發的專案,也有三年了吧?

不過,編譯型語言還是有好處的,比如一個原本要 54 秒的 netlist 相關報表,現在只要 15 秒即可搞定(之前慢是慢在 bash script,不是 Tcl)。

Golang 還有一個額外的好處就是很容易跨平台編譯,比如我在 Windows 就可以編譯出 Linux 上跑的 ELF 執行檔。

今天在電腦的 WSL2 環境,想要驗證一下功能是否正常,突然發現,原本上面那個例子,居然要跑到 200 秒?

我連 pprof 都用上了,但還是只能看到問題是出在 System Call 上,中間一度還懷疑到我有一個很大的 struct 變數,在遞迴函數裡並不是傳遞 pointer 的緣故!

也懷疑是否是用了大量的 fmt.Sprintf 導致!

最後看到一篇文章,才發現是檔案系統的問題,但我不太確定是 NTFS 的鍋還是 WSL2 + NTFS 的鍋就是了?

總之,要在 Linux 跑程式,還是要使用 Linux 相關的檔案系統比較不會有問題,尤其我的工具就是要寫一大堆跟 cell 有關的報表。

2025年4月17日 星期四

Declare function in Vim script

簡單來說,除了 map 指令呼叫的函數以外,我們都可以用 s: 來宣告函數是屬於 script 的,map 會用到的就是要用 <SID>。


至於我們要如何來 debug 我們寫的 Vim script 呢?

下斷點等太進階,C 語言的 print 大法簡單好用。

使用 echom 印出訊息,使用 :messages 看訊息,簡單搞定。

又或是先將 code 寫在獨立的檔案,使用 :source 直接執行,確定沒問題後再移植到 .vimrc。

官方建議將函數寫在 .vim/autoload 裡面而不是寫在 .vimrc,這樣的好處是不影響啟動速度,缺點是第一次用相關函數時需等待載入。

2025年4月16日 星期三

Vim 最後一哩路

陸續搞定了 netrw 的一些功能,寫了幾個函數來幫忙,終於對 Vim script 有點感覺了。


雖然回復 cursor 的方法還有點鳥,但目前找不到適合的 event 來監聽,只好勉強先用 Vimresized 頂著先,壞處就是要一個 count 來計算何時該清空變數。


總之,開啟檔案到右邊視窗會觸發第一次,關閉右邊視窗又會觸發第二次,所以當 count == 2 時,我才能放心清空此變數。

現在大概只差寫 Plugin 的經驗了XD

2025/04/17 更新


早上又多檢查了 winnr 的個數,避免開到第三個 Window 後,汙染了原本的 s:MK_sv 變數。

另外,Vimresized 之所以能成功的原因是因為當開了右邊的分割視窗後,此時原本的視窗左邊會長出 scrollbar,故才會有此 Event 的發生。

如果我們去調整 guioption,讓它永遠為空,Vimresized Event 就不再發生了,故我原本的 patch 就不起作用了。

2025/04/18 更新

原來也可以設定 g:netrw_fastbrowse = 2,這樣就不會每次重新抓取目錄列表而導致游標跑掉(離開原本開啟檔案那列),但第一次因為 Buffer 沒有東西,故還是會重刷。

用這個的好處是我可以設定 set guioptions-=L,強制左邊不會有 scrollbar,看起來比較好看。

如果用我原來的 BackToNetrwWindow,則是不能設定沒有左邊 scollbar,不然 Vimresized Event 會失效。

真是有一好沒兩好。

2025/05/12 更新

最後,還是用了自己寫的 netrw,除了工作站無法修改外,公司及家裡的電腦目前都是用自己的 netrw,還是自己的狗糧最好吃XD