// TODO: Change amount to a proper type with 4 values, etc. to avoid confusion with other funcs where amount can be an arbitrary number. // TOOD: Rename to JumpTo or something to indicate it's a method that can never fail. // Move jumps the caret position to a new position. This operation never fails, but may not have any effect. // If amount is ±1, move by 1 character within same line if possible. // If amount is ±2, jump to start/end of line. // If amount is ±3, jump to start/end of content. func (cp *caretPositionInternal) Move(amount int8) { originalPosition := *cp switch amount { // Move by 1 character within same line, if possible. case -1: if cp.positionWithinLine > 0 { cp.positionWithinLine-- } case +1: if cp.positionWithinLine < cp.w.Line(cp.lineIndex).Length() { cp.positionWithinLine++ } case -2: cp.positionWithinLine = 0 case +2: cp.positionWithinLine = cp.w.Line(cp.lineIndex).Length() case -3: cp.lineIndex = 0 cp.positionWithinLine = 0 case +3: cp.lineIndex = cp.w.LenLines() - 1 cp.positionWithinLine = cp.w.Line(cp.lineIndex).Length() } if cp.Compare(&originalPosition) == 0 { // There's no change, so don't do anything else return } cp.targetExpandedX, _ = cp.expandedPosition() // TODO: More direct gist7802150.ExternallyUpdated(&cp.DepNode2Manual) }
func (cp *caretPositionInternal) MoveTo(other *caretPositionInternal) { cp.lineIndex = other.lineIndex cp.positionWithinLine = other.positionWithinLine cp.targetExpandedX = other.targetExpandedX gist7802150.ExternallyUpdated(&cp.DepNode2Manual) }
// Moves caret horizontally by amount. It doesn't do bounds checking, so it's // the caller's responsibility to ensure it's a legal amount to move by. // // Pre-conditions: // - Moving caret by amount should result in a valid position. func (cp *caretPositionInternal) willMoveH(amount int32) { switch { case amount < 0: absAmount := uint32(-amount) for absAmount != 0 { if cp.positionWithinLine >= absAmount { cp.positionWithinLine -= absAmount absAmount = 0 } else { //if cp.lineIndex > 0 absAmount -= 1 + cp.positionWithinLine cp.lineIndex-- cp.positionWithinLine = cp.w.Line(cp.lineIndex).Length() } } case amount > 0: absAmount := uint32(amount) for absAmount != 0 { if cp.positionWithinLine+absAmount <= cp.w.Line(cp.lineIndex).Length() { cp.positionWithinLine += absAmount absAmount = 0 } else { //if cp.lineIndex < some_max absAmount -= 1 + cp.w.Line(cp.lineIndex).Length() - cp.positionWithinLine cp.lineIndex++ cp.positionWithinLine = 0 } } default: // There's no change, so don't do anything else return } cp.targetExpandedX, _ = cp.expandedPosition() // TODO: More direct gist7802150.ExternallyUpdated(&cp.DepNode2Manual) }
// updateWorker is a sequential updater of Go packages. It does not update them in parallel // to avoid race conditions or other problems, since `go get -u` does not seem to protect against that. func updateWorker() { for updateRequest := range updateRequestChan { if !production { fmt.Println("got req:", updateRequest.importPathPattern) time.Sleep(time.Second) fmt.Println("Done.") updateRequest.resultChan <- nil continue } var updateErr = fmt.Errorf("import path pattern %q not found in GOPATH", updateRequest.importPathPattern) gist7802150.MakeUpdated(goPackages) for _, goPackage := range goPackages.List() { if rootPath := getRootPath(goPackage); rootPath != "" { if gist7480523.GetRepoImportPathPattern(rootPath, goPackage.Bpkg.SrcRoot) == updateRequest.importPathPattern { vcs := goPackage.Dir.Repo.RepoRoot.VCS fmt.Printf("cd %s\n", rootPath) fmt.Printf("%s %s", vcs.Cmd, vcs.DownloadCmd) updateErr = vcs.Download(rootPath) // Invalidate cache of the package's local revision, since it's expected to change after updating. gist7802150.ExternallyUpdated(goPackage.Dir.Repo.VcsLocal.GetSources()[1].(gist7802150.DepNode2ManualI)) break } } } updateRequest.resultChan <- updateErr fmt.Println("\nDone.") } }
func (u GopathUpdater) Update(importPathPattern string) error { // TODO: This uses a legacy gist7802150 caching/cache-invalidation system. It's functional, // but poorly documented, has known flaws (it does not allow concurrent updates), // and very contributor-unfriendly (people don't like packages that have the word "gist" in // the import path, even if's not actually a gist; which is understandable, since it's basically // a package without a name that describes what it's for - that's something acceptable during // rapid prototyping, but not for the finished product). Need to redesign it and replace with // something better. // // First step might be to simply drop the caching behavior and hope the user doesn't try // to manually refresh their browser page very often. var updateErr = fmt.Errorf("import path pattern %q not found in GOPATH", importPathPattern) gist7802150.MakeUpdated(u.GoPackages) for _, goPackage := range u.GoPackages.List() { if rootPath := util.GetRootPath(goPackage); rootPath != "" { if gist7480523.GetRepoImportPathPattern(rootPath, goPackage.Bpkg.SrcRoot) == importPathPattern { vcs := goPackage.Dir.Repo.RepoRoot.VCS fmt.Printf("cd %s\n", rootPath) fmt.Printf("%s %s", vcs.Cmd, vcs.DownloadCmd) updateErr = vcs.Download(rootPath) // Invalidate cache of the package's local revision, since it's expected to change after updating. gist7802150.ExternallyUpdated(goPackage.Dir.Repo.VcsLocal.GetSources()[1].(gist7802150.DepNode2ManualI)) break } } } return updateErr }
func (cp *caretPositionInternal) tryMoveV(direction direction, jumpWords bool) { switch direction { case Backward: if cp.lineIndex > 0 { if jumpWords { for cp.lineIndex > 0 { cp.lineIndex-- line := cp.w.Content()[cp.w.Line(cp.lineIndex).Start():cp.w.Line(cp.lineIndex).End()] if line == "" { break } } cp.positionWithinLine = 0 } else { cp.lineIndex-- line := cp.w.Content()[cp.w.Line(cp.lineIndex).Start():cp.w.Line(cp.lineIndex).End()] cp.positionWithinLine = ExpandedToLogical(line, cp.targetExpandedX) } gist7802150.ExternallyUpdated(&cp.DepNode2Manual) } else { cp.Move(-2) } case Forward: if cp.lineIndex < cp.w.LenLines()-1 { if jumpWords { for cp.lineIndex < cp.w.LenLines()-1 { cp.lineIndex++ line := cp.w.Content()[cp.w.Line(cp.lineIndex).Start():cp.w.Line(cp.lineIndex).End()] if line == "" { break } } cp.positionWithinLine = 0 } else { cp.lineIndex++ line := cp.w.Content()[cp.w.Line(cp.lineIndex).Start():cp.w.Line(cp.lineIndex).End()] cp.positionWithinLine = ExpandedToLogical(line, cp.targetExpandedX) } gist7802150.ExternallyUpdated(&cp.DepNode2Manual) } else { cp.Move(+2) } } }
// TrySetPositionAtLineIndex places caret at beginning of lineIndex line. It accepts out of range line indicies. func (cp *caretPositionInternal) TrySetPositionAtLineIndex(lineIndex int) { if lineIndex < 0 { lineIndex = 0 } else if lineIndex > cp.w.LenLines()-1 { lineIndex = cp.w.LenLines() - 1 } cp.lineIndex = lineIndex cp.positionWithinLine = 0 cp.targetExpandedX = 0 gist7802150.ExternallyUpdated(&cp.DepNode2Manual) }
func (cp *caretPositionInternal) TrySet(position uint32) { if position > uint32(cp.w.LenContent()) { position = uint32(cp.w.LenContent()) } cp.lineIndex = sort.Search(cp.w.LenLines()-1, func(lineIndex int) bool { return cp.w.Line(lineIndex+1).Start() > position }) cp.positionWithinLine = position - cp.w.Line(cp.lineIndex).Start() cp.targetExpandedX, _ = cp.expandedPosition() // TODO: More direct gist7802150.ExternallyUpdated(&cp.DepNode2Manual) }
func (cp *caretPositionInternal) SetPositionFromLogical(pos mgl64.Vec2) { if pos[1] < 0 { cp.lineIndex = 0 } else if pos[1] >= float64(cp.w.LenLines()) { cp.lineIndex = cp.w.LenLines() - 1 } else { cp.lineIndex = int(pos[1]) } if pos[0] < 0 { cp.targetExpandedX = 0 } else { cp.targetExpandedX = uint32(pos[0] + 0.5) } line := cp.w.Content()[cp.w.Line(cp.lineIndex).Start():cp.w.Line(cp.lineIndex).End()] cp.positionWithinLine = ExpandedToLogical(line, cp.targetExpandedX) gist7802150.ExternallyUpdated(&cp.DepNode2Manual) }