@@ -279,23 +279,28 @@ given a prefix arg."
279279 " Print info on the identifier at point.
280280If PROMPT-VALUE is non-nil, request identifier via mini-buffer."
281281 (interactive " P" )
282- (haskell-process-do-simple-echo
283- (let ((ident (replace-regexp-in-string
284- " ^!\\ ([A-Z_a-z]\\ )"
285- " \\ 1"
286- (if prompt-value
287- (read-from-minibuffer " Info: " (haskell-ident-at-point))
288- (haskell-ident-at-point))))
289- (modname (unless prompt-value
290- (haskell-utils-parse-import-statement-at-point))))
291- (if modname
292- (format " :browse! %s " modname)
293- (format (if (string-match " ^[a-zA-Z_]" ident)
294- " :info %s"
295- " :info (%s)" )
296- (or ident
297- (haskell-ident-at-point)))))
298- 'haskell-mode ))
282+ (let ((at-point (haskell-ident-at-point)))
283+ (when (or prompt-value at-point)
284+ (let* ((ident (replace-regexp-in-string
285+ " ^!\\ ([A-Z_a-z]\\ )"
286+ " \\ 1"
287+ (if prompt-value
288+ (read-from-minibuffer " Info: " at-point)
289+ at-point)))
290+ (modname (unless prompt-value
291+ (haskell-utils-parse-import-statement-at-point)))
292+ (command (cond
293+ (modname
294+ (format " :browse! %s " modname))
295+ ((string= ident " " ) ; For the minibuffer input case
296+ nil )
297+ (t (format (if (string-match " ^[a-zA-Z_]" ident)
298+ " :info %s"
299+ " :info (%s)" )
300+ (or ident
301+ at-point))))))
302+ (when command
303+ (haskell-process-do-simple-echo command 'haskell-mode ))))))
299304
300305;;;### autoload
301306(defun haskell-process-do-type (&optional insert-value )
@@ -369,67 +374,71 @@ to to get there."
369374(defun haskell-process-insert-type ()
370375 " Get the identifer at the point and insert its type, if
371376possible, using GHCi's :type."
372- (let ((process (haskell-interactive-process))
373- (query (let ((ident (haskell-ident-at-point)))
374- (format (if (string-match " ^[_[:lower:][:upper:]]" ident)
375- " :type %s"
376- " :type (%s)" )
377- ident))))
378- (haskell-process-queue-command
379- process
380- (make-haskell-command
381- :state (list process query (current-buffer ))
382- :go (lambda (state )
383- (haskell-process-send-string (nth 0 state)
384- (nth 1 state)))
385- :complete (lambda (state response )
386- (cond
387- ; ; TODO: Generalize this into a function.
388- ((or (string-match " ^Top level" response)
389- (string-match " ^<interactive>" response))
390- (message response))
391- (t
392- (with-current-buffer (nth 2 state)
393- (goto-char (line-beginning-position ))
394- (insert (format " %s \n " (replace-regexp-in-string " \n $" " " response)))))))))))
377+ (let ((ident (haskell-ident-at-point)))
378+ (when ident
379+ (let ((process (haskell-interactive-process))
380+ (query (format (if (string-match " ^[_[:lower:][:upper:]]" ident)
381+ " :type %s"
382+ " :type (%s)" )
383+ ident)))
384+ (haskell-process-queue-command
385+ process
386+ (make-haskell-command
387+ :state (list process query (current-buffer ))
388+ :go (lambda (state )
389+ (haskell-process-send-string (nth 0 state)
390+ (nth 1 state)))
391+ :complete (lambda (state response )
392+ (cond
393+ ; ; TODO: Generalize this into a function.
394+ ((or (string-match " ^Top level" response)
395+ (string-match " ^<interactive>" response))
396+ (message response))
397+ (t
398+ (with-current-buffer (nth 2 state)
399+ (goto-char (line-beginning-position ))
400+ (insert (format " %s \n " (replace-regexp-in-string " \n $" " " response)))))))))))))
395401
396402(defun haskell-mode-find-def (ident )
397403 " Find definition location of identifier. Uses the GHCi process
398- to find the location.
404+ to find the location. Returns `nil' if it can't find the
405+ identifier or the identifier isn't a string.
399406
400407Returns:
401408
402409 (library <package> <module>)
403410 (file <path> <line> <col>)
404411 (module <name>)
412+ nil
405413"
406- (let ((reply (haskell-process-queue-sync-request
407- (haskell-interactive-process)
408- (format (if (string-match " ^[a-zA-Z_]" ident)
409- " :info %s"
410- " :info (%s)" )
411- ident))))
412- (let ((match (string-match " -- Defined \\ (at\\ |in\\ ) \\ (.+\\ )$" reply)))
413- (when match
414- (let ((defined (match-string 2 reply)))
415- (let ((match (string-match " \\ (.+?\\ ):\\ ([0-9]+\\ ):\\ ([0-9]+\\ )$" defined)))
416- (cond
417- (match
418- (list 'file
419- (expand-file-name (match-string 1 defined)
420- (haskell-session-current-dir (haskell-interactive-session)))
421- (string-to-number (match-string 2 defined))
422- (string-to-number (match-string 3 defined))))
423- (t
424- (let ((match (string-match " `\\ (.+?\\ ):\\ (.+?\\ )'$" defined)))
425- (if match
426- (list 'library
427- (match-string 1 defined)
428- (match-string 2 defined))
429- (let ((match (string-match " `\\ (.+?\\ )'$" defined)))
430- (if match
431- (list 'module
432- (match-string 1 defined))))))))))))))
414+ (when (stringp ident)
415+ (let ((reply (haskell-process-queue-sync-request
416+ (haskell-interactive-process)
417+ (format (if (string-match " ^[a-zA-Z_]" ident)
418+ " :info %s"
419+ " :info (%s)" )
420+ ident))))
421+ (let ((match (string-match " -- Defined \\ (at\\ |in\\ ) \\ (.+\\ )$" reply)))
422+ (when match
423+ (let ((defined (match-string 2 reply)))
424+ (let ((match (string-match " \\ (.+?\\ ):\\ ([0-9]+\\ ):\\ ([0-9]+\\ )$" defined)))
425+ (cond
426+ (match
427+ (list 'file
428+ (expand-file-name (match-string 1 defined)
429+ (haskell-session-current-dir (haskell-interactive-session)))
430+ (string-to-number (match-string 2 defined))
431+ (string-to-number (match-string 3 defined))))
432+ (t
433+ (let ((match (string-match " `\\ (.+?\\ ):\\ (.+?\\ )'$" defined)))
434+ (if match
435+ (list 'library
436+ (match-string 1 defined)
437+ (match-string 2 defined))
438+ (let ((match (string-match " `\\ (.+?\\ )'$" defined)))
439+ (if match
440+ (list 'module
441+ (match-string 1 defined)))))))))))))))
433442
434443;;;### autoload
435444(defun haskell-mode-jump-to-def (ident )
@@ -612,26 +621,29 @@ command from GHCi."
612621 (interactive " P" )
613622 (let ((ty (haskell-mode-type-at))
614623 (orig (point )))
615- (if insert-value
616- (let ((ident-pos (haskell-ident-pos-at-point)))
617- (cond
618- ((region-active-p )
619- (delete-region (region-beginning )
620- (region-end ))
621- (insert " (" ty " )" )
622- (goto-char (1+ orig)))
623- ((= (line-beginning-position ) (car ident-pos))
624- (goto-char (line-beginning-position ))
625- (insert (haskell-fontify-as-mode ty 'haskell-mode )
626- " \n " ))
627- (t
628- (save-excursion
629- (goto-char (car ident-pos))
630- (let ((col (current-column )))
631- (save-excursion (insert " \n " )
632- (indent-to col))
633- (insert (haskell-fontify-as-mode ty 'haskell-mode )))))))
634- (message " %s " (haskell-fontify-as-mode ty 'haskell-mode )))))
624+ (unless (= (aref ty 0 ) ?\n )
625+ ; ; That seems to be what happens when `haskell-mode-type-at` fails
626+ (if insert-value
627+ (let ((ident-pos (or (haskell-ident-pos-at-point)
628+ (cons (point ) (point )))))
629+ (cond
630+ ((region-active-p )
631+ (delete-region (region-beginning )
632+ (region-end ))
633+ (insert " (" ty " )" )
634+ (goto-char (1+ orig)))
635+ ((= (line-beginning-position ) (car ident-pos))
636+ (goto-char (line-beginning-position ))
637+ (insert (haskell-fontify-as-mode ty 'haskell-mode )
638+ " \n " ))
639+ (t
640+ (save-excursion
641+ (goto-char (car ident-pos))
642+ (let ((col (current-column )))
643+ (save-excursion (insert " \n " )
644+ (indent-to col))
645+ (insert (haskell-fontify-as-mode ty 'haskell-mode )))))))
646+ (message " %s " (haskell-fontify-as-mode ty 'haskell-mode ))))))
635647
636648;;;### autoload
637649(defun haskell-process-generate-tags (&optional and-then-find-this-tag )
0 commit comments