emacs/sekka.el in sekka-1.5.7 vs emacs/sekka.el in sekka-1.5.8

- old
+ new

@@ -1,11 +1,11 @@ ;;; sekka.el --- A client for Sekka IME server ;; ;; Copyright (C) 2010-2014 Kiyoka Nishiyama ;; ;; Author: Kiyoka Nishiyama <kiyoka@sumibi.org> -;; Version: 1.5.7 ;;SEKKA-VERSION +;; Version: 1.5.8 ;;SEKKA-VERSION ;; Keywords: ime, skk, japanese ;; Package-Requires: ((cl-lib "0.3") (concurrent "0.3.1") (popup "0.5.0")) ;; URL: https://github.com/kiyoka/sekka ;; ;; This file is part of Sekka @@ -80,10 +80,15 @@ (defcustom sekka-stop-chars "(){}<> " "*漢字変換文字列を取り込む時に変換範囲に含めない文字を設定する" :type 'string :group 'sekka) +(defcustom sekka-use-curl t + "non-nil でcurlコマンドを使う。nilでEmacs Lisp(url.elを使う)" + :type 'boolean + :group 'sekka) + (defcustom sekka-curl "curl" "curlコマンドの絶対パスを設定する" :type 'string :group 'sekka) @@ -206,10 +211,12 @@ ((buffer (get-buffer-create "*sekka-debug*"))) (with-current-buffer buffer (goto-char (point-max)) (insert string))))) +;; HTTPクライアントの多重起動防止用 +(defvar sekka-busy 0) ;;; 現在のsekka-serverの接続先 (defvar current-sekka-server-url nil) ;;; 辞書のアップロード中かどうか @@ -376,11 +383,11 @@ (sekka-next-sekka-server) nil) result))) (let ((arg-alist (cons - `(userid . ,sekka-login-name) + `("userid" . ,sekka-login-name) arg-alist))) (or (one-request func-name arg-alist) (one-request func-name arg-alist) (one-request func-name arg-alist) @@ -395,11 +402,11 @@ (append (if (< 0 (length sekka-no-proxy-hosts)) (list "--noproxy" sekka-no-proxy-hosts) nil) (sekka-construct-curl-argstr (cons - '(format . "sexp") + '("format" . "sexp") arg-alist)))) (buffername "*sekka-output*") (result "")) (sekka-debug-print (format "arg-lst :[%S]\n" lst)) (progn @@ -427,17 +434,79 @@ (setq current-sekka-server-url "http://localhost:12929/") (sekka-rest-request-by-curl "henkan" '( ("yomi" . "Nihon") - (limit . "1") - (method . "normal") + ("limit" . "1") + ("method" . "normal") ("userid" . "kiyoka"))) ) - +(defun sekka-url-http-post (url args) + "Send ARGS to URL as a POST request." + (progn + (setq url-request-method "POST") + (setq url-http-version "1.0") + (setq url-request-extra-headers + '(("Content-Type" . "application/x-www-form-urlencoded"))) + (setq url-request-data + (mapconcat (lambda (arg) + (concat (url-hexify-string (car arg)) + "=" + (url-hexify-string (cdr arg)))) + args + "&")) + (let* ((lines + (let ((buf (url-retrieve-synchronously url))) + (sekka-debug-print (buffer-name buf)) + (sekka-debug-print "\n") + (if buf + (with-current-buffer buf + (decode-coding-string + (let ((str (buffer-substring-no-properties (point-min) (point-max)))) + (sekka-debug-print (format "http result code:%s\n" url-http-response-status)) + (sekka-debug-print (format "(%d-%d) eoh=%s\n" (point-min) (point-max) url-http-end-of-headers)) + (sekka-debug-print (format "<<<%s>>>\n" str)) + str) + 'utf-8)) + (list "curl: (7) Couldn't connect to host 'localhost'")))) ;; Emulate curl error. + (line-list + (split-string lines "\n"))) + + (car (reverse line-list))))) + +;; +;; http request function with pure emacs +;; (no proxy supported) +(defun sekka-rest-request-by-pure (func-name arg-alist) + (setq sekka-busy (+ sekka-busy 1)) + (sekka-debug-print (format "sekka-busy=%d\n" sekka-busy)) + (let* ((arg-alist + (cons + '("format" . "sexp") + arg-alist)) + (result + (sekka-url-http-post + (concat current-sekka-server-url func-name) + arg-alist))) + (setq sekka-busy (- sekka-busy 1)) + (sekka-debug-print (format "sekka-busy=%d\n" sekka-busy)) + result)) + +(when nil + ;; unit test + (setq sekka-login-name (user-login-name)) + (setq current-sekka-server-url "http://localhost:12929/") + (sekka-rest-request-by-pure + "henkan" + '( + ("yomi" . "Nihon") + ("limit" . "1") + ("method" . "normal") + ("userid" . "kiyoka")))) + (defun sekka-rest-request-sub (func-name arg-alist) (if sekka-psudo-server (cond ((string-equal func-name "henkan") ;; クライアント単体で仮想的にサーバーに接続しているようにしてテストするモード @@ -450,11 +519,15 @@ "(\"四文字熟語\" \"4文字熟語\" \"4文字熟語\" \"よんもじじゅくご\" \"ヨンモジジュクゴ\")" ;; 2) しょかいきどう ;; "(\"初回起動\", \"諸快気堂\", \"諸開基堂\", \"しょかいきどう\", \"ショカイキドウ\")" )) ;; 実際のサーバに接続する - (sekka-rest-request-by-curl func-name arg-alist))) + (cond + (sekka-use-curl + (sekka-rest-request-by-curl func-name arg-alist)) + (t + (sekka-rest-request-by-pure func-name arg-alist))))) ;; ;; 現在時刻をUNIXタイムを返す(単位は秒) ;; (defun sekka-current-unixtime () @@ -474,13 +547,13 @@ (when (string-equal "en" sekka-keyboard-type) (setq yomi (replace-regexp-in-string ":" "+" yomi))) (sekka-debug-print (format "henkan-send :[%s]\n" yomi)) (let ( - (result (sekka-rest-request "henkan" `((yomi . ,yomi) - (limit . ,(format "%d" limit)) - (method . ,sekka-roman-method))))) + (result (sekka-rest-request "henkan" `(("yomi" . ,yomi) + ("limit" . ,(format "%d" limit)) + ("method" . ,sekka-roman-method))))) (sekka-debug-print (format "henkan-result:%S\n" result)) (if (eq (string-to-char result) ?\( ) (progn (message nil) (condition-case err @@ -500,12 +573,12 @@ (sekka-debug-print (format "henkan-kakutei key=[%s] tango=[%s]\n" key tango)) ;;(message "Requesting to sekka server...") (let ((result (sekka-rest-request "kakutei" `( - (key . ,key) - (tango . ,tango))))) + ("key" . ,key) + ("tango" . ,tango))))) (sekka-debug-print (format "kakutei-result:%S\n" result)) (message result) t)) @@ -516,11 +589,11 @@ (sekka-debug-print (format "googleime yomi=[%s]\n" yomi)) ;;(message "Requesting to sekka server...") (let ((result (sekka-rest-request "googleime" `( - (yomi . ,yomi))))) + ("yomi" . ,yomi))))) (sekka-debug-print (format "googleime-result:%S\n" result)) (progn (message nil) (condition-case err (read result) @@ -552,11 +625,11 @@ (cc:thread 100 (while (< 0 (length str-lst)) (setq x (pop str-lst)) ;;(message "Requesting to sekka server...") (sekka-debug-print (format "register [%s]\n" x)) - (lexical-let ((result (sekka-rest-request "register" `((dict . ,x))))) + (lexical-let ((result (sekka-rest-request "register" `(("dict" . ,x))))) (sekka-debug-print (format "register-result:%S\n" result)))) (setq sekka-uploading-flag nil) (redraw-modeline))) t)) @@ -851,10 +924,11 @@ (define-key map "\C-s" 'popup-isearch) (define-key map "\C-g" 'popup-close) (define-key map "\C-r" 'popup-select) map)) + ;; 選択操作回数のインクリメント (defun sekka-select-operation-inc () (incf sekka-select-operation-times) (when (< 3 sekka-select-operation-times) (sekka-select-operation-reset) @@ -870,11 +944,11 @@ (result (popup-menu* lst :scroll-bar t :margin t :keymap sekka-popup-menu-keymap - :initial-index sekka-cand-cur))) + :initial-index sekka-cand-cur))) (let ((selected-word (car (split-string result " ")))) (setq sekka-cand-cur (sekka-find-by-tango selected-word)))))) ;; 選択操作回数のリセット @@ -1495,10 +1569,14 @@ (defun sekka-realtime-guide () "リアルタイムで変換中のガイドを出す sekka-modeがONの間中呼び出される可能性がある。" (cond + ((< 0 sekka-busy) + ;; 残り回数のデクリメント + (setq sekka-timer-rest (- sekka-timer-rest 1)) + (sekka-debug-print "busy!\n")) ((or (null sekka-mode) (> 1 sekka-timer-rest)) (cancel-timer sekka-timer) (setq sekka-timer nil) (delete-overlay sekka-guide-overlay)) @@ -1664,10 +1742,10 @@ ;; input-method として登録する。 (set-language-info "Japanese" 'input-method "japanese-sekka") (setq default-input-method "japanese-sekka") (defconst sekka-version - "1.5.7" ;;SEKKA-VERSION + "1.5.8" ;;SEKKA-VERSION ) (defun sekka-version (&optional arg) "入力モード変更" (interactive "P") (message sekka-version))