2010-03-02 6 views
17

Diese Frage steht im Zusammenhang mit einer anderen, Emacs :TODO indicator at left side. Ich bin kürzlich auf einen kleinen Modus gestoßen, den ich sehr gerne FixmeMode nenne. Es unterstützt die automatische Markierung von TODO Marken und die Navigation zwischen ihnen. Ich denke jedoch, dass es sinnvoller ist, die "TODO" -Strings nur in Kommentaren zu erkennen, anstatt die gesamte Datei zu verschmutzen. Ist es möglich?Emacs: Hervorhebung TODO * nur * in Kommentaren

Antwort

24

Schauen Sie sich die Bibliothek fic-mode.el, wurde in C++ und Emacs-Lisp verifiziert.

Es wurde speziell zur Beantwortung dieser Frage geschrieben.

Die Installation ist wie jedes Standard-Paket:

(require 'fic-mode) 
(add-hook 'c++-mode-hook 'turn-on-fic-mode) 

Obwohl Wei Hu hat für eine einfache Möglichkeit zu bitten, es zu mehreren Modi hinzuzufügen, geht so hier:

(defun add-something-to-mode-hooks (mode-list something) 
    "helper function to add a callback to multiple hooks" 
    (dolist (mode mode-list) 
    (add-hook (intern (concat (symbol-name mode) "-mode-hook")) something))) 

(add-something-to-mode-hooks '(c++ tcl emacs-lisp) 'turn-on-fic-mode) 
+0

Schöne Arbeit, danke! Können Sie kurz erklären, wie Sie diese Aufgabe mit so wenig Code gelöst haben? Es wäre auch schön, eine anpassbare Variable 'fic-modes' zu haben, mit der alle aktivierten Modi definiert werden können, anstatt die Modus-Hooks einzeln hinzufügen zu müssen. –

+1

@WeiHu Wie es mit so wenig Code gelöst wurde, lohnt es sich, nur den Code zu lesen - Font-Lock bietet einen reichhaltigen Rahmen, um das Problem zu lösen. Der eigentliche Schlüssel war die Verwendung einer Schriftartverriegelungseinstellung, die eine Routine aufruft (im Gegensatz zu nur einer Regexp), die festlegt, welche Zeichenfolgen hervorgehoben werden sollen (das wäre "fic-search-for-keyword"), und diese Routine prüft nur dass die Zeichenfolge in einem Kommentar/einer Zeichenfolge enthalten ist. –

+0

Sie nutzen also die Tatsache, dass Strings und Kommentare spezielle Schriftarten verwenden. Könnte es falsche Positive geben? –

3

Es ist möglich, aber ein bisschen schwieriger. Der Fixme-Modus verwendet font-lock, um seine Hervorhebung vorzunehmen. Daher arbeitet er auf einer "as-you-type" -Basis, um die Schlüsselwörter hervorzuheben. Die Font-Lock-Funktion schaltet sich auf einem sehr niedrigen Level ein und läuft im Grunde nach jeder Änderung des Pufferinhalts. Es ist jedoch sehr optimiert, wodurch es auf modernen Computern augenblicklich erscheint.

Der TODO-Indikator im linken Rand ist statisch. Führe die Funktion aus und alle aktuellen TODOs sind hervorgehoben; Ändern Sie den Puffer (Hinzufügen oder Entfernen von TODOs) ändert nicht den Interferenzstreifen; das wird nur geändert, wenn die Funktion erneut ausgeführt wird.

Ihr Ansatz müsste in Syntaxtabellen gehen, zuerst bestimmen, wenn Sie in einem Kommentar sind und dann nach den Schlüsselwörtern suchen. Der schwierige Teil kommt dabei interaktiv (d. H. Beim Tippen). Sie sollten in der Lage sein, in die font-lock Konstrukte einhaken, um dies zu tun, aber die Funktion, die Sie für die Suche nach der Kommentarsyntaxtabelle und dann für die Schlüsselwörter bieten, ist sehr effizient, da es jedes Mal ausgeführt wird, wenn sich ein Puffer ändert es wird nur auf der veränderten Region laufen, denke ich). Sie würden das alles in font-lock-syntactic-keywords anstelle von font-lock-keywords stopfen, weil das syntaktische Schlüsselwort Pass vor dem syntaktischen Pass passiert (was passiert, bevor das Schlüsselwort pass), und Sie müssen TODO innerhalb von Kommentaren setzen, bevor Kommentare selbst gesetzt werden.

Leider ist es kein voll funktions-Code Antwort .....

+0

Wow. Das ist viel schwieriger, als ich gedacht hätte. –

+0

Es ist einfacher und schwieriger als ich dachte. Einfacher in dem Sinne, dass der gesamte Font-Lock-Haken und die Bindung nicht so schwer waren, aber viel, viel schwerer, weil es wirklich schwierig ist herauszufinden, ob Sie in einem Kommentar stehen. Zumindest konnte ich es bisher nicht herausfinden. Also noch kein Codebeispiel ..... –

2

Vielleicht wird dies helfen: es gibt eine fn c-in-literal in cc-Modus, und ein ähnliches csharp-in-literal in csharp Modus. Der Rückgabewert ist c, wenn in einem C-style-Kommentar, c++ wenn in einem C++ Stil Kommentar. Sie könnten das dem Code unter Emacs :TODO indicator at left side hinzufügen, um zu bekommen, was Sie wollen.

(defun annotate-todo() 
    "put fringe marker on TODO: lines in the curent buffer" 
    (interactive) 
    (let (lit) 
    (save-excursion 
    (goto-char (point-min)) 
    (while (re-search-forward "TODO:" nil t) 
     (progn 
     (setq lit (c-in-literal)) ;; or csharp-in-literal 
     (if (or (eq lit 'c) (eq lit 'c++)) 
      (let ((overlay (make-overlay (- (point) 5) (point)))) 
       (overlay-put overlay 'before-string 
          (propertize "A" 
             'display 
             '(left-fringe ;; right 
             horizontal-bar 
             better-fringes-important-bitmap)))))))))) 
+0

Danke für deine Antwort. Ich würde gerne eine Antwort hören, die den FixmeMode verbessert, weil er auf einer as-you-type-Basis funktioniert, wie @Joe gesagt hat. –

+0

Ja, das macht Sinn.Als Nebeneffekt denke ich, dass die Hervorhebung der Dinge, die bereits auf dem Bildschirm sind, nicht so nützlich ist, wie eine visuelle Anzeige der ungefähren Position des FIXME im Quellcode bereitzustellen. Visual Diff-Tools tun dies, ebenso wie Eclipse, wenn Kompilierungsfehler angezeigt werden, und Visual Studio, denke ich. Ich fragte getrennt darüber: http://stackoverflow.com/questions/2348679/emacs-todo-indicator-on-left-fringe-has-a-strange-side-effect-deleting-charact – Cheeso