2016-10-11 2 views
2

GNU Readline library을 사용하여 C의 화살표 키에 바인딩하려고합니다. rl_bind_key의 ASCII (0-255) 키 값 조합을 모두 인쇄했지만 화살표 키가 감지되지 않는 것 같습니다.Readline 라이브러리의 화살표 키에 바인딩

어떻게 바인딩 할 수 있습니까?

static int readline_func(int count, int key) { 
    printf("key pressed\n"); 
    return 0; 
} 

int i = 0; 
for (; i < 255; i++) { 
    rl_bind_key(i, readline_func); 
} 

도움 주셔서 감사합니다.

답변

5

화살표 키를 묶는 것은 그렇게 간단하지 않습니다.

먼저 화살표 키는 하나의 문자가 아닙니다. 문자 시퀀스입니다. 각 화살표 키가 보낸 정확한 문자 시퀀스는 터미널 에뮬레이터에 따라 달라집니다,하지만 당신은 xterm이 같은 터미널 에뮬레이터와 리눅스를 사용하는 경우, 당신은 아마 화살표 키를 순서 보내 확인할 수있는 것들 :

  • 을 ↑   ESC[
  • ↓   ESC[B
  • ESC[C
  • ESC[D

(당신은 토마스 당나귀에 의해 유지되는 useful compendium of control sequences에서 자세한 정보를 찾을 수 있습니다. CSI은 "제어 시퀀스 개시 자"입니다. ESC[]입니다.

이러한 시퀀스를 바인딩하려면 rl_bind_keyseq을 사용해야하며, readline 스타일의 "keyseq"(man readline; keyseq 검색 참조)을 지정해야합니다. 예를 들어, 함수에 오른쪽 화살표를 바인딩, 당신은 호출 할 수

rl_bind_keyseq("\\e[C", right_arrow_function); 

을 초기의 readline 바인딩이 경우 터미널을 다른 가능한 키 - 투 - keyseq 매핑의 다양한 사용하여, 모든 표준 키 바인딩을 포함 에뮬레이터는 다른 에뮬레이션을 사용하고 있습니다.

rl_bind_key을 사용하여 이스케이프 키 (0x1B)를 바인딩하면 해당 키 시퀀스가 ​​무시되므로 (이스케이프로 시작하기 때문에), readline 작동 방식이 아닌 것으로 생각할 수 있습니다.

Readline은 연결된 키맵의 트리를 사용하여 다중 문자 시퀀스를 바인딩합니다. 시퀀스의 각 키는 차례로 다음 키맵에 바인딩됩니다. 정확한 메커니즘은 중요하지 않습니다. readline은 처리 할 것입니다. 그러나 접두어가 하위 키맵에 바인딩되고 하위 키맵에 바인드되므로 바인딩 된 키 시퀀스의 접두사를 바인딩 할 수 없음을 알아야합니다. -keymap 바인딩은 다른 종류의 바인딩보다 우선합니다.

바인드 된 keyseq의 접두어를 리 바인드하려는 경우 오류 표시없이 이 실패합니다.; rl_bind_key (또는 rl_bind_keyseq)은 바인딩에 아무런 영향이없는 경우에도 0을 반환합니다. 결과적으로 가능한 모든 8 비트 문자에 대한 루프가 ESC을 바인드하려고했으나 rl_bind_key에 대한 호출이 성공했지만 이스케이프 키는 하위 키맵에 바인드 된 상태로 남아 있습니다. (나는 개인적으로 오류 반환의 자극이 부족하다는 것을 알게된다. 오류 표시를 얻는 것이 좋을 것이다.) rl_command_function이 호출되면, key 인수는 마지막 키에 대한 코드를 포함한다. 순서. (이는 실제로 해당 바인딩 키 정보에서 바인딩 정보를 보유하고있는 마지막 키입니다.) 화살표 키는 괜찮지 만 PageUp 및 PageDown을 포함하여 많은 수의 키를 바인딩하는 것은 귀찮습니다. 누구 코드 시퀀스 p 키를 식별 할 수 있도록 일부 (아마도 multidigit) 번호 형태 인 ESC[p~하지만 모든 시퀀스의 마지막 문자를 ~이다.

+0

이것은 훌륭한 대답입니다! 이것에 대한 더 많은 문서가 없다는 것에 놀랐습니다. 정말 고마워! –

+0

@rici 정말 좋은 답변이었습니다! 나는 이것을 거의 하루 종일 찾고 있었다. 나는 이것을 시도 할 것이다. – hrushi

0

ASCII encoding character set은 알 수 있듯이 평범한 키보드가 제공하는 화살표 키와 같은 특별한 키 개념이 없습니다.

플랫폼 키보드 드라이버가 프로그램에 바이트 시퀀스를 보내면 플랫폼에 따라 응답이 달라집니다. 리눅스에서는 termcap이이 정보를 제공하며 C 프로그램에서 ncurses library을 통해이 정보에 액세스 할 수 있습니다.

체크 this article.

관련 문제