2009-10-13 10 views
11

In TextMate kann man ctrl-shift-w verwenden, um Text in ein Open/Close-Tag und ctrl-shift-cmd-w zu umbrechen, um jede Zeile in einer Region in Open/Close-Tags zu umbrechen. Wie kann ich diese Funktionalität in Emacs mit emacs lisp implementieren?Wrap Auswahl in Open/Close Tag wie TextMate?

 
emacs 

becomes 

<p>emacs</p> 

Und ...

 
emacs 
textmate 
vi 

becomes 

<li>emacs</li> 
<li>textmate</li> 
<li>vi</li> 

Antwort

7

This answer gibt Ihnen eine Lösung, die die Region für die Verpackung (wenn Sie es ändern spitze Klammern verwenden).

Diese Routine werden Sie für den Tag aufgefordert, zu verwenden und soll jede Zeile in der Region mit einem Öffnen/Schließen-Tag dieser Art Tag:

(defun my-tag-lines (b e tag) 
    "'tag' every line in the region with a tag" 
    (interactive "r\nMTag for line: ") 
    (save-restriction 
    (narrow-to-region b e) 
    (save-excursion 
     (goto-char (point-min)) 
     (while (< (point) (point-max)) 
     (beginning-of-line) 
     (insert (format "<%s>" tag)) 
     (end-of-line) 
     (insert (format "</%s>" tag)) 
     (forward-line 1))))) 

* Hinweis: * Wenn Sie die tag wollten immer li sein, dann entfernen Sie das Tag-Argument, entfernen Sie den Text \nMTag for line: aus dem Aufruf zu interaktiven, und aktualisieren Sie die Einfügeaufrufe, um nur die "<li\>" einfügen, wie Sie erwarten würden.

3

yasnippet ist eine besonders gute Implementierung von Textmates Snippet-Syntax für Emacs. Damit können Sie alle Textmate-Snippets importieren. Wenn Sie es dann installieren, das Snippet, das ich geschrieben habe sollte das tun, was Sie wollen:

(defun wrap-region-or-point-with-html-tag (start end) 
    "Wraps the selected text or the point with a tag" 
    (interactive "r") 
    (let (string) 
    (if mark-active 
     (list (setq string (buffer-substring start end)) 
      (delete-region start end))) 
    (yas/expand-snippet (point) 
         (point) 
         (concat "<${1:p}>" string "$0</${1:$(replace-regexp-in-string \" .*\" \"\" text)}>")))) 

(global-set-key (kbd "C-W") 'wrap-region-or-point-with-html-tag) 

EDIT: (Okay das bei Festsetzung dies mein letzter Versuch ist, ist es genau wie Textmate-Version Es gibt sogar Zeichen nach einem ignoriert.. Leerzeichen im End-Tag)

Entschuldigung, ich habe Ihre Frage falsch gelesen. Diese Funktion sollte jede Zeile in der Region bearbeiten.

(defun wrap-lines-in-region-with-html-tag (start end) 
    "Wraps the selected text or the point with a tag" 
    (interactive "r") 
    (let (string) 
    (if mark-active 
     (list (setq string (buffer-substring start end)) 
       (delete-region start end))) 
    (yas/expand-snippet 
    (replace-regexp-in-string "\\(<$1>\\).*\\'" "<${1:p}>" 
     (mapconcat 
     (lambda (line) (format "%s" line)) 
     (mapcar 
     (lambda (match) (concat "<$1>" match "</${1:$(replace-regexp-in-string \" .*\" \"\" text)}>")) 
     (split-string string "[\r\n]")) "\n") t nil 1) (point) (point)))) 
5

Für sgml-mode deratives, um Markierungsbereich tagify, Typ M-x sgml-tag, und geben Sie den Tag-Namen (Presse TAB erhalten Liste der verfügbaren HTML-Elemente) nutzen möchten. Mit dieser Methode können Sie zwar nicht jede Zeile in einer Region markieren, Sie können dies jedoch umgehen, indem Sie ein Tastaturmakro aufzeichnen.

0

Diese Variante auf Treys Antwort wird auch den HTML-Code korrekt einrücken.

(defun wrap-lines-region-html (b e tag) "'tag' every line in the region with a tag" (interactive "r\nMTag for line: ") (setq p (point-marker)) (save-excursion (goto-char b) (while (< (point) p) (beginning-of-line) (indent-according-to-mode) (insert (format "<%s>" tag)) (end-of-line) (insert (format "</%s>" tag)) (forward-line 1))))