Проблема:
В системе контроля версий 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.
Отличительная черта (увы, не фича) заключается в автоматическом закрывании кавычек после автодополнения.
|