El verdadero objetivo que tenía, al estar manejando estas cosas flymake, era conseguir un menú de opciones "solución rápida" para que aparezca cuando flymake muestra los errores . Visual Studio hace esto si haces clic en ALT-Shift-F10, o algo así.
Y, lo tengo para trabajar, en algunos escenarios básicos. Aquí está la experiencia del usuario:
Paso 1: escriba el código con una referencia de tipo no resuelto, en este caso, Stream. banderas Flymake el problema, de esta manera:
alt text http://i41.tinypic.com/8xo29t.jpg
Paso 2: ejecutar el menú de error flymake través (flymake-display-err-menu-for-current-line)
alt text http://i40.tinypic.com/mwryw0.jpg
Paso 3: Seleccionar la opción de menú, y la solución rápida es aplicado automáticamente
alt text http://i39.tinypic.com/w1z4n5.jpg
Me dispuesto para proporcionar opciones "solución rápida" para algunos casos especiales: CS0246
- de error: El tipo o espacio de nombres 'xxxx' no se pudo encontrar
- error CS1002: punto y coma esperado
- error CS0103: El nombre "identificador" no existe en el contexto actual.
El truco fue, de nuevo, un consejo. Esta vez en el flymake-make-emacs-menu
fn. Esa función dentro de flymake prepara la estructura de datos que se pasa directamente al x-popup-menu
. El consejo (consejo "después") analiza la lista de errores, busca los códigos de error conocidos, y si se encuentra, "parches de mono" en el menú emergente, para insertar opciones para corregir el error.
;; 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")
;; ))
))
El "inserto usando" fijar también depende de una capacidad de búsqueda, que resuelve un nombre de tipo corto, como Stream
a un nombre de tipo totalmente cualificado, como System.IO.Stream
. Ese es un problema aparte.
Si el usuario selecciona la opción de menú para aplicar la solución rápida, se ejecuta un fn para insertar un nuevo "uso" cláusula:
(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 ";"))
)
)
)
Creo que esto podría ampliarse para manejar soluciones rápidas para otros tipos de errores Pero no sé cuáles podrían ser esos errores fáciles de corregir. Si alguien tiene alguna idea, o quiere ayudar, avíseme.
Parece un error, es posible que desee 'M-x report-emacs-bug' –
Después de leer sobre esto un poco más, supongo que el problema real no es con superposiciones, sino información sobre herramientas. – Cheeso
tooltips de una sola línea parece que funcionan bien para mí (pase el mouse sobre un búfer en modo búfer, por ejemplo). El tuyo es multilínea, sospecho que es donde comienza a caer – Bahbar