bagaimana cara memformat path dalam prompt zsh?

23

Saya ingin memiliki jalur berwarna yang dapat dibaca. Sebagai contoh, alih-alih hanya menggunakan% ~ untuk kembali, ~/path/to/foosaya ingin memformatnya ~$RED/$NOCOLORpath$RED/$NOCOLORto$RED/$NOCOLORfoountuk menyorot pemisah jalur.

Bisakah saya mendefinisikan konten PROMPT sehingga ekspresi jalur akan dievaluasi kembali pada setiap tampilan? Sesuatu seperti ${${(%):-%~}//\//_some_format_expression/}jelas tidak berfungsi.

Atau haruskah saya meretas ini lebih lanjut, dan memaksakan nilai PROMPT untuk mendapatkan reset setiap kali kita mengubah direktori?

Solusi apa pun yang mencapai sasaran pemformatan jalur akan diterima.

Terima kasih :)

Nicolas Dumazet
sumber
jika Anda masih ada, Anda mungkin ingin menandai jawaban terbaik untuk ini :)
Dan Rosenstark

Jawaban:

36

zsh

Coba ini:

setopt PROMPT_SUBST
PROMPT='%{$(pwd|grep --color=always /)%${#PWD}G%} %(!.%F{red}.%F{cyan})%n%f@%F{yellow}%m%f%(!.%F{red}.)%#%f '

Berikut ini rincian dari prompt:

  • PROMPT_SUBST mengaktifkan substitusi perintah di prompt (dan perluasan parameter dan ekspansi aritmatika)
  • %{...%} - urutan pelarian
  • $(pwd|grep --color=always /)- cetak direktori saat ini dan sorot /- warna akan tergantung pada variabel lingkungan $ GREP_COLORS (atau nilai standarnya) - tebal merah adalah default
  • %${#PWD}G- gunakan panjang karakter karakter dari direktori saat ini sebagai nilai kesalahan. Ini membuat shell menganggap ini sebagai panjang dari urutan karakter sebelumnya (setelah " %{") alih-alih panjang sebenarnya dari string yang mencakup urutan escape ANSI. Ini menjaga shell agar tidak bingung tentang posisi kursor relatif terhadap akhir prompt.
    - - - - - - - ini adalah akhir dari bagian yang menjawab pertanyaan Anda - - - - - - -
  • %(!.%F{red}.%F{cyan}) - jika ini adalah shell istimewa (root) atur warna foreground menjadi merah, jika tidak cyan
  • %n - Keluarkan nama pengguna
  • %f - mengatur ulang warna latar depan ke default
  • @ - Tanda harafiah
  • %F{yellow} - membuat warna foreground menjadi kuning
  • %m - Keluarkan nama host
  • %f - mengatur ulang warna latar depan ke default
  • %(!.%F{red}.) - jika ini adalah shell istimewa (root) atur warna foreground menjadi merah
  • %#- Output a #untuk shell istimewa atau %untuk shell yang tidak terjangkau
  • %f - mengatur ulang warna latar depan ke default

Saya menempatkan jalan pertama dalam prompt ini untuk penekanan, karena pertanyaannya menyangkut jalan.

teks alternatif

Ini adalah versi untuk zsh yang mengubah warna garis miring tergantung pada apakah Anda root (diistimewakan) dengan memanipulasi $GREP_COLORSvariabel:

setopt PROMPT_SUBST
PROMPT='%{$(pwd|([[ $EUID == 0 ]] && GREP_COLORS="mt=01;31" grep --color=always /|| GREP_COLORS="mt=01;34" grep --color=always /))%${#PWD}G%} %(!.%F{red}.%F{cyan})%n%f@%F{yellow}%m%f%(!.%F{red}.)%#%f '

Pesta

Anda dapat melakukan prompt serupa di Bash. Dalam contoh ini, saya telah menempatkan pengguna dan nama host terlebih dahulu dan warna garis miring juga berubah ketika UID adalah 0. Peringatan: ini menimpa $PS1variabel prompt Bash . Itu seharusnya tidak menjadi masalah kecuali jika Anda melakukan sesuatu yang istimewa atau Anda mengharapkan perilaku berubah ketika Anda mengatur variabel itu secara langsung dan ini berlaku. Juga, ini menggunakan variabel yang disebut " usercolor" yang mungkin bertabrakan dengan sesuatu yang lain, meskipun semua ini bisa dimasukkan ke dalam fungsi dan variabel dideklarasikan secara lokal.

PROMPT_COMMAND='usercolor="\[\033[0;36m\]";[[ $EUID == 0 ]] && usercolor="\[\033[1;31m\]";PS1="$(pwd)";PS1="$usercolor\u\[\033[0m\]@\[\033[0;33m\]\h\[\033[0m\]:${PS1//\//$usercolor/\[\033[0m\]}$usercolor\\$\[\033[0m\] "'

teks alternatif

Saya mengambil keuntungan dari fakta bahwa Bash tidak memiliki fitur "glitch" zsh untuk menggunakan substitusi ekspansi parameter untuk secara kondisional mewarnai garis miring (daripada menggunakan grep).

Dijeda sampai pemberitahuan lebih lanjut.
sumber
panggil saya bodoh, tetapi satu-satunya bagian yang salah yang saya miliki adalah penggunaan tanda kutip ganda dan bukan tanda kutip tunggal dalam definisi PROMPT. Terima kasih :)
Nicolas Dumazet
@NicDumZ, lucu, saya menghabiskan sekitar 20 menit untuk masalah di tempat lain kemarin :)
Dan Rosenstark
1
ini masif (geeky dan) keren. Terima kasih ...
Dan Rosenstark
Adakah yang tahu bagaimana melakukan ini di Bash, atau mengapa itu tidak berhasil di Bash? Bagi saya dengan Bash itu hanya macet di direktori pertama saya memulai terminal saya, dan tidak memperbarui ketika saya bergerak. Saya hanya mengambil $ (pwd | grep --color = always /) dan meletakkannya di PS1 saya dan mendapatkan perilaku aneh. Sunting: OH! Tidak melihat bagian Bash, lol.
Ibrahim
Sebenarnya, saya mencoba menggunakan trik PS1 Anda untuk Bash di prompt saya yang lebih kompleks dan tidak berfungsi, PWD saya macet lagi. Tapi cuplikan Anda berfungsi apa adanya. Apa tujuan PROMPT_COMMAND? Inilah yang saya dapat: PS1="$(pwd)"; PS1="${debian_chroot:+($debian_chroot)}\[$bldgrn\]\u@$(fgcolor $hostnamecolor)\h$(resetcolor)\[$txtrst\]:\[$bldblu\]${PS1//\//$txtred/$bldblu}\[\e[00m\]$bldred\$(parse_git_branch)\[$txtrst\] \[$undcyn\]\T \d\[$txtrst\] 95\$ "warna-warna yang ditentukan di github.com/ibrahima/dotfiles/blob/master/.bashrc.d/prompt.sh
Ibrahim
4

Setelah beberapa berkeliling, saya dapat memberikan solusi mengesampingkan chpwd:

doprompt() {
  local my_path=${(%):-%~}
  PROMPT="${yourstuff}${my_path//\//${PR_BOLD_RED}/${reset_color}}${otherstuff}"
}
doprompt

chpwd() {
  doprompt
  # unrelated: set window title
  [[ -t 1 ]] || return;
  print -Pn "\e]2;%n@%m: %~\a";
}
  • Apakah ada cara untuk meningkatkan kode ini untuk menyingkirkan my_pathvar sementara ? Saya tidak bisa langsung mengganti / inside% ~ ...
  • Solusi apa pun yang menggunakan sintaks dinamis untuk menghindari panggilan pada setiap perubahan direktori dopromptmungkin lebih bersih.
Nicolas Dumazet
sumber
4

Solusi zsh murni:

PROMPT='%n@%m: %{$PR_BOLD_RED%}${${(%):-%~}//\//${PR_BOLD_RED}/%f}%f '
  • ${(%):-%~} adalah jalur saat ini.
  • ${xxxxx//\//${PR_BOLD_RED}/%f} mengganti setiap / di xxxxx oleh yang berwarna merah tebal
  • dan tentu saja PROMPT_SUBST harus aktif.

Saya telah menggunakan tanda kutip ganda dalam tes saya, yang tidak memungkinkan substitusi. Semuanya bekerja dengan baik dengan tanda kutip tunggal.

Nicolas Dumazet
sumber
Anda harus $PR_BOLD_REDmendefinisikan di tempat lain. Saya harus menggunakan PROMPT='%n@%m: %{%B%F{red}%}${${(%):-%~}//\//%B%F{red\}/%b%f}%b%f 'termasuk pelarian yang sangat aneh dari kurung kurawal penutupan (hanya) setelah yang kedua "merah".
Dijeda sampai pemberitahuan lebih lanjut.
ya, saya menggunakan penamaan Aaron Toponce pthree.org/wp-content/uploads/2009/03/zsh_prompt yang menurut saya berguna. Selain itu, saya tidak perlu melarikan diri dari apa pun, itu berfungsi sebagaimana disediakan.
Nicolas Dumazet
0

Ini usaha saya (berdasarkan NicDumZ's):

setopt PROMPT_SUBST
# red, green, yellow, blue, magenta, cyan, white, black
# B (bold), K(background color), F(foreground color)

function doprompt {
# this is just the directory (%d could be %~ -- I prefer full path always)
PROMPT='%F{yellow}${${(%):-%d}//\//%F{magenta\}%B/%b%F{yellow\}}%f'
}

function chpwd() {
    doprompt
}

Perbedaannya adalah bahwa saya menggunakan jalur berwarna, jadi saya harus kembali ke warna asli saya untuk jalur setelah garis miring berwarna. Dalam kasus saya, jalan biasanya berwarna kuning, dan garis miring diwarnai dengan magenta, kemudian kembali menjadi kuning. Saya juga lebih suka menggunakan urutan% F% f karena tampak jauh lebih mudah dibaca untuk saya.

bcelary
sumber