Here is the code for the command that I mentioned before, to go to a node and insert a backlink in the target node. I put this code into an @setting node with the headline:
@command zettel-goto-node @key=Alt+F6 The @setting node goes into the myLeoSettings.leo file. This code could use a bit more work. The main thing is that it may reorder the metadata lines in a zettel node. This does not change any behavior, but I like to have those lines in a particular order. I like them to start with the node id, then a timestamp, like this: :id: TomP.20200221124629.1 :timestamp: 02/22/2020 08:24:58 :link: TomP.20200221221759.1 TM4J :link: TomP.20200223153257.1 The order may get changed when the code inserts a new backlink in the target node because one did not exist before. I decided to have the link meta-lines have optional labels, because they help you know which links goes where. In the older paper-based system, identifiers generally looked like this (from https://www.lesswrong.com/posts/NfdHG6oHBJ8Qxc26s/the-zettelkasten-method-1 ): "I might have a train of thought which goes across cards 11, 11a, 11b, 11b1, 11b1a, 11b1a1, 18, 18a…" All well and good, but a few months later, if you see "11b1a1" in a link, you probably won't know what it goes to. You would have to fish around trying all the link references in your zettel to see which ones you might be interested it. Using an optional label seems better. -- You received this message because you are subscribed to the Google Groups "leo-editor" group. To unsubscribe from this group and stop receiving emails from it, send an email to leo-editor+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/leo-editor/4c34df33-c030-400a-918d-5866aa789c44%40googlegroups.com.
# Get gnx (node id) of target node from the ":link:" line of this node, # insert a backlink to this node in the target if the target does not have one, # and jump to the target node. # Does nothing if cursor is not on a line starting with ":link:". # If the backlink exists on the target node, but it has no label, then # add a label. The :link: specifier line is expected to look like this: # :link: TomP.20200223153257.1 About Leo # The "About Leo" part is the label. If a label on the backlink exists, # it is not changed, but if the link has no label, then one is constructed # from the headline of the node. def get_gnx_from_link(line): line = line.lstrip() is_link_line = line.startswith(':link:') gnx = '' label = '' if is_link_line: splits = line.split(':link:') if len(splits) > 1: fields = splits[1].split() gnx = fields[0] label = ' '.join(fields[1:]) if len(fields) > 1 else '' return gnx, label # List of line(s) containing cursor or selection cursor_lines = c.getBodyLines()[1] line = cursor_lines[0] if cursor_lines else '' line = line.lstrip() gnx, sending_label = get_gnx_from_link(line) if gnx: start_gnx = p.gnx node_label = p.h if node_label.startswith('@'): node_label = ' '.join(node_label.split()[1:]) start_link = f':link: {start_gnx}' start_link_label = f'{start_link} {node_label}' _found_target = False for _p in c.all_unique_positions(): if _p.gnx == gnx: c.selectPosition(_p) _found_target = True break if _found_target: lines = _p.b.split('\n') # Three cases for backlinks to sending node: # 1. Sending node has no backlink # 2. Sending node has backlink, but the backlink has no label # 3. Sending node has backlink with label. got_start_link = False for i, line in enumerate(lines): line = line.lstrip() if not line.startswith(':link:'): continue if start_link in line: got_start_link = True # case 2 if start_link == line: lines[i] = start_link_label _p.b = '\n'.join(lines) else: # Case 3 pass break if not got_start_link: # case 1 _p.b = f'{start_link_label}\n{_p.b}'