별칭으로 작업하기 위해 bash 완료를 어떻게 얻습니까? 나는 별칭을

지목 사항:

나는 bash v3.2.17을 사용하는 Mac에서 bash_completion 변형과 함께 macports를 통해 설치된 git을 사용하고 있습니다.

내가 입력하면 git checkout m<tab>. 예를 들어에 완료되었습니다 master.

그러나, 나는 별칭을 가지고있다 git checkout, gco. 을 입력 gco m<tab>하면 지점 이름이 자동 완성되지 않습니다.

이상적으로는 자동 완성 기능을 사용하여 모든 별칭에 마술처럼 작동하고 싶습니다. 가능합니까? 실패하면 각 별칭에 대해 수동으로 사용자 정의하고 싶습니다. 그래서 어떻게해야합니까?



답변

위의 의견에서 언급했듯이

complete -o default -o nospace -F _git_checkout gco

더 이상 작동하지 않습니다. 그러나 __git_completegit-completion.bash에는 다음과 같이 별칭의 완성을 설정하는 데 사용할 수 있는 기능이 있습니다.

__git_complete gco _git_checkout


답변

나는이 문제에 부딪 쳤고이 코드 스 니펫을 생각해 냈습니다. 이렇게하면 모든 별칭의 완성이 자동으로 제공됩니다. 모든 (또는 다른) 별명을 선언 한 후 실행하십시오.

# wrap_alias takes three arguments:
# $1: The name of the alias
# $2: The command used in the alias
# $3: The arguments in the alias all in one string
# Generate a wrapper completion function (completer) for an alias
# based on the command and the given arguments, if there is a
# completer for the command, and set the wrapper as the completer for
# the alias.
function wrap_alias() {
  [[ "$#" == 3 ]] || return 1

  local alias_name="$1"
  local aliased_command="$2"
  local alias_arguments="$3"
  local num_alias_arguments=$(echo "$alias_arguments" | wc -w)

  # The completion currently being used for the aliased command.
  local completion=$(complete -p $aliased_command 2> /dev/null)

  # Only a completer based on a function can be wrapped so look for -F
  # in the current completion. This check will also catch commands
  # with no completer for which $completion will be empty.
  echo $completion | grep -q -- -F || return 0

  local namespace=alias_completion::

  # Extract the name of the completion function from a string that
  # looks like: something -F function_name something
  # First strip the beginning of the string up to the function name by
  # removing "* -F " from the front.
  local completion_function=${completion##* -F }
  # Then strip " *" from the end, leaving only the function name.
  completion_function=${completion_function%% *}

  # Try to prevent an infinite loop by not wrapping a function
  # generated by this function. This can happen when the user runs
  # this twice for an alias like ls='ls --color=auto' or alias l='ls'
  # and alias ls='l foo'
  [[ "${completion_function#$namespace}" != $completion_function ]] && return 0

  local wrapper_name="${namespace}${alias_name}"

  eval "
function ${wrapper_name}() {
  let COMP_CWORD+=$num_alias_arguments
  args=( \"${alias_arguments}\" )
  COMP_WORDS=( $aliased_command \${args[@]} \${COMP_WORDS[@]:1} )
  $completion_function
  }
"

  # To create the new completion we use the old one with two
  # replacements:
  # 1) Replace the function with the wrapper.
  local new_completion=${completion/-F * /-F $wrapper_name }
  # 2) Replace the command being completed with the alias.
  new_completion="${new_completion% *} $alias_name"

  eval "$new_completion"
}

# For each defined alias, extract the necessary elements and use them
# to call wrap_alias.
eval "$(alias -p | sed -e 's/alias \([^=][^=]*\)='\''\([^ ][^ ]*\) *\(.*\)'\''/wrap_alias \1 \2 '\''\3'\'' /')"

unset wrap_alias


답변

에서 git-completion.bash선이있다 :

complete -o default -o nospace -F _git git

해당 줄과 _git 함수를 보면이 줄을 다음에 추가 할 수 있습니다 .bash_profile.

complete -o default -o nospace -F _git_checkout gco


답변

나는 g = ‘git’이라는 별칭을 가지고 있으며, git 별칭과 결합하여 다음과 같은 것을 입력합니다.

$ g co <branchname>

내 특정 사용 사례에 대한 간단한 수정은 git-completion에 한 줄을 추가하는 것이 었습니다.

이 줄 바로 아래 :

__git_complete git _git

단일 ‘g’별칭을 처리하기 위해이 줄을 추가했습니다.

__git_complete g _git


답변

이상적으로는 자동 완성 기능을 사용하여 모든 별칭에 마술처럼 작동하고 싶습니다. 가능합니까?

예, 전체 별칭 프로젝트 (Linux의 경우)로 가능합니다. Mac 지원은 실험적이지만 사용자는 성공을보고했습니다.


답변

Git 별칭을 사용해 볼 수도 있습니다. 예를 들어, 내 ~/.gitconfig파일에는 다음과 같은 섹션이 있습니다.

[alias]
        co = checkout

따라서을 입력 하면 명령으로 git co m<TAB>확장됩니다 .git co mastergit checkout


답변

이 포럼 페이지 는 솔루션을 보여줍니다.

이 줄을 당신의 .bashrc또는에 넣으십시오 .bash_profile:

# Author.: Ole J
# Date...: 23.03.2008
# License: Whatever

# Wraps a completion function
# make-completion-wrapper <actual completion function> <name of new func.>
#                         <command name> <list supplied arguments>
# eg.
#   alias agi='apt-get install'
#   make-completion-wrapper _apt_get _apt_get_install apt-get install
# defines a function called _apt_get_install (that's $2) that will complete
# the 'agi' alias. (complete -F _apt_get_install agi)
#
function make-completion-wrapper () {
    local function_name="$2"
    local arg_count=$(($#-3))
    local comp_function_name="$1"
    shift 2
    local function="
function $function_name {
    ((COMP_CWORD+=$arg_count))
    COMP_WORDS=( "$@" \${COMP_WORDS[@]:1} )
    "$comp_function_name"
    return 0
}"
    eval "$function"
}

# and now the commands that are specific to this SO question

alias gco='git checkout'

# we create a _git_checkout_mine function that will do the completion for "gco"
# using the completion function "_git"
make-completion-wrapper _git _git_checkout_mine git checkout

# we tell bash to actually use _git_checkout_mine to complete "gco"
complete -o bashdefault -o default -o nospace -F _git_checkout_mine gco

이 솔루션은 balshetzer의 스크립트 와 유사 하지만 실제로이 솔루션 만 작동합니다. (balshetzer의 스크립트에 내 별칭 중 일부에 문제가있었습니다.)