mirror of
https://github.com/unisonweb/unison.git
synced 2024-10-26 02:55:19 +03:00
Merge remote-tracking branch 'upstream/trunk' into doc-lexer
This commit is contained in:
commit
1ee188d0e3
@ -42,7 +42,7 @@ Some tests are executables instead:
|
||||
|
||||
* `stack exec transcripts` runs the transcripts-related integration tests, found in `unison-src/transcripts`. You can add more tests to this directory.
|
||||
* `stack exec transcripts -- prefix-of-filename` runs only transcript tests with a matching filename prefix.
|
||||
* `stack exec integration-tests` runs the additional integration tests for cli. These tests are not triggered by `tests` or `transcripts`.
|
||||
* `stack exec cli-integration-tests` runs the additional integration tests for cli. These tests are not triggered by `tests` or `transcripts`.
|
||||
* `stack exec unison -- transcript unison-src/transcripts-round-trip/main.md` runs the pretty-printing round trip tests
|
||||
* `stack exec unison -- transcript unison-src/transcripts-manual/benchmarks.md` runs the benchmark suite. Output goes in unison-src/transcripts-manual/benchmarks/output.txt.
|
||||
|
||||
@ -220,3 +220,7 @@ nix develop '.#cabal-unison-parser-typechecker'
|
||||
cd unison-cli
|
||||
cabal run --enable-profiling unison-cli-main:exe:unison -- +RTS -p
|
||||
```
|
||||
|
||||
## Native compilation
|
||||
|
||||
See the [readme](scheme-libs/racket/unison/Readme.md).
|
||||
|
@ -35,6 +35,7 @@ module Unison.PatternMatchCoverage
|
||||
)
|
||||
where
|
||||
|
||||
import Data.List.NonEmpty (nonEmpty)
|
||||
import Data.Set qualified as Set
|
||||
import Debug.Trace
|
||||
import Unison.Debug
|
||||
@ -53,24 +54,25 @@ import Unison.Util.Pretty qualified as P
|
||||
checkMatch ::
|
||||
forall vt v loc m.
|
||||
(Pmc vt v loc m) =>
|
||||
-- | the match location
|
||||
loc ->
|
||||
-- | scrutinee type
|
||||
Type.Type vt loc ->
|
||||
-- | match cases
|
||||
[Term.MatchCase loc (Term.Term' vt v loc)] ->
|
||||
-- | (redundant locations, inaccessible locations, inhabitants of uncovered refinement type)
|
||||
m ([loc], [loc], [Pattern ()])
|
||||
checkMatch matchLocation scrutineeType cases = do
|
||||
checkMatch scrutineeType cases = do
|
||||
ppe <- getPrettyPrintEnv
|
||||
v0 <- fresh
|
||||
grdtree0 <- desugarMatch matchLocation scrutineeType v0 cases
|
||||
doDebug (P.hang (title "desugared:") (prettyGrdTree (prettyPmGrd ppe) (\_ -> "<loc>") grdtree0)) (pure ())
|
||||
(uncovered, grdtree1) <- uncoverAnnotate (Set.singleton (NC.markDirty v0 $ NC.declVar v0 scrutineeType id NC.emptyNormalizedConstraints)) grdtree0
|
||||
mgrdtree0 <- traverse (desugarMatch scrutineeType v0) (nonEmpty cases)
|
||||
doDebug (P.hang (title "desugared:") (prettyGrdTreeMaybe (prettyPmGrd ppe) (\_ -> "<loc>") mgrdtree0)) (pure ())
|
||||
let initialUncovered = Set.singleton (NC.markDirty v0 $ NC.declVar v0 scrutineeType id NC.emptyNormalizedConstraints)
|
||||
(uncovered, grdtree1) <- case mgrdtree0 of
|
||||
Nothing -> pure (initialUncovered, Nothing)
|
||||
Just grdtree0 -> fmap Just <$> uncoverAnnotate initialUncovered grdtree0
|
||||
doDebug
|
||||
( P.sep
|
||||
"\n"
|
||||
[ P.hang (title "annotated:") (prettyGrdTree (NC.prettyDnf ppe) (NC.prettyDnf ppe . fst) grdtree1),
|
||||
[ P.hang (title "annotated:") (prettyGrdTreeMaybe (NC.prettyDnf ppe) (NC.prettyDnf ppe . fst) grdtree1),
|
||||
P.hang (title "uncovered:") (NC.prettyDnf ppe uncovered)
|
||||
]
|
||||
)
|
||||
@ -78,9 +80,14 @@ checkMatch matchLocation scrutineeType cases = do
|
||||
uncoveredExpanded <- concat . fmap Set.toList <$> traverse (expandSolution v0) (Set.toList uncovered)
|
||||
doDebug (P.hang (title "uncovered expanded:") (NC.prettyDnf ppe (Set.fromList uncoveredExpanded))) (pure ())
|
||||
let sols = map (generateInhabitants v0) uncoveredExpanded
|
||||
let (_accessible, inaccessible, redundant) = classify grdtree1
|
||||
let (_accessible, inaccessible, redundant) = case grdtree1 of
|
||||
Nothing -> ([], [], [])
|
||||
Just x -> classify x
|
||||
pure (redundant, inaccessible, sols)
|
||||
where
|
||||
prettyGrdTreeMaybe prettyNode prettyLeaf = \case
|
||||
Nothing -> "<empty>"
|
||||
Just x -> prettyGrdTree prettyNode prettyLeaf x
|
||||
title = P.bold
|
||||
doDebug out = case shouldDebug PatternCoverage of
|
||||
True -> trace (P.toAnsiUnbroken out)
|
||||
|
@ -20,19 +20,14 @@ import Unison.Type qualified as Type
|
||||
desugarMatch ::
|
||||
forall loc vt v m.
|
||||
(Pmc vt v loc m) =>
|
||||
-- | loc of match
|
||||
loc ->
|
||||
-- | scrutinee type
|
||||
Type vt loc ->
|
||||
-- | scrutinee variable
|
||||
v ->
|
||||
-- | match cases
|
||||
[MatchCase loc (Term' vt v loc)] ->
|
||||
NonEmpty (MatchCase loc (Term' vt v loc)) ->
|
||||
m (GrdTree (PmGrd vt v loc) loc)
|
||||
desugarMatch loc0 scrutineeType v0 cs0 =
|
||||
traverse desugarClause cs0 >>= \case
|
||||
[] -> pure $ Leaf loc0
|
||||
x : xs -> pure $ Fork (x :| xs)
|
||||
desugarMatch scrutineeType v0 cs0 = Fork <$> traverse desugarClause cs0
|
||||
where
|
||||
desugarClause :: MatchCase loc (Term' vt v loc) -> m (GrdTree (PmGrd vt v loc) loc)
|
||||
desugarClause MatchCase {matchPattern, matchGuard} =
|
||||
|
@ -1525,7 +1525,7 @@ ensurePatternCoverage theMatch _theMatchType _scrutinee scrutineeType cases = do
|
||||
constructorCache = mempty
|
||||
}
|
||||
(redundant, _inaccessible, uncovered) <- flip evalStateT pmcState do
|
||||
checkMatch matchLoc scrutineeType cases
|
||||
checkMatch scrutineeType cases
|
||||
let checkUncovered = case Nel.nonEmpty uncovered of
|
||||
Nothing -> pure ()
|
||||
Just xs -> failWith (UncoveredPatterns matchLoc xs)
|
||||
|
6
scheme-libs/racket/unison/.gitignore
vendored
Normal file
6
scheme-libs/racket/unison/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
compiled/
|
||||
boot-generated.ss
|
||||
builtin-generated.ss
|
||||
compound-wrappers.ss
|
||||
data-info.ss
|
||||
simple-wrappers.ss
|
@ -1,5 +1,18 @@
|
||||
This directory contains libraries necessary for building and running
|
||||
unison programs via Racket Scheme.
|
||||
unison programs via Racket Scheme. The rough steps are as follows:
|
||||
|
||||
* Build Racket libraries from the current Unison version.
|
||||
* Build the `unison-runtime` binary.
|
||||
* Pass the path to `unison-runtime` to `ucm`.
|
||||
|
||||
Native compilation is done via the `compile.native` `ucm` command.
|
||||
Under-the-hood, Unison does the following:
|
||||
|
||||
* Convert the function to bytecode (similar to how `compile` command works).
|
||||
* Call `unison-runtime` which will convert the bytecode to a temporary Racket
|
||||
file. The Racket file is usually placed in your `.cache/unisonlanguage`.
|
||||
* folder. Call `raco exe file.rkt -o executable` which will create a native
|
||||
executable from the Racket source code.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -9,20 +22,56 @@ You'll need to have a couple things installed on your system:
|
||||
* [Racket](https://racket-lang.org/), with the executable `racket` on your path somewhere
|
||||
* [BLAKE2](https://github.com/BLAKE2/libb2) (you may need to install this manually)
|
||||
|
||||
|
||||
In particular, our crypto functions require on both `libcrypto` (from openssl) and `libb2`. You may have to tell racket where to find `libb2`, by adding an entry to the hash table in your [`config.rktd` file](https://docs.racket-lang.org/raco/config-file.html). This is what I had, for an M1 mac w/ libb2 installed via Homebrew:
|
||||
In particular, our crypto functions require both `libcrypto` (from openssl or
|
||||
eg. libressl) and `libb2`. You may have to tell racket where to find `libb2`, by
|
||||
adding an entry to the hash table in your
|
||||
[`config.rktd` file](https://docs.racket-lang.org/raco/config-file.html).
|
||||
This is what I had, for an M1 mac with `libb2` installed via Homebrew:
|
||||
```
|
||||
(lib-search-dirs . (#f "/opt/homebrew/Cellar/libb2/0.98.1/lib/"))
|
||||
$ cat scheme-libs/racket/config/config.rktd
|
||||
#hash(
|
||||
(lib-search-dirs . (#f "/opt/homebrew/Cellar/libb2/0.98.1/lib/"))
|
||||
)
|
||||
```
|
||||
You'll also need to install `x509-lib` with `raco pkg install x509-lib`
|
||||
|
||||
Finally, some distributions only package `racket-minimal`. You'll need to
|
||||
install the full compiler suite using `raco pkg install compiler-lib`
|
||||
([source](https://www.dbrunner.de/blog/2016/01/12/using-racket-minimal-and-raco/))
|
||||
|
||||
## Building
|
||||
|
||||
First, make sure unison is built (see [development](../../../development.markdown))
|
||||
|
||||
Next, use unison to generate the racket libraries. These are dependencies for
|
||||
building `unison-runtime`.
|
||||
* Read [gen-racket-libs.md](../../../unison-src/transcripts-manual/gen-racket-libs.md).
|
||||
It will contain two things:
|
||||
* `ucm` and `unison` transcripts that generate the libraries
|
||||
* Instructions on how to build `unison-runtime` using `raco`
|
||||
|
||||
If everything went well you should now have a new executable in `scheme-libs/racket/unison-runtime`.
|
||||
For example:
|
||||
```
|
||||
$ file scheme-libs/racket/unison-runtime
|
||||
scheme-libs/racket/unison-runtime: Mach-O 64-bit executable arm64
|
||||
```
|
||||
|
||||
## Running the unison test suite
|
||||
|
||||
To run the test suite, first `stack build` (or `stack build --fast`), then:
|
||||
Note that if you set up `config.rktd` above, you'll need to pass the path to its
|
||||
folder in `PLTCONFIGDIR` before invoking unison or the test scripts:
|
||||
|
||||
```
|
||||
./unison-src/builtin-tests/jit-tests.sh $(stack exec which unison) --runtime-path <path>
|
||||
export PLTCONFIGDIR=$(pwd)/scheme-libs/racket/config
|
||||
```
|
||||
|
||||
If you don't, some of the tests will fail with eg `ffi-lib: could not load foreign library`.
|
||||
|
||||
To run the test suite you can do:
|
||||
|
||||
```
|
||||
./unison-src/builtin-tests/jit-tests.sh $(stack exec which unison) --runtime-path scheme-libs/racket/unison-runtime
|
||||
```
|
||||
|
||||
OR if you want to run the same tests in interpreted mode:
|
||||
@ -31,7 +80,9 @@ OR if you want to run the same tests in interpreted mode:
|
||||
./unison-src/builtin-tests/interpreter-tests.sh
|
||||
```
|
||||
|
||||
The above scripts fetch and cache a copy of base and the scheme-generating libraries, and copy this directory to `$XDG_DATA_DIRECTORY/unisonlanguage/scheme-libs`.
|
||||
The above scripts fetch and cache a copy of base and the scheme-generating
|
||||
libraries, and copy this directory to `$XDG_DATA_DIRECTORY/unisonlanguage/scheme-libs`.
|
||||
Both scripts _should_ pass.
|
||||
|
||||
## Iterating more quickly
|
||||
|
||||
|
@ -63,6 +63,7 @@ import Unison.Codebase.Editor.HandleInput.DeleteProject (handleDeleteProject)
|
||||
import Unison.Codebase.Editor.HandleInput.EditNamespace (handleEditNamespace)
|
||||
import Unison.Codebase.Editor.HandleInput.FindAndReplace (handleStructuredFindI, handleStructuredFindReplaceI)
|
||||
import Unison.Codebase.Editor.HandleInput.FormatFile qualified as Format
|
||||
import Unison.Codebase.Editor.HandleInput.Global qualified as Global
|
||||
import Unison.Codebase.Editor.HandleInput.InstallLib (handleInstallLib)
|
||||
import Unison.Codebase.Editor.HandleInput.LSPDebug qualified as LSPDebug
|
||||
import Unison.Codebase.Editor.HandleInput.Load (EvalMode (Sandboxed), evalUnisonFile, handleLoad, loadUnisonFile)
|
||||
@ -496,23 +497,27 @@ loop e = do
|
||||
fixupOutput = HQ'.toHQ . Path.nameFromHQSplit
|
||||
NamesI global query -> do
|
||||
hqLength <- Cli.runTransaction Codebase.hashLength
|
||||
(names, pped) <-
|
||||
if global
|
||||
then do
|
||||
error "TODO: Implement names.global."
|
||||
else do
|
||||
names <- Cli.currentNames
|
||||
let searchNames names = do
|
||||
pped <- Cli.prettyPrintEnvDeclFromNames names
|
||||
pure (names, pped)
|
||||
|
||||
let unsuffixifiedPPE = PPED.unsuffixifiedPPE pped
|
||||
terms = Names.lookupHQTerm Names.IncludeSuffixes query names
|
||||
types = Names.lookupHQType Names.IncludeSuffixes query names
|
||||
terms' :: [(Referent, [HQ'.HashQualified Name])]
|
||||
terms' = map (\r -> (r, PPE.allTermNames unsuffixifiedPPE r)) (Set.toList terms)
|
||||
types' :: [(Reference, [HQ'.HashQualified Name])]
|
||||
types' = map (\r -> (r, PPE.allTypeNames unsuffixifiedPPE r)) (Set.toList types)
|
||||
Cli.respond $ ListNames global hqLength types' terms'
|
||||
let unsuffixifiedPPE = PPED.unsuffixifiedPPE pped
|
||||
terms = Names.lookupHQTerm Names.IncludeSuffixes query names
|
||||
types = Names.lookupHQType Names.IncludeSuffixes query names
|
||||
terms' :: [(Referent, [HQ'.HashQualified Name])]
|
||||
terms' = map (\r -> (r, PPE.allTermNames unsuffixifiedPPE r)) (Set.toList terms)
|
||||
types' :: [(Reference, [HQ'.HashQualified Name])]
|
||||
types' = map (\r -> (r, PPE.allTypeNames unsuffixifiedPPE r)) (Set.toList types)
|
||||
pure (terms', types')
|
||||
if global
|
||||
then do
|
||||
Global.forAllProjectBranches \(projBranchNames, _ids) branch -> do
|
||||
let names = Branch.toNames . Branch.head $ branch
|
||||
(terms, types) <- searchNames names
|
||||
when (not (null terms) || not (null types)) do
|
||||
Cli.respond $ GlobalListNames projBranchNames hqLength types terms
|
||||
else do
|
||||
names <- Cli.currentNames
|
||||
(terms, types) <- searchNames names
|
||||
Cli.respond $ ListNames hqLength types terms
|
||||
DocsI srcs -> do
|
||||
for_ srcs docsI
|
||||
CreateAuthorI authorNameSegment authorFullName -> do
|
||||
@ -1088,7 +1093,7 @@ handleFindI ::
|
||||
Cli ()
|
||||
handleFindI isVerbose fscope ws input = do
|
||||
Cli.Env {codebase} <- ask
|
||||
(pped, names, searchRoot, branch0) <- case fscope of
|
||||
case fscope of
|
||||
FindLocal p -> do
|
||||
searchRoot <- Cli.resolvePath' p
|
||||
branch0 <- Cli.getBranch0FromProjectPath searchRoot
|
||||
@ -1096,7 +1101,21 @@ handleFindI isVerbose fscope ws input = do
|
||||
-- Don't exclude anything from the pretty printer, since the type signatures we print for
|
||||
-- results may contain things in lib.
|
||||
pped <- Cli.currentPrettyPrintEnvDecl
|
||||
pure (pped, names, Just p, branch0)
|
||||
let suffixifiedPPE = PPED.suffixifiedPPE pped
|
||||
results <- searchBranch0 codebase branch0 names
|
||||
if (null results)
|
||||
then do
|
||||
Cli.respond FindNoLocalMatches
|
||||
-- We've already searched everything else, so now we search JUST the
|
||||
-- names in lib.
|
||||
let mayOnlyLibBranch = branch0 & Branch.children %%~ \cs -> Map.singleton NameSegment.libSegment <$> Map.lookup NameSegment.libSegment cs
|
||||
case mayOnlyLibBranch of
|
||||
Nothing -> respondResults codebase suffixifiedPPE (Just p) []
|
||||
Just onlyLibBranch -> do
|
||||
let onlyLibNames = Branch.toNames onlyLibBranch
|
||||
results <- searchBranch0 codebase branch0 onlyLibNames
|
||||
respondResults codebase suffixifiedPPE (Just p) results
|
||||
else respondResults codebase suffixifiedPPE (Just p) results
|
||||
FindLocalAndDeps p -> do
|
||||
searchRoot <- Cli.resolvePath' p
|
||||
branch0 <- Cli.getBranch0FromProjectPath searchRoot
|
||||
@ -1104,64 +1123,57 @@ handleFindI isVerbose fscope ws input = do
|
||||
-- Don't exclude anything from the pretty printer, since the type signatures we print for
|
||||
-- results may contain things in lib.
|
||||
pped <- Cli.currentPrettyPrintEnvDecl
|
||||
pure (pped, names, Just p, branch0)
|
||||
let suffixifiedPPE = PPED.suffixifiedPPE pped
|
||||
results <- searchBranch0 codebase branch0 names
|
||||
respondResults codebase suffixifiedPPE (Just p) results
|
||||
FindGlobal -> do
|
||||
-- TODO: Rewrite to be properly global again
|
||||
projectRootNames <- Names.makeAbsolute . Branch.toNames <$> Cli.getCurrentProjectRoot0
|
||||
pped <- Cli.prettyPrintEnvDeclFromNames projectRootNames
|
||||
currentBranch0 <- Cli.getCurrentBranch0
|
||||
pure (pped, projectRootNames, Nothing, currentBranch0)
|
||||
let suffixifiedPPE = PPED.suffixifiedPPE pped
|
||||
let getResults :: Names -> Cli [SearchResult]
|
||||
getResults names =
|
||||
case ws of
|
||||
[] -> pure (List.sortBy SR.compareByName (SR.fromNames names))
|
||||
-- type query
|
||||
":" : ws -> do
|
||||
typ <- parseSearchType (show input) (unwords ws)
|
||||
let keepNamed = Set.intersection (Branch.deepReferents branch0)
|
||||
(noExactTypeMatches, matches) <- do
|
||||
Cli.runTransaction do
|
||||
matches <- keepNamed <$> Codebase.termsOfType codebase typ
|
||||
if null matches
|
||||
then (True,) . keepNamed <$> Codebase.termsMentioningType codebase typ
|
||||
else pure (False, matches)
|
||||
when noExactTypeMatches (Cli.respond NoExactTypeMatches)
|
||||
pure $
|
||||
-- in verbose mode, aliases are shown, so we collapse all
|
||||
-- aliases to a single search result; in non-verbose mode,
|
||||
-- a separate result may be shown for each alias
|
||||
(if isVerbose then uniqueBy SR.toReferent else id) $
|
||||
searchResultsFor names (Set.toList matches) []
|
||||
Global.forAllProjectBranches \(projAndBranchNames, _ids) branch -> do
|
||||
let branch0 = Branch.head branch
|
||||
let projectRootNames = Names.makeAbsolute . Branch.toNames $ branch0
|
||||
pped <- Cli.prettyPrintEnvDeclFromNames projectRootNames
|
||||
results <- searchBranch0 codebase branch0 projectRootNames
|
||||
when (not $ null results) do
|
||||
Cli.setNumberedArgs $ fmap (SA.SearchResult Nothing) results
|
||||
results' <- Cli.runTransaction (Backend.loadSearchResults codebase results)
|
||||
Cli.respond $ GlobalFindBranchResults projAndBranchNames (PPED.suffixifiedPPE pped) isVerbose results'
|
||||
where
|
||||
searchBranch0 :: Codebase.Codebase m Symbol Ann -> Branch0 IO -> Names -> Cli [SearchResult]
|
||||
searchBranch0 codebase branch0 names =
|
||||
case ws of
|
||||
[] -> pure (List.sortBy SR.compareByName (SR.fromNames names))
|
||||
-- type query
|
||||
":" : ws -> do
|
||||
typ <- parseSearchType (show input) (unwords ws)
|
||||
let keepNamed = Set.intersection (Branch.deepReferents branch0)
|
||||
(noExactTypeMatches, matches) <- do
|
||||
Cli.runTransaction do
|
||||
matches <- keepNamed <$> Codebase.termsOfType codebase typ
|
||||
if null matches
|
||||
then (True,) . keepNamed <$> Codebase.termsMentioningType codebase typ
|
||||
else pure (False, matches)
|
||||
when noExactTypeMatches (Cli.respond NoExactTypeMatches)
|
||||
pure $
|
||||
-- in verbose mode, aliases are shown, so we collapse all
|
||||
-- aliases to a single search result; in non-verbose mode,
|
||||
-- a separate result may be shown for each alias
|
||||
(if isVerbose then uniqueBy SR.toReferent else id) $
|
||||
searchResultsFor names (Set.toList matches) []
|
||||
|
||||
-- name query
|
||||
qs -> do
|
||||
let anythingBeforeHash :: Megaparsec.Parsec (L.Token Text) [Char] Text
|
||||
anythingBeforeHash = Text.pack <$> Megaparsec.takeWhileP Nothing (/= '#')
|
||||
let srs =
|
||||
searchBranchScored
|
||||
names
|
||||
Find.simpleFuzzyScore
|
||||
(mapMaybe (HQ.parseTextWith anythingBeforeHash . Text.pack) qs)
|
||||
pure $ uniqueBy SR.toReferent srs
|
||||
let respondResults results = do
|
||||
Cli.setNumberedArgs $ fmap (SA.SearchResult searchRoot) results
|
||||
results' <- Cli.runTransaction (Backend.loadSearchResults codebase results)
|
||||
Cli.respond $ ListOfDefinitions fscope suffixifiedPPE isVerbose results'
|
||||
results <- getResults names
|
||||
case (results, fscope) of
|
||||
([], FindLocal {}) -> do
|
||||
Cli.respond FindNoLocalMatches
|
||||
-- We've already searched everything else, so now we search JUST the
|
||||
-- names in lib.
|
||||
let mayOnlyLibBranch = branch0 & Branch.children %%~ \cs -> Map.singleton NameSegment.libSegment <$> Map.lookup NameSegment.libSegment cs
|
||||
case mayOnlyLibBranch of
|
||||
Nothing -> respondResults []
|
||||
Just onlyLibBranch -> do
|
||||
let onlyLibNames = Branch.toNames onlyLibBranch
|
||||
results <- getResults onlyLibNames
|
||||
respondResults results
|
||||
_ -> respondResults results
|
||||
-- name query
|
||||
qs -> do
|
||||
let anythingBeforeHash :: Megaparsec.Parsec (L.Token Text) [Char] Text
|
||||
anythingBeforeHash = Text.pack <$> Megaparsec.takeWhileP Nothing (/= '#')
|
||||
let srs =
|
||||
searchBranchScored
|
||||
names
|
||||
Find.simpleFuzzyScore
|
||||
(mapMaybe (HQ.parseTextWith anythingBeforeHash . Text.pack) qs)
|
||||
pure $ uniqueBy SR.toReferent srs
|
||||
respondResults :: Codebase.Codebase m Symbol Ann -> PPE.PrettyPrintEnv -> Maybe Path' -> [SearchResult] -> Cli ()
|
||||
respondResults codebase ppe searchRoot results = do
|
||||
Cli.setNumberedArgs $ fmap (SA.SearchResult searchRoot) results
|
||||
results' <- Cli.runTransaction (Backend.loadSearchResults codebase results)
|
||||
Cli.respond $ ListOfDefinitions fscope ppe isVerbose results'
|
||||
|
||||
handleDependencies :: HQ.HashQualified Name -> Cli ()
|
||||
handleDependencies hq = do
|
||||
|
22
unison-cli/src/Unison/Codebase/Editor/HandleInput/Global.hs
Normal file
22
unison-cli/src/Unison/Codebase/Editor/HandleInput/Global.hs
Normal file
@ -0,0 +1,22 @@
|
||||
module Unison.Codebase.Editor.HandleInput.Global (forAllProjectBranches) where
|
||||
|
||||
import Control.Monad.Reader
|
||||
import U.Codebase.Sqlite.DbId (ProjectBranchId, ProjectId)
|
||||
import U.Codebase.Sqlite.Queries qualified as Q
|
||||
import Unison.Cli.Monad (Cli)
|
||||
import Unison.Cli.Monad qualified as Cli
|
||||
import Unison.Codebase qualified as Codebase
|
||||
import Unison.Codebase.Branch (Branch)
|
||||
import Unison.Core.Project
|
||||
import Unison.Prelude
|
||||
import Unison.Util.Monoid (foldMapM)
|
||||
|
||||
-- | Map over ALL project branches in the codebase.
|
||||
-- This is a _very_ big hammer, that you should basically never use, except for things like debugging or migrations.
|
||||
forAllProjectBranches :: (Monoid r) => ((ProjectAndBranch ProjectName ProjectBranchName, ProjectAndBranch ProjectId ProjectBranchId) -> Branch IO -> Cli r) -> Cli r
|
||||
forAllProjectBranches f = do
|
||||
Cli.Env {codebase} <- ask
|
||||
projectBranches <- Cli.runTransaction Q.loadAllProjectBranchNamePairs
|
||||
projectBranches & foldMapM \(names, ids@(ProjectAndBranch projId branchId)) -> do
|
||||
b <- liftIO $ Codebase.expectProjectBranchRoot codebase projId branchId
|
||||
f (names, ids) b
|
@ -127,8 +127,8 @@ data Input
|
||||
| PushRemoteBranchI PushRemoteBranchInput
|
||||
| ResetI (BranchId2 {- namespace to reset it to -}) (Maybe UnresolvedProjectBranch {- ProjectBranch to reset -})
|
||||
-- todo: Q: Does it make sense to publish to not-the-root of a Github repo?
|
||||
-- Does it make sense to fork from not-the-root of a Github repo?
|
||||
| -- used in Welcome module to give directions to user
|
||||
| -- Does it make sense to fork from not-the-root of a Github repo?
|
||||
-- used in Welcome module to give directions to user
|
||||
CreateMessage (P.Pretty P.ColorText)
|
||||
| -- Change directory.
|
||||
SwitchBranchI Path'
|
||||
|
@ -261,7 +261,11 @@ data Output
|
||||
| MovedOverExistingBranch Path'
|
||||
| DeletedEverything
|
||||
| ListNames
|
||||
IsGlobal
|
||||
Int -- hq length to print References
|
||||
[(Reference, [HQ'.HashQualified Name])] -- type match, type names
|
||||
[(Referent, [HQ'.HashQualified Name])] -- term match, term names
|
||||
| GlobalListNames
|
||||
(ProjectAndBranch ProjectName ProjectBranchName)
|
||||
Int -- hq length to print References
|
||||
[(Reference, [HQ'.HashQualified Name])] -- type match, type names
|
||||
[(Referent, [HQ'.HashQualified Name])] -- term match, term names
|
||||
@ -269,6 +273,7 @@ data Output
|
||||
| ListOfDefinitions FindScope PPE.PrettyPrintEnv ListDetailed [SearchResult' Symbol Ann]
|
||||
| ListShallow (IO PPE.PrettyPrintEnv) [ShallowListEntry Symbol Ann]
|
||||
| ListStructuredFind [HQ.HashQualified Name]
|
||||
| GlobalFindBranchResults (ProjectAndBranch ProjectName ProjectBranchName) PPE.PrettyPrintEnv ListDetailed [SearchResult' Symbol Ann]
|
||||
| -- ListStructuredFind patternMatchingUsages termBodyUsages
|
||||
-- show the result of add/update
|
||||
SlurpOutput Input PPE.PrettyPrintEnv SlurpResult
|
||||
@ -543,8 +548,10 @@ isFailure o = case o of
|
||||
MoveRootBranchConfirmation -> False
|
||||
MovedOverExistingBranch {} -> False
|
||||
DeletedEverything -> False
|
||||
ListNames _ _ tys tms -> null tms && null tys
|
||||
ListNames _ tys tms -> null tms && null tys
|
||||
GlobalListNames {} -> False
|
||||
ListOfDefinitions _ _ _ ds -> null ds
|
||||
GlobalFindBranchResults _ _ _ _ -> False
|
||||
ListStructuredFind tms -> null tms
|
||||
SlurpOutput _ _ sr -> not $ SR.isOk sr
|
||||
ParseErrors {} -> True
|
||||
|
@ -24,11 +24,10 @@ where
|
||||
import CMark qualified
|
||||
import Data.Char qualified as Char
|
||||
import Data.Text qualified as Text
|
||||
import Data.These (These (..))
|
||||
import Text.Megaparsec qualified as P
|
||||
import Unison.Codebase.Transcript
|
||||
import Unison.Prelude
|
||||
import Unison.Project (ProjectAndBranch (ProjectAndBranch))
|
||||
import Unison.Project (fullyQualifiedProjectAndBranchNamesParser)
|
||||
|
||||
formatAPIRequest :: APIRequest -> Text
|
||||
formatAPIRequest = \case
|
||||
@ -72,24 +71,16 @@ ucmLine :: P UcmLine
|
||||
ucmLine = ucmCommand <|> ucmComment
|
||||
where
|
||||
ucmCommand :: P UcmLine
|
||||
ucmCommand = do
|
||||
context <-
|
||||
P.try do
|
||||
contextString <- P.takeWhile1P Nothing (/= '>')
|
||||
context <-
|
||||
case (tryFrom @Text contextString) of
|
||||
(Right (These project branch)) -> pure (UcmContextProject (ProjectAndBranch project branch))
|
||||
_ -> fail "expected project/branch or absolute path"
|
||||
void $ lineToken $ word ">"
|
||||
pure context
|
||||
line <- P.takeWhileP Nothing (/= '\n') <* spaces
|
||||
pure $ UcmCommand context line
|
||||
ucmCommand =
|
||||
UcmCommand
|
||||
<$> fmap UcmContextProject (P.try $ fullyQualifiedProjectAndBranchNamesParser <* lineToken (word ">"))
|
||||
<*> P.takeWhileP Nothing (/= '\n')
|
||||
<* spaces
|
||||
|
||||
ucmComment :: P UcmLine
|
||||
ucmComment = do
|
||||
word "--"
|
||||
line <- P.takeWhileP Nothing (/= '\n') <* spaces
|
||||
pure $ UcmComment line
|
||||
ucmComment =
|
||||
P.label "comment (delimited with “--”)" $
|
||||
UcmComment <$> (word "--" *> P.takeWhileP Nothing (/= '\n')) <* spaces
|
||||
|
||||
apiRequest :: P APIRequest
|
||||
apiRequest = do
|
||||
@ -118,7 +109,7 @@ fenced info = do
|
||||
hide <- hidden
|
||||
err <- expectingError
|
||||
P.setInput body
|
||||
pure . Ucm hide err <$> (spaces *> many ucmLine)
|
||||
pure . Ucm hide err <$> (spaces *> P.manyTill ucmLine P.eof)
|
||||
"unison" ->
|
||||
do
|
||||
-- todo: this has to be more interesting
|
||||
@ -132,7 +123,7 @@ fenced info = do
|
||||
pure . Unison hide err fileName <$> (spaces *> P.getInput)
|
||||
"api" -> do
|
||||
P.setInput body
|
||||
pure . API <$> (spaces *> many apiRequest)
|
||||
pure . API <$> (spaces *> P.manyTill apiRequest P.eof)
|
||||
_ -> pure Nothing
|
||||
|
||||
word :: Text -> P Text
|
||||
|
@ -1149,7 +1149,7 @@ findAll :: InputPattern
|
||||
findAll = find' "find.all" (Input.FindLocalAndDeps Path.relativeEmpty')
|
||||
|
||||
findGlobal :: InputPattern
|
||||
findGlobal = find' "find.global" Input.FindGlobal
|
||||
findGlobal = find' "debug.find.global" Input.FindGlobal
|
||||
|
||||
findIn, findInAll :: InputPattern
|
||||
findIn = findIn' "find-in" Input.FindLocal
|
||||
@ -1197,8 +1197,8 @@ findHelp =
|
||||
"lists all definitions with a name similar to 'foo' or 'bar' in the "
|
||||
<> "specified subnamespace (including one level of its 'lib')."
|
||||
),
|
||||
( "find.global foo",
|
||||
"lists all definitions with a name similar to 'foo' in any namespace"
|
||||
( "debug.find.global foo",
|
||||
"Iteratively searches all projects and branches and lists all definitions with a name similar to 'foo'. Note that this is a very slow operation."
|
||||
)
|
||||
]
|
||||
)
|
||||
@ -2611,12 +2611,15 @@ names isGlobal =
|
||||
[]
|
||||
I.Visible
|
||||
[("name or hash", Required, definitionQueryArg)]
|
||||
(P.wrap $ makeExample (names isGlobal) ["foo"] <> " shows the hash and all known names for `foo`.")
|
||||
(P.wrap $ makeExample (names isGlobal) ["foo"] <> description)
|
||||
$ \case
|
||||
[thing] -> Input.NamesI isGlobal <$> handleHashQualifiedNameArg thing
|
||||
args -> wrongArgsLength "exactly one argument" args
|
||||
where
|
||||
cmdName = if isGlobal then "names.global" else "names"
|
||||
description
|
||||
| isGlobal = "Iteratively search across all projects and branches for names matching `foo`. Note that this is expected to be quite slow and is primarily for debugging issues with your codebase."
|
||||
| otherwise = "List all known names for `foo` in the current branch."
|
||||
cmdName = if isGlobal then "debug.names.global" else "names"
|
||||
|
||||
dependents, dependencies :: InputPattern
|
||||
dependents =
|
||||
@ -3456,7 +3459,7 @@ validInputs =
|
||||
mergeInputPattern,
|
||||
mergeCommitInputPattern,
|
||||
names False, -- names
|
||||
names True, -- names.global
|
||||
names True, -- debug.names.global
|
||||
namespaceDependencies,
|
||||
previewAdd,
|
||||
previewUpdate,
|
||||
|
@ -855,49 +855,24 @@ notifyUser dir = \case
|
||||
]
|
||||
ListOfDefinitions fscope ppe detailed results ->
|
||||
listOfDefinitions fscope ppe detailed results
|
||||
ListNames global len types terms ->
|
||||
if null types && null terms
|
||||
then
|
||||
pure . P.callout "😶" $
|
||||
P.sepNonEmpty "\n\n" $
|
||||
[ P.wrap "I couldn't find anything by that name.",
|
||||
globalTip
|
||||
]
|
||||
else
|
||||
pure . P.sepNonEmpty "\n\n" $
|
||||
[ formatTypes types,
|
||||
formatTerms terms,
|
||||
globalTip
|
||||
]
|
||||
where
|
||||
globalTip =
|
||||
if global
|
||||
then mempty
|
||||
else (tip $ "Use " <> IP.makeExample (IP.names True) [] <> " to see more results.")
|
||||
formatTerms tms =
|
||||
P.lines . P.nonEmpty $ P.plural tms (P.blue "Term") : List.intersperse "" (go <$> tms)
|
||||
where
|
||||
go (ref, hqs) =
|
||||
P.column2
|
||||
[ ("Hash:", P.syntaxToColor (prettyReferent len ref)),
|
||||
( "Names: ",
|
||||
P.group $
|
||||
P.spaced $
|
||||
P.bold . P.syntaxToColor . prettyHashQualified' <$> List.sortBy Name.compareAlphabetical hqs
|
||||
)
|
||||
]
|
||||
formatTypes types =
|
||||
P.lines . P.nonEmpty $ P.plural types (P.blue "Type") : List.intersperse "" (go <$> types)
|
||||
where
|
||||
go (ref, hqs) =
|
||||
P.column2
|
||||
[ ("Hash:", P.syntaxToColor (prettyReference len ref)),
|
||||
( "Names:",
|
||||
P.group $
|
||||
P.spaced $
|
||||
P.bold . P.syntaxToColor . prettyHashQualified' <$> List.sortBy Name.compareAlphabetical hqs
|
||||
)
|
||||
]
|
||||
GlobalFindBranchResults projBranchName ppe detailed results -> do
|
||||
output <- listOfDefinitions Input.FindGlobal ppe detailed results
|
||||
pure $
|
||||
P.lines
|
||||
[ P.wrap $ "Found results in " <> P.text (into @Text projBranchName),
|
||||
"",
|
||||
output
|
||||
]
|
||||
ListNames len types terms ->
|
||||
listOfNames len types terms
|
||||
GlobalListNames projectBranchName len types terms -> do
|
||||
output <- listOfNames len types terms
|
||||
pure $
|
||||
P.lines
|
||||
[ P.wrap $ "Found results in " <> P.text (into @Text projectBranchName),
|
||||
"",
|
||||
output
|
||||
]
|
||||
-- > names foo
|
||||
-- Terms:
|
||||
-- Hash: #asdflkjasdflkjasdf
|
||||
@ -2816,6 +2791,45 @@ listOfDefinitions ::
|
||||
listOfDefinitions fscope ppe detailed results =
|
||||
pure $ listOfDefinitions' fscope ppe detailed results
|
||||
|
||||
listOfNames :: Int -> [(Reference, [HQ'.HashQualified Name])] -> [(Referent, [HQ'.HashQualified Name])] -> IO Pretty
|
||||
listOfNames len types terms = do
|
||||
if null types && null terms
|
||||
then
|
||||
pure . P.callout "😶" $
|
||||
P.sepNonEmpty "\n\n" $
|
||||
[ P.wrap "I couldn't find anything by that name."
|
||||
]
|
||||
else
|
||||
pure . P.sepNonEmpty "\n\n" $
|
||||
[ formatTypes types,
|
||||
formatTerms terms
|
||||
]
|
||||
where
|
||||
formatTerms tms =
|
||||
P.lines . P.nonEmpty $ P.plural tms (P.blue "Term") : List.intersperse "" (go <$> tms)
|
||||
where
|
||||
go (ref, hqs) =
|
||||
P.column2
|
||||
[ ("Hash:", P.syntaxToColor (prettyReferent len ref)),
|
||||
( "Names: ",
|
||||
P.group $
|
||||
P.spaced $
|
||||
P.bold . P.syntaxToColor . prettyHashQualified' <$> List.sortBy Name.compareAlphabetical hqs
|
||||
)
|
||||
]
|
||||
formatTypes types =
|
||||
P.lines . P.nonEmpty $ P.plural types (P.blue "Type") : List.intersperse "" (go <$> types)
|
||||
where
|
||||
go (ref, hqs) =
|
||||
P.column2
|
||||
[ ("Hash:", P.syntaxToColor (prettyReference len ref)),
|
||||
( "Names:",
|
||||
P.group $
|
||||
P.spaced $
|
||||
P.bold . P.syntaxToColor . prettyHashQualified' <$> List.sortBy Name.compareAlphabetical hqs
|
||||
)
|
||||
]
|
||||
|
||||
data ShowNumbers = ShowNumbers | HideNumbers
|
||||
|
||||
-- | `ppe` is just for rendering type signatures
|
||||
|
@ -64,6 +64,7 @@ library
|
||||
Unison.Codebase.Editor.HandleInput.EditNamespace
|
||||
Unison.Codebase.Editor.HandleInput.FindAndReplace
|
||||
Unison.Codebase.Editor.HandleInput.FormatFile
|
||||
Unison.Codebase.Editor.HandleInput.Global
|
||||
Unison.Codebase.Editor.HandleInput.InstallLib
|
||||
Unison.Codebase.Editor.HandleInput.Load
|
||||
Unison.Codebase.Editor.HandleInput.Ls
|
||||
|
@ -155,6 +155,15 @@ instance (ToJSON b, ToJSON a) => ToJSON (DisplayObject b a) where
|
||||
MissingObject sh -> object ["tag" Aeson..= String "MissingObject", "contents" Aeson..= sh]
|
||||
UserObject a -> object ["tag" Aeson..= String "UserObject", "contents" Aeson..= a]
|
||||
|
||||
instance (FromJSON a, FromJSON b) => FromJSON (DisplayObject b a) where
|
||||
parseJSON = withObject "DisplayObject" \o -> do
|
||||
tag <- o .: "tag"
|
||||
case tag of
|
||||
"BuiltinObject" -> BuiltinObject <$> o .: "contents"
|
||||
"MissingObject" -> MissingObject <$> o .: "contents"
|
||||
"UserObject" -> UserObject <$> o .: "contents"
|
||||
_ -> fail $ "Invalid tag: " <> Text.unpack tag
|
||||
|
||||
deriving instance (ToSchema b, ToSchema a) => ToSchema (DisplayObject b a)
|
||||
|
||||
-- [21/10/07] Hello, this is Mitchell. Name refactor in progress. Changing internal representation from a flat text to a
|
||||
|
@ -20,12 +20,11 @@ complement of unison libraries for a given combination of ucm version
|
||||
and @unison/internal version.
|
||||
|
||||
To set up racket to use these files, we need to create a package with
|
||||
them. This is accomplished by running.
|
||||
them. This is accomplished by running:
|
||||
|
||||
raco pkg install -t dir unison
|
||||
raco pkg install -t dir scheme-libs/racket/unison
|
||||
|
||||
in the directory where the `unison` directory is located. Then the
|
||||
runtime executable can be built with
|
||||
After, the runtime executable can be built with
|
||||
|
||||
raco exe scheme-libs/racket/unison-runtime.rkt
|
||||
|
||||
|
@ -1,22 +1,21 @@
|
||||
|
||||
When we start out, `./scheme-libs/racket` contains a bunch of library files that we'll need. They define the Unison builtins for Racket.
|
||||
|
||||
Next, we'll download the jit project and generate a few Racket files from it.
|
||||
|
||||
```ucm
|
||||
``` ucm
|
||||
jit-setup/main> lib.install @unison/internal/releases/0.0.18
|
||||
|
||||
Downloaded 14917 entities.
|
||||
Downloaded 14949 entities.
|
||||
|
||||
I installed @unison/internal/releases/0.0.18 as
|
||||
unison_internal_0_0_18.
|
||||
|
||||
```
|
||||
```unison
|
||||
``` unison
|
||||
go = generateSchemeBoot "scheme-libs/racket"
|
||||
```
|
||||
|
||||
```ucm
|
||||
``` ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
@ -29,7 +28,7 @@ go = generateSchemeBoot "scheme-libs/racket"
|
||||
go : '{IO, Exception} ()
|
||||
|
||||
```
|
||||
```ucm
|
||||
``` ucm
|
||||
jit-setup/main> run go
|
||||
|
||||
()
|
||||
@ -42,16 +41,23 @@ and @unison/internal version.
|
||||
To set up racket to use these files, we need to create a package with
|
||||
them. This is accomplished by running.
|
||||
|
||||
raco pkg install -t dir unison
|
||||
```
|
||||
raco pkg install -t dir unison
|
||||
```
|
||||
|
||||
in the directory where the `unison directory is located. Then the
|
||||
in the directory where the `unison` directory is located. Then the
|
||||
runtime executable can be built with
|
||||
|
||||
raco exe scheme-libs/racket/unison-runtime.rkt
|
||||
```
|
||||
raco exe scheme-libs/racket/unison-runtime.rkt
|
||||
```
|
||||
|
||||
and a distributable directory can be produced with:
|
||||
|
||||
raco distribute <output-dir> scheme-libs/racket/unison-runtime
|
||||
```
|
||||
raco distribute <output-dir> scheme-libs/racket/unison-runtime
|
||||
```
|
||||
|
||||
At that point, <output-dir> should contain the executable and all
|
||||
dependencies necessary to run it.
|
||||
|
||||
|
@ -45,7 +45,5 @@ scratch/main> names term1
|
||||
Term
|
||||
Hash: #8hum58rlih
|
||||
Names: term1 term2
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
```
|
||||
|
@ -48,16 +48,12 @@ scratch/app1> names a
|
||||
Term
|
||||
Hash: #gjmq673r1v
|
||||
Names: lib.text_v1.a lib.text_v2.a
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
scratch/app1> names x
|
||||
|
||||
Term
|
||||
Hash: #nsmc4p1ra4
|
||||
Names: lib.http_v3.x lib.http_v4.x
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
```
|
||||
Our `app2` project includes the `http` library twice as direct dependencies, and once as an indirect dependency via `webutil`.
|
||||
@ -102,15 +98,11 @@ scratch/app2> names a
|
||||
Term
|
||||
Hash: #gjmq673r1v
|
||||
Names: lib.webutil.lib.text_v1.a
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
scratch/app2> names x
|
||||
|
||||
Term
|
||||
Hash: #nsmc4p1ra4
|
||||
Names: lib.http_v1.x lib.http_v2.x
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
```
|
||||
|
@ -25,7 +25,7 @@ scratch/main> find.verbose
|
||||
No results. Check your spelling, or try using tab completion
|
||||
to supply command arguments.
|
||||
|
||||
`find.global` can be used to search outside the current
|
||||
`debug.find.global` can be used to search outside the current
|
||||
namespace.
|
||||
|
||||
```
|
||||
@ -42,7 +42,7 @@ scratch/main> find mynamespace
|
||||
No results. Check your spelling, or try using tab completion
|
||||
to supply command arguments.
|
||||
|
||||
`find.global` can be used to search outside the current
|
||||
`debug.find.global` can be used to search outside the current
|
||||
namespace.
|
||||
|
||||
```
|
||||
|
3
unison-src/transcripts/errors/invalid-api-requests.md
Normal file
3
unison-src/transcripts/errors/invalid-api-requests.md
Normal file
@ -0,0 +1,3 @@
|
||||
``` api:error
|
||||
DELETE /something/important
|
||||
```
|
5
unison-src/transcripts/errors/no-abspath-in-ucm.md
Normal file
5
unison-src/transcripts/errors/no-abspath-in-ucm.md
Normal file
@ -0,0 +1,5 @@
|
||||
``` ucm:error
|
||||
scratch/main> builtins.merge
|
||||
-- As of 0.5.25, we no longer allow loose code paths for UCM commands.
|
||||
.> ls
|
||||
```
|
@ -34,15 +34,10 @@ Finding within a namespace
|
||||
|
||||
```ucm
|
||||
scratch/main> find bar
|
||||
-- Shows UUIDs
|
||||
-- scratch/main> find.global bar
|
||||
scratch/other> debug.find.global bar
|
||||
scratch/main> find-in somewhere bar
|
||||
```
|
||||
|
||||
```ucm:error
|
||||
scratch/main> find baz
|
||||
```
|
||||
|
||||
```ucm:error
|
||||
scratch/main> find.global notHere
|
||||
```
|
||||
|
@ -65,8 +65,15 @@ scratch/main> find bar
|
||||
1. somewhere.bar : Nat
|
||||
|
||||
|
||||
-- Shows UUIDs
|
||||
-- scratch/main> find.global bar
|
||||
scratch/other> debug.find.global bar
|
||||
|
||||
Found results in scratch/main
|
||||
|
||||
1. .cat.lib.bar : Nat
|
||||
2. .lib.bar : Nat
|
||||
3. .somewhere.bar : Nat
|
||||
|
||||
|
||||
scratch/main> find-in somewhere bar
|
||||
|
||||
1. bar : Nat
|
||||
@ -86,17 +93,7 @@ scratch/main> find baz
|
||||
No results. Check your spelling, or try using tab completion
|
||||
to supply command arguments.
|
||||
|
||||
`find.global` can be used to search outside the current
|
||||
`debug.find.global` can be used to search outside the current
|
||||
namespace.
|
||||
|
||||
```
|
||||
``` ucm
|
||||
scratch/main> find.global notHere
|
||||
|
||||
😶
|
||||
|
||||
No results. Check your spelling, or try using tab completion
|
||||
to supply command arguments.
|
||||
|
||||
|
||||
```
|
||||
|
@ -113,6 +113,50 @@ scratch/main> help
|
||||
debug.file
|
||||
View details about the most recent successfully typechecked file.
|
||||
|
||||
debug.find.global
|
||||
`find` lists all definitions in the
|
||||
current namespace.
|
||||
`find foo` lists all definitions with a
|
||||
name similar to 'foo' in the
|
||||
current namespace (excluding
|
||||
those under 'lib').
|
||||
`find foo bar` lists all definitions with a
|
||||
name similar to 'foo' or
|
||||
'bar' in the current
|
||||
namespace (excluding those
|
||||
under 'lib').
|
||||
`find-in namespace` lists all definitions in the
|
||||
specified subnamespace.
|
||||
`find-in namespace foo bar` lists all definitions with a
|
||||
name similar to 'foo' or
|
||||
'bar' in the specified
|
||||
subnamespace.
|
||||
find.all foo lists all definitions with a
|
||||
name similar to 'foo' in the
|
||||
current namespace (including
|
||||
one level of 'lib').
|
||||
`find-in.all namespace` lists all definitions in the
|
||||
specified subnamespace
|
||||
(including one level of its
|
||||
'lib').
|
||||
`find-in.all namespace foo bar` lists all definitions with a
|
||||
name similar to 'foo' or
|
||||
'bar' in the specified
|
||||
subnamespace (including one
|
||||
level of its 'lib').
|
||||
debug.find.global foo Iteratively searches all
|
||||
projects and branches and
|
||||
lists all definitions with a
|
||||
name similar to 'foo'. Note
|
||||
that this is a very slow
|
||||
operation.
|
||||
|
||||
debug.names.global
|
||||
`debug.names.global foo` Iteratively search across all
|
||||
projects and branches for names matching `foo`. Note that this
|
||||
is expected to be quite slow and is primarily for debugging
|
||||
issues with your codebase.
|
||||
|
||||
debug.numberedArgs
|
||||
Dump the contents of the numbered args state.
|
||||
|
||||
@ -269,9 +313,12 @@ scratch/main> help
|
||||
'bar' in the specified
|
||||
subnamespace (including one
|
||||
level of its 'lib').
|
||||
find.global foo lists all definitions with a
|
||||
name similar to 'foo' in any
|
||||
namespace
|
||||
debug.find.global foo Iteratively searches all
|
||||
projects and branches and
|
||||
lists all definitions with a
|
||||
name similar to 'foo'. Note
|
||||
that this is a very slow
|
||||
operation.
|
||||
|
||||
find-in
|
||||
`find` lists all definitions in the
|
||||
@ -304,9 +351,12 @@ scratch/main> help
|
||||
'bar' in the specified
|
||||
subnamespace (including one
|
||||
level of its 'lib').
|
||||
find.global foo lists all definitions with a
|
||||
name similar to 'foo' in any
|
||||
namespace
|
||||
debug.find.global foo Iteratively searches all
|
||||
projects and branches and
|
||||
lists all definitions with a
|
||||
name similar to 'foo'. Note
|
||||
that this is a very slow
|
||||
operation.
|
||||
|
||||
find-in.all
|
||||
`find` lists all definitions in the
|
||||
@ -339,9 +389,12 @@ scratch/main> help
|
||||
'bar' in the specified
|
||||
subnamespace (including one
|
||||
level of its 'lib').
|
||||
find.global foo lists all definitions with a
|
||||
name similar to 'foo' in any
|
||||
namespace
|
||||
debug.find.global foo Iteratively searches all
|
||||
projects and branches and
|
||||
lists all definitions with a
|
||||
name similar to 'foo'. Note
|
||||
that this is a very slow
|
||||
operation.
|
||||
|
||||
find.all
|
||||
`find` lists all definitions in the
|
||||
@ -374,48 +427,16 @@ scratch/main> help
|
||||
'bar' in the specified
|
||||
subnamespace (including one
|
||||
level of its 'lib').
|
||||
find.global foo lists all definitions with a
|
||||
name similar to 'foo' in any
|
||||
namespace
|
||||
debug.find.global foo Iteratively searches all
|
||||
projects and branches and
|
||||
lists all definitions with a
|
||||
name similar to 'foo'. Note
|
||||
that this is a very slow
|
||||
operation.
|
||||
|
||||
find.all.verbose
|
||||
`find.all.verbose` searches for definitions like `find.all`, but includes hashes and aliases in the results.
|
||||
|
||||
find.global
|
||||
`find` lists all definitions in the
|
||||
current namespace.
|
||||
`find foo` lists all definitions with a
|
||||
name similar to 'foo' in the
|
||||
current namespace (excluding
|
||||
those under 'lib').
|
||||
`find foo bar` lists all definitions with a
|
||||
name similar to 'foo' or
|
||||
'bar' in the current
|
||||
namespace (excluding those
|
||||
under 'lib').
|
||||
`find-in namespace` lists all definitions in the
|
||||
specified subnamespace.
|
||||
`find-in namespace foo bar` lists all definitions with a
|
||||
name similar to 'foo' or
|
||||
'bar' in the specified
|
||||
subnamespace.
|
||||
find.all foo lists all definitions with a
|
||||
name similar to 'foo' in the
|
||||
current namespace (including
|
||||
one level of 'lib').
|
||||
`find-in.all namespace` lists all definitions in the
|
||||
specified subnamespace
|
||||
(including one level of its
|
||||
'lib').
|
||||
`find-in.all namespace foo bar` lists all definitions with a
|
||||
name similar to 'foo' or
|
||||
'bar' in the specified
|
||||
subnamespace (including one
|
||||
level of its 'lib').
|
||||
find.global foo lists all definitions with a
|
||||
name similar to 'foo' in any
|
||||
namespace
|
||||
|
||||
find.verbose
|
||||
`find.verbose` searches for definitions like `find`, but includes hashes and aliases in the results.
|
||||
|
||||
@ -526,11 +547,8 @@ scratch/main> help
|
||||
`move.type foo bar` renames `foo` to `bar`.
|
||||
|
||||
names
|
||||
`names foo` shows the hash and all known names for `foo`.
|
||||
|
||||
names.global
|
||||
`names.global foo` shows the hash and all known names for
|
||||
`foo`.
|
||||
`names foo` List all known names for `foo` in the current
|
||||
branch.
|
||||
|
||||
namespace.dependencies
|
||||
List the external dependencies of the specified namespace.
|
||||
|
@ -1435,8 +1435,6 @@ project/alice> names A
|
||||
Type
|
||||
Hash: #65mdg7015r
|
||||
Names: A A.inner.X
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
```
|
||||
Bob's branch:
|
||||
|
@ -32,16 +32,13 @@ scratch/main> names #gjmq673r1v
|
||||
scratch/main> names .some.place.x
|
||||
```
|
||||
|
||||
`names.global` searches from the root, and absolutely qualifies results
|
||||
`debug.names.global` searches from the root, and absolutely qualifies results
|
||||
|
||||
|
||||
TODO: swap this back to a 'ucm' block when names.global is re-implemented
|
||||
|
||||
```
|
||||
```ucm
|
||||
-- We can search from a different branch and find all names in the codebase named 'x', and each of their aliases respectively.
|
||||
scratch/other> names.global x
|
||||
scratch/other> debug.names.global x
|
||||
-- We can search by hash, and see all aliases of that hash in the codebase
|
||||
scratch/other> names.global #gjmq673r1v
|
||||
scratch/other> debug.names.global #gjmq673r1v
|
||||
-- We can search using an absolute name
|
||||
scratch/other> names.global .some.place.x
|
||||
scratch/other> debug.names.global .some.place.x
|
||||
```
|
||||
|
@ -59,8 +59,6 @@ scratch/main> names x
|
||||
|
||||
Hash: #pi25gcdv0o
|
||||
Names: some.otherplace.x
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
-- We can search by hash, and see all aliases of that hash
|
||||
scratch/main> names #gjmq673r1v
|
||||
@ -68,8 +66,6 @@ scratch/main> names #gjmq673r1v
|
||||
Term
|
||||
Hash: #gjmq673r1v
|
||||
Names: some.otherplace.y some.place.x somewhere.z
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
-- Works with absolute names too
|
||||
scratch/main> names .some.place.x
|
||||
@ -77,20 +73,39 @@ scratch/main> names .some.place.x
|
||||
Term
|
||||
Hash: #gjmq673r1v
|
||||
Names: some.otherplace.y some.place.x somewhere.z
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
```
|
||||
`names.global` searches from the root, and absolutely qualifies results
|
||||
`debug.names.global` searches from the root, and absolutely qualifies results
|
||||
|
||||
TODO: swap this back to a 'ucm' block when names.global is re-implemented
|
||||
|
||||
```
|
||||
``` ucm
|
||||
-- We can search from a different branch and find all names in the codebase named 'x', and each of their aliases respectively.
|
||||
scratch/other> names.global x
|
||||
-- We can search by hash, and see all aliases of that hash in the codebase
|
||||
scratch/other> names.global #gjmq673r1v
|
||||
-- We can search using an absolute name
|
||||
scratch/other> names.global .some.place.x
|
||||
```
|
||||
scratch/other> debug.names.global x
|
||||
|
||||
Found results in scratch/main
|
||||
|
||||
Terms
|
||||
Hash: #gjmq673r1v
|
||||
Names: some.otherplace.y some.place.x somewhere.z
|
||||
|
||||
Hash: #pi25gcdv0o
|
||||
Names: some.otherplace.x
|
||||
|
||||
-- We can search by hash, and see all aliases of that hash in the codebase
|
||||
scratch/other> debug.names.global #gjmq673r1v
|
||||
|
||||
Found results in scratch/main
|
||||
|
||||
Term
|
||||
Hash: #gjmq673r1v
|
||||
Names: some.otherplace.y some.place.x somewhere.z
|
||||
|
||||
-- We can search using an absolute name
|
||||
scratch/other> debug.names.global .some.place.x
|
||||
|
||||
Found results in scratch/main
|
||||
|
||||
Term
|
||||
Hash: #gjmq673r1v
|
||||
Names: some.otherplace.y some.place.x somewhere.z
|
||||
|
||||
```
|
||||
|
@ -165,8 +165,6 @@ scratch/main> names distributed.lib.baz.qux
|
||||
Term
|
||||
Hash: #nhup096n2s
|
||||
Names: lib.distributed.lib.baz.qux
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
```
|
||||
## Corner cases
|
||||
|
@ -60,8 +60,6 @@ scratch/main> names A
|
||||
Term
|
||||
Hash: #uj8oalgadr#0
|
||||
Names: A.A
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
```
|
||||
``` unison
|
||||
@ -99,8 +97,6 @@ scratch/main> names A
|
||||
Term
|
||||
Hash: #ufo5tuc7ho#0
|
||||
Names: A.A
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
```
|
||||
``` unison
|
||||
@ -140,7 +136,5 @@ scratch/main> names A
|
||||
Term
|
||||
Hash: #uj8oalgadr#0
|
||||
Names: A.A
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
```
|
||||
|
@ -62,7 +62,5 @@ scratch/main> names foo
|
||||
Term
|
||||
Hash: #9ntnotdp87
|
||||
Names: foo
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user