함수를 키에 바인딩하거나 Mx로 호출 할 수없는 이유는 무엇입니까?


13

함수를 작성하고 Mx를 통해 호출하고 키에 바인딩하고 싶습니다. 이것은 내 기능입니다.

(defun my-function ()
    (message "This is a great function"))

로 호출하려고 하면 미니 버퍼에 M-x my-function오류가 발생 [no match]합니다.

키 (또는 마우스 클릭)에 바인딩하려고하면 :

(global-set-key (kbd "C-c a") 'my-function)

작동하는 것처럼 보이지만으로 호출하려고 C-c a하면 오류가 발생합니다.

잘못된 유형 인수 : commandp, my-function

왜 내 기능을 사용할 수 없습니까?


5
이 주제에 관해 자주 묻는 질문에 대한 일반적인 답변으로이 질문에 자원합니다. 자유롭게 확장하거나 명확하게 설명하지만 비슷한 문제를 가진 사람들이 질문과 답변을 발견하고 유용하게 만드는 것이 합리적입니다!
Tyler

1
이렇게 해줘서 고마워, 타일러 중재자에게 Q를 신고하여 커뮤니티 질문으로 변환하십시오.
Drew

내가 궁금한 점은 제목이 오류 메시지를 인용 해야하는지 여부입니다. 사람들이 찾기가 더 쉬울 수 있으며 추가와 관련이없는 답변을 허용 할 수도 있습니다. interactive예를 들어 명령이 새 버전의 라이브러리에서 사라지는 경우가 있습니다. Emacs가 명령을 기대하는 모든 상황에서 오류가 발생할 수 있습니다.
Drew

예를 들어 사람들 commandp이이 위키 와 중복되어 닫힐 수있는 다른 Q를 찾으려고 위키를 검색하면 좋을 것 입니다. 그러나 일부는 다르므로 Q & A를주의해서 읽으십시오. 어떤 경우에는 대답 (및 Q 컨텍스트)을 여기에서 반복 할 가치가 있습니다. 에서 다른 경우 문제는 무관하고 (폐쇄되지 않음)로 남아 있어야합니다.
Drew

1
@Drew 제목에 '광고'하는 것이 가장 좋은 방법인지 확실하지 않았습니다. commandp 오류는 키 바인딩과 함께 만 나타나므로 Mx 방향 에서이 사람들은 연결을 볼 수 없습니다. 명확하고 간결한 제목과 모든 관련 검색어에 대해 표시되는 제목간에 최상의 균형이 무엇인지 확실하지 않습니다. 원하는대로 조정하십시오!
Tyler

답변:


22

핵심은 기능과 명령 사이에 차이 가 있다는 것입니다 .

Emacs lisp에서는 기본적으로 함수를 대화식으로 호출 할 수 없습니다. 즉 M-x, 키 또는 마우스 클릭을 통해 액세스 하거나 바인딩 할 수 없습니다 . 그렇게하려면 함수를 명시 적으로 선언해야합니다.이 함수 는 본문에서 첫 번째 행으로 양식을 interactive추가하여 (interactive)(문서 문자열 다음에) 수행합니다. 대화식 기능을 명령 이라고합니다 . (info "(elisp) Using Interactive") (온라인 버전) 설명서에 설명되어 있습니다 .

표시되는 오류 메시지 Wrong type argument: commandp, my-function는 함수를 대화식으로 호출하려고하지만 해당 함수가 명령 이 아님을 나타냅니다 .

실제 오류를 설명하기 위해 문자 p는 종종 술어 또는 테스트를 나타 내기 위해 lisp에서 사용됩니다. 이 경우 Emacs는 test my-function를 사용한 명령인지 확인하기 위해 테스트하고 commandp있습니다. 그렇지 않아 오류가 발생합니다. 잘못된 유형의 객체를 사용할 때마다 비슷한 오류가 나타납니다. Emacs가 문자열을 예상하고 기호를 전달하면 stringp예를 들어에 대한 참조가 표시 될 수 있습니다 .

요청에 따라 질문에 대답하려면 (interactive)정의에 행을 추가해야합니다 .

(defun my-function ()
    (interactive)
    (message "This is a great function"))

양식에는 정보를 함수에 전달하는 모든 종류의 방법을 지원 하는 많은 옵션이 있습니다 interactive. 자세한 내용은 설명서를 확인하십시오.

이 상황에서 키보드 매크로는 특별한 경우입니다. 키보드 매크로는 일련의 입력 이벤트이며 문자열로 표시됩니다. 키보드 매크로는 명령처럼 동작하므로 interactive선언을 추가하지 않아도 키에 바인딩 할 수 있습니다 . 예를 들어 다음과 같습니다.

(global-set-key (kbd "C-c l") "λ")

"λ"키보드 매크로이므로 C-c l문제없이 바인딩 할 수 있습니다 . 함수로 같은 일을하려고하면 함수를 interactive다음 과 같이 정의해야합니다 .

(global-set-key (kbd "C-c k") 
  (lambda () (insert "λ"))
;; C-c k is undefined! We tried to bind it to a function

(global-set-key (kbd "C-c m") 
  (lambda () (interactive) (insert "λ"))
;; C-c m is bound to a command that inserts λ

내가 추가하고 싶은 한 가지 제안 은, 당신의 예제를 하기 전에 Cx Ce 를해야한다는 것을 분명히 M-x my-function하십시오. 또한 emacs 초보자로서 나는 정확히 정확히 무엇을 해야하는지 C-x C-e또는 언제 그것을 실행 해야하는지에 대해 100 % 명확하지 않지만, 어 ... 실행하면 버퍼를 구문 분석하고 my-function메모리에 덮어 씁니다 . C-x C-e M-x마지막으로 실행 한 시간부터 기능을 실행하지 마십시오C-x C-e
jrh

C-x C-e 버퍼평가하는 것으로 보입니다.이 포함 된 버퍼를 평가 한 결과 defun함수를 등록하는 것 같습니다. 이 기사에서는 함수를 실행해야한다고 생각하는 것처럼 보이지만 미니 버퍼에 표시된 유일한 것은 my-function(함수를 반환한다는 의미입니까?), not This is a great function. 나는 여기서 뭔가를 놓치고 있어야합니다.
jrh

1
귀하의 의견에 감사드립니다, @jrh. 이 질문과 대답은 elisp의 특정 측면, 즉 대화식으로 함수를 만드는 방법 (즉, 함수를 명령으로 바꾸는 방법)을 다루고 있습니다. elisp의보다 기본적인 측면에 대해 질문하고 있으며이 질문의 범위를 벗어납니다. Emacs Lisp Intro를 통해 작업하는 것이 좋습니다. 함수를 정의하지만 실제로는 호출하지 않는 함수 정의 평가와 함수 코드를 실행하는 함수 호출의 차이점에 대해 혼란스러워하는 것 같습니다.
Tyler
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.