2008-08-13 18 views
6

Für den Kontext bin ich so etwas wie ein Emacs-Neuling. Ich habe es nicht sehr lange benutzt, aber ich benutze es immer mehr (ich mag es sehr). Auch ich bin vertraut mit Lisp, aber nicht super vertraut mit elisp.Wie binde ich einen regulären Ausdruck an eine Tastenkombination in Emacs?

Was ich tun muss, ist ein regulärer Ausdruck an eine Tastaturkombination zu binden, weil ich diese bestimmte Regex so oft verwende.

Was ich getan habe:

M-C-s ^.*Table\(\(.*\n\)*?GO\) 

Hinweis, benutzen ich Newline oben, aber ich habe festgestellt, dass für isearch-forward-regexp, Sie wirklich brauchen, um die \n im regulären Ausdruck mit dem Ergebnis der zu ersetzen Cq Qj. Dies fügt einen literalen Zeilenumbruch ein (ohne den Befehl zu beenden), wodurch es mir möglich ist, einen neuen Zeilenumbruch in den Ausdruck einzufügen und ihn über mehrere Zeilen hinweg anzupassen.

Wie kann ich dies an eine Tastenkombination binden?

Ich verstehe vage, dass ich eine elisp Funktion erstellen muss, die isearch-forward-regexp mit dem Ausdruck ausführt, aber ich bin verschwommen auf die Details. Ich habe google gesucht und die meisten Dokumente als etwas verwirrend empfunden.

Wie kann ich einen regulären Ausdruck an eine Tastenkombination in Emacs binden?


Mike Stone hatte die beste Antwort so weit - nicht genau, was ich suchte, aber es funktionierte für das, was ich brauchte

Bearbeiten - diese Art gearbeitet, aber nach dem Speichern das Makro, als ich es später wieder benutzte, konnte ich es nicht mit Cx e verwenden. (Dh, wenn ich Emacs neu starten und geben Sie dann Mx Makroname und dann Cx e, erhalte ich eine Nachricht in der Minipuffer wie ‚keine letzte kbd Makro‘ oder etwas ähnliches)


@ Mike Stone - Danke für die Information. Ich habe versucht, ein Makro wie so erstellen:

C-x(M-C-s ^.*Table\(\(.*C-q C-J\)*?GO\) C-x) 

Das ist mein Makro erstellt, aber wenn ich mein Makro ausgeführt Ich habe nicht die gleiche Markierung erhalten, die ich normalerweise, wenn ich isearch-forward-regexp verwenden. Stattdessen sprang es einfach auf das Ende der nächsten Übereinstimmung des Ausdrucks. Das funktioniert nicht wirklich für das, was ich brauche. Irgendwelche Ideen?

Edit: Es sieht aus wie ich kann Makros zu tun, was ich will, ich muss nur außerhalb der Box von isearch-forward-regexp denken. Ich werde versuchen, was du vorgeschlagen hast.

Antwort

5

Sie Makros, nur tun C-x ( dann alles tun, für das Makro, dann C-x) das Makro zu beenden, dann C-x e die zuletzt definierte Makro auszuführen.Dann können Sie es nennen Mx name-last-kbd-macro mit dem Sie einen Namen zuweisen können, die Sie dann mit Mx TestIt, dann speichern Sie die Definition mit Mx insert-kbd-Makro aufrufen Das wird das Makro in Ihren aktuellen Puffer setzen, und Sie können es dann in Ihrer .emacs Datei speichern.

Beispiel:

C-x(abc *return* C-x) 

Wird ein Makro definieren "abc" und drücken Sie die Eingabetaste zu geben.

C-xeee 

führt die oben Makro sofort, 3-mal (erste E führt es aus, dann folgt der 2 e wird es noch zweimal ausführen).

M-x name-last-kbd-macro testit 

Namen der Makro "testit"

M-x testit 

führt das nur dem Namen Makro (prints "abc" dann zurück).

M-x insert-kbd-macro 

setzt die folgend in Ihrem aktuellen Puffer:

(fset 'testit 
    [?a ?b ?c return]) 

die dann in Ihrer .emacs-Datei gespeichert werden kann, die den Namen Makro immer und immer wieder nach dem Neustart Emacs zu verwenden.

1

@Justin:

Wenn ein Makro ausgeführt wird, ist es ein wenig anders ... inkrementelle Suche wird nur einmal geschehen, und Sie werden das Makro erneut ausführen, wenn Sie wieder suchen möchten. Sie können jedoch leistungsfähigere und komplexere Dinge tun, wie zum Beispiel nach einem Schlüsselwort suchen, zum Anfang der Zeile springen, markieren, zum Ende der Zeile gehen, Mw (zum Kopieren), dann zu einem anderen Puffer springen, dann Cy (einfügen), dann springen Sie zurück zum anderen Puffer und beenden Sie Ihr Makro. Jedes Mal, wenn Sie das Makro ausführen, kopieren Sie eine Zeile in den nächsten Puffer.

Die wirklich coole Sache über Emacs Makros ist es wird aufhören, wenn es die Glocke sieht ... was passiert, wenn Sie eine inkrementelle Suche (unter anderem) nicht übereinstimmen. Also das obige Makro, Sie können C-u 1000 C-x e tun, die das Makro 1000 mal ausführen wird ... aber seit Sie eine Suche durchgeführt haben, wird es nur 1000 Zeilen kopieren, ODER BIS DIE SUCHE FEHLT! Das bedeutet, wenn 100 Übereinstimmungen vorhanden sind, wird das Makro nur 100 Mal ausgeführt.

EDIT: Check-out C-hf Highlight-Linien-Matching-Regexp, die die Hilfe eines Befehls, der alles mit einer Regex markiert hervorhebt ... Ich weiß nicht, wie Sie die Hervorhebung aber ... rückgängig machen Sie können ein gespeichertes Makro verwenden, um alle zu markieren, die mit der Regex übereinstimmen, und dann ein anderes Makro, um das nächste zu finden ...?

WEITERE EDIT: Mx hebt sie-regexp wird die Markierung rückgängig zu machen, Sie haben allerdings die letzte regex eingeben (aber es standardmäßig die regex Sie markieren verwendet)

1

Im Allgemeinen eine benutzerdefinierte Tastenkombination in Emacs zu definieren , würden Sie

(define-key global-map (kbd "C-c C-f") 'function-name) 

define-key ist, wenig überraschend schreiben, die Funktion einen neuen Schlüssel zu definieren. global-map ist die globale Tastenbelegung, im Gegensatz zu einzelnen Karten für jeden Modus.(kbd "C-c C-f") gibt eine Zeichenfolge zurück, die die Tastenfolge C-c C-f darstellt. Es gibt andere Möglichkeiten, dies zu tun, einschließlich der Eingabe der Zeichenkette direkt, aber dies ist normalerweise am einfachsten, da es die normale geschriebene Darstellung benötigt. 'function-name ist ein Symbol, das der Name der Funktion ist.

Nun, wenn Ihre Funktion nicht bereits definiert ist, sollten Sie sie definieren, bevor Sie diese verwenden. Um das zu tun, schreiben

(defun function-name (args) 
    (interactive) 
    stuff 
    ...) 

defun eine Funktion definiert - verwendet C-h f defun für spezifischere Informationen. Die (interactive) gibt es nicht wirklich einen Funktionsaufruf; Es teilt dem Compiler mit, dass es in Ordnung ist, dass die Funktion vom Benutzer über M-x function-name und über Tastenkombinationen aufgerufen wird.

Jetzt speziell für die interaktive Suche ist das schwierig; das isearch Modul scheint nicht wirklich für das eingerichtet zu sein, was Sie versuchen zu tun. Aber Sie können dies verwenden, um etwas Ähnliches zu tun.

2

ich buchstäblich mit der Lösung Ihres Problems begonnen haben,

(defun search-maker (s) 
    `(lambda() 
    (interactive) 
    (let ((regexp-search-ring (cons ,s regexp-search-ring)) ;add regexp to history 
      (isearch-mode-map (copy-keymap isearch-mode-map))) 
     (define-key isearch-mode-map (vector last-command-event) 'isearch-repeat-forward) ;make last key repeat 
     (isearch-forward-regexp)))) ;` 

(global-set-key (kbd "C-. t") (search-maker "^.*Table\\(\\(.*\\n\\)*?GO\\)")) 
(global-set-key (kbd "<f6>") (search-maker "HELLO WORLD")) 

Die Tastenfolge von (kbd ...) eine neue leere Suche beginnt. Um tatsächlich nach Ihrer Zeichenfolge zu suchen, drücken Sie letzte Taste erneut so oft wie Sie benötigen. Also C-. t t t oder <f6> <f6> <f6>. Die Lösung ist im Grunde ein Hack, aber ich werde es hier lassen, wenn Sie damit experimentieren wollen.

Hier finden Sie wahrscheinlich in der Nähe von, was Sie brauchen,

(defmacro define-isearch-yank (key string) 
    `(define-key isearch-mode-map ,key 
    (lambda() 
     (interactive) 
     (isearch-yank-string ,string)))) ;` 

(define-isearch-yank (kbd "C-. t") "^.*Table\\(\\(.*\\n\\)*?GO\\)") 
(define-isearch-yank (kbd "<f6>") "HELLO WORLD") 

Die wichtigsten Combos jetzt nur in isearch Modus arbeiten. Sie starten die Suche normal und drücken dann Tastenkombinationen, um die vordefinierte Zeichenfolge einzufügen.