fordon_greeman / voidfiles

Branch: main
Switch branches/tags
main
theidioticdev add emacs 2079ec5 22h ago
180 lines · 7 KB Raw Blame History
1 ;;; emms-i18n.el --- functions for handling coding systems -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4
5 ;; Author: Ye Wenbin <wenbinye@163.com>
6
7 ;; This file is part of EMMS.
8
9 ;; This program is free software; you can redistribute it and/or
10 ;; modify it under the terms of the GNU General Public License as
11 ;; published by the Free Software Foundation; either version 3, or (at
12 ;; your option) any later version.
13
14 ;; This program is distributed in the hope that it will be useful, but
15 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 ;; General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with this program; if not, write to the Free Software
21 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23 ;;; Commentary:
24
25 ;; When reading from process, first check the car part of
26 ;; `emms-i18n-default-coding-system'; if non-nil, use this for
27 ;; decoding, and never detect coding system; if nil, first call
28 ;; `emms-i18n-coding-detect-functions' to get coding system, if
29 ;; success, decode the result, otherwise, use
30 ;; `emms-i18n-detect-coding-function', the Emacs detect coding
31 ;; function, if the coding detected is not in
32 ;; `emms-i18n-never-used-coding-system', decode it, otherwise use
33 ;; locale-coding-system.
34
35 ;; When writing/sending data to process, first check the cdr part of
36 ;; `emms-i18n-default-coding-system', if non-nil, use this to encode
37 ;; data, otherwise do nothing, that means use
38 ;; `default-process-coding-system' or `process-coding-system-alist' to
39 ;; encode data.
40
41 ;; Put this file into your load-path and the following into your
42 ;; ~/.emacs:
43
44 ;; (require 'emms-i18n)
45
46 ;;; Code:
47
48 (provide 'emms-i18n)
49
50 ;; TODO: Use defcustom.
51 (defvar emms-i18n-never-used-coding-system
52 '(raw-text undecided)
53 "If the `emms-i18n-coding-detect-functions' return a coding
54 system in this list, use `emms-i18n-default-coding-system'
55 instead.")
56
57 ;; TODO: Use defcustom.
58 (defvar emms-i18n-coding-system-for-read
59 'utf-8
60 "If coding detect fails, use this for decoding.")
61
62 ;; TODO: Use defcustom.
63 (defvar emms-i18n-default-coding-system
64 '(no-conversion . no-conversion)
65 "If non-nil, use this for decoding and encoding.")
66
67 ;; TODO: Use defcustom.
68 (defvar emms-i18n-coding-detect-functions
69 nil
70 "A list of functions to call to detect codings.")
71
72 ;; TODO: Use defcustom.
73 (defvar emms-i18n-detect-max-size
74 10000
75 "Maximum amount of bytes to detect the coding system. nil
76 means to scan the whole buffer.")
77
78 (defun emms-i18n-iconv (from to str)
79 "Convert string STR from FROM coding to TO coding."
80 (if (and from to)
81 (decode-coding-string
82 (encode-coding-string str to)
83 from)
84 str))
85
86 (defun emms-i18n-iconv-region (beg end from to)
87 (when (and from to)
88 (save-restriction
89 (narrow-to-region beg end)
90 (encode-coding-region (point-min) (point-max) to)
91 (decode-coding-region (point-min) (point-max) from))))
92
93 (defun emms-i18n-iconv-buffer (from to &optional buf)
94 "Convert buffer BUF from FROM coding to TO coding. BUF
95 defaults to the current buffer."
96 (save-excursion
97 (and buf (set-buffer buf))
98 (emms-i18n-iconv-region (point-min) (point-max) from to)))
99
100 (defun emms-i18n-set-default-coding-system (read-coding write-coding)
101 "Set `emms-i18n-default-coding-system'."
102 (interactive "zSet coding system for read: \nzSet coding system for write: ")
103 (setq emms-i18n-default-coding-system
104 (cons
105 (and (coding-system-p read-coding) read-coding)
106 (and (coding-system-p write-coding) write-coding)))
107 (message (concat
108 (if (car emms-i18n-default-coding-system)
109 (format "The coding system for reading is %S." (car emms-i18n-default-coding-system))
110 "Good, you want me to detect the coding system!")
111 (format " The coding system for writing is %S."
112 (or (cdr emms-i18n-default-coding-system)
113 (cdr default-process-coding-system))))))
114
115 (defun emms-i18n-call-process-simple (&rest args)
116 "Run a program and return the program result.
117 If the car part of `emms-i18n-default-coding-system' is non-nil,
118 the program result will be decoded using the car part of
119 `emms-i18n-default-coding-system'. Otherwise, use
120 `emms-i18n-coding-detect-functions' to detect the coding system
121 of the result. If the `emms-i18n-coding-detect-functions'
122 failed, use `emms-i18n-detect-coding-function' to detect coding
123 system. If all the coding systems are nil or in
124 `emms-i18n-never-used-coding-system', decode the result using
125 `emms-i18n-coding-system-for-read'.
126
127 ARGS are the same as in `call-process', except BUFFER should
128 always have the value t. Otherwise the coding detection will not
129 be performed."
130 (let ((default-process-coding-system (copy-tree default-process-coding-system))
131 (process-coding-system-alist nil) exit pos)
132 (when (eq (nth 2 args) 't)
133 (setcar default-process-coding-system (car emms-i18n-default-coding-system))
134 (setq pos (point)))
135 (setq exit (apply 'call-process args))
136 (when (and (eq (nth 2 args) 't)
137 (eq (car emms-i18n-default-coding-system) 'no-conversion))
138 (save-restriction
139 (narrow-to-region pos (point))
140 (decode-coding-region (point-min) (point-max) (emms-i18n-detect-buffer-coding-system))))
141 exit))
142
143 ;; TODO: Is this function useful?
144 (defun emms-i18n-call-process (&rest args)
145 "Run the program like `call-process'. If the cdr part of
146 `emms-i18n-default-coding-system' is non-nil, the string in ARGS
147 will be encoded by the cdr part of
148 `emms-i18n-default-coding-system'; otherwise, all parameters are
149 simply passed to `call-process'."
150 (with-temp-buffer
151 (if (cdr emms-i18n-default-coding-system)
152 (let ((default-process-coding-system emms-i18n-default-coding-system)
153 (process-coding-system-alist nil))
154 (apply 'call-process args))
155 (apply 'call-process args))))
156
157 (defun emms-i18n-detect-coding-function (size)
158 (detect-coding-region (point)
159 (+ (if (null emms-i18n-detect-max-size)
160 size
161 (min size emms-i18n-detect-max-size))
162 (point)) t))
163
164 (defun emms-i18n-detect-buffer-coding-system (&optional buf)
165 "Before calling this function, make sure the buffer is literal."
166 (let ((size (- (point-max) (point-min)))
167 (_func (append emms-i18n-coding-detect-functions 'emms-i18n-detect-coding-function))
168 coding)
169 (save-excursion
170 (and buf (set-buffer buf))
171 (goto-char (point-min))
172 (when (> size 0)
173 (setq coding (run-hook-with-args-until-success 'func size))
174 (if (member (coding-system-base coding) emms-i18n-never-used-coding-system)
175 (setq coding (emms-i18n-detect-coding-function size))))
176 (if (or (null coding) (member (coding-system-base coding) emms-i18n-never-used-coding-system))
177 emms-i18n-coding-system-for-read
178 coding))))
179
180 ;;; emms-i18n.el ends here