포인트가 댓글 영역 내에 있는지 어떻게 감지합니까?


15

포인트가 댓글 영역 내에 있는지 어떻게 감지합니까?

답변:


19

목록에서 네 번째 * 값을 확인하십시오 syntax-ppss.

(nth 4 (syntax-ppss))

그것은이다 nil점은, 어떤 코멘트를 벗어나면 t경우 비 중첩 가능한 주석 내부, 또는 정수 (중첩 깊이) 중첩 가능한 주석 내부 경우. 자세한 내용은 docstring을 parse-partial-sexp참조하십시오.

* 제로 기반.

조직 모드에서는 작동하지 않으므로 다음을 사용해야합니다.

(defun in-comment-p ()
  "Testy if cursor/point in a commented line?"
  (save-excursion
        (if (derived-mode-p 'org-mode)
                (save-match-data (beginning-of-line) (looking-at "^[ \t]*#"))
          (nth 4 (syntax-ppss)))))

완벽합니다. syntax-ppss제공 하는 다른 모든 정보에 대한 설명서가 있습니까?
이름

2
예,의 docstring에 parse-partial-sexp있습니다.
legoscia

2
@Name :에 대한 docstring은 syntax-ppss을 가리키고 parse-partial-sexp, 후자는 이러한 함수에 의해 반환되는 모든 것들에 대한 설명을 제공합니다. 바라건대 그것은 시작에 도움이됩니다.
Dan

1
Emacs Lisp 매뉴얼의 34.6 "파싱 표현식"섹션도 참조하십시오.
Sue D. Nymme

7

폰트 페이스를 사용하면 플라이 스펠에서 배운 트릭입니다.

syntax-ppss2 년 전에 시도했지만 두 가지 이유로 작동하지 않습니다.

  • 예를 들어 // this is commentc ++-mode 와 같은 주석의 경우 주석 모서리 ​​(설명 한계)에서 작동하지 않습니다 . /문자 위에 커서를 놓으면 결과 (nth 4 (syntax-ppss))는 nil입니다.

  • 웹 모드와 같은 주요 모드에서는 전혀 작동하지 않습니다

다음은 flyspell에서 복사 한 코드입니다.

(defun evilnc--in-comment-p (&optional pos)
  "Test if character at POS is comment.  If POS is nil, character at `(point)' is tested"
  (interactive)
  (unless pos (setq pos (point)))
  (let* ((fontfaces (get-text-property pos 'face)))
    (when (not (listp fontfaces))
      (setf fontfaces (list fontfaces)))
    (delq nil
          (mapcar #'(lambda (f)
                      ;; learn this trick from flyspell
                      (or (eq f 'font-lock-comment-face)
                          (eq f 'font-lock-comment-delimiter-face)))
                  fontfaces))))

폰트 페이스를 일치시켜 새로운 주요 모드를 지원하도록 코드를 확장 할 수 있습니다.

나는이 트릭을 약 3 년 동안 실패없이 사용했습니다. 게다가, 플라이 스펠이 오랫동안 널리 사용되었다는 것을 고려할 때, 나는이 방법이 신뢰할 만하다고 주장 할 수 있습니다.

비슷한 질문 에 대한 문자열탐색하는 데 사용할 키보드 단축키를 참조하십시오 .


1
편집은 POS인수를 사용 하지 않고 사용 하는 다른 버전을 제안했습니다 point. 이러한 두 가지 버전을 사용하는 것보다 arg를 POS선택적 으로 만들고 (point)when로 설정하는 것이 nil좋습니다.
Drew
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.