Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

183 linhas
3.7KB

  1. #include <stdio.h>
  2. #include <readline/readline.h>
  3. #include <readline/history.h>
  4. #include "global.h"
  5. #include "build.h"
  6. #include <ncurses.h>
  7. static int input_available = 0;
  8. static int input_char;
  9. char input_line[PATLEN + 1];
  10. /* used for saving a line not [Enter]-ed yet,
  11. * so its not lost if the user scrolls the history
  12. */
  13. static struct PARTIAL_LINE {
  14. bool is_active;
  15. char* line;
  16. int pos;
  17. } partial_line = {
  18. .line = NULL,
  19. .is_active = true
  20. };
  21. static inline void previous_history_proxy(void);
  22. static inline void next_history_proxy(void);
  23. static inline int rebuild_reference(void);
  24. bool interpret(int c) {
  25. /* A switch is faster then binding Readline to a billion functions
  26. * and since KEY_* values can't be bound anyways (values too large
  27. * (because while the first argument of rl_bind_key() is an int,
  28. * only unsigned chars are valid)), handling everything here
  29. * creates consistency too.
  30. */
  31. switch(c){
  32. case KEY_BACKSPACE:
  33. rl_rubout(1, 0);
  34. break;
  35. case KEY_UP:
  36. previous_history_proxy();
  37. break;
  38. case KEY_DOWN:
  39. next_history_proxy();
  40. break;
  41. case ctrl('R'):
  42. rebuild_reference();
  43. break;
  44. case ESC:
  45. case ctrl('X'):
  46. process_mouse();
  47. break;
  48. default:
  49. input_char = c;
  50. input_available = 1;
  51. rl_callback_read_char();
  52. return 0;
  53. }
  54. //XXX:
  55. // rl_bind_key(ctrl('\\'), /**/); /* bypass bindings */
  56. window_change |= CH_INPUT;
  57. return 0;
  58. }
  59. static int getc_function(FILE *ignore) {
  60. UNUSED(ignore);
  61. input_available = 0;
  62. return input_char;
  63. }
  64. static int input_available_hook() {
  65. return input_available;
  66. }
  67. static void redisplay_function() {
  68. window_change |= CH_INPUT;
  69. }
  70. static void callback_handler(char *line) {
  71. if(!line) { return; }
  72. add_history(line);
  73. switch(input_mode) {
  74. case INPUT_NORMAL:
  75. strncpy(input_line, line, PATLEN);
  76. search(input_line);
  77. horswp_field();
  78. curdispline = 0;
  79. current_page = 0;
  80. PCS_reset();
  81. break;
  82. case INPUT_CHANGE_TO:
  83. strncpy(newpat, line, PATLEN);
  84. change = calloc(totallines, sizeof(*change));
  85. input_mode = INPUT_CHANGE;
  86. horswp_field();
  87. return;
  88. }
  89. switch(field) {
  90. case CHANGE:
  91. input_mode = INPUT_CHANGE_TO;
  92. break;
  93. case DEFINITION:
  94. case FILENAME:
  95. if(totallines == 1) { editref(0); }
  96. break;
  97. }
  98. }
  99. static inline int rebuild_reference() {
  100. if(isuptodate == true) {
  101. postmsg("The -d option prevents rebuilding the symbol database");
  102. return (false);
  103. }
  104. exitcurses();
  105. freefilelist(); /* remake the source file list */
  106. makefilelist();
  107. rebuild();
  108. if(errorsfound == true) {
  109. errorsfound = false;
  110. askforreturn();
  111. }
  112. entercurses();
  113. postmsg(""); /* clear any previous message */
  114. totallines = 0;
  115. disprefs = 0;
  116. return (true);
  117. }
  118. static inline void previous_history_proxy(){
  119. HIST_ENTRY* i = previous_history();
  120. if(i){
  121. if(partial_line.is_active){
  122. free(partial_line.line);
  123. partial_line = (struct PARTIAL_LINE){
  124. .line = rl_line_buffer,
  125. .pos = rl_point,
  126. .is_active = false
  127. };
  128. }else{
  129. free(rl_line_buffer);
  130. }
  131. //
  132. rl_line_buffer = strdup(i->line);
  133. rl_point = strlen(rl_line_buffer);
  134. }
  135. }
  136. static inline void next_history_proxy(){
  137. HIST_ENTRY* i = next_history();
  138. if(i){
  139. free(rl_line_buffer);
  140. rl_line_buffer = strdup(i->line);
  141. rl_point = strlen(rl_line_buffer);
  142. }else if(!partial_line.is_active){
  143. rl_line_buffer = strdup(partial_line.line);
  144. rl_point = partial_line.pos;
  145. partial_line.is_active = true;
  146. }
  147. }
  148. void rlinit() {
  149. rl_readline_name = PROGRAM_NAME;
  150. using_history();
  151. rl_catch_signals = 0;
  152. rl_catch_sigwinch = 0;
  153. rl_prep_term_function = NULL;
  154. rl_deprep_term_function = NULL;
  155. rl_change_environment = 0;
  156. rl_getc_function = getc_function;
  157. rl_input_available_hook = input_available_hook;
  158. rl_redisplay_function = redisplay_function;
  159. rl_callback_handler_install("", callback_handler);
  160. }