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

2025年4月10日 星期四

Vim 內建 file tree view - Netrw

最近突然發現 Vim 內建的檔案總管,其實已經很夠用了,只要多設定下面幾個全域變數,臨時要瀏覽檔案還算行。

let g:netrw_keepdir = 0
let g:netrw_banner = 0
let g:netrw_winsize = 30
let g:netrw_browse_split = 3

雖然我可以拿到目前 Netrw 指到的檔案名稱,但不太確定要如何操作 Vim 的視窗還是緩衝區來達到 IDE 的介面?


沒關係,我已經比以前的我還進步了XD

不過還是改不了長久以來使用 UltraEdit 的習慣,即使知道快速鍵的使用,但還是很習慣使用方向鍵、delete、backspace。

目前也還沒養成習慣,不編輯時常保持在 Normal Mode。

2025/04/11 更新

今天終於看懂如何改 netrw 顏色了XD


我們只要知道 netrw 的 define 是什麼或是他 link 到那個。

比如說 netrwDir 是 link 到 Directory,故我可以直接改 Directory。

但是像 netrwExe 是 link 到 PreProc,這跟我 Coding 顏色相衝,故我重新定義一個 MKExe,改將 netrwExe link 到 MKExe 即可。

詳情可以參考 vim/syntax/netrw.vim。

2025/04/12 更新

原來 NERDTree 也還好,重點是速度比 netrw 慢(git bash on Windows)。

今天多加了一個視情況改變 statusline 的檢查,看起來舒服多了。


Vim 果然是編輯器之神!

2025/04/16 更新

加入自動增測 winwidth 功能,並可以開啟檔案到右邊視窗,回來也可以順利記住游標位置,目前總算有點樣子了。

2025年4月4日 星期五

Python 工匠案例、技巧與開發實戰

雖然我是很想直接用 Tcl 單幹寫出現在要寫的 EDA Flow Tool?

不過考量到之後可能要一起協同合作,還是使用最大公約數的 Python 語言?

個人不是寫 Python 的,於是便看了一本買了很久但還沒看的書,也就是如標題所述的書。

不得不說,只要幾百塊的金額,便可以學到原本沒接觸過的知識實在是很划算。

據我之前理解,要稱得上是 Python 進階使用者,大概要知道下面兩個技巧:

01. 生成式的使用
02. 裝飾器的使用

不過,我到現在一個都沒用過。

個人覺得只要能把程式用不同的函數來清楚表達,這樣就已經屌打很多人了XD

因此,我們需要一個方法來檢查我們的函數是否有達到上列目的,剛好這本書在函數這一章節,介紹了一個 package - radon,它可以給函數一個分數,這樣我們就知道函數是否可以改進?

之前做財委時,為了將新補上的歷史資料填上我 Excel 前面的總表分析 sheet,於是便用 Python 寫了一支程式,當然這支程式還有別的功能就是。

總之,目前程式碼為 469 行,下面是我執行 radon cc -s xxx.py 的結果。


從上面可以看到,我有 5 支函數稍嫌複雜,只拿到 B 的分數,原則上最好都拿到 A 的分數是比較好的。


在這 469 行的程式中,扣掉 main 用了 17 個函數,一個函數平均大概不會超過 50 行,即使這樣,也不能保證我每個函數都能拿到 A 的分數。


其中以 adjust_cell_format 最為明顯,雖然行數只有 23 行,但我這支函數拿到的分數最差。

正常來說,應該比照 columns,將對齊方式也用 list 記錄,這樣就可以少掉 42 行與 45 行的 if statement。

但要說這支函數不好懂嗎?我也不太確定,至少這個程式已經是一年多前寫的,當我需要新增功能時,回過頭來再看一次函數也不會有多大困難就是了。

在不斷的思考與自我對話中,程式設計之道也會越來越清楚吧?我想…