dmenu

Kris's build of dmenu
git clone git clone https://git.krisyotam.com/krisyotam/dmenu.git
Log | Files | Refs | README | LICENSE

vi_mode.c (3733B)


      1 static unsigned int using_vi_mode = 0;
      2 
      3 void
      4 vi_keypress(KeySym ksym, const XKeyEvent *ev)
      5 {
      6 	static const size_t quit_len = LENGTH(quit_keys);
      7 	if (ev->state & ControlMask) {
      8 		switch(ksym) {
      9 		/* movement */
     10 		case XK_d: /* fallthrough */
     11 			if (next) {
     12 				sel = curr = next;
     13 				calcoffsets();
     14 				goto draw;
     15 			} else
     16 				ksym = XK_G;
     17 			break;
     18 		case XK_u:
     19 			if (prev) {
     20 				sel = curr = prev;
     21 				calcoffsets();
     22 				goto draw;
     23 			} else
     24 				ksym = XK_g;
     25 			break;
     26 		case XK_p: /* fallthrough */
     27 		case XK_P: break;
     28 		case XK_c:
     29 			cleanup();
     30 			exit(1);
     31 		case XK_Return: /* fallthrough */
     32 		case XK_KP_Enter: break;
     33 		default: return;
     34 		}
     35 	}
     36 
     37 	switch(ksym) {
     38 	/* movement */
     39 	case XK_0:
     40 		cursor = 0;
     41 		break;
     42 	case XK_dollar:
     43 		if (text[cursor + 1] != '\0') {
     44 			cursor = strlen(text) - 1;
     45 			break;
     46 		}
     47 		break;
     48 	case XK_b:
     49 		movewordedge(-1);
     50 		break;
     51 	case XK_e:
     52 		cursor = nextrune(+1);
     53 		movewordedge(+1);
     54 		if (text[cursor] == '\0')
     55 			--cursor;
     56 		else
     57 			cursor = nextrune(-1);
     58 		break;
     59 	case XK_g:
     60 		if (sel == matches) {
     61 			break;
     62 		}
     63 		sel = curr = matches;
     64 		calcoffsets();
     65 		break;
     66 	case XK_G:
     67 		if (next) {
     68 			/* jump to end of list and position items in reverse */
     69 			curr = matchend;
     70 			calcoffsets();
     71 			curr = prev;
     72 			calcoffsets();
     73 			while (next && (curr = curr->right))
     74 				calcoffsets();
     75 		}
     76 		sel = matchend;
     77 		break;
     78 	case XK_h:
     79 		if (cursor)
     80 			cursor = nextrune(-1);
     81 		break;
     82 	case XK_j:
     83 		if (sel && sel->right && (sel = sel->right) == next) {
     84 			curr = next;
     85 			calcoffsets();
     86 		}
     87 		break;
     88 	case XK_k:
     89 		if (sel && sel->left && (sel = sel->left)->right == curr) {
     90 			curr = prev;
     91 			calcoffsets();
     92 		}
     93 		break;
     94 	case XK_l:
     95 		if (text[cursor] != '\0' && text[cursor + 1] != '\0')
     96 			cursor = nextrune(+1);
     97 		else if (text[cursor] == '\0' && cursor)
     98 			--cursor;
     99 		break;
    100 	case XK_w:
    101 		movewordedge(+1);
    102 		if (text[cursor] != '\0' && text[cursor + 1] != '\0')
    103 			cursor = nextrune(+1);
    104 		else if (cursor)
    105 			--cursor;
    106 		break;
    107 	/* insertion */
    108 	case XK_a:
    109 		cursor = nextrune(+1);
    110 		/* fallthrough */
    111 	case XK_i:
    112 		using_vi_mode = 0;
    113 		break;
    114 	case XK_A:
    115 		if (text[cursor] != '\0')
    116 			cursor = strlen(text);
    117 		using_vi_mode = 0;
    118 		break;
    119 	case XK_I:
    120 		cursor = using_vi_mode = 0;
    121 		break;
    122 	case XK_p:
    123 		if (text[cursor] != '\0')
    124 			cursor = nextrune(+1);
    125 		XConvertSelection(dpy, (ev->state & ControlMask) ? clip : XA_PRIMARY,
    126 							utf8, utf8, win, CurrentTime);
    127 		return;
    128 	case XK_P:
    129 		XConvertSelection(dpy, (ev->state & ControlMask) ? clip : XA_PRIMARY,
    130 							utf8, utf8, win, CurrentTime);
    131 		return;
    132 	/* deletion */
    133 	case XK_D:
    134 		text[cursor] = '\0';
    135 		if (cursor)
    136 			cursor = nextrune(-1);
    137 		match();
    138 		break;
    139 	case XK_x:
    140 		cursor = nextrune(+1);
    141 		insert(NULL, nextrune(-1) - cursor);
    142 		if (text[cursor] == '\0' && text[0] != '\0')
    143 			--cursor;
    144 		match();
    145 		break;
    146 	/* misc. */
    147 	case XK_Return:
    148 	case XK_KP_Enter:
    149 		#if RESTRICT_RETURN_PATCH
    150 		if (restrict_return && (!sel || ev->state & (ShiftMask | ControlMask)))
    151 			break;
    152 		#endif // RESTRICT_RETURN_PATCH
    153 		#if !MULTI_SELECTION_PATCH
    154 		printcurrent(ev->state);
    155 		#endif // MULTI_SELECTION_PATCH
    156 		if (!(ev->state & ControlMask)) {
    157 			#if MULTI_SELECTION_PATCH
    158 			printselected(ev->state);
    159 			#endif // MULTI_SELECTION_PATCH
    160 			cleanup();
    161 			exit(0);
    162 		}
    163 		#if !MULTI_SELECTION_PATCH
    164 		if (sel)
    165 			sel->out = 1;
    166 		#endif // MULTI_SELECTION_PATCH
    167 		break;
    168 		break;
    169 	case XK_Tab:
    170 		if (!sel)
    171 			return;
    172 		strncpy(text, sel->text, sizeof text - 1);
    173 		text[sizeof text - 1] = '\0';
    174 		cursor = strlen(text) - 1;
    175 		match();
    176 		break;
    177 	default:
    178 		for (size_t i = 0; i < quit_len; ++i)
    179 			if (quit_keys[i].ksym == ksym &&
    180 				(quit_keys[i].state & ev->state) == quit_keys[i].state) {
    181 				cleanup();
    182 				exit(1);
    183 			}
    184 	}
    185 
    186 draw:
    187 	drawmenu();
    188 }