顯示具有 vim 標籤的文章。 顯示所有文章
顯示具有 vim 標籤的文章。 顯示所有文章

2018年6月15日 星期五

在 linux 下處理 windows/dos 格式的中文檔案

在 linux 下一般都是 utf8/unix 格式的編碼, 那處理中文 big5/windows/dos 格式時會遇到什麼問題?

會影響中文正確的程式很多, 這邊以我自己遇到的程式來說明:
  1. 終端機
  2. vim
  3. git/hg diff

我用的是 mate-terminal, 支援 utf8/big5 模式, 你一定猜想, 要正確看 windows/big5 檔案, 應該會需要切換到 big5 編碼吧, 答案 "是", 也 "不是", 要看你在終端機用什麼軟體看 windows/big5 檔案。

t1.txt 是一個 windows/big5 檔案, 內容是 "施逼\r\n"

cat
mate-terminal 使用 utf8
descent@debian64:~$ cat /tmp/t1.txt
�I�G

mate-terminal 使用 big5
descent@debian64:~$ cat /tmp/t1.txt
施逼
descent@debian64:~$

less
mate-terminal 使用 big5
less.txt
1
2 <AC>I<B9>G
3 /media/vbox_share/tmp/t1.txt (END)

mate-terminal 使用 utf8
less.txt
1
2 <AC>I<B9>G
3 /media/vbox_share/tmp/t1.txt (END)

mate-terminal 使用 big5
export LESSCHARSET=latin1
施逼
/media/vbox_share/tmp/t1.txt (END)

mate-terminal 使用 utf8
export LESSCHARSET=latin1
�I�G
/media/vbox_share/tmp/t1.txt (END)

git/hg diff 同 less

好了, 重頭戲 vim 來了, 有好幾個組合可以正確顯示 windows/big5 中文, 我要用的組合是:
mate-terminal 使用 utf8
~/.vimrc
set fileencodings=utf-8,big5,gb18030
encoding=utf-8
這樣 vim 就會將 t1.txt 用 big5 的編碼打開, 然後轉成 utf8 編碼, 而 termencoding 我沒有設定, 所以和 encoding 一樣是 utf8, 由於 mate-terminal 使用 utf8, 所以一切配合的很好, windows/big5 中文檔案正確顯示, 沒有亂碼。

如果 vim 誤判編碼的話, 使用 :e ++enc=big5, 會讓 vim 重新讀取檔案, 並以 fileencoding = big5 編碼開啟檔案。



使用 vim 寫入中文之後, 也會將這個中文從內部編碼 utf8 轉回原本的 big5 中文編碼, 用 windows notepad 開啟, 中文可以正常顯示。

locale 設定全都是 en_US.UTF-8, 沒有設定為 zh_tw.BIG5。
descent@debian64:tmp$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

vim 相關編碼設定請參考 ref 1。

另外一個問題是 \r \n, cr, lf 換行問題。

cr: \r, 0xd, ^M
lf: \n, 0xa

windows 用 \r\n 來表示換行, linux 用 \n 表示換行, mac 用 \r 表示換行。
vi 很貼心的會偵測檔案格式, 如果是 windows 格式, 會用 windows 換行存檔, 基本上沒什麼問題, 不過在使用 git diff 時, 就會看到多一個 ^M, 就是 cr, git 可以設定讓這些換行符號不當成差異顯示出來。

為什麼以我一個 linux 使用者會有機會遇到 windows/big5 中文檔案呢? 說來話長, 就不說了。

ref:
  1. VIM 教程/编码/乱码
  2. DOS 和Unix 文件--vim轉化
  3. 远程登录linux,使用vi和less查看文本出现中文乱码,使用cat正常
  4. 【详解】回车 换行 0x0D 0x0A CR LF \r \n的来龙去脉
  5. [VIM] encoding , fileencoding , and fileencodings



2016年8月19日 星期五

global/gtags with vim

應 l 君要求放上 DD 圖

vim + ctags + cscope 應該是查到爛的組合, 基本上是 linux 環境下 Source Insight 的替代品, 我使用 vim 多年, 從沒有把這組合技練成過, 只用過 ctags, 記住僅僅的 ctrl+], ctrl+t 兩個組合鍵, 在瀏覽程式碼就省下不少功夫, 可惜要 reference 那個 function 使用了那個變數/函式, 還是得靠 grep, 過了這麼多年, 終於可以靠 global 取代 ctags + cscope, 也不用改變 ctrl+], ctrl+t 這兩個組合鍵的使用習慣。

descent@u64:simple_compiler$ 
find . -name "*.h" -o -name "*.cpp" > gtags.files

cat gtags.files 
./token.h
./parser.h
./mytype.h
./astnode.h
./lexer.h
./op.h
./env.h
./env.cpp
./c_parser.cpp
./lexer.cpp
./op.cpp
./token.cpp
./astnode.cpp

$ gtags

建立 gtags.files 再按下 gtags (不用建立 gtags.files 也可以) 就會產生 tag 檔案了。

複製 gtags.vim (global 套件提供) 到 ~/.vim/plugin/, 在最後面加入 list 1 的 hot key 定義。最主要就是

:Gtags -s abc - 找誰用了 abc 這個函式
:Gtags -r xyz - 找誰用了 xyz 這個變數

list 1. ~/.vim/plugin/gtags.vim
451 map <C-n> :cn<CR>
452 map <C-p> :cp<CR>
455 nnoremap <C-\> :exec("Gtags -r ".expand("<cword>"))<cr>
456 nnoremap <C-m> :exec("Gtags -s ".expand("<cword>"))<cr>

在 ~/.vim/vimrc 加入 list 2 內容, 最主要是相容於 ctags 的 hot key, 原有的習慣就不用改變。

list 2. ~/.vim/vimrc
64 set cscopeprg=gtags-cscope
65 "set cs add GTAGS
66
67 let s:command = "cs add GTAGS"
68 exe s:command

在某個 function 按下 ctrl+], ctrl+t 一樣是原來 ctags 的功能, 然後在某個 function 按下, crtl+\, 神奇的事情就發生了, 會跳到用這個函式的地方 (如同 fig 1),然後 ctrl+n, ctrl+p 是上一個, 下一個。

如果是 symbaol (變數) 就用 ctrl+m, 沒問題吧 \ 是函式, m 是對付變數。如果不喜歡 \, m, 參考 list 1 改成自己喜歡的按鍵。

fig 1. eval 出現的地方

只要有這 4 個按鍵, 看 code 就輕鬆多了, 只要 4 個, 你不會記不住吧! 好吧! 你可能還需要 ctrl+w+up/down 來切換視窗, 會需要在多記住幾個按鍵。

感謝 irc l 君友情支援 vim script。

不過我沒搞定怎麼跳到 symbol definition, 所以現在還是搭配著 ctags 一起用, 實在是太蠢了。

這裡有個方便的 vim plugin, 不過我不會用, 才自己搞。
https://github.com/tranngocthachs/gtags-cscope-vim-plugin

ref:

2014年10月29日 星期三

vim 調 syntax 顏色

the 1st edition: 2011/11/16

註解的藍色太深了, 很不好看, 改這樣好多了。


~/.vimrc

hi Comment term=bold cterm=bold ctermfg=4 gui=bold guifg=Blue
hi PreProc term=standout ctermfg=Yellow guibg=Yellow

看來好多了。

:highlight

可以用來參考目前的顏色。

vim indent 只使用 space 不要使用 tab

the 1st edition: 20120514
the 2nd edition: 20141029

在 vim 下使用以下的 indent, 就不會插入 tab, 而是用空白來作 indent, 之前同事總是反應我的程式碼 indent 有點問題, 就是因為 tab 的關係。
set list 可以查看這些看不見的 character。
set nolist 隱藏這些看不見的 character。

set autoindent
set expandtab

有個後遺症, 那就是在按下 tab 鍵 vi 會使用 space 來代替, 在寫 makefile 會有問題。

:set shiftwidth=2 - indenting is 4 spaces
>> 用在 indent 程式碼時增加空白。

https://www.cs.oberlin.edu/~kuperman/help/vim/indenting.html

Format a code block
以下 2 個 hotkey 還不錯用。

  • =
  • =i{
ref: