Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help: Prompt Segment Update #2814

Open
mayurankv opened this issue Jan 14, 2025 · 0 comments
Open

Help: Prompt Segment Update #2814

mayurankv opened this issue Jan 14, 2025 · 0 comments

Comments

@mayurankv
Copy link

mayurankv commented Jan 14, 2025

I'm trying to integrate Kanata (a keyboard remapping software) with poweerlevel10k via the prompt. I'd like it to indicate which layer Kanata is in at a given moment. I was able to get a prompt section working fine with the following code:

zmodload zsh/net/tcp

typeset -gA unicode_map=(
	qwerty 'QWE'
	colemak 'COL'
	dvorak 'DVO'
	layers $'\ueea8'
	numpad '123'
	symbols 'SYMB'
	delimiters '()'
)
default_value=$'\uf12a'

# function redraw_prompt() {
# 	local f
# 	for f in chpwd "${chpwd_functions[@]}" precmd "${precmd_functions[@]}"; do
# 		[[ "${+functions[$f]}" == 0 ]] || "$f" &>/dev/null || true
# 	done
# 	p10k display -r
# }

function prompt_my_kanata() {
ztcp 127.0.0.1 ${MYKANATAPORT-5829} &> /dev/null
if [[ -n "${REPLY:-}" ]]; then
	read -r line <&$REPLY
	if [[ "$line" =~ \{\"LayerChange\":\{\"new\":\"([^\"]+)\"\}\} ]]; then
		layer="${match[1]}"
		icon=${unicode_map[$layer]:-$default_value}
		p10k segment -c "$layer" -s "$layer" -i '' -f blue -t "$icon"
	fi
	exec {REPLY}<&-
fi
}

This works fine, but doesn't update (refers/redraw) the prompt when kanata changes a layer (via keybinding or TCP server or whatever). I've looked at issue #2048 but that appears to be related to zle widget behaviour a la #72. This made me think I need some sort of asynchronous update similar to #609.

My attempt is as follows:

#!/usr/bin/env zsh

zmodload zsh/net/tcp

typeset -gA unicode_map=(
	qwerty 'QWE'
	colemak 'COL'
	dvorak 'DVO'
	layers $'\ueea8'
	numpad '123'
	symbols 'SYMB'
	delimiters '()'
)
typeset -g MY_P10K_KANATA_LAYER=""


function check_kanata_layer() {
	ztcp 127.0.0.1 ${MYKANATAPORT-5829} &> /dev/null
	if [[ -n "${REPLY:-}" ]]; then
		read -r line <&$REPLY
		if [[ "$line" =~ \{\"LayerChange\":\{\"new\":\"([^\"]+)\"\}\} ]]; then
			MY_P10K_KANATA_LAYER="${match[1]}"
		fi
		exec {REPLY}<&-
	fi
}

function my_p10k_refresh() {
	zle reset-prompt
	zle -R
}

async_init
async_start_worker kanata_layer -n
async_register_callback kanata_layer my_p10k_refresh

function prompt_my_kanata() {
	local default_value=$'\uf12a'
	# (( $+commands[docker-compose] )) || return
	async_job kanata_layer check_kanata_layer
	local layer="$MY_P10K_KANATA_LAYER"
	local icon=${unicode_map[$MY_P10K_KANATA_LAYER]:-$default_value}
	p10k segment -e -c "$MY_P10K_KANATA_LAYER" -s "$MY_P10K_KANATA_LAYER" -i '' -f blue -t "$icon"
}

However, this script (sourced before p10k) doesn't work, it only shows up in the prompt when I manually run check_kanata_layer in the shell. It then doesn't update when new prompts are spawned even if the layer changes, and then needs check_kanata_layer to be run again to update.

One more concern I had is that the use case described in #609 seems to be for a function with large overhead being updated after the prompt is initially rendered, whereas, I want to almost have a constantly running listener that refreshes the prompt every time it receives a certain message - potentially multiple times between shell entry. Hence I'm not sure this is even the right approach.

It's been a while since I did any zsh scripting and I'm by no means proficient at it so I'd really appreciate any help with this!

EDIT: For reference, I have added my_kanata to the right prompt environment variable in my p10k config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant