def cut_assign(cursor): """Cuts selected text and assigns it to a LilyPond variable.""" # ask the variable name name = inputdialog.getText(None, _("Cut and Assign"), _( "Please enter the name for the variable to assign the selected " "text to:"), regexp="[A-Za-z]+") if not name: return cursortools.strip_selection(cursor) # determine state at cursor block = cursortools.block(cursor) state = tokeniter.state(block) for t in tokeniter.partition(cursor).left: state.follow(t) mode = "" for p in state.parsers(): if isinstance(p, ly.lex.lilypond.ParseInputMode): if isinstance(p, ly.lex.lilypond.ParseLyricMode): mode = " \\lyricmode" elif isinstance(p, ly.lex.lilypond.ParseChordMode): mode = " \\chordmode" elif isinstance(p, ly.lex.lilypond.ParseFigureMode): mode = " \\figuremode" elif isinstance(p, ly.lex.lilypond.ParseDrumMode): mode = " \\drummode" break # find insertion place: found = False while block.previous().isValid(): block = block.previous() state = tokeniter.state(block) if isinstance(state.parser(), ly.lex.lilypond.ParseGlobal): found = True break tokens = tokeniter.tokens(block) for t in tokens: if isinstance(t, ly.lex.lilypond.Name): found = True break elif not isinstance(t, (ly.lex.Space, ly.lex.Comment)): break if found: break insert = QTextCursor(block) text = cursor.selection().toPlainText() space = '\n' if '\n' in text else ' ' text = ''.join((name, ' =', mode, ' {', space, text, space, '}\n\n')) with cursortools.compress_undo(cursor): cursor.insertText('\\' + name) pos = insert.selectionStart() insert.insertText(text) if metainfo.info(cursor.document()).auto_indent: insert.setPosition(pos, QTextCursor.KeepAnchor) with cursortools.compress_undo(insert, True): indent.re_indent(insert)
def slotAccepted(self): """Makes the score and puts it in the editor.""" from . import build builder = build.Builder(self) cursor = self.parent().currentView().textCursor() with cursortools.compress_undo(cursor): cursortools.insert_select(cursor, builder.text()) indent.re_indent(cursor)
def reformat(cursor): """Reformats the selection or the whole document, adjusting the whitespace.""" def newlinebefore(t): editor.insertText(tokeniter.cursor(block, t, end=0), '\n') def newlineafter(t): editor.insertText(tokeniter.cursor(block, t, start=len(t)), '\n') indent_vars = indent.indent_variables(cursor.document()) with cursortools.compress_undo(cursor): indent.re_indent(cursor) with cursortools.Editor() as editor: for block in get_blocks(cursor): denters = [] tokens = tokeniter.tokens(block) nonspace_index = -1 for i, t in enumerate(tokens): if isinstance(t, ly.lex.Indent) and t in ('{', '<<'): denters.append(i) elif isinstance(t, ly.lex.Dedent) and t in ('}', '>>'): if denters: denters.pop() elif nonspace_index != -1: newlinebefore(t) elif not isinstance(t, ly.lex.Space): nonspace_index = i for i in denters: if i < nonspace_index: newlineafter(tokens[i]) # TODO: wrap long lines indent.re_indent(cursor) with cursortools.Editor() as editor: for block in get_blocks(cursor): tokens = tokeniter.tokens(block) if (len(tokens) == 2 and isinstance(tokens[0], ly.lex.Space) and isinstance(tokens[1], ( ly.lex.lilypond.LineComment, ly.lex.scheme.LineComment)) and len(tokens[1]) > 2 and len(set(tokens[1][:3])) == 1): # move commented lines with more than 2 comment characters # to column 0 editor.removeSelectedText(tokeniter.cursor(block, tokens[0])) else: # remove trialing whitespace for t in tokens[::-1]: if isinstance(t, ly.lex.Space): editor.removeSelectedText(tokeniter.cursor(block, t)) else: break
def save(self): """Called to perform the edits in the document.""" cursor = QTextCursor(self._range) start = cursor.selectionStart() # use cursordiff; don't destroy point and click positions cursordiff.insert_text(cursor, self.view.toPlainText()) cursor.setPosition(start, QTextCursor.KeepAnchor) with cursortools.compress_undo(cursor, True): # re-indent the inserted line(s) indent.re_indent(cursor)
def slotAccepted(self): """Makes the score and puts it in the editor.""" if self._createNewDocument: self.parent().setCurrentDocument(app.openUrl(QUrl())) from . import build builder = build.Builder(self) cursor = self.parent().currentView().textCursor() cursortools.insert_select(cursor, builder.text()) with cursortools.compress_undo(cursor, True): indent.re_indent(cursor)
def insertText(self, text, indent=True, blankline=False): """Insert text in the current document and focuses the document again. Besides the text, the following keyword arguments may be used: indent (default: True): The text will be indented if there are one or more newlines in it. blankline (default: False): A newline will be prepended to text if the cursor is currently not on a blank line. """ cursor = self.mainwindow().textCursor() if blankline and not cursor.hasSelection() and not cursortools.isblank_before(cursor): text = '\n' + text pos = cursor.selectionStart() cursor.insertText(text) if indent and '\n' in text: cursor.setPosition(pos, cursor.KeepAnchor) import indent with cursortools.compress_undo(cursor, True): indent.re_indent(cursor)
def insert(name, view): """Insert named snippet into the view.""" text, variables = snippets.get(name) cursor = view.textCursor() selection = variables.get('selection', '') if 'yes' in selection and not cursor.hasSelection(): return if 'strip' in selection: cursortools.strip_selection(cursor) pos = cursor.selectionStart() with cursortools.compress_undo(cursor): # insert the snippet, might return a new cursor if 'python' in variables: new = insert_python(text, cursor, name, view) elif 'macro' in variables: new = insert_macro(text, view) else: new = insert_snippet(text, cursor, variables) # QTextBlocks the snippet starts and ends block = cursor.document().findBlock(pos) last = cursor.block() # re-indent if not explicitly suppressed by a 'indent: no' variable if last != block and 'no' not in variables.get('indent', ''): c = QTextCursor(last) c.setPosition(block.position(), QTextCursor.KeepAnchor) with cursortools.compress_undo(c, True): indent.re_indent(c, True) if not new and 'keep' in selection: end = cursor.position() cursor.setPosition(pos) cursor.setPosition(end, QTextCursor.KeepAnchor) view.setTextCursor(new or cursor)
def re_indent(self): import indent indent.re_indent(self.currentView().textCursor())
def cut_assign(cursor): """Cuts selected text and assigns it to a LilyPond variable.""" # ask the variable name name = inputdialog.getText( None, _("Cut and Assign"), _("Please enter the name for the variable to assign the selected " "text to:"), regexp="[A-Za-z]+") if not name: return cursortools.strip_selection(cursor) # determine state at cursor block = cursortools.block(cursor) state = tokeniter.state(block) for t in tokeniter.partition(cursor).left: state.follow(t) mode = "" for p in state.parsers(): if isinstance(p, ly.lex.lilypond.ParseInputMode): if isinstance(p, ly.lex.lilypond.ParseLyricMode): mode = " \\lyricmode" elif isinstance(p, ly.lex.lilypond.ParseChordMode): mode = " \\chordmode" elif isinstance(p, ly.lex.lilypond.ParseFigureMode): mode = " \\figuremode" elif isinstance(p, ly.lex.lilypond.ParseDrumMode): mode = " \\drummode" break # find insertion place: found = False while block.previous().isValid(): block = block.previous() state = tokeniter.state(block) if isinstance(state.parser(), ly.lex.lilypond.ParseGlobal): found = True break tokens = tokeniter.tokens(block) for t in tokens: if isinstance(t, ly.lex.lilypond.Name): found = True break elif not isinstance(t, (ly.lex.Space, ly.lex.Comment)): break if found: break insert = QTextCursor(block) text = cursor.selection().toPlainText() space = '\n' if '\n' in text else ' ' text = ''.join((name, ' =', mode, ' {', space, text, space, '}\n\n')) with cursortools.compress_undo(cursor): cursor.insertText('\\' + name) pos = insert.selectionStart() insert.insertText(text) if metainfo.info(cursor.document()).auto_indent: insert.setPosition(pos, QTextCursor.KeepAnchor) with cursortools.compress_undo(insert, True): indent.re_indent(insert)