Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hover] [api] Allow hover access to full document. #591

Merged
merged 1 commit into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
information on hover; previous flag was fixed in code, which is way
less flexible. This also fixes the option being on in 0.1.8 by
mistake (@ejgallego, #588)
- hover plugins can now access the full document, this is convenient
for many use cases (@ejgallego, #591)

# coq-lsp 0.1.8: Trick-or-treat
-------------------------------
Expand Down
22 changes: 14 additions & 8 deletions controller/rq_hover.ml
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,16 @@ open Fleche
(* Hover handler *)
module Handler = struct
(** Returns [Some markdown] if there is some hover to match *)
type 'node h =
type 'node h_node =
contents:Contents.t -> point:int * int -> node:'node -> string option

type h_doc =
doc:Doc.t -> point:int * int -> node:Doc.Node.t option -> string option

type t =
| MaybeNode : Doc.Node.t option h -> t
| WithNode : Doc.Node.t h -> t
| MaybeNode : Doc.Node.t option h_node -> t
| WithNode : Doc.Node.t h_node -> t
| WithDoc : h_doc -> t
end

module type HoverProvider = sig
Expand Down Expand Up @@ -207,23 +211,25 @@ module Register = struct
let handlers : Handler.t list ref = ref []
let add fn = handlers := fn :: !handlers

let handle ~contents ~point ~node = function
let handle ~(doc : Doc.t) ~point ~node =
let contents = doc.contents in
function
| Handler.MaybeNode h -> h ~contents ~point ~node
| Handler.WithNode h ->
Option.bind node (fun node -> h ~contents ~point ~node)
| Handler.WithDoc h -> h ~doc ~point ~node

let fire ~contents ~point ~node =
List.filter_map (handle ~contents ~point ~node) !handlers
let fire ~doc ~point ~node =
List.filter_map (handle ~doc ~point ~node) !handlers
end

(* Register in-file hover plugins *)
let () = List.iter Register.add [ Loc_info.h; Stats.h; Type.h; Notation.h ]

let hover ~doc ~point =
let contents = doc.Doc.contents in
let node = Info.LC.node ~doc ~point Exact in
let range = Option.map Doc.Node.range node in
let hovers = Register.fire ~contents ~point ~node in
let hovers = Register.fire ~doc ~point ~node in
match hovers with
| [] -> `Null
| hovers ->
Expand Down
16 changes: 13 additions & 3 deletions controller/rq_hover.mli
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,22 @@ open Fleche

module Handler : sig
(** Returns [Some markdown] if there is some hover to match *)
type 'node h =
type 'node h_node =
contents:Contents.t -> point:int * int -> node:'node -> string option

type h_doc =
doc:Doc.t -> point:int * int -> node:Doc.Node.t option -> string option

(** Many use cases could be grouped into a hook that would pass an
[Identifier_context.] object, containing the object, its location,
documentation, and some other relevant information.
For now we provide hooks for node inspection, contents inspection, and
document (usually TOC + contents) inspection. *)
type t =
| MaybeNode : Doc.Node.t option h -> t
| WithNode : Doc.Node.t h -> t
| MaybeNode : Doc.Node.t option h_node -> t
| WithNode : Doc.Node.t h_node -> t
| WithDoc : h_doc -> t
end

(** Register a hover plugin *)
Expand Down
Loading