Search 

    Search is Kimün's superpower. Every Markdown file in your workspace is indexed, and a small query language lets you slice by content, name, section, path, label, and links.

    The whole grammar fits in one table:

    WantShortLongExample
    Free text(just type)meeting notes
    By note name=name:=tasks
    By section heading@in:@personal
    By path/pt:/journal/2024
    By label (hashtag)#lb:#finance
    Notes linking to X<lk:<projects
    Notes X links to>fwd:>projects
    Exclude anything- prefix-#draft, -@temp

    Space between terms = AND. There is no OR. That's the whole precedence story.

    • TUI: Ctrl+K opens the query search modal; Ctrl+E opens the FIND drawer view. Both take the same queries.
    • CLI:
    kimun search "your search query"

    Free text 

    kimun search     → must contain both "kimun" AND "search"
    task report      → must contain both "task" AND "report"

    Free text looks across note content and filenames at once. Searches are:

    • Case-insensitive: kimun matches Kimün, KIMÜN, kimun
    • Diacritics-ignored: kimun matches Kimün
    • Wildcard-friendly: * matches patterns

    Wildcard patterns 

    kimu*            → anything starting with "kimu" (kimun, kimune, kimurei)
    *meeting*        → "meeting" anywhere (meeting notes, team-meeting)
    *report          → anything ending with "report"

    Operators 

    Each operator has a short form (symbol) and a long form (colon-prefixed). Pick whichever your fingers prefer.

    = or name: — note name 

    =tasks           → notes whose name contains "tasks"
    name:tasks       → same (long form)
    =project         → notes with "project" in the name

    Matches the basename only, not the full path.

    @ or in: — section 

    @personal        → content under a "Personal" heading
    in:personal      → same (long form)
    @meeting         → content under a "Meeting" heading

    Filters by Markdown sections (#, ##, ###, …). The search term must appear within that section. Section names match heading text case-insensitively; a note matches if any of its sections contain the term.

    Wildcards on @ are prefix-only. The section filter is full-text indexed, so * works only at the end of a term (@meet* matches "meeting", "meetup") and matches whole words. Unlike =, <, >, and / — which support * anywhere (*report, ta*sk) — the section filter does not support leading or mid-term *.

    / or pt: — path 

    /docs            → notes under a "docs/" directory
    pt:docs          → same (long form)
    /journal/2024    → notes under "journal/2024/"

    Paths match as prefixes: /docs matches both /docs/readme.md and /docs/guides/tutorial.md.

    <projects        → notes that link to the note "projects"
    lk:projects      → same (long form)
    <projects.md     → same (the .md extension is optional)

    Finds the notes that link to a given note, via [[wikilink]] or Markdown link. Matching rules:

    • By note identity, not substring: <projects matches links to projects, but not to projects-archive
    • Case-insensitive, matched by note name; a bare name matches a note in any folder, so add a path to disambiguate (<work/projects) and use * wildcards freely (<proj*)
    • Only note links count: attachments, images, and external URLs are ignored
    >projects        → notes that the note "projects" links to
    fwd:projects     → same (long form)
    >projects.md     → same (the .md extension is optional)

    The mirror image of <: the notes a given note links to. Same matching rules as backlinks.

    Labels 

    Labels are #name tokens written directly in your note body:

    Reviewed the quarterly numbers today. #finance #q2 #review

    Search them with #<label> (short) or lb:<label> (long):

    #finance             → notes labelled "finance"
    lb:finance           → same (long form)
    -#draft              → exclude notes labelled "draft"
    #finance #q2         → both labels required (AND)
    #finance report =2024 → mixes freely with text and other operators

    An unknown label returns zero results, not an error.

    Label rules 

    • Allowed characters: letters, digits, underscores ([A-Za-z0-9_]+). A hashtag ends at the first character outside that set, so #tag-with-dash yields the label tag.
    • Case-insensitive: stored lowercase; #Finance and #finance are the same label.
    • Not indexed as labels: hashtags inside inline code or fenced code blocks, YAML/TOML frontmatter, HTML, Markdown link spans [text](url#fragment), or wikilinks [[#section]].

    Excluding things 

    The - prefix excludes. It always leads; any operator follows:

    -cancelled           → exclude notes containing "cancelled"
    -@draft              → exclude notes with "draft" in any section title
    -=temp               → exclude notes with "temp" in the name
    -/private            → exclude notes under "private/"
    -#draft              → exclude notes labelled "draft"
    -<draft              → exclude notes that link to "draft"
    ->draft              → exclude notes that "draft" links to

    Long forms work the same: -in:draft, -name:temp, -pt:private, -lb:draft, -lk:draft, -fwd:draft.

    Exclusion-only searches are fine too — -cancelled alone returns every note except those containing "cancelled".

    Combining filters 

    Everything composes. Space = AND, each term must match:

    =tasks @work report                → name "tasks", has "Work" section, contains "report"
    meeting -cancelled                 → "meeting" but not "cancelled"
    =2024 -@draft                      → names from 2024 without "draft" in section titles
    /journal -@temp report             → in journal/, no "temp" section, containing "report"
    screen* =notes                     → starts with "screen", in name "notes"
    #project -#archived @work          → labelled "project", not "archived", under "Work"

    Query variables 

    Some queries contain a {name} placeholder that the TUI fills in at run time, before the query reaches the search engine. The first (and currently only) variable is {note}:

    • {note} resolves to the clean name of the note open in the editor (its filename without the extension).
    • A bare note operator — <, > or = with no target, including the long forms lk: / fwd: / name: and the - exclusion variants — is shorthand for <{note}, >{note} or ={note}: the backlinks of the current note, its forward links, or the note itself by name. Operators inside quoted terms are not expanded.

    With spec.md open, <{note} runs as <spec (the notes that link to spec). When no note is open, {note} resolves to an empty string.

    Variables are resolved wherever the query runs — both the FIND drawer view and the Ctrl+K search modal substitute {note} against the open note. Because saved searches store the template (the unresolved {note}), a saved <{note} re-targets to whatever note is open each time you run it.

    Saved searches 

    A saved search stores a query under a name so you can re-run it without retyping — common filters, project views, or backlink queries. Saved searches live with the workspace and are managed from the TUI:

    • Save the current query with Ctrl+D — from the FIND view or the Ctrl+K search modal — then give it a name.
    • Open the Saved Searches picker with F3 to run a saved search (Enter), quick-select with 19, or remove one with Delete.

    Running a saved search loads its results in the FIND view. See Saved Searches in the TUI guide for the full workflow.

    Running by name 

    You can also run a saved search straight from the search field, without the picker. In the FIND view or the Ctrl+K search modal, type ? as the first character to autocomplete saved-search names:

    • Type ? followed by part of a name (e.g. ?todo) to filter the list; pick one with Enter or Tab. An empty ? lists every saved search.
    • Accepting expands the stored query into the field, so you can tweak it before running like any other query.
    • The search-box border then shows the search's name as a breadcrumb (‹ todo ›). Edit the query and it gains an ‹ todo • edited › marker; clear the field to drop the breadcrumb. Changing only the sort order does not count as edited.

    Because the field holds the query template, any {note} variable stays intact and re-resolves each time you run it.

    Example queries 

    Given these notes:

    tasks.md

    # Work
    ## TODO
    * Talk with Bill
    * Finish the report
    
    # Personal
    * Make the search in Kimün awesome
    * Buy groceries

    projects.md

    # Projects
    ## Personal
    ### Kimün
    The simple but great note taking app!
    SearchReturnsReason
    kimunprojects.md, tasks.mdboth contain "kimun"
    @personal kimunprojects.md, tasks.md"kimun" under a Personal heading in both
    @personal reporttasks.md"report" only under Personal in tasks.md
    =tasks @worktasks.mdname "tasks", has Work section
    screen*any note with "screenshot", "screens", etc.wildcard matches "screen" prefix
    meeting -cancellednotes with "meeting" but not "cancelled"exclusion removes matching notes
    =2024 -@draftnames from 2024 without "draft" in section titlescombined exclusion
    -cancelledall notes except those with "cancelled"exclusion-only search
    /journal -@tempnotes in journal/ without "temp" in section titlespath + section exclusion
    =tasks @work reporttasks.mdname "tasks", "Work" section, contains "report"
    -=archive -@draftall notes except those named archive/, excluding "draft" titlescombined exclusions
    #financenotes labelled "finance"label filter
    lb:reviewnotes labelled "review"label filter (long form)
    #finance #q2notes with both "finance" and "q2" labelscombined label filters
    #project -#draftnotes labelled "project" but not "draft"label inclusion + exclusion
    <kimunnotes that link to the note "kimun"backlink filter
    lk:kimun #projectnotes linking to "kimun" and labelled "project"backlink + label
    <spec -<draftnotes linking to "spec" but not to "draft"backlink inclusion + exclusion
    >kimunnotes that the note "kimun" links toforward link filter
    fwd:spec #projectnotes that "spec" links to and labelled "project"forward link + label

    Edge cases 

    • Wildcards with operators: =task* @work matches notes named starting with "task" that have a "Work" section
    • Operator prefixes are case-insensitive: @Personal@personal, =Tasks=tasks
    • Multiple operators of the same type: @work @personal is AND — both sections must exist
    • Empty results: if nothing matches, you get an empty list, never an error
    • Unknown labels: #nonexistent returns zero results, not an error
    • Hashtags in code: `#tag` and hashtags inside fenced code blocks are not treated as labels