Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
I have a dumb editor question.
-
With the default setting to auto add closing brackets and quotes, is there any magic way to skip to just past the nearest auto-added closing quote or bracket? I always turn the setting off because moving the cursor is maddeningly difficult compared to just manually inserting the closing character myself.
Since all editors love to do this these days, I wonder if there’s some secret way to skip past them that I’ve just never gotten the memo on lol.
-
@Zoot You can skip the closing bracket by typing it.
-
@Zoot for the fun, you could try this little script that you can run as a tool. So you will have a supplementary row with only one key (or more) which skips automatically the cursor after first closing ' or " or ) or ] or }
The @omz solution only works if the cursor is just before the closing character but this tool also works if the cursor is several positions before the closing character.
Edit : the script, as a Pythonista tool, has to be run once for each new editor tab.
import editor from objc_util import * import ui def key_pressed(sender): tv = sender.objc_instance.firstResponder() # associated TextView # get actual cursor position cursor = tv.offsetFromPosition_toPosition_(tv.beginningOfDocument(), tv.selectedTextRange().start()) if sender.name == 'after': # skip to just past the nearest auto-added closing ' or " or } or ] or ) while True: if cursor == (len(str(tv.text()))-1): return t = str(tv.text())[cursor] cursor += 1 if t in ("')]}"+'"'): break else: # normal key tv.insertText_(sender.title) return # set cursor cursor_position = tv.positionFromPosition_offset_(tv.beginningOfDocument(), cursor) tv.selectedTextRange = tv.textRangeFromPosition_toPosition_(cursor_position, cursor_position) class MyView(ui.View): def __init__(self, pad, *args, **kwargs): #super().__init__(self, *args, **kwargs) self.width = ui.get_screen_size()[0] # width of keyboard = screen self.background_color = 'lightgray'#(0,1,0,0.2) self.h_button = 32 self.pad = pad # build buttons for pad_elem in self.pad: if pad_elem['key'] in ('nul', 'new row'): # free space or new row continue button = ui.Button() # Button for user functionnality button.name = pad_elem['key'] button.background_color = 'white' # or any other color button.tint_color = 'black' button.corner_radius = 5 button.font = ('<system>',self.h_button - 8) button.title = '' if 'title' in pad_elem: button.title = pad_elem['title'] elif 'icon' in pad_elem: button.image = ui.Image.named(pad_elem['icon']).with_rendering_mode(ui.RENDERING_MODE_ORIGINAL) else: button.title = pad_elem['key'] button.action = key_pressed retain_global(button) # see https://forum.omz-software.com/topic/4653/button-action-not-called-when-view-is-added-to-native-view self.add_subview(button) self.layout() def layout(self): import ui #print('layout') # supports changing orientation #print(ui.get_screen_size()) dx = 8 dy = 2 x0 = 15 y0 = 10 dx_middle = 25 y = y0 x = x0 w_button = (ui.get_screen_size()[0] - 2*x0 - 17*dx - dx_middle)/18 for pad_elem in self.pad: nw = pad_elem.get('width', 1) wb = w_button*nw + dx*(nw-1) if (x + wb + dx) > self.width: y = y + self.h_button + dy x = x0 if pad_elem['key'] == 'nul': # let free space x = x + wb + dx continue elif pad_elem['key'] == 'new row': # new row y = y + self.h_button + dy x = x0 continue button = self[pad_elem['key']] xb = x + dx_middle if (x+wb) > self.width/2 else x button.frame = (xb,y,wb,self.h_button) if button.title != '': font_size = self.h_button - 8 while True: d = ui.measure_string(button.title,font=(button.font[0],font_size))[0]+4 if d <= wb: break font_size = font_size - 1 button.font = (button.font[0],font_size) x = x + wb + dx self.height = y + self.h_button + dy @on_main_thread def AddButtonsToPythonistaKeyboard(pad=None): if not pad: pad = [ {'key':'after','title':'⤵️'}] ev = editor._get_editor_tab().editorView() tv = ev.textView() #print(tv._get_objc_classname()) #print(dir(tv)) # create ui.View for InputAccessoryView above keyboard v = MyView(pad) # view above keyboard vo = ObjCInstance(v) # get ObjectiveC object of v retain_global(v) # see https://forum.omz-software.com/topic/4653/button-action-not-called-when-view-is-added-to-native-view tv.setInputAccessoryView_(vo) # attach accessory to textview if __name__ == '__main__': AddButtonsToPythonistaKeyboard()