代码之家  ›  专栏  ›  技术社区  ›  Cheeso

套印格式/工具提示在Emacs for Windows中是否正常工作?

  •  9
  • Cheeso  · 技术社区  · 15 年前

    我使用的是C代码上的Flymake,Windows上的EmacsV22.2.1。

    Flymake的产品对我来说一直很好。对于那些不知道的人, you can read an overview of flymake 但最快的情况是,为了进行语法检查,Flymake会反复构建当前在后台工作的源文件。然后它突出显示当前缓冲区中的编译器警告和错误。

    最初,Flymake不适用于C,但 I "monkey-patched it" and it works nicely now . 如果您在Emacs中编辑c,我强烈建议您使用Flymake。

    唯一的问题是UI。Flymake可以很好地突出显示错误和警告,然后使用包含完整错误或警告文本的工具提示插入“覆盖”。如果将鼠标指针悬停在代码中突出显示的行上, 覆盖 弹出工具提示。

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

    但正如你所见, 覆盖 工具提示被剪切,并且显示不正确。

    Flymake似乎做得对, 似乎是覆盖部分损坏了。 和覆盖似乎做了正确的事情。是工具提示显示不正确。

    覆盖物 工具提示在Emacs for Windows中正常工作?

    我要在哪里解决这个问题?


    经过一些研究,我发现这种效果是可以证明的 (tooltip-show really-long-string)

    它与覆面或Flymake无关。

    2 回复  |  直到 14 年前
        1
  •  8
  •   Cheeso    15 年前

    我在工具提示节目上用涂鸦解决了这个问题。

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

    结果:

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

        2
  •  0
  •   Cheeso    14 年前

    当我摆弄这个flymake的东西时,我真正的目标是得到一个“快速修复”选项菜单,当flymake显示错误时弹出。如果单击alt-shift-f10或类似的按钮,Visual Studio将执行此操作。

    而且,我让它在一些基本场景中发挥作用。 以下是用户体验:

    步骤1:使用未解析的类型引用编写代码-在本例中,为stream。Flymake标记问题,如下所示:

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

    步骤2:通过弹出flymake错误菜单 (flymake-display-err-menu-for-current-line)

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

    步骤3:选择菜单项,自动应用快速修复。

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


    我安排为一些特殊情况提供“快速修复”选项:

    • 错误CS0246:找不到类型或命名空间“XXXX”
    • 错误CS1002:需要分号
    • 错误CS0103:当前上下文中不存在名称“identifier”。

    诀窍还是建议。这次在 flymake-make-emacs-menu FN。Flymake中的函数准备直接传递给 x-popup-menu . 通知(“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")
        ;;                             ))
    
        ))
    

    “insert using”修复程序还依赖于查找功能,该功能解析短类型名,例如 Stream 完全限定的类型名,例如 System.IO.Stream . 这是另外一个问题。

    如果用户选择菜单项应用快速修复,则运行fn以插入新的“using”子句:

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

    我认为这可以扩展到处理其他类型错误的快速修复。但我不知道那些容易修复的错误可能是什么。如果有人有任何想法或想帮忙,请告诉我。