2009-09-20 9 views
6

Ich habe in letzter Zeit versucht, in Emacs zu kommen, und eines der Dinge, die ich richtig machen muss, ist Einzug.Wie emimiere ich Vim's Softtabstop in Emacs?

Beispiel 1:

sub foo { 
    my $bar = 'quux'; 
    | 

Beispiel 2:

sub foo { 
    my $bar = 'quux';  |# foo 

vorstellen, dass die Verkettungszeichen in den obigen Beispielen die Cursorposition anzeigt. Jetzt verwende ich (4) Leerzeichen für jede Einzugsebene (keine Tabs), und ich habe Emacs eingerichtet, um meinen Code automatisch mit diesem Gedanken einzurücken. Keine Probleme dort. Wenn ich jedoch in den obigen Beispielen die Rücktaste an den angegebenen Cursorpositionen drücke, möchte ich, dass Emacs bis zur nächsten Einzugsebene zurückgeht (Spalte/4). Das heißt, ich möchte, dass das vorherige Leerzeichen so behandelt wird, als ob es aus Tabs bestehen würde. Stattdessen löscht es immer nur ein einzelnes Leerzeichen.

In vim, ich schalte 'expandtab', um Leerzeichen anstelle von Tabs einzufügen, und 'softtabstop', die es (unter anderem) zurück zum nächsten "weichen Tabstop" wie oben beschrieben macht.

In Emacs, ich glaube, ich könnte (wenn ich Emacs/elisp besser wusste) binden Backspace auf eine Funktion, die nach so etwas wie das funktioniert:

if indent-tabs-mode is nil 
    if the cursor position is preceded by whitespace 
     calculate the position of the previous "soft tabstop" 
     if there's enough whitespace 
      backspace all the way to that point 
     else 
      backspace by one character 

Was ich wissen will, ist es eine einfachere wie geht das und/oder kennt jemand eine bestehende Lösung?

+0

Dies wird durch die Tatsache kompliziert, dass es, wie Sie Perl gerade schreiben aussieht, und cperl-Modus (die beste Perl-Modus für Emacs) bindet bereits Backspace zu 'cperl -elektrischer Rückschritt'. (Obwohl diese Funktion nichts Kritisches bewirkt, könnte man ohne das von ihr gebotene Verhalten auskommen.) – cjm

+0

Ein kleines Update: Ich habe eine Sache falsch verstanden. Wenn vim nicht zum nächsten Soft-Tabstopp zurückgehen kann, löscht es so viel Leerzeichen wie möglich (dh 1 bis 3), nicht nur 1. – Hinrik

+0

Lösung aktualisiert, um so viel Leerraum wie möglich zu löschen (bis zum Tabstopp) –

Antwort

7

Das funktioniert bei mir, wo die 'tab-width als die Breite der Spalten verwendet wird. Stellen Sie den Schlüssel in den entsprechenden keymaps ...

(local-set-key (kbd "DEL") 'backward-delete-whitespace-to-column) 
(defun backward-delete-whitespace-to-column() 
    "delete back to the previous column of whitespace, or as much whitespace as possible, 
or just one char if that's not possible" 
    (interactive) 
    (if indent-tabs-mode 
     (call-interactively 'backward-delete-char-untabify) 
    (let ((movement (% (current-column) tab-width)) 
      (p (point))) 
     (when (= movement 0) (setq movement tab-width)) 
     (save-match-data 
     (if (string-match "\\w*\\(\\s-+\\)$" (buffer-substring-no-properties (- p movement) p)) 
      (backward-delete-char-untabify (- (match-end 1) (match-beginning 1))) 
     (call-interactively 'backward-delete-char-untabify)))))) 
+0

Siehe: https://www.emacswiki.org/emacs/BackspaceWhitespaceToTabStop (hat eine * erweiterte * Version). – ideasman42

+0

Schön, aber gefunden 'rückwärts-löschen-char-untabify' ziemlich nervig, einige Benutzer möchten es vielleicht ersetzen mit 'rückwärts löschen-char'. – ideasman42

Verwandte Themen