foo.c의 foo.h에 프로토 타입을 자동으로 삽입하려면 어떻게해야합니까?


11

foo.c 파일에 C 프로그램을 작성한다고 가정하십시오.

int add_numbers(int x, int y, int z) {
    // Very complex implementation here.
    return x + y + z;
}

foo.h에 해당 함수 프로토 타입을 삽입하는 명령을 원합니다.

int add_numbers(int x, int y, int z);

이에 대한 기존 Emacs 솔루션이 있습니까?

답변:


9

업데이트 : 이 문제 등을 완전히 해결하는 Semantic Refactor 패키지를 만들었습니다 . 당신은 볼 수 데모 어떻게 작동하는지 볼 수 있습니다. 이 문장 다음에이 답변의 나머지 텍스트는 오래되어 역사적 이유가 있습니다.

오래된 답변 :

senator-copy-tag함수 서명을 정확하게 복사 한 다음 소스 파일에 다시 붙여 넣는 데 사용할 수 있습니다 . senator-copy-tag다음을 활성화하면 Senator 명령을 사용할 수 있습니다 semantic-mode.

(semantic-mode 1)

시맨틱은 Emacs 내장 패키지입니다.

Semantic Senator와 Projectile을 명령에 결합하여 프로젝트의 어느 곳에서나 함수 프로토 타입을 다른 파일 (같은 이름이지만 확장자가 다른 파일)에 삽입 할 수 있습니다. 다른 파일이 하나만 있으면 명령은 해당 파일에 즉시 삽입합니다. 둘 이상인 경우 파일을 선택하라는 메시지가 표시됩니다. 없는 경우 프로젝트의 전체 파일을 입력하라는 메시지가 표시됩니다. 파일을 선택한 후 프롬프트는 현재 버퍼에 삽입 할 수있는 시맨틱 태그 목록을 제공합니다.

나는 Emacs Refactor에 PR 을 제출 했다 . PR을 기다리지 않고 시도하려는 경우 전체 코드 : 여기를 클릭하십시오 .

다음은 데모입니다 ( START DEMO맨 아래에 표시 될 때 시작 ).

발사체 시맨틱 삽입 함수 프로토 타입

또한 Senator 만 사용하여 프로토 타입을 복사 및 기능 할 수 있습니다. 포인트가 함수 시그니처 또는 함수 본문 안에 있으면 ( 기본적으로 senator-copy-tag바인딩 된 run) , C-c , M-w전체 함수 (서명과 본문 모두)를 복사합니다. 그러나 원하는 경우 기본적으로 senator-yank-tag바인딩 된 명령을 실행하여 서명 만 붙여 넣을 수 있습니다 C-c , C-y. 누르면 C-y전체 기능 서명을 본문과 함께 붙여 넣습니다. senator-copy-tag다음과 같이 여러 줄로 확장 된 함수 서명으로도 작동합니다.

void 
func(int a,
     int b, 
     int c)
{
    .....
}

이 방법은 동일한 이름의 버퍼에 직접 삽입되지 않지만 다른 경우에 더 적합합니다. 동일한 디렉토리에 이름은 같지만 확장자가 다른 두 개의 파일이있는 경우에만 사용 사례가 작동합니다. 함수 선언과 함수 정의가 이름이 다른 다른 파일에 있어야하는 경우 어떻게합니까?

EDIT2 : 다음은 시맨틱 태그를 사용하여 함수 프로토 타입을 스마트하게 삽입하는 예입니다. 현재 최상위 시맨틱 태그의 상대 위치 ( "이전"및 "이후")를 기준으로 만 삽입 할 수 있습니다. 나는 시맨틱 태그 이상의 위치로 사용할 수 있습니다 어떤 장소에 삽입 할 수 할 수 있도록 사용자에게 업데이트됩니다 (태그가을 때 예 Class: 추가적인 위치를 제공해야합니다 public, projected그리고 private). 데모 START DEMO는 하단에 표시되면 시작됩니다 .

발사체 시맨틱 삽입 함수 프로토 타입 2

보너스 : .cpp헤더 파일에서 파일 에 빈 함수 정의 목록을 생성 하려면 member-functions.el을 사용하십시오 . 그러나 곧 Semantic + Projectile로 대체하겠습니다.


3

다음 명령을 수행해야합니다. 테스트를 통과했으며 외부 종속성이 없습니다.

(defun endless/copy-proto-to-header-file ()
  (interactive)
  (save-excursion
    ;; c-mode's `beginning-of-defun' should be robust enough.
    (beginning-of-defun)
    (let ((l (point)))
      (search-forward-regexp " *{")
      (let ((proto (buffer-substring l (match-beginning 0))))
        (ff-find-other-file)
        ;; If other file is already open, we don't want to move point.
        (save-excursion
          (goto-char (point-max))
          ;; Do some more movement here if you want.
          (insert "\n" proto ";"))))))

2

나는 다음과 같이 작동해야 한다고 생각 한다.

(defun c-copy-function-signature-to-header ()
  (interactive)
  (save-excursion
    (let ((last-point -1))
      (while (/= (point) last-point)
        (setq last-point (point))
        (sp-backward-up-sexp))
      (kill-ring-save (point) (line-beginning-position))
      (ff-find-other-file)
      (yank)
      ;; clean whitespace between closing paren and opening curly 
      (delete-trailing-whitespace
        (line-beginning-position)
        (line-end-position))
      (insert ";")))

수용 할 수없는 경우 smartparens자신의 사본을 해킹 할 수 있지만을 요구합니다 sp-backward-up-sexp.

또한 헤더의 (point)마지막 위치에 헤더가 배치됩니다. 원하는 위치를 지정하지 않았으므로 이것이 최선이라고 생각했습니다. 당신이 마지막에 추가하려는 경우 물론, 당신은 넣을 수 있습니다 (end-of-buffer)전과 (yank). 물론 포인트 근처에 새 줄을 만들고 거기에서 yan 거리는 것과 같은 더 멋진 것들을 추가 할 수 있지만, 그것은 당신의 취향에 달려 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.