2024年6月28日 星期五

vim 使用筆記

模式 (mode)

一開始認識 vim就要先了解其不同的模式:

  • 普通模式 (Normal Mode)
  • 插入模式 (Insert Mode)
  • 命令列模式 (Command Line Mode)
  • 可視模式 (Visual Mode)

其中最常用是一般模式 (Normal Mode)、插入模式 (Insert Mode)及命令列模式 (Command Line Mode)。一開始進入 vim時的模式為普通模式, 其他模式都要經過普通模式進入,透過 Esc鍵返回。

普通模式 (Normal Mode)


游標移動
h or [←]游標向左移動一個字元
j or [↓]游標向下移動一個字元
k or [↑]游標向上移動一個字元
l or [→]游標向右移動一個字元
可以在指令前加上要執行指令的次數,例如 20l or 20[→],就可以往右移動 20個字元。
[Ctrl] + b or [PgUp]向上移動一頁 (backward)
[Ctrl] + f or [PgDn]向下移動一頁 (forward)
[Ctrl] + u 向上移動半頁 (upward)
[Ctrl] + d 向下移動半頁 (downward)
0 or [Home] 移動到此列的起始位置
$ or [End] 移動到此列最後面非空字元
^ 移動到此列最前面非空字元
+ 移動到下一列最前面的非空字元
- 移動到上一列最前面的非空字元
gg 移動到檔案的第一行
G 移動到檔案的最後一行
{number}G 可以移動到第 {number}行,例如 20G,可以移動到檔案第 20行
H 移動到目前顯示的第一行首字元
M 移動到目前顯示的中間一行首字元
L 移動到目前顯示的最後一行首字元
[Space] 向右移動一個字元
[Enter] 移動到下一行
{number}[Space]可以向右移動 {number}個字元,與[→]不同的是,[Space]會移動到下一行。 {number}[Enter]可以向下移動 {number}行。

搜尋與取代
/{string}向後搜尋 {string}字串
?{string}向前搜尋 {string}字串
n執行上一個搜尋操作
N反向執行上一個搜尋操作
s/{string1}/{string2}/g將此行的 {string1}取代成 {string2}
%s/{string1}/{string2}/g將檔案裡的 {string1}取代成 {string2}
%s/{string1}/{string2}/gc將檔案裡的 {string1}取代成 {string2},取代前需要確認

編輯
x刪除游標後面的字元
X刪除游標前面的字元
dd刪除游標所在的這一行
{number}X及 {number}x可以刪除游標前、後 {number}個字元。 {number}dd可以刪除游標往下 {number}行。
d1G刪除游標到第一行中的內容
dG刪除游標到最後一行的內容
d0刪除游標前的這一行的內容
d$刪除游標後的這一行的內容
yy複製游標所在的這一行 (yank)
{number}yy可以複製游標往下 {number}行。
y1G複製游標到第一行中的內容
yG複製游標到最後一行的內容
y0複製游標前的這一行的內容
y$複製游標後的這一行的內容
p在游標的後一行貼上
P在游標的前一行貼上
J將此行與下一行合成同一行
u回到上一個操作的狀態 (undo)
[Ctrl] + r回到下一個操作的狀態 (redo)
.重複上一個操作

插入模式 (Insert Mode)


進入插入模式
i在游標字元處前插入 (insert)
I從此行第一個非空字元前插入
a在游標字元處後插入 (append)
A從此行最後字元後插入
o插入新的下面一行 (open)
O插入新的上面一行
r進入取代模式,只取代一個字元 (replace)
R進入取代模式,直到離開

命令列模式 (Command Line Mode)


Command Line Mode指令
:w儲存目前檔案變更 (write)
:q離開 vim (quit)
:w!可以強制寫入唯讀檔案。:q!可以強制不儲存離開。
:wq儲存並離開
ZZ若檔案沒有修改,直接離開。若檔案有修改,儲存並離開
:w {filename}將檔案另存到 {filename}
:r {filename}將另外一個檔案的內容加到游標位置的下一行
:! {command}暫時離開 vim並執行 {command}
vim 可以同時打開多個檔案進行編輯。ex: vim a.txt b.txt。
:files列出目前 vim所開啟的檔案
:n編輯下一個檔案
:N編輯上一個檔案

可視模式 (Visual Mode)


Visual Mode指令
v將游標經過的字元反白選擇
V將游標經過的行反白選擇
[Ctrl + v]以blcok的方式進行反白選擇
y複製選擇的內容
d刪除選擇的內容
p貼上選擇的內容

參考連結:
鳥哥私房菜 第九章、vim程式編輯器

2024年6月2日 星期日

[Python] threading

在閱讀關於 python multi-thread(多執行緒)、multi-process(多行程)及GIL的相關文章時,突然想到在公司寫的一個 script。 這 script需要使用同個 api發送不同參數的HTTP request,一開始的寫法是使用 for loop來執行,等到 request結束,再執行下一個。

由於每個 request需要幾十秒才會完成,所以整個 sciprt跑完就要花費好幾分鐘。如果能改寫成 使用 multi-thread的方式來發送 request,就能省下大量的時間。因為 GIL的關係,同時間只會 有一個 thread在執行,但以這 case來說已經很夠用了。

以下是要修改的 sample code,使用 for loop來執行 20次的 request:

import requests

def do_request(url):
    response = requests.get(url)
    print(response.status_code)
    return response

if __name__ == '__main__':
    for i in range(0, 20):
        ret = do_request("https://api.github.com")
        print (ret.json())

使用 python threading來改寫:

import requests
import threading

def do_request(url):
    response = requests.get(url)
    print(response.status_code)
    return response

if __name__ == '__main__':
    thread_list = []
    for i in range(0, 20):
        t = threading.Thread(target=do_request, args=("https://api.github.com",))
        thread_list.append(t)
        t.start()

    for t in thread_list:
        t.join()


宣告 Thread


t = threading.Thread(target=do_request, args=("https://api.github.com",))

建立一個 Thread物件,將要使用 threads來執行的 function傳入 target,並把 target所需要的引數以 tuple的形式傳入 args。


啟動 Thread


t.start()

透過呼叫 start來啟動此 thread。


等待 Thread執行完成


t.join()

使用 join來等待此 thread結束。這裡使用 for loop來等待所有的 thread結束。 若沒有使用 join,thread可能會在主程式後才執行完成。


獲得 Thread的返回值

上面的程式碼雖然可以讓函式使用 thread的方式執行,卻沒辦法得到函式的返回值。其中一個解法是將函式改寫,使其將返回值存到 list中。

import requests
import threading

def do_request(url, index, response_list):
    response = requests.get(url)
    print(response.status_code)
    response_list[index] = response

if __name__ == '__main__':
    thread_list = []
    response_list = [None] * len(range(0, 20))
    for i in range(0, 20):
        t = threading.Thread(target=do_request, args=("https://api.github.com", i, response_list))
        thread_list.append(t)
        t.start()

    for t in thread_list:
        t.join()

    print(response_list)

參考資料:
https://docs.python.org/zh-tw/3/library/threading.html
https://realpython.com/intro-to-python-threading/