|
49 | 49 | (cl-defmethod xref-backend-identifier-completion-table ((_backend (eql merlin-xref))) |
50 | 50 | nil) |
51 | 51 |
|
| 52 | +(defconst merlin-xref--operator-regexp |
| 53 | + (eval-when-compile |
| 54 | + (let* ((core-operator-char |
| 55 | + `(or "$" "&" "*" "+" "-" "/" "=" ">" "@" "^" "|")) |
| 56 | + (operator-char `(or "~" "!" "?" ,core-operator-char "%" "<" ":" ".")) |
| 57 | + (prefix-symbol `(or (seq "!" (* ,operator-char)) |
| 58 | + (seq (or "?" "~") (+ ,operator-char)))) |
| 59 | + (infix-symbol `(or (seq (or ,core-operator-char "%" "<") |
| 60 | + (* ,operator-char)) |
| 61 | + (seq "#" (+ ,operator-char)))) |
| 62 | + (infix-op `(or ,infix-symbol |
| 63 | + ":=" |
| 64 | + ;; Already handled as part of `infix-symbol': |
| 65 | + ;; "*" "+" "-" "-." "=" "!=" "<" ">" "||" "&" "&&" |
| 66 | + ;; Treated as normal symbols: |
| 67 | + ;; "or" "mod" "land" "lor" "lxor" "lsl" "lsr" "asr" |
| 68 | + )) |
| 69 | + (operator-name `(or ,prefix-symbol ,infix-op))) |
| 70 | + (rx-to-string operator-name t)))) |
| 71 | + |
| 72 | +(defconst merlin-xref--binding-operator-regexp |
| 73 | + (eval-when-compile |
| 74 | + (let* ((core-operator-char |
| 75 | + `(or "$" "&" "*" "+" "-" "/" "=" ">" "@" "^" "|")) |
| 76 | + (dot-operator-char |
| 77 | + `(or "!" "?" ,core-operator-char "%" ":")) |
| 78 | + (binding-suffix |
| 79 | + `(seq (or ,core-operator-char "<") (* ,dot-operator-char))) |
| 80 | + (binding-operator |
| 81 | + `(seq symbol-start (or "let" "and") ,binding-suffix))) |
| 82 | + (rx-to-string binding-operator t)))) |
| 83 | + |
| 84 | +(defconst merlin-xref--identifier-regexp |
| 85 | + (rx symbol-start (in "A-Za-z_") (* (in "A-Za-z0-9_'")))) |
| 86 | + |
52 | 87 | (cl-defmethod xref-backend-identifier-at-point ((_backend (eql merlin-xref))) |
53 | | - (let ((symbol (thing-at-point 'symbol))) |
| 88 | + (let ((symbol |
| 89 | + (and |
| 90 | + (or |
| 91 | + ;; Starting at point: |
| 92 | + ;; - binding operator |
| 93 | + (looking-at merlin-xref--binding-operator-regexp) |
| 94 | + ;; - ordinary name |
| 95 | + (looking-at merlin-xref--identifier-regexp) |
| 96 | + ;; - operator |
| 97 | + (looking-at merlin-xref--operator-regexp) |
| 98 | + ;; Starting before point: |
| 99 | + (let ((pt (point))) |
| 100 | + (and (or |
| 101 | + ;; - binding operator |
| 102 | + (save-excursion |
| 103 | + (skip-chars-backward "letand$&*+/=<>@^|!?%:-") |
| 104 | + (looking-at merlin-xref--binding-operator-regexp)) |
| 105 | + ;; - ordinary name |
| 106 | + (save-excursion |
| 107 | + (skip-chars-backward "A-Za-z0-9_'") |
| 108 | + (looking-at merlin-xref--identifier-regexp)) |
| 109 | + ;; - operator |
| 110 | + (save-excursion |
| 111 | + (skip-chars-backward "$&*+/=<>@^|!?%:.~#-") |
| 112 | + (looking-at merlin-xref--operator-regexp))) |
| 113 | + |
| 114 | + (<= pt (match-end 0))))) |
| 115 | + (match-string 0)))) |
54 | 116 | ;; Return a string with the buffer position in a property, in case |
55 | 117 | ;; point changes before the string is used by one of the methods above. |
56 | 118 | (and symbol (propertize symbol 'merlin-xref-point (point))))) |
|
0 commit comments