zsh completion não funcionará no shell do emacs

3

Estou aprendendo sobre os recursos mais poderosos de conclusão de tabulação e expansão do zsh, e eles não parecem funcionar quando eu executo o zsh no emacs com o shell M-x:

cat $PATH<TAB> expande a variável de tabulação no Terminal, mas no modo shell apenas emite um bipe.

Eu pesquisei o ambiente do emacs e aqui está o que eu encontrei:

TAB (translated from ) runs the command completion-at-point, which is an interactive compiled Lisp function in 'minibuffer.el'.

It is bound to TAB, .

(completion-at-point)

Perform completion on the text around point. The completion method is determined by 'completion-at-point-functions'.

completion-at-point-functions is a variable defined in 'minibuffer.el'. Its value is (tags-completion-at-point-function)

Então, estou supondo que preciso adicionar uma função às funções completion-at-point, mas qual delas?

    
por benhsu 26.11.2011 / 05:36

4 respostas

2

Você não pode usar o preenchimento de shell dentro de M-x shell . O Emacs envia a entrada para o shell uma linha por vez quando você pressiona RET . Quando você pressiona TAB , a conclusão integrada do Emacs é acionada. No modo shell, o Emacs tenta rastrear seu diretório atual e completa os nomes dos arquivos, mas isso é tudo.

Dependendo do programa com o qual você está interagindo, o modo shell pode ser legal (porque você tem todos os recursos da edição do Emacs em vez de recursos limitados que o shell ou outro programa oferece) ou não é legal (porque você não obtém Qualquer que seja o recurso que o shell ou outro programa oferece, você pode executar M-x term para rodar um emulador de terminal mais completo dentro do Emacs, onde você interage diretamente com o programa subjacente. Você ganha alguns, mas também perde alguns: os recursos de rolagem do modo Term são ruins.

Você pode alternar entre o modo Termo e o modo Shell no mesmo buffer . Você deve iniciar o buffer no modo Termo e, em seguida, você pode usar essas funções para alternar entre os dois. (Nota: eu não escrevi essas funções originalmente, foi contribuído para o Wiki do Emacs e eu não rastreei a fonte. Eu o adaptei um pouco; aviso: eu não testei esse código.)

(defun term-switch-to-shell-mode ()
  (interactive)
  (shell-mode)
  (set-process-filter  (get-buffer-process (current-buffer)) 'comint-output-filter )
  (compilation-shell-minor-mode 1)
  (comint-send-input))
(defun shell-switch-to-term-mode ()
  (compilation-shell-minor-mode -1)
  (font-lock-mode -1)
  (set-process-filter  (get-buffer-process (current-buffer)) 'term-emulate-terminal)
  (term-mode)
  (term-char-mode)
  (term-send-raw-string (kbd "C-l")))
    
por 26.11.2011 / 15:10
2

Tente MultiTerm . É o único modo terminal do Emacs que parece funcionar bem com o zsh.

Com o modo 'M-x shell' você não pode usar zle (o material de conclusão da guia zsh legal).

Com 'M-x term' (e ansi-term), o terminal captura a maioria dos comandos C e M do emacs que você deseja rotear para o emacs.

O MultiTerm permite que você defina facilmente quais comandos você deseja capturar pelo emacs e quais você deseja rotear para o terminal. Ele vem pré-carregado com padrões que funcionam muito bem.

Mais uma dica: Adicione o seguinte ao seu .zshrc para permitir que o emacs rastreie seu diretório atual enquanto você faz o cd.

if [ -n "$INSIDE_EMACS" ]; then
  chpwd() { print -P "3AnSiTc %d" }
  print -P "3AnSiTu %n"
  print -P "3AnSiTc %d"
fi
    
por 07.04.2012 / 00:59
1

Este é um problema complexo. Vamos ver o que realmente acontece por trás do sentido.

De acordo com o Emacs Doc, <Tab> é obrigado a funcionar completion-at-point . Aqui está o que completion-at-point faz:

Perform completion on the text around point.

The completion method is determined by 'completion-at-point-functions'.

Verifique o Doc Emacs, a variável completion-at-point-functions vai aqui:

completion-at-point-functions is a variable defined in 'minibuffer.el'.

Its value is (comint-completion-at-point t)

Local in buffer shell; global value is

(tags-completion-at-point-function)

Então, vamos verificar o documento de comint-completion-at-point

comint-completion-at-point é um alias para icicle-comint-dynamic-complete' in ob-sh.el '.

(comint-completion-at-point)

Dynamically perform completion at point.

Calls the functions in 'comint-dynamic-complete-functions', but with

Icicles functions substituted, to perform completion until a function

returns non-nil. Return that value.

Portanto, é claro que você precisa adicionar suas funções completas favoritas à variável comint-dynamic-complete-functions .

      (add-to-list 'comint-dynamic-complete-functions 'icicle-shell-dynamic-complete-filename)
      (add-to-list 'comint-dynamic-complete-functions 'icicle-shell-dynamic-complete-command)
    
por 28.05.2013 / 16:57
0

Obrigado bengineerd pela boa explicação e snippet:)

Eu uso o zsh junto com o grml config - a função chpwd funcionou totalmente, mas algumas coisas foram quebradas. Aqui está o snippet modificado para que a conclusão automática da chave de seta seja feita:

if [ -n "$INSIDE_EMACS" ]; then
  # keep the old chpwd command and apply it later
  which zsh_chpwd >&/dev/null || \
    eval "$(echo "zsh_chpwd() {"; declare -f chpwd | tail -n +2)"
  chpwd() {
    print -P "3AnSiTc %d"
    zsh_chpwd
  }
  print -P "3AnSiTu %n"
  print -P "3AnSiTc %d"
fi

e anexe na parte inferior do seu .zshrc

Atualizar

Para corrigir o salto e a exclusão em terminais, encontrei várias fontes que ajudaram a melhorar a experiência geral:

e os combinou no link

Aqui estão alguns trechos da parte crítica, que permitiram chaves de setas meta + (salto de palavras) e exclusão de palavras para trás:

(add-hook 'term-mode-hook
  (lambda ()
    (define-key term-raw-map (kbd "M-d") 'term-send-raw-meta)
    (define-key term-raw-map (kbd "M-<left>") 'term-send-backward-word)
    (define-key term-raw-map (kbd "M-<right>") 'term-send-forward-word)
    (define-key term-raw-map (kbd "M-<backspace>") 'term-send-backward-kill-word))
    (add-to-list 'term-bind-key-alist '("C-z e" . term-send-esc))))

(defun term-send-esc ()
  "Send ESC in term mode."
  (interactive)
  (term-send-raw-string "\e"))

Veja o termo-send-esc do git repo se você fizer um ssh em um remoto, entre no modo de inserção em algum vim e fique preso porque ainda não há mapeamento para o ESC.

também um pouco relacionado - com grml zshrc Se você quiser que a conclusão da chave de seta aconteça também se você tiver menos de cinco opções, pesquise

 zstyle ':completion:*'               menu select=5

e altere o valor "5" (valor padrão) para "1"

    
por 04.08.2018 / 15:54