1 #include "autopick/autopick-inserter-killer.h"
2 #include "autopick/autopick-dirty-flags.h"
3 #include "autopick/autopick-util.h"
4 #include "cmd-io/macro-util.h"
5 #include "game-option/input-options.h"
6 #include "game-option/keymap-directory-getter.h"
7 #include "io/input-key-acceptor.h"
8 #include "io/input-key-requester.h"
9 #include "main/sound-of-music.h"
10 #include "term/screen-processor.h"
11 #include "util/string-processor.h"
14 * @brief Check if this line is expression or not. And update it if it is.
16 void check_expression_line(text_body_type *tb, int y)
18 concptr s = tb->lines_list[y];
20 if ((s[0] == '?' && s[1] == ':') || (tb->states[y] & LSTAT_BYPASS)) {
21 tb->dirty_flags |= DIRTY_EXPRESSION;
26 * @brief 行を追加可能かチェックする
27 * @param tb text_body_type
28 * @param add_num 追加する行数
30 * @retval false 最大行数を超えるため追加不可
32 bool can_insert_line(text_body_type *tb, int add_num)
34 const int count = count_line(tb);
35 return !is_greater_autopick_max_line(count + add_num);
39 * @brief Insert return code and split the line
41 bool insert_return_code(text_body_type *tb)
43 char buf[MAX_LINELEN];
46 num_lines = count_line(tb);
47 if (is_greater_autopick_max_line(num_lines)) {
53 for (; tb->cy < num_lines; num_lines--) {
54 tb->lines_list[num_lines + 1] = tb->lines_list[num_lines];
55 tb->states[num_lines + 1] = tb->states[num_lines];
58 for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++) {
60 if (iskanji(tb->lines_list[tb->cy][i])) {
61 buf[j++] = tb->lines_list[tb->cy][i++];
64 buf[j++] = tb->lines_list[tb->cy][i];
68 tb->lines_list[tb->cy + 1] = string_make(&tb->lines_list[tb->cy][i]);
69 string_free(tb->lines_list[tb->cy]);
70 tb->lines_list[tb->cy] = string_make(buf);
71 tb->dirty_flags |= DIRTY_EXPRESSION;
77 * @brief Get a trigger key and insert ASCII string for the trigger
79 bool insert_macro_line(text_body_type *tb)
81 if (!can_insert_line(tb, 2)) {
100 ascii_to_text(tmp, buf, sizeof(tmp));
106 insert_return_code(tb);
107 string_free(tb->lines_list[tb->cy]);
108 tb->lines_list[tb->cy] = string_make(format("P:%s", tmp).data());
110 i = macro_find_exact(buf);
114 ascii_to_text(tmp, macro_actions[i], sizeof(tmp));
117 insert_return_code(tb);
118 string_free(tb->lines_list[tb->cy]);
119 tb->lines_list[tb->cy] = string_make(format("A:%s", tmp).data());
125 * @brief Get a command key and insert ASCII string for the key
127 bool insert_keymap_line(text_body_type *tb)
129 if (!can_insert_line(tb, 2)) {
133 if (rogue_like_commands) {
134 mode = KEYMAP_MODE_ROGUE;
136 mode = KEYMAP_MODE_ORIG;
146 ascii_to_text(tmp, buf, sizeof(tmp));
152 insert_return_code(tb);
153 string_free(tb->lines_list[tb->cy]);
154 tb->lines_list[tb->cy] = string_make(format("C:%d:%s", mode, tmp).data());
156 concptr act = keymap_act[mode][(byte)(buf[0])];
158 ascii_to_text(tmp, act, sizeof(tmp));
161 insert_return_code(tb);
162 string_free(tb->lines_list[tb->cy]);
163 tb->lines_list[tb->cy] = string_make(format("A:%s", tmp).data());
169 * @brief Insert single letter at cursor position.
171 void insert_single_letter(text_body_type *tb, int key)
174 char buf[MAX_LINELEN];
176 for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++) {
177 buf[j++] = tb->lines_list[tb->cy][i];
186 if (j + 2 < MAX_LINELEN) {
187 buf[j++] = (char)key;
188 buf[j++] = (char)next;
196 if (j + 1 < MAX_LINELEN) {
197 buf[j++] = (char)key;
202 for (; tb->lines_list[tb->cy][i] && j + 1 < MAX_LINELEN; i++) {
203 buf[j++] = tb->lines_list[tb->cy][i];
207 string_free(tb->lines_list[tb->cy]);
208 tb->lines_list[tb->cy] = string_make(buf);
209 len = strlen(tb->lines_list[tb->cy]);
214 tb->dirty_line = tb->cy;
215 check_expression_line(tb, tb->cy);
220 * @brief Kill segment of a line
222 void kill_line_segment(text_body_type *tb, int y, int x0, int x1, bool whole)
224 concptr s = tb->lines_list[y];
225 if (whole && x0 == 0 && s[x1] == '\0' && tb->lines_list[y + 1]) {
226 string_free(tb->lines_list[y]);
229 for (i = y; tb->lines_list[i + 1]; i++) {
230 tb->lines_list[i] = tb->lines_list[i + 1];
232 tb->lines_list[i] = nullptr;
234 tb->dirty_flags |= DIRTY_EXPRESSION;
243 char buf[MAX_LINELEN];
245 for (int x = 0; x < x0; x++) {
249 for (int x = x1; s[x]; x++) {
254 string_free(tb->lines_list[y]);
255 tb->lines_list[y] = string_make(buf);
256 check_expression_line(tb, y);