다른 디렉토리와 완전히 관련된 명령 완료

다른 디렉토리와 완전히 관련된 명령 완료

다른 범주에서 단일 명령을 실행하는 기능이 있습니다. cd1 SOMEDIR MYCOMMAND ARG…마찬가지로 (cd SOMEDIR && MYCOMMAND ARG…)두 가지 장점이 있습니다. 입력하기가 약간 더 쉽고(명령줄 중독자인 경우 모든 키 입력이 중요함) (대부분) SOMEDIR.

즉, 완성 함수를 정의할 수 있습니다 cd1.친척 완료를 어떻게 준비할 수 있나요 SOMEDIR?

다음은 수정하지 않으면 작동하지 않습니다.

  • _files여기서는 명령 매개변수의 수정된 매개변수를 사용하여 임시 호출을 수행하는 것이 좋지 않습니다.거기) 일반적인 상황에 맞는 완성을 모두 적용하고 싶기 때문입니다.
  • (cd $words[2] && shift 2 words && ((CURRENT-=2)) && _normal)완성이 서브쉘에서 작동한다면 올바른 일을 할 것이지만 그렇지 않습니다.
  • cd $words[2] && shift 2 words && ((CURRENT-=2)) && _normal; cd $OLDPWD정상적인 상황에서는 작동하지만, + 취소를 SOMEDIR누르면 완료하는 데 오랜 시간이 걸리는 것처럼 특정 상황에서는 중단되고 꼼짝 못하게 됩니다 .CtrlC

이것이 의 정의입니다 cd1. 대상 디렉터리에 대한 별칭 및 확장 와일드카드를 지원합니다(반면에 명령 대체 등은 원래 디렉터리에서 계속 실행됩니다).

cd1_glob () {
  if (($# <= 1)); then
    cd -- "$1"
  elif (($+aliases[$2])); then
    ( cd -- $1 && eval $2 '$~@[3,$#]' )
  else
    ( cd -- $1 && $~@[2,$#] )
  fi
}
alias cd1='noglob cd1_glob'

(저는 이 함수를 호출하지 않습니다. 호출할 경우 cd함수 내부 호출을 로 변경하세요.)cdbuiltin cd

답변1

이것이 내가 지금까지 가지고 있는 것입니다. 완벽하지는 않지만 다음과 같습니다.

  • 대상 디렉터리를 기준으로 완료되었습니다.
  • 대상 디렉터리가 없으면 자동 오류가 발생합니다.
  • 건너뛰고 chpwd복원 chpwd_functions하는 것이 맞다고 생각합니다.
  • 취소가 완료되면 현재 디렉터리가 복원됩니다.

복잡하고 취약해 보이기 때문에 극단적인 경우에는 전혀 자신이 없습니다. 알려진 문제:

  • 완성이 항상 접미사 문자(예: 공백 또는 디렉토리)를 추가하는 것은 아닙니다 /. 예를 들어 삽입 만 삽입 cd1 / echo /biTab합니다 ( 삽입은 ).n/cd1 / echo biTabnecho biTabn/
  • 작업이 완료되는 동안 원래 디렉터리의 이름이 바뀌면 쉘은 새 이름을 가진 이전 디렉터리 대신 이전 이름을 가진 새 디렉터리로 돌아갑니다.
#compdef cd1 cd1_glob
# cd for one command

_cd1_in () {
  setopt local_options local_traps
  # Cleanup:
  # * Restore the old directory. We do this only if cd succeeded beause
  #   the restoration can do the wrong thing in corner cases (renamed
  #   directory).
  # * Restore the chpwd hook function and the hook array.
  trap 'if ((_cd1_cd_succeeded)); then cd $OLDPWD; fi
        if [[ -n $_cd1_chpwd_function ]]; then
          functions[chpwd]=$_cd1_chpwd_function
        fi
       ' EXIT INT
  builtin cd $words[2] 2>/dev/null || { _cd1_cd_succeeded=0; return 1; }
  shift 2 words; ((CURRENT -= 2))
  _normal
}

_cd1 () {
  if ((CURRENT > 2)); then
    setopt local_options no_auto_pushd unset
    local _cd1_cd_succeeded=1
    # Save the current directory and the chpwd hook. They will be restored
    # by the exit trap in _cd1_in.
    local _cd1_chpwd_function=$functions[chpwd]
    # Save the current directory in $OLDPWD. _cd_in will call cd, which would
    # generally call cd
    local OLDPWD=$PWD
    # Turn off the chpwd hook function and the associated hook array.
    local chpwd_functions=
    unset -f chpwd 2>/dev/null
    # Call a separate function to do the work. Its exit trap will take care
    # of cleanup. The reason to have a separate function is so that the
    # local variables defined here can be used in the exit trap.
    _cd1_in
  else
    _dirs
  fi
}

_cd1 "$@"

관련 정보