string key_input_line()
{
	//DLOG("key_input_line");
	fflush(stdout);
	string strRet;
	struct termios old_term, new_term;
	char input[8194] =
		{ 0 };
	int cnt = 0;
	int maxLen = 8190;
	int pos = 0;
	char ch;

	// 保存原始终端设置
	tcgetattr(STDIN_FILENO, &old_term);
	// 设置新的终端模式
	new_term = old_term;
	new_term.c_lflag &= ~(ICANON | ECHO);  // 关闭规范模式和回显
	tcsetattr(STDIN_FILENO, TCSANOW, &new_term);

	while (read(STDIN_FILENO, &ch, 1) == 1 && ch != '\n')
	{
		DLOG("ch1=%02X", ch);
		if ('\b' == ch || 0x7F == ch) // 退格键 wsl 0x7f
		{
			if (pos > 0)
			{
				int slen =  (int) cnt; //strlen(input);//
				memmove(&input[pos - 1], &input[pos], (slen - pos + 1));
				cnt--;
				pos--;
				int npr = (int) (cnt - pos); // strlen(input + pos);//
				int npr1 = npr + 1;
				printf("\b%s ", input + pos);  //光标左移 打印剩余内容和空格
				fflush(stdout);
				for (int ix = 0; ix < npr1; ix++){
					printf("\b");
					fflush(stdout);
				}
			}
		}
		else if (0x1B == ch)  // ESC键(方向键前缀)
		{
			read(STDIN_FILENO, &ch, 1);
			DLOG("ch2=%02X", ch);
			if (ch == '[')  //0x5B
			{
				read(STDIN_FILENO, &ch, 1);
				DLOG("ch3=%02X", ch);
				if ('D' == ch) // 左箭头44
				{
					if (pos > 0)
					{
						printf("\b");
						fflush(stdout);
						pos--;
					}
				}
				else if ('C' == ch) // 右箭头43
				{
					int slen = (int) cnt; // strlen(input);
					if (pos < slen)
					{
						printf("%c", input[pos]);
						fflush(stdout);
						pos++;
					}
				}
				else if (0x33 == ch)
				{
					read(STDIN_FILENO, &ch, 1);
					DLOG("ch4=%02X", ch);
					if (0x7E == ch) // Delete键(1b 5b 33 7E)
					{
						//DLOG("<del>");
						int slen = (int) cnt; // strlen(input);
						if (pos < slen)
						{
							memmove(&input[pos], &input[pos + 1], (slen - pos));
							cnt--;
							int npr = (int) (cnt - pos); // strlen(input + pos);
							int npr1 = npr + 1;
							printf("%s ", input + pos);  // 打印剩余内容和空格
							fflush(stdout);
							for (int ix = 0; ix < npr1; ix++){
								printf("\b");
								fflush(stdout);
							}
						}
					}
				}
			}
		}
		else  // 普通字符 insert
		{
			if (pos < maxLen)
			{
				int slen = (int) cnt;  //strlen(input);
				if (slen < maxLen)
				{
					memmove(&input[pos + 1], &input[pos], (slen - pos + 1));
					input[pos] = ch;
					int npr = (int) (cnt - pos);  // strlen(input + pos);
					printf("%s", input + pos);
					fflush(stdout);
					for (int ix = 0; ix < npr; ix++){
						printf("\b");
						fflush(stdout);
					}
					pos++;
					cnt++;
				}
			}
		}
	}
	printf("\n");
	input[cnt] = 0;
	strRet = input;

	// 恢复原始终端设置
	tcsetattr(STDIN_FILENO, TCSANOW, &old_term);

	return strRet;
}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐