history.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /******************************************************************************
  2. * This file is part of TinTin++ *
  3. * *
  4. * Copyright 2004-2019 Igor van den Hoven *
  5. * *
  6. * TinTin++ is free software; you can redistribute it and/or modify *
  7. * it under the terms of the GNU General Public License as published by *
  8. * the Free Software Foundation; either version 3 of the License, or *
  9. * (at your option) any later version. *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * *
  17. * You should have received a copy of the GNU General Public License *
  18. * along with TinTin++. If not, see https://www.gnu.org/licenses. *
  19. ******************************************************************************/
  20. /******************************************************************************
  21. * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t *
  22. * *
  23. * coded by Igor van den Hoven 2006 *
  24. ******************************************************************************/
  25. #include "tintin.h"
  26. DO_COMMAND(do_history)
  27. {
  28. char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE];
  29. int cnt;
  30. arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
  31. arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN);
  32. if (*arg1 == 0)
  33. {
  34. tintin_header(ses, " HISTORY COMMANDS ");
  35. for (cnt = 0 ; *history_table[cnt].name != 0 ; cnt++)
  36. {
  37. tintin_printf2(ses, " [%-13s] %s", history_table[cnt].name, history_table[cnt].desc);
  38. }
  39. tintin_header(ses, "");
  40. return ses;
  41. }
  42. for (cnt = 0 ; *history_table[cnt].name ; cnt++)
  43. {
  44. if (!is_abbrev(arg1, history_table[cnt].name))
  45. {
  46. continue;
  47. }
  48. history_table[cnt].fun(ses, arg2);
  49. return ses;
  50. }
  51. do_history(ses, "");
  52. return ses;
  53. }
  54. void add_line_history(struct session *ses, char *line)
  55. {
  56. struct listroot *root;
  57. root = ses->list[LIST_HISTORY];
  58. if (HAS_BIT(root->flags, LIST_FLAG_IGNORE))
  59. {
  60. return;
  61. }
  62. if (*line == 0)
  63. {
  64. if (root->used && HAS_BIT(ses->flags, SES_FLAG_REPEATENTER))
  65. {
  66. strcpy(line, root->list[root->used - 1]->arg1);
  67. }
  68. return;
  69. }
  70. if (*line == gtd->repeat_char)
  71. {
  72. search_line_history(ses, line);
  73. }
  74. update_node_list(ses->list[LIST_HISTORY], line, "", "", "");
  75. while (root->used > gtd->history_size)
  76. {
  77. delete_index_list(ses->list[LIST_HISTORY], 0);
  78. }
  79. return;
  80. }
  81. void search_line_history(struct session *ses, char *line)
  82. {
  83. struct listroot *root;
  84. int i;
  85. root = ses->list[LIST_HISTORY];
  86. for (i = root->used - 1 ; i >= 0 ; i--)
  87. {
  88. if (!strncmp(root->list[i]->arg1, &line[1], strlen(&line[1])))
  89. {
  90. strcpy(line, root->list[i]->arg1);
  91. return;
  92. }
  93. }
  94. tintin_printf2(ses, "#REPEAT: NO MATCH FOUND FOR '%s'", line);
  95. }
  96. DO_HISTORY(history_character)
  97. {
  98. gtd->repeat_char = *arg;
  99. show_message(ses, LIST_HISTORY, "#HISTORY CHARACTER SET TO {%c}.", gtd->repeat_char);
  100. }
  101. DO_HISTORY(history_delete)
  102. {
  103. if (ses->list[LIST_HISTORY]->used)
  104. {
  105. delete_index_list(ses->list[LIST_HISTORY], ses->list[LIST_HISTORY]->used - 1);
  106. }
  107. return;
  108. }
  109. DO_HISTORY(history_insert)
  110. {
  111. add_line_history(ses, arg);
  112. }
  113. DO_HISTORY(history_list)
  114. {
  115. struct listroot *root;
  116. int i, cnt = 1;
  117. root = ses->list[LIST_HISTORY];
  118. for (i = 0 ; i < root->used ; i++)
  119. {
  120. tintin_printf2(ses, "%6d - %s", cnt++, root->list[i]->arg1);
  121. }
  122. return;
  123. }
  124. DO_HISTORY(history_read)
  125. {
  126. FILE *file;
  127. char *cptr, buffer[BUFFER_SIZE];
  128. file = fopen(arg, "r");
  129. if (file == NULL)
  130. {
  131. show_message(ses, LIST_HISTORY, "#HISTORY: COULDN'T OPEN FILE {%s} TO READ.", arg);
  132. return;
  133. }
  134. kill_list(ses->list[LIST_HISTORY]);
  135. while (fgets(buffer, BUFFER_SIZE-1, file))
  136. {
  137. cptr = strchr(buffer, '\n');
  138. if (cptr)
  139. {
  140. *cptr = 0;
  141. if (*buffer)
  142. {
  143. insert_node_list(ses->list[LIST_HISTORY], buffer, "", "", "");
  144. }
  145. }
  146. }
  147. insert_node_list(ses->list[LIST_HISTORY], "", "", "", "");
  148. fclose(file);
  149. if (ses->list[LIST_HISTORY]->used > gtd->history_size)
  150. {
  151. char buf[BUFFER_SIZE];
  152. sprintf(buf, "{HISTORY SIZE} {%d}", UMIN(ses->list[LIST_HISTORY]->used, 9999));
  153. do_configure(gts, buf);
  154. }
  155. return;
  156. }
  157. DO_HISTORY(history_size)
  158. {
  159. if (atoi(arg) < 1 || atoi(arg) > 100000)
  160. {
  161. tintin_printf(ses, "#HISTORY SIZE: PROVIDE A NUMBER BETWEEN 1 and 100,000");
  162. }
  163. else
  164. {
  165. gtd->history_size = atoi(arg);
  166. }
  167. return;
  168. }
  169. DO_HISTORY(history_write)
  170. {
  171. struct listroot *root = ses->list[LIST_HISTORY];
  172. FILE *file;
  173. int i;
  174. file = fopen(arg, "w");
  175. if (file == NULL)
  176. {
  177. tintin_printf2(ses, "#HISTORY: COULDN'T OPEN FILE {%s} TO WRITE.", arg);
  178. return;
  179. }
  180. for (i = 0 ; i < root->used ; i++)
  181. {
  182. fprintf(file, "%s\n", root->list[i]->arg1);
  183. }
  184. fclose(file);
  185. return;
  186. }