@@ -597,14 +597,32 @@ _cs_redraw() {
597597 colored=" $_CS_BUFFER "
598598 fi
599599
600- local _term_cols; _term_cols=$( tput cols 2> /dev/null || printf ' 80' )
601- local _prev_len=$(( _CS_PS1 _LEN + ${# _CS_BUFFER} ))
600+ # local _term_cols; _term_cols=$(tput cols 2>/dev/null || printf '80')
601+ # local _prev_len=$(( _CS_PS1_LEN + ${#_CS_BUFFER} ))
602+ # local _prev_lines=$(( _prev_len / _term_cols ))
603+
604+ local _term_cols=$(( COLUMNS > 0 ? COLUMNS : 80 ))
605+ local _buf_visual=" ${_CS_BUFFER// \\ / } "
606+ local _char_count
607+ _char_count=$( printf ' %s' " $_buf_visual " | wc -m 2> /dev/null || printf ' %s' " ${# _buf_visual} " )
608+ local _prev_len=$(( _CS_PS1 _LEN + _char_count ))
602609 local _prev_lines=$(( _prev_len / _term_cols ))
610+ if (( _prev_lines > 0 )) ; then
611+ printf ' \e[%dA' " $_prev_lines " >&2
612+ fi
613+ printf ' \r\e[2K%s%s\e[K' " $_CS_PS1_LAST " " $colored " >&2
614+ printf ' \r\e[%dG' " $(( ( _CS_PS1 _LEN + _CS_POS ) % _term_cols + 1 )) " >&2
603615
616+ local _prev_lines=$(( _prev_len / _term_cols ))
617+ printf ' DEBUG redraw buf_len=%s pos=%s visual_len=%s\n' \
618+ " ${# _CS_BUFFER} " " $_CS_POS " " $_char_count " >> " ${TMPDIR} /cs_debug.log"
604619 if (( _prev_lines > 0 )) ; then
605620 printf ' \e[%dA' " $_prev_lines " >&2
606621 fi
607622
623+ printf ' DEBUG term_cols=%s buf_visual="%s" char_count=%s wide_count=%s prev_len=%s prev_lines=%s\n' \
624+ " $_term_cols " " ${_buf_visual: 0: 30} " " $_char_count " " $_wide_count " " $_prev_len " " $_prev_lines " >> " ${TMPDIR} /cs_debug.log"
625+
608626 if [[ -n " $TERMUX_VERSION " ]]; then
609627 local _ghost_inline=" "
610628 local _ghost_len=0
@@ -624,6 +642,7 @@ _cs_redraw() {
624642 fi
625643 fi
626644 fi
645+ printf ' DEBUG buf_len=%s colored_len=%s\n' " ${# _CS_BUFFER} " " ${# colored} " >> " ${TMPDIR} /cs_debug.log"
627646 printf ' \r\e[J%s%s%s' " $_CS_PS1_LAST " " $colored " " $_ghost_inline " >&2
628647 local _cursor_target=$(( ( _CS_PS1 _LEN + _CS_POS ) % _term_cols + 1 ))
629648 local _total_drawn=$(( _CS_PS1 _LEN + ${# _CS_BUFFER} + _ghost_len ))
@@ -696,77 +715,34 @@ _cs_do_shift_tab() {
696715 _cs_redraw
697716}
698717
699- _cs_quote_completion () {
700- local completion=" $1 "
701- if [[ " $completion " == * ' ' * ]]; then
702- completion=" ${completion/# \~ / $HOME } "
703- completion=" ${completion// \" / } "
704- # Trailing slash será preservada dentro das aspas
705- completion=" \" ${completion} \" "
706- fi
707- printf ' %s' " $completion "
708- }
718+ # _cs_quote_completion() {
719+ # local completion="$1"
720+ # if [[ "$completion" == *' '* ]]; then
721+ # completion="${completion/#\~/$HOME}"
722+ # completion="${completion//\"/}"
723+ # # Trailing slash será preservada dentro das aspas
724+ # completion="\"${completion}\""
725+ # fi
726+ # printf '%s' "$completion"
727+ # }
709728
710- f_cs_quote_completion () {
729+ _cs_quote_completion () {
711730 local completion=" $1 "
712731 local trailing_slash=" "
713732 [[ " $completion " == * / ]] && trailing_slash=" /" && completion=" ${completion%/ } "
714733
715- # Escapa sempre com \ se contém espaço ou qualquer caractere não-seguro
716- # Inclui caracteres unicode problemáticos via verificação de espaço e ASCII especial
717- local needs_escape=0
718- [[ " $completion " == * ' ' * ]] && needs_escape=1
719- [[ " $completion " == * " '" * ]] && needs_escape=1
720- [[ " $completion " == * ' "' * ]] && needs_escape=1
721- [[ " $completion " == * ' (' * ]] && needs_escape=1
722- [[ " $completion " == * ' )' * ]] && needs_escape=1
723- [[ " $completion " == * ' [' * ]] && needs_escape=1
724- [[ " $completion " == * ' ]' * ]] && needs_escape=1
725- [[ " $completion " == * ' {' * ]] && needs_escape=1
726- [[ " $completion " == * ' }' * ]] && needs_escape=1
727- [[ " $completion " == * ' &' * ]] && needs_escape=1
728- [[ " $completion " == * ' ;' * ]] && needs_escape=1
729- [[ " $completion " == * ' !' * ]] && needs_escape=1
730- [[ " $completion " == * ' #' * ]] && needs_escape=1
731- [[ " $completion " == * ' $' * ]] && needs_escape=1
732- [[ " $completion " == * ' `' * ]] && needs_escape=1
733- [[ " $completion " == * ' |' * ]] && needs_escape=1
734- [[ " $completion " == * ' <' * ]] && needs_escape=1
735- [[ " $completion " == * ' >' * ]] && needs_escape=1
736- [[ " $completion " == * ' ,' * ]] && needs_escape=1
737- [[ " $completion " == * ' ~' * ]] && needs_escape=1
738- [[ " $completion " == * ' *' * ]] && needs_escape=1
739- [[ " $completion " == * ' ?' * ]] && needs_escape=1
740- [[ " $completion " == * ' \' * ]] && needs_escape=1
741-
742- if (( needs_escape )) ; then
743- # Escapa \ primeiro para não duplo-escapar
744- completion=" ${completion// \\ / \\\\ } "
745- completion=" ${completion// / \\ } "
746- completion=" ${completion// \' / \\\' } "
747- completion=" ${completion// \" / \\\" } "
748- completion=" ${completion// (/ \\ (} "
749- completion=" ${completion// )/ \\ )} "
750- completion=" ${completion// [/ \\ [} "
751- completion=" ${completion// ]/ \\ ]} "
752- completion=" ${completion// \{ / \\\{ } "
753- completion=" ${completion// \} / \\\} } "
754- completion=" ${completion// &/ \\ &} "
755- completion=" ${completion// ;/ \\ ;} "
756- completion=" ${completion//!/ \\ ! } "
757- completion=" ${completion//#/ \\ # } "
758- completion=" ${completion// \$ / \\\$ } "
759- completion=" ${completion// \` / \\\` } "
760- completion=" ${completion// |/ \\ |} "
761- completion=" ${completion// </ \\ <} "
762- completion=" ${completion// >/ \\ >} "
763- completion=" ${completion// ,/ \\ ,} "
764- completion=" ${completion// ~/ \\ ~} "
765- completion=" ${completion// \* / \\ * } "
766- completion=" ${completion// \? / \\ ?} "
767- fi
734+ local result=" " i c
735+ local safe_chars=' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-+@=%^:~//'
736+ for (( i= 0 ; i< ${# completion} ; i++ )) ; do
737+ c=" ${completion: $i : 1} "
738+ if [[ " $safe_chars " == * " $c " * ]]; then
739+ result+=" $c "
740+ else
741+ result+=" \\ ${c} "
742+ fi
743+ done
768744
769- printf ' %s' " ${completion }${trailing_slash} "
745+ printf ' %s' " ${result }${trailing_slash} "
770746}
771747
772748_cs_do_tab () {
@@ -820,7 +796,6 @@ _cs_do_tab() {
820796 fi
821797 (( word_start-- ))
822798 done
823- printf ' DEBUG word_start=%s cur="%s"\n' " $word_start " " ${line: $word_start : $((point - word_start))} " >> " ${TMPDIR} /cs_debug.log"
824799
825800 local cur=" ${line: $word_start : $((point - word_start))} "
826801 # Normaliza cur: remove aspas externas e backslashes de escape
@@ -867,6 +842,12 @@ _cs_do_tab() {
867842 _glob_matches+=(" $_f " )
868843 done
869844 eval " $_shopt_save "
845+ printf ' DEBUG glob_matches="%s"\n' " ${_glob_matches[*]} " >> " ${TMPDIR} /cs_debug.log"
846+ printf ' DEBUG glob_n="%s"\n' " ${# _glob_matches[@]} " >> " ${TMPDIR} /cs_debug.log"
847+ if (( ${# _glob_matches[@]} == 1 )) ; then
848+ printf ' DEBUG single_match="%s"\n' " ${_glob_matches[0]} " >> " ${TMPDIR} /cs_debug.log"
849+ printf ' DEBUG after_quote="%s"\n' " $( _cs_quote_completion " ${_glob_matches[0]} " ) " >> " ${TMPDIR} /cs_debug.log"
850+ fi
870851 if (( ${# _glob_matches[@]} == 0 )) ; then
871852 printf ' \a' >&2 ; _cs_redraw; return
872853 fi
@@ -881,7 +862,12 @@ _cs_do_tab() {
881862 local _suffix=" "
882863 [[ -d " ${_clean/# \~ / $HOME } " && " $_clean " != * / ]] && _suffix=" /"
883864 _CS_BUFFER=" ${line: 0: $word_start }${_completion}${_suffix}${after} "
884- _CS_POS=$(( word_start + ${# _completion} + ${# _suffix} ))
865+ local _completion_visual=" ${_completion// \\ / } "
866+ local _completion_visual_len
867+ _completion_visual_len=$( printf ' %s' " $_completion_visual " | wc -m 2> /dev/null || printf ' %s' " ${# _completion_visual} " )
868+ _CS_POS=$(( word_start + _completion_visual_len + ${# _suffix} ))
869+ printf ' DEBUG final_buf="%s" final_pos=%s buf_len=%s\n' \
870+ " ${_CS_BUFFER: 0: 50} " " $_CS_POS " " ${# _CS_BUFFER} " >> " ${TMPDIR} /cs_debug.log"
885871 _cs_tab_reset; _cs_redraw; return
886872 fi
887873 mapfile -t completions < <( printf ' %s\n' " ${_glob_matches[@]} " | sort -u)
@@ -987,7 +973,10 @@ _cs_do_tab() {
987973 local _suffix=" "
988974 [[ -d " ${_clean/# \~ / $HOME } " && " $_clean " != * / ]] && _suffix=" /"
989975 _CS_BUFFER=" ${line: 0: $word_start }${_completion}${_suffix}${after} "
990- _CS_POS=$(( word_start + ${# _completion} + ${# _suffix} ))
976+ local _completion_visual=" ${_completion// \\ / } "
977+ local _completion_visual_len
978+ _completion_visual_len=$( printf ' %s' " $_completion_visual " | wc -m 2> /dev/null || printf ' %s' " ${# _completion_visual} " )
979+ _CS_POS=$(( word_start + _completion_visual_len + ${# _suffix} ))
991980 _cs_tab_reset; _cs_redraw; return
992981 else
993982 mapfile -t completions < <( printf ' %s\n' " ${_glob_matches[@]} " | sort -u)
@@ -1090,11 +1079,12 @@ _cs_do_tab() {
10901079 # _CS_POS=$(( word_start + ${#completion} + ${#suffix} ))
10911080 # _cs_tab_reset; _cs_redraw; return
10921081 # fi
1082+
1083+ printf ' DEBUG completion_raw="%s"\n' " ${completions[0]} " >> " ${TMPDIR} /cs_debug.log"
1084+ printf ' DEBUG completion_after_quote="%s"\n' " $( _cs_quote_completion " ${completions[0]} " ) " >> " ${TMPDIR} /cs_debug.log"
10931085
1094- printf ' DEBUG before_n1 n=%s completions="%s"\n' " $n " " ${completions[*]} " >> " ${TMPDIR} /cs_debug.log"
10951086 if (( n == 1 )) ; then
10961087 local completion=" ${completions[0]} "
1097- printf ' DEBUG n1 completion="%s" cur="%s" word_start=%s\n' " $completion " " $cur " " $word_start " >> " ${TMPDIR} /cs_debug.log"
10981088 if [[ " ${cur} " == ~ * || " ${line: 0: $word_start } " == * ~* ]]; then
10991089 completion=" ${completion/# $HOME / \~ } "
11001090 fi
@@ -1163,7 +1153,10 @@ _cs_do_tab() {
11631153 local _suffix=" "
11641154 [[ -d " ${_clean/# \~ / $HOME } " && " $_clean " != * / ]] && _suffix=" /"
11651155 _CS_BUFFER=" ${line: 0: $word_start }${_completion}${_suffix}${after} "
1166- _CS_POS=$(( word_start + ${# _completion} + ${# _suffix} ))
1156+ local _completion_visual=" ${_completion// \\ / } "
1157+ local _completion_visual_len
1158+ _completion_visual_len=$( printf ' %s' " $_completion_visual " | wc -m 2> /dev/null || printf ' %s' " ${# _completion_visual} " )
1159+ _CS_POS=$(( word_start + _completion_visual_len + ${# _suffix} ))
11671160 _cs_tab_reset; _cs_redraw; return
11681161 else
11691162 mapfile -t completions < <( printf ' %s\n' " ${_glob_matches[@]} " | sort -u)
@@ -1250,12 +1243,6 @@ _cs_do_tab() {
12501243 _CS_POS=$(( _CS_TAB_WORD_START + ${# _first_c} ))
12511244 _cs_redraw; return
12521245 fi
1253- printf ' DEBUG cur_clean="%s" cur_expanded="%s"\n' " $cur_clean " " $cur_expanded " >> " ${TMPDIR} /cs_debug.log"
1254- printf ' DEBUG glob_pattern="%s"\n' " ${cur_expanded} *" >> " ${TMPDIR} /cs_debug.log"
1255- for _f in " ${cur_expanded} " * ; do
1256- printf ' DEBUG glob_match="%s"\n' " $_f " >> " ${TMPDIR} /cs_debug.log"
1257- done
1258- printf ' DEBUG completions="%s" n=%s\n' " ${completions[*]} " " ${# completions[@]} " >> " ${TMPDIR} /cs_debug.log"
12591246
12601247 _CS_TAB_COMPLETIONS= (" ${completions[@]} " )
12611248 _CS_TAB_STATE= -1
0 commit comments