Haken, der anzeigt, wann der Cursor durch Scrollen bewegt wurde

7

Inspiriert von dieser Frage: Lassen Sie Emacs den Cursor vom Bildschirm entfernen. Ich denke darüber nach, einen Nebenmodus zu schreiben, der den Cursor an einer festen Position hält, die nicht von Bildlaufvorgängen betroffen ist. Ich habe einige Ideen, wie ich dies implementieren könnte, aber es würde einen Haken erfordern, um mich wissen zu lassen, wenn der Cursor vom Bildschirm "gedrückt" wird.

Irgendwo im Darm von Emacs gibt es Code, der aufgerufen wird, wenn der Ort von pointaus dem Display verschoben wird. Obwohl gesagt wurde, dass der Code, der dieses Verhalten steuert, tief mit dem C-Quellcode zusammenlebt, würde ich gerne wissen, ob ich auf irgendeine Weise benachrichtigt werden kann, wenn dies bevorsteht.

Kann ich auf irgendeine Weise benachrichtigt werden, wenn ein Bildlaufbefehl den Cursor bewegt? Oder gibt es zumindest eine Möglichkeit, wie ich benachrichtigt werden kann, wenn die Anzeige gescrollt werden soll?


Update: Ich bin nicht mehr Planung auf einen kleineren Modus schreibt dies zu erreichen , weil ein neues Paket nur auf veröffentlicht wurde GNU ELPA genannt , scroll-restoredass bietet genau die Eigenschaften , dass ich dachte , mich Umsetzung!

Nispio
quelle

Antworten:

5

Ja .

Die Funktionen in window-scroll-functionswerden kurz vor einer erneuten Anzeige aufgerufen, die ein Scrollen verursachen würde. Jede Funktion gibt zwei Argumente zurück, das Fenster windowund die neue Fensterstartposition new-start. Sie können aufrufen , um die aktuelle Fensterstartposition, die aktuelle Fensterendposition und die neue Fensterendposition abzurufen. Wenn der Punkt nicht zwischen und liegt , wird er verschoben. Soweit ich das beurteilen kann, werden diese Funktionen in allen Fällen aufgerufen, die die Ausdehnung eines Fensters ändern, einschließlich Scrollen und Ändern der Größe. Sie werden auch aufgerufen, wenn in einem Fenster ein Puffer angezeigt wird (weil er gerade erstellt wurde oder jetzt einen neuen Puffer anzeigt).(window-start window)(window-end window)(window-end window t)new-start(window-end window t)

Damit Bildlaufbefehle den Punkt nicht verschieben, möchten Sie wahrscheinlich den aktuellen Punkt in diesem Hook speichern und etwas tun post-command-hook. Da sich der Punkt aufgrund des Bildlaufs verschieben muss, würden Sie ihn vermutlich speichern und wiederherstellen pre-command-hook.

Gilles 'SO - hör auf böse zu sein'
quelle
1
Ausgezeichnet! Ich muss zugeben, ich hatte nicht erwartet, dass die Antwort "Ja" lautet.
Nispio
Gibt es so etwas wie (window-start)horizontales Scrollen? (Beachten Sie, dass window-hscrolldies nicht der Fall ist, wenn sich die Schriftart im Puffer von der Standardschriftart unterscheidet.)
AlwaysLearning
1

@ Gilles Antwort ist der richtige Weg. Ich werde dieses hier für die Informationen und die Hacks behalten.

Ich glaube, die pointBewegung wird von den C-Funktionen ausgeführt window_scroll_line_basedund window_scroll_pixel_based(abhängig von Ihren Rahmenparametern). Diese Funktionen sind der Lisp-Maschine nicht ausgesetzt, daher können Sie sie nicht empfehlen. Sie müssten Funktionen beraten, die sie aufrufen.

Zwei der (lisp-zugänglichen) Funktionen, die dies tun können, sind scroll-upund scroll-down. So habe ich von ihnen erfahren:

  1. Gehe zu einem langen Puffer.
  2. Wählen Sie eine kleine Region.
  3. Rufen Sie an , M-x (put-text-property (region-beginning) (region-end) 'point-left (lambda (&rest _) (error "Point leaving"))). Dies löst einen Fehler aus, wenn der Punkt die Region verlässt.
  4. Aktivieren M-x toggle-debug-on-error.
  5. Stellen Sie sicher, dass sich der Punkt innerhalb dieser Region befindet.
  6. Scrollen Sie mit dem Mausrad, bis der Punkt aus dem Bereich gezogen wird.

Sie erhalten einen Backtrace-Puffer wie diesen, der die scroll-downFunktion deutlich macht.

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)

Ich folgte scroll-downseiner C-Definition, die window_scrollmich zu diesen beiden obigen Funktionen führte.

Was du tun kannst

Sie können scroll-down/upmit einem aroundRat beraten (sowie alle anderen Funktionen, die ebenfalls zu einer Punktbewegung führen können). Verwenden Sie diesen Rat, um zu überprüfen, ob sich die Position von pointgeändert hat, und notieren Sie die alte Position. Und dann mach was du willst.

Seien Sie gewarnt, Ratschläge sind sehr unzuverlässig, wenn es um C-Funktionen geht. Einige wichtige Funktionen haben spezielle Adressen in bytekompiliertem Code, was bedeutet, dass beim Kompilieren des Codes keine Hinweise dazu aufgerufen werden. Ich denke nicht, dass dies hier der Fall sein wird, aber ich dachte, Sie sollten nicht.

Malabarba
quelle
Ich denke nicht beraten scroll-downund scroll-upwäre hier nützlich. Es gibt viele andere Möglichkeiten, wie gescrollt werden kann. Zumindest alle Befehle mit der isearch-scrollEigenschaft sollten als Bildlaufbefehle betrachtet werden.
Gilles 'SO - hör auf böse zu sein'
@ Gilles, deshalb sagte ich "sowie alle anderen Funktionen, die ebenfalls zu Punktbewegungen führen könnten" . Aber deine Antwort sieht definitiv besser aus!
Malabarba
Das ist ein ziemlich cleveres Debugging!
Nispio