Change the values โ€‹โ€‹of $ READLINE_LINE and $ READLINE_POINT inside a bash script

When I answered this question , I used a very dirty bind function to change the current line according to the result of my automplete.sh script.

Since I used this script for personal use, I tried to simplify bind and will try to do all the reading and modification directly inside the script.

So far, I can access $READLINE_LINE and $READLINE_POINT and extract the data I need, but I cannot replace the current value. Quoting the bind mand page, this should work though:

When the shell is executed, the shell sets the READLINE_LINE variable to the contents of the readline string buffer and the READLINE_POINT variable to the current location of the insertion point. If the executed command changes the value of READLINE_LINE or READLINE_POINT, these new values โ€‹โ€‹will be displayed in the editing state.

I associated my session with bind -x '"\t":autocomplete.sh' and did something like this:

 #!/bin/bash #autocomplete.sh BASE="${READLINE_LINE% *} " LAST_CMD="${READLINE_LINE##* }" EXPANSION=($(magical_autocomplete $LAST_CMD)) #we store the desired value for the line in ${EXPANSION[0]} [[ ${#EXPANSION[@]} -gt 1 ]] && echo ${EXPANSION[@]:1} #we echo the match if there are more than 1 #Doesn't work, even with simple values like READLINE_LINE="test" or READLINE_POINT=0 READLINE_LINE=${EXPANSION[0]} READLINE_POINT=${#READLINE_LINE} #echo READLINE_LINE READLINE_POINT echoes the correct value here 

After the script is executed, the correct matches are displayed, but the current line feed is not updated. Since I am repeating some data, I cannot just redirect the output of my script to the bind part. Why can I read from variables but not write to it?

+4
source share
1 answer

For the same reason why this does not work:

 $ export a=1 $ bash -c 'echo $a; let a++' 1 $ echo $a 1 

Environment variables are inheritable, not shared. Since autocomplete.sh runs as a new child process, it can read all the parent variables, but cannot return new values.

To change READLINE_LINE and READLINE_POINT , you must run your autostart in the same process - source , and the functions will help you.

 # autocomplete.sh # should be sourced from ~/.bashrc or something autocomplete() { echo $READLINE_LINE $READLINE_POINT EXPANSION=($(magical_autocomplete $READLINE_LINE)) #we store the desired value for the line in ${EXPANSION[0]} [[ ${#EXPANSION[@]} -gt 1 ]] && echo ${EXPANSION[@]:1} READLINE_LINE=${EXPANSION[0]} READLINE_POINT=${#READLINE_LINE} } 

Binding:

 if [[ -s "$HOME/.bashrc.d/autocomplete.sh" ]]; then source "$HOME/.bashrc.d/autocomplete.sh" bind -x '"\t" : autocomplete' fi 
+6
source

Source: https://habr.com/ru/post/973218/


All Articles