n-list-input 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. # Copy this file into /usr/share/zsh/site-functions/
  2. # and add 'autoload n-list-input` to .zshrc
  3. #
  4. # This is an internal function not for direct use
  5. emulate -L zsh
  6. zmodload zsh/curses
  7. setopt typesetsilent
  8. # Compute first to show index
  9. _nlist_compute_first_to_show_idx() {
  10. from_what_idx_list_is_shown=0+((current_idx-1)/page_height)*page_height+1
  11. }
  12. typeset -ga reply
  13. reply=( -1 '' )
  14. integer current_idx="$1"
  15. integer from_what_idx_list_is_shown="$2"
  16. integer page_height="$3"
  17. integer page_width="$4"
  18. integer last_element="$5"
  19. integer hscroll="$6"
  20. local key="$7"
  21. integer search="$8"
  22. local buffer="$9"
  23. integer uniq_mode="$10"
  24. #
  25. # Listening for input
  26. #
  27. if [ "$search" = "0" ]; then
  28. case "$key" in
  29. (UP|k|$'\C-P')
  30. # Are there any elements before the current one?
  31. [ "$current_idx" -gt 1 ] && current_idx=current_idx-1;
  32. _nlist_compute_first_to_show_idx
  33. ;;
  34. (DOWN|j|$'\C-N')
  35. # Are there any elements after the current one?
  36. [ "$current_idx" -lt "$last_element" ] && current_idx=current_idx+1;
  37. _nlist_compute_first_to_show_idx
  38. ;;
  39. (PPAGE|$'\b'|$'\C-?'|BACKSPACE)
  40. current_idx=current_idx-page_height
  41. [ "$current_idx" -lt 1 ] && current_idx=1;
  42. _nlist_compute_first_to_show_idx
  43. ;;
  44. (NPAGE|" ")
  45. current_idx=current_idx+page_height
  46. [ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
  47. _nlist_compute_first_to_show_idx
  48. ;;
  49. ($'\C-U')
  50. current_idx=current_idx-page_height/2
  51. [ "$current_idx" -lt 1 ] && current_idx=1;
  52. _nlist_compute_first_to_show_idx
  53. ;;
  54. ($'\C-D')
  55. current_idx=current_idx+page_height/2
  56. [ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
  57. _nlist_compute_first_to_show_idx
  58. ;;
  59. (HOME|g)
  60. current_idx=1
  61. _nlist_compute_first_to_show_idx
  62. ;;
  63. (END|G)
  64. current_idx=last_element
  65. _nlist_compute_first_to_show_idx
  66. ;;
  67. ($'\n'|ENTER)
  68. # Is that element selectable?
  69. # Check for this only when there is no search
  70. if [[ "$NLIST_SEARCH_BUFFER" != "" || "$NLIST_IS_UNIQ_MODE" -eq 1 ||
  71. ${NLIST_NONSELECTABLE_ELEMENTS[(r)$current_idx]} != $current_idx ]]
  72. then
  73. # Save current element in the result variable
  74. reply=( $current_idx SELECT )
  75. fi
  76. ;;
  77. (q)
  78. reply=( -1 QUIT )
  79. ;;
  80. (/)
  81. search=1
  82. _nlist_cursor_visibility 1
  83. ;;
  84. ($'\t')
  85. reply=( $current_idx LEAVE )
  86. ;;
  87. ($'\C-L')
  88. reply=( -1 REDRAW )
  89. ;;
  90. (\])
  91. [[ "${(t)NLIST_HOP_INDEXES}" = "array" || "${(t)NLIST_HOP_INDEXES}" = "array-local" ]] &&
  92. [ -z "$NLIST_SEARCH_BUFFER" ] && [ "$NLIST_IS_UNIQ_MODE" -eq 0 ] &&
  93. for idx in "${(n)NLIST_HOP_INDEXES[@]}"; do
  94. if [ "$idx" -gt "$current_idx" ]; then
  95. current_idx=$idx
  96. _nlist_compute_first_to_show_idx
  97. break
  98. fi
  99. done
  100. ;;
  101. (\[)
  102. [[ "${(t)NLIST_HOP_INDEXES}" = "array" || "${(t)NLIST_HOP_INDEXES}" = "array-local" ]] &&
  103. [ -z "$NLIST_SEARCH_BUFFER" ] && [ "$NLIST_IS_UNIQ_MODE" -eq 0 ] &&
  104. for idx in "${(nO)NLIST_HOP_INDEXES[@]}"; do
  105. if [ "$idx" -lt "$current_idx" ]; then
  106. current_idx=$idx
  107. _nlist_compute_first_to_show_idx
  108. break
  109. fi
  110. done
  111. ;;
  112. ('<'|'{'|LEFT|'h')
  113. hscroll=hscroll-7
  114. [ "$hscroll" -lt 0 ] && hscroll=0
  115. ;;
  116. ('>'|'}'|RIGHT|'l')
  117. hscroll+=7
  118. ;;
  119. ($'\E')
  120. buffer=""
  121. ;;
  122. (o|$'\C-O')
  123. uniq_mode=1-uniq_mode
  124. ;;
  125. (*)
  126. ;;
  127. esac
  128. else
  129. case "$key" in
  130. ($'\n'|ENTER)
  131. search=0
  132. _nlist_cursor_visibility 0
  133. ;;
  134. ($'\C-L')
  135. reply=( -1 REDRAW )
  136. ;;
  137. #
  138. # Slightly limited navigation
  139. #
  140. (UP|$'\C-P')
  141. [ "$current_idx" -gt 1 ] && current_idx=current_idx-1;
  142. _nlist_compute_first_to_show_idx
  143. ;;
  144. (DOWN|$'\C-N')
  145. [ "$current_idx" -lt "$last_element" ] && current_idx=current_idx+1;
  146. _nlist_compute_first_to_show_idx
  147. ;;
  148. (PPAGE)
  149. current_idx=current_idx-page_height
  150. [ "$current_idx" -lt 1 ] && current_idx=1;
  151. _nlist_compute_first_to_show_idx
  152. ;;
  153. (NPAGE)
  154. current_idx=current_idx+page_height
  155. [ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
  156. _nlist_compute_first_to_show_idx
  157. ;;
  158. ($'\C-U')
  159. current_idx=current_idx-page_height/2
  160. [ "$current_idx" -lt 1 ] && current_idx=1;
  161. _nlist_compute_first_to_show_idx
  162. ;;
  163. ($'\C-D')
  164. current_idx=current_idx+page_height/2
  165. [ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
  166. _nlist_compute_first_to_show_idx
  167. ;;
  168. (HOME)
  169. current_idx=1
  170. _nlist_compute_first_to_show_idx
  171. ;;
  172. (END)
  173. current_idx=last_element
  174. _nlist_compute_first_to_show_idx
  175. ;;
  176. (LEFT)
  177. hscroll=hscroll-7
  178. [ "$hscroll" -lt 0 ] && hscroll=0
  179. ;;
  180. (RIGHT)
  181. hscroll+=7
  182. ;;
  183. (F1|F2|F3|F4|F5|F6|F7|F8|F9|F10)
  184. # ignore
  185. ;;
  186. #
  187. # The input
  188. #
  189. ($'\b'|$'\C-?'|BACKSPACE)
  190. buffer="${buffer%?}"
  191. ;;
  192. ($'\C-W')
  193. [ "$buffer" = "${buffer% *}" ] && buffer="" || buffer="${buffer% *}"
  194. ;;
  195. ($'\C-K')
  196. buffer=""
  197. ;;
  198. ($'\E')
  199. buffer=""
  200. search=0
  201. _nlist_cursor_visibility 0
  202. ;;
  203. ($'\C-O')
  204. uniq_mode=1-uniq_mode
  205. ;;
  206. (*)
  207. if [[ $#key == 1 && $((#key)) -lt 31 ]]; then
  208. # ignore all other control keys
  209. else
  210. buffer+="$key"
  211. fi
  212. ;;
  213. esac
  214. fi
  215. reply[3]="$current_idx"
  216. reply[4]="$from_what_idx_list_is_shown"
  217. reply[5]="$hscroll"
  218. reply[6]="$search"
  219. reply[7]="$buffer"
  220. reply[8]="$uniq_mode"
  221. # vim: set filetype=zsh: