NEDIT_require_macro_file("RSextensions.nm") NEDIT_require_macro_file("RSselect.nm") NEDIT_require_macro_file("centerline.nm") # ------------------------------------------------------------------------------ # RangeSet_NavigateWhich([rs [, ask]]): if rangeset name rs is supplied, it is # checked for validity. If OK, it is returned. Otherwise, or if a second # argument is supplied, a new rangeset name is requested from the user # and returned. Whatever the result, $RS_Navigate["?"] is updated as # as appropriate. # ------------------------------------------------------------------------------ define RangeSet_NavigateWhich { RSnavigation = "Navigation Range Set" none = !RangeSet_defined() $RS_Navigate[""] = "" error = "" blank = "" oldrs = "" current = "" if ("?" in $RS_Navigate) { oldrs = $RS_Navigate["?"] if (oldrs != "") current = "\n(Current " RSnavigation " name is \"" oldrs "\")" } rs = oldrs if ($n_args <= 1) { if ($n_args == 1) { if (RangeSet_defined($1)) { $RS_Navigate["?"] = $1 return $1 } } # no args given if (RangeSet_defined(oldrs)) return oldrs } # two arguments or more; or an error - ask if (none) error = RSnavigation " cannot be chosen: no range set defined" current else if (oldrs != "") { if (!RangeSet_defined(oldrs)) error = RSnavigation " \"" oldrs "\" not defined in this document" else error = RSnavigation " was \"" oldrs "\"" } # ask for a rangeset to navigate if any if (error != "") blank = "\n\n" if (!none) { rs = RangeSet_askExisting(error blank "Range set to navigate") if (RangeSet_defined(rs)) { dialog(RSnavigation" "rs" has "$RangeSet_ranges" ranges") $RS_Navigate["?"] = rs return rs } } else if (error != "") dialog(error) return "" } # ------------------------------------------------------------------------------ # RangeSet_Navigate(rs, direction, selectit, center): "navigates" the given # rangeset rs's ranges, asking for a valid rangeset if rs is empty or # invalid. Each time this is called, the cursor is moved in the current # window to the next or previous range in the set, if any. # If the operation cannot be completed, a beep is issued. Direction # should be a negative value for backward navigation; otherwise it is # forward. If selectit is non-zero, the range "navigated to" is selected; # if center is non-zero, the cursor line after cursor movement is centered # in the window. # ------------------------------------------------------------------------------ define RangeSet_Navigate { rs = $1 direction = $2 selectit = 0 center = 0 if ($n_args > 2) { selectit = $3 if ($n_args > 3) center = $4 } if (rs == "") rs = RangeSet_NavigateWhich() else rs = RangeSet_NavigateWhich(rs) nrs = $RangeSet_ranges if (nrs == 0 || !("?" in $RS_Navigate)) { return } # are we in a range of the set? prev = -1 next = -1 pos = $cursor r = -1 if (RangeSet_includes_pos(rs, pos)) { # we are in a range: if we're at its front, our prev is before it prev = $RangeSet_range_index - (pos == $RangeSet_range_start) next = $RangeSet_range_index + 1 } else { # we are not in a range: find which gap we are in hi = nrs lo = 0 for (mi = nrs / 2; lo < hi; mi = (lo + hi) / 2) { RangeSet_defined(rs, mi) if (pos < $RangeSet_range_start) hi = mi else lo = mi + 1 } next = hi prev = next - 1 } # right: move appropriately if (direction < 0 && prev >= 0) { # backward - use prev r = prev } else if (direction >= 0 && next < nrs) { # forward - use next r = next } else { # chosen direction has no more range motion possible beep() return } RangeSet_defined(rs, r) # try to maximise the visibility of the new range, # finishing with the cursor at the front of the range set_cursor_pos($RangeSet_range_end) if (center) centerline() set_cursor_pos($RangeSet_range_start) if (selectit) RangeSet_select(rs, r) }