Móc cho biết khi con trỏ đã được di chuyển bằng cách cuộn


7

Lấy cảm hứng từ câu hỏi này: Hãy để Emacs di chuyển con trỏ ra khỏi màn hình , tôi đang xem xét việc viết một chế độ nhỏ sẽ giữ con trỏ ở một vị trí cố định không bị ảnh hưởng bởi các thao tác cuộn. Tôi có một số ý tưởng về cách tôi có thể thực hiện điều này, nhưng nó sẽ cần một cái móc để cho tôi biết khi con trỏ bị "đẩy" ra khỏi màn hình.

Ở đâu đó trong ruột của Emacs, tồn tại mã được gọi khi vị trí của pointđược di chuyển khỏi màn hình. Mặc dù người ta nói rằng mã kiểm soát hành vi này sống sâu với mã nguồn C, tôi muốn biết liệu có cách nào tôi có thể được thông báo khi nó sắp xảy ra hay không.

Có cách nào tôi có thể được thông báo khi lệnh cuộn sắp di chuyển con trỏ không? Hoặc ít nhất, có cách nào để tôi có thể được thông báo khi màn hình sắp được cuộn không?


Cập nhật: Tôi không còn có kế hoạch viết một chế độ nhỏ để đạt được điều này bởi vì một gói mới vừa được phát hành trên GNU ELPA được gọi là scroll-restorecung cấp chính xác các tính năng mà tôi đã nghĩ đến khi tự thực hiện!

Câu trả lời:


5

.

Các chức năng trong window-scroll-functionsđược gọi ngay trước khi hiển thị lại sẽ gây ra cuộn. Mỗi hàm trả về hai đối số, cửa sổ windowvà vị trí bắt đầu cửa sổ mới new-start. Bạn có thể gọi để có được vị trí bắt đầu cửa sổ hiện tại, để có được vị trí kết thúc cửa sổ hiện tại và để có được vị trí kết thúc cửa sổ mới. Nếu điểm không nằm giữa và , nó sẽ bị di chuyển. Theo như tôi có thể nói, các chức năng này được gọi trong mọi trường hợp thay đổi phạm vi của một cửa sổ, bao gồm cuộn và thay đổi kích thước. Chúng cũng được gọi khi một cửa sổ bắt đầu hiển thị bộ đệm (vì nó vừa được tạo hoặc vì hiện tại nó đang hiển thị bộ đệm mới).(window-start window)(window-end window)(window-end window t)new-start(window-end window t)

Để làm cho các lệnh cuộn xuất hiện không di chuyển điểm, có lẽ bạn sẽ muốn lưu điểm hiện tại trong hook này và thực hiện một cái gì đó trong post-command-hook. Vì điểm sẽ phải di chuyển do cuộn, nên có lẽ bạn sẽ lưu nó và khôi phục lại pre-command-hook.


1
Thông minh! Tôi phải thừa nhận, tôi đã không mong đợi câu trả lời là "có".
nispio

Có bất cứ điều gì như (window-start)cho cuộn ngang? (lưu ý rằng window-hscrollkhông thực hiện công việc khi phông chữ trong bộ đệm khác với phông chữ mặc định).
Luôn luôn học

1

@Gilles trả lời là cách đúng đắn để đi. Tôi sẽ giữ cái này ở đây để biết thông tin và hack.

Tôi tin rằng pointchuyển động được thực hiện bởi các hàm C window_scroll_line_basedwindow_scroll_pixel_based(phụ thuộc vào tham số khung của bạn). Các chức năng này không được tiếp xúc với máy lisp, vì vậy bạn không thể tư vấn cho chúng. Bạn sẽ phải tư vấn các chức năng gọi chúng.

Hai trong số các hàm (lisp access) có thể làm điều này là scroll-upscroll-down. Đây là cách tôi tìm hiểu về họ:

  1. Đi đến một số bộ đệm dài.
  2. Chọn một vùng nhỏ.
  3. Gọi , M-x (put-text-property (region-beginning) (region-end) 'point-left (lambda (&rest _) (error "Point leaving"))). Điều này sẽ ném một lỗi khi điểm rời khỏi khu vực.
  4. Kích hoạt M-x toggle-debug-on-error.
  5. Hãy chắc chắn rằng điểm nằm trong khu vực này.
  6. Cuộn bằng bánh xe chuột cho đến khi điểm được kéo ra khỏi khu vực.

Bạn sẽ được cung cấp một bộ đệm backtrace như thế này, trong đó chỉ rõ scroll-downchức năng.

Debugger entered--Lisp error: (error "Point leaving")
  signal(error ("Point leaving"))
  error("Point leaving")
  (lambda (&rest _) (error "Point leaving"))(1508 1192)
  scroll-down(10)
  funcall(scroll-down 10)
  mwheel-scroll((double-mouse-4 (#<window 50 on *Backtrace*> 1299 (578 . 545) 77086296 nil 1299 (57 . 25) nil (398 . 20) (10 . 21)) 2))
  funcall-interactively(mwheel-scroll (double-mouse-4 (#<window 50 on *Backtrace*> 1299 (578 . 545) 77086296 nil 1299 (57 . 25) nil (398 . 20) (10 . 21)) 2))
  call-interactively(mwheel-scroll nil nil)
  command-execute(mwheel-scroll)

Tôi đã làm theo scroll-downđịnh nghĩa C của nó, dẫn tôi đến window_scroll, dẫn tôi đến hai chức năng trên.

Bạn có thể làm gì

Bạn có thể tư vấn scroll-down/upvới một aroundlời khuyên (cũng như bất kỳ chức năng nào khác cũng có thể dẫn đến chuyển động điểm). Sử dụng lời khuyên này để kiểm tra xem vị trí của pointđã thay đổi và ghi lại vị trí cũ. Và sau đó làm bất cứ điều gì bạn muốn với nó.

Được cảnh báo, lời khuyên rất không đáng tin cậy khi nói đến chức năng C. Một số hàm quan trọng có địa chỉ đặc biệt trong mã được biên dịch byte, có nghĩa là lời khuyên về chúng không được gọi khi mã được biên dịch. Tôi không nghĩ rằng đó sẽ là trường hợp ở đây, nhưng tôi đoán bạn không nên.


Tôi không nghĩ rằng tư vấn scroll-downscroll-upsẽ hữu ích ở đây. Có nhiều cách cuộn khác có thể xảy ra. Ít nhất tất cả các lệnh có thuộc isearch-scrolltính nên được coi là lệnh cuộn.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles đó là lý do tại sao tôi nói "cũng như bất kỳ chức năng nào khác cũng có thể dẫn đến chuyển động điểm" . Nhưng câu trả lời của bạn chắc chắn có vẻ tốt hơn!
Malabarba

Đó là một số gỡ lỗi khá thông minh!
nispio
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.