Subject: bug#26694: preview-at-point fails on very long lines with "End of buffer"

From: Ikumi Keita <[email-masked]>
Date: Tue, 30 May 2017 22:50:02 +0900

Hi all,

Now I propose to apply the attached fix.  This doesn't change the action
of "%b" and "%n".  If no objection, I'll commit it soon.

Bye,
Ikumi Keita

diff --git a/preview.el.in b/preview.el.in
--- a/preview.el.in
+++ b/preview.el.in
@@ -1622,11 +1622,8 @@
 	    (unless (eq preview-state 'disabled)
 	      (preview-toggle ovr 'toggle (selected-window))
 	      (throw 'exit t)))))
-      ;; Let-bind `TeX-source-correlate-mode' to nil in order to work around
-      ;; bug#26694.
-      (let ((TeX-source-correlate-mode nil))
-	(preview-region (preview-next-border t)
-			(preview-next-border nil))))))
+      (preview-region (preview-next-border t)
+		      (preview-next-border nil)))))
 
 (defun preview-disabled-string (ov)
   "Generate a before-string for disabled preview overlay OV."
diff --git a/tex-buf.el b/tex-buf.el
--- a/tex-buf.el
+++ b/tex-buf.el
@@ -492,6 +492,11 @@
 	 (setq TeX-current-process-region-p t))
 	((eq file #'TeX-master-file)
 	 (setq TeX-current-process-region-p nil)))
+
+  ;; When we're operating on a region, we need to update the position
+  ;; of point in the region file so that forward search works.
+  (if (string= name "View") (TeX-region-update-point))
+
   (let ((command (TeX-command-expand (nth 1 (assoc name TeX-command-list))
 				     file))
 	(hook (nth 2 (assoc name TeX-command-list)))
@@ -899,17 +904,21 @@
 the current buffer.
 
 Does nothing in case the last command hasn't operated on the
-region."
-  (when TeX-current-process-region-p
+region or `TeX-source-correlate-mode' is disabled."
+  (when (and TeX-current-process-region-p TeX-source-correlate-mode))
     (let ((region-buf (get-file-buffer (TeX-region-file t)))
-	  (current-line (TeX-line-number-at-pos)))
+	  (orig-line (TeX-current-offset))
+	  (pos-in-line (- (point) (max (line-beginning-position)
+				       (or TeX-command-region-begin
+					   (region-beginning))))))
       (when region-buf
 	(with-current-buffer region-buf
 	  (goto-char (point-min))
-	  (when (re-search-forward "!offset(\\(-?[0-9]+\\)")
+	  (when (re-search-forward "!offset(\\(-?[0-9]+\\)" nil t)
 	    (let ((offset (string-to-number (match-string 1))))
 	      (goto-char (point-min))
-	      (forward-line (- current-line (1+ offset))))))))))
+	      (forward-line (- orig-line offset))
+	      (forward-char pos-in-line))))))))
 
 (defun TeX-view ()
   "Start a viewer without confirmation.
@@ -918,11 +927,7 @@
   (interactive)
   (let ((output-file (TeX-active-master (TeX-output-extension))))
     (if (file-exists-p output-file)
-	(progn
-	  ;; When we're operating on a region, we need to update the position
-	  ;; of point in the region file so that forward search works.
-	  (TeX-region-update-point)
-	  (TeX-command "View" 'TeX-active-master 0))
+	(TeX-command "View" 'TeX-active-master 0)
       (message "Output file %S does not exist." output-file))))
 
 (defun TeX-output-style-check (styles)
@@ -2140,17 +2145,6 @@
 		") }\n"
 		trailer)
 	(setq TeX-region-orig-buffer orig-buffer)
-	;; Position point at the line/col that corresponds to point's line in
-	;; orig-buffer in order to make forward search work.  Move point only
-	;; when `TeX-source-correlate-mode' is non-nil, in order to work around
-	;; bug#26694.
-	(when TeX-source-correlate-mode
-	    (let ((line-col (with-current-buffer orig-buffer
-			   (cons (TeX-line-number-at-pos)
-				 (current-column)))))
-	   (goto-char (point-min))
-	   (forward-line (1- (abs (- header-offset (car line-col)))))
-	   (forward-char (cdr line-col))))
 	(run-hooks 'TeX-region-hook)
 	(if (string-equal (buffer-string) original-content)
 	    (set-buffer-modified-p nil)
diff --git a/tex.el b/tex.el
--- a/tex.el
+++ b/tex.el
@@ -1335,7 +1335,13 @@
 	   (format "org.%s.%s.Window" de app)
 	   "SyncView"
 	   (buffer-file-name)
-	   (list :struct :int32 (TeX-line-number-at-pos)
+	   (list :struct :int32 (1+ (TeX-current-offset))
+		 ;; FIXME: Using `current-column' here is dubious.
+		 ;; Most of CJK letters count as occupying 2 columns,
+		 ;; so the column number is not equal to the number of
+		 ;; the characters counting from the beginning of a
+		 ;; line.  What is the right number to specify here?
+		 ;; number of letters? bytes in UTF8? or other?
 		 :int32 (1+ (current-column)))
 	   :uint32 0))
       (error "Couldn't find the %s instance for %s" (capitalize app) uri))))
@@ -1385,7 +1391,7 @@
 		 "%d" (mode-io-correlate " \"# %n '%b'\"")) "dviout")
       ("SumatraPDF"
        ("SumatraPDF -reuse-instance"
-	(mode-io-correlate " -forward-search \"%b\" %n") " %o")
+	(mode-io-correlate " -forward-search %b %n") " %o")
        "SumatraPDF")
       ("dvips and start" "dvips %d -o && start \"\" %f" "dvips")
       ("start" "start \"\" %o")))
@@ -2090,11 +2096,14 @@
   (let ((synctex-output
 	 (with-output-to-string
 	   (call-process "synctex" nil (list standard-output nil) nil "view"
-			 "-i" (format "%s:%s:%s" (TeX-line-number-at-pos)
-				      (current-column)
+			 "-i" (format "%s:%s:%s" (1+ (TeX-current-offset))
+				      ;; FIXME: Using `current-column'
+				      ;; here is dubious.  See comment in
+				      ;; `TeX-evince-sync-view-1'.
+				      (1+ (current-column))
 				      file)
 			 "-o" (TeX-active-master (TeX-output-extension))))))
-    (when (string-match "Page:\\([0-9]+\\)" synctex-output)
+    (when (string-match "^Page:\\([0-9]+\\)" synctex-output)
       (match-string 1 synctex-output))))
 
 (defun TeX-synctex-output-page ()