diff options
| author | Noam Postavsky | 2016-12-28 20:13:20 -0500 |
|---|---|---|
| committer | Noam Postavsky | 2017-01-03 08:58:40 -0500 |
| commit | 134e86b360cab0d0a5cb634b71a4b06ec26c5f1f (patch) | |
| tree | c690d1ac910ab7b1e07298035cec3c232c3eea55 | |
| parent | 975b2acfe6a4e246631c372063d7bdef0f832d3d (diff) | |
| download | emacs-134e86b360cab0d0a5cb634b71a4b06ec26c5f1f.tar.gz emacs-134e86b360cab0d0a5cb634b71a4b06ec26c5f1f.zip | |
Handle multibyte chars spanning chunks in term.el
* lisp/term.el (term-terminal-undecoded-bytes): New variable.
(term-mode): Make it buffer local. Don't make `term-terminal-parameter'
buffer-local twice.
(term-emulate-terminal): Check for bytes of incompletely decoded
characters, and save them until the next call when they can be fully
decoded (Bug#25288).
| -rw-r--r-- | lisp/term.el | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/lisp/term.el b/lisp/term.el index e624f7dcd9f..a3933ae4a4f 100644 --- a/lisp/term.el +++ b/lisp/term.el | |||
| @@ -341,6 +341,7 @@ | |||
| 341 | (defconst term-protocol-version "0.96") | 341 | (defconst term-protocol-version "0.96") |
| 342 | 342 | ||
| 343 | (eval-when-compile (require 'ange-ftp)) | 343 | (eval-when-compile (require 'ange-ftp)) |
| 344 | (eval-when-compile (require 'cl-lib)) | ||
| 344 | (require 'ring) | 345 | (require 'ring) |
| 345 | (require 'ehelp) | 346 | (require 'ehelp) |
| 346 | 347 | ||
| @@ -404,6 +405,7 @@ state 4: term-terminal-parameter contains pending output.") | |||
| 404 | (defvar term-kill-echo-list nil | 405 | (defvar term-kill-echo-list nil |
| 405 | "A queue of strings whose echo we want suppressed.") | 406 | "A queue of strings whose echo we want suppressed.") |
| 406 | (defvar term-terminal-parameter) | 407 | (defvar term-terminal-parameter) |
| 408 | (defvar term-terminal-undecoded-bytes nil) | ||
| 407 | (defvar term-terminal-previous-parameter) | 409 | (defvar term-terminal-previous-parameter) |
| 408 | (defvar term-current-face 'term) | 410 | (defvar term-current-face 'term) |
| 409 | (defvar term-scroll-start 0 "Top-most line (inclusive) of scrolling region.") | 411 | (defvar term-scroll-start 0 "Top-most line (inclusive) of scrolling region.") |
| @@ -1015,7 +1017,6 @@ Entry to this mode runs the hooks on `term-mode-hook'." | |||
| 1015 | 1017 | ||
| 1016 | ;; These local variables are set to their local values: | 1018 | ;; These local variables are set to their local values: |
| 1017 | (make-local-variable 'term-saved-home-marker) | 1019 | (make-local-variable 'term-saved-home-marker) |
| 1018 | (make-local-variable 'term-terminal-parameter) | ||
| 1019 | (make-local-variable 'term-saved-cursor) | 1020 | (make-local-variable 'term-saved-cursor) |
| 1020 | (make-local-variable 'term-prompt-regexp) | 1021 | (make-local-variable 'term-prompt-regexp) |
| 1021 | (make-local-variable 'term-input-ring-size) | 1022 | (make-local-variable 'term-input-ring-size) |
| @@ -1052,6 +1053,7 @@ Entry to this mode runs the hooks on `term-mode-hook'." | |||
| 1052 | (make-local-variable 'term-ansi-current-invisible) | 1053 | (make-local-variable 'term-ansi-current-invisible) |
| 1053 | 1054 | ||
| 1054 | (make-local-variable 'term-terminal-parameter) | 1055 | (make-local-variable 'term-terminal-parameter) |
| 1056 | (make-local-variable 'term-terminal-undecoded-bytes) | ||
| 1055 | (make-local-variable 'term-terminal-previous-parameter) | 1057 | (make-local-variable 'term-terminal-previous-parameter) |
| 1056 | (make-local-variable 'term-terminal-previous-parameter-2) | 1058 | (make-local-variable 'term-terminal-previous-parameter-2) |
| 1057 | (make-local-variable 'term-terminal-previous-parameter-3) | 1059 | (make-local-variable 'term-terminal-previous-parameter-3) |
| @@ -2748,6 +2750,10 @@ See `term-prompt-regexp'." | |||
| 2748 | 2750 | ||
| 2749 | (when term-log-buffer | 2751 | (when term-log-buffer |
| 2750 | (princ str term-log-buffer)) | 2752 | (princ str term-log-buffer)) |
| 2753 | (when term-terminal-undecoded-bytes | ||
| 2754 | (setq str (concat term-terminal-undecoded-bytes str)) | ||
| 2755 | (setq str-length (length str)) | ||
| 2756 | (setq term-terminal-undecoded-bytes nil)) | ||
| 2751 | (cond ((eq term-terminal-state 4) ;; Have saved pending output. | 2757 | (cond ((eq term-terminal-state 4) ;; Have saved pending output. |
| 2752 | (setq str (concat term-terminal-parameter str)) | 2758 | (setq str (concat term-terminal-parameter str)) |
| 2753 | (setq term-terminal-parameter nil) | 2759 | (setq term-terminal-parameter nil) |
| @@ -2763,13 +2769,6 @@ See `term-prompt-regexp'." | |||
| 2763 | str i)) | 2769 | str i)) |
| 2764 | (when (not funny) (setq funny str-length)) | 2770 | (when (not funny) (setq funny str-length)) |
| 2765 | (cond ((> funny i) | 2771 | (cond ((> funny i) |
| 2766 | ;; Decode the string before counting | ||
| 2767 | ;; characters, to avoid garbling of certain | ||
| 2768 | ;; multibyte characters (bug#1006). | ||
| 2769 | (setq decoded-substring | ||
| 2770 | (decode-coding-string | ||
| 2771 | (substring str i funny) | ||
| 2772 | locale-coding-system)) | ||
| 2773 | (cond ((eq term-terminal-state 1) | 2772 | (cond ((eq term-terminal-state 1) |
| 2774 | ;; We are in state 1, we need to wrap | 2773 | ;; We are in state 1, we need to wrap |
| 2775 | ;; around. Go to the beginning of | 2774 | ;; around. Go to the beginning of |
| @@ -2778,7 +2777,31 @@ See `term-prompt-regexp'." | |||
| 2778 | (term-down 1 t) | 2777 | (term-down 1 t) |
| 2779 | (term-move-columns (- (term-current-column))) | 2778 | (term-move-columns (- (term-current-column))) |
| 2780 | (setq term-terminal-state 0))) | 2779 | (setq term-terminal-state 0))) |
| 2780 | ;; Decode the string before counting | ||
| 2781 | ;; characters, to avoid garbling of certain | ||
| 2782 | ;; multibyte characters (bug#1006). | ||
| 2783 | (setq decoded-substring | ||
| 2784 | (decode-coding-string | ||
| 2785 | (substring str i funny) | ||
| 2786 | locale-coding-system)) | ||
| 2781 | (setq count (length decoded-substring)) | 2787 | (setq count (length decoded-substring)) |
| 2788 | ;; Check for multibyte characters that ends | ||
| 2789 | ;; before end of string, and save it for | ||
| 2790 | ;; next time. | ||
| 2791 | (when (= funny str-length) | ||
| 2792 | (let ((partial 0)) | ||
| 2793 | (while (eq (char-charset (aref decoded-substring | ||
| 2794 | (- count 1 partial))) | ||
| 2795 | 'eight-bit) | ||
| 2796 | (cl-incf partial)) | ||
| 2797 | (when (> partial 0) | ||
| 2798 | (setq term-terminal-undecoded-bytes | ||
| 2799 | (substring decoded-substring (- partial))) | ||
| 2800 | (setq decoded-substring | ||
| 2801 | (substring decoded-substring 0 (- partial))) | ||
| 2802 | (cl-decf str-length partial) | ||
| 2803 | (cl-decf count partial) | ||
| 2804 | (cl-decf funny partial)))) | ||
| 2782 | (setq temp (- (+ (term-horizontal-column) count) | 2805 | (setq temp (- (+ (term-horizontal-column) count) |
| 2783 | term-width)) | 2806 | term-width)) |
| 2784 | (cond ((or term-suppress-hard-newline (<= temp 0))) | 2807 | (cond ((or term-suppress-hard-newline (<= temp 0))) |