Rizin
unix-like reverse engineering framework and cli tools
dietline.c File Reference
#include <rz_cons.h>
#include <rz_core.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <signal.h>

Go to the source code of this file.

Macros

#define USE_UTF8   1
 

Enumerations

enum  BreakMode { MINOR_BREAK , MAJOR_BREAK }
 

Functions

static bool is_word_break_char (char ch, bool mode)
 
static void backward_kill_word (BreakMode mode)
 
static void kill_word (BreakMode mode)
 
static void paste (bool *enable_yank_pop)
 
static void unix_word_rubout (void)
 
static int inithist (void)
 
RZ_API int rz_line_dietline_init (void)
 
static int rz_line_readchar_utf8 (ut8 *s, int slen)
 
RZ_API int rz_line_set_hist_callback (RzLine *line, RzLineHistoryUpCb up, RzLineHistoryDownCb down)
 
static bool match_hist_line (char *hist_line, char *cur_line)
 
static void setup_hist_match (RzLine *line)
 
RZ_API int rz_line_hist_cmd_up (RzLine *line)
 
RZ_API int rz_line_hist_cmd_down (RzLine *line)
 
RZ_API int rz_line_hist_add (const char *line)
 
static int rz_line_hist_up (void)
 
static int rz_line_hist_down (void)
 
RZ_API const char * rz_line_hist_get (int n)
 
RZ_API int rz_line_hist_list (void)
 
RZ_API void rz_line_hist_free (void)
 
RZ_API int rz_line_hist_load (RZ_NONNULL const char *path)
 Load the history of commands from path. More...
 
RZ_API int rz_line_hist_save (RZ_NONNULL const char *path)
 Save the history of commands executed until now to file path. More...
 
RZ_API int rz_line_hist_chop (const char *file, int limit)
 
static void selection_widget_draw (void)
 
static void selection_widget_up (int steps)
 
static void selection_widget_down (int steps)
 
static void print_rline_task (void *_core)
 
static void selection_widget_erase (void)
 
static void selection_widget_select (void)
 
static void selection_widget_update (void)
 
static bool is_valid_buffer_limits (RzLineBuffer *buf, size_t start, size_t end, size_t s_len)
 
static void replace_buffer_text (RzLineBuffer *buf, size_t start, size_t end, const char *s)
 
static char * get_max_common_pfx (RzPVector *options)
 
static void print_options (int argc, const char **argv)
 
RZ_API void rz_line_autocomplete (void)
 
RZ_API const char * rz_line_readline (void)
 
static void rotate_kill_ring (bool *enable_yank_pop)
 
static void __delete_next_char (void)
 
static void __delete_prev_char (void)
 
static void delete_till_end (void)
 
static void __print_prompt (void)
 
static void __move_cursor_right (void)
 
static void __move_cursor_left (void)
 
static void vi_cmd_b (void)
 
static void vi_cmd_B (void)
 
static void vi_cmd_W (void)
 
static void vi_cmd_w (void)
 
static void vi_cmd_E (void)
 
static void vi_cmd_e (void)
 
static void __update_prompt_color (void)
 
static void __vi_mode (bool *enable_yank_pop)
 
RZ_API const char * rz_line_readline_cb (RzLineReadCallback cb, void *user)
 

Variables

static char * rz_line_nullstr = ""
 
static const char word_break_characters [] = "\t\n ~`!@#$%^&*()-_=+[]{}\\|;:\"'<>,./"
 

Macro Definition Documentation

◆ USE_UTF8

#define USE_UTF8   1

Definition at line 19 of file dietline.c.

Enumeration Type Documentation

◆ BreakMode

enum BreakMode
Enumerator
MINOR_BREAK 
MAJOR_BREAK 

Definition at line 25 of file dietline.c.

25  {
28 } BreakMode;
BreakMode
Definition: dietline.c:25
@ MAJOR_BREAK
Definition: dietline.c:27
@ MINOR_BREAK
Definition: dietline.c:26

Function Documentation

◆ __delete_next_char()

static void __delete_next_char ( void  )
inlinestatic

Definition at line 931 of file dietline.c.

931  {
932  if (I.buffer.index < I.buffer.length) {
933  int len = rz_str_utf8_charsize(I.buffer.data + I.buffer.index);
934  memmove(I.buffer.data + I.buffer.index,
935  I.buffer.data + I.buffer.index + len,
936  strlen(I.buffer.data + I.buffer.index + 1) + 1);
937  I.buffer.length -= len;
938  }
939 }
size_t len
Definition: 6502dis.c:15
#define I(x)
Definition: arc.h:164
RZ_API size_t rz_str_utf8_charsize(const char *str)
Definition: str.c:2298

References I, len, and rz_str_utf8_charsize().

Referenced by __vi_mode(), and rz_line_readline_cb().

◆ __delete_prev_char()

static void __delete_prev_char ( void  )
inlinestatic

Definition at line 941 of file dietline.c.

941  {
942  if (I.buffer.index < I.buffer.length) {
943  if (I.buffer.index > 0) {
944  size_t len = rz_str_utf8_charsize_prev(I.buffer.data + I.buffer.index, I.buffer.index);
945  I.buffer.index -= len;
946  memmove(I.buffer.data + I.buffer.index,
947  I.buffer.data + I.buffer.index + len,
948  strlen(I.buffer.data + I.buffer.index));
949  I.buffer.length -= len;
950  }
951  } else {
952  I.buffer.length -= rz_str_utf8_charsize_last(I.buffer.data);
953  I.buffer.index = I.buffer.length;
954  if (I.buffer.length < 0) {
955  I.buffer.length = 0;
956  }
957  }
958  I.buffer.data[I.buffer.length] = '\0';
959  if (I.buffer.index < 0) {
960  I.buffer.index = 0;
961  }
962 }
RZ_API size_t rz_str_utf8_charsize_prev(const char *str, int prev_len)
Definition: str.c:2317
RZ_API size_t rz_str_utf8_charsize_last(const char *str)
Definition: str.c:2335

References I, len, rz_str_utf8_charsize_last(), and rz_str_utf8_charsize_prev().

Referenced by __vi_mode(), and rz_line_readline_cb().

◆ __move_cursor_left()

static void __move_cursor_left ( void  )
inlinestatic

Definition at line 1009 of file dietline.c.

1009  {
1010  I.buffer.index = I.buffer.index
1011  ? I.buffer.index - rz_str_utf8_charsize_prev(I.buffer.data + I.buffer.index, I.buffer.index)
1012  : 0;
1013 }

References I, and rz_str_utf8_charsize_prev().

Referenced by __vi_mode(), and rz_line_readline_cb().

◆ __move_cursor_right()

static void __move_cursor_right ( void  )
inlinestatic

Definition at line 1003 of file dietline.c.

1003  {
1004  I.buffer.index = I.buffer.index < I.buffer.length
1005  ? I.buffer.index + rz_str_utf8_charsize(I.buffer.data + I.buffer.index)
1006  : I.buffer.length;
1007 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
Definition: buffer.h:15

References I, and rz_str_utf8_charsize().

Referenced by __vi_mode(), and rz_line_readline_cb().

◆ __print_prompt()

static void __print_prompt ( void  )
static

Definition at line 970 of file dietline.c.

970  {
971  RzCons *cons = rz_cons_singleton();
972  int columns = rz_cons_get_size(NULL) - 2;
973  int chars = strlen(I.buffer.data);
974  int len, i, cols = RZ_MAX(1, columns - rz_str_ansi_len(I.prompt) - 2);
975  if (cons->line->prompt_type == RZ_LINE_PROMPT_OFFSET) {
976  rz_cons_gotoxy(0, cons->rows);
977  rz_cons_flush();
978  }
980  if (cons->context->color_mode > 0) {
981  printf("\r%s%s", Color_RESET, I.prompt);
982  } else {
983  printf("\r%s", I.prompt);
984  }
985  fwrite(I.buffer.data, 1, RZ_MIN(cols, chars), stdout);
986  printf("\r%s", I.prompt);
987  if (I.buffer.index > cols) {
988  printf("< ");
989  i = I.buffer.index - cols;
990  if (i > sizeof(I.buffer.data)) {
991  i = sizeof(I.buffer.data) - 1;
992  }
993  } else {
994  i = 0;
995  }
996  len = I.buffer.index - i;
997  if (len > 0 && (i + len) <= I.buffer.length) {
998  fwrite(I.buffer.data + i, 1, len, stdout);
999  }
1000  fflush(stdout);
1001 }
lzma_index ** i
Definition: index.h:629
RZ_API int rz_cons_get_size(int *rows)
Definition: cons.c:1446
RZ_API RzCons * rz_cons_singleton(void)
Definition: cons.c:300
RZ_API void rz_cons_clear_line(int std_err)
Definition: cons.c:756
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_API void rz_cons_gotoxy(int x, int y)
Definition: cons.c:724
#define NULL
Definition: cris-opc.c:27
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
#define Color_RESET
Definition: rz_cons.h:617
@ RZ_LINE_PROMPT_OFFSET
Definition: rz_cons.h:1038
RZ_API size_t rz_str_ansi_len(const char *str)
Definition: str.c:1945
#define RZ_MIN(x, y)
#define RZ_MAX(x, y)
struct rz_line_t * line
Definition: rz_cons.h:553
RzConsContext * context
Definition: rz_cons.h:502
int rows
Definition: rz_cons.h:508
RzLinePromptType prompt_type
Definition: rz_cons.h:1116

References rz_cons_context_t::color_mode, Color_RESET, rz_cons_t::context, I, i, len, rz_cons_t::line, NULL, printf(), rz_line_t::prompt_type, rz_cons_t::rows, rz_cons_clear_line(), rz_cons_flush(), rz_cons_get_size(), rz_cons_gotoxy(), rz_cons_singleton(), RZ_LINE_PROMPT_OFFSET, RZ_MAX, RZ_MIN, and rz_str_ansi_len().

Referenced by __vi_mode(), and rz_line_readline_cb().

◆ __update_prompt_color()

static void __update_prompt_color ( void  )
static

Definition at line 1093 of file dietline.c.

1093  {
1094  RzCons *cons = rz_cons_singleton();
1095  const char *BEGIN = "", *END = "";
1096  if (cons->context->color_mode) {
1097  if (I.prompt_mode) {
1098  switch (I.vi_mode) {
1099  case CONTROL_MODE:
1100  BEGIN = cons->context->pal.invalid;
1101  break;
1102  case INSERT_MODE:
1103  default:
1104  BEGIN = cons->context->pal.prompt;
1105  break;
1106  }
1107  } else {
1108  BEGIN = cons->context->pal.prompt;
1109  }
1110  END = cons->context->pal.reset;
1111  }
1112  char *prompt = rz_str_escape(I.prompt); // remote the color
1113  free(I.prompt);
1114  I.prompt = rz_str_newf("%s%s%s", BEGIN, prompt, END);
1115  free(prompt);
1116 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
@ CONTROL_MODE
Definition: rz_cons.h:780
@ INSERT_MODE
Definition: rz_cons.h:779
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API RZ_OWN char * rz_str_escape(RZ_NONNULL const char *buf)
Definition: str.c:1550
RzConsPrintablePalette pal
Definition: rz_cons.h:491
static char * prompt(const char *str, const char *txt)
Definition: vmenus.c:30

References rz_cons_context_t::color_mode, rz_cons_t::context, CONTROL_MODE, free(), I, INSERT_MODE, rz_cons_printable_palette_t::invalid, rz_cons_context_t::pal, prompt(), rz_cons_printable_palette_t::prompt, rz_cons_printable_palette_t::reset, rz_cons_singleton(), rz_str_escape(), and rz_str_newf().

Referenced by __vi_mode().

◆ __vi_mode()

static void __vi_mode ( bool enable_yank_pop)
static

Definition at line 1118 of file dietline.c.

1118  {
1119  char ch;
1120  I.vi_mode = CONTROL_MODE;
1122  const char *gcomp_line = "";
1123  static int gcomp = 0;
1124  for (;;) {
1125  int rep = 0;
1126  if (I.echo) {
1127  __print_prompt();
1128  }
1129  if (I.vi_mode != CONTROL_MODE) { // exit if insert mode is selected
1131  break;
1132  }
1133  bool o_do_setup_match = I.history.do_setup_match;
1134  I.history.do_setup_match = true;
1135  ch = rz_cons_readchar();
1136  while (IS_DIGIT(ch)) { // handle commands like 3b
1137  if (ch == '0' && rep == 0) { // to handle the command 0
1138  break;
1139  }
1140  int tmp = ch - '0';
1141  rep = (rep * 10) + tmp;
1142  ch = rz_cons_readchar();
1143  }
1144  rep = rep > 0 ? rep : 1;
1145 
1146  switch (ch) {
1147  case 3:
1148  if (I.hud) {
1149  I.hud->activate = false;
1150  I.hud->current_entry_n = -1;
1151  }
1152  if (I.echo) {
1153  eprintf("^C\n");
1154  }
1155  I.buffer.index = I.buffer.length = 0;
1156  *I.buffer.data = '\0';
1157  gcomp = 0;
1158  return;
1159  case 'D':
1160  delete_till_end();
1161  break;
1162  case 'r': {
1163  char c = rz_cons_readchar();
1164  I.buffer.data[I.buffer.index] = c;
1165  } break;
1166  case 'x':
1167  while (rep--) {
1169  }
1170  break;
1171  case 'c':
1172  I.vi_mode = INSERT_MODE; // goto insert mode
1173  /* fall through */
1174  case 'd': {
1175  char c = rz_cons_readchar();
1176  while (rep--) {
1177  switch (c) {
1178  case 'i': {
1179  char t = rz_cons_readchar();
1180  if (t == 'w') { // diw
1183  } else if (t == 'W') { // diW
1186  }
1187  if (I.hud) {
1188  I.hud->vi = false;
1189  }
1190  } break;
1191  case 'W':
1193  break;
1194  case 'w':
1196  break;
1197  case 'B':
1199  break;
1200  case 'b':
1202  break;
1203  case 'h':
1205  break;
1206  case 'l':
1208  break;
1209  case '$':
1210  delete_till_end();
1211  break;
1212  case '^':
1213  case '0':
1214  strncpy(I.buffer.data, I.buffer.data + I.buffer.index, I.buffer.length);
1215  I.buffer.length -= I.buffer.index;
1216  I.buffer.index = 0;
1217  break;
1218  }
1219  __print_prompt();
1220  }
1221  } break;
1222  case 'I':
1223  if (I.hud) {
1224  I.hud->vi = false;
1225  }
1226  I.vi_mode = INSERT_MODE;
1227  /* fall through */
1228  case '^':
1229  case '0':
1230  if (gcomp) {
1231  strcpy(I.buffer.data, gcomp_line);
1232  I.buffer.length = strlen(I.buffer.data);
1233  I.buffer.index = 0;
1234  gcomp = false;
1235  }
1236  I.buffer.index = 0;
1237  break;
1238  case 'A':
1239  I.vi_mode = INSERT_MODE;
1240  /* fall through */
1241  case '$':
1242  if (gcomp) {
1243  strcpy(I.buffer.data, gcomp_line);
1244  I.buffer.index = strlen(I.buffer.data);
1245  I.buffer.length = I.buffer.index;
1246  gcomp = false;
1247  } else {
1248  I.buffer.index = I.buffer.length;
1249  }
1250  break;
1251  case 'p':
1252  while (rep--) {
1253  paste(enable_yank_pop);
1254  }
1255  break;
1256  case 'a':
1258  /* fall through */
1259  case 'i':
1260  I.vi_mode = INSERT_MODE;
1261  if (I.hud) {
1262  I.hud->vi = false;
1263  }
1264  break;
1265  case 'h':
1266  while (rep--) {
1268  }
1269  break;
1270  case 'l':
1271  while (rep--) {
1273  }
1274  break;
1275  case 'E':
1276  while (rep--) {
1277  vi_cmd_E();
1278  }
1279  break;
1280  case 'e':
1281  while (rep--) {
1282  vi_cmd_e();
1283  }
1284  break;
1285  case 'B':
1286  while (rep--) {
1287  vi_cmd_B();
1288  }
1289  break;
1290  case 'b':
1291  while (rep--) {
1292  vi_cmd_b();
1293  }
1294  break;
1295  case 'W':
1296  while (rep--) {
1297  vi_cmd_W();
1298  }
1299  break;
1300  case 'w':
1301  while (rep--) {
1302  vi_cmd_w();
1303  }
1304  break;
1305  default: // escape key
1306  ch = tolower(rz_cons_arrow_to_hjkl(ch));
1307  switch (ch) {
1308  case 'k': // up
1309  I.history.do_setup_match = o_do_setup_match;
1310  rz_line_hist_up();
1311  break;
1312  case 'j': // down
1313  I.history.do_setup_match = o_do_setup_match;
1315  break;
1316  case 'l': // right
1318  break;
1319  case 'h': // left
1321  break;
1322  }
1323  break;
1324  }
1325  if (I.hud) {
1326  return;
1327  }
1328  }
1329 }
static void kill_word(BreakMode mode)
Definition: dietline.c:73
static void __move_cursor_left(void)
Definition: dietline.c:1009
static void backward_kill_word(BreakMode mode)
Definition: dietline.c:44
static void delete_till_end(void)
Definition: dietline.c:964
static void vi_cmd_w(void)
Definition: dietline.c:1054
static void __delete_next_char(void)
Definition: dietline.c:931
static void __move_cursor_right(void)
Definition: dietline.c:1003
static void vi_cmd_E(void)
Definition: dietline.c:1067
static void __update_prompt_color(void)
Definition: dietline.c:1093
static int rz_line_hist_down(void)
Definition: dietline.c:417
static void paste(bool *enable_yank_pop)
Definition: dietline.c:89
static void __delete_prev_char(void)
Definition: dietline.c:941
static void vi_cmd_B(void)
Definition: dietline.c:1028
static void vi_cmd_W(void)
Definition: dietline.c:1041
static int rz_line_hist_up(void)
Definition: dietline.c:410
static void vi_cmd_b(void)
Definition: dietline.c:1015
static void __print_prompt(void)
Definition: dietline.c:970
static void vi_cmd_e(void)
Definition: dietline.c:1080
RZ_API int rz_cons_arrow_to_hjkl(int ch)
Definition: input.c:78
RZ_API int rz_cons_readchar(void)
Definition: input.c:619
#define eprintf(x, y...)
Definition: rlcc.c:7
#define IS_DIGIT(x)
Definition: rz_str_util.h:11
#define tolower(c)
Definition: safe-ctype.h:149
#define c(i)
Definition: sha256.c:43

References __delete_next_char(), __delete_prev_char(), __move_cursor_left(), __move_cursor_right(), __print_prompt(), __update_prompt_color(), backward_kill_word(), c, CONTROL_MODE, delete_till_end(), eprintf, I, INSERT_MODE, IS_DIGIT, kill_word(), MAJOR_BREAK, MINOR_BREAK, paste(), rz_cons_arrow_to_hjkl(), rz_cons_readchar(), rz_line_hist_down(), rz_line_hist_up(), autogen_x86imm::tmp, tolower, vi_cmd_b(), vi_cmd_B(), vi_cmd_E(), vi_cmd_e(), vi_cmd_W(), and vi_cmd_w().

Referenced by rz_line_readline_cb().

◆ backward_kill_word()

static void backward_kill_word ( BreakMode  mode)
static

Definition at line 44 of file dietline.c.

44  {
45  int i, len;
46  if (I.buffer.index <= 0) {
47  return;
48  }
49  for (i = I.buffer.index; i > 0 && is_word_break_char(I.buffer.data[i], mode); i--) {
50  /* Move the cursor index back until we hit a non-word-break-character */
51  }
52  for (; i > 0 && !is_word_break_char(I.buffer.data[i], mode); i--) {
53  /* Move the cursor index back until we hit a word-break-character */
54  }
55  if (i > 0) {
56  i++;
57  } else if (i < 0) {
58  i = 0;
59  }
60  if (I.buffer.index > I.buffer.length) {
61  I.buffer.length = I.buffer.index;
62  }
63  len = I.buffer.index - i;
64  free(I.clipboard);
65  I.clipboard = rz_str_ndup(I.buffer.data + i, len);
66  rz_line_clipboard_push(I.clipboard);
67  memmove(I.buffer.data + i, I.buffer.data + I.buffer.index,
68  I.buffer.length - I.buffer.index + 1);
69  I.buffer.length = strlen(I.buffer.data);
70  I.buffer.index = i;
71 }
static bool is_word_break_char(char ch, bool mode)
Definition: dietline.c:30
const char int mode
Definition: ioapi.h:137
RZ_API void rz_line_clipboard_push(const char *str)
Definition: line.c:50
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006

References free(), I, i, is_word_break_char(), len, rz_line_clipboard_push(), and rz_str_ndup().

Referenced by __vi_mode(), and rz_line_readline_cb().

◆ delete_till_end()

static void delete_till_end ( void  )
inlinestatic

Definition at line 964 of file dietline.c.

964  {
965  I.buffer.data[I.buffer.index] = '\0';
966  I.buffer.length = I.buffer.index;
967  I.buffer.index = I.buffer.index > 0 ? I.buffer.index - 1 : 0;
968 }

References I.

Referenced by __vi_mode().

◆ get_max_common_pfx()

static char* get_max_common_pfx ( RzPVector options)
static

Definition at line 726 of file dietline.c.

726  {
727  const char *ref = rz_pvector_at(options, 0);
728  size_t min_common_len = strlen(ref);
729  void **it;
730  bool first = true;
732  if (first) {
733  first = false;
734  continue;
735  }
736  char *s = *(char **)it;
737  size_t j;
738  for (j = 0; s[j] && ref[j] && s[j] == ref[j]; j++)
739  ;
740  if (j < min_common_len) {
741  min_common_len = j;
742  }
743  }
744  return rz_str_ndup(ref, min_common_len);
745 }
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
static RzSocket * s
Definition: rtr.c:28
static void * rz_pvector_at(const RzPVector *vec, size_t index)
Definition: rz_vector.h:236
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334

References options, rz_pvector_at(), rz_pvector_foreach, rz_str_ndup(), and s.

Referenced by rz_line_autocomplete().

◆ inithist()

static int inithist ( void  )
static

Definition at line 133 of file dietline.c.

133  {
134  ZERO_FILL(I.history);
135  if ((I.history.size + 1024) * sizeof(char *) < I.history.size) {
136  return false;
137  }
138  I.history.data = (char **)calloc((I.history.size + 1024), sizeof(char *));
139  if (!I.history.data) {
140  return false;
141  }
142  I.history.size = RZ_LINE_HISTSIZE;
143  return true;
144 }
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
#define RZ_LINE_HISTSIZE
Definition: rz_cons.h:992
#define ZERO_FILL(x)
Definition: rz_types.h:281

References calloc(), I, RZ_LINE_HISTSIZE, and ZERO_FILL.

Referenced by rz_line_dietline_init(), rz_line_hist_add(), rz_line_hist_cmd_down(), rz_line_hist_cmd_up(), rz_line_hist_get(), and rz_line_hist_list().

◆ is_valid_buffer_limits()

static bool is_valid_buffer_limits ( RzLineBuffer buf,
size_t  start,
size_t  end,
size_t  s_len 
)
static

Definition at line 698 of file dietline.c.

698  {
699  if (start > end || s_len < end - start) {
700  return false;
701  }
702  if (start > buf->length || start + s_len >= RZ_LINE_BUFSIZE - 1) {
703  return false;
704  }
705  if (end > buf->length || end + s_len >= RZ_LINE_BUFSIZE - 1) {
706  return false;
707  }
708  return true;
709 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
voidpf void * buf
Definition: ioapi.h:138
#define RZ_LINE_BUFSIZE
Definition: rz_cons.h:991

References test_evm::end, RZ_LINE_BUFSIZE, and start.

Referenced by replace_buffer_text().

◆ is_word_break_char()

static bool is_word_break_char ( char  ch,
bool  mode 
)
inlinestatic

Definition at line 30 of file dietline.c.

30  {
31  int i;
32  if (mode == MAJOR_BREAK) {
33  return ch == ' ';
34  }
35  for (i = 0; i < RZ_ARRAY_SIZE(word_break_characters); i++) {
36  if (ch == word_break_characters[i]) {
37  return true;
38  }
39  }
40  return false;
41 }
static const char word_break_characters[]
Definition: dietline.c:23
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300

References i, MAJOR_BREAK, RZ_ARRAY_SIZE, and word_break_characters.

Referenced by backward_kill_word(), kill_word(), rz_line_readline_cb(), vi_cmd_b(), vi_cmd_B(), vi_cmd_E(), vi_cmd_e(), vi_cmd_W(), and vi_cmd_w().

◆ kill_word()

static void kill_word ( BreakMode  mode)
static

Definition at line 73 of file dietline.c.

73  {
74  int i, len;
75  for (i = I.buffer.index; i < I.buffer.length && is_word_break_char(I.buffer.data[i], mode); i++) {
76  /* Move the cursor index forward until we hit a non-word-break-character */
77  }
78  for (; i < I.buffer.length && !is_word_break_char(I.buffer.data[i], mode); i++) {
79  /* Move the cursor index forward until we hit a word-break-character */
80  }
81  len = i - I.buffer.index;
82  free(I.clipboard);
83  I.clipboard = rz_str_ndup(I.buffer.data + I.buffer.index, len);
84  rz_line_clipboard_push(I.clipboard);
85  memmove(I.buffer.data + I.buffer.index, I.buffer.data + i, I.buffer.length - i + 1);
86  I.buffer.length -= len;
87 }

References free(), I, i, is_word_break_char(), len, rz_line_clipboard_push(), and rz_str_ndup().

Referenced by __vi_mode(), and rz_line_readline_cb().

◆ match_hist_line()

static bool match_hist_line ( char *  hist_line,
char *  cur_line 
)
inlinestatic

Definition at line 301 of file dietline.c.

301  {
302  // Starts with but not equal to
303  return rz_str_startswith(hist_line, cur_line) && strcmp(hist_line, cur_line);
304 }
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286

References rz_str_startswith().

Referenced by rz_line_hist_cmd_down(), and rz_line_hist_cmd_up().

◆ paste()

static void paste ( bool enable_yank_pop)
static

Definition at line 89 of file dietline.c.

89  {
90  if (I.clipboard) {
91  char *cursor = I.buffer.data + I.buffer.index;
92  int dist = (I.buffer.data + I.buffer.length) - cursor;
93  int len = strlen(I.clipboard);
94  I.buffer.length += len;
95  memmove(cursor + len, cursor, dist);
96  memcpy(cursor, I.clipboard, len);
97  I.buffer.index += len;
98  *enable_yank_pop = true;
99  }
100 }
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))

References I, len, and memcpy().

Referenced by __vi_mode(), rotate_kill_ring(), and rz_line_readline_cb().

◆ print_options()

static void print_options ( int  argc,
const char **  argv 
)
static

Definition at line 747 of file dietline.c.

747  {
748  int cols = (int)(rz_cons_get_size(NULL) * 0.82);
749  size_t i, len;
750  const int sep = 3;
751  int slen, col = 10;
752 
753  for (i = 0; i < argc && argv[i]; i++) {
754  int l = strlen(argv[i]);
755  if (sep + l > col) {
756  col = sep + l;
757  }
758  if (col > (cols >> 1)) {
759  col = (cols >> 1);
760  break;
761  }
762  }
763  for (len = i = 0; i < argc && argv[i]; i++) {
764  if (len + col > cols) {
765  rz_cons_printf("\n");
766  len = 0;
767  }
768  rz_cons_printf("%-*s ", col - sep, argv[i]);
769  slen = strlen(argv[i]);
770  len += (slen > col) ? (slen + sep) : (col + sep);
771  }
772  rz_cons_printf("\n");
773 }
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
static int
Definition: sfsocketcall.h:114

References argv, i, int, len, NULL, rz_cons_get_size(), and rz_cons_printf().

Referenced by rz_line_autocomplete().

◆ print_rline_task()

static void print_rline_task ( void *  _core)
static

Definition at line 627 of file dietline.c.

627  {
629  rz_cons_printf("%s%s%s", Color_RESET, I.prompt, I.buffer.data);
630  rz_cons_flush();
631 }

References Color_RESET, I, rz_cons_clear_line(), rz_cons_flush(), and rz_cons_printf().

Referenced by selection_widget_erase().

◆ replace_buffer_text()

static void replace_buffer_text ( RzLineBuffer buf,
size_t  start,
size_t  end,
const char *  s 
)
static

Definition at line 711 of file dietline.c.

711  {
712  size_t s_len = strlen(s);
713  if (!is_valid_buffer_limits(buf, start, end, s_len)) {
714  return;
715  }
716 
717  size_t diff = end - start;
718  // FIXME: escape s
719  memmove(buf->data + start + s_len, buf->data + end, buf->length - end);
720  memmove(buf->data + start, s, s_len);
721  buf->length += s_len - diff;
722  buf->index += s_len - diff;
723  buf->data[buf->length] = '\0';
724 }
static bool is_valid_buffer_limits(RzLineBuffer *buf, size_t start, size_t end, size_t s_len)
Definition: dietline.c:698

References test_evm::end, is_valid_buffer_limits(), s, and start.

Referenced by rz_line_autocomplete().

◆ rotate_kill_ring()

static void rotate_kill_ring ( bool enable_yank_pop)
inlinestatic

Definition at line 917 of file dietline.c.

917  {
918  if (!*enable_yank_pop) {
919  return;
920  }
921  I.buffer.index -= strlen(rz_list_get_n(I.kill_ring, I.kill_ring_ptr));
922  I.buffer.data[I.buffer.index] = 0;
923  I.kill_ring_ptr -= 1;
924  if (I.kill_ring_ptr < 0) {
925  I.kill_ring_ptr = I.kill_ring->length - 1;
926  }
927  I.clipboard = rz_list_get_n(I.kill_ring, I.kill_ring_ptr);
928  paste(enable_yank_pop);
929 }
RZ_API RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
Definition: list.c:574

References I, paste(), and rz_list_get_n().

Referenced by rz_line_readline_cb().

◆ rz_line_autocomplete()

RZ_API void rz_line_autocomplete ( void  )

Definition at line 775 of file dietline.c.

775  {
776  char *p;
777  const char **argv = NULL;
778  int argc = 0, i, j, plen;
779  bool opt = false;
780  RzCons *cons = rz_cons_singleton();
781 
782  if (I.ns_completion.run) {
783  RzLineNSCompletionResult *res = I.ns_completion.run(&I.buffer, I.prompt_type, I.ns_completion.run_user);
784  if (!res || rz_pvector_empty(&res->options)) {
785  // do nothing
786  } else if (rz_pvector_len(&res->options) == 1) {
787  // if there is just one option, just use it
788  bool is_at_end = I.buffer.length == I.buffer.index;
789  replace_buffer_text(&I.buffer, res->start, res->end, rz_pvector_at(&res->options, 0));
790  if (is_at_end && res->end_string) {
791  replace_buffer_text(&I.buffer, I.buffer.length, I.buffer.length, res->end_string);
792  }
793  } else {
794  // otherwise find maxcommonprefix, print it, and then print options
795  char *max_common_pfx = get_max_common_pfx(&res->options);
796  replace_buffer_text(&I.buffer, res->start, res->end, max_common_pfx);
797  free(max_common_pfx);
798 
799  rz_cons_printf("%s%s\n", I.prompt, I.buffer.data);
800  print_options(rz_pvector_len(&res->options), (const char **)rz_pvector_data(&res->options));
801  }
802 
804  return;
805  }
806 
807  /* prepare argc and argv */
808  if (I.completion.run) {
809  I.completion.opt = false;
810  I.completion.run(&I.completion, &I.buffer, I.prompt_type, I.completion.run_user);
811  argc = rz_pvector_len(&I.completion.args);
812  argv = (const char **)rz_pvector_data(&I.completion.args);
813  opt = I.completion.opt;
814  }
815  if (I.sel_widget && !I.sel_widget->complete_common) {
817  return;
818  }
819 
820  if (opt) {
821  p = (char *)rz_sub_str_lchr(I.buffer.data, 0, I.buffer.index, '=');
822  } else {
823  p = (char *)rz_sub_str_lchr(I.buffer.data, 0, I.buffer.index, ' ');
824  }
825  if (!p) {
826  p = (char *)rz_sub_str_lchr(I.buffer.data, 0, I.buffer.index, '@'); // HACK FOR r2
827  }
828  if (p) {
829  p++;
830  plen = sizeof(I.buffer.data) - (int)(size_t)(p - I.buffer.data);
831  } else {
832  p = I.buffer.data; // XXX: removes current buffer
833  plen = sizeof(I.buffer.data);
834  }
835  /* autocomplete */
836  if (argc == 1) {
837  const char *end_word = rz_sub_str_rchr(I.buffer.data,
838  I.buffer.index, strlen(I.buffer.data), ' ');
839  const char *t = end_word != NULL ? end_word : I.buffer.data + I.buffer.index;
840  int largv0 = strlen(argv[0] ? argv[0] : "");
841  size_t len_t = strlen(t);
842  p[largv0] = '\0';
843 
844  if ((p - I.buffer.data) + largv0 + 1 + len_t < plen) {
845  if (len_t > 0) {
846  int tt = largv0;
847  if (*t != ' ') {
848  p[tt++] = ' ';
849  }
850  memmove(p + tt, t, len_t);
851  }
852  memcpy(p, argv[0], largv0);
853 
854  if (p[largv0 - 1] != RZ_SYS_DIR[0]) {
855  p[largv0] = ' ';
856  if (!len_t) {
857  p[largv0 + 1] = '\0';
858  }
859  }
860  I.buffer.length = strlen(I.buffer.data);
861  I.buffer.index = I.buffer.length;
862  }
863  } else if (argc > 0) {
864  if (*p) {
865  // TODO: avoid overflow
866  const char *t = I.buffer.data + I.buffer.index;
867  const char *root = argv[0];
868  int min_common_len = strlen(root);
869  size_t len_t = strlen(t);
870 
871  // try to autocomplete argument
872  for (i = 0; i < argc; i++) {
873  j = 0;
874  if (!argv[i]) {
875  break;
876  }
877  while (argv[i][j] == root[j] && root[j] != '\0')
878  j++;
879  if (j < min_common_len) {
880  min_common_len = j;
881  }
882  root = argv[i];
883  }
884  if (len_t > 0) {
885  int tt = min_common_len;
886  memmove(p + tt, t, len_t);
887  p[tt + len_t] = '\0';
888  }
889  memmove(p, root, min_common_len);
890  if (!len_t) {
891  p[min_common_len] = '\0';
892  }
893  I.buffer.length = strlen(I.buffer.data);
894  I.buffer.index = (p - I.buffer.data) + min_common_len;
895  }
896  }
897 
898  if (I.prompt_type != RZ_LINE_PROMPT_DEFAULT || cons->show_autocomplete_widget) {
900  if (I.sel_widget) {
901  I.sel_widget->complete_common = false;
902  }
903  return;
904  }
905 
906  /* show options */
907  if (argc > 1 && I.echo) {
908  rz_cons_printf("%s%s\n", I.prompt, I.buffer.data);
909  print_options(argc, argv);
910  }
911 }
static void selection_widget_update(void)
Definition: dietline.c:671
static void print_options(int argc, const char **argv)
Definition: dietline.c:747
static char * get_max_common_pfx(RzPVector *options)
Definition: dietline.c:726
static void replace_buffer_text(RzLineBuffer *buf, size_t start, size_t end, const char *s)
Definition: dietline.c:711
int root
Definition: enough.c:226
void * p
Definition: libc.cpp:67
RZ_API void rz_line_ns_completion_result_free(RzLineNSCompletionResult *res)
Definition: line.c:144
@ RZ_LINE_PROMPT_DEFAULT
Definition: rz_cons.h:1037
RZ_API const char * rz_sub_str_rchr(const char *str, int start, int end, char chr)
Definition: str.c:690
RZ_API const char * rz_sub_str_lchr(const char *str, int start, int end, char chr)
Definition: str.c:682
#define RZ_SYS_DIR
Definition: rz_types.h:218
static void ** rz_pvector_data(RzPVector *vec)
Definition: rz_vector.h:257
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
static bool rz_pvector_empty(RzPVector *vec)
Definition: rz_vector.h:246
int size_t
Definition: sftypes.h:40
bool show_autocomplete_widget
Definition: rz_cons.h:516
size_t start
First byte that was considered for autocompletion. Everything before this will be left intact.
Definition: rz_cons.h:1062
const char * end_string
String to place after the only option available is autocompleted. By default a space is used.
Definition: rz_cons.h:1064
size_t end
Last byte that was considered for autocompletion. Everything after this will be left intact.
Definition: rz_cons.h:1063
RzPVector options
Vector of options that can be used for autocompletion.
Definition: rz_cons.h:1060

References argv, rz_line_ns_completion_result_t::end, rz_line_ns_completion_result_t::end_string, free(), get_max_common_pfx(), I, i, memcpy(), NULL, rz_line_ns_completion_result_t::options, p, print_options(), replace_buffer_text(), root, rz_cons_printf(), rz_cons_singleton(), rz_line_ns_completion_result_free(), RZ_LINE_PROMPT_DEFAULT, rz_pvector_at(), rz_pvector_data(), rz_pvector_empty(), rz_pvector_len(), rz_sub_str_lchr(), rz_sub_str_rchr(), RZ_SYS_DIR, selection_widget_update(), rz_cons_t::show_autocomplete_widget, and rz_line_ns_completion_result_t::start.

Referenced by rz_line_readline_cb().

◆ rz_line_dietline_init()

RZ_API int rz_line_dietline_init ( void  )

Definition at line 147 of file dietline.c.

147  {
148  ZERO_FILL(I.completion);
149  if (!inithist()) {
150  return false;
151  }
152  I.echo = true;
153  return true;
154 }
static int inithist(void)
Definition: dietline.c:133

References I, inithist(), and ZERO_FILL.

Referenced by rz_line_new().

◆ rz_line_hist_add()

RZ_API int rz_line_hist_add ( const char *  line)

Definition at line 382 of file dietline.c.

382  {
383  if (!line || !*line) {
384  return false;
385  }
386  if (!I.history.data) {
387  inithist();
388  }
389  /* ignore dup */
390  if (I.history.top > 0) {
391  const char *data = I.history.data[I.history.top - 1];
392  if (data && !strcmp(line, data)) {
393  I.history.index = I.history.top;
394  return false;
395  }
396  }
397  if (I.history.top == I.history.size) {
398  int i;
399  free(I.history.data[0]);
400  for (i = 0; i <= I.history.size - 2; i++) {
401  I.history.data[i] = I.history.data[i + 1];
402  }
403  I.history.top--;
404  }
405  I.history.data[I.history.top++] = strdup(line);
406  I.history.index = I.history.top;
407  return true;
408 }
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
line
Definition: setup.py:34

References free(), I, i, inithist(), setup::line, and strdup().

Referenced by __rtr_shell(), core_cmd_tsrzcmd(), rtr_visual(), rz_core_visual_prompt(), rz_lang_prompt(), and rz_line_hist_load().

◆ rz_line_hist_chop()

RZ_API int rz_line_hist_chop ( const char *  file,
int  limit 
)

Definition at line 528 of file dietline.c.

528  {
529  /* TODO */
530  return 0;
531 }

◆ rz_line_hist_cmd_down()

RZ_API int rz_line_hist_cmd_down ( RzLine line)

Definition at line 346 of file dietline.c.

346  {
347  if (line->hist_down) {
348  return line->hist_down(line->user);
349  }
350  if (!line->history.data) {
351  inithist();
352  }
354  if (line->history.match) {
355  int i;
356  for (i = line->history.index + 1; i < line->history.top; i++) {
357  if (match_hist_line(line->history.data[i], line->history.match)) {
358  break;
359  }
360  }
361  line->history.index = i;
362  } else {
363  line->history.index++;
364  }
365  if (line->history.index >= line->history.top) {
366  line->history.index = line->history.top;
367  if (line->history.match) {
368  strncpy(line->buffer.data, line->history.match, RZ_LINE_BUFSIZE - 1);
369  } else {
370  line->buffer.data[0] = '\0';
371  }
372  line->buffer.index = line->buffer.length = strlen(line->buffer.data);
373  return false;
374  }
375  if (line->history.data && line->history.data[line->history.index]) {
376  strncpy(line->buffer.data, line->history.data[line->history.index], RZ_LINE_BUFSIZE - 1);
377  line->buffer.index = line->buffer.length = strlen(line->buffer.data);
378  }
379  return true;
380 }
static bool match_hist_line(char *hist_line, char *cur_line)
Definition: dietline.c:301
static void setup_hist_match(RzLine *line)
Definition: dietline.c:306

References i, inithist(), setup::line, match_hist_line(), RZ_LINE_BUFSIZE, and setup_hist_match().

Referenced by __break_points_cb(), __open_file_cb(), rz_cmd_kuery(), rz_core_visual_offset(), rz_line_hist_down(), rz_line_hist_up(), and visual_offset().

◆ rz_line_hist_cmd_up()

RZ_API int rz_line_hist_cmd_up ( RzLine line)

Definition at line 316 of file dietline.c.

316  {
317  if (line->hist_up) {
318  return line->hist_up(line->user);
319  }
320  if (!line->history.data) {
321  inithist();
322  }
323  if (line->history.index > 0 && line->history.data) {
325  if (line->history.match) {
326  int i;
327  for (i = line->history.index - 1; i >= 0; i--) {
328  if (match_hist_line(line->history.data[i], line->history.match)) {
329  line->history.index = i;
330  break;
331  }
332  }
333  if (i < 0) {
334  return false;
335  }
336  } else {
337  line->history.index--;
338  }
339  strncpy(line->buffer.data, line->history.data[line->history.index], RZ_LINE_BUFSIZE - 1);
340  line->buffer.index = line->buffer.length = strlen(line->buffer.data);
341  return true;
342  }
343  return false;
344 }

References i, inithist(), setup::line, match_hist_line(), RZ_LINE_BUFSIZE, and setup_hist_match().

Referenced by __break_points_cb(), __open_file_cb(), rz_cmd_kuery(), rz_core_visual_offset(), rz_line_hist_down(), rz_line_hist_up(), and visual_offset().

◆ rz_line_hist_down()

static int rz_line_hist_down ( void  )
static

Definition at line 417 of file dietline.c.

417  {
418  if (!I.cb_history_down) {
420  }
421  return I.cb_history_down(&I);
422 }
RZ_API int rz_line_hist_cmd_down(RzLine *line)
Definition: dietline.c:346
RZ_API int rz_line_hist_cmd_up(RzLine *line)
Definition: dietline.c:316
RZ_API int rz_line_set_hist_callback(RzLine *line, RzLineHistoryUpCb up, RzLineHistoryDownCb down)
Definition: dietline.c:292

References I, rz_line_hist_cmd_down(), rz_line_hist_cmd_up(), and rz_line_set_hist_callback().

Referenced by __vi_mode(), and rz_line_readline_cb().

◆ rz_line_hist_free()

RZ_API void rz_line_hist_free ( void  )

Definition at line 455 of file dietline.c.

455  {
456  int i;
457  if (I.history.data) {
458  for (i = 0; i < I.history.size; i++) {
459  RZ_FREE(I.history.data[i]);
460  }
461  }
462  RZ_FREE(I.history.data);
463  RZ_FREE(I.sdbshell_hist);
464  I.history.index = 0;
465 }
#define RZ_FREE(x)
Definition: rz_types.h:369

References I, i, and RZ_FREE.

Referenced by rz_history_clear_handler(), and rz_line_free().

◆ rz_line_hist_get()

RZ_API const char* rz_line_hist_get ( int  n)

Definition at line 424 of file dietline.c.

424  {
425  int i = 0;
426  if (!I.history.data) {
427  inithist();
428  }
429  n--;
430  if (I.history.data) {
431  for (i = 0; i < I.history.size && I.history.data[i]; i++) {
432  if (n == i) {
433  return I.history.data[i];
434  }
435  }
436  }
437  return NULL;
438 }
int n
Definition: mipsasm.c:19

References I, i, inithist(), n, and NULL.

Referenced by rz_history_list_or_exec_handler().

◆ rz_line_hist_list()

RZ_API int rz_line_hist_list ( void  )

Definition at line 440 of file dietline.c.

440  {
441  int i = 0;
442  if (!I.history.data) {
443  inithist();
444  }
445  if (I.history.data) {
446  for (i = 0; i < I.history.size && I.history.data[i]; i++) {
447  // when you execute a command, you always move the history
448  // by 1 before actually printing it.
449  rz_cons_printf("%5d %s\n", i + 1, I.history.data[i]);
450  }
451  }
452  return i;
453 }

References I, i, inithist(), and rz_cons_printf().

Referenced by rz_history_list_or_exec_handler(), and rz_line_readline_cb().

◆ rz_line_hist_load()

RZ_API int rz_line_hist_load ( RZ_NONNULL const char *  path)

Load the history of commands from path.

Parameters
pathPath of the history file, where commands executed in the shell were saved in a previous session
Returns
false(0) if it fails, true(!0) otherwise

Definition at line 474 of file dietline.c.

474  {
475  rz_return_val_if_fail(path, false);
476 
477  FILE *fd;
478  char buf[RZ_LINE_BUFSIZE];
479  if (!(fd = rz_sys_fopen(path, "r"))) {
480  return false;
481  }
482  while (fgets(buf, sizeof(buf), fd) != NULL) {
485  }
486  fclose(fd);
487  return true;
488 }
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
RZ_API int rz_line_hist_add(const char *line)
Definition: dietline.c:382
string FILE
Definition: benchmark.py:21
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API RZ_BORROW char * rz_str_trim_tail(RZ_NONNULL char *str)
Removes whitespace characters (space, tab, newline etc.) from the end of a string and replaces them w...
Definition: str_trim.c:125
RZ_API FILE * rz_sys_fopen(const char *path, const char *mode)
Definition: sys.c:1815
static const z80_opcode fd[]
Definition: z80_tab.h:997

References fd, benchmark::FILE, NULL, path, RZ_LINE_BUFSIZE, rz_line_hist_add(), rz_return_val_if_fail, rz_str_trim_tail(), and rz_sys_fopen().

Referenced by rz_core_init().

◆ rz_line_hist_save()

RZ_API int rz_line_hist_save ( RZ_NONNULL const char *  path)

Save the history of commands executed until now to file path.

Parameters
pathPath of the history file, where commands executed in the shell will be saved
Returns
false(0) if it fails, true(!0) otherwise

Definition at line 497 of file dietline.c.

497  {
498  FILE *fd;
499  int i, ret = false;
500  if (RZ_STR_ISEMPTY(path)) {
501  return false;
502  }
503  char *p = (char *)rz_str_lastbut(path, RZ_SYS_DIR[0], NULL);
504  if (p) {
505  *p = 0;
506  if (!rz_sys_mkdirp(path)) {
507  RZ_LOG_ERROR("Could not save history into %s\n", path);
508  return false;
509  }
510  *p = RZ_SYS_DIR[0];
511  }
512  fd = rz_sys_fopen(path, "w");
513  if (fd != NULL) {
514  if (I.history.data) {
515  for (i = 0; i < I.history.index; i++) {
516  fputs(I.history.data[i], fd);
517  fputs("\n", fd);
518  }
519  fclose(fd);
520  ret = true;
521  } else {
522  fclose(fd);
523  }
524  }
525  return ret;
526 }
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API const char * rz_str_lastbut(const char *s, char ch, const char *but)
Definition: str.c:2670
RZ_API bool rz_sys_mkdirp(const char *dir)
Definition: sys.c:691

References fd, benchmark::FILE, I, i, NULL, p, path, RZ_LOG_ERROR, RZ_STR_ISEMPTY, rz_str_lastbut(), RZ_SYS_DIR, rz_sys_fopen(), and rz_sys_mkdirp().

Referenced by rz_history_save_handler(), and rz_main_rizin().

◆ rz_line_hist_up()

static int rz_line_hist_up ( void  )
static

Definition at line 410 of file dietline.c.

410  {
411  if (!I.cb_history_up) {
413  }
414  return I.cb_history_up(&I);
415 }

References I, rz_line_hist_cmd_down(), rz_line_hist_cmd_up(), and rz_line_set_hist_callback().

Referenced by __vi_mode(), and rz_line_readline_cb().

◆ rz_line_readchar_utf8()

static int rz_line_readchar_utf8 ( ut8 s,
int  slen 
)
static

Definition at line 158 of file dietline.c.

158  {
159 #if __WINDOWS__
160  return rz_line_readchar_win(s, slen);
161 #else
162  // TODO: add support for w32
163  ssize_t len, i;
164  if (slen < 1) {
165  return 0;
166  }
167  int ch = rz_cons_readchar();
168  if (ch == -1) {
169  return -1;
170  }
171  *s = ch;
172 #if 0
173  if ((t = read (0, s, 1)) != 1) {
174  return t;
175  }
176 #endif
177  *s = rz_cons_controlz(*s);
178  if (*s < 0x80) {
179  len = 1;
180  } else if ((s[0] & 0xe0) == 0xc0) {
181  len = 2;
182  } else if ((s[0] & 0xf0) == 0xe0) {
183  len = 3;
184  } else if ((s[0] & 0xf8) == 0xf0) {
185  len = 4;
186  } else {
187  return -1;
188  }
189  if (len > slen) {
190  return -1;
191  }
192  for (i = 1; i < len; i++) {
193  int ch = rz_cons_readchar();
194  if (ch != -1) {
195  s[i] = ch;
196  }
197  if ((s[i] & 0xc0) != 0x80) {
198  return -1;
199  }
200  }
201  return len;
202 #endif
203 }
RZ_API int rz_cons_controlz(int ch)
Definition: input.c:14
int ssize_t
Definition: sftypes.h:39
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115

References i, len, read(), rz_cons_controlz(), rz_cons_readchar(), and s.

Referenced by rz_line_readline_cb().

◆ rz_line_readline()

RZ_API const char* rz_line_readline ( void  )

Definition at line 913 of file dietline.c.

913  {
914  return rz_line_readline_cb(NULL, NULL);
915 }
RZ_API const char * rz_line_readline_cb(RzLineReadCallback cb, void *user)
Definition: dietline.c:1331

References NULL, and rz_line_readline_cb().

Referenced by __input_cb(), __rtr_shell(), rz_cons_hud(), rz_cons_less_str(), rz_core_fgets(), rz_core_visual_bit_editor(), rz_core_visual_cmd(), rz_core_visual_graph(), rz_core_visual_view_rop(), and rz_lang_prompt().

◆ rz_line_readline_cb()

RZ_API const char* rz_line_readline_cb ( RzLineReadCallback  cb,
void *  user 
)

Definition at line 1331 of file dietline.c.

1331  {
1332  int rows;
1333  const char *gcomp_line = "";
1334  static int gcomp_idx = 0;
1335  static bool yank_flag = 0;
1336  static int gcomp = 0;
1337  static int gcomp_is_rev = true;
1338  char buf[10];
1339 #if USE_UTF8
1340  int utflen;
1341 #endif
1342  int ch = 0, key, i = 0; /* grep completion */
1343  char *tmp_ed_cmd, prev = 0;
1344  int prev_buflen = -1;
1345  bool enable_yank_pop = false;
1346 
1347  RzCons *cons = rz_cons_singleton();
1348 
1349  if (!I.hud || (I.hud && !I.hud->activate)) {
1350  I.buffer.index = I.buffer.length = 0;
1351  I.buffer.data[0] = '\0';
1352  if (I.hud) {
1353  I.hud->activate = true;
1354  }
1355  }
1356  int mouse_status = cons->mouse;
1357  if (I.hud && I.hud->vi) {
1358  __vi_mode(&enable_yank_pop);
1359  goto _end;
1360  }
1361  if (I.contents) {
1362  memmove(I.buffer.data, I.contents,
1363  RZ_MIN(strlen(I.contents) + 1, RZ_LINE_BUFSIZE - 1));
1364  I.buffer.data[RZ_LINE_BUFSIZE - 1] = '\0';
1365  I.buffer.index = I.buffer.length = strlen(I.contents);
1366  }
1367  if (I.disable) {
1368  if (!fgets(I.buffer.data, RZ_LINE_BUFSIZE, stdin)) {
1369  return NULL;
1370  }
1371  return (*I.buffer.data) ? I.buffer.data : rz_line_nullstr;
1372  }
1373 
1374  memset(&buf, 0, sizeof buf);
1375  rz_cons_set_raw(1);
1376 
1377  if (I.echo) {
1378  __print_prompt();
1379  }
1381  rz_cons_enable_mouse(I.hud);
1382  for (;;) {
1383  yank_flag = 0;
1384  if (rz_cons_is_breaked()) {
1385  break;
1386  }
1387  I.buffer.data[I.buffer.length] = '\0';
1388  if (cb) {
1389  int cbret = cb(user, I.buffer.data);
1390  if (cbret == 0) {
1391  I.buffer.data[0] = 0;
1392  I.buffer.length = 0;
1393  }
1394  }
1395 #if USE_UTF8
1396  utflen = rz_line_readchar_utf8((ut8 *)buf, sizeof(buf));
1397  if (utflen < 1) {
1399  return NULL;
1400  }
1401  buf[utflen] = 0;
1402 #else
1403 #if __WINDOWS__
1404  {
1405  int len = rz_line_readchar_win((ut8 *)buf, sizeof(buf));
1406  if (len < 1) {
1408  return NULL;
1409  }
1410  buf[len] = 0;
1411  }
1412 #else
1413  ch = rz_cons_readchar();
1414  if (ch == -1) {
1416  return NULL;
1417  }
1418  buf[0] = ch;
1419 #endif
1420 #endif
1421  bool o_do_setup_match = I.history.do_setup_match;
1422  I.history.do_setup_match = true;
1423  if (I.echo) {
1424  rz_cons_clear_line(0);
1425  }
1426  (void)rz_cons_get_size(&rows);
1427  switch (*buf) {
1428  case 0: // control-space
1429  /* ignore atm */
1430  break;
1431  case 1: // ^A
1432  if (gcomp) {
1433  strcpy(I.buffer.data, gcomp_line);
1434  I.buffer.length = strlen(I.buffer.data);
1435  I.buffer.index = 0;
1436  gcomp = false;
1437  }
1438  I.buffer.index = 0;
1439  break;
1440  case 2: // ^b // emacs left
1442  break;
1443  case 5: // ^E
1444  if (gcomp) {
1445  strcpy(I.buffer.data, gcomp_line);
1446  I.buffer.index = strlen(I.buffer.data);
1447  I.buffer.length = I.buffer.index;
1448  gcomp = false;
1449  } else if (prev == 24) { // ^X = 0x18
1450  I.buffer.data[I.buffer.length] = 0; // probably unnecessary
1451  tmp_ed_cmd = I.cb_editor(I.user, I.buffer.data);
1452  if (tmp_ed_cmd) {
1453  /* copied from yank (case 25) */
1454  I.buffer.length = strlen(tmp_ed_cmd);
1455  if (I.buffer.length < RZ_LINE_BUFSIZE) {
1456  I.buffer.index = I.buffer.length;
1457  strncpy(I.buffer.data, tmp_ed_cmd, RZ_LINE_BUFSIZE - 1);
1458  I.buffer.data[RZ_LINE_BUFSIZE - 1] = '\0';
1459  } else {
1460  I.buffer.length -= strlen(tmp_ed_cmd);
1461  }
1462  free(tmp_ed_cmd);
1463  }
1464  } else {
1465  I.buffer.index = I.buffer.length;
1466  }
1467  break;
1468  case 3: // ^C
1469  if (I.hud) {
1470  I.hud->activate = false;
1471  I.hud->current_entry_n = -1;
1472  }
1473  if (I.echo) {
1474  eprintf("^C\n");
1475  }
1476  I.buffer.index = I.buffer.length = 0;
1477  *I.buffer.data = '\0';
1478  gcomp = 0;
1479  goto _end;
1480  case 4: // ^D
1481  if (!I.buffer.data[0]) { /* eof */
1482  if (I.echo) {
1483  __print_prompt();
1484  printf("\n");
1485  }
1486  rz_cons_set_raw(false);
1488  return NULL;
1489  }
1490  if (I.buffer.index < I.buffer.length) {
1492  }
1493  break;
1494  case 11: // ^K
1495  I.buffer.data[I.buffer.index] = '\0';
1496  I.buffer.length = I.buffer.index;
1497  break;
1498  case 6: // ^f // emacs right
1500  break;
1501  case 12: // ^L -- right
1503  if (I.echo) {
1504  eprintf("\x1b[2J\x1b[0;0H");
1505  }
1506  fflush(stdout);
1507  break;
1508  case 18: // ^R -- reverse-search
1509  if (gcomp) {
1510  gcomp_idx++;
1511  }
1512  gcomp_is_rev = true;
1513  gcomp = 1;
1514  break;
1515  case 19: // ^S -- forward-search
1516  if (gcomp) {
1517  if (gcomp_idx > 0) {
1518  gcomp_idx--;
1519  }
1520  gcomp_is_rev = false;
1521  } else {
1523  }
1524  break;
1525  case 21: // ^U - cut
1526  free(I.clipboard);
1527  I.clipboard = strdup(I.buffer.data);
1528  rz_line_clipboard_push(I.clipboard);
1529  I.buffer.data[0] = '\0';
1530  I.buffer.length = 0;
1531  I.buffer.index = 0;
1532  break;
1533 #if __WINDOWS__
1534  case 22: // ^V - Paste from windows clipboard
1535  {
1536  HANDLE hClipBoard;
1537  PTCHAR clipText;
1538  if (OpenClipboard(NULL)) {
1539  hClipBoard = GetClipboardData(CF_UNICODETEXT);
1540  if (hClipBoard) {
1541  clipText = GlobalLock(hClipBoard);
1542  if (clipText) {
1543  char *txt = rz_utf16_to_utf8(clipText);
1544  if (!txt) {
1545  RZ_LOG_ERROR("Failed to allocate memory\n");
1546  break;
1547  }
1548  int len = strlen(txt);
1549  I.buffer.length += len;
1550  if (I.buffer.length < RZ_LINE_BUFSIZE) {
1551  I.buffer.index = I.buffer.length;
1552  strcat(I.buffer.data, txt);
1553  } else {
1554  I.buffer.length -= len;
1555  }
1556  free(txt);
1557  }
1558  GlobalUnlock(hClipBoard);
1559  }
1560  CloseClipboard();
1561  }
1562  } break;
1563 #endif
1564  case 23: // ^W ^w unix-word-rubout
1565  unix_word_rubout();
1566  break;
1567  case 24: // ^X
1568  if (I.buffer.index > 0) {
1569  strncpy(I.buffer.data, I.buffer.data + I.buffer.index, I.buffer.length);
1570  I.buffer.length -= I.buffer.index;
1571  I.buffer.index = 0;
1572  }
1573  break;
1574  case 25: // ^Y - paste
1575  paste(&enable_yank_pop);
1576  yank_flag = 1;
1577  break;
1578  case 29: // ^^ - rotate kill ring
1579  rotate_kill_ring(&enable_yank_pop);
1580  yank_flag = enable_yank_pop ? 1 : 0;
1581  break;
1582  case 20: // ^t Kill from point to the end of the current word,
1584  break;
1585  case 15: // ^o kill backward
1587  break;
1588  case 14: // ^n
1589  if (I.hud) {
1590  if (I.hud->top_entry_n + 1 < I.hud->current_entry_n) {
1591  I.hud->top_entry_n++;
1592  }
1593  } else if (I.sel_widget) {
1596  } else if (gcomp) {
1597  if (gcomp_idx > 0) {
1598  gcomp_idx--;
1599  }
1600  } else {
1601  I.history.do_setup_match = o_do_setup_match;
1603  }
1604  break;
1605  case 16: // ^p
1606  if (I.hud) {
1607  if (I.hud->top_entry_n >= 0) {
1608  I.hud->top_entry_n--;
1609  }
1610  } else if (I.sel_widget) {
1613  } else if (gcomp) {
1614  gcomp_idx++;
1615  } else {
1616  I.history.do_setup_match = o_do_setup_match;
1617  rz_line_hist_up();
1618  }
1619  break;
1620  case 27: // esc-5b-41-00-00 alt/meta key
1621 #if __WINDOWS__
1622  if (I.vtmode != RZ_VIRT_TERM_MODE_COMPLETE) {
1623  memmove(buf, buf + 1, strlen(buf));
1624  if (!buf[0]) {
1625  buf[0] = -1;
1626  }
1627  } else {
1628 #endif
1629  buf[0] = rz_cons_readchar_timeout(50);
1630 #if __WINDOWS__
1631  }
1632 #endif
1633  switch (buf[0]) {
1634  case 127: // alt+bkspace
1636  break;
1637  case 27: // escape key, goto vi mode
1638  if (I.enable_vi_mode) {
1639  if (I.hud) {
1640  I.hud->vi = true;
1641  }
1642  __vi_mode(&enable_yank_pop);
1643  };
1644  if (I.sel_widget) {
1646  }
1647  break;
1648  case 1: // begin
1649  I.buffer.index = 0;
1650  break;
1651  case 5: // end
1652  I.buffer.index = I.buffer.length;
1653  break;
1654  case 'B':
1655  case 'b':
1656  for (i = I.buffer.index - 2; i >= 0; i--) {
1657  if (is_word_break_char(I.buffer.data[i], MINOR_BREAK) && !is_word_break_char(I.buffer.data[i + 1], MINOR_BREAK)) {
1658  I.buffer.index = i + 1;
1659  break;
1660  }
1661  }
1662  if (i < 0) {
1663  I.buffer.index = 0;
1664  }
1665  break;
1666  case 'D':
1667  case 'd':
1669  break;
1670  case 'F':
1671  case 'f':
1672  // next word
1673  for (i = I.buffer.index + 1; i < I.buffer.length; i++) {
1674  if (!is_word_break_char(I.buffer.data[i], MINOR_BREAK) && is_word_break_char(I.buffer.data[i - 1], MINOR_BREAK)) {
1675  I.buffer.index = i;
1676  break;
1677  }
1678  }
1679  if (i >= I.buffer.length) {
1680  I.buffer.index = I.buffer.length;
1681  }
1682  break;
1683  default:
1684  if (I.vtmode == RZ_VIRT_TERM_MODE_COMPLETE) {
1685  buf[1] = rz_cons_readchar_timeout(50);
1686  if (buf[1] == -1) { // alt+e
1688  __print_prompt();
1689  continue;
1690  }
1691  }
1692  if (buf[0] == 0x5b) { // [
1693  switch (buf[1]) {
1694  case '3': // supr
1696  if (I.vtmode == RZ_VIRT_TERM_MODE_COMPLETE) {
1697  buf[1] = rz_cons_readchar();
1698  if (buf[1] == -1) {
1700  return NULL;
1701  }
1702  }
1703  break;
1704  case '5': // pag up
1705  if (I.vtmode == RZ_VIRT_TERM_MODE_COMPLETE) {
1706  buf[1] = rz_cons_readchar();
1707  }
1708  if (I.hud) {
1709  I.hud->top_entry_n -= (rows - 1);
1710  if (I.hud->top_entry_n < 0) {
1711  I.hud->top_entry_n = 0;
1712  }
1713  }
1714  if (I.sel_widget) {
1715  selection_widget_up(RZ_MIN(I.sel_widget->h, RZ_SELWIDGET_MAXH));
1717  }
1718  break;
1719  case '6': // pag down
1720  if (I.vtmode == RZ_VIRT_TERM_MODE_COMPLETE) {
1721  buf[1] = rz_cons_readchar();
1722  }
1723  if (I.hud) {
1724  I.hud->top_entry_n += (rows - 1);
1725  if (I.hud->top_entry_n >= I.hud->current_entry_n) {
1726  I.hud->top_entry_n = I.hud->current_entry_n - 1;
1727  }
1728  }
1729  if (I.sel_widget) {
1732  }
1733  break;
1734  case '9': // handle mouse wheel
1735  key = rz_cons_readchar();
1736  cons->mouse_event = 1;
1737  if (key == '6') { // up
1738  if (I.hud && I.hud->top_entry_n + 1 < I.hud->current_entry_n) {
1739  I.hud->top_entry_n--;
1740  }
1741  } else if (key == '7') { // down
1742  if (I.hud && I.hud->top_entry_n >= 0) {
1743  I.hud->top_entry_n++;
1744  }
1745  }
1746  while (rz_cons_readchar() != 'M') {
1747  }
1748  break;
1749  /* arrows */
1750  case 'A': // up arrow
1751  if (I.hud) {
1752  if (I.hud->top_entry_n > 0) {
1753  I.hud->top_entry_n--;
1754  }
1755  } else if (I.sel_widget) {
1758  } else if (gcomp) {
1759  gcomp_idx++;
1760  } else {
1761  I.history.do_setup_match = o_do_setup_match;
1762  if (rz_line_hist_up() == -1) {
1764  return NULL;
1765  }
1766  }
1767  break;
1768  case 'B': // down arrow
1769  if (I.hud) {
1770  if (I.hud->top_entry_n + 1 < I.hud->current_entry_n) {
1771  I.hud->top_entry_n++;
1772  }
1773  } else if (I.sel_widget) {
1776  } else if (gcomp) {
1777  if (gcomp_idx > 0) {
1778  gcomp_idx--;
1779  }
1780  } else {
1781  I.history.do_setup_match = o_do_setup_match;
1782  if (rz_line_hist_down() == -1) {
1784  return NULL;
1785  }
1786  }
1787  break;
1788  case 'C': // right arrow
1790  break;
1791  case 'D': // left arrow
1793  break;
1794  case 0x31: // control + arrow
1795  if (I.vtmode == RZ_VIRT_TERM_MODE_COMPLETE) {
1796  ch = rz_cons_readchar();
1797  if (ch == 0x7e) { // HOME in screen/tmux
1798  // corresponding END is 0x34 below (the 0x7e is ignored there)
1799  I.buffer.index = 0;
1800  break;
1801  }
1802  rz_cons_readchar();
1803  ch = rz_cons_readchar();
1804  }
1805 #if __WINDOWS__
1806  else {
1807  ch = buf[2];
1808  }
1809 #endif
1810  int fkey = ch - '0';
1811  switch (ch) {
1812  case 0x41:
1813  // first
1814  I.buffer.index = 0;
1815  break;
1816  case 0x44:
1817  // previous word
1818  for (i = I.buffer.index; i > 0; i--) {
1819  if (I.buffer.data[i] == ' ') {
1820  I.buffer.index = i - 1;
1821  break;
1822  }
1823  }
1824  if (I.buffer.data[i] != ' ') {
1825  I.buffer.index = 0;
1826  }
1827  break;
1828  case 0x42:
1829  // end
1830  I.buffer.index = I.buffer.length;
1831  break;
1832  case 0x43:
1833  // next word
1834  for (i = I.buffer.index; i < I.buffer.length; i++) {
1835  if (I.buffer.data[i] == ' ') {
1836  I.buffer.index = i + 1;
1837  break;
1838  }
1839  }
1840  if (I.buffer.data[i] != ' ') {
1841  I.buffer.index = I.buffer.length;
1842  }
1843  break;
1844  default:
1845  if (I.vtmode == RZ_VIRT_TERM_MODE_COMPLETE) {
1846  if (I.cb_fkey) {
1847  I.cb_fkey(I.user, fkey);
1848  }
1849  }
1850  break;
1851  }
1852  rz_cons_set_raw(1);
1853  break;
1854  case 0x37: // HOME xrvt-unicode
1855  rz_cons_readchar();
1856  /* fall through */
1857  case 0x48: // HOME
1858  if (I.sel_widget) {
1859  selection_widget_up(I.sel_widget->options_len - 1);
1861  break;
1862  }
1863  I.buffer.index = 0;
1864  break;
1865  case 0x34: // END
1866  case 0x38: // END xrvt-unicode
1867  rz_cons_readchar();
1868  /* fall through */
1869  case 0x46: // END
1870  if (I.sel_widget) {
1871  selection_widget_down(I.sel_widget->options_len - 1);
1873  break;
1874  }
1875  I.buffer.index = I.buffer.length;
1876  break;
1877  }
1878  }
1879  }
1880  break;
1881  case 8:
1882  case 127:
1883  if (I.hud && (I.buffer.index == 0)) {
1884  I.hud->activate = false;
1885  I.hud->current_entry_n = -1;
1886  }
1888  break;
1889  case 9: // TAB tab
1890  if (I.sel_widget) {
1892  I.sel_widget->complete_common = true;
1894  }
1895  if (I.hud) {
1896  if (I.hud->top_entry_n + 1 < I.hud->current_entry_n) {
1897  I.hud->top_entry_n++;
1898  } else {
1899  I.hud->top_entry_n = 0;
1900  }
1901  } else {
1903  rz_cons_flush();
1904  }
1905  break;
1906  case 10: // ^J -- ignore
1907  case 13: // enter
1908  if (I.hud) {
1909  I.hud->activate = false;
1910  break;
1911  }
1912  if (I.sel_widget) {
1914  break;
1915  }
1916  if (gcomp && I.buffer.length > 0) {
1917  strncpy(I.buffer.data, gcomp_line, RZ_LINE_BUFSIZE - 1);
1918  I.buffer.data[RZ_LINE_BUFSIZE - 1] = '\0';
1919  I.buffer.length = strlen(gcomp_line);
1920  }
1921  gcomp_idx = gcomp = 0;
1922  goto _end;
1923  default:
1924  if (gcomp) {
1925  gcomp++;
1926  }
1927  {
1928 #if USE_UTF8
1929  int size = utflen;
1930 #else
1931  int size = 1;
1932 #endif
1933  if (I.buffer.length + size >= RZ_LINE_BUFSIZE) {
1934  break;
1935  }
1936  }
1937  if (I.buffer.index < I.buffer.length) {
1938 #if USE_UTF8
1939  if ((I.buffer.length + utflen) < sizeof(I.buffer.data)) {
1940  I.buffer.length += utflen;
1941  for (i = I.buffer.length; i > I.buffer.index; i--) {
1942  I.buffer.data[i] = I.buffer.data[i - utflen];
1943  }
1944  memcpy(I.buffer.data + I.buffer.index, buf, utflen);
1945  }
1946 #else
1947  for (i = ++I.buffer.length; i > I.buffer.index; i--) {
1948  I.buffer.data[i] = I.buffer.data[i - 1];
1949  }
1950  I.buffer.data[I.buffer.index] = buf[0];
1951 #endif
1952  } else {
1953 #if USE_UTF8
1954  if ((I.buffer.length + utflen) < sizeof(I.buffer.data)) {
1955  memcpy(I.buffer.data + I.buffer.length, buf, utflen);
1956  I.buffer.length += utflen;
1957  }
1958  I.buffer.data[I.buffer.length] = '\0';
1959 #else
1960  I.buffer.data[I.buffer.length] = buf[0];
1961  I.buffer.length++;
1962  if (I.buffer.length > (RZ_LINE_BUFSIZE - 1)) {
1963  I.buffer.length--;
1964  }
1965  I.buffer.data[I.buffer.length] = '\0';
1966 #endif
1967  }
1968 #if USE_UTF8
1969  if ((I.buffer.index + utflen) <= I.buffer.length) {
1970  I.buffer.index += utflen;
1971  }
1972 #else
1973  if (I.buffer.index < I.buffer.length) {
1974  I.buffer.index++;
1975  }
1976 #endif
1977  break;
1978  }
1979  if (I.sel_widget && I.buffer.length != prev_buflen) {
1980  prev_buflen = I.buffer.length;
1982  rz_cons_flush();
1983  }
1984  prev = buf[0];
1985  if (I.echo) {
1986  if (gcomp) {
1987  gcomp_line = "";
1988  int counter = 0;
1989  if (I.history.data != NULL) {
1990  for (i = I.history.size - 1; i >= 0; i--) {
1991  if (!I.history.data[i]) {
1992  continue;
1993  }
1994  if (strstr(I.history.data[i], I.buffer.data)) {
1995  gcomp_line = I.history.data[i];
1996  if (++counter > gcomp_idx) {
1997  break;
1998  }
1999  }
2000  if (i == 0) {
2001  if (gcomp_is_rev) {
2002  gcomp_idx--;
2003  }
2004  }
2005  }
2006  }
2007  const char *prompt = gcomp_is_rev ? "reverse-i-search" : "forward-i-search";
2008  printf("\r (%s (%s)): %s\r", prompt, I.buffer.data, gcomp_line);
2009  } else {
2010  __print_prompt();
2011  }
2012  fflush(stdout);
2013  }
2014  enable_yank_pop = yank_flag ? 1 : 0;
2015  if (I.hud) {
2016  goto _end;
2017  }
2018  }
2019 _end:
2021  rz_cons_set_raw(0);
2022  rz_cons_enable_mouse(mouse_status);
2023  if (I.echo) {
2024  printf("\r%s%s\n", I.prompt, I.buffer.data);
2025  fflush(stdout);
2026  }
2027 
2028  RZ_FREE(I.sel_widget);
2029 
2030  // should be here or not?
2031  if (!memcmp(I.buffer.data, "!history", 8)) {
2032  // if (I.buffer.data[0]=='!' && I.buffer.data[1]=='\0') {
2034  return rz_line_nullstr;
2035  }
2036  return I.buffer.data[0] != '\0' ? I.buffer.data : rz_line_nullstr;
2037 }
RZ_API void rz_cons_set_raw(bool is_raw)
Definition: cons.c:1617
RZ_API bool rz_cons_enable_mouse(const bool enable)
Definition: cons.c:500
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
Definition: cons.c:357
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
static void selection_widget_select(void)
Definition: dietline.c:652
static void selection_widget_down(int steps)
Definition: dietline.c:605
static void selection_widget_erase(void)
Definition: dietline.c:633
RZ_API int rz_line_hist_list(void)
Definition: dietline.c:440
static char * rz_line_nullstr
Definition: dietline.c:22
RZ_API void rz_line_autocomplete(void)
Definition: dietline.c:775
static void unix_word_rubout(void)
Definition: dietline.c:102
static void selection_widget_draw(void)
Definition: dietline.c:533
static void __vi_mode(bool *enable_yank_pop)
Definition: dietline.c:1118
static void selection_widget_up(int steps)
Definition: dietline.c:583
static int rz_line_readchar_utf8(ut8 *s, int slen)
Definition: dietline.c:158
static void rotate_kill_ring(bool *enable_yank_pop)
Definition: dietline.c:917
RZ_API int rz_cons_readchar_timeout(ut32 usec)
Definition: input.c:560
voidpf void uLong size
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
@ RZ_VIRT_TERM_MODE_COMPLETE
All the sequences goes through VT (Windows Terminal, mintty, all OSs)
Definition: rz_cons.h:451
#define RZ_SELWIDGET_MAXH
Definition: rz_cons.h:996
int mouse_event
Definition: rz_cons.h:524
int mouse
Definition: rz_cons.h:551
int64_t counter
Definition: main.c:4
DWORD * HANDLE
static const char * cb[]
Definition: z80_tab.h:176

References __delete_next_char(), __delete_prev_char(), __move_cursor_left(), __move_cursor_right(), __print_prompt(), __vi_mode(), backward_kill_word(), cb, counter, eprintf, free(), HANDLE, I, i, is_word_break_char(), key, kill_word(), len, memcpy(), memset(), MINOR_BREAK, rz_cons_t::mouse, rz_cons_t::mouse_event, NULL, paste(), printf(), prompt(), rotate_kill_ring(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_clear_line(), rz_cons_enable_mouse(), rz_cons_flush(), rz_cons_get_size(), rz_cons_is_breaked(), rz_cons_readchar(), rz_cons_readchar_timeout(), rz_cons_set_raw(), rz_cons_singleton(), RZ_FREE, rz_line_autocomplete(), RZ_LINE_BUFSIZE, rz_line_clipboard_push(), rz_line_hist_down(), rz_line_hist_list(), rz_line_hist_up(), rz_line_nullstr, rz_line_readchar_utf8(), RZ_LOG_ERROR, RZ_MIN, RZ_SELWIDGET_MAXH, RZ_VIRT_TERM_MODE_COMPLETE, selection_widget_down(), selection_widget_draw(), selection_widget_erase(), selection_widget_select(), selection_widget_up(), strdup(), and unix_word_rubout().

Referenced by rz_core_visual_asm(), and rz_line_readline().

◆ rz_line_set_hist_callback()

RZ_API int rz_line_set_hist_callback ( RzLine line,
RzLineHistoryUpCb  up,
RzLineHistoryDownCb  down 
)

Definition at line 292 of file dietline.c.

292  {
293  line->cb_history_up = up;
294  line->cb_history_down = down;
295  line->offset_hist_index = 0;
296  line->file_hist_index = 0;
297  line->sdbshell_hist_iter = rz_list_head(line->sdbshell_hist);
298  return 1;
299 }

References setup::line.

Referenced by __break_points_cb(), __open_file_cb(), rz_cmd_kuery(), rz_core_visual_offset(), rz_line_hist_down(), rz_line_hist_up(), and visual_offset().

◆ selection_widget_down()

static void selection_widget_down ( int  steps)
static

Definition at line 605 of file dietline.c.

605  {
606  RzSelWidget *sel_widget = I.sel_widget;
607  if (sel_widget) {
608  if (sel_widget->direction == RZ_SELWIDGET_DIR_UP) {
609  sel_widget->selection = RZ_MAX(sel_widget->selection - steps, 0);
610  if (steps == 1) {
611  sel_widget->scroll = RZ_MAX(sel_widget->scroll - 1, 0);
612  } else if (sel_widget->selection - sel_widget->scroll <= 0) {
613  sel_widget->scroll = sel_widget->selection;
614  }
615  } else {
616  int height = RZ_MIN(sel_widget->h, RZ_SELWIDGET_MAXH - 1);
617  sel_widget->selection = RZ_MIN(sel_widget->selection + steps, sel_widget->options_len - 1);
618  if (steps == 1) {
619  sel_widget->scroll = RZ_MIN(sel_widget->scroll + 1, RZ_SELWIDGET_MAXH - 1);
620  } else if (sel_widget->selection + (height - sel_widget->scroll) > sel_widget->options_len - 1) {
621  sel_widget->scroll = height - (sel_widget->options_len - 1 - sel_widget->selection);
622  }
623  }
624  }
625 }
#define RZ_SELWIDGET_DIR_UP
Definition: rz_cons.h:998
int height
Definition: main.c:10

References rz_selection_widget_t::direction, rz_selection_widget_t::h, height, I, rz_selection_widget_t::options_len, RZ_MAX, RZ_MIN, RZ_SELWIDGET_DIR_UP, RZ_SELWIDGET_MAXH, rz_selection_widget_t::scroll, and rz_selection_widget_t::selection.

Referenced by rz_line_readline_cb().

◆ selection_widget_draw()

static void selection_widget_draw ( void  )
static

Definition at line 533 of file dietline.c.

533  {
534  RzCons *cons = rz_cons_singleton();
535  RzSelWidget *sel_widget = I.sel_widget;
536  int y, pos_y, pos_x = rz_str_ansi_len(I.prompt);
537  sel_widget->h = RZ_MIN(sel_widget->h, RZ_SELWIDGET_MAXH);
538  for (y = 0; y < sel_widget->options_len; y++) {
539  sel_widget->w = RZ_MAX(sel_widget->w, strlen(sel_widget->options[y]));
540  }
541  if (sel_widget->direction == RZ_SELWIDGET_DIR_UP) {
542  pos_y = cons->rows;
543  } else {
544  pos_y = rz_cons_get_cur_line();
545  if (pos_y + sel_widget->h > cons->rows) {
546  printf("%s\n", rz_str_pad('\n', sel_widget->h));
547  pos_y = cons->rows - sel_widget->h - 1;
548  }
549  }
550  sel_widget->w = RZ_MIN(sel_widget->w, RZ_SELWIDGET_MAXW);
551 
552  char *background_color = cons->context->color_mode ? cons->context->pal.widget_bg : Color_INVERT_RESET;
553  char *selected_color = cons->context->color_mode ? cons->context->pal.widget_sel : Color_INVERT;
554  bool scrollbar = sel_widget->options_len > RZ_SELWIDGET_MAXH;
555  int scrollbar_y = 0, scrollbar_l = 0;
556  if (scrollbar) {
557  scrollbar_y = (RZ_SELWIDGET_MAXH * (sel_widget->selection - sel_widget->scroll)) / sel_widget->options_len;
558  scrollbar_l = (RZ_SELWIDGET_MAXH * RZ_SELWIDGET_MAXH) / sel_widget->options_len;
559  }
560 
561  for (y = 0; y < sel_widget->h; y++) {
562  if (sel_widget->direction == RZ_SELWIDGET_DIR_UP) {
563  rz_cons_gotoxy(pos_x + 1, pos_y - y - 1);
564  } else {
565  rz_cons_gotoxy(pos_x + 1, pos_y + y + 1);
566  }
567  int scroll = RZ_MAX(0, sel_widget->selection - sel_widget->scroll);
568  const char *option = y < sel_widget->options_len ? sel_widget->options[y + scroll] : "";
569  rz_cons_printf("%s", sel_widget->selection == y + scroll ? selected_color : background_color);
570  rz_cons_printf("%-*.*s", sel_widget->w, sel_widget->w, option);
571  if (scrollbar && RZ_BETWEEN(scrollbar_y, y, scrollbar_y + scrollbar_l)) {
573  } else {
574  rz_cons_memcat(" ", 1);
575  }
576  }
577 
578  rz_cons_gotoxy(pos_x + I.buffer.length, pos_y);
580  rz_cons_flush();
581 }
RZ_API int rz_cons_memcat(const char *str, int len)
Definition: cons.c:1224
RZ_API int rz_cons_get_cur_line(void)
Definition: cons.c:387
#define RZ_SELWIDGET_MAXW
Definition: rz_cons.h:997
#define Color_RESET_BG
Definition: rz_cons.h:619
#define Color_INVERT_RESET
Definition: rz_cons.h:607
#define Color_INVERT
Definition: rz_cons.h:606
RZ_API const char * rz_str_pad(const char ch, int len)
Definition: str.c:3236
#define RZ_BETWEEN(x, y, z)
Definition: getopt.h:84
const char ** options
Definition: rz_cons.h:1002

References Color_INVERT, Color_INVERT_RESET, rz_cons_context_t::color_mode, Color_RESET_BG, rz_cons_t::context, rz_selection_widget_t::direction, rz_selection_widget_t::h, I, rz_selection_widget_t::options, rz_selection_widget_t::options_len, rz_cons_context_t::pal, printf(), rz_cons_t::rows, RZ_BETWEEN, rz_cons_flush(), rz_cons_get_cur_line(), rz_cons_gotoxy(), rz_cons_memcat(), rz_cons_printf(), rz_cons_singleton(), RZ_MAX, RZ_MIN, RZ_SELWIDGET_DIR_UP, RZ_SELWIDGET_MAXH, RZ_SELWIDGET_MAXW, rz_str_ansi_len(), rz_str_pad(), rz_selection_widget_t::scroll, rz_selection_widget_t::selection, rz_selection_widget_t::w, rz_cons_printable_palette_t::widget_bg, and rz_cons_printable_palette_t::widget_sel.

Referenced by rz_line_readline_cb(), selection_widget_erase(), and selection_widget_update().

◆ selection_widget_erase()

static void selection_widget_erase ( void  )
static

Definition at line 633 of file dietline.c.

633  {
634  RzSelWidget *sel_widget = I.sel_widget;
635  if (sel_widget) {
636  sel_widget->options_len = 0;
637  sel_widget->selection = -1;
639  RZ_FREE(I.sel_widget);
640  RzCons *cons = rz_cons_singleton();
641  if (cons->event_resize && cons->event_data) {
642  cons->event_resize(cons->event_data);
643  RzCore *core = (RzCore *)(cons->user);
644  if (core) {
645  cons->cb_task_oneshot(&core->tasks, print_rline_task, core);
646  }
647  }
649  }
650 }
static void print_rline_task(void *_core)
Definition: dietline.c:627
#define RZ_CONS_CLEAR_FROM_CURSOR_TO_END
Definition: rz_cons.h:595
RzConsEvent event_resize
Definition: rz_cons.h:522
void * event_data
Definition: rz_cons.h:523
RzConsQueueTaskOneshot cb_task_oneshot
Definition: rz_cons.h:531
void * user
Definition: rz_cons.h:534
RzCoreTaskScheduler tasks
Definition: rz_core.h:362

References rz_cons_t::cb_task_oneshot, rz_cons_t::event_data, rz_cons_t::event_resize, I, rz_selection_widget_t::options_len, print_rline_task(), printf(), RZ_CONS_CLEAR_FROM_CURSOR_TO_END, rz_cons_singleton(), RZ_FREE, rz_selection_widget_t::selection, selection_widget_draw(), rz_core_t::tasks, and rz_cons_t::user.

Referenced by rz_line_readline_cb(), selection_widget_select(), and selection_widget_update().

◆ selection_widget_select()

static void selection_widget_select ( void  )
static

Definition at line 652 of file dietline.c.

652  {
653  RzSelWidget *sel_widget = I.sel_widget;
654  if (sel_widget && sel_widget->selection < sel_widget->options_len) {
655  char *sp = strchr(I.buffer.data, ' ');
656  if (sp) {
657  int delta = sp - I.buffer.data + 1;
658  I.buffer.length = RZ_MIN(delta + strlen(sel_widget->options[sel_widget->selection]), RZ_LINE_BUFSIZE - 1);
659  memcpy(I.buffer.data + delta, sel_widget->options[sel_widget->selection], strlen(sel_widget->options[sel_widget->selection]));
660  I.buffer.index = I.buffer.length;
661  return;
662  }
663  I.buffer.length = RZ_MIN(strlen(sel_widget->options[sel_widget->selection]), RZ_LINE_BUFSIZE - 1);
664  memcpy(I.buffer.data, sel_widget->options[sel_widget->selection], I.buffer.length);
665  I.buffer.data[I.buffer.length] = '\0';
666  I.buffer.index = I.buffer.length;
668  }
669 }
static st64 delta
Definition: vmenus.c:2425
static int sp
Definition: z80asm.c:91

References delta, I, memcpy(), rz_selection_widget_t::options, rz_selection_widget_t::options_len, RZ_LINE_BUFSIZE, RZ_MIN, rz_selection_widget_t::selection, selection_widget_erase(), and sp.

Referenced by rz_line_readline_cb().

◆ selection_widget_up()

static void selection_widget_up ( int  steps)
static

Definition at line 583 of file dietline.c.

583  {
584  RzSelWidget *sel_widget = I.sel_widget;
585  if (sel_widget) {
586  if (sel_widget->direction == RZ_SELWIDGET_DIR_UP) {
587  int height = RZ_MIN(sel_widget->h, RZ_SELWIDGET_MAXH - 1);
588  sel_widget->selection = RZ_MIN(sel_widget->selection + steps, sel_widget->options_len - 1);
589  if (steps == 1) {
590  sel_widget->scroll = RZ_MIN(sel_widget->scroll + 1, RZ_SELWIDGET_MAXH - 1);
591  } else if (sel_widget->selection + (height - sel_widget->scroll) > sel_widget->options_len - 1) {
592  sel_widget->scroll = height - (sel_widget->options_len - 1 - sel_widget->selection);
593  }
594  } else {
595  sel_widget->selection = RZ_MAX(sel_widget->selection - steps, 0);
596  if (steps == 1) {
597  sel_widget->scroll = RZ_MAX(sel_widget->scroll - 1, 0);
598  } else if (sel_widget->selection - sel_widget->scroll <= 0) {
599  sel_widget->scroll = sel_widget->selection;
600  }
601  }
602  }
603 }

References rz_selection_widget_t::direction, rz_selection_widget_t::h, height, I, rz_selection_widget_t::options_len, RZ_MAX, RZ_MIN, RZ_SELWIDGET_DIR_UP, RZ_SELWIDGET_MAXH, rz_selection_widget_t::scroll, and rz_selection_widget_t::selection.

Referenced by rz_line_readline_cb().

◆ selection_widget_update()

static void selection_widget_update ( void  )
static

Definition at line 671 of file dietline.c.

671  {
672  int argc = rz_pvector_len(&I.completion.args);
673  const char **argv = (const char **)rz_pvector_data(&I.completion.args);
674  if (argc == 0 || (argc == 1 && I.buffer.length >= strlen(argv[0]))) {
676  return;
677  }
678  if (!I.sel_widget) {
679  RzSelWidget *sel_widget = RZ_NEW0(RzSelWidget);
680  I.sel_widget = sel_widget;
681  }
682  I.sel_widget->scroll = 0;
683  I.sel_widget->selection = 0;
684  I.sel_widget->options_len = argc;
685  I.sel_widget->options = argv;
686  I.sel_widget->h = RZ_MAX(I.sel_widget->h, I.sel_widget->options_len);
687 
688  if (I.prompt_type == RZ_LINE_PROMPT_DEFAULT) {
689  I.sel_widget->direction = RZ_SELWIDGET_DIR_DOWN;
690  } else {
691  I.sel_widget->direction = RZ_SELWIDGET_DIR_UP;
692  }
694  rz_cons_flush();
695  return;
696 }
#define RZ_SELWIDGET_DIR_DOWN
Definition: rz_cons.h:999
#define RZ_NEW0(x)
Definition: rz_types.h:284

References argv, I, rz_cons_flush(), RZ_LINE_PROMPT_DEFAULT, RZ_MAX, RZ_NEW0, rz_pvector_data(), rz_pvector_len(), RZ_SELWIDGET_DIR_DOWN, RZ_SELWIDGET_DIR_UP, selection_widget_draw(), and selection_widget_erase().

Referenced by rz_line_autocomplete().

◆ setup_hist_match()

static void setup_hist_match ( RzLine line)
static

Definition at line 306 of file dietline.c.

306  {
307  if (line->history.do_setup_match) {
308  RZ_FREE(line->history.match);
309  if (*line->buffer.data) {
310  line->history.match = strdup(line->buffer.data);
311  }
312  }
313  line->history.do_setup_match = false;
314 }

References setup::line, RZ_FREE, and strdup().

Referenced by rz_line_hist_cmd_down(), and rz_line_hist_cmd_up().

◆ unix_word_rubout()

static void unix_word_rubout ( void  )
static

Definition at line 102 of file dietline.c.

102  {
103  int i, len;
104  if (I.buffer.index > 0) {
105  for (i = I.buffer.index - 1; i > 0 && I.buffer.data[i] == ' '; i--) {
106  /* Move cursor backwards until we hit a non-space character or EOL */
107  /* This removes any trailing spaces from the input */
108  }
109  for (; i > 0 && I.buffer.data[i] != ' '; i--) {
110  /* Move cursor backwards until we hit a space character or EOL */
111  /* This deletes everything back to the previous space character */
112  }
113  if (i > 0) {
114  i++;
115  } else if (i < 0) {
116  i = 0;
117  }
118  if (I.buffer.index > I.buffer.length) {
119  I.buffer.length = I.buffer.index;
120  }
121  len = I.buffer.index - i + 1;
122  free(I.clipboard);
123  I.clipboard = rz_str_ndup(I.buffer.data + i, len);
124  rz_line_clipboard_push(I.clipboard);
125  memmove(I.buffer.data + i,
126  I.buffer.data + I.buffer.index,
127  I.buffer.length - I.buffer.index + 1);
128  I.buffer.length = strlen(I.buffer.data);
129  I.buffer.index = i;
130  }
131 }

References free(), I, i, len, rz_line_clipboard_push(), and rz_str_ndup().

Referenced by rz_line_readline_cb().

◆ vi_cmd_b()

static void vi_cmd_b ( void  )
inlinestatic

Definition at line 1015 of file dietline.c.

1015  {
1016  int i;
1017  for (i = I.buffer.index - 2; i >= 0; i--) {
1018  if ((is_word_break_char(I.buffer.data[i], MINOR_BREAK) && !is_word_break_char(I.buffer.data[i], MAJOR_BREAK)) || (is_word_break_char(I.buffer.data[i - 1], MINOR_BREAK) && !is_word_break_char(I.buffer.data[i], MINOR_BREAK))) {
1019  I.buffer.index = i;
1020  break;
1021  }
1022  }
1023  if (i < 0) {
1024  I.buffer.index = 0;
1025  }
1026 }

References I, i, is_word_break_char(), MAJOR_BREAK, and MINOR_BREAK.

Referenced by __vi_mode().

◆ vi_cmd_B()

static void vi_cmd_B ( void  )
inlinestatic

Definition at line 1028 of file dietline.c.

1028  {
1029  int i;
1030  for (i = I.buffer.index - 2; i >= 0; i--) {
1031  if ((!is_word_break_char(I.buffer.data[i], MAJOR_BREAK) && is_word_break_char(I.buffer.data[i - 1], MAJOR_BREAK))) {
1032  I.buffer.index = i;
1033  break;
1034  }
1035  }
1036  if (i < 0) {
1037  I.buffer.index = 0;
1038  }
1039 }

References I, i, is_word_break_char(), and MAJOR_BREAK.

Referenced by __vi_mode().

◆ vi_cmd_E()

static void vi_cmd_E ( void  )
inlinestatic

Definition at line 1067 of file dietline.c.

1067  {
1068  int i;
1069  for (i = I.buffer.index + 1; i < I.buffer.length; i++) {
1070  if ((!is_word_break_char(I.buffer.data[i], MAJOR_BREAK) && is_word_break_char(I.buffer.data[i + 1], MAJOR_BREAK))) {
1071  I.buffer.index = i;
1072  break;
1073  }
1074  }
1075  if (i >= I.buffer.length) {
1076  I.buffer.index = I.buffer.length - 1;
1077  }
1078 }

References I, i, is_word_break_char(), and MAJOR_BREAK.

Referenced by __vi_mode().

◆ vi_cmd_e()

static void vi_cmd_e ( void  )
inlinestatic

Definition at line 1080 of file dietline.c.

1080  {
1081  int i;
1082  for (i = I.buffer.index + 1; i < I.buffer.length; i++) {
1083  if ((!is_word_break_char(I.buffer.data[i], MINOR_BREAK) && is_word_break_char(I.buffer.data[i + 1], MINOR_BREAK)) || (is_word_break_char(I.buffer.data[i], MINOR_BREAK) && !is_word_break_char(I.buffer.data[i], MAJOR_BREAK))) {
1084  I.buffer.index = i;
1085  break;
1086  }
1087  }
1088  if (i >= I.buffer.length) {
1089  I.buffer.index = I.buffer.length - 1;
1090  }
1091 }

References I, i, is_word_break_char(), MAJOR_BREAK, and MINOR_BREAK.

Referenced by __vi_mode().

◆ vi_cmd_W()

static void vi_cmd_W ( void  )
inlinestatic

Definition at line 1041 of file dietline.c.

1041  {
1042  int i;
1043  for (i = I.buffer.index + 1; i < I.buffer.length; i++) {
1044  if ((!is_word_break_char(I.buffer.data[i], MAJOR_BREAK) && is_word_break_char(I.buffer.data[i - 1], MAJOR_BREAK))) {
1045  I.buffer.index = i;
1046  break;
1047  }
1048  }
1049  if (i >= I.buffer.length) {
1050  I.buffer.index = I.buffer.length - 1;
1051  }
1052 }

References I, i, is_word_break_char(), and MAJOR_BREAK.

Referenced by __vi_mode().

◆ vi_cmd_w()

static void vi_cmd_w ( void  )
inlinestatic

Definition at line 1054 of file dietline.c.

1054  {
1055  int i;
1056  for (i = I.buffer.index + 1; i < I.buffer.length; i++) {
1057  if ((!is_word_break_char(I.buffer.data[i], MINOR_BREAK) && is_word_break_char(I.buffer.data[i - 1], MINOR_BREAK)) || (is_word_break_char(I.buffer.data[i], MINOR_BREAK) && !is_word_break_char(I.buffer.data[i], MAJOR_BREAK))) {
1058  I.buffer.index = i;
1059  break;
1060  }
1061  }
1062  if (i >= I.buffer.length) {
1063  I.buffer.index = I.buffer.length - 1;
1064  }
1065 }

References I, i, is_word_break_char(), MAJOR_BREAK, and MINOR_BREAK.

Referenced by __vi_mode().

Variable Documentation

◆ rz_line_nullstr

char* rz_line_nullstr = ""
static

Definition at line 22 of file dietline.c.

Referenced by rz_line_readline_cb().

◆ word_break_characters

const char word_break_characters[] = "\t\n ~`!@#$%^&*()-_=+[]{}\\|;:\"'<>,./"
static

Definition at line 23 of file dietline.c.

Referenced by is_word_break_char().