Source code for ly.cursortools

# This file is part of python-ly, https://pypi.python.org/pypi/python-ly
#
# Copyright (c) 2013 - 2015 by Wilbert Berendsen
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
# See http://www.gnu.org/licenses/ for more information.

"""
Routines manipulating ly.document.Cursor instances.

"""

from __future__ import unicode_literals


import ly.lex
import ly.document


[docs]def find_indent(iterable): """Yield (token, is_indent, nest) for every occurring indent/dedent token. The tokens are yielded from the specified iterable. """ nest = 0 for token in iterable: if isinstance(token, ly.lex.Indent): nest += 1 yield token, True, nest elif isinstance(token, ly.lex.Dedent): nest -= 1 yield token, False, nest
[docs]def select_block(cursor): """Try to select a meaningful block. Searches backwards for an indenting token, then selects up to the corresponding dedenting token. If needed searches an extra level back to always extend the selection. Returns True if the cursor's selection has changed. """ end = cursor.end if cursor.end is not None else cursor.document.size() tokens = ly.document.Runner.at(cursor, after_token=True) # search backwards to the first indenting token for token, isindent, nest in find_indent(tokens.backward()): if isindent and nest == 1: pos1 = tokens.position() startpoint = tokens.copy() # found, now look forward for token, isindent, nest in find_indent(tokens.forward()): if not isindent and nest < 0 and tokens.position() + len(token) >= end: # we found the endpoint pos2 = tokens.position() + len(token) if nest < -1: threshold = 1 - nest for token, isindent, nest in find_indent(startpoint.backward()): if isindent and nest == threshold: pos1 = tokens.position() break cursor.start, cursor.end = pos1, pos2 return True return