安裝完 Godef 插件后,有些文件的代碼跳轉總是報下面的錯誤
=================[Godef]Begin=================
[Godef]INFO: using godef: C:\gopath\bin\godef.exe
[Godef]INFO: selcet_begin: 636 offset: 798
[Godef]INFO: spawning: C:\gopath\bin\godef.exe -f D:\development\go\go-example\src\example\test\net\httpserver\form\login.go -o 798
[Godef]ERROR: no definition found: b'godef: no identifier found\n'
=================[Godef] End =================
到底是 Godef.py 代碼中的輸入參數 offset 錯了呢?還是 godef.exe 解析出錯了呢?我琢磨了下,發現 Godef.py 中打印的 selcet_begin 就是 sublime 提供的光標所在的字符位置(一個中文字符算一個字符) - 在 sublime 用鼠標從文件起始位置選中拖到剛才光標的位置,所選中的區域總共的字符個數在左下腳狀態欄中會顯示出來。而 offset 是上面區域字符串的字節長度 (注意是字節不是字符,一個中文字符有多個字節)。下面是 Godef.py 計算 offset 的代碼。我就納悶了上面打印的 offset > selcet_begin ,計算出來的應該就是字節,沒有問題啊!而且 godef.exe 要求的參數肯定也是按字節計算的,因為有些帶有中文注釋的代碼也是可以正常跳轉的!
view = self.window.active_view()
filename = view.file_name()
select = view.sel()[0]
select_begin = select.begin()
select_before = sublime.Region(0, select_begin)
string_before = view.substr(select_before)
string_before.encode("utf-8")
buffer_before = bytearray(string_before, encoding="utf8")
offset = len(buffer_before)
print("[Godef]INFO: selcet_begin: %s offset: %s" %
(str(select_begin), str(offset)))
我使用notepad 打開該文件,發現用鼠標從文件起始位置選中拖到剛才光標的位置,notepad 狀態欄顯示的選中長度居然比上面的 offset 大,我再用這個值在命令行中執行 godef.exe ...\login.go -o xxx 命令,發現正確輸出了要跳轉的文件名和光標應所處的位置。看來是 Godef.py 插件提供的 offset 錯了導致的!
為什么會錯,我又細心的分析起這段文本,終於發現 notepad 顯示這段文本的換行符是 Dos\Windows (\r\n),意識到可能是換行符的問題,我把換行符轉為 unix 后,就可以正常跳轉了!也就是說 Godef.py 計算出的 offset 每一行少計算了一個 \r 字符!
我嘗試修改 Godef.py 代碼,但是發現這不是 Godef.py 的錯,可以肯定是 sublime text 提供的這個方法 view.substr() 方法把 windows 的換行符轉為了 unix 的換行符!我查了一下 sublime text 的 api ,寄希望於 Region 提供的一個 size() 方法,使用下面的代碼打印后發現返回的是字符的個數,看來此路不通。
print("[Godef]INFO: size:%d" % select_before.size())
好吧,那就把 windows 換行符轉換為 unix 換行符吧。好在 sublime 已經為我們提供了該功能,我修改了下 sublime text 下面的配置。在狀態欄右下腳就出現了換行符轉換的功能按鈕,點擊后轉換到 unix 即可!
"show_line_endings": true,
"default_line_ending": "unix"