C# 覆盖图/工具提示在Emacs for Windows中是否正常工作?
我在C代码上使用Flymake,在Windows上使用emacs v22.2.1 Flymake的东西对我来说一直很好用。对于那些不知道的人来说,最简单的故事是flymake会在后台反复构建您当前正在处理的源文件,以便进行语法检查。然后突出显示当前缓冲区中的编译器警告和错误 Flymake最初并不为C#工作,但是。如果您在emacs中编辑C#,我强烈建议您使用flymake 我唯一的问题是UI。Flymake很好地突出显示错误和警告,然后插入带有包含完整错误或警告文本的工具提示的“覆盖图”。如果将鼠标指针悬停在代码中高亮显示的行上,将弹出覆盖工具提示 但正如您所看到的,叠加工具提示被剪裁,并且无法正确显示 Flymake似乎做了正确的事情,覆盖层部分似乎坏了,覆盖层似乎做了正确的事情。工具提示显示不正确 覆盖工具提示在emacs for Windows中是否正常工作 我应该在哪里解决这个问题C# 覆盖图/工具提示在Emacs for Windows中是否正常工作?,c#,emacs,C#,Emacs,我在C代码上使用Flymake,在Windows上使用emacs v22.2.1 Flymake的东西对我来说一直很好用。对于那些不知道的人来说,最简单的故事是flymake会在后台反复构建您当前正在处理的源文件,以便进行语法检查。然后突出显示当前缓冲区中的编译器警告和错误 Flymake最初并不为C#工作,但是。如果您在emacs中编辑C#,我强烈建议您使用flymake 我唯一的问题是UI。Flymake很好地突出显示错误和警告,然后插入带有包含完整错误或警告文本的工具提示的“覆盖图”。如果
经过一些研究,我发现
(工具提示显示很长的字符串)
它与覆盖层或flymake无关 我通过在工具提示上的修改解决了这个问题
;; 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))
))))
;;将单行字符串ARG改为具有max的多行字符串
;; 在一条线上限制字符数。
;;
;; 这旨在解决工具提示文本的显示问题
;; 在Win32上的emacs中,工具提示被扩展为非常
;; 很长,最后一行被剪掉了。
;;
;; 解决方案是将文本拆分为多行,并添加
;; 跟踪换行符以欺骗工具提示逻辑,使其执行正确的操作。
;;
(defun cheeso改革字符串(limit arg)
(let((原arg)(修饰“”)(卷线“”)单词
(单词(拆分字符串arg“”))
(而文字
(项目
(setq卷曲线“”)
(while(和单词(<(长度卷曲线)限制))
(项目
(setq单词(汽车单词))
(setq字(cdr字))
(setq卷曲线(concat卷曲线“单词”))
(setq修改(concat修改的卷曲线“\n”))
(setq修改(concat修改“\n”))
)
(defadvice工具提示显示(之前)
flymake csharp修复工具提示
(参数&可选使用回音区域)
激活(编译)
(项目
(如果(和)(不使用回波区)
(均衡器主模式“csharp模式”)
(let((原始(ad get arg 0)))
(ad set arg 0(奇索改革字符串72原点))
))))
结果:
当我摆弄这个flymake的东西时,我真正的目标是当flymake显示错误时,得到一个“快速修复”选项的菜单弹出。如果单击ALT-Shift-F10或类似的内容,VisualStudio会执行此操作 在一些基本的场景中,我让它起作用了。 以下是用户体验: 步骤1:使用未解析的类型引用编写代码-在本例中为Stream。Flymake会标记问题,如下所示: 步骤2:通过
弹出flymake错误菜单(当前行的flymake显示错误菜单)
步骤3:选择菜单项,快速修复将自动应用
我安排为一些特殊情况提供“快速修复”选项:
- 错误CS0246:找不到类型或命名空间“xxxx”
- 错误CS1002:需要分号
- 错误CS0103:名称“标识符”在当前上下文中不存在李>
flymake-make-emacs菜单上
fn。flymake中的该功能准备直接传递到x-popup-menu
的数据结构。通知(“之后”通知)解析错误列表,查找已知的错误代码,如果找到,则在弹出菜单中“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以插入新的“使用”子句:
(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 ";"))
)
)
)
我认为这可以扩展到处理其他类型错误的快速修复。但我不知道这些容易修复的错误可能是什么。如果有人有任何想法,或想帮忙,请告诉我 看起来像一个bug,你可能想
M-x报告emacs bug
在进一步阅读之后,我想真正的问题不是覆盖,而是工具提示。单行工具提示看起来对我来说很好(例如,在缓冲区模式下悬停在缓冲区上)。你的是多行,我怀疑这就是它开始出错的地方。我不知道它是多行,还是一条很长的错误消息。但你是对的,多行工具提示不起作用。我通过运行带有嵌入式\n
字符串的工具提示show
看到了这一点。有人建议在Windows上的v23.x中修复emacs中的此错误。其他人可以确认吗?如果你要像lisp代码一样共享lisp代码格式,请确认。在行上拖尾“)”会让人分心,让lisp代码更难阅读。这很有趣,对我来说更容易阅读。lisp真的有标准格式吗?