Правильно обрабатывающие пробелы и кавычки в завершении удара

Я с Желанием:

  • Двойные кавычки для текста
  • Одинарные кавычки для чего-либо, что ведет себя как идентификатор
  • Двойные заключенные в кавычки необработанные строковые литералы для regexps
  • Утроенные двойные кавычки для docstrings

, который я продолжу работать с этим, даже если это будет означать большой выход.

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

26
задан Karl Ove Hufthammer 17 July 2009 в 23:38
поделиться

1 ответ

Мне кажется, это не слишком элегантное решение для постобработки работает (GNU bash, версия 3.1.17 (6) -релиз (i686-pc-cygwin)). (Если я не тестировал какой-нибудь пограничный регистр, как обычно :))

Не нужно оценивать вещи, есть только два вида кавычек.

Поскольку compgen не хочет для нас экранировать пробелы, мы сами избежите их (только если слово не начинается с цитаты). Это имеет побочный эффект - полный список (на двойной вкладке) также имеет экранированные значения. Не уверен, хорошо это или нет, поскольку ls этого не делает ...

РЕДАКТИРОВАТЬ: Исправлена ​​обработка одинарных и двойных кавычек внутри слов. По сути, нам нужно пройти 3 перехода :). Первый для grep, второй для compgen и последний для самой команды words, когда автозаполнение выполнено.

_find_words()
{
    search=$(eval echo "$cur" 2>/dev/null || eval echo "$cur'" 2>/dev/null || eval echo "$cur\"" 2>/dev/null || "")
    grep -- "^$search" words.dat | sed -e "{" -e 's#\\#\\\\#g' -e "s#'#\\\'#g" -e 's#"#\\\"#g' -e "}"
}

_words_complete()
{
    local IFS=$'\n'

    COMPREPLY=()
    local cur="${COMP_WORDS[COMP_CWORD]}"

    COMPREPLY=( $( compgen -W "$(_find_words)" -- "$cur" ) )

    local escaped_single_qoute="'\''"
    local i=0
    for entry in ${COMPREPLY[*]}
    do
        if [[ "${cur:0:1}" == "'" ]] 
        then
            # started with single quote, escaping only other single quotes
            # [']bla'bla"bla\bla bla --> [']bla'\''bla"bla\bla bla
            COMPREPLY[$i]="${entry//\'/${escaped_single_qoute}}" 
        elif [[ "${cur:0:1}" == "\"" ]] 
        then
            # started with double quote, escaping all double quotes and all backslashes
            # ["]bla'bla"bla\bla bla --> ["]bla'bla\"bla\\bla bla
            entry="${entry//\\/\\\\}" 
            COMPREPLY[$i]="${entry//\"/\\\"}" 
        else 
            # no quotes in front, escaping _everything_
            # [ ]bla'bla"bla\bla bla --> [ ]bla\'bla\"bla\\bla\ bla
            entry="${entry//\\/\\\\}" 
            entry="${entry//\'/\'}" 
            entry="${entry//\"/\\\"}" 
            COMPREPLY[$i]="${entry// /\\ }"
        fi
        (( i++ ))
    done
}
8
ответ дан 28 November 2019 в 07:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: