Gibt es eine Möglichkeit, das Gesicht am Bild x / y (Mausposition) zu bestimmen?

8

Wenn Sie versuchen, bestimmte Modi zu thematisieren, ist es nicht möglich, den Punkt auf dem Themenelement zu platzieren (z. B. zu tun C-u C-x =) und das verwendete Gesicht zu identifizieren.

Mein Gedanke ist, die Maus zu verwenden, um das verwendete Gesicht zu identifizieren, aber alles, was ich bekommen kann, ist die Position x, y des Rahmens (mit (mouse-position))

Von dort weiß ich nicht, wie ich die Gesichtsdefinition an diesen Koordinaten erhalten soll.

Jede Hilfe wird geschätzt.

ocodo
quelle

Antworten:

4

Hier ist eine Möglichkeit. Sie müssen den Befehl an ein Mausereignis binden. Wenn Sie jedoch einen Mausklick verwenden, müssen Sie wahrscheinlich das Ereignis für den anderen Teil des Klicks (z ignore. B. nach unten) an binden . Dies ist nur ein Beispiel - Sie möchten möglicherweise keinen C-mouse1solchen Befehl verschwenden .

Die Hauptfunktion (eigentlich Befehl) ist describe-char. Es beschreibt den Punkt an einer bestimmten Pufferposition. Ein Teil dieser Beschreibung enthält die Texteigenschaften und Überlagerungen an dieser Position. Wenn die Eigenschaft faceeine davon ist, wird ihr Wert angezeigt.

(defun foo (event)
  (interactive "e")
  (let* ((mouse-pos  (event-start event))
         (pos-pt     (posn-point mouse-pos)))
    (describe-char pos-pt)))

(global-set-key [(control down-mouse-1)] 'ignore)
(global-set-key [(control mouse-1)] 'foo)

Dies ist möglicherweise etwas besser - die oben genannten Funktionen funktionieren in einigen Kontexten möglicherweise nicht:

(defun foo (event)
  (interactive "e")
  (let* ((mouse-pos  (event-start event))
         (mouse-buf  (window-buffer (posn-window mouse-pos)))
         (pos-pt     (posn-point mouse-pos)))
    (with-current-buffer mouse-buf (describe-char pos-pt))))

(Beachten Sie auch, dass C-x =gebunden ist what-cursor-position, was verwendet describe-char. Sie waren also auf dem richtigen Weg mit C-u C-x =.)


In Bezug auf Ido: Im Gegensatz zu Icomplete, das eine Überlagerung verwendet, fügt der Ido-Modus Text in den Minibuffer ein. Der Grund, warum der obige Code für diesen Text nicht funktioniert, ist, dass der Ido-Modus den Text am Anfang jedes Befehls mit entfernt pre-command-hook. Wenn der obige Befehl ausgeführt wird, wurde der Text mit den Vervollständigungen bereits entfernt.

Der folgende Code behebt dieses Problem nur für den Ido-Modus. Der Text mit den Vervollständigungen am Anfang wird erneut eingefügt und am Ende werden die Vervollständigungen entfernt.

(defun foo (event)
  (interactive "e")
  (when (and (boundp 'ido-mode)  ido-mode) (ido-exhibit))
  (let* ((mouse-pos  (event-start event))
         (mouse-buf  (window-buffer (posn-window mouse-pos)))
         (pos-pt     (posn-point mouse-pos)))
    (with-current-buffer mouse-buf (describe-char pos-pt)))
  (when (and (boundp 'ido-mode)  ido-mode) (ido-tidy)))
Drew
quelle
Nizza @ zog sehr geschätzt
ocodo
Oh, leider, wenn dies im Minibuffer mit ido-vertikal (und anderen) verwendet wird, wird die Nachricht: describe-char: No character follows specified positionvon description -char zurückgegeben. Ich denke, es liegt daran, dass der Minibuffer irgendwann nach dem Ereignis gelöscht wird. Ich nahm an 'ignore, dass das aufhören würde, aber das passiert nicht. Irgendwelche Ideen?
ocodo
Bitte geben Sie ein schrittweises Rezept. (Es funktioniert für mich: M-x some-text, C-mouse-1an diesem Text in dem Minipuffer) . Sie müssen natürlich mit der Maus klicken an einer Position , den Text hat. Wenn Sie nach dem Ende des Textes klicken, wird der von Ihnen erwähnte Fehler angezeigt.
Drew
Verwenden Sie den Ido-Vertikal-Modus oder den Ido-Grid-Modus mit dem Ido-Modus. Klicken Sie jetzt bei gedrückter Strg-Taste auf den Ido-Auswahltext im Minibuffer. Error.
ocodo
Wenn Sie auf die Liste der Abschlüsse für den Ido- oder Icomplete-Modus klicken, klicken Sie über den Text im Puffer (Minibuffer) hinaus. Sie klicken auf eine Überlagerung (nur). Wenn Sie auf eine Überlagerung klicken, die sich über dem Puffertext befindet, gibt es kein Problem. Wenn Sie jedoch über das Pufferende hinaus klicken (was Sie gerade tun), wird die Fehlermeldung angezeigt.
Drew
2

Wenn Sie den Punkt nicht an der richtigen Stelle platzieren und verwenden können C-u C-x =, kann dies daran liegen, dass das relevante Element über die Vorher / Nachher-Zeichenfolge eines Overlays angezeigt wird oder dass dieses Element verschwindet / sich ändert, wenn Sie versuchen, einen Punkt einzufügen es oder wenn du C-u C-x =.

Sie können versuchen, diese Probleme wie folgt zu vermeiden:

  • Verwenden Sie posn-at-x-ydiese Option, um eine Beschreibung der an dieser x / y-Koordinate befindlichen Elemente zurückzugeben. Wenn es sich beispielsweise um einen Text handelt, der aus einer Nach- / Vor-Zeichenfolge stammt, wird diese Zeichenfolge dort (sowie die Position innerhalb dieser Zeichenfolge) erwähnt, sodass Sie die auf diese Zeichenfolge an dieser Position angewendete Gesichtseigenschaft nachschlagen können.
  • Sie können den Code "im Hintergrund" anstatt über einen Befehl ausführen. Zum Beispiel run-with-timerkönnen Sie den Code jede Sekunde ausführen und das Ergebnis in eine Art Debug-Puffer Ihrer Wahl drucken.
Stefan
quelle
1

Sie können das Paket offen verwenden , um eine lesbare Textdarstellung eines Textes mit Gesichtsinformationen zu erstellen. Zum Beispiel:

(defun foo (arg)
  (if arg 1 2))

Führen Sie M-x faceup-vire-buffer RETFolgendes aus, und Folgendes wird angezeigt:

(«k:defun» «f:foo» («v:arg»)
  («k:if» arg 1 2))

Die Standardflächen für die Schriftsperre werden wie kfür mit Kurznamen dargestellt font-lock-keyword-face, während Nicht-Standardflächen mit ihrem vollständigen Namen dargestellt werden.

(Faceup ist ein Regressionstestsystem zum Hervorheben von Paketen, z. B. Schlüsselwörtern zum Sperren von Schriftarten. Die Textdarstellung wird als Referenzdatei gespeichert.)

BEARBEITEN:

Um die Frage im Kommentar zu beantworten: "Wenn ich versuche, die in einer Minibuffer-Anzeige verwendeten Gesichter zu debuggen, gibt mir das dann immer noch die Informationen?"

Ja tut es. Sie müssen die Funktion jedoch an einen Schlüssel binden, da die Ausführung mit M-xnicht funktioniert, wenn der Minibuffer verwendet wird. Zum Beispiel:

(global-set-key (kbd "<f6>") 'faceup-view-buffer)

Wenn Sie mit dem "Minibuffer" wirklich den Echo-Bereich gemeint haben - dass es so ist, möchten Sie die aktuelle Nachricht überprüfen, die Sie etwas mehr benötigen. Die folgende Funktion erledigt dies:

(defun my-faceup-view-current-message ()
  (interactive)
  (let ((msg (current-message)))
    (unless msg
      (error "Echo area is empty"))
    (with-temp-buffer
      (insert msg)
      (faceup-view-buffer))))

Zum Beispiel Folgendes:

(let ((s "My Message"))
  (add-text-properties 3 (length s) '(face font-lock-warning-face) s)
  (message s)
  (my-faceup-view-current-message))

Wird dir zeigen:

My «w:Message»
Lindydancer
quelle
Wenn ich versuche, die in einer Minibuffer-Anzeige verwendeten Gesichter zu debuggen, gibt mir dies dann immer noch die Informationen?
ocodo
@EmacsFodder Ja, siehe meine aktualisierte Antwort.
Lindydancer
Um genau zu sein, hat mich die Frage dazu gebracht, die Gesichter von ido-vertikal und ido-Gitter zu bekommen. Beide leeren den Puffer vor dem Mausereignis (wie es scheint).
ocodo
Technisch gesehen ist die direkte Antwort auf die Frage nicht möglich. Diese Methode ist ein bisschen einfacher als das Durchsuchen des Emacslisp eines beliebigen Modus. Obwohl das so einfach ist wie: Cs defface Frau o
ocodo
1

Eine alternative Lösung könnte darin bestehen, einen Farbwähler zu verwenden und den list-faces-for-colorunten definierten Farbwert anzugeben (falls der Farbwähler etwas abweicht, verwenden Sie das Distanzargument):

(defun list-faces-for-color (color &optional distance)
  "List faces which use COLOR as fg or bg color.

            Accept colors within DISTANCE which defaults to 0."
  (interactive (list (read-color "Color: ")
                     (and current-prefix-arg
                          (prefix-numeric-value current-prefix-arg))))
  (with-help-window (get-buffer-create (format " *%s*" this-command))
    (dolist (face (sort
                   (list-faces--for-color color distance)
                   (lambda (f1 f2)
                     (string< (symbol-name f1)
                              (symbol-name f2)))))
      (list-faces--print-face face)
      (terpri))))

(defun list-faces--print-face (face)
  "Print face and its parents if any."
  (with-current-buffer standard-output
    (let ((fchain (cdr (list-faces--inheritance-chain face :foreground)))
          (bchain (cdr (list-faces--inheritance-chain face :background))))
      (insert (propertize (format "%s" face) 'face face))
      (cond (fchain
             (dolist (face fchain)
               (insert " > " (propertize (format "%s" face) 'face face))))
            (bchain
             (dolist (face bchain)
               (insert " > " (propertize (format "%s" face) 'face face))))))))

(defun list-faces--inheritance-chain (face attr)
  "Return inheritence change for face and attr."
  (let ((g (face-attribute face attr)))
    (if (and (stringp g)
             (not (string= "unspecified" g)))
        (list face)
      (let ((inherit (face-attribute face :inherit)))
        (when inherit
          (if (facep inherit)
              (cons face
                    (list-faces--inheritance-chain inherit attr))
            (if (consp inherit)
                (cl-dolist (face inherit)
                  (let ((res nil))
                    (when (and (facep face)
                               (setq res (list-faces--inheritance-chain face attr)))
                      (cl-return res)))))))))))


(defun list-faces--attribute (face attr)
  "Get face attribute of face as defined or inherited."
  (let* ((chain (list-faces--inheritance-chain face attr)))
    (cl-dolist (f (nreverse chain))
      (let ((g (face-attribute f attr)))
        (when (and (stringp g)
                   (not (string= "unspecified" g)))
          (cl-return g))))))



(defun list-faces--for-color (color &optional distance)
  "Return all faces with COLOR as fg or bg withing DISTANCE."
  (let ((faces ())
        (distance (or distance 0)))
    (mapatoms (lambda (atom)
                (when (facep atom)
                  (let ((fg (list-faces--attribute atom :foreground))
                        (bg (list-faces--attribute atom  :background)))
                    (when (or (and fg
                                   (<= (color-distance
                                        fg
                                        color)
                                       distance))
                              (and bg
                                   (<= (color-distance
                                        bg
                                        color)
                                       distance)))
                      (push atom faces))))))
    (delete-dups faces)))
Clemera
quelle