Автор Тема: [РЕШЕНО] Подстановка имен файлов в строку трюком "\M-s": menu-complete"  (Прочитано 685 раз)

Alexcostariha

  • Пользователь
  • **
  • Сообщений: 70
  • Карма: +11/-0
    • Просмотр профиля
                                                                ОС Linux Mint 17.2 Cinnamon, русская.
       Добрый день!  Прошу извинить меня, если я что-то по незнанию изложу неточно.
       Пакет  bash-completion  позволяет пристраивать дополнительные навороты к командной строке в bash.
Для этого используется библиотека трюков readline .
      Трюк с именем menu-complete позволяет вставлять в командную строку  файлы с похожими названиями  из текущей директории
по очереди, то есть друг за дружкой.
       Дополню свои объяснения описанием, которое дал Simon Myers в 2003 году, трюк №28-29  Перевожу как умею:
Цитировать

 К примеру, допустим  вы хотите изменить  в редакторе xemacs ваш файл .bashrc. Вы набираете :
$ xemacs  ~/.b
Затем жмете "Tab" и на выходе получаете список подходящих  файлов,  а имя файла  в строке дописывается само насколько это возможно :
.bash_history  .bash_profile  .bashrc
$  xemacs ~/.bash
Теперь нажатием  "Meta+S" подставляете в строку имена файлов из этого списка по-очереди.
Так нажав "Meta+S" один раз вы получите:
$ xemacs  ~/.bash_history
За следующие два нажатия вы пройдете  имена всех выбранных файлов.
           Далее следует описание того как этот трюк  делается:
Цитировать

29 Устанавливаем перебор имен "друг-за-другом".
   Указанные ниже строки следует внести  в ваш  файл .inputrc .
   # При  нажатии клавишы Tab  показать подходящие файлы: 
    set show-all-if-ambiguous on
   # Запустить перебор имен "друг-за-другом" при  нажатии клавиш "Meta+S" :
    "\M-s": menu-complete
 
        Самое неприятное - что этот трюк у меня не работает. В интернетах пишут (по-английски, но не получается видимо у русских), что кодировка терминала UTF-8 искажает  запись  "\M-s" .
Я пробовал переключать кодировку на "Западная ISO-8859-1" , пробовал писать "\Meta-s" или "\ESC-s". Пробовал  и без   "\"- не получается.
Может кто-то подскажет в чем дело? Буду очень признателен.
« Последнее редактирование: 31 Март 2016, 14:10:26 от Alexcostariha »

Brego

  • Ветеран
  • *****
  • Сообщений: 566
  • Карма: +93/-1
  • Перебьемся
    • Просмотр профиля
    • MintMem
Зачем же это Вам какие-то древние пути дворами-огородами? Все эти трюки хорошо известны под именем "автодополнение" и многократно описаны по-русски, например, тут: http://mintmem.com/page/lm16-cinnamon-terminal#lm16ct3-1  :)
"Следующая эпоха началась с сожжения всех хроник вместе с хронистами". С. Лем

Alexcostariha

  • Пользователь
  • **
  • Сообщений: 70
  • Карма: +11/-0
    • Просмотр профиля
            Спасибо за подсказку! В той ссылке, что вы дали вместо команды "Meta+s" используется TAB:
Цитировать
TAB: menu-complete  *STOP*
           Действительно, огласно документации readline ряд символов распознается этой библиотекой "железно" :
Цитировать
Распознаются следующие имена символов: RUBOUT, DEL, ESC, LFD, NEWLINE, RET, RETURN, SPC, SPACE и TAB.  *OK*
Я проверил  на TAB и  ESC.  Работает !  Прочие команды которые есть в Вашей ссылке и "многократно описаны по-русски" у меня уже есть.

          Конечно клавиша TAB  и ей подобные - это на мой взгляд костыльное решение. Во-первых оно дополнительно загружает  клавиши которые уже загружены.
 Во-вторых остается непонятным почему  более изящное решение с   "Meta+s" не работает. Двенадцать лет прошло !  :-) 
          Насчет древних-путей с огородами не соглашусь.  Вот товарищ иностранец-программист -он виртуозно владеет
 поиском по истории команд  командами типа  "!..." - с  восклицательным знаком, Об этом он  написал статью, не так давно - в 2012 году. Однако, судя по комментариям, 
он ничего не знает о трюке "волшебный пробел" иначе   "magic space" для предварительного просмотра такого рода команд.   
Зато про этот трюк писал наш общий друг  Simon Myers все в том же  2003 году - трюк №15-16 .
Такая "древность с огородами" делает искуство владения восклицательным знаком простенькой задачкой для новичков.    :-)
         Возможно я чего-то не понимаю, но  функцию  "menu-complete"   можно  назвать "автодополнение" только условно. 
        Обращаю Ваше внимание , что  функция "menu-complete" перелистывает ИМЕНА ФАЙЛОВ  в самой командной строке, прямо там где вы стоите .  Это  круто!!  *THUMBS*
        Более того, функция "menu-complete"  имеет  возможность перелистывать имена файлов также по их расширению.  Для этого нужно использовать трюк №30 в статье автора.
Правда весь трюк состоит  в том, что вы подключаете пакет "bash_completion" (он есть изначально) запуском файла  "/etc/bash_completion".  :-X . Автор статьи Simon Myers   называет его "Программируемое автодополнение".
В той ссылке, что вы мне дали имеется хотя и современное, но на вид более сложное  решение - со скриптиком.  *SCRATCH*
        Давайте сопоставим. Учтем, что в  записях вида "source /etc/bash_completion" и " . /etc/bash_completion" -с точкой,  слова "source" и "." (точка) означают одну и ту же команду - "запуск!"  *YES*.
Команды которые рекомендуется прописать в файл ".bashrc":
Цитировать
Команда " запустить файл bash_completion в папке /etc " в древней записи Simon_а Myers_а с путями "дворами-огородами" :

            # Программируемое автодополнение позволяет более грамотно дополнять различные команды:
              source /etc/bash_completion


Та же самая команда " запустить файл bash_completion в папке /etc ", из Вашей ссылки, в современном исполнении (для Линукс Минт 16 или LM16) типа без огородов:

            # enable bash completion in interactive shells
             if [ -f /etc/bash_completion ]; then
             . /etc/bash_completion
             fi

* Примечание. Эта  запись - копия записи в основном файле /etc/bash.bashrc для LM 17.2 . 
 Отсюда следует, если я не ошибаюсь конечно, что функция ". /etc/bash_completion" и так включена в системе? - и обе записи уже погоды не делают.
        Давайте снова вернемся к команде "Meta+s".
        Вот что пишет Simon Myers про работу  пакета "bash_completion" совместно с трюком по команде "Meta+s" :
Цитировать
        Когда вы составляете документы, то часто оказывается, что у вас набралось несколько файлов  с одним и тем же названием, но с разными расширениями:
$ ls
Bash_tips.aux  Bash_tips.log  Bash_tips.pdf  Bash_tips.tex

          Однако если у вас установлено "Программируемое автодополнение"  оболочка Bash подберет только те из файлов, которые соответствуют  набранной команде и не заметит остальные.
Возьмем к примеру команду для чтения PDF файлов "acroread" ( Acrobat Reader for Linux) и наберем:
$ acroread ba
Если теперь нажать клавишу Tab , то запись выше превратится в:
$ acroread Bash_tips.pdf
        Если в папке находится только один PDF файл, то вам даже не нужно ничего набирать из его имени; просто наберите  подходящую команду и жмите на Tab чтобы вставить имя этого файла.
Даже если там будет  несколько PDF файлов, то скорее всего окажется, что легче  ничего не печатать из имен этих файлов, а просто применить трюк с " Meta+S" чтобы перебрать их друг за другом.
       Этот способ подходит для любого приложения, которое способно работать с  ограниченным типом файлов. Его можно также применять для того,
 чтобы не допустить  ненужные типы файлов к командам. Например файлы с изображенями  и музыкой можно исключить из списка выбора для текстовых  редакторов.
  *THUMBS*




« Последнее редактирование: 22 Март 2016, 14:26:05 от Alexcostariha »

Brego

  • Ветеран
  • *****
  • Сообщений: 566
  • Карма: +93/-1
  • Перебьемся
    • Просмотр профиля
    • MintMem
Извиняюсь, что не сразу ответил, -- не мог.
Хотя, по большому счету, мне добавить почти нечего. Meta+s может не работать по нескольким причинам. Первая, наиболее вероятная, заключается  не столько в кодировке терминала, сколько в реальных кодах клавиш клавиатуры. Например, у меня ряд кейбиндов типа Meta+N срабатывает при нажатии Alt+N. Нужны дополнительные исследования и эксперименты, которыми я не занимался, поскольку мне более чем хватает автодополнения по Tab.
Кроме того, bash с 2003 года сильно изменился, и надо бы, по хорошему, вдумчиво курить man readline, -- а это хоть и не "Война и мир", но тоже до фига, 14 кб и всё по английски :)
* Примечание. Эта  запись - копия записи в основном файле /etc/bash.bashrc для LM 17.2 . 
 Отсюда следует, если я не ошибаюсь конечно, что функция ". /etc/bash_completion" и так включена в системе? - и обе записи уже погоды не делают.
Эта функция включена была уже давно, она была и в LM 16, о которой и была заметка в mintmem.com, но всегда лучше полагаться на ~/.bashrc -- хотя бы потому, что именно он считывается первым при поиске системой настроек. Лично я вообще в /etc/bash.bashrc держу копию ~/.bashrc -- на всякий аварийный случай. Конечно, в системе с несколькими пользователями этого делать не следует.
Ну, и поскольку я не сторонник Emacs-стиля (пользуюсь Vim), мне совершенно не понятно, почему "клавиша Tab и подобные -- костыльное решение". По-моему, наоборот, удобнее нажимать одну клавишу, чем включать дополнительное пользовательское пространство имен, если это возможно.
Сейчас не имею возможности подключиться к Вашим разысканиям, но если что-то выясните, отпишитесь сюда.
« Последнее редактирование: 24 Март 2016, 18:29:18 от Brego »
"Следующая эпоха началась с сожжения всех хроник вместе с хронистами". С. Лем

Alexcostariha

  • Пользователь
  • **
  • Сообщений: 70
  • Карма: +11/-0
    • Просмотр профиля
Добрый день!
1. Используем встроенную команду bind библиотеки READLINE:
bind  '"\es": menu-complete'Проверяем что получилось:
bind -q menu-complete
menu-complete может быть вызван с помощью "\es"
  • * Обратите внимание - вся фраза команды одета в одинарные кавычки, а сочетание клавиш - еще и в двойные.
Знак «\e» - от слова escape означает клавишу "Esc", которая в свою очередь заменяет клавишу "Meta".  Работает на ура!!! *THUMBS*
            * Клавиша "s" - одна из немногих оставлена свободной, чтобы на нее можно было что-нибудь навесить.
            ** Вместо клавиши "Esc"  можно использовать "Alt" или "Ctrl+[ "  - см. ниже.
            ***Изменения действительны только в текущей сессии.  Другими словами, если вы закроете и снова откроете терминал, то вам придется набирать все заново.
2. Прописывание в файле .inputrc соответствующей записи дает такой же замечательный  результат:
# Нажимайте клавиши-заменители для "Meta" (Esc, Alt или Ctrl+[ ) и с помощью "Meta+S" подставляйте в строку имена файлов друг-за-другом  :
"\es": menu-complete
  • Не забудьте выполнить следующую команду, чтобы изменения вошли в силу:
bind  -f  .inputrcИли нужно  выйти и снова зайти в ваше окно.
                                                                 
Вывод: Kлавиша-заменитель для  «Meta» (или «M»)  в библиотеке Readline обозначается как «\e»; от слова "escape"- "спасайся". С другими ключами она пришется слитно, например «\es», что в более привычной нам записи соответствует «Meta-s», «Meta+s» или «M-s».


3.    Немного о команде bind (вяжи их!).
 Команда bind связывает сочетание клавиш с каким-нибудь действием, которое называется "функцией".

    В мане Readline на РУССКОМ нет того, на что указывается в этой заметке. Благодаря ей удалось понять правильную запись для  команды bind:
  • С ключем "-x"  задается комбинация клавиш, для команды ОБОЛОЧКИ:
    bind -x '"key": shell-command''
  • Без ключа "-x" — задается комбинация клавиш к имеющейся функции или команде Readline:
    bind '"key": command'
    Команда "bind" без ключа "-x" – это то, что нам было нужно! * Комбинацию клавиш в этом случае можно задавать только короткой записью  вида "\C-e"; в отличие от длинной, вида Control-e .

    •   Другие возможности команды "bind":
            help bind     # краткая справка по команде bind;  можно набрать также "man builtins" - "вбитые" в bash команды.
            bind  функция(трюк)   #  запускает трюк сразу, например : "bind Space:magic-space ", - запустит трюк "волшебный пробел", см. выше.
            bind  -u функция           #  Снять все  сочетания клавиш, которые привязаны к указанной функции(трюку).
            bind  -r "keyseq"           #  Удалить имеющуюся  привязку к указанному сочетанию клавиш; keyseq - сочетание клавиш. Например bind -r "\es" - отключит сочетание  "Esc s" от "menu-complete".
                                                     Если это сочетание клавиш было ранее прописано в файле ".inputrc" - то оно будет продолжать работать.
            bind  -l                  #   Список имен всех функций readline. * От слова list - список.
            bind -P                   #   Выдает текущие имена функций и привязки readline.  Эта команда содержит много примеров, как писать "привязки", например видно, что клавиша "Esc" пишется "\e".
    •   * Посложнее:

             bind -x '"\C-l": ls'    # пример применения команды bind  с ключем -x: при наборе Ctrl-L, вызывается команда ls.     
             bind '"key":"keystrokes"'  #  Keystrokes - любые сочетания клавиш с командами. Это можно называть макросом.  Например, создадим связку из двух  команд :
                                                      1) bind '"\es": menu-complete'  и 2) bind '"\ez": "ls \es"' .   Такая связка  позволяет подставлять имена файлов и папок  после команды "ls"  друг-за-другом, листая их.
                                                     Сначала нажимаем "Esc z" - получаем "ls имя-1" (файла или папки), далее "Esc s": ls имя-2, далее "Esc s": ls имя-3  и т. д.
                                                     Листается в алфавитном порядке; сначала идут имена с точкой.
             bind -S             # Выдает комбинации клавиш readline, привязанные к макросам с их описанием.
             bind  '"\e\C-l": "\C-e | less\C-m"'  # При наборе Alt+Ctrl+L перейти в конец строки Ctrl+e,  набрать  "| less" и нажать "Ввод" ( Ctrl+M  равносильно Ввод).

    P. S.
    Суть проблемы была в том, что в современных клавиатурах отсутствует клавиша «Meta». Ее заменяют клавиши «Esc»(нажать и отпустить) и/или «Alt»(нажать и удерживать). Еще вместо клавиши «Esc» можно нажать комбинацию «Ctrl + [».
    Поэтому запись от 2003 года из замечательной статьи Simon-а Myers-а 
    Цитировать
    # Запустить перебор имен "друг-за-другом" при  нажатии клавиш "Meta+S" :
         "\M-s": menu-complete
    нужно понимать буквально: "Это работает, если у вас есть клавиша «Meta». Если ее нет - то  значит ничего не выйдет". 
    Русский перевод маны Readline для поиска решения подходит плохо. Про комбинацию «\e» там написано так:
    Цитировать
    e    управляющий символ
    мало того, что не точно, но еще нет обратного слэша. * Имеется другой перевод , но неполный.

    Теперь в оригинале:
    Цитировать
    \e    an escape character
    Перевод :  " «\e» - это символ клавиши «escape»(«Esc»)!!!! "  *WALL*
    Теперь запись «\e»  можно использовать в командах для указания клавиши «Esc». 
    Как ведет себя  клавиша «Esc» описано  среди встроенных команд Readline:
    Цитировать
    prefix-meta (ESC)
        Заменяет клавишу Meta на клавишу Esc для следующего введенного символа. Таким образом нажатие Esc потом f эквивалентно Meta-f. Это работает также для Alt или Ctrl+[, которые заменяют Esc.
    « Последнее редактирование: 06 Апрель 2016, 00:55:26 от Alexcostariha »

    Brego

    • Ветеран
    • *****
    • Сообщений: 566
    • Карма: +93/-1
    • Перебьемся
      • Просмотр профиля
      • MintMem
    Очень интересно и полезно. О возможности напрямую биндить комбинации клавиш к readline я как-то даже и не знал. Век живи -- век учись!  :)
    "Следующая эпоха началась с сожжения всех хроник вместе с хронистами". С. Лем