Ahh, yeah. I misread what you said there; sorry about that. Here’s an example of a plugin that jumps the cursor to the center of the current view:
def run(self, edit):
# To shorten things up a bit, alias the view
v = self.view
# Based on the view, get the height of a line, the height of the
# viewport in general, and the viewport position information.
lh = v.line_height()
vh = v.viewport_extent()
vp = v.viewport_position()
# Calculate the number of lines the view can hold, the line currently
# at the top of the view (even partially), and the line that falls at
# the middle of the view; note that these are 0 based, not 1 based.
view_lines = vh / lh
top_line = vp / lh
window_mid = (view_lines / 2) + top_line
# Get the caret position of the first selection and convert it from a
# point (buffer offset) into a (row, column) value instead.
cur_rowcol = v.rowcol(v.sel().b)
# Get the region that spans the line in the middle of the window and
# convert it's endpoint to a (row, column) offset so that we know at
# what column it ends.
mid_line = v.rowcol(v.line(v.text_point(window_mid, 0)).end())
# Create the new caret location; place it on the line in the middle of
# the window and using either the original column, or the end of the
# mid line if the mid line is shorter than the line it was already on.
pt = v.text_point(window_mid, min(cur_rowcol, mid_line))
# If the point falls outside of the view, put it at the last character
if pt > v.size():
pt = v.size()
# Clear the selection and replace it with the new one
This inherently converts multiple selections into a single selection centered on the line in the middle of the view; for multiple cursors it would have to do similar manipulations on the existing selections one at a time, perhaps by calculating the line offset of the first selection and then applying it to the remainder.