1/* $FreeBSD: head/contrib/libreadline/vi_mode.c 157188 2006-03-27 23:11:32Z ache $ */ |
2/* vi_mode.c -- A vi emulation mode for Bash. 3 Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */ 4 |
5/* Copyright (C) 1987-2005 Free Software Foundation, Inc. |
6 7 This file is part of the GNU Readline Library, a library for 8 reading lines of text with interactive input and history editing. 9 10 The GNU Readline Library is free software; you can redistribute it 11 and/or modify it under the terms of the GNU General Public License 12 as published by the Free Software Foundation; either version 2, or 13 (at your option) any later version. --- 72 unchanged lines hidden (view full) --- 86static char *vi_insert_buffer; 87static int vi_insert_buffer_size; 88 89static int _rl_vi_last_repeat = 1; 90static int _rl_vi_last_arg_sign = 1; 91static int _rl_vi_last_motion; 92#if defined (HANDLE_MULTIBYTE) 93static char _rl_vi_last_search_mbchar[MB_LEN_MAX]; |
94static int _rl_vi_last_search_mblen; |
95#else 96static int _rl_vi_last_search_char; 97#endif 98static int _rl_vi_last_replacement; 99 100static int _rl_vi_last_key_before_insert; 101 102static int vi_redoing; 103 104/* Text modification commands. These are the `redoable' commands. */ 105static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~"; 106 107/* Arrays for the saved marks. */ 108static int vi_mark_chars['z' - 'a' + 1]; 109 110static void _rl_vi_stuff_insert PARAMS((int)); 111static void _rl_vi_save_insert PARAMS((UNDO_LIST *)); |
112 113static int _rl_vi_arg_dispatch PARAMS((int)); |
114static int rl_digit_loop1 PARAMS((void)); 115 |
116static int _rl_vi_set_mark PARAMS((void)); 117static int _rl_vi_goto_mark PARAMS((void)); 118 119static int _rl_vi_callback_getchar PARAMS((char *, int)); 120 121#if defined (READLINE_CALLBACKS) 122static int _rl_vi_callback_set_mark PARAMS((_rl_callback_generic_arg *)); 123static int _rl_vi_callback_goto_mark PARAMS((_rl_callback_generic_arg *)); 124static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *)); 125static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *)); 126#endif 127 |
128void 129_rl_vi_initialize_line () 130{ 131 register int i; 132 133 for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++) 134 vi_mark_chars[i] = -1; |
135 136 RL_UNSETSTATE(RL_STATE_VICMDONCE); |
137} 138 139void 140_rl_vi_reset_last () 141{ 142 _rl_vi_last_command = 'i'; 143 _rl_vi_last_repeat = 1; 144 _rl_vi_last_arg_sign = 1; --- 539 unchanged lines hidden (view full) --- 684rl_vi_movement_mode (count, key) 685 int count, key; 686{ 687 if (rl_point > 0) 688 rl_backward_char (1, key); 689 690 _rl_keymap = vi_movement_keymap; 691 _rl_vi_done_inserting (); |
692 693 /* This is how POSIX.2 says `U' should behave -- everything up until the 694 first time you go into command mode should not be undone. */ 695 if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0) 696 rl_free_undo_list (); 697 698 RL_SETSTATE (RL_STATE_VICMDONCE); |
699 return (0); 700} 701 702int 703rl_vi_arg_digit (count, c) 704 int count, c; 705{ 706 if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg) --- 153 unchanged lines hidden (view full) --- 860 861 if (!member (c, vi_motion)) 862 { 863 if (_rl_digit_p (c)) 864 { 865 save = rl_numeric_arg; 866 rl_numeric_arg = _rl_digit_value (c); 867 rl_explicit_arg = 1; |
868 RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION); |
869 rl_digit_loop1 (); |
870 RL_UNSETSTATE (RL_STATE_VIMOTION); |
871 rl_numeric_arg *= save; 872 RL_SETSTATE(RL_STATE_MOREINPUT); 873 c = rl_read_key (); /* real command */ 874 RL_UNSETSTATE(RL_STATE_MOREINPUT); 875 *nextkey = c; 876 } 877 else if (key == c && (key == 'd' || key == 'y' || key == 'c')) 878 { --- 56 unchanged lines hidden (view full) --- 935 } 936 937 if (rl_mark < rl_point) 938 SWAP (rl_point, rl_mark); 939 940 return (0); 941} 942 |
943/* Process C as part of the current numeric argument. Return -1 if the 944 argument should be aborted, 0 if we should not read any more chars, and 945 1 if we should continue to read chars. */ 946static int 947_rl_vi_arg_dispatch (c) 948 int c; 949{ 950 int key; 951 952 key = c; 953 if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument) 954 { 955 rl_numeric_arg *= 4; 956 return 1; 957 } 958 959 c = UNMETA (c); 960 961 if (_rl_digit_p (c)) 962 { 963 if (rl_explicit_arg) 964 rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c); 965 else 966 rl_numeric_arg = _rl_digit_value (c); 967 rl_explicit_arg = 1; 968 return 1; 969 } 970 else 971 { 972 rl_clear_message (); 973 rl_stuff_char (key); 974 return 0; 975 } 976} 977 |
978/* A simplified loop for vi. Don't dispatch key at end. 979 Don't recognize minus sign? 980 Should this do rl_save_prompt/rl_restore_prompt? */ 981static int 982rl_digit_loop1 () 983{ |
984 int c, r; |
985 |
986 while (1) 987 { |
988 if (_rl_arg_overflow ()) 989 return 1; |
990 |
991 c = _rl_arg_getchar (); |
992 |
993 r = _rl_vi_arg_dispatch (c); 994 if (r <= 0) 995 break; |
996 } 997 998 RL_UNSETSTATE(RL_STATE_NUMERICARG); 999 return (0); 1000} 1001 1002int 1003rl_vi_delete_to (count, key) --- 73 unchanged lines hidden (view full) --- 1077 1078 return (0); 1079} 1080 1081int 1082rl_vi_yank_to (count, key) 1083 int count, key; 1084{ |
1085 int c, save; |
1086 |
1087 save = rl_point; |
1088 if (_rl_uppercase_p (key)) 1089 rl_stuff_char ('$'); 1090 1091 if (rl_vi_domove (key, &c)) 1092 { 1093 rl_ding (); 1094 return -1; 1095 } --- 8 unchanged lines hidden (view full) --- 1104 rl_end_undo_group (); 1105 rl_do_undo (); 1106 rl_point = save; 1107 1108 return (0); 1109} 1110 1111int |
1112rl_vi_rubout (count, key) 1113 int count, key; 1114{ 1115 int p, opoint; 1116 1117 if (count < 0) 1118 return (rl_vi_delete (-count, key)); 1119 1120 if (rl_point == 0) 1121 { 1122 rl_ding (); 1123 return -1; 1124 } 1125 1126 opoint = rl_point; 1127 if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1128 rl_backward_char (count, key); 1129 else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1130 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); 1131 else 1132 rl_point -= count; 1133 1134 if (rl_point < 0) 1135 rl_point = 0; 1136 1137 rl_kill_text (rl_point, opoint); 1138 1139 return (0); 1140} 1141 1142int |
1143rl_vi_delete (count, key) 1144 int count, key; 1145{ 1146 int end; 1147 |
1148 if (count < 0) 1149 return (rl_vi_rubout (-count, key)); 1150 |
1151 if (rl_end == 0) 1152 { 1153 rl_ding (); 1154 return -1; 1155 } 1156 1157 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1158 end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); 1159 else 1160 end = rl_point + count; 1161 1162 if (end >= rl_end) 1163 end = rl_end; 1164 1165 rl_kill_text (rl_point, end); 1166 1167 if (rl_point > 0 && rl_point == rl_end) 1168 rl_backward_char (1, key); |
1169 |
1170 return (0); 1171} 1172 1173int 1174rl_vi_back_to_indent (count, key) 1175 int count, key; 1176{ 1177 rl_beg_of_line (1, key); --- 4 unchanged lines hidden (view full) --- 1182 1183int 1184rl_vi_first_print (count, key) 1185 int count, key; 1186{ 1187 return (rl_vi_back_to_indent (1, key)); 1188} 1189 |
1190static int _rl_cs_dir, _rl_cs_orig_dir; 1191 1192#if defined (READLINE_CALLBACKS) 1193static int 1194_rl_vi_callback_char_search (data) 1195 _rl_callback_generic_arg *data; 1196{ 1197#if defined (HANDLE_MULTIBYTE) 1198 _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); 1199#else 1200 RL_SETSTATE(RL_STATE_MOREINPUT); 1201 _rl_vi_last_search_char = rl_read_key (); 1202 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1203#endif 1204 1205 _rl_callback_func = 0; 1206 _rl_want_redisplay = 1; 1207 1208#if defined (HANDLE_MULTIBYTE) 1209 return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen)); 1210#else 1211 return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char)); 1212#endif 1213} 1214#endif 1215 |
1216int 1217rl_vi_char_search (count, key) 1218 int count, key; 1219{ 1220#if defined (HANDLE_MULTIBYTE) 1221 static char *target; |
1222 static int tlen; |
1223#else 1224 static char target; 1225#endif |
1226 1227 if (key == ';' || key == ',') |
1228 _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir; |
1229 else 1230 { |
1231 switch (key) 1232 { 1233 case 't': |
1234 _rl_cs_orig_dir = _rl_cs_dir = FTO; |
1235 break; 1236 1237 case 'T': |
1238 _rl_cs_orig_dir = _rl_cs_dir = BTO; |
1239 break; 1240 1241 case 'f': |
1242 _rl_cs_orig_dir = _rl_cs_dir = FFIND; |
1243 break; 1244 1245 case 'F': |
1246 _rl_cs_orig_dir = _rl_cs_dir = BFIND; |
1247 break; 1248 } |
1249 1250 if (vi_redoing) 1251 { 1252 /* set target and tlen below */ 1253 } 1254#if defined (READLINE_CALLBACKS) 1255 else if (RL_ISSTATE (RL_STATE_CALLBACK)) 1256 { 1257 _rl_callback_data = _rl_callback_data_alloc (count); 1258 _rl_callback_data->i1 = _rl_cs_dir; 1259 _rl_callback_func = _rl_vi_callback_char_search; 1260 return (0); 1261 } 1262#endif 1263 else 1264 { 1265#if defined (HANDLE_MULTIBYTE) 1266 _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); 1267#else 1268 RL_SETSTATE(RL_STATE_MOREINPUT); 1269 _rl_vi_last_search_char = rl_read_key (); 1270 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1271#endif 1272 } |
1273 } 1274 1275#if defined (HANDLE_MULTIBYTE) |
1276 target = _rl_vi_last_search_mbchar; 1277 tlen = _rl_vi_last_search_mblen; |
1278#else |
1279 target = _rl_vi_last_search_char; |
1280#endif |
1281 1282#if defined (HANDLE_MULTIBYTE) 1283 return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen)); 1284#else 1285 return (_rl_char_search_internal (count, _rl_cs_dir, target)); 1286#endif |
1287} 1288 1289/* Match brackets */ 1290int 1291rl_vi_match (ignore, key) 1292 int ignore, key; 1293{ 1294 int count = 1, brack, pos, tmp, pre; --- 93 unchanged lines hidden (view full) --- 1388 case '[': return 2; 1389 case ']': return -2; 1390 case '{': return 3; 1391 case '}': return -3; 1392 default: return 0; 1393 } 1394} 1395 |
1396static int 1397_rl_vi_change_char (count, c, mb) 1398 int count, c; 1399 char *mb; |
1400{ |
1401 int p; |
1402 |
1403 if (c == '\033' || c == CTRL ('C')) 1404 return -1; 1405 1406 rl_begin_undo_group (); 1407 while (count-- && rl_point < rl_end) 1408 { 1409 p = rl_point; 1410 rl_vi_delete (1, c); |
1411 if (rl_point < p) /* Did we retreat at EOL? */ 1412 rl_point++; |
1413#if defined (HANDLE_MULTIBYTE) 1414 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) |
1415 rl_insert_text (mb); |
1416 else 1417#endif |
1418 _rl_insert_char (1, c); |
1419 } |
1420 1421 /* The cursor shall be left on the last character changed. */ 1422 rl_backward_char (1, c); 1423 |
1424 rl_end_undo_group (); 1425 1426 return (0); 1427} 1428 |
1429static int 1430_rl_vi_callback_getchar (mb, mblen) 1431 char *mb; 1432 int mblen; 1433{ 1434 int c; 1435 1436 RL_SETSTATE(RL_STATE_MOREINPUT); 1437 c = rl_read_key (); 1438 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1439 1440#if defined (HANDLE_MULTIBYTE) 1441 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1442 c = _rl_read_mbstring (c, mb, mblen); 1443#endif 1444 1445 return c; 1446} 1447 1448#if defined (READLINE_CALLBACKS) 1449static int 1450_rl_vi_callback_change_char (data) 1451 _rl_callback_generic_arg *data; 1452{ 1453 int c; 1454 char mb[MB_LEN_MAX]; 1455 1456 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); 1457 1458 _rl_callback_func = 0; 1459 _rl_want_redisplay = 1; 1460 1461 return (_rl_vi_change_char (data->count, c, mb)); 1462} 1463#endif 1464 |
1465int |
1466rl_vi_change_char (count, key) 1467 int count, key; 1468{ 1469 int c; 1470 char mb[MB_LEN_MAX]; 1471 1472 if (vi_redoing) 1473 { 1474 c = _rl_vi_last_replacement; 1475 mb[0] = c; 1476 mb[1] = '\0'; 1477 } 1478#if defined (READLINE_CALLBACKS) 1479 else if (RL_ISSTATE (RL_STATE_CALLBACK)) 1480 { 1481 _rl_callback_data = _rl_callback_data_alloc (count); 1482 _rl_callback_func = _rl_vi_callback_change_char; 1483 return (0); 1484 } 1485#endif 1486 else 1487 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); 1488 1489 return (_rl_vi_change_char (count, c, mb)); 1490} 1491 1492int |
1493rl_vi_subst (count, key) 1494 int count, key; 1495{ 1496 /* If we are redoing, rl_vi_change_to will stuff the last motion char */ 1497 if (vi_redoing == 0) 1498 rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */ 1499 1500 return (rl_vi_change_to (count, 'c')); --- 105 unchanged lines hidden (view full) --- 1606 rl_possible_completions (); 1607 rl_point = save_pos; 1608 1609 return (0); 1610} 1611#endif 1612 1613/* Functions to save and restore marks. */ |
1614static int 1615_rl_vi_set_mark () |
1616{ 1617 int ch; 1618 1619 RL_SETSTATE(RL_STATE_MOREINPUT); 1620 ch = rl_read_key (); 1621 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1622 1623 if (ch < 'a' || ch > 'z') 1624 { 1625 rl_ding (); 1626 return -1; 1627 } 1628 ch -= 'a'; 1629 vi_mark_chars[ch] = rl_point; 1630 return 0; 1631} 1632 |
1633#if defined (READLINE_CALLBACKS) 1634static int 1635_rl_vi_callback_set_mark (data) 1636 _rl_callback_generic_arg *data; 1637{ 1638 _rl_callback_func = 0; 1639 _rl_want_redisplay = 1; 1640 1641 return (_rl_vi_set_mark ()); 1642} 1643#endif 1644 |
1645int |
1646rl_vi_set_mark (count, key) |
1647 int count, key; 1648{ |
1649#if defined (READLINE_CALLBACKS) 1650 if (RL_ISSTATE (RL_STATE_CALLBACK)) 1651 { 1652 _rl_callback_data = 0; 1653 _rl_callback_func = _rl_vi_callback_set_mark; 1654 return (0); 1655 } 1656#endif 1657 1658 return (_rl_vi_set_mark ()); 1659} 1660 1661static int 1662_rl_vi_goto_mark () 1663{ |
1664 int ch; 1665 1666 RL_SETSTATE(RL_STATE_MOREINPUT); 1667 ch = rl_read_key (); 1668 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1669 1670 if (ch == '`') 1671 { --- 11 unchanged lines hidden (view full) --- 1683 { 1684 rl_ding (); 1685 return -1; 1686 } 1687 rl_point = vi_mark_chars[ch]; 1688 return 0; 1689} 1690 |
1691#if defined (READLINE_CALLBACKS) 1692static int 1693_rl_vi_callback_goto_mark (data) 1694 _rl_callback_generic_arg *data; 1695{ 1696 _rl_callback_func = 0; 1697 _rl_want_redisplay = 1; 1698 1699 return (_rl_vi_goto_mark ()); 1700} 1701#endif 1702 1703int 1704rl_vi_goto_mark (count, key) 1705 int count, key; 1706{ 1707#if defined (READLINE_CALLBACKS) 1708 if (RL_ISSTATE (RL_STATE_CALLBACK)) 1709 { 1710 _rl_callback_data = 0; 1711 _rl_callback_func = _rl_vi_callback_goto_mark; 1712 return (0); 1713 } 1714#endif 1715 1716 return (_rl_vi_goto_mark ()); 1717} |
1718#endif /* VI_MODE */ |