명령 없이 zsh에서 용어 평가

명령 없이 zsh에서 용어 평가

zsh를 사용하고 있습니다프레스토 악장구성 프레임워크. 비슷한 용어를 입력하여 1 + 2 * (3 / 4)"2.5"를 얻을 수 있기를 바랍니다 .

이러한 용어는 다음과 같은 특정 문자만 포함하기 때문에 인식될 수 있습니다 0123456789 +-*/(). 더 복잡한 작업의 경우 Python 셸과 같은 전용 프로그램을 열 수 있습니다.

솔루션이 충분하지 않음

  1. 사용프로그램python -c: 용어 앞에 입력하거나 에 입력하고 싶지 않습니다 bc. 입력이 너무 많습니다. 더 잘할 수 있었으면 좋겠습니다.
  2. 함수 또는 별칭 사용: 좀 있어요해결책cOR을 사용할 때 에서 와 같이 =이러한 계산을 수행 할 수 있습니다 . 훌륭하지만 기본적으로 포인트 1과 동일합니다.calc= 1 + 2 * (3 / 4)
  3. 다른 쉘 사용: 알아요젠시나는 이것을 할 수 있는 다른 쉘이 있다고 확신합니다. 하지만 나는 zsh를 좋아하고 쉘을 바꾸고 싶지 않습니다.

무엇이 효과가 있을지

  1. zsh 플러그인:명령이 특정 정규식과 일치하는지 확인한 다음 이를 python/bc/whatever로 파이프하는 zsh 플러그인을 상상할 수 있습니다. 디렉토리 이름만 입력하면 autocd가 수행하는 작업과 다소 유사합니다. 이것이 가능한지 모르겠습니다. 몇 가지 팁을 듣고 싶어서 적어보겠습니다.
  2. 가로채기command not found: 4와 비슷합니다. 명령을 찾을 수 없을 때 zsh의 동작을 가로채는 것이 가능할 수도 있습니다. 하지만 어떻게 해야할지 모르겠습니다.
  3. 모든 번호에 대한 별칭:모든 숫자에 대한 별칭을 작성하여 나머지 수학 문자열을 인수로 사용하는 명령이 되도록 할 수 있을 것 같습니다. 이것은 효과가 있을 수 있지만 진부해 보입니다. 또한 "모든 숫자"는 자동으로 코드를 생성하는 경우에도 별칭입니다.

이 문제를 해결하는 방법에 대한 아이디어를 듣고 싶습니다. 나는 코드 작성을 두려워하지 않지만, 해킹된 솔루션보다 깔끔한 솔루션을 선호합니다.

답변1

명령이 실행되기 전에 가로채는 것이 가능하지만 너무 늦었습니다. 명령이 이미 구문 분석되었고 별칭이 확장되었습니다. 예를 들어, 이는 찾을 수 없는 명령 (해당 이름의 명령이 없다고 가정) 2 * 3으로 나타나고 그 뒤에 현재 디렉터리에 있는 파일 목록이 표시됩니다.2

대신, 명령이 제출된 후 즉시(파싱되기 전이라도) 명령을 차단해야 합니다. 따라서 명령 실행 엔진이 아닌 명령줄 인터페이스에 연결해야 합니다. 이 작업을 수행하는 일반적인 방법은 없다고 생각합니다. 제가 생각할 수 있는 유일한 방법은 Enter 키 명령과 그 형제 명령을 무시하고 명령줄을 덮어쓰도록 하는 것입니다. 예쁘지는 않지만 원하는 대로 작동합니다.

주요 Enter 키 명령은 다음과 같습니다.accept-line, 에 바인딩 ^J^M. 다음과 같이 이를 재정의할 수 있습니다(예를 accept-and-hold들어 사용하는 다른 유사한 위젯에 대해 이 작업을 수행해야 합니다 accept-line-and-down-history).

function my-accept-line {
    my-rewrite-accepted-line "$@"
    zle accept-line "$@"
}
zle -N my-accept-line
bindkey '^J' my-accept-line
bindkey '^M' my-accept-line

이제 함수가 허용된 행을 다시 작성하도록 합니다. 이 노선은 다음 위치에 있습니다.BUFFER. 유일한 어려움은 다시 작성된 논리입니다. 아마도 다음과 같이 행이 숫자(변수가 아니라 너무 모호함)로 시작해야 하고 선택적으로 단항 연산자와 괄호가 앞에 오고 그 뒤에 이진 연산자가 와야 합니다.

function my-rewrite-accepted-line {
  emulate -L zsh
  setopt extended_glob
  if [[ ${BUFFER// /} == [\(+\-]#([0-9]##(|.[0-9]#)(|e(-|+|)[0-9]##)|0x[0-9A-Fa-f]##)[-+*/%\&\|\^]* ]]; then
    BUFFER="echo \$(($BUFFER))"
  fi
}

저는 베어 zsh를 사용하여 최소한의 테스트만 수행했습니다. 이것이 Prezto를 방해하는지 여부는 조사하지 않았습니다.

관련 정보