8: Moving Through Text - transcript

Download the MP3

Liam: The QUILL Cast, episode eight. I'm Liam. We just closed the first-steps arc with episode seven, where Jessica walked you through the verbosity system. Today we are in the same neighborhood, except the words are about getting your cursor to where the next edit happens. Editing speed is mostly navigation speed, and the rest of the everyday-editor arc that runs through episode fourteen is going to lean on the vocabulary we build here.

Jessica: I'm Jessica, and I want to recap episode seven in one breath, because it sets up today's framing. Last episode we described the five-layer verbosity cake. Channels, the four-way routing of speech, braille, sound, and visual. Profiles, the talkativeness ladder of beginner, normal, expert, and quiet. Runtime modes, the mid-work toggles for quiet and meeting. Per-verb overrides and templates, the surgical rewrites. And history, the audit trail. The framing matters today because every navigation command produces an announcement, and how loud or quiet that announcement is depends on the profile you set up in episode seven.

Liam: The honest frame for the next forty minutes is this: navigation in QUILL is a vocabulary, not a feature list. The words in the vocabulary are characters, words, lines, paragraphs, sections, headings, bookmarks, marks, lines-by-number. Each is a word in the sentence "get me there," and fluency is knowing which word fits the moment. We are going to walk the vocabulary in roughly the order most people discover it, and we are going to verify every claim against the source. When the docs and the source disagree, we will say so out loud. The first seven episodes were the on-ramp. The next eight are the everyday editor, and movement is the foundation under all of it.

Jessica: Layer one is the standard grammar you already know, and QUILL honors all of it. Arrows move the caret by character and by line. Control plus arrows move by word. Home and End move to the edges of a line. Control plus Home and Control plus End move to the start and end of the document. Page Up and Page Down move by a screen. Holding Shift while doing any of those extends the range into a selection. The reason this is layer one and not the headline: if you can edit in Notepad, your hands already work here. The rest of today's episode is about reaching for the bigger words when arrows stop being fast enough.

Liam: Layer two is structural movement, and this is where QUILL starts to do work that plain editors do not. In a Markdown document, and Markdown is just text with headings, which we will formalize in episode fourteen, QUILL can hop between the structural elements of the document. The keymap registers Alt+Down as navigate.next_structure and Alt+Up as navigate.previous_structure. The implementation calls next_structure_position and previous_structure_position from quill.core.structure_nav, which know how to step between headings, paragraphs, and blocks based on the document's effective markup kind. So one chord, Alt+Down, is your structural "go down one unit of meaning." Hold Alt and tap the arrow enough times, and you can walk a long document by structure without ever counting paragraphs by eye.

Jessica: What you just described is also the introduction to a new mental model. Most editing thought happens a paragraph at a time, not a character at a time, and the structural movement chord is the first time the keyboard matches that thought. In a forty-paragraph document, Alt+Down nine times gets you to paragraph ten. The arrows feel slow afterward. The catch is that the granularity of "structural" depends on the file. In a Markdown file it means headings and blocks. In a plain text file it falls back to paragraphs. The code makes the call based on the file extension, and the same Alt+Down behaves correctly across file types.


Liam: Layer three is remembered places, and there are two flavors: named bookmarks, which are persistent and per-document, and the mark ring, which is transient and session-scoped. The keymap registers Control plus Shift plus M as set_mark, Control plus M as pop_mark, Control plus Shift plus X as exchange_point_and_mark, and Alt plus M as list_marks. Named bookmarks are a separate feature with their own commands, navigate.set_bookmark, navigate.go_to_bookmark, and navigate.list_bookmarks, and the keymap lists the third one, Alt plus Shift plus B for list_bookmarks. The set and go commands exist in the code but are not bound in the default keymap, which is a small code-versus-keymap drift we want to name: if you want a one-key chord for setting and jumping bookmarks, you can wire one up in the keymap editor.

Jessica: Named bookmarks are the one to fall in love with first, because they are persistent. When you set a bookmark, the position is saved to the document's memory in core DocumentMemory, and when the document is saved to disk, those bookmarks survive a restart. Each document has its own list. You name the bookmark when you set it, default name "Bookmark N," and you can rename it to anything that helps you remember. The list_bookmarks command opens a small navigator with each bookmark labeled by line and column, and selecting one jumps you there. The honest framing: bookmarks are for places you go back to often. The mark ring, by contrast, is for places you were just now and might want to bounce back to. They are different tools, and they earn their keep in different ways.

Liam: The mark ring is implemented in quill.core.marks as a stack of positions with a default max size of twenty. set_mark pushes the current caret position onto the ring, with one small smart bit: if the position is already on the ring, the ring removes the older copy and pushes the new one, so the most recent use floats to the top. pop_mark pops the most recent mark and moves you there. exchange_point_and_mark swaps your current position with the top of the ring, which is the "bounce back" operation: you set a mark, you wander, you exchange, you are back where you started, and the mark is now where you were. This is the operation that screen-reader users reach for when they need to look something up elsewhere in a document and return. The status announcements are exact. Set says "Mark ring point set at line N, column M, temporary jump." Pop says "Popped to mark ring point." Exchange says "Exchanged point and mark to line N, column M." The naming is honest, "temporary jump," so you know the marks do not outlive the session.

Jessica: A code honesty moment, because we promised them. The list_marks command in the keymap is bound to Alt plus M, and we have not yet verified that the ring survives a quit. It does not. The MarkRing is a transient, session-scoped structure. The status text calls them "temporary jump points" and the code is honest about that. If you want a persistent jump, set a named bookmark. The ring is for the last twenty places you were; bookmarks are for the places you go back to next week.


Liam: Do this with us right now, before we go deeper. Open any document, and the longer the better. Hit Control plus Shift plus M twice in two different places, then Control plus M to pop back. Notice the status line each time. Now hit Control plus Shift plus X to exchange, and notice the caret jump. Then move somewhere unrelated, exchange again, and you are back where you started. That single thirty-second interaction is the entire mark ring. If it lands, the rest of the show is going to make sense. If it does not land, pause the audio and come back. We will still be here.

Jessica: Welcome back. The next layer is Go To Line, and the keymap binds it to Control plus G. The dialog is a simple text entry, and the placeholder prompt is "Enter line or line,column." You can type a number for a line, or a number, comma, number for line and column, for example 12 or 12,4. The implementation parses the input, validates the line is at least one and the column, if present, is at least one, computes the insertion point by walking line starts in the document buffer, and moves the caret there. There is also a non-prompting entry point, go_to_line_number, used by Go To Anything, which silently sets the status to "Line N out of range" if you ask for a line the document does not have. Go To Line is a small dialog with two modes, and either one of them will save you the cost of scrolling.

Liam: The single most important thing about Go To Line is what happens around it. Before it moves the caret, it calls _record_location_before_jump, which records the current caret position into the location ring. After it moves, it calls _location_ring.record to put the new position on the ring too. The same pattern is used by every other jump command. The result is that you get free undo for any jump. If you Go To Line 240 by accident, you can pop the location ring forward to come back, and the navigation ring knows your path. The keymap does not bind the back and forward location commands by default, which is a small design call: the reachability story is "open the palette and type back or forward," and the chord story is "bind them yourself in the keymap editor." Either way works.

Jessica: A second honesty moment, also promised. The status text after a Go To Line is "Moved to line N" for a line-only jump, or "Moved to line N, column M" for a line-and-column jump. If the line is out of range, the dialog shows a message box saying the document has only N lines, and the caret does not move. If the input is malformed, the dialog says "Use a line number or line,column." The error paths are designed to be spoken by a screen reader and read in the status bar, which means the failure mode is announced, not silent. That is the same design law we described in episode seven: errors survive the suppression ladder, because losing your place silently is worse than being interrupted by an explanation.


Liam: The next layer is the mode that ties navigation together: Browse Mode and Quick Nav, and this is the proper introduction. Browse Mode is the one that makes the rest of the vocabulary feel fast. QUILL has a configurable prefix key, called the QUILL key. The default binding is Control plus Shift plus Grave, the backtick and tilde key. The label the interface uses is the QUILL key, so we will use that name. Press it once, and the next key you press is a command instead of a letter. That is Quick Nav: one command, then back to typing. Press it twice in a row, the second press within the prefix window, and Browse Mode locks on. Now letters and arrows keep acting as navigation commands until you press Escape. If you have used a screen reader on the web, you know this idea intimately. It is the virtual cursor pattern, brought into the editor. Skim a long document by headings in Browse Mode, escape, and you are typing again.

Jessica: The browse mode follow-on timeout is its own setting, browse_mode_followon_timeout, with presets of fast at 1.5 seconds, normal at 4 seconds, slow at 8 seconds, plus instant, custom, and unlimited tokens. The default after a fresh install is unlimited, which means Browse Mode stays active until you press Escape. The reason this is a separate setting from the prefix-decision window, which is the quill_key_timeout_seconds setting with a default of 2.5 seconds, is that you want the prefix decision to be quick, but you want Browse Mode itself to be generous. The two are different user experiences, and the code reflects that.

Liam: Once Browse Mode is on, the keys it accepts are the Quick Nav bindings in the keymap, plus the digits 1 through 6 for heading levels and Tab for blocks. The default Quick Nav bindings in profile_default.json are H for heading, A for link, L for list, I for list item, T for table, Q for block quote, B for bookmark, apostrophe for code block, C for table of contents, P for paragraph, S for sentence, Tab for block, close-bracket for skip forward, open-bracket for skip backward, and period to repeat the last Browse Mode action. Hold Shift to reverse direction. The mnemonic is the letter, the convention is the direction, and the muscle memory builds the second time you use it.

Jessica: Browse Mode is also the only place where the period key does anything. Pressing period re-runs the last action. If you H-jumped to the next heading twice and you want a third, just press period. The same is true for jumping tables, block quotes, list items, sentences, and the rest. The honest framing: this is the muscle-memory payoff for the whole layer cake. Once Browse Mode is in your fingers, the period key is the one that turns "remember the chord" into "press it again without thinking."


Liam: Do this with us, one more interactive beat. Press the QUILL key, Control plus Shift plus Grave, once. Listen for the prefix announcement. Press it again within the prefix window. You should hear "QUILL browse mode active" or "QUILL browse mode locked," depending on whether the sticky default is on in your settings. Now press H a few times, period a few more times, and notice the headings fly by. Then press Escape. The status should confirm the exit. If your QUILL key binding has been changed from the default, the prefix will still be whatever you set, but the flow is identical. Take a minute, do the dance, then come back. The Browse Mode rhythm is what the rest of the show is pointing at.

Jessica: Welcome back. The next layer is Quick Nav as a panel, which is the live-count navigator that the prefix can also open. The keymap registers G as the second-key to open Quick Nav from the prefix, and the standalone command navigate.quick_nav exists in the command registry as a palette-reachable command. Quick Nav builds a unified index of the document's navigable landmarks in quill.core.quick_nav, the same index Browse Mode walks, and presents it as a search-as-you-type panel. The index knows about headings, links, lists, list items, tables, block quotes, bookmarks, code blocks, and two transient types, misspellings and active-search hits. The misspellings and search hits are computed on demand, not prewarmed, so opening the panel does not slow down the editor. The point: Browse Mode is the keyboard version, Quick Nav is the searchable version. Either gets you there.

Liam: A code honesty moment for the Quick Nav panel. The index is built from the browse navigation context, which is cached and only rebuilt when the document text or markup kind changes. The misspellings and search hits are layered on top of that context in the panel's own context builder, _quick_nav_panel_context, which calls list_misspellings and find_matches directly. The browse cache never contains transient nav types, so the perf-critical path stays light, and the panel computes the rest on demand. The transient types are filtered in the index along with the structural ones, so the panel can show a unified count and let you jump to any kind.

Jessica: The Quick Nav panel also has a settings story, the three boolean settings quick_nav_include_headings, quick_nav_include_links, quick_nav_include_lists. Tables, block quotes, bookmarks, and code blocks are always on. The reason is that headings, links, and lists are noisy in long documents, and the others are sparse enough that filtering them out would be more annoying than helpful. The takeaway: Quick Nav is the searchable version of the same index Browse Mode walks. If Browse Mode is a rhythm you build in your hands, Quick Nav is the search box for the moments when you would rather type than press.


Liam: The next layer is the outline and heading organizer, and these are two distinct surfaces. navigate.outline_navigator is bound to Control plus Shift plus O, and it opens a tree navigator over the document's headings. You arrow through, Enter to jump, Escape to close. navigate.heading_organizer is bound to the QUILL key chord Control plus Shift plus Grave comma O, and it opens a different dialog for restructuring the heading tree, including reorder and level changes. We are not going to walk the organizer in depth today, because it is a writing tool more than a navigation tool. The two are listed in the keymap, and the difference is that one is for finding headings, the other is for fixing them. Episode fourteen will revisit the organizer in context.

Jessica: A second outline-related navigation command is the structural one we already covered, Alt+Down and Alt+Up. The granularity is determined by the file's effective markup kind. The list of structural elements in Markdown includes headings, paragraphs, list items, block quotes, code blocks, and tables. Alt+Down walks by structure, and the status message tells you the kind when the jump happens. The two commands pair well: the outline navigator is for seeing the structure, and Alt+Down is for walking it. Use them together when you are editing a long structured document for the first time and want to feel the shape before you start changing words.

Liam: A small architectural note, because it is one of the more interesting design choices in the editor. The browse mode cache is shared between Browse Mode, the Quick Nav panel, and the outline navigator. The three features all consume the same _browse_navigation_context dict, and that dict is rebuilt on text or markup change. The cache is invalidated explicitly by _refresh_browse_navigation_cache_now, which is called from the QUILL key chord bindings when you press Shift plus Escape inside Browse Mode. The reason for that explicit refresh is the cheat sheet. Shift plus Escape inside Browse Mode rebuilds the cache and updates the count, so the cheat sheet shows the live numbers, not the cached ones. We will come back to the cheat sheet in episode nine.


Jessica: We need to say a few words about token and bracket navigation, because they round out the vocabulary. The keymap registers Control plus Shift plus backslash as navigate.match_bracket, which jumps the caret to the matching parenthesis, brace, bracket, or angle bracket. The behavior is standard: the caret is moved to the matching opening or closing pair, or the status says there is no match. Token navigation, navigate.next_token and navigate.previous_token, are registered in the keymap, but the default binding is empty. The implementation calls next_token_position and prev_token_position from quill.core.token_nav, which classify each token as word, punctuation, whitespace, or other. The empty default binding is the same code-versus-keymap honesty: the commands exist, the keymap chooses not to bind them, and the palette is the path until you wire your own.

Liam: Region navigation is the other one that rounds out the family. The keymap binds navigate.next_region to F6 and navigate.previous_region to Shift plus F6. A region, in QUILL's vocabulary, is a chunk of the editor surface outside the text buffer: the document tabs, the status bar, the toolbar, the outline pane when one is open. F6 cycles forward through the regions, Shift plus F6 cycles backward, and the focused region is announced. This is the navigation that makes the rest of the editor surface reachable by keyboard in a screen-reader-friendly way, and it is in the same family as the in-buffer navigation we have been talking about because the model is the same: you get to where the next thing is, instead of reaching for a mouse. The same design law as the structural movement commands, applied one level up.

Jessica: Two final features before we close the vocabulary. First, document summary, which the keymap binds to Alt plus I. It announces a one-sentence summary of the current document. It is not navigation in the strict sense, but it is the fastest way to find out what the document is about, and the "is this the right file" check is a kind of navigation too. Second, the back and forward location ring commands, navigate.back_location and navigate.forward_location. We said earlier these are not bound in the default keymap, and we want to be honest about why. The design call is that the most reliable path through jumps is the bookmark system, the mark ring, and the explicit Go To Line dialog. The location ring is a useful safety net, and the palette path is intentional. If you find yourself reaching for back-location ten times a day, that is the right signal to bind it, and the keymap editor in episode nine is how.


Liam: Putting the vocabulary together, with a mental model that makes it stick. The vocabulary has five layers. Layer one: characters, words, lines, the standard grammar your hands already know. Layer two: structural movement, Alt plus Down and Alt plus Up for paragraphs, blocks, and headings in structured documents. Layer three: remembered places, named bookmarks that persist and the mark ring that does not. Layer four: explicit jumps, Go To Line, Go To Page, Go To Anything, and the back and forward location ring. Layer five: mode-based movement, the QUILL key prefix, Browse Mode, Quick Nav, the outline navigator, and the cheat sheet. The five layers are not in tension. They are five ways to say the same thing, "get me there," and fluency is reaching for the right one. Arrows for "the next character." Alt plus Down for "the next paragraph." Browse Mode for "the next heading I have not looked at." Go To Line for "line two-four-zero, the one the error mentioned." All five are true, and the right one depends on the moment.

Jessica: The fluency plan, the one we genuinely recommend, is the same shape as the verbosity plan from episode seven. Week one, do not bind anything new. Use the defaults. Reach for arrows, reach for Alt plus Down, reach for Control plus G, reach for the mark ring, and reach for Browse Mode once a day. Notice which of those you reach for, and which you avoid. Week two, at the end of the work day, look at the avoidance pattern. The pattern is usually "I never use the mark ring," or "I always use Browse Mode by headings, never by anything else," not "I want everything faster." Tuning is a habit, not a one-time setup, and trying to optimize on day one means optimizing before you have heard the defaults enough to know what you are missing.

Liam: A code-versus-doc honesty moment before homework. First, the help text that some users may have seen in older builds mentions "Ctrl plus Alt plus Q" as a way to enter Browse Mode. That string is in a comment block in the editor mode key summary helper, but the actual binding for Browse Mode is the QUILL key sequence, Control plus Shift plus Grave then N, or the QUILL key twice for sticky. The Ctrl plus Alt plus Q phrasing is leftover from an earlier design and is not wired in the code. The way to actually enter Browse Mode today is the QUILL key, and that is the only way. Second, the browse_mode_sticky setting controls whether the QUILL key then N locks Browse Mode until Escape or whether it expires on the follow-on timeout, but the QUILL key twice always locks. We mention this so you do not get confused if a tutorial uses one of the older conventions.

Jessica: Third, the set_bookmark and go_to_bookmark commands exist in the command registry and are implemented with the Set Bookmark dialog and the Go To Bookmark SingleChoiceDialog, but the keymap does not bind them by default. The list_bookmarks command, which opens the navigator, is bound to Alt plus Shift plus B. The set and jump commands are palette-reachable. If you want a one-key chord for setting and jumping bookmarks, the keymap editor in episode nine is the way. We are calling this out because some users will be surprised that "Set Bookmark" and "Go To Bookmark" do not show up in the default keymap even though they are listed in the command palette. The reason is the same reason list_marks is bound to Alt plus M and not to anything else: the discoverability surface and the daily-use surface are different.


Liam: Homework, and the homework is built around actually feeling the vocabulary. One: open your longest document and traverse it three ways. Once by paragraph using Alt plus Down. Once by heading using Browse Mode, QUILL key then H. Once with two named bookmarks, set at the halfway point and at the end. Feel the difference in effort, and notice which one you instinctively reach for. Two: enter Browse Mode, the QUILL key twice, and stay there for thirty seconds. Press H, then period, then period, then period. Press Escape. The goal is for the rhythm to feel natural. Three: use Go To Line on a specific line number, just to have done it. Type a line and column, jump, undo with the location ring from the palette if you want to come back. Four: the optional stretch. Open the Quick Nav panel, QUILL key then G, type a substring of a heading or a list item or a bookmark name, and jump to it. Notice that the panel agrees with Browse Mode about what is in the document. The agreement is by design, and you are feeling the unified index.

Jessica: The closing thought for episode eight, and the setup for episode nine. Movement is the foundation under the rest of the everyday-editor arc, which runs from this episode through episode fourteen. Episode nine gives the QUILL key its full due, the chord map behind the prefix, the keymap editor, and the design choices that shape which commands are bound and which are reached by palette. The same way episode seven tuned what QUILL says, episode nine tunes what QUILL does when you press two keys. The vocabulary we built today is the consumer of that conversation. Browse Mode, the cheat sheet, the per-command chord bindings, the location ring, the named bookmarks, the mark ring, the Go To Line, the structural movement. They are all vocabulary words. Episode nine is the dictionary.

Liam: This is episode eight of fifty-four. Forty-six to go after this, and the first eight are the foundation. Movement, the verbosity system, the command palette, the main window, your first document, install and launch, welcome. The arc we are on now is the everyday editor, and movement is its first word.

Jessica: I'm Jessica.

Liam: I'm Liam. Get there faster.

Back to all episodes