2020年03月31日

在emacs中用星际词霸学习英文

在emacs中使用sdcv.el(https://github.com/manateelazycat/sdcv)需要命令行的sdcv.exe,而不是stardict.exe。windows中的 sdcv 需要自己编译。需要安装 cmake、zlib、readline 等。

在windows中安装sdcv

cd /e/workspace

# 使用 Dushistov 的版本
git clone https://github.com/Dushistov/sdcv.git --config "http.proxy=127.0.0.1:1080"
#git clone --depth 1 https://github.com/yygcode/sdcv  --config "http.proxy=127.0.0.1:1080"

# 建个新目录编译sdcv
mkdir /e/workspace/build-sdcv

pacman -S zlib-devel
pacman -S libreadline-devel
pacman -S glib2-devel

#cmake /e/workspace/sdcv -DZLIB_LIBRARY=/mingw64/bin -DREADLINE_LIBRARY=/mingw64/bin -G "MSYS Makefiles"
# 生成msys的makefile,默认生成visual studio的sln
cmake /e/workspace/sdcv -G "MSYS Makefiles"

make VERBOSE=1

src/utils.cpp 编译报错

/C/msys64/mingw64/bin/g++.exe  -DHAVE_CONFIG_H -DVERSION=\"0.5.2\" -I/C/msys64/mingw64/include/glib-2.0 -I/C/msys64/mingw64/lib/glib-2.0/include -I/E/workspace/sdcv/src/lib -I/E/workspace/build-sdcv  -std=c++11 -o CMakeFiles/sdcv.dir/src/utils.cpp.obj -c /E/workspace/sdcv/src/utils.cpp
In file included from C:/msys64/mingw64/include/glib-2.0/glib/gi18n.h:23,
                 from E:/workspace/sdcv/src/utils.cpp:29:
C:/msys64/mingw64/include/c++/9.2.0/bits/basic_string.h: In function 'std::string std::__cxx11::to_string(int)':
C:/msys64/mingw64/include/c++/9.2.0/bits/basic_string.h:6547:50: error: 'libintl_vsnprintf' is not a member of 'std'; did you mean 'libintl_vsnprintf'?
 6547 |   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(int),

需要修改头文件的顺序。详见下面的patch。

src/stardict_lib.cpp 编译报错

stat在c++中是32bit的,需要改为stat64,才能在mingw64中编译成功。

patch

Albert@Albert MINGW64 /e/workspace/sdcv
$ git diff
diff --git a/src/stardict_lib.cpp b/src/stardict_lib.cpp
index a911ddd..427e062 100644
--- a/src/stardict_lib.cpp
+++ b/src/stardict_lib.cpp
@@ -564,7 +564,7 @@ bool OffsetIndex::load_cache(const std::string &url)
     const std::list<std::string> vars = get_cache_variant(url);

     for (const std::string &item : vars) {
-        struct ::stat idxstat, cachestat;
+        struct ::stat64 idxstat, cachestat;
         if (g_stat(url.c_str(), &idxstat) != 0 || g_stat(item.c_str(), &cachestat) != 0)
             continue;
         if (cachestat.st_mtime < idxstat.st_mtime)
diff --git a/src/utils.cpp b/src/utils.cpp
index 33bfeaa..a5f1e21 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -25,11 +25,11 @@
 #include <algorithm>
 #include <cstdio>
 #include <cstdlib>
-#include <glib.h>
-#include <glib/gi18n.h>
 #include <iomanip>
 #include <sstream>

+#include <glib.h>
+#include <glib/gi18n.h>
 #include "utils.hpp"

 std::string utf8_to_locale_ign_err(const std::string &utf8_str)

sdcv.exe的路径

在mingw64中执行sdcv是ok的,但是在cmd中调用sdcv.exe会报错,有依赖的dll找不到。直接放到emacs的bin目录,里面的mingw64的dll比较全,居然就不报错了。懒得找具体缺了哪个dll了。

在macos中安装sdcv

在macos中安装sdcv非常简单,直接brew安装即可。安装后在emacs中使用

brew install sdcv

字典下载

http://download.huzheng.org/zh_CN/

wget -t 0 -c http://download.huzheng.org/zh_CN/stardict-lazyworm-ce-2.4.2.tar.bz2

sdcv.el

sdcv的配置。

字典名要用中文的。

[2020-12-31 Thu 16:32] 新增macos的sdcv配置。

;; https://www.albertzhou.net/blog/2020/03/emacs-sdcv.html
(use-package sdcv
  :defer t
  :load-path "~/.emacs.d/site-lisp/extensions/sdcv"
  :bind (("s-t p" . sdcv-search-pointer)  ;; 光标处的单词, buffer显示
         ("s-t t" . sdcv-search-pointer+) ;; 光标处的单词, frame显示
         ("s-t i" . sdcv-search-input)    ;; 输入的单词, buffer显示
         ("s-t ;" . sdcv-search-input+))
  :init
  ;; fix non-prefix "s-t" key error.
  (define-key global-map (kbd "s-t") (make-sparse-keymap))

  ;; (global-set-key (kbd "s-t p") 'sdcv-search-pointer)
  ;; (global-set-key (kbd "s-t t") 'sdcv-search-pointer+)
  ;; (global-set-key (kbd "s-t i") 'sdcv-search-input)
  ;; (global-set-key (kbd "s-t ;") 'sdcv-search-input+)

  :config
  (when IS-WINDOWS
    (progn
      (setq sdcv-program "D:\\emacs\\bin\\sdcv.exe")
      ;; set local sdcv dict to search word
      (setq sdcv-dictionary-data-dir "c:\\home\\albert\\stardict")))

  (when (eq system-type 'darwin)
    (progn
      ;; (bind-key* "s-t" sdcv-search-pointer+)
      (setq sdcv-dictionary-data-dir "/Volumes/Win10/home/albert/stardict")))

  (setq sdcv-dictionary-simple-list        ;; a simple dictionary list
        '(;; "懒虫简明汉英词典"
          ;; "KDic11万英汉词典"
          "牛津现代英汉双解词典"
          "朗道英汉字典5.0"
          "懒虫简明英汉词典"))

  ;; (shell-command-to-string "E:\\emacs\\bin\\sdcv.exe -n --data-dir=\"e:\\home\\albert\\stardict\" \"test\"")
  (setq sdcv-tooltip-timeout 0))

windows调用sdcv的参数和linux里有点不一样,需要修改 https://github.com/manateelazycat/sdcvsdcv.el

modified   sdcv.el
@@ -594,11 +594,13 @@ string of results."
   (sdcv-filter
    (shell-command-to-string
     ;; Set LANG environment variable, make sure `shell-command-to-string' can handle CJK character correctly.
-    (format "env LANG=zh_CN.UTF-8 %s -x -n %s %s --data-dir=%s"
+    ;; (format "env LANG=zh_CN.UTF-8 %s -x -n %s %s --data-dir=%s"
+    ;; (format "%s -n %s %s --data-dir=%s"
+    (format "%s -n %s --data-dir=%s"
             sdcv-program
-            (mapconcat (lambda (dict)
-                         (concat "-u \"" dict "\""))
-                       dictionary-list " ")
+            ;; (mapconcat (lambda (dict)
+            ;;              (concat "-u \"" dict "\""))
+            ;;            dictionary-list " ")
             (format "\"%s\"" word)
             sdcv-dictionary-data-dir))))

参考