diff --git a/src/Init/System/FilePath.lean b/src/Init/System/FilePath.lean index 0116512b1b..59e66a974b 100644 --- a/src/Init/System/FilePath.lean +++ b/src/Init/System/FilePath.lean @@ -42,11 +42,9 @@ def normalizePath (fname : String) : String := -- else if isCaseInsensitive then c.toLower else c -def dirName (fname : String) : String := +def parent (fname : String) : Option String := let fname := normalizePath fname - match fname.revPosOf pathSeparator with - | none => "." - | some pos => { str := fname, startPos := 0, stopPos := pos : Substring }.toString + fname.extract 0 <$> fname.revPosOf pathSeparator end FilePath diff --git a/src/Init/System/IO.lean b/src/Init/System/IO.lean index a66bf0d78b..18e7a7f969 100644 --- a/src/Init/System/IO.lean +++ b/src/Init/System/IO.lean @@ -328,7 +328,9 @@ def appPath : m String := liftM Prim.appPath def appDir : m String := do let p ← appPath - realPath (System.FilePath.dirName p) + let some p ← pure <| System.FilePath.parent p + | liftM (m := IO) <| throw <| IO.userError s!"System.IO.appDir: unexpected filename '{p}'" + realPath p def currentDir : m String := liftM Prim.currentDir diff --git a/src/Lean/Util/Path.lean b/src/Lean/Util/Path.lean index 72dad5e30a..bb92806025 100644 --- a/src/Lean/Util/Path.lean +++ b/src/Lean/Util/Path.lean @@ -65,11 +65,24 @@ def initSearchPath (path : Option String := none) : IO Unit := let sp ← addSearchPathFromEnv sp searchPathRef.set sp -def findOLean (mod : Name) : IO String := do +partial def findOLean (mod : Name) : IO String := do let sp ← searchPathRef.get - let some fname ← sp.findWithExt ".olean" mod - | throw $ IO.userError $ "unknown package '" ++ mod.getRoot.toString ++ "'" - return fname + if let some fname ← sp.findWithExt ".olean" mod then + return fname + else + let pkg := mod.getRoot + let mut msg := s!"unknown package '{pkg}'" + let rec maybeThisOne dir := do + let dir := s!"{dir}{pathSep}{pkg}" + if ← IO.fileExists dir then + return some s!"\nYou might need to open '{dir}' as a workspace in your editor" + if let some dir ← System.FilePath.parent dir then + maybeThisOne dir + else + return none + if let some msg' ← maybeThisOne (← IO.currentDir) then + msg := msg ++ msg' + throw <| IO.userError msg /-- Infer module name of source file name. -/ @[export lean_module_name_of_file]