Emacs equivalente a VIM ci "?

13

O emacs tem o equivalente de VIMs ci "comando? Basicamente eu quero substituir o texto dentro de um conjunto de aspas.

No vim eu posso ci) ou ci] ou ci} para "alterar o interior *" ...

    
por erikcw 26.03.2010 / 01:03

10 respostas

18

Na minha cabeça, o comando mais próximo é M-z " , que elimina tudo, desde o ponto até a próxima ocorrência do "caractere".

Há também C-M-k , também conhecido como "kill balanced expression", que exclui uma instrução com parêntesis completa ou uma cadeia com aspas duplas etc. com base na definição de modos atuais de "expressão balanceada" e o caractere atualmente sob ponto (ex. só funciona se o cursor estiver na abertura '' 'ou' ('etc.).

    
por 26.03.2010 / 01:45
7

Semelhantemente à sugestão de Justin, o C-M-SPACE dá a você "mark-sexp", que seleciona a parêntese de balanceamento, cotação, etc., e então você pode usar C-w ou qualquer coisa para fazê-lo desaparecer. No caso de você querer ver o que você está prestes a excluir antes de excluí-lo ...

    
por 09.04.2010 / 23:38
6

Sim! O equivalente de VIMs ci "comando no Emacs é ... ci" :-)
link

    
por 29.05.2010 / 17:07
3

Apenas tropeçou nesta questão; aqui está uma solução personalizada que funcionou para mim:

(defun seek-backward-to-char (chr)
  "Seek backwards to a character"
  (interactive "cSeek back to char: ")
  (while (not (= (char-after) chr))
    (forward-char -1)))


(defun delete-between-pair (char)
  "Delete in between the given pair"
  (interactive "cDelete between char: ")
  (seek-backward-to-char char)
  (forward-char 1)
  (zap-to-char 1 char)
  (insert char)
  (forward-char -1))

Em seguida, vincule delete-entre-par a qualquer tecla que desejar. Para mim, eu tenho ligado em C-z i.

    
por 13.10.2011 / 20:38
2

Eu tenho medo de não saber sobre o recurso ci do VIM, mas você já olhou para o Eexs regexp replace? Eu não posso falar com a semântica exata ou como é fácil de usar em comparação, mas é o que eu usaria para o que eu acho que você quer.

por 26.03.2010 / 02:52
2

Eu fiz um modo secundário que fornece alguns desses recursos do Vim chamados Markit .

    
por 02.12.2011 / 14:38
0

Magnars (autor do site EmacsRocks) escreveu este plugin para fazer exatamente o que você está pedindo.

link

Obviamente, você também pode usar o modo Maligno.

    
por 28.11.2014 / 07:51
0

Aqui está minha versão, que irá apagar tudo dentro (ou incluindo) um par de caracteres correspondentes. Os pares de caracteres são definidos em uma lista para que o caractere inicial / final correspondente seja conhecido. Eu mapeei para "C-c i" para alterar e "C-c a" para alterar todos.

Também copia os caracteres removidos para a placa de recorte para colar mais tarde.

; Re-create ci" ca"...
(defun seek-backward-to-char (chr)
  "Seek backwards to a character"
  (interactive "cSeek back to char: ")
  (while (not (= (char-after) chr))
    (forward-char -1)))

(setq char-pairs
      '(( ?\" . ?\" )
        ( ?\' . ?\' )
        ( ?\( . ?\) )
        ( ?\[ . ?\] )
        ( ?\{ . ?\} )
        ( ?<  . ?>  )))

(defun get-char-pair (chr)
  (let ((result ()))
    (dolist (x char-pairs)
      (setq start (car x))
      (setq end (cdr x))
      (when (or (= chr start) (= chr end))
        (setq result x)))
      result))

(defun get-start-char (chr)
  (car (get-char-pair chr)))
(defun get-end-char (chr)
  (cdr (get-char-pair chr)))

(defun seek-to-matching-char (start end count)
  (while (> count 0)
    (if (= (following-char) end)
        (setq count (- count 1))
      (if (= (following-char) start)
          (setq count (+ count 1))))
    (forward-char 1)))

(defun seek-backward-to-matching-char (start end count)
  (if (= (following-char) end)
      (forward-char -1))
  (while (> count 0)
    (if (= (following-char) start)
        (setq count (- count 1))
      (if (= (following-char) end)
          (setq count (+ count 1))))
    (if (> count 0)
        (forward-char -1))))

(defun delete-between-pair (char)
  "Delete in between the given pair"
  (interactive "cDelete between char: ")
  (seek-backward-to-matching-char (get-start-char char) (get-end-char char) 1)
  (forward-char 1)
  (setq mark (point))
  (seek-to-matching-char (get-start-char char) (get-end-char char) 1)
  (forward-char -1)
  (kill-region mark (point)))

(defun delete-all-pair (char)
  "Delete in between the given pair and the characters"
  (interactive "cDelete all char: ")
  (seek-backward-to-matching-char (get-start-char char) (get-end-char char) 1)
  (setq mark (point))
  (forward-char 1)
  (seek-to-matching-char (get-start-char char) (get-end-char char) 1)
  (kill-region mark (point)))

(global-set-key (kbd "C-c i") 'delete-between-pair)
(global-set-key (kbd "C-c a") 'delete-all-pair)
    
por 23.04.2015 / 15:49
0

Isso era algo que eu estava perdendo no Vim, e zap-to-char não pareceu entender direito.

Aqui está minha humilde tentativa de recriar "ci" e "ca":

(defun change-outer (str)
  (interactive "sChange outer: ")
  (condition-case nil
      (search-backward str (line-beginning-position))
    (error (search-forward str (line-end-position))
       (forward-char -1)))
  (kill-sexp)
)

(defun change-inner (str)
  (interactive "sChange inner: ")
  (condition-case nil
      (search-backward str (line-beginning-position))
    (error (search-forward str (line-end-position))
       (forward-char -1)))
  (push-mark)
  (forward-sexp)
  (forward-char -1)
  (exchange-point-and-mark)
  (forward-char 1)
  (kill-region (point) (mark))
)

Normalmente, o caso-condição não é necessário, já que o terceiro parâmetro (opcional) de pesquisa-encaminhamento / pesquisa-retrocesso serve para indicar o que fazer caso a pesquisa falhe. Mas, por algum motivo, colocar a segunda pesquisa como o terceiro parâmetro para a primeira gera um comportamento estranho.

    
por 16.03.2015 / 00:43
0

Eu tentei as soluções aqui, mas achei que cada uma delas queria de alguma forma, então eu cheguei a isso. Ele aceita um delimitador inicial ou final e usa funções integradas do Emacs para evitar a necessidade de uma tabela de tradução para delimitadores.

(defun change-inner (prefix character)
  "Kill region inside delimiters, using either beginning or
ending delimiter.  With prefix arg, kill including delimiters."

  (interactive "p\nc")
  (let ((initial-point (point))
        (start)
        (end)
        (move-point-by (if (> prefix 1) 0 1)))

    (condition-case nil
        (progn
          ;; Search forward for given char
          (search-forward (char-to-string character))
          (setq end (- (point) move-point-by))

          (condition-case nil
              (backward-sexp)
            (error (backward-list)))

          (setq start (+ (point) move-point-by))
          (kill-region start end)
          (or prefix (forward-char)))

      (error (progn
               ;; Reset and search backward for given char
               (goto-char initial-point)
               (search-backward (char-to-string character))
               (setq start (+ (point) move-point-by))

               (condition-case nil
                   (forward-list)
                 (error (forward-sexp))))

             (setq end (- (point) move-point-by))
             (kill-region start end)
             (or prefix (backward-char))))))
(global-set-key (kbd "M-i") 'change-inner)

(defun change-outer ()
  (interactive)
  (let ((current-prefix-arg '(4)))
    (call-interactively 'change-inner)))
(global-set-key (kbd "M-o") 'change-outer) 
    
por 31.10.2015 / 07:00

Tags