mirror of
https://github.com/m00natic/vlfi.git
synced 2025-01-18 20:10:47 +00:00
Manually decode and use several bytes buffer when loading chunk.
This commit is contained in:
parent
df8c9ea5dd
commit
dd43af51ff
191
vlf-base.el
191
vlf-base.el
@ -27,15 +27,9 @@
|
|||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(defconst vlf-min-chunk-size 16
|
(defconst vlf-sample-size 24
|
||||||
"Minimal number of bytes that can be properly decoded.")
|
"Minimal number of bytes that can be properly decoded.")
|
||||||
|
|
||||||
(defconst vlf-partial-decode-shown
|
|
||||||
(cond ((< emacs-major-version 24) t)
|
|
||||||
((< 24 emacs-major-version) nil)
|
|
||||||
(t ;; TODO: use (< emacs-minor-version 4) after 24.4 release
|
|
||||||
(string-lessp emacs-version "24.3.5")))
|
|
||||||
"Indicates whether partial decode codes are displayed.")
|
|
||||||
(defun vlf-get-file-size (file)
|
(defun vlf-get-file-size (file)
|
||||||
"Get size in bytes of FILE."
|
"Get size in bytes of FILE."
|
||||||
(or (nth 7 (file-attributes file)) 0))
|
(or (nth 7 (file-attributes file)) 0))
|
||||||
@ -70,7 +64,7 @@ If non-nil, UPDATE-VISITED-TIME."
|
|||||||
(setq buffer-undo-list undo-list))))
|
(setq buffer-undo-list undo-list))))
|
||||||
|
|
||||||
(defun vlf-move-to-chunk (start end &optional minimal)
|
(defun vlf-move-to-chunk (start end &optional minimal)
|
||||||
"Move to chunk determined by START END.
|
"Move to chunk enclosed by START END bytes.
|
||||||
When given MINIMAL flag, skip non important operations.
|
When given MINIMAL flag, skip non important operations.
|
||||||
If same as current chunk is requested, do nothing.
|
If same as current chunk is requested, do nothing.
|
||||||
Return number of bytes moved back for proper decoding and number of
|
Return number of bytes moved back for proper decoding and number of
|
||||||
@ -84,7 +78,7 @@ bytes added to the end."
|
|||||||
shifts)))
|
shifts)))
|
||||||
|
|
||||||
(defun vlf-move-to-chunk-1 (start end)
|
(defun vlf-move-to-chunk-1 (start end)
|
||||||
"Move to chunk determined by START END keeping as much edits if any.
|
"Move to chunk enclosed by START END keeping as much edits if any.
|
||||||
Return number of bytes moved back for proper decoding and number of
|
Return number of bytes moved back for proper decoding and number of
|
||||||
bytes added to the end."
|
bytes added to the end."
|
||||||
(let* ((modified (buffer-modified-p))
|
(let* ((modified (buffer-modified-p))
|
||||||
@ -113,8 +107,9 @@ bytes added to the end."
|
|||||||
(let ((pos (+ (position-bytes (point)) vlf-start-pos))
|
(let ((pos (+ (position-bytes (point)) vlf-start-pos))
|
||||||
(inhibit-read-only t))
|
(inhibit-read-only t))
|
||||||
(cond ((< end edit-end)
|
(cond ((< end edit-end)
|
||||||
(let* ((del-pos (1+ (byte-to-position
|
(let* ((del-pos (1+ (or (byte-to-position
|
||||||
(- end vlf-start-pos))))
|
(- end vlf-start-pos))
|
||||||
|
0)))
|
||||||
(del-len (length (encode-coding-region
|
(del-len (length (encode-coding-region
|
||||||
del-pos (point-max)
|
del-pos (point-max)
|
||||||
buffer-file-coding-system
|
buffer-file-coding-system
|
||||||
@ -126,13 +121,11 @@ bytes added to the end."
|
|||||||
(vlf-with-undo-disabled
|
(vlf-with-undo-disabled
|
||||||
(delete-region del-pos (point-max)))))
|
(delete-region del-pos (point-max)))))
|
||||||
((< edit-end end)
|
((< edit-end end)
|
||||||
(if (and (not vlf-partial-decode-shown)
|
(vlf-with-undo-disabled
|
||||||
(< (- end vlf-end-pos) 4))
|
(setq shift-end (cdr (vlf-insert-file-contents
|
||||||
(setq end vlf-end-pos)
|
vlf-end-pos end
|
||||||
(vlf-with-undo-disabled
|
(/= start vlf-end-pos) t
|
||||||
(setq shift-end (cdr (vlf-insert-file-contents
|
(point-max)))))))
|
||||||
vlf-end-pos end nil t
|
|
||||||
(point-max))))))))
|
|
||||||
(cond ((< vlf-start-pos start)
|
(cond ((< vlf-start-pos start)
|
||||||
(let* ((del-pos (1+ (byte-to-position
|
(let* ((del-pos (1+ (byte-to-position
|
||||||
(- start vlf-start-pos))))
|
(- start vlf-start-pos))))
|
||||||
@ -143,20 +136,18 @@ bytes added to the end."
|
|||||||
(setq start (+ vlf-start-pos del-len))
|
(setq start (+ vlf-start-pos del-len))
|
||||||
(vlf-with-undo-disabled
|
(vlf-with-undo-disabled
|
||||||
(delete-region (point-min) del-pos))
|
(delete-region (point-min) del-pos))
|
||||||
(vlf-shift-undo-list (- 1 del-pos))))
|
(vlf-shift-undo-list (- (point-min) del-pos))))
|
||||||
((< start vlf-start-pos)
|
((< start vlf-start-pos)
|
||||||
(if (and (not vlf-partial-decode-shown)
|
(let ((edit-end-pos (point-max)))
|
||||||
(< (- vlf-start-pos start) 4))
|
(vlf-with-undo-disabled
|
||||||
(setq start vlf-start-pos)
|
(setq shift-start (car (vlf-insert-file-contents
|
||||||
(let ((edit-end-pos (point-max)))
|
start vlf-start-pos t
|
||||||
(vlf-with-undo-disabled
|
(/= end vlf-start-pos)
|
||||||
(setq shift-start (car (vlf-insert-file-contents
|
edit-end-pos)))
|
||||||
start vlf-start-pos
|
(goto-char (point-min))
|
||||||
t nil edit-end-pos)))
|
(insert (delete-and-extract-region
|
||||||
(goto-char (point-min))
|
edit-end-pos (point-max))))
|
||||||
(insert (delete-and-extract-region
|
(vlf-shift-undo-list (- (point-max) edit-end-pos)))))
|
||||||
edit-end-pos (point-max))))
|
|
||||||
(vlf-shift-undo-list (- (point-max) edit-end-pos))))))
|
|
||||||
(setq start (- start shift-start))
|
(setq start (- start shift-start))
|
||||||
(goto-char (or (byte-to-position (- pos start))
|
(goto-char (or (byte-to-position (- pos start))
|
||||||
(byte-to-position (- pos vlf-start-pos))
|
(byte-to-position (- pos vlf-start-pos))
|
||||||
@ -200,17 +191,19 @@ bytes added to the end."
|
|||||||
(setq adjust-start (and adjust-start (not (zerop start)))
|
(setq adjust-start (and adjust-start (not (zerop start)))
|
||||||
adjust-end (and adjust-end (< end vlf-file-size))
|
adjust-end (and adjust-end (< end vlf-file-size))
|
||||||
position (or position (point-min)))
|
position (or position (point-min)))
|
||||||
|
(goto-char position)
|
||||||
(let ((shift-start 0)
|
(let ((shift-start 0)
|
||||||
(shift-end 0))
|
(shift-end 0)
|
||||||
|
(safe-end (if adjust-end
|
||||||
|
(min vlf-file-size (+ end 4))
|
||||||
|
end)))
|
||||||
(if adjust-start
|
(if adjust-start
|
||||||
(setq shift-start (vlf-adjust-start start end position
|
(setq shift-start (vlf-adjust-start start safe-end position
|
||||||
adjust-end)
|
adjust-end)
|
||||||
start (- start shift-start))
|
start (- start shift-start))
|
||||||
(setq shift-end (vlf-insert-content-safe start end position)
|
(vlf-insert-file-contents-safe start safe-end position))
|
||||||
end (+ end shift-end)))
|
|
||||||
(if adjust-end
|
(if adjust-end
|
||||||
(setq shift-end (+ shift-end
|
(setq shift-end (vlf-adjust-end start end position)))
|
||||||
(vlf-adjust-end start end position))))
|
|
||||||
(cons shift-start shift-end)))
|
(cons shift-start shift-end)))
|
||||||
|
|
||||||
(defun vlf-adjust-start (start end position adjust-end)
|
(defun vlf-adjust-start (start end position adjust-end)
|
||||||
@ -218,83 +211,75 @@ bytes added to the end."
|
|||||||
be properly decoded. Use buffer POSITION as start.
|
be properly decoded. Use buffer POSITION as start.
|
||||||
ADJUST-END is non-nil if end would be adjusted later.
|
ADJUST-END is non-nil if end would be adjusted later.
|
||||||
Return number of bytes moved back for proper decoding."
|
Return number of bytes moved back for proper decoding."
|
||||||
(let* ((min-end (min end (+ start vlf-min-chunk-size)))
|
(let* ((safe-start (max 0 (- start 4)))
|
||||||
(chunk-size (- min-end start))
|
(sample-end (min end (+ safe-start vlf-sample-size)))
|
||||||
(strict (and (not adjust-end) (= min-end end)))
|
(chunk-size (- sample-end safe-start))
|
||||||
(shift (vlf-insert-content-safe start min-end position t)))
|
(strict (or (= sample-end vlf-file-size)
|
||||||
(setq start (- start shift))
|
(and (not adjust-end) (= sample-end end))))
|
||||||
(while (and (not (zerop start))
|
(shift 0))
|
||||||
|
(while (and (progn (vlf-insert-file-contents-safe
|
||||||
|
safe-start sample-end position)
|
||||||
|
(not (zerop safe-start)))
|
||||||
(< shift 3)
|
(< shift 3)
|
||||||
(let ((diff (- chunk-size
|
(let ((diff (- chunk-size
|
||||||
(length
|
(length
|
||||||
(encode-coding-region
|
(encode-coding-region
|
||||||
position (point-max)
|
position (point-max)
|
||||||
buffer-file-coding-system t)))))
|
buffer-file-coding-system t)))))
|
||||||
(cond (strict (not (zerop diff)))
|
(if strict
|
||||||
(vlf-partial-decode-shown
|
(not (zerop diff))
|
||||||
(or (< diff -3) (< 0 diff)))
|
(or (< diff 0) (< 3 diff)))))
|
||||||
(t (or (< diff 0) (< 3 diff))))))
|
|
||||||
(setq shift (1+ shift)
|
(setq shift (1+ shift)
|
||||||
start (1- start)
|
safe-start (1- safe-start)
|
||||||
chunk-size (1+ chunk-size))
|
chunk-size (1+ chunk-size))
|
||||||
(delete-region position (point-max))
|
(delete-region position (point-max)))
|
||||||
(insert-file-contents buffer-file-name nil start min-end))
|
(let ((cut-pos position)
|
||||||
(unless (= min-end end)
|
(cut-len 0))
|
||||||
(delete-region position (point-max))
|
(while (< safe-start start)
|
||||||
(insert-file-contents buffer-file-name nil start end))
|
(setq cut-len (length (encode-coding-region
|
||||||
shift))
|
cut-pos (1+ cut-pos)
|
||||||
|
buffer-file-coding-system t))
|
||||||
|
cut-pos (1+ cut-pos)
|
||||||
|
safe-start (+ safe-start cut-len)))
|
||||||
|
(if (< start safe-start)
|
||||||
|
(setq safe-start (- safe-start cut-len)
|
||||||
|
cut-pos (1- cut-pos)))
|
||||||
|
(if (= sample-end end)
|
||||||
|
(delete-region position cut-pos)
|
||||||
|
(delete-region position (point-max))
|
||||||
|
(vlf-insert-file-contents-safe safe-start end position)))
|
||||||
|
(- start safe-start)))
|
||||||
|
|
||||||
(defun vlf-adjust-end (start end position)
|
(defun vlf-adjust-end (start end position)
|
||||||
"Adjust chunk end at absolute START to END till content can be\
|
"Adjust chunk end at absolute START to END starting at POSITION.
|
||||||
properly decoded starting at POSITION.
|
Remove characters from the end until length is closest to expected.
|
||||||
Return number of bytes added for proper decoding."
|
Return number of bytes added over expected."
|
||||||
(let ((shift 0))
|
(let ((expected-size (- end start))
|
||||||
(if vlf-partial-decode-shown
|
(current-size (length (encode-coding-region
|
||||||
(let ((new-pos (max position
|
position (point-max)
|
||||||
(- (point-max) vlf-min-chunk-size))))
|
buffer-file-coding-system t)))
|
||||||
(if (< position new-pos)
|
(cut-point (point-max))
|
||||||
(setq start (+ start (length (encode-coding-region
|
(cut-len 0))
|
||||||
position new-pos
|
(while (< expected-size current-size)
|
||||||
buffer-file-coding-system
|
(setq cut-len (length (encode-coding-region
|
||||||
t)))
|
(1- cut-point) cut-point
|
||||||
position new-pos))))
|
buffer-file-coding-system t))
|
||||||
(let ((chunk-size (- end start)))
|
cut-point (1- cut-point)
|
||||||
(goto-char (point-max))
|
current-size (- current-size cut-len)))
|
||||||
(while (and (< shift 3)
|
(if (< current-size expected-size)
|
||||||
(< end vlf-file-size)
|
(setq cut-point (1+ cut-point)
|
||||||
(or (eq (char-charset (preceding-char)) 'eight-bit)
|
current-size (+ current-size cut-len)))
|
||||||
(/= chunk-size
|
(delete-region cut-point (point-max))
|
||||||
(length (encode-coding-region
|
(- current-size expected-size)))
|
||||||
position (point-max)
|
|
||||||
buffer-file-coding-system t)))))
|
|
||||||
(setq shift (1+ shift)
|
|
||||||
end (1+ end)
|
|
||||||
chunk-size (1+ chunk-size))
|
|
||||||
(delete-region position (point-max))
|
|
||||||
(insert-file-contents buffer-file-name nil start end)
|
|
||||||
(goto-char (point-max))))
|
|
||||||
shift))
|
|
||||||
|
|
||||||
(defun vlf-insert-content-safe (start end position &optional shift-start)
|
(defun vlf-insert-file-contents-safe (start end position)
|
||||||
"Insert file content from absolute START to END of file at\
|
"Extract decoded file bytes START to END at POSITION."
|
||||||
POSITION. Adjust start if SHIFT-START is non nil, end otherwise.
|
(let ((coding buffer-file-coding-system))
|
||||||
Clean up if no characters are inserted."
|
(insert-file-contents-literally buffer-file-name nil start end)
|
||||||
(goto-char position)
|
(let ((coding-system-for-read coding))
|
||||||
(let ((shift 0))
|
(decode-coding-inserted-region position (point-max)
|
||||||
(while (and (< shift 3)
|
buffer-file-name nil start end))
|
||||||
(zerop (cadr (insert-file-contents buffer-file-name
|
(setq buffer-file-coding-system last-coding-system-used)))
|
||||||
nil start end)))
|
|
||||||
(if shift-start
|
|
||||||
(not (zerop start))
|
|
||||||
(< end vlf-file-size)))
|
|
||||||
;; TODO: this seems like regression after Emacs 24.3
|
|
||||||
(message "Buffer content may be broken")
|
|
||||||
(setq shift (1+ shift))
|
|
||||||
(if shift-start
|
|
||||||
(setq start (1- start))
|
|
||||||
(setq end (1+ end)))
|
|
||||||
(delete-region position (point-max)))
|
|
||||||
shift))
|
|
||||||
|
|
||||||
(defun vlf-shift-undo-list (n)
|
(defun vlf-shift-undo-list (n)
|
||||||
"Shift undo list element regions by N."
|
"Shift undo list element regions by N."
|
||||||
|
1
vlf.el
1
vlf.el
@ -149,6 +149,7 @@ You can customize number of bytes displayed by customizing
|
|||||||
(with-current-buffer (generate-new-buffer "*vlf*")
|
(with-current-buffer (generate-new-buffer "*vlf*")
|
||||||
(set-visited-file-name file)
|
(set-visited-file-name file)
|
||||||
(set-buffer-modified-p nil)
|
(set-buffer-modified-p nil)
|
||||||
|
(setq buffer-file-coding-system nil)
|
||||||
(vlf-mode 1)
|
(vlf-mode 1)
|
||||||
(switch-to-buffer (current-buffer))))
|
(switch-to-buffer (current-buffer))))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user