# 練習 50:`vi`
> 原文:[Exercise 50: vi](https://learncodethehardway.org/more-python-book/ex50.html)
> 譯者:[飛龍](https://github.com/wizardforcel)
> 協議:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
> 自豪地采用[谷歌翻譯](https://translate.google.cn/)
你有一個模塊,實現了`ed`和`sed`中使用的功能。顯然,下一步是實現世界歷史上最討厭和實用的文本編輯器:`vi`。如果你知道 Lisp 可以實現 Emacs,但沒有人有時間創建一個偽裝成文本編輯器的全新操作系統。人生苦短,不能整天按住三個按鍵并敲擊 TAB 鍵。
這個練習的目的不是做一個非常精確的`vi`的副本。這是一個非常大的項目,但如果你想嘗試它,那么就去做吧。你這個項目中的目標是,再次復用你的`ed`模塊,并玩轉 Python 的 [`curse`](https://docs.python.org/2/howto/curses.html) 模塊。`curse`模塊讓你處理舊式的文本終端窗口和圖形操作。實際上“圖形”應該加引號,因為`curse`中的實際圖形很少。
你將使用`curse`來創建一個低級的`vi`實現,它可以打開文件,使用模塊運行`ed`和`sed`命令,并使用`curse`將其顯示到終端屏幕。你也會發現,嘗試自動化測試它是非常困難的。如果你能弄清楚如何做一個假的`curse`測試框架,你會得到附加分,但是這將需要 Unix pty 系統的一些魔術技巧(我認為)。
使其可測試的更好方法是,將盡可能多的`vi`放入 Python 模塊,以便你可以測試代碼,而無需運行`curses`屏幕系統。當我說“模塊”時,我并不意味著一個完整的 Python 模塊,像使用`ed`模塊一樣,你可以使用`pip`安裝它。我的意思是`vi`的代碼中的模塊,然后導入到你的項目中。
思考這個項目的方法是,將控制視圖(`curses`)的代碼與其余代碼分開,以便你可以插入自己的假視圖來測試。之后還剩下少量的功能,你可以通過實際運行你的`vi`來手動測試。
## 挑戰練習
我們不會實現整個`vi`。我需要把它說清楚,因為實際的`vi`是舊的,非常復雜,所以實現一個完整的“代碼大師副本”將需要很長時間。你實際上只做以下事情:
+ 獲取你的`ed`模塊。
+ 為其創建一個`curses`UI。
+ 使其在多個文件上工作。
這或多或少是你正在做的事情,所以你應該關注的第一件事是,`curses`如何工作。閱讀`curses`的文檔,來了解它的工作原理,并根據需要編寫盡可能多的測試來了解它。
一旦你掌握了`curses`,你就需要學習如何使用`vi`。我為這個練習包括一個`vi`速成課,你可以觀看它,還有幾個可以在線參考的`vi`速查表。我建議你看我的`vi`教程,并且在這個會話期間,嘗試使用真正的`vi`來編輯代碼。實際上從你的`ed`和`sed`的實現中,你可以了解`vi`如何工作。理論上,`vi`僅僅是圖形化的`ed`,所以你幾乎只是向`ed`提供一個更好的 UI。
## 研究性學習
+ 你的`ed`實現中的有限狀態機,如何與這個`vi`實現中的東西相匹配?假設你使用了這個設計。
+ 實現 GUI 版本而不是`curses`,有多難?我不建議你這樣做,但研究它,看看它需要什么。
- 笨辦法學 Python · 續 中文版
- 引言
- 第一部分:預備知識
- 練習 0:起步
- 練習 1:流程
- 練習 2:創造力
- 練習 3:質量
- 第二部分:簡單的黑魔法
- 練習 4:處理命令行參數
- 練習 5:cat
- 練習 6:find
- 練習 7:grep
- 練習 8:cut
- 練習 9:sed
- 練習 10:sort
- 練習 11:uniq
- 練習 12:復習
- 第三部分:數據結構
- 練習 13:單鏈表
- 練習 14:雙鏈表
- 練習 15:棧和隊列
- 練習 16:冒泡、快速和歸并排序
- 練習 17:字典
- 練習 18:性能測量
- 練習 19:改善性能
- 練習 20:二叉搜索樹
- 練習 21:二分搜索
- 練習 22:后綴數組
- 練習 23:三叉搜索樹
- 練習 24:URL 快速路由
- 第四部分:進階項目
- 練習 25:xargs
- 練習 26:hexdump
- 練習 27:tr
- 練習 28:sh
- 練習 29:diff和patch
- 第五部分:文本解析
- 練習 30:有限狀態機
- 練習 31:正則表達式
- 練習 32:掃描器
- 練習 33:解析器
- 練習 34:分析器
- 練習 35:解釋器
- 練習 36:簡單的計算器
- 練習 37:小型 BASIC
- 第六部分:SQL 和對象關系映射
- 練習 38:SQL 簡介
- 練習 39:SQL 創建
- 練習 40:SQL 讀取
- 練習 41:SQL 更新
- 練習 42:SQL 刪除
- 練習 43:SQL 管理
- 練習 44:使用 Python 的數據庫 API
- 練習 45:創建 ORM
- 第七部分:大作業
- 練習 46:blog
- 練習 47:bc
- 練習 48:ed
- 練習 49:sed
- 練習 50:vi
- 練習 51:lessweb
- 練習 52:moreweb