2010-04-08 27 views
9

Tôi đang sử dụng Flymake trên mã C#, emacs v22.2.1 trên Windows.Các lớp phủ/chú giải công cụ có hoạt động chính xác trong các Emacs cho Windows không?

Công cụ làm bánh đã hoạt động tốt cho tôi. Đối với những người không biết, you can read an overview of flymake, nhưng câu chuyện nhanh là flymake liên tục xây dựng tệp nguồn mà bạn hiện đang làm việc ở chế độ nền, với mục đích thực hiện kiểm tra cú pháp. Sau đó nó làm nổi bật các cảnh báo trình biên dịch và các erros trong bộ đệm hiện tại.

Flymake không hoạt động đối với C# ban đầu, nhưng I "monkey-patched it" and it works nicely now. Nếu bạn chỉnh sửa C# trong emacs, tôi khuyên bạn nên sử dụng flymake.

Vấn đề duy nhất tôi gặp phải là với giao diện người dùng. Flymake làm nổi bật các lỗi và cảnh báo độc đáo, sau đó chèn "lớp phủ" với chú giải công cụ chứa toàn bộ lỗi hoặc văn bản cảnh báo. Nếu tôi di con trỏ chuột lên dòng được đánh dấu trong mã, thì công cụ che phủ sẽ xuất hiện.

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

Nhưng như bạn có thể thấy, overlay tooltip được cắt bớt, và nó không hiển thị một cách chính xác.

Flymake dường như đang làm điều đúng, đó là phần lớp phủ có vẻ bị hỏng. và lớp phủ dường như làm điều đúng. Đó là chú giải công cụ được hiển thị không chính xác.

Làm lớp phủ chú giải công cụ hoạt động chính xác trong các emacs dành cho Windows?

Tôi tìm cách sửa lỗi này ở đâu?


Sau khi một số nghiên cứu, tôi thấy rằng hiệu quả là có thể chứng minh với (tooltip-show really-long-string)

Nó không có gì để làm với lớp phủ, hoặc flymake.

+0

Trông giống như một lỗi, bạn có thể muốn 'M-x báo cáo-emacs-bug' –

+0

Sau khi đọc thêm về điều này thêm một chút, tôi đoán vấn đề thực sự không phải là với lớp phủ, nhưng chú giải công cụ. – Cheeso

+0

chú giải một dòng trông giống như chúng hoạt động tốt cho tôi (di chuột qua bộ đệm trong chế độ đệm, ví dụ). Của bạn là đa dòng, mà tôi nghi ngờ là nơi nó bắt đầu rơi – Bahbar

Trả lời

8

Tôi đã giải quyết vấn đề này với một hạn chế về hiển thị chú giải công cụ.

;; 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)) 
     )))) 

kết quả:

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

0

Mục đích thực sự tôi đã có, khi loay hoay với những thứ flymake này, là để có được một menu các tùy chọn "sửa chữa nhanh chóng" để bật lên khi flymake hiển thị lỗi . Visual Studio làm điều này nếu bạn bấm ALT-Shift-F10, hoặc một cái gì đó như thế.

Và tôi đã làm việc đó trong một số trường hợp cơ bản. Đây là trải nghiệm người dùng:

Bước 1: viết mã với tham chiếu loại chưa được giải quyết - trong trường hợp này là Luồng. cờ Flymake vấn đề, như thế này:

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

Bước 2: Popup menu lỗi flymake qua (flymake-display-err-menu-for-current-line)

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

Bước 3: Chọn mục menu, và chóng vánh là tự động áp dụng.

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


Tôi sắp xếp để cung cấp "sửa chữa nhanh chóng" tùy chọn trong một vài trường hợp đặc biệt:

  • lỗi CS0246: Loại hoặc không gian tên 'xxxx' không thể tìm được
  • lỗi CS1002: dấu chấm phẩy được mong đợi
  • lỗi CS0103: Tên 'số nhận dạng' không tồn tại trong ngữ cảnh hiện tại.

Bí quyết là, một lần nữa, lời khuyên. Lần này trên flymake-make-emacs-menu fn. Chức năng đó trong flymake chuẩn bị cấu trúc dữ liệu được truyền trực tiếp đến x-popup-menu. Lời khuyên (lời khuyên "sau") phân tích danh sách lỗi, tìm kiếm các mã lỗi đã biết, và nếu tìm thấy, "các bản vá lỗi khỉ" trình đơn bật lên, để chèn các tùy chọn để sửa lỗi.

;; 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") 
    ;;       )) 

    )) 

Các "chèn sử dụng" sửa chữa cũng phụ thuộc vào khả năng tra cứu, mà giải quyết một tên kiểu ngắn, giống như Stream đến một loại tên đầy đủ điều kiện, như System.IO.Stream. Đó là một vấn đề riêng biệt.

Nếu người sử dụng chọn mục trình đơn để áp dụng việc sửa chữa nhanh chóng, nó chạy một fn để chèn một mới "sử dụng" khoản:

(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 ";")) 
    ) 
) 
) 

Tôi nghĩ rằng điều này có thể được mở rộng để xử lý nhanh chóng các bản sửa lỗi cho các loại lỗi. Nhưng tôi không biết những lỗi dễ sửa lỗi đó có thể là gì. Nếu có ai có ý kiến, hoặc muốn giúp đỡ, hãy cho tôi biết.

+1

Xin vui lòng vui lòng nếu bạn định chia sẻ định dạng mã lisp nó giống như mã lisp. Trailing ")" trên các dòng của chính họ đang thực sự mất tập trung, và làm cho mã lisp khó đọc hơn. –

+0

Điều đó thật thú vị, nó giúp tôi dễ đọc hơn. Có thực sự là một định dạng chuẩn cho lisp? – Cheeso

Các vấn đề liên quan