Sunday, February 28, 2021

vim 的「搜尋」相關技巧

我研究了自己在 vim 裡的搜尋行為之後,發現了自己有兩個使用習慣,很明顯地沒有最佳化:

  • 有「無意義的反白高亮度顯示」,卻沒有關閉它。
  • 反覆搜尋同一個字串。
什麼是「無意義的反白高亮度顯示」呢?因為我有設定搜尋字串高亮度顯示,所以一旦我搜尋了 AAA,整個檔案裡所有的 AAA 字串都會變成『反白高亮度』。然而,當我按下 Enter 之後,也就意味著,我已經打算在某一個特定的 AAA 位置開始做編輯了。即使如此,這個時間點,『反白高亮度』卻不會自動消失,有時到達甚至造成干擾的程度。這時候,應該下的指令是 :noh ,這樣一來,就可以順利地關閉反白高亮度。

什麼時候會反覆搜尋同一字串呢?這個低效率的行為常發生在開發程式時,有時候要寫第 50 行的地方,卻需要同時參考第 15, 75, 95 行這三處的寫法。由於行號是會變動的,所以我通常是去記下某一行的關鍵字,比方說,第 15 行有一個關鍵詞是 upload ,我就透過搜尋 upload ,如此就可以從其它地方很快地回到該行。

上述的作法是很低效率的習慣。相對有效率的作法則是,使用 vim 的 marks 功能。比方說,如果我需要之後回到第 15 行的話,我就在該地方,先下個指令 ma ,讓 a 這個 mark 記住該位置。之後,如果我要回到那一行時,我只要下 `a ,就可以快速地回到 a mark 的位置。

Wednesday, February 24, 2021

vim 查找關鍵字/函數引用 vs 開啟多重檔案

vim 有兩組功能,我覺得很適合一起使用

  • 查找關鍵字/函數引用
  • 開啟多重檔案

查找關鍵字的功能,我是安裝 ack.vim 。設定好之後,就可以下 :Ack 指令來找。有比對到關鍵字的檔案,就會在 Quickfix List 裡列出,而且可以用上下鍵來選擇開啟。於是,這時候下列的一組 Quickfix List 專用的指令,就值得記憶了。

搭配指令
:copen                  =>  打開 Quickfix 窗口,顯示所有結果
:cclose, :ccl           =>  關閉 Quickfix 窗口

如果 vim 配合 language server protocol 來使用的話,可以有查找「函數引用」的功能,我使用的 vim plugin 會將函數引用列在 Location list 裡。於是,這時候下列的一組 Location List 專用的指令,就值得記憶了。

搭配指令
:lopen                  =>  打開 Location 窗口,顯示所有結果
:lclose, :lcl            =>  關閉 Location 窗口

上述的功能,就很容易開啟許多的 buffers (即開啟後正在編輯的檔案),於是我們如果想要看到,現在開啟了哪些 buffers ,就可以下 :ls 來看,目前有哪些檔案被開啟。

搭配指令
:ls                          => 看有哪些檔案被開啟成為 buffer
:b [數字id]               => 顯示對應該 id 的檔案
:e [檔名]                  => 開啟特定檔案 
:bd                         => 關閉目前的 buffer

Monday, February 22, 2021

塑造工作 (ShapeUp)

我朋友很欣賞 37 signals 公司的工作哲學 ---「塑造工作」,推荐給我看。(37 signals 公司是間一流的 web application 公司)

該書對於軟體工作倡議的分工方式,我認為相當的有道理。杜拉克曾經有一篇文章探討如何提高知識工作者的產出? 該文提到了幾個重點:

 1. 界定任務

 2. 專注於核心工作

 3. 界定績效

 4. 管理者與知識工作者建立夥伴關系


杜拉克來自實務的觀察自然有其道理,但是,要怎麼應用在軟體開發上呢?對於軟體開發的實務來講,十次中有九次,往往都牽扯到未知的實驗與探索,換言之,軟體開發的實務之中,往往帶有一定的科學理論建構性質。有了未知性質的工作,任務難以界定;而邊界難以界定清楚的工作,績效又該如何界定呢?我在過往工作的經驗之中,往往只能使用「專注核心工作」的原則,對於其它三項原則,往往只聽樓梯響,不見人下樓。


塑造工作」一書提出的解決之道相當有特色:將團隊拆分成「資深團隊」與「循環團隊」。「資深團隊」負責塑造工作,塑造完成的工作,應該是已經將高風險與未知的部分移除、可以在 6 週之內完成的明確開發工作。塑造完成的工作,交給「循環團隊」去開發,而循環團隊的任務則是要在 6 週內完成開發任務。


從界定任務與績效的角度來看,資深團隊的任務是要正確地塑造工作。而循環團隊的工作則是準時地把塑造完成的工作加以交付。這正也符合了杜拉克說過的,「規畫」與「執行」應該分開來做。有了明確的任務界定,界定明確的績效也因此可能發生。(註:杜拉克同時也說:『分開來做,是指在不同的時間做,但是,不一定要交給不同的人來做。』)

從夥伴關系的角度來看,上述的資深團隊,一方面帶有中階管理階層的屬性,因為他們的任務要決定『去做什麼與不做什麼』。更重要的是,他們也是該領域中極為卓越的知識工作者,否則,勢必沒有足夠的能力,來為循環團隊塑造可以達成的工作。管理者與知識工作者兩個不同的身分放在同一個腦子裡,自然可以形成夥伴關系。

Tuesday, February 16, 2021

從 leiningen 換成 deps.edn

Clojure 的官方出了自己的 build tool 。老實說,我一直都覺得,比起 leiningen 來得沒有那麼容易上手。經過一些調整之後,總算是覺得還可以啦,就是多學一些東西嘛。主要有幾個需要調整的地方:

  • 如何生成新的 project ?
  • 如何產生 nREPL 的開發環境?
  • 如何在專案的資料夾之下做 grep 

第一個問題,我的解法是安裝 clj-new 這個 alias 。裝完之後,就可以用下列的指令來生成 project

clojure -X:new :name myname/myapp ;; 生成專案
cd myapp
clojure -M -m myname.myapp      ;; 啟動


第二個問題,我的解法是設定對應的 alias 。網路上我找到相對完整豐富的範例是 practicalli/clojure-deps-edn

第三個問題:我用 ack-grep 時,常常都會掃瞄一堆暫存檔,妨礙我取得關鍵的資訊。於是,我設定了 ack-grep 的 config ,直接設定不搜尋這些暫存檔。我的 .ackrc 如下

# Tips:
# using ack to show only the clojure files for further processing
# ack -f --clojure
#

--ignore-dir=resources
--ignore-dir=.shadow-cljs
--ignore-dir=.cpcache

減少不必要的 reflection

在 Clojure 與 Java 的交界處,會產生大量的 reflection 。這種時候,可以用 type hints 來減少不必要的 reflection 。有效的作法是開啟一個特定的變數,將它的值改成 true ,然後 Clojure compiler 就會產生 reflection warning ,讓我們可以在開發的時候,很清楚明確地知道「哪些地方產生了 reflection」,於是就可以針對這些地方,去加上 type hint 。

這個重要的變數是 *warn-on-reflection*

Clojure 程式開發的依賴注入

Clojure 的世界裡,常用的依賴注入 (dependency injection) 手法主要有五種:

  • 依賴注入應用於函數 (function) 
  • 依賴注入應用於命名空間 (namespace)
  • 依賴注入應用於攔截器 (interceptor)
  • 依賴注入應用於網站處理器 (web handler)
  • 依賴注入應用於 Java program 的物件工廠 (factory)

這五種手法都頗為重要:

  • 第一種非常的常見,可以算是基本的要求。
  • 第二種,在使用 REPL workflow 就會應用到,Luminus 搭配的 mount 就是例子。
  • 第三種可以提高程式碼的可讀性、可預測性。因為條件限制 (constraints) 多,可讀性就變好。通常是將 web handler 之後會依賴的 component 透過攔截器注入到 request 裡。
  • 第四種可以看成是第三種的變型:在生成 web handler 的時候,注入依賴。
  • 第五種則應用於 Clojure/Java interoperation 。當要利用 java library 的時候,有時候既有的 java library 有預留可以注入的 factory pattern 。這時候,如果覺得既有的 java library 不夠好用,想做一些微調整的話,就可以考慮使用 Clojure 的關鍵字 reify 去生成新的 factory 來給 java library 使用。於是,Clojure wrapper 包覆的 java library 就是有微調過的版本。

Mac 筆電的快捷鍵整理

由於新工作的資安規定,硬碟要加密,我決定全心全意地來改用 Mac book 。研究了一陣子之後,發現還真的滿多需要且值得記憶的:

1. 截圖類

cmd + shift + 3 --- screen shot 
cmd + shift + 4 --- screen shot with area
cmd + shift + 5 --- screen record 

2. Finder 類

cmd + <up>     --- 往上移一層資料夾
cmd + [           --- 回到前一個資料夾  // 同時也適用於 browser 
cmd + alt + L   --- 到「下載資料夾」    // 同時也適用於 browser

3. 文字編輯器

cmd + <left>      --- 移動到行首
cmd + <right>    --- 移動到行尾
cmd + <up>       --- 移動到文章首
cmd + <down>   --- 移動到文章尾
cmd + shift + T   --- 切換 .txt 與 .rtf  (存檔的格式)
cmd + T             --- 顯示字型
cmd + shift + C   --- 顯示色碼
cmd + V                  --- 貼上 with formatting
cmd + alt + shift + V --- 貼上 without formatting


4. 一般應用程式

cmd + <Comma>    --- 偏好設定
cmd + Q                --- 關閉應用程式


5. 移動類

fn + <up>      ---   Page Up
fn + <down>  ---   Page Down 
fn + <left>     ---   Home
fn + <right>   ---   End


6. 其它

cmd + <Space>       ---  Spotlight search
cmd + shift + ESC   --- 強制關閉應用程式
cmd + ctrl + Q        --- lock screen