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

feat: add #help note command #948

Merged
merged 30 commits into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1f7bcc0
Add check_note command
edegeltje Sep 14, 2024
4f13b7c
Update LibraryNote.lean
edegeltje Sep 19, 2024
6251e89
Merge branch 'leanprover-community:main' into check-note-command
edegeltje Sep 20, 2024
e51570d
Merge branch 'main' into check-note-command
edegeltje Sep 26, 2024
2b3dc76
i promise it builds this time
Sep 26, 2024
112372d
Merge branch 'leanprover-community:main' into check-note-command
edegeltje Sep 28, 2024
dc95500
Merge remote-tracking branch 'origin/main' into check-note-command
Oct 16, 2024
479c45c
change to #help
Oct 16, 2024
600ce80
more switching, adding authorship
Oct 16, 2024
7b56b6f
improve style, add test
Oct 16, 2024
174a55c
add additional notes for testing, test imported notes.
Oct 16, 2024
4201f3a
fix batteries.lean, add code for prefix search.
Oct 16, 2024
e31da2f
fix typo
Oct 16, 2024
4c03b24
apparently i can't read
Oct 16, 2024
1359131
Merge branch 'leanprover-community:main' into check-note-command
edegeltje Oct 17, 2024
b22e78c
Merge branch 'main' into check-note-command
edegeltje Oct 17, 2024
319bceb
use head!, implement prefix search, add tests
Oct 17, 2024
a5cc8f4
add requested style changes
Oct 17, 2024
4eba128
remove case-insensitivity
Oct 17, 2024
6f134b5
change displayed delimiter
Oct 17, 2024
273078f
fix test (for now)
Oct 18, 2024
625d456
Merge branch 'leanprover-community:main' into check-note-command
edegeltje Oct 18, 2024
2e0f597
Merge branch 'main' into check-note-command
fgdorais Oct 19, 2024
375c2f5
use markdown style formatting.
Oct 26, 2024
4e47972
Merge branch 'main' into check-note-command
edegeltje Oct 26, 2024
1169c02
add requested suggestion
edegeltje Oct 26, 2024
4f0a07a
update module doc for helpcmd
Oct 26, 2024
2c1b9f1
move the command
Oct 27, 2024
afde65f
remove comment
Oct 27, 2024
d1fff4b
Apply suggestions from code review
edegeltje Oct 27, 2024
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 Batteries.lean
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ import Batteries.Tactic.Trans
import Batteries.Tactic.Unreachable
import Batteries.Tactic.Where
import Batteries.Test.Internal.DummyLabelAttr
import Batteries.Test.Internal.DummyLibraryNote
import Batteries.Test.Internal.DummyLibraryNote2
import Batteries.Util.Cache
import Batteries.Util.ExtendedBinder
import Batteries.Util.LibraryNote
Expand Down
14 changes: 14 additions & 0 deletions Batteries/Test/Internal/DummyLibraryNote.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Batteries.Util.LibraryNote

library_note "test" /--
1: This is a testnote for testing the library note feature of batteries.
The `#help note` command should be able to find this note when imported.
-/

library_note "test" /--
2: This is a second testnote for testing the library note feature of batteries.
-/

library_note "temporary note" /--
1: This is a testnote whose label also starts with "te", but gets sorted before "test"
-/
15 changes: 15 additions & 0 deletions Batteries/Test/Internal/DummyLibraryNote2.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Batteries.Test.Internal.DummyLibraryNote

library_note "test" /--
3: this is a note in a different file importing the above testnotes,
but still imported by the actual testfile.
-/

library_note "Test" /--
1: this is a testnote with a label starting with "Te"
-/

library_note "Other" /--
1: this is a testnote with a label not starting with "te",
so it shouldn't appear when looking for notes with label starting with "te".
-/
44 changes: 43 additions & 1 deletion Batteries/Util/LibraryNote.lean
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/-
Copyright (c) 2022 Gabriel Ebner. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Gabriel Ebner
Authors: Gabriel Ebner, Edward van de Meent
-/
import Lean.Elab.Command

Expand All @@ -15,6 +15,7 @@ open Lean

/-- A library note consists of a (short) tag and a (long) note. -/
def LibraryNoteEntry := String × String
deriving Inhabited

/-- Environment extension supporting `library_note`. -/
initialize libraryNoteExt : SimplePersistentEnvExtension LibraryNoteEntry (Array LibraryNoteEntry) ←
Expand All @@ -35,6 +36,47 @@ creates a new "library note", which can then be cross-referenced using
-- See note [some tag]
```
in doc-comments.
Use `#help note "some tag"` to display all notes with the tag
`"some tag"` in the infoview.
-/
elab "library_note " title:strLit ppSpace text:docComment : command => do
modifyEnv (libraryNoteExt.addEntry · (title.getString, text.getDocString))

/--
format the string to be included in a single markdown bullet
-/
def _root_.String.makeBullet (s:String) := "* " ++ ("\n ").intercalate (s.splitOn "\n")

open Lean Parser in
/--
`#help note "foo"` searches (case-insensitively) for all library notes whose
label starts with "foo", then displays those library notes sorted alphabetically by label,
grouped by label.
The command only displays the library notes that are declared in
imported files or in the same file above the line containing the command.
-/
elab "#help note" name:strLit : command => do
edegeltje marked this conversation as resolved.
Show resolved Hide resolved
let env ← getEnv

-- get the library notes from both this and imported files
let local_entries := (libraryNoteExt.getEntries env).reverse
let imported_entries := (libraryNoteExt.toEnvExtension.getState env).importedEntries

-- filter for the appropriate notes while casting to list
let label_prefix := name.getString
let imported_entries_filtered := imported_entries.flatten.toList.filterMap
fun x => if label_prefix.isPrefixOf x.fst then some x else none
let valid_entries := imported_entries_filtered ++ local_entries.filterMap
fun x => if label_prefix.isPrefixOf x.fst then some x else none
let grouped_valid_entries := valid_entries.mergeSort (·.fst ≤ ·.fst)
|>.groupBy (·.fst == ·.fst)

-- display results in a readable style
if grouped_valid_entries.isEmpty then
logError "Note not found"
else
logInfo <| "\n\n".intercalate <|
grouped_valid_entries.map
fun l => "library_note \"" ++ l.head!.fst ++ "\"\n" ++
"\n\n".intercalate (l.map (·.snd.trim.makeBullet))
-- this could use List.head when List.ne_nil_of_mem_groupBy gets upstreamed from mathlib
47 changes: 47 additions & 0 deletions test/library_note.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Batteries.Util.LibraryNote
import Batteries.Test.Internal.DummyLibraryNote2

/--
error: Note not found
-/
#guard_msgs in
#help note "no note"

/--
info: library_note "Other"
* 1: this is a testnote with a label not starting with "te",
so it shouldn't appear when looking for notes with label starting with "te".
-/
#guard_msgs in
#help note "Other"

library_note "test"/--
4: This note was not imported, and therefore appears below the imported notes.
-/

library_note "test"/--
5: This note was also not imported, and therefore appears below the imported notes,
and the previously added note.
-/


/--
info: library_note "temporary note"
* 1: This is a testnote whose label also starts with "te", but gets sorted before "test"

library_note "test"
* 1: This is a testnote for testing the library note feature of batteries.
The `#help note` command should be able to find this note when imported.

* 2: This is a second testnote for testing the library note feature of batteries.

* 3: this is a note in a different file importing the above testnotes,
but still imported by the actual testfile.

* 4: This note was not imported, and therefore appears below the imported notes.

* 5: This note was also not imported, and therefore appears below the imported notes,
and the previously added note.
-/
#guard_msgs in
#help note "te"