Форум программистов, компьютерный форум, киберфорум
Наши страницы
Mysterious Light
Войти
Регистрация
Восстановить пароль
Оценить эту запись

Автодополнение текста сообщений в darcs

Запись от Mysterious Light размещена 01.11.2017 в 16:13

Проблема:
В системе контроля версий darcs можно задать автодополнение bash, которое дополняет некоторые параметры командной строки.
Во время составления текста сообщения коммита возникает желание использовать автодополнение названий длинных или сложнозапоминаемых функций.

Возьмём в качестве стартовой точки скрипт автодополнений 2002г, написанный Дэвидом Рунди (David Roundy).
Кликните здесь для просмотра всего текста
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# darcs command line completion.
# Copyright 2002 "David Roundy" <droundy@abridgegame.org>
# This archive should be copied in the directory /etc/bash_completion.d/
 
_darcs()
{
    local cur
    cur=${COMP_WORDS[COMP_CWORD]}
 
    COMPREPLY=()
 
    if (($COMP_CWORD == 1)); then
        COMPREPLY=( $( darcs --commands | command grep "^$cur" ) )
        return 0
    fi
 
    local IFS=$'\n' # So that the following "command-output to array" operation splits only at newlines, not at each space, tab or newline.
    COMPREPLY=( $( darcs ${COMP_WORDS[1]} --list-option | command grep "^${cur//./\\.}") )
 
    # Then, we adapt the resulting strings to be reusable by bash. If we don't
    # do this, in the case where we have two repositories named
    # ~/space in there-0.1 and ~/space in there-0.2, the first completion will
    # give us:
    # bash> darcs push ~/space in there-0.
    # ~/space in there-0.1 ~/space in there-0.2
    # and we have introduced two spaces in the command line (if we try to
    # recomplete that, it won't find anything, as it doesn't know anything
    # starting with "there-0.").
    # printf %q will gracefully add the necessary backslashes.
    #
    # Bash also interprets colon as a separator. If we didn't handle it
    # specially, completing http://example.org/repo from http://e would 
    # give us:
    # bash> darcs pull http:http://example.org/repo
    # An option would be to require the user to escape : as \: and we
    # would do the same here. Instead, we return only the part after
    # the last colon that is already there, and thus fool bash. The
    # downside is that bash only shows this part to the user.
    local i=${#COMPREPLY[*]}
    local colonprefixes=${cur%"${cur##*:}"}
    while [ $((--i)) -ge 0 ]; do
      COMPREPLY[$i]=`printf %q "${COMPREPLY[$i]}"`
 
      COMPREPLY[$i]=${COMPREPLY[$i]#"$colonprefixes"} 
    done
    return 0
 
}
complete -F _darcs -o default darcs


Создадим скрипт, который сканирует все файлы рабочей директории и создаёт словарь слов в файле _darcs/var.list
Bash
1
2
3
4
5
6
7
#!/bin/sh
 
# run this script from the root of the repo
# Alternatively: replace . with repodir=$( darcs show repo | sed '/^\s*Root:/!d; s/^\s*Root:\s*//' )
find . -type f -print0 | xargs -0 -n1 cat | \
  sed -n '/\n/{P;D;}; s/ \([a-zA-Z]\w\{5,15\}\)\W/\n\1\n/; D;'|\
  sort -u > _darcs/var.list;
После запуска этого файла появится файл var.list в папке репозитория. Он включает в себя все слова, которые слева отбиты пробельным символом, а справа неалфавитным знаком, причём длина находится в диапазоне 5-15 букв. На данный момент эта евристика даёт хороший результат, мой словарь содержит 8258 слов. Регистр учитывается.
Конечно, можно улучшить евристику и добавить параметры для исключения фалов. Но и так мне кажется достаточно.

Далее изменим скрипт автодополнения
Кликните здесь для просмотра всего текста
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# darcs command line completion.
# Copyright 2002 "David Roundy" <droundy@abridgegame.org>
# Modified 2017 by "Mysterious Light"
# This archive should be copied in the directory /etc/bash_completion.d/
 
_darcs()
{
    local cur
    cur=${COMP_WORDS[COMP_CWORD]}
 
    COMPREPLY=()
 
    if (($COMP_CWORD == 1)); then
        # ML: add "status" to a command list
        COMPREPLY=( $( (darcs --commands; echo "status") | command grep "^$cur" ) )
        return 0
    fi
 
    local IFS=$'\n' # So that the following "command-output to array" operation splits only at newlines, not at each space, tab or newline.
    COMPREPLY=( $( darcs ${COMP_WORDS[1]} --list-option | command grep "^${cur//./\\.}") )
 
    # ML: begin of message completion
    cur1=$( echo "$cur" | sed '/^\"/!d; s/^\"//; s/\"$//' )
    if [ -n "$cur1" ];
    then
      cur1=$( echo "$cur1" | sed 's/\s\(\S*\)$/\n\1/' )
      cur0=$( echo "$cur1" | head -n -1 )
      if [ -n "$cur0" ]; then cur0="$cur0 "; fi
      cur1=$( echo "$cur1" | tail -n  1 )
      repodir=$( darcs show repo | sed '/^\s*Root:/!d; s/^\s*Root:\s*//' )
      lst=$repodir/_darcs/var.list
      if [ -e "$lst" ];
      then
        COMPREPLY=( $(
            cat $repodir/darcs-tool/var.list | sed "/^${cur1//./\\.}/!D; s//${cur0}&/"
          ) )
        return 0
      fi
    fi
    # ML: end of message completion
 
    # Then, we adapt the resulting strings to be reusable by bash. If we don't
    # do this, in the case where we have two repositories named
    # ~/space in there-0.1 and ~/space in there-0.2, the first completion will
    # give us:
    # bash> darcs push ~/space in there-0.
    # ~/space in there-0.1 ~/space in there-0.2
    # and we have introduced two spaces in the command line (if we try to
    # recomplete that, it won't find anything, as it doesn't know anything
    # starting with "there-0.").
    # printf %q will gracefully add the necessary backslashes.
    #
    # Bash also interprets colon as a separator. If we didn't handle it
    # specially, completing http://example.org/repo from http://e would 
    # give us:
    # bash> darcs pull http:http://example.org/repo
    # An option would be to require the user to escape : as \: and we
    # would do the same here. Instead, we return only the part after
    # the last colon that is already there, and thus fool bash. The
    # downside is that bash only shows this part to the user.
    local i=${#COMPREPLY[*]}
    local colonprefixes=${cur%"${cur##*:}"}
    while [ $((--i)) -ge 0 ]; do
      COMPREPLY[$i]=`printf %q "${COMPREPLY[$i]}"`
 
      COMPREPLY[$i]=${COMPREPLY[$i]#"$colonprefixes"} 
    done
 
    return 0
 
}
complete -F _darcs -o default darcs

Проверяем:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
$ darcs re<Tab+Tab>
rebase   record   remove   repair   replace  revert 
$ darcs re
$ darcs rec<Tab>
$ darcs record 
$ darcs record -m "Abs<Tab>
$ darcs record -m "Abstracts"
$ darcs record -m "An ab<Tab+Tab>
An ability         An abortRecording  An absolute        An abstraction
An aborted         An absDelta        An abstract        An abstractions
$ darcs record -m "An ab
$ darcs record -m "An abil<Tab>
$ darcs record -m "An ability"
<Tab> -- в этом месте нажал на Tab, <Tab+Tab> -- два раза.
Следующая после строка с $ указывает на состояние командной строки после нажатия на Tab.

Отличительная черта (увы, не фича) заключается в автоматическом закрывании кавычек после автодополнения.
Размещено в Без категории
Просмотров 302 Комментарии 0
Всего комментариев 0
Комментарии
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru