測試環境linux
系統版本:openSUSE Leap 42.2
桌面環境:KDE Plasma 5
輸入法:fcitx-rime (中州韻)shell
見周圍用 Windows 和 macOS 的小夥伴幾乎都在用簡單強大的 Sublime Text 敲代碼,惟有長期泡在 Linux 環境的本身一直把 Vim 當主力(長時間在終端裏折騰,GUI 環境也用 Atom 和 Emacs),略好奇 Linux 版本的 Sublime Text 體驗會怎麼樣。各類緣由沒有打算試用中文版,因而安裝了官網的 Sublime Text 3,沒想到很快就發現了兩個問題。將字體設置爲平時經常使用的 DejaVu Sans Mono 和 Hack 的時候,代碼註釋裏中文顯示相對英文總體下沉,中英文行高明顯不統一。根據經驗這種排版問題大都是字體回退機制(Fallback)鬧的,換個中文字體就行。然而,修改配置的時候又發現輸入法根本不能切換,無法輸入中文,好吧這就尷尬了。瀏覽器
因而,打開瀏覽器搜搜搜!有關的解決方案和插件大都是針對 Debian 系發行版的(好比 Ubuntu)的,畢竟用戶多,考慮到兼容問題沒有試驗。很快找到了 Sublime 官方論壇的一箇舊帖子,其中 cjacker 回覆的一段 C 源代碼就是用來解決輸入法問題的,不少用戶已經把那段代碼編譯成共享庫做爲輸入法補丁解決了問題(原帖戳這裏)。而後又找到了一段啓動 Sublime 自動加載共享庫的 shell 腳本(來源在此),這下輸入法問題就好解決啦。bash
首先,將這段廣爲流傳的代碼保存爲 sublime_imfix.c,並編譯成共享庫,做爲輸入法補丁。app
/* sublime-imfix.c Use LD_PRELOAD to interpose some function to fix sublime input method support for linux. By Cjacker Huang <jianzhong.huang at i-soft.com.cn> gcc -shared -o libsublime-imfix.so sublime_imfix.c `pkg-config --libs --cflags gtk+-2.0` -fPIC LD_PRELOAD=./libsublime-imfix.so sublime_text */ #include <gtk/gtk.h> #include <gdk/gdkx.h> typedef GdkSegment GdkRegionBox; struct _GdkRegion { long size; long numRects; GdkRegionBox *rects; GdkRegionBox extents; }; GtkIMContext *local_context; void gdk_region_get_clipbox (const GdkRegion *region, GdkRectangle *rectangle) { g_return_if_fail (region != NULL); g_return_if_fail (rectangle != NULL); rectangle->x = region->extents.x1; rectangle->y = region->extents.y1; rectangle->width = region->extents.x2 - region->extents.x1; rectangle->height = region->extents.y2 - region->extents.y1; GdkRectangle rect; rect.x = rectangle->x; rect.y = rectangle->y; rect.width = 0; rect.height = rectangle->height; //The caret width is 2; //Maybe sometimes we will make a mistake, but for most of the time, it should be the caret. if(rectangle->width == 2 && GTK_IS_IM_CONTEXT(local_context)) { gtk_im_context_set_cursor_location(local_context, rectangle); } } //this is needed, for example, if you input something in file dialog and return back the edit area //context will lost, so here we set it again. static GdkFilterReturn event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer im_context) { XEvent *xev = (XEvent *)xevent; if(xev->type == KeyRelease && GTK_IS_IM_CONTEXT(im_context)) { GdkWindow * win = g_object_get_data(G_OBJECT(im_context),"window"); if(GDK_IS_WINDOW(win)) gtk_im_context_set_client_window(im_context, win); } return GDK_FILTER_CONTINUE; } void gtk_im_context_set_client_window (GtkIMContext *context, GdkWindow *window) { GtkIMContextClass *klass; g_return_if_fail (GTK_IS_IM_CONTEXT (context)); klass = GTK_IM_CONTEXT_GET_CLASS (context); if (klass->set_client_window) klass->set_client_window (context, window); if(!GDK_IS_WINDOW (window)) return; g_object_set_data(G_OBJECT(context),"window",window); int width = gdk_window_get_width(window); int height = gdk_window_get_height(window); if(width != 0 && height !=0) { gtk_im_context_focus_in(context); local_context = context; } gdk_window_add_filter (window, event_filter, context); }
編譯:編輯器
gcc -shared -o libsublime-imfix.so sublime_imfix.c `pkg-config --libs --cflags gtk+-2.0` -fPIC
順利完成後,將編譯的 libsublime-imfix.so 文件複製到 Sublime 的安裝目錄:工具
sudo cp libsublime-imfix.so /opt/sublime_text/
而後,準備用來加載共享庫的shell腳本。測試
將如下 shell 腳本代碼保存爲 sublime_text.sh字體
#!/bin/bash SUBLIME_HOME="/opt/sublime_text" LD_LIB=$SUBLIME_HOME/libsublime-imfix.so sh -c "LD_PRELOAD=$LD_LIB $SUBLIME_HOME/sublime_text $@"
授予文件可執行權限:this
sudo chmod a+x sublime_text.sh
把腳本文件複製到 Sublime 安裝目錄:
sudo cp sublime_text.sh /opt/sublime_text/
最後,修改用來啓動 sublime 的 sublime_text.desktop 文件,以便從系統菜單等處點擊圖標直接啓動編輯器就可正常輸入中文。
將 sublime_text.desktop 文件複製到本身的用戶目錄,右鍵打開設置窗口並切換到應用程序標籤頁,修改命令一項裏的 sublime_text 爲 sublime_text.sh 後肯定保存。點擊圖標測試能正常啓動編輯器而且切換輸入法後,將修改過的文件複製到 usr/share/applications/ 目錄。
sudo cp sublime_text.desktop usr/share/applications/
一切順利,在程序菜單裏點擊圖標就能啓動 sublime_text 而且正常輸入中文,經驗證經過右鍵菜單打開文件也能正常切換輸入法。
(sublime_text.desktop 文件所在的位置與安裝方式有關,若是直接下載的壓縮包,文件就在解壓的目錄裏。若是經過加載官方源用包管理器安裝,文件通常在 /usr/share/applications/ 目錄裏。直接用 chmod 命令修改系統路徑裏的 desktop 文件權限修改屬性是行不通的,權限不足的狀況下儘可能新建文件或者複製到用戶目錄修改後再用覆蓋 /usr/share/applications/ 裏的。其餘方法相對複雜。)
以上方案絕非解決問題的惟一方法,只是看起來相對可移植性好,修改內容少,文件好整理之後好維護的一種。還有在 desktop 裏寫入更復雜的命令直接啓動程序,給 sublime_text 設置軟連接等各類方法沒有探索,空間很大。
解決了輸入法問題,立刻修改字體。點擊 Preferences-settings,在右邊的用戶設置里加上 "font_face": "文泉驛等寬正黑" 並保存,這樣中文顯示和輸入的問題就基本解決了。
最後還沒有解決的細節問題是輸入法候選框沒有像在其餘編輯器裏那樣跟隨光標,而是在編輯器下方必定的範圍內左右浮動(不一樣輸入法效果是不同),強迫症羣體慎用。另外想要使用特定的西文字體而且與中文排版行高統一暫未找到有效方法。
畢竟編輯器只是個工具,你們的喜愛和需求都不同,堅持最順手的就好了,在此拒不發表可能引戰的任何內容。惟一想感慨的是,這些解決方案的原始資料都是 N 年前的了,如今依舊得照樣折騰!