Function: haskell-ident-pos-at-point
haskell-ident-pos-at-point is a natively compiled function defined in
haskell-mode.el.
Signature
(haskell-ident-pos-at-point)
Documentation
Return the span of the identifier near point going backward.
Returns nil if no identifier found or point is inside string or comment. May return a qualified name.
Source Code
;; Defined in /nix/store/9lz2mhw95f9fqxr9mnq46k3f6qz3aq83-emacs-packages-deps/share/emacs/site-lisp/elpa/haskell-mode-20260904.1042/haskell-mode.el
(defun haskell-ident-pos-at-point ()
"Return the span of the identifier near point going backward.
Returns nil if no identifier found or point is inside string or
comment. May return a qualified name."
(when (not (nth 8 (syntax-ppss)))
;; Do not handle comments and strings
(let (start end)
;; Initial point position is non-deterministic, it may occur anywhere
;; inside identifier span, so the approach is:
;; - first try go left and find left boundary
;; - then try go right and find right boundary
;;
;; In both cases assume the longest path, e.g. when going left take into
;; account than point may occur at the end of identifier, when going right
;; take into account that point may occur at the beginning of identifier.
;;
;; We should handle `.` character very careful because it is heavily
;; overloaded. Examples of possible cases:
;; Control.Monad.>>= -- delimiter
;; Control.Monad.when -- delimiter
;; Data.Aeson..: -- delimiter and operator symbol
;; concat.map -- composition function
;; .? -- operator symbol
(save-excursion
;; First, skip whitespace if we're on it, moving point to last
;; identifier char. That way, if we're at "map ", we'll see the word
;; "map".
(when (and (eolp)
(not (bolp)))
(backward-char))
(when (and (not (eobp))
(eq (char-syntax (char-after)) ? ))
(skip-chars-backward " \t")
(backward-char))
;; Now let's try to go left.
(save-excursion
(if (not (haskell-mode--looking-at-varsym))
;; Looking at non-operator char, this is quite simple
(progn
(skip-syntax-backward "w_")
;; Remember position
(setq start (point)))
;; Looking at operator char.
(while (and (not (bobp))
(haskell-mode--looking-at-varsym))
;; skip all operator chars backward
(setq start (point))
(backward-char))
;; Extra check for case when reached beginning of the buffer.
(when (haskell-mode--looking-at-varsym)
(setq start (point))))
;; Slurp qualification part if present. If identifier is qualified in
;; case of non-operator point will stop before `.` dot, but in case of
;; operator it will stand at `.` delimiting dot. So if we're looking
;; at `.` let's step one char forward and try to get qualification
;; part.
(goto-char start)
(when (looking-at-p (rx "."))
(forward-char))
(let ((pos (haskell-mode--skip-qualification-backward)))
(when pos
(setq start pos))))
;; Finally, let's try to go right.
(save-excursion
;; Try to slurp qualification part first.
(skip-syntax-forward "w_")
(setq end (point))
(while (and (looking-at (rx "." upper))
(not (zerop (progn (forward-char)
(skip-syntax-forward "w_")))))
(setq end (point)))
;; If point was at non-operator we already done, otherwise we need an
;; extra check.
(while (haskell-mode--looking-at-varsym)
(forward-char)
(setq end (point))))
(when (not (= start end))
(cons start end))))))