2010-04-08 2 views
9

Flymake를 C# 코드에서 사용하고 있습니다. Windows에서는 emacs v22.2.1입니다.Windows 용 Emacs에서 오버레이/툴팁이 올바르게 작동합니까?

플라이 메이크 (Flymake) 제품이 나에게 잘 작동하고 있습니다. 사람들은 모르겠지만, you can read an overview of flymake,하지만 빠른 이야기는 flymake가 구문 검사를하기 위해 백그라운드에서 현재 작업하고있는 소스 파일을 반복적으로 빌드한다는 것입니다. 그런 다음 현재 버퍼의 컴파일러 경고 및 오류를 강조 표시합니다.

Flymake는 처음에 C#에서는 작동하지 않지만 I "monkey-patched it" and it works nicely now에서는 작동하지 않았습니다. 이맥스에서 C#을 편집한다면 플라이 메이크 사용을 적극 권장합니다.

내가 가진 유일한 문제는 UI 때문입니다. Flymake는 오류와 경고를 멋지게 강조한 다음 전체 오류 또는 경고 텍스트가 포함 된 툴팁으로 "오버레이"를 삽입합니다. 코드에서 강조 표시된 행 위에 마우스 포인터를 올려 놓으면 오버레이 툴팁이 나타납니다. 당신이 볼 수있는

alt text http://i42.tinypic.com/qqu0ja.jpg

는 단, 오버레이 툴팁가 잘립니다, 그리고 제대로 표시되지 않습니다.

플라이 메이크가 옳은 일을하고있는 것 같습니다. 그것은 겹쳐 보이는 오버레이 부분입니다. 이고 오버레이가 올바른 일을하는 것처럼 보입니다. 잘못 표시된 툴팁입니다.

do overlay 툴팁이 Windows 용 emacs에서 올바르게 작동합니까?

어디에서 해결할 수 있습니까?


은 몇 가지 조사 후, 나는 효과가 (tooltip-show really-long-string)

그것은 오버레이 또는 flymake과 아무 상관이와 논증 할 수있는 것으로 나타났습니다.

+0

버그처럼 보일지 모르지만,'M-x report-emacs-bug' –

+0

조금 더 자세히 읽은 후에, 진짜 문제는 오버레이가 아니라 툴팁입니다. – Cheeso

+0

나를 위해 잘 작동하는 것처럼 단일 행 툴팁이 나타납니다 (예 : 버퍼 모드에서 버퍼 위로 마우스를 이동). 너의 것이 멀티 라인인데, 나는 그것이 어디서 떨어지기 시작할 것인가? – Bahbar

답변

8

나는 이것을 툴팁 쇼의 결함으로 해결했다.

;; Reforms a single-line string ARG to a multi-line string with a max 
;; of LIMIT chars on a line. 
;; 
;; This is intended to solve a problem with the display of tooltip text 
;; in emacs on Win32 - which is that the tooltip is extended to be very very 
;; long, and the final line is clipped. 
;; 
;; The solution is to split the text into multiple lines, and to add a 
;; trailing newline to trick the tooltip logic into doing the right thing. 
;; 
(defun cheeso-reform-string (limit arg) 
    (let ((orig arg) (modified "") (curline "") word 
     (words (split-string arg " "))) 
    (while words 
     (progn 
     (setq curline "") 
     (while (and words (< (length curline) limit)) 
      (progn 
      (setq word (car words)) 
      (setq words (cdr words)) 
      (setq curline (concat curline " " word)))) 
     (setq modified (concat modified curline "\n")))) 
    (setq modified (concat modified " \n"))) 
) 

(defadvice tooltip-show (before 
         flymake-csharp-fixup-tooltip 
         (arg &optional use-echo-area) 
         activate compile) 
    (progn 
    (if (and (not use-echo-area) 
      (eq major-mode 'csharp-mode)) 
     (let ((orig (ad-get-arg 0))) 
      (ad-set-arg 0 (cheeso-reform-string 72 orig)) 
     )))) 

는 결과 : flymake이 오류를 표시 할 때, 팝업 "빠른 수정"옵션 메뉴를 얻을 수

alt text http://i41.tinypic.com/1zoylg8.jpg

0

이 flymake 물건을 만지작 때이 있었다 진짜 목표였다 . Visual Studio는 ALT-Shift-F10 또는 이와 비슷한 것을 클릭하면이 작업을 수행합니다.

그리고 몇 가지 기본 시나리오에서 작동하도록했습니다. 다음은 사용자 경험입니다.

1 단계 : 해결되지 않은 형식 참조 (이 경우 스트림)로 코드를 작성하십시오. Flymake 플래그이 같은 문제 :

alt text http://i41.tinypic.com/8xo29t.jpg

2 단계 : 빠른 수정이 메뉴 항목을 선택하고 : (flymake-display-err-menu-for-current-line)

alt text http://i40.tinypic.com/mwryw0.jpg

3 단계를 통해 flymake 오류 팝업 메뉴에 자동 적용됩니다.

  • 오류 CS0246 :

    alt text http://i39.tinypic.com/w1z4n5.jpg


    나는 몇 가지 특별한 경우를 "빠른 수정"옵션을 제공하기 위해 배열 형식 또는 네임 스페이스를 찾을 수 없습니다 'XXXX'

  • 오류 CS1002 : 세미콜론 예상 됨
  • 오류 CS0103 : '식별자'이름이 현재 컨텍스트에 없습니다.

트릭은 또 다시 조언이었습니다. 이 시간은 flymake-make-emacs-menu fn입니다. 플라이 메이크 (flakemake) 내의 해당 기능은 x-popup-menu으로 직접 전달되는 데이터 구조를 준비합니다. advice ("after"advice)는 에러리스트를 파싱하고, 알려진 에러 코드를 찾아 내고, 팝업 메뉴에서 "monkey patches"를 선택하여 에러를 수정하기위한 옵션을 삽입한다.

;; The flymake-make-emacs-menu function prepares the menu for display in 
;; x-popup-menu. But the menu from flymake is really just a static list 
;; of errors. Clicking on any of the items, does nothing. This advice 
;; re-jiggers the menu structure to add dynamic actions into the menu, 
;; for some error cases. For example, with an unrecognized type error 
;; (CS0246), this fn injects a submenu item that when clicked, will 
;; insert a using statement into the top of the file. Other errors are 
;; also handled. 
;; 
;; This won't work generally. It required some changes to flymake.el, 
;; so that flymake-goto-next-error would go to the line AND column. The 
;; original flymake only goes to the line, not the column. Therefore, 
;; quickfixes like inserting a semicolon or a namespace in front of a 
;; typename, won't work because the position is off. 
;; 
(defadvice flymake-make-emacs-menu (after 
            flymake-csharp-offer-quickfix-menu 
            () 
            activate compile) 
    (let* ((menu ad-return-value) 
     (title (car menu)) 
     (items (cadr menu)) 
     action 
     new-items 
     ) 

    (setq new-items (mapcar 
        '(lambda (x) 
         (let ((msg (car x)) missing-type namespace m2 m3) 
          (cond ((or (string-match "error CS0246:" msg) 
            (string-match "error CS0103:" msg)) 

           (progn 
            (string-match "^\\(.+'\\([^']+\\)'[^(]+\\)" msg) 
            (setq missing-type (substring msg 
                   (match-beginning 2) 
                   (match-end 2))) 

            ;; trim the message to get rid of the (did you forget to ...?) 
            (setq msg 
             (substring msg 
                (match-beginning 1) 
                (match-end 1))) 
            (setq namespace (csharp-get-namespace-for-type missing-type)) 
            (if namespace 
             ;; the namespace was found 
             (progn 
             (setq m2 (concat "insert using " namespace ";")) 
             (setq m3 (concat namespace "." missing-type)) 
             (list msg 
               (list m2 'csharp-insert-using-clause-for-type missing-type) 
               (list m3 'csharp-insert-fully-qualified-type namespace) 
               (list "resolve this type reference manually"))) 
            ;; couldn't find the namespace; maybe it's just a typo 
            (list msg 
              (list "resolve this type reference manually"))))) 

           ;; missing semicolon 
           ((string-match "error CS1002:" msg) 
           (progn 
            (list msg 
              (list "insert ; " 'insert ";")) 
            )) 

           ;; all other cases 
           (t 
           ;; no quick fixes for this error 
           (list msg 
             (list "resolve this error manually")))))) 
        (cdr items))) 

    ;; If there's only one menu item, it sometimes won't display 
    ;; properly. The main error message is hidden, and the submenu 
    ;; items become the menu items. I don't know why. Appending a list 
    ;; of ("" nil) to the end, insures that the menu will display 
    ;; properly. 
    (setq new-items (append new-items (list (list "" nil)))) 

    ;; finally, set the return value 
    (setq ad-return-value (cons title new-items)) 

    ;; (setq ad-return-value (list title 
    ;;        (list "item1" (list "choice 1.A" 1) (list "choice 1.B" 2)) 
    ;;        (list "item2" (list "choice 2.A" 3) (list "choice 2.B" 4)) 
    ;;        (list "item3") 
    ;;       )) 

    )) 

또한 수정은 "사용하여 삽입"System.IO.Stream처럼 정규화 된 형식 이름에 Stream처럼 짧은 형식의 이름을 확인 조회 기능에 따라 달라집니다. 그것은 별개의 문제입니다.

(defun csharp-insert-using-clause (namespace) 
    "inserts a new using clause, for the given namespace" 
    (interactive "sInsert using clause; Namespace: ") 
    (save-excursion 
    (let ((beginning-of-last-using (re-search-backward "^[ \t]*using [^ ]+;"))) 
     (end-of-line) 
     (newline) 
     (insert (concat "using " namespace ";")) 
    ) 
) 
) 

나는이 다른 유형의 빠른 수정 사항을 처리하기 위해 확장 될 수 있다고 생각 :

사용자가 빠른 수정을 적용 할 수있는 메뉴 항목을 선택하면, 그것은 새로운 "사용"조항을 삽입 할 FN을 실행 오류. 그러나 나는 그처럼 쉽게 고칠 수있는 오류가 무엇인지 모릅니다. 누구든지 아이디어가 있거나 도움을 원한다면 알려주십시오.

+1

lisp 코드처럼 Lisp 코드 형식을 공유하려고한다면 제발 제발 바랍니다. Trailing ")"은 혼자서 혼란스럽고, lisp 코드를 읽기가 더 어렵게 만든다. –

+0

그건 재밌 네요, 나를 쉽게 읽을 수 있습니다. 실제로 lisp에 대한 표준 형식이 있습니까? – Cheeso

관련 문제