branch: externals/vlf
commit ca13beac241036d60ff0bd1bc9ae84ac39a76012
Author: Andrey Kotlarski <[email protected]>
Commit: Andrey Kotlarski <[email protected]>
Try utf-8 and if not successful, auto detect when adjusting chunk for
proper decoding.
---
vlfi.el | 122 ++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 64 insertions(+), 58 deletions(-)
diff --git a/vlfi.el b/vlfi.el
index 5e10c60..0d82fcc 100644
--- a/vlfi.el
+++ b/vlfi.el
@@ -296,6 +296,7 @@ When given MINIMAL flag, skip non important operations."
(let ((changed (not (verify-visited-file-modtime
(current-buffer))))
(modified (buffer-modified-p))
+ (inhibit-read-only t)
(start (max 0 start))
(end (min end vlfi-file-size)))
(if changed
@@ -310,13 +311,14 @@ When given MINIMAL flag, skip non important operations."
(throw 'abort nil))
(setq vlfi-start-pos start
vlfi-end-pos end)
- (let ((inhibit-read-only t)
- (pos (position-bytes (point))))
+ (let ((pos (position-bytes (point))))
(erase-buffer)
(insert-file-contents-literally
buffer-file-name nil vlfi-start-pos vlfi-end-pos)
- (goto-char (or (byte-to-position
- (+ pos (vlfi-adjust-chunk)))
+ (setq pos (+ pos (vlfi-prepare-chunk)))
+ (decode-coding-region (point-min) (point-max)
+ buffer-file-coding-system)
+ (goto-char (or (byte-to-position pos)
(point-max))))
(set-buffer-modified-p nil))
(if (and modified
@@ -324,19 +326,16 @@ When given MINIMAL flag, skip non important operations."
(< 3 (- start vlfi-start-pos)))
(not (y-or-n-p "Buffer modified, are you sure? ")))
(throw 'abort nil))
- (let ((pos (+ (position-bytes (point))
+ (let* ((pos (+ (position-bytes (point))
vlfi-start-pos))
- (adjust-encoding (or (< vlfi-end-pos end)
- (< start vlfi-start-pos)))
- (adjust-chunk (< start vlfi-start-pos)))
+ (adjust-chunk (< start vlfi-start-pos))
+ (adjust-encoding (or adjust-chunk
+ (< vlfi-end-pos end))))
(if adjust-encoding
- (let ((inhibit-read-only t))
- (encode-coding-region (point-min) (point-max)
- buffer-file-coding-system)))
- (vlfi-print-offset "require goto:" start end)
+ (encode-coding-region (point-min) (point-max)
+ buffer-file-coding-system))
(cond ((< end vlfi-end-pos) ; adjust ends
- (let ((inhibit-read-only t)
- (offset (- end vlfi-start-pos)))
+ (let ((offset (- end vlfi-start-pos)))
(if adjust-encoding
(progn (delete-region offset (point-max))
(setq vlfi-end-pos end)))
@@ -347,19 +346,16 @@ When given MINIMAL flag, skip non important operations."
(1- offset))))))
((< vlfi-end-pos end)
(goto-char (point-max))
- (let ((inhibit-read-only t))
- (insert-file-contents-literally
- buffer-file-name nil vlfi-end-pos end))
+ (insert-file-contents-literally
+ buffer-file-name nil vlfi-end-pos end)
(setq vlfi-end-pos end)))
(cond ((< start vlfi-start-pos) ; adjust start
(goto-char (point-min))
- (let ((inhibit-read-only t))
- (insert-file-contents-literally
- buffer-file-name nil start vlfi-start-pos))
+ (insert-file-contents-literally
+ buffer-file-name nil start vlfi-start-pos)
(setq vlfi-start-pos start))
((< 3 (- start vlfi-start-pos))
- (let ((inhibit-read-only t)
- (offset (- start vlfi-start-pos)))
+ (let ((offset (- start vlfi-start-pos)))
(if adjust-encoding
(progn (delete-region (point-min) offset)
(setq vlfi-start-pos start))
@@ -369,12 +365,11 @@ When given MINIMAL flag, skip non important operations."
(1+ offset))))
(delete-region (point-min) offset)))
(setq vlfi-start-pos start)))
- (vlfi-print-offset "actual goto:" vlfi-start-pos vlfi-end-pos)
- (if adjust-chunk (vlfi-adjust-chunk))
- (if adjust-encoding
- (let ((inhibit-read-only t))
- (decode-coding-region (point-min) (point-max)
- buffer-file-coding-system)))
+ (when adjust-encoding
+ (if adjust-chunk
+ (vlfi-prepare-chunk))
+ (decode-coding-region (point-min) (point-max)
+ buffer-file-coding-system))
(or modified (set-buffer-modified-p nil))
(goto-char
(cond ((< pos vlfi-start-pos) (point-min))
@@ -384,38 +379,49 @@ When given MINIMAL flag, skip non important operations."
(if changed (set-visited-file-modtime)))
(or minimal (vlfi-update-buffer-name))))
-(defun vlfi-print-offset (text start end)
- (message "%s: %d %d" text start end))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; encoding
-(defun vlfi-adjust-chunk ()
- "Adjust chunk beginning until content can be properly decoded.
+(defun vlfi-prepare-chunk ()
+ "Apply proper decoding and adjust chunk start if needed.
Return number of bytes moved back for this to happen."
- (with-coding-priority '(utf-8)
- (setq buffer-file-coding-system 'utf-8;; (detect-coding-region (point-min)
- ;; (point-max)
- ;; t)
- )
- (let ((shift 0)
- (inhibit-read-only t))
- (while (and (not (zerop vlfi-start-pos))
- (< shift 3)
- (/= (- vlfi-end-pos vlfi-start-pos)
- (length (encode-coding-string
- (decode-coding-region
- (point-min) (point-max)
- buffer-file-coding-system t)
- buffer-file-coding-system t))))
- (setq shift (1+ shift)
- vlfi-start-pos (1- vlfi-start-pos))
- (goto-char (point-min))
- (insert-file-contents-literally
- buffer-file-name nil vlfi-start-pos (1+ vlfi-start-pos))
- (setq buffer-file-coding-system 'utf-8
- ;; (detect-coding-region (point-min) (point-max) t)
- ))
- (decode-coding-region (point-min) (point-max)
- buffer-file-coding-system)
- shift)))
+ (let ((status (vlfi-adjust-chunk 'utf-8)))
+ (unless (car status) ; no success with utf-8, auto-detect
+ (delete-region (point-min) (+ (point-min) (cdr status)))
+ (setq vlfi-start-pos (+ vlfi-start-pos (cdr status))
+ status (vlfi-adjust-chunk)))
+ (cdr status)))
+
+(defun vlfi-adjust-chunk (&optional encoding)
+ "Adjust chunk beginning until content can be properly decoded.
+Try with explicit ENCODING if given, otherwise auto-detect.
+Return cons \(success-status . number-of-bytes-moved-back\)."
+ (setq buffer-file-coding-system
+ (or encoding
+ (detect-coding-region (point-min) (point-max) t)))
+ (let ((shift 0)
+ (success nil)
+ (chunk-size (- vlfi-end-pos vlfi-start-pos)))
+ (while (and (< shift 4)
+ (not (setq success (vlfi-decode-status chunk-size)))
+ (not (zerop vlfi-start-pos)))
+ (goto-char (point-min))
+ (insert-file-contents-literally ; insert 1 byte
+ buffer-file-name nil (1- vlfi-start-pos) vlfi-start-pos)
+ (setq shift (1+ shift)
+ chunk-size (1+ chunk-size)
+ vlfi-start-pos (1- vlfi-start-pos)
+ buffer-file-coding-system
+ (or encoding
+ (detect-coding-region (point-min) (point-max) t))))
+ (cons success shift)))
+
+(defun vlfi-decode-status (size)
+ "Check if decoding followed by encoding results in SIZE bytes."
+ (= size (length (encode-coding-string
+ (decode-coding-region (point-min) (point-max)
+ buffer-file-coding-system t)
+ buffer-file-coding-system t))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; search