Bash автозаполнение в режиме оболочки Emacs

В терминале GNOME Bash выполняется интеллектуальное автоматическое завершение. Например

apt-get in<TAB>

становится

apt-get install

В режиме оболочки Emacs это автозаполнение не работает даже после явного источника /etc/bash_completion. Вышеприведенный пример выглядит как in или автоматически завершается с именем файла в текущем каталоге, а не с допустимой командой apt-get. Предположительно, это происходит потому, что Emacs перехватывает нажатие клавиши Tab. Как включить интеллектуальное автоматическое завершение в shell-mode?

Ответ 1

Я знаю, что этот вопрос - три года, но это то, что меня также интересовало решение. Веб-поиск направил меня на кусок elisp, который заставляет Emacs использовать bash для завершения в режиме оболочки. В любом случае это работает для меня.

Проверьте это на https://github.com/szermatt/emacs-bash-completion.

Ответ 2

В оболочке emacs он фактически выполняет make-автозаполнение, а не bash. Если оболочка и emacs не синхронизированы (например, с помощью pushd, popd или некоторой пользовательской функции bash, которая меняет текущий каталог оболочки), автозаполнение перестает работать.

Чтобы исправить это, просто введите "dirs" в оболочку, и все вернется к синхронизации.

У меня также есть следующее в моем .emacs:

(global-set-key "\M-\r" 'shell-resync-dirs)

Затем просто нажатие Esc-return повторяет автозаполнение.

Ответ 3

Я не знаю ответа на это. Но причина в том, что он не работает так, как вы ожидаете, вероятно, из-за того, что завершение в оболочках emacs обрабатывается emacs внутренне (с помощью функции comint-dynamic-complete) и не имеет встроенных функций интеллектуального завершения.

Боюсь, это нелегко исправить.

Изменить: предложение njsf использования term-mode, вероятно, так же хорошо, как и получается. Начните с

M-x term
Он включен в стандартное распределение emacs (и в emacs21-common или emacs22-common на Ubuntu и Debian по крайней мере).

Ответ 4

Как сказал Матли, это непростая задача, так как bash запускается с -noediting и TAB привязана к comint-dynamic-complete.

Можно было бы переустановить TAB для самостоятельной вставки команды в shell-comand-hook с помощью локального набора ключей и заставить shell-режим не запускаться с -noediting с помощью M-x customize-variable RET explicit- bash -args, но я подозреваю, что он не будет хорошо сочетаться со всем другим редактированием.

Возможно, вы захотите попробовать режим term-mode, но у него есть еще один набор проблем, потому что некоторые из обычных регулярных клавиш перекрываются термином-режимом.

РЕДАКТИРОВАТЬ: другими регулярными ключевыми словами, наложенными терминальным режимом, я имею в виду все, кроме C-c, который становится побегом, чтобы иметь возможность переключать буферы. Поэтому вместо C-x k, чтобы убить буфер, вы должны иметь C-c C-x k. Или переключиться на другой буфер "C-c C-x o" или "C-c C-x 2"

Ответ 5

Пожалуйста, рассмотрите другой режим M-x term, как я сделал это, когда ударил проблему в 2011 году. Я пытаюсь собрать все усилия над Inet в то время, чтобы заставить shell работать с завершением Bash, включая этот вопрос. Но, обнаружив альтернативу перед term-mode, я никогда не хочу попробовать eshell.

Это полный эмулятор терминала, поэтому вы можете запускать интерактивную программу внутри, например, Midnight commander. Или переключитесь на завершение zsh, чтобы не потерять время, потраченное на настройку Emacs, - сделайте один раз всю жизнь.

С этой характеристикой - завершение TAB в Bash вы получаете бесплатно. Но что более важно, вы получаете полную мощность Readline, например инкрементный или префиксный поиск команд. Чтобы сделать эту настройку более удобной для использования, проверьте .inputrc, .bashrc, .emacs.

Существенная часть .inputrc:

# I like this!
set editing-mode emacs

# Don't strip characters to 7 bits when reading.
set input-meta on

# Allow iso-latin1 characters to be inserted rather than converted to
# prefix-meta sequences.
set convert-meta off

# Display characters with the eighth bit set directly rather than as
# meta-prefixed characters.
set output-meta on

# Ignore hidden files.
set match-hidden-files off

# Ignore case (on/off).
set completion-ignore-case on

set completion-query-items 100

# First tab suggests ambiguous variants.
set show-all-if-ambiguous on

# Replace common prefix with ...
set completion-prefix-display-length 1

set skip-completed-text off

# If set to 'on', completed directory names have a slash appended. The default is 'on'.
set mark-directories on
set mark-symlinked-directories on

# If set to 'on', a character denoting a file type is appended to the
# filename when listing possible completions. The default is 'off'.
set visible-stats on

set horizontal-scroll-mode off

$if Bash
"\C-x\C-e": edit-and-execute-command
$endif

# Define my favorite Emacs key bindings.
"\[email protected]": set-mark
"\C-w": kill-region
"\M-w": copy-region-as-kill

# Ctrl+Left/Right to move by whole words.
"\e[1;5C": forward-word
"\e[1;5D": backward-word
# Same with Shift pressed.
"\e[1;6C": forward-word
"\e[1;6D": backward-word

# Ctrl+Backspace/Delete to delete whole words.
"\e[3;5~": kill-word
"\C-_": backward-kill-word

# UP/DOWN filter history by typed string as prefix.
"\e[A": history-search-backward
"\C-p": history-search-backward
"\eOA": history-search-backward
"\e[B": history-search-forward
"\C-n": history-search-forward
"\eOB": history-search-forward

# Bind 'Shift+TAB' to complete as in Python TAB was need for another purpose.
"\e[Z": complete
# Cycling possible completion forward and backward in place.
"\e[1;3C": menu-complete                    # M-Right
"\e[1;3D": menu-complete-backward           # M-Left
"\e[1;5I": menu-complete                    # C-TAB

.bashrc (YEA! Существует dabbrev в Bash из любого слова в ~/.bash_history):

set -o emacs

if [[ $- == *i* ]]; then
  bind '"\e/": dabbrev-expand'
  bind '"\ee": edit-and-execute-command'
fi

.emacs, чтобы сделать навигацию удобной в терминальном буфере:

(setq term-buffer-maximum-size (lsh 1 14))

(eval-after-load 'term
  '(progn
    (defun my-term-send-delete-word-forward () (interactive) (term-send-raw-string "\ed"))
    (defun my-term-send-delete-word-backward () (interactive) (term-send-raw-string "\e\C-h"))
    (define-key term-raw-map [C-delete] 'my-term-send-delete-word-forward)
    (define-key term-raw-map [C-backspace] 'my-term-send-delete-word-backward)
    (defun my-term-send-forward-word () (interactive) (term-send-raw-string "\ef"))
    (defun my-term-send-backward-word () (interactive) (term-send-raw-string "\eb"))
    (define-key term-raw-map [C-left] 'my-term-send-backward-word)
    (define-key term-raw-map [C-right] 'my-term-send-forward-word)
    (defun my-term-send-m-right () (interactive) (term-send-raw-string "\e[1;3C"))
    (defun my-term-send-m-left () (interactive) (term-send-raw-string "\e[1;3D"))
    (define-key term-raw-map [M-right] 'my-term-send-m-right)
    (define-key term-raw-map [M-left] 'my-term-send-m-left)
    ))

(defun my-term-mode-hook ()
  (goto-address-mode 1))
(add-hook 'term-mode-hook #'my-term-mode-hook)

Поскольку любая обычная команда как C-x o не работает в режиме эмуляции терминала, я расширяю раскладку с помощью:

(unless
    (ignore-errors
      (require 'ido)
      (ido-mode 1)
      (global-set-key [?\s-d] #'ido-dired)
      (global-set-key [?\s-f] #'ido-find-file)
      t)
  (global-set-key [?\s-d] #'dired)
  (global-set-key [?\s-f] #'find-file))

(defun my--kill-this-buffer-maybe-switch-to-next ()
  "Kill current buffer. Switch to next buffer if previous command
was switching to next buffer or this command itself allowing
sequential closing of uninteresting buffers."
  (interactive)
  (let ( (cmd last-command) )
    (kill-buffer (current-buffer))
    (when (memq cmd (list 'next-buffer this-command))
      (next-buffer))))
(global-set-key [s-delete] 'my--kill-this-buffer-maybe-switch-to-next)
(defun my--backward-other-window ()
  (interactive)
  (other-window -1))
(global-set-key [s-up] #'my--backward-other-window)
(global-set-key [s-down] #'other-window)
(global-set-key [s-tab] 'other-window)

Обратите внимание, что выше я super key так term-raw-map и, возможно, любая другая раскладка клавиатуры не конфликтует с моими привязками клавиш. Чтобы сделать ключ super с левой клавиши Win, я использую .xmodmaprc:

! To load this config run:
!   $ xmodmap .xmodmaprc

! Win key.
clear mod3
clear mod4

keycode 133 = Super_L
keycode 134 = Hyper_R
add mod3 = Super_L
add mod4 = Hyper_R

Вы просто должны помнить команду 2: C-c C-j - перейти в обычный режим редактирования Emacs в буфере - я использую его для копирования или grepping, C-c C-k - вернуться в режим эмуляции терминала.

Выбор мыши и Shift-Insert работают как в xterm.

Ответ 6

Я использую Prelude, и когда я нажимаю Meta + Tab, он заканчивается для меня.

Кроме того, Ctrl + i, похоже, делает то же самое.

Ответ 7

Я использую рулевой режим. Он имеет эту функциональность (после нажатия "TAB" ): введите описание изображения здесь

Ответ 8

Я не претендую на то, чтобы быть экспертом emacs, но это должно решить вашу проблему:

Создать: ~/.emacs

Добавьте к этому:

(требуется командная оболочка) (Оболочка-команда-завершение-режим)

Emacs берет оболочку, поэтому параметры BASH не переносятся. Это будет автоматически завершено для EMACS.