저는 Bash를 사용하고 있으며 PS1은 두 줄에 걸쳐 있습니다.
╭-ivan·dotfiles (master)
╰ဝ █
때로는 출력에 줄바꿈 문자가 없고 프롬프트가 잘못 정렬되는 명령을 실행합니다.
╭-ivan·dotfiles (master)
╰ဝ curl localhost:3002/is_alive
{"web_server_status":"success","db_status":"success"}╭-ivan·dotfiles (master)
╰ဝ █
커서가 첫 번째 열을 넘어서는 경우 프롬프트 앞에 조건부로 개행을 추가하는 솔루션을 마침내 찾았습니다.
build_prompt() {
export PS1="\$(ps1_head)...
}
ps1_head() {
if (( $(cursor_col) > 1 )); then
printf '\n╭-'
else
printf '╭-'
fi
}
cursor_col() {
local _row col
IFS=';' read -s -dR -p $'\033[6n' _row col
echo "${col}"
}
이로써 원래의 문제가 해결되었습니다.
╭-ivan·dotfiles (master)
╰ဝ curl localhost:3002/is_alive
{"web_server_status":"success","db_status":"success"}
╭-ivan·dotfiles (master)
╰ဝ █
그러나 새로운 것을 소개합니다. 현재 명령이 완료되기 전에 다음 명령을 입력할 수 있도록 자동 완성 기능을 사용합니다. 조건부 래핑으로 인해 이 동작이 중단되는 것 같습니다.
조건부 래핑 논리가 없는 예:
╭-ivan·dotfiles (master)
╰ဝ git status
On branch master
Your branch is up-to-date with 'origin/master'.
lnothing to commit, working tree clean
s╭-ivan·dotfiles (master)
╰ဝ ls
myfile.txt
첫 번째 명령의 출력이 인쇄를 완료하기 전에 ( )를 입력했고 l
, 첫 번째 명령이 완료된 후 프롬프트가 인쇄되기 전에 이를 입력했습니다. typeahead는 두 문자( )를 다음 명령으로 우아하게 가져옵니다.lnothing to commit
s
ls
이제 내 프롬프트에서 조건부 래핑 논리를 사용하는 동일한 예가 있습니다.
╭-ivan·dotfiles (master)
╰ဝ git status
On branch master
Your branch is up-to-date with 'origin/master'.
lnothing to commit, working tree clean
s╭-ivan·dotfiles (master)
╰ဝ s
bash: s: command not found
이번에는 typeahead가 어떻게 s
두 번째 명령을 우아하게 가져오지만 뒤에 남겨지는지 확인하세요 l
.
이를 좀 더 우아하게 처리할 수 있는 방법이 있습니까? 아니면 결국 zsh로 전환해야 합니까?
답변1
이와 같은 동적 프롬프트 텍스트가 있는데 자동 완성에는 문제가 없습니다. 하지만 설정 메서드 호출 PS1
에 프로세스 교체를 직접 포함하지 않았습니다 . PROMPT_COMMAND
적절한 동적 텍스트를 생성하고 이를 변수에 저장한 다음 PS1
.
그럼 이런 걸 시도해 보세요...
export ps1_head_text
build_prompt() {
export PS1="\${ps1_head_text}..."
}
ps1_head() {
if (( $(cursor_col) > 1 )); then
ps1_head_text=$'\n'╭-
else
ps1_head_text=╭-
fi
}
export PROMPT_COMMAND=ps1_head
나는 프로세스 대체에 문제가 있었기 때문에 결국 이 작업을 수행하게 되었습니다. (비록 이것이 미리 입력된 것인지 아니면 다른 것인지는 기억나지 않지만).
편집하다:지금 생각해보면 타이밍 문제가 있을 수 있습니다. PROMPT_COMMAND
커서 위치를 올바르게 읽을 수 없는 시간에 if가 호출되고 있습니다. 이런 일이 발생하면 "zsh 사용"을 선택할 수 있습니다. 하지만 한번 시도해 보세요.
고쳐 쓰다:에 따르면dave_thompson_085의 댓글이스케이프 시퀀스(커서 위치를 인쇄하는 데 사용됨) 방출에 대한 응답을 읽으면 자동 완성 기능과 충돌할 수 있습니다.
자동 완성 텍스트가 입력된 동일한 셸에서 읽기가 발생하므로 이는 의미가 있습니다. 그렇다면 동일한 쉘에서 실행되지 않으면 어떻게 될까요? 괄호를 사용하여 하위 쉘에 넣는 것이 도움이 될까요? 터미널에서 응답을 리디렉션(예: 파일이나 파이프 등)하여 거기에서 읽는 것은 어떻습니까?
이 문제를 해결할 방법이 있을 것 같아서 벽에 몇 가지 물건을 던져 무엇이 붙는지 확인했습니다.