1
0
mirror of https://github.com/m00natic/vlfi.git synced 2025-02-07 13:40:49 +00:00

Keep as much editing as possible when moving to intersecting chunk.

This commit is contained in:
Andrey Kotlarski 2013-08-08 12:43:00 +03:00
parent 02a37c4192
commit 0ecb40a5ee

231
vlfi.el
View File

@ -289,149 +289,118 @@ When prefix argument is negative
Adjust according to file start/end and show `vlfi-batch-size' bytes. Adjust according to file start/end and show `vlfi-batch-size' bytes.
When given MINIMAL flag, skip non important operations." When given MINIMAL flag, skip non important operations."
(vlfi-verify-size) (vlfi-verify-size)
(let ((start (max 0 start)) (let* ((start (max 0 start))
(end (min (+ vlfi-start-pos vlfi-batch-size) (end (min (+ start vlfi-batch-size) vlfi-file-size)))
vlfi-file-size)))
(if (= vlfi-file-size end) ; re-adjust start (if (= vlfi-file-size end) ; re-adjust start
(setq start (max 0 (- end vlfi-batch-size)))) (setq start (max 0 (- end vlfi-batch-size))))
(vlfi-move-to-chunk start end minimal))) (vlfi-move-to-chunk start end minimal)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; primitive chunk operations
(defun vlfi-move-to-chunk (start end &optional minimal) (defun vlfi-move-to-chunk (start end &optional minimal)
"Move to chunk determined by START END. "Move to chunk determined by START END.
When given MINIMAL flag, skip non important operations." When given MINIMAL flag, skip non important operations."
(catch 'abort (vlfi-verify-size)
(let ((changed (not (verify-visited-file-modtime (if (buffer-modified-p)
(current-buffer)))) (and (vlfi-move-to-chunk-2 start end)
(modified (buffer-modified-p)) (not minimal)
(inhibit-read-only t) (vlfi-update-buffer-name))
(start (max 0 start)) (vlfi-move-to-chunk-1 start end)
(end (min end vlfi-file-size)))
(if changed
(setq vlfi-file-size (vlfi-get-file-size buffer-file-name)))
(if (or changed
(<= vlfi-end-pos start)
(<= end vlfi-start-pos))
(progn ; full chunk renewal
(if (and modified
(not (y-or-n-p
"Buffer modified, are you sure? ")))
(throw 'abort nil))
(setq vlfi-start-pos start
vlfi-end-pos end)
(let ((pos (position-bytes (point))))
(erase-buffer)
(insert-file-contents-literally
buffer-file-name nil vlfi-start-pos vlfi-end-pos)
(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
(or (< end vlfi-end-pos)
(< 3 (- start vlfi-start-pos)))
(not (y-or-n-p "Buffer modified, are you sure? ")))
(throw 'abort nil))
(let* ((pos (+ (position-bytes (point))
vlfi-start-pos))
(adjust-chunk (< start vlfi-start-pos))
(adjust-encoding (or adjust-chunk
(< vlfi-end-pos end))))
(if adjust-encoding
(encode-coding-region (point-min) (point-max)
buffer-file-coding-system))
(cond ((< end vlfi-end-pos) ; adjust ends
(let ((offset (- end vlfi-start-pos)))
(if adjust-encoding
(progn (delete-region offset (point-max))
(setq vlfi-end-pos end)))
(setq offset (byte-to-position offset))
(delete-region offset (point-max))
(setq vlfi-end-pos (+ vlfi-start-pos
(position-bytes
(1- offset))))))
((< vlfi-end-pos end)
(goto-char (point-max))
(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))
(insert-file-contents-literally
buffer-file-name nil start vlfi-start-pos)
(setq vlfi-start-pos start))
((< 3 (- start vlfi-start-pos))
(let ((offset (- start vlfi-start-pos)))
(if adjust-encoding
(progn (delete-region (point-min) offset)
(setq vlfi-start-pos start))
(setq offset (byte-to-position offset))
(setq vlfi-start-pos (+ vlfi-start-pos
(position-bytes
(1+ offset))))
(delete-region (point-min) offset)))
(setq vlfi-start-pos start)))
(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))
((< vlfi-end-pos pos) (point-max))
(t (or (byte-to-position (- pos vlfi-start-pos))
(point-min)))))))
(if changed (set-visited-file-modtime)))
(or minimal (vlfi-update-buffer-name)))) (or minimal (vlfi-update-buffer-name))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun vlfi-move-to-chunk-1 (start end)
;;; encoding "Move to chunk determined by START END."
(setq vlfi-start-pos (max 0 start)
vlfi-end-pos (min end vlfi-file-size))
(let ((inhibit-read-only t)
(pos (position-bytes (point))))
(erase-buffer)
(insert-file-contents buffer-file-name nil
vlfi-start-pos vlfi-end-pos)
(let ((shift (vlfi-adjust-chunk vlfi-start-pos vlfi-end-pos)))
(setq vlfi-start-pos (- vlfi-start-pos shift))
(goto-char (or (byte-to-position (+ pos shift))
(point-max)))))
(set-buffer-modified-p nil)
(set-visited-file-modtime))
(defun vlfi-prepare-chunk () (defun vlfi-move-to-chunk-2 (start end)
"Apply proper decoding and adjust chunk start if needed. "Move to chunk determined by START END.
Return number of bytes moved back for this to happen." Return t if move hasn't been canceled."
(let ((status (vlfi-adjust-chunk 'utf-8))) (let ((start (max 0 start))
(unless (car status) ; no success with utf-8, auto-detect (end (min end vlfi-file-size))
(delete-region (point-min) (+ (point-min) (cdr status))) (edit-end (+ (position-bytes (point-max)) vlfi-start-pos)))
(setq vlfi-start-pos (+ vlfi-start-pos (cdr status)) (cond
status (vlfi-adjust-chunk))) ((and (= start vlfi-start-pos) (= end edit-end))
(cdr status))) nil)
((or (<= edit-end start) (<= end vlfi-start-pos))
(defun vlfi-adjust-chunk (&optional encoding) (when (y-or-n-p "Buffer modified, are you sure? ") ; full chunk renewal
"Adjust chunk beginning until content can be properly decoded. (vlfi-move-to-chunk-1 start end)
Try with explicit ENCODING if given, otherwise auto-detect. t))
Return cons \(success-status . number-of-bytes-moved-back\)." ((or (and (<= start vlfi-start-pos) (<= edit-end end))
(setq buffer-file-coding-system (y-or-n-p "Buffer modified, are you sure? "))
(or encoding (let ((pos (+ (position-bytes (point)) vlfi-start-pos))
(detect-coding-region (point-min) (point-max) t))) (shift 0)
(let ((shift 0) (inhibit-read-only t))
(success nil) (cond ((< end edit-end)
(chunk-size (- vlfi-end-pos vlfi-start-pos))) (delete-region (byte-to-position (- end
(while (and (< shift 4) vlfi-start-pos))
(not (setq success (vlfi-decode-status chunk-size))) (point-max)))
(not (zerop vlfi-start-pos))) ((< edit-end end)
(let ((edit-end-pos (point-max)))
(goto-char edit-end-pos)
(insert-file-contents buffer-file-name nil
vlfi-end-pos end)
(vlfi-adjust-chunk vlfi-end-pos end edit-end-pos))))
(cond ((< vlfi-start-pos start)
(delete-region (point-min) (byte-to-position
(- start vlfi-start-pos))))
((< start vlfi-start-pos)
(let ((edit-end-pos (point-max)))
(goto-char edit-end-pos)
(insert-file-contents buffer-file-name nil
start vlfi-start-pos)
(setq shift (vlfi-adjust-chunk start vlfi-start-pos
edit-end-pos))
(goto-char (point-min)) (goto-char (point-min))
(insert-file-contents-literally ; insert 1 byte (insert (delete-and-extract-region edit-end-pos
buffer-file-name nil (1- vlfi-start-pos) vlfi-start-pos) (point-max))))))
(setq shift (1+ shift) (setq vlfi-start-pos (- start shift)
chunk-size (1+ chunk-size) vlfi-end-pos end)
vlfi-start-pos (1- vlfi-start-pos) (goto-char (or (byte-to-position (- pos vlfi-start-pos))
buffer-file-coding-system (point-max))))
(or encoding (set-visited-file-modtime)
(detect-coding-region (point-min) (point-max) t)))) t))))
(cons success shift)))
(defun vlfi-decode-status (size) (defun vlfi-adjust-chunk (start end &optional position)
"Check if decoding followed by encoding results in SIZE bytes." "Adjust chunk at absolute START till END until content can be \
(< (abs (- size (setq vlfi-encode-size properly decoded. Use buffer POSITION as start if given.
(length (encode-coding-string Set `vlfi-encode-size' to size of buffer when encoded.
(decode-coding-region Return number of bytes moved back for this to happen."
(point-min) (point-max) (let ((update-encode-size (not position))
buffer-file-coding-system t) (encode-size 0)
buffer-file-coding-system t))))) (position (or position (point-min)))
4)) (shift 0)
(chunk-size (- end start)))
(while (and (< shift 4)
(< 4 (abs (- chunk-size
(setq encode-size
(length (encode-coding-region
position (point-max)
buffer-file-coding-system
t))))))
(not (zerop start)))
(setq shift (1+ shift)
start (1- start)
chunk-size (1+ chunk-size))
(let ((inhibit-read-only t))
(delete-region position (point-max))
(goto-char position)
(insert-file-contents buffer-file-name nil start end)))
(if update-encode-size
(setq vlfi-encode-size encode-size))
shift))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; search ;;; search