Zulip Chat Archive
Stream: mathlib4
Topic: Try this
Johan Commelin (Jan 06 2023 at 10:15):
Can we make "Try this" work in the Lean4 VScode? Maybe there are plans to have a better solution in the future, but I think it's really useful to have a tmp fix as well.
Johan Commelin (Jan 06 2023 at 10:15):
Doesn't even have to be via the extension. If someone knows how to make it work via some other snippet, or so.
Heather Macbeth (Jan 06 2023 at 17:50):
I hadn't even realised that it wasn't working! I've had mysterious output before from library_search
and abel
and I guess that would explain it.
Mario Carneiro (Jan 06 2023 at 23:17):
I think @Gabriel Ebner should make the call on whether it would be good to introduce a short term solution here
Wojciech Nawrocki (Jan 07 2023 at 04:14):
In the meantime here is one short-term solution:
import Lean.Widget.UserWidget
open Lean Widget
@[widget]
def tryThisWidget : UserWidgetDefinition where
name := "Try this"
javascript := "
import * as React from 'react'
import { EditorContext } from '@leanprover/infoview'
const e = React.createElement
/**
* @typedef TryThisProps
* @type {object}
* @property {DocumentPosition} pos - where the text cursor is.
* @property {TextEdit} edit - the edit to apply.
*/
export default function({pos, edit}) {
const textDocEdit = {
textDocument: {
uri: pos.uri,
version: null
},
edits: [edit]
}
const ec = React.useContext(EditorContext)
const aProps = {
className: 'link pointer dim',
onClick: () => {
const workspaceEdit = {
documentChanges: [textDocEdit]
}
console.log(workspaceEdit)
ec.api.applyEdit(workspaceEdit)
}
}
return e('a', aProps, `Try this: ${edit.newText}`)
}
"
def Lean.FileMap.utf8RangeToLspRange (text : FileMap) (range : String.Range) : Lsp.Range where
start := text.utf8PosToLspPos range.start
«end» := text.utf8PosToLspPos range.stop
/-- Call this from a tactic or other metaprogram in order to display a "Try this" link in the infoview
when the cursor is on `ref`. When clicked, the link will replace `replaceRef` with `newText`. -/
def saveTryThis (ref : Syntax) (newText : String) (replaceRef := ref) : MetaM Unit := do
let some range := replaceRef.getRange? |
throwError "No position associated with syntax '{replaceRef}'. Is it synthetic?"
let text ← getFileMap
let textEdit : Lsp.TextEdit := { range := text.utf8RangeToLspRange range, newText }
logInfo m!"Try this: {newText}"
saveWidgetInfo
``tryThisWidget
(Json.mkObj [
("edit", toJson textEdit)
])
ref
elab "secretlyrfl" : tactic => do
let ref ← getRef
saveTryThis ref "rfl"
example : 2 + 2 = 4 := by
secretlyrfl
Wojciech Nawrocki (Jan 07 2023 at 04:18):
One issue is that this comes up with a non-clickable message, and a separate yes-clickable panel in the infoview. A proper solution would be good but is a little technically involved (a MessageData.ofWidget
constructor).
Last updated: Dec 20 2023 at 11:08 UTC