mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-14 21:09:05 +08:00
347 lines
15 KiB
Markdown
347 lines
15 KiB
Markdown
# File-path handling in Notepad3
|
|
|
|
Everywhere Notepad3 turns a piece of text into a *file* — a clickable link in
|
|
the editor, a path you typed into a dialog, a reference you selected from a
|
|
build log — it goes through the same few rules. This page collects them in
|
|
one place.
|
|
|
|
> Related references
|
|
> - **Menu entries** for the commands below: [`../MenuEntriesAndCmds.md`](../MenuEntriesAndCmds.md).
|
|
> - **INI keys** that influence path handling: [`../config/Configuration.md`](../config/Configuration.md).
|
|
> - **Command-line switches** for opening files: [`../cmdln/CmdLnOptions.md`](../cmdln/CmdLnOptions.md).
|
|
> - **MiniPath** (the bundled file browser): [`../minipath/`](../minipath/).
|
|
|
|
## Quick reference
|
|
|
|
| Want to … | Do this |
|
|
|---|---|
|
|
| Open a `http://…` or `https://…` URL from the document | Ctrl+Click the highlighted link → opens in your default browser. |
|
|
| Open a `file:///…` URL in Notepad3 | Alt+Click the highlighted link → loads the target into the editor. |
|
|
| Open a bare path like `C:\foo\bar.c:42` in Notepad3 | Alt+Click — bare paths are highlighted only when they end in `:42`, `:42:7`, or `(42)`. |
|
|
| Reveal the file under the caret in Explorer | Place the caret on the path and choose **Edit → Miscellaneous → Open Containing Folder of Selection** (also under **File → Launch**, or right-click). |
|
|
| Open a file referenced by selection / token at caret in **current window** | **Ctrl+N** (*Smart New*) — or **Edit → Miscellaneous → Open File from Selection** (also under **File → Launch**, or right-click). |
|
|
| Open a file referenced by selection / token at caret in a **new window** | **Alt+N** (*Smart New Window*) — spawns a new Notepad3 instance with the file loaded. |
|
|
| Reveal the *current* document in Explorer | **File → Open File Explorer**. |
|
|
| Copy the current path | **File → Path to Clipboard → Copy Filename / Directory / Full-Path**. |
|
|
|
|
---
|
|
|
|
## 1. Clickable hyperlinks in your document
|
|
|
|
When **View → Hyperlink Hotspots** is enabled (default), Notepad3 detects
|
|
links and paths in your text and marks them with an underline. Click
|
|
modifiers control what happens:
|
|
|
|
| Gesture | Action |
|
|
|---|---|
|
|
| **Ctrl+Click** | Open in the associated external app (browser for URLs, default opener for files). |
|
|
| **Ctrl+Shift+Click** | Open in the associated app *in the background* (Notepad3 stays in front). |
|
|
| **Alt+Click** | Open in Notepad3 itself — works for `file:///…` URLs and bare file paths. |
|
|
| **Alt+Shift+Click** | Open in a *new* Notepad3 instance. |
|
|
| **Middle-mouse click** | Same as Ctrl+Click. |
|
|
| **Right-click on a hotspot** | Context menu with explicit "Open Hyperlink" / "Copy Hyperlink URL" entries. |
|
|
| **Hover** (with `ShowHypLnkToolTip`) | Tooltip showing the link target. |
|
|
|
|
### URL forms Notepad3 recognises
|
|
|
|
Detected as a clickable URL with a scheme:
|
|
|
|
| Form | Example |
|
|
|---|---|
|
|
| HTTP(S) | `https://example.com/foo` |
|
|
| FTP | `ftp://example.com/foo` |
|
|
| `www.…` (no scheme) | `www.example.com` |
|
|
| `ftp.…` (no scheme) | `ftp.example.com` |
|
|
| `mailto:` | `mailto:nobody@example.com` |
|
|
| `file://` | `file://server/share/file.txt` |
|
|
| `file:///` | `file:///D:/projects/foo/readme.md` |
|
|
|
|
The matcher is a single PCRE2 regular expression — it stops at common
|
|
sentence punctuation (`. , ! ? :`) so a URL followed by punctuation in prose
|
|
doesn't absorb the period.
|
|
|
|
### File URLs (`file://` and `file:///`)
|
|
|
|
After the scheme is stripped, the rest is treated as a filesystem path.
|
|
**Relative `file:///` URLs** are resolved against:
|
|
|
|
1. The directory of the *current document*, if it has been saved.
|
|
2. Otherwise, the working directory (the directory Notepad3 was launched
|
|
from, or set via `/y` on the command line).
|
|
|
|
It is *never* resolved against Notepad3's install directory — that was a bug
|
|
in older versions and is now fixed.
|
|
|
|
A trailing `#fragment` (e.g. `file:///foo.md#section-2`) is **stripped before
|
|
the file is opened**. Notepad3 doesn't resolve Markdown anchor names; the
|
|
file is opened cleanly without trying to interpret `#section-2`.
|
|
|
|
### Bare file paths (with mandatory line spec)
|
|
|
|
Plain filesystem paths are clickable **when they're followed by a line-number
|
|
indicator** — that's a strong signal the text is a build-error reference,
|
|
log entry, or stack-trace line rather than prose. Three prefix shapes are
|
|
recognised:
|
|
|
|
| Form | Example |
|
|
|---|---|
|
|
| Drive letter + separator | `C:\foo\bar.c:42` · `c:/foo/bar.c(42)` |
|
|
| UNC | `\\server\share\foo\bar.c:42` |
|
|
| Relative | `.\src\Helpers.c:42` · `../include/foo.h:42:7` |
|
|
|
|
A bare path without a line spec — for example `C:\Windows` typed in prose —
|
|
is **not** highlighted. That's intentional, to keep false positives down.
|
|
If you need to act on such a path, select it and use **Open Containing
|
|
Folder of Selection** or **Open File from Selection** (see §2).
|
|
|
|
### Line / column suffix patterns
|
|
|
|
Notepad3 recognises four trailing patterns and jumps to the parsed line
|
|
when opening:
|
|
|
|
| Pattern | Example | Meaning |
|
|
|---|---|---|
|
|
| `:N` | `Helpers.c:42` | Line 42 |
|
|
| `:N:M` | `Helpers.c:42:7` | Line 42, column 7 (column currently ignored) |
|
|
| `(N)` | `Helpers.c(42)` | Line 42 |
|
|
| `,N` | `Helpers.c,42` | Line 42 |
|
|
|
|
The parser is digit-only — `Helpers.c:42+1` is **not** interpreted as
|
|
"line 43"; it's treated as a non-match and the path is opened without a
|
|
jump.
|
|
|
|
A colon that follows a drive letter (`C:`) is never treated as a line
|
|
separator.
|
|
|
|
---
|
|
|
|
## 2. Selection-based commands
|
|
|
|
For paths that *aren't* highlighted as hotspots — or when you just want to
|
|
act on the path under the caret without targeting an indicator precisely —
|
|
use the two **Edit → Miscellaneous** entries (also in the editor right-click
|
|
menu when there's a selection or a token at the click point):
|
|
|
|
### Open Containing Folder of Selection
|
|
|
|
Resolves the selected text (or token at caret) to a filesystem path and
|
|
opens Windows Explorer with that file highlighted. If the target is a
|
|
folder, opens the folder itself.
|
|
|
|
### Open File from Selection
|
|
|
|
Resolves the same way, then loads the file into Notepad3 (jumps to the
|
|
parsed line if a line spec was present). If the target is a folder, opens
|
|
the file-open dialog rooted in it.
|
|
|
|
### How the token is extracted
|
|
|
|
If there's a non-empty selection:
|
|
- Use the selected text.
|
|
- Truncate at the first newline or tab character.
|
|
|
|
If the selection is empty:
|
|
- Expand from the caret outward on the same line.
|
|
- Stop at any of: whitespace, single quote, backtick, double quote, `<`,
|
|
`>`, `|`, `*`, `,`, `;`.
|
|
- **Markdown link special-case**: if the caret sits inside `(…)` parens
|
|
immediately preceded by `]`, the inner contents of the parens are used
|
|
instead — so caret inside the URL of `[label](D:\projects\foo\readme.md)`
|
|
picks up `D:\projects\foo\readme.md`, not the surrounding text.
|
|
|
|
Surrounding whitespace, `"`, `'`, `` ` ``, `<`, `>` are stripped from the
|
|
result.
|
|
|
|
Any trailing line/column suffix (`:N`, `:N:M`, `(N)`, `,N`) is split off
|
|
before path resolution. For *Open File from Selection*, the parsed line
|
|
number controls the caret jump after the file loads.
|
|
|
|
### Menu state and *Smart* shortcuts
|
|
|
|
Both commands are greyed out when there's no selection *and* no word at the
|
|
caret / click position.
|
|
|
|
The commands themselves have no dedicated accelerator, but the same path
|
|
detection is layered onto the standard "new" shortcuts — turning them into
|
|
**Smart New** and **Smart New Window**:
|
|
|
|
- **Ctrl+N** — *Smart New* (`IDM_FILE_NEW`). When a file is detected,
|
|
behaves as *Open File from Selection* in the current window (jumps to
|
|
the parsed line spec); when a directory is detected, opens the file-open
|
|
dialog rooted there; otherwise it falls back to its classic "clear
|
|
current buffer" behavior — so you only ever need one key to either
|
|
start fresh **or** jump to the file your eye is already on.
|
|
- **Alt+N** — *Smart New Window* (`IDM_FILE_NEWWINDOW`). When a file is
|
|
detected, spawns a new Notepad3 instance with that file loaded; when a
|
|
directory is detected, the new instance opens its file-open dialog
|
|
there; otherwise it falls back to spawning an empty new window.
|
|
|
|
Both shortcuts always ignore `Flags.bReuseWindow`: Ctrl+N is by definition
|
|
a current-window operation, Alt+N a new-window one.
|
|
|
|
---
|
|
|
|
## 3. Path resolution rules
|
|
|
|
The same rules apply to file-URL clicks, bare-path clicks, and both
|
|
selection-based commands.
|
|
|
|
### Anchor priority for relative paths
|
|
|
|
A *relative* path (one without a drive letter, UNC `\\`, or leading slash)
|
|
is resolved against:
|
|
|
|
1. The directory of the **current document** (`Paths.CurrentFile`), if it
|
|
has been saved.
|
|
2. Otherwise, the **working directory** (`Paths.WorkingDirectory`).
|
|
|
|
Notepad3's *install directory* (`Paths.ModuleDirectory`) is **never** used
|
|
as an anchor for in-document references.
|
|
|
|
### Environment-variable expansion
|
|
|
|
Tokens containing `%VAR%` are expanded against the current process
|
|
environment before resolution. So `%WINDIR%\notepad.exe` and
|
|
`%USERPROFILE%\Documents\foo.txt` resolve correctly.
|
|
|
|
### `file://` → Windows path conversion
|
|
|
|
`file://`-prefixed URLs go through the Windows shell's `PathCreateFromUrlW`
|
|
to convert URL-encoded characters (`%20` → space, etc.) into a real
|
|
filesystem path. If `PathCreateFromUrlW` fails on a malformed URL, the
|
|
prefix is stripped manually and the resolver tries the rest as a best
|
|
effort.
|
|
|
|
### Long paths (`\\?\` prefix)
|
|
|
|
When **Open Containing Folder of Selection** hands a path to the Windows
|
|
shell, the long-path prefix `\\?\` is stripped first so Explorer can accept
|
|
the path:
|
|
|
|
- `\\?\C:\Windows` → `C:\Windows`
|
|
- `\\?\UNC\server\share\file.txt` → `\\server\share\file.txt`
|
|
|
|
Internally Notepad3 uses long-path-aware Win32 wrappers throughout. If
|
|
Windows' long-path support (`LongPathsEnabled` group policy) is off and a
|
|
path is ≥ 260 characters, Notepad3 applies the `\\?\` prefix transparently
|
|
where necessary.
|
|
|
|
---
|
|
|
|
## 4. Path-related menu commands
|
|
|
|
### File menu
|
|
|
|
| Command | What it does |
|
|
|---|---|
|
|
| **Open…** (Ctrl+O) | Standard file-open dialog. |
|
|
| **Open with…** (Alt+L) | Hand the current file to an external editor — choose via `OpenWithDir` setting. |
|
|
| **Recent Files** (sub-menu) | Most-recently-used list. Paths are stored relative to Notepad3.exe by default — flip via the `Notepad3.ini` redirect mechanism. |
|
|
| **Save** / **Save As…** / **Save Copy…** | Standard write paths; respects `AtomicFileSave` (see §5). |
|
|
| **Launch → Open Containing Folder of Selection** | Same command as in the Edit menu / right-click — exposed here for discoverability alongside the other "open something external" actions. |
|
|
| **Launch → Open File from Selection** | Same command as in the Edit menu / right-click. |
|
|
| **Launch → Open File Explorer** | Reveal the **current document** in Windows Explorer (or, if untitled, the working directory). Distinct from **Open Containing Folder of Selection**, which operates on text *inside* the document. |
|
|
| **Path to Clipboard → Copy Filename only / Copy Directory-Path only / Copy Full-Path** | Self-explanatory; for filling into other tools. |
|
|
| **Add to Favorites** / **Favorites…** | Pin a path to a quick-pick list, stored under `FavoritesDir`. |
|
|
| **Launch Default Application** (Ctrl+L) | ShellExecute the current document with its registered "open" verb. |
|
|
| **Run…** | ShellExecute an arbitrary command line, prefilled with the document's full path. |
|
|
|
|
### Edit menu
|
|
|
|
| Command | What it does |
|
|
|---|---|
|
|
| **Edit → Miscellaneous → Open Containing Folder of Selection** | See §2. |
|
|
| **Edit → Miscellaneous → Open File from Selection** | See §2. |
|
|
| **Edit → Insert → Filename / Directory / Path** | Insert the current document's name / parent dir / full path into the buffer at the caret. |
|
|
|
|
---
|
|
|
|
## 5. Background behavior
|
|
|
|
These mechanisms aren't user-triggered but are worth knowing about because
|
|
they affect what you'll see on disk.
|
|
|
|
### File watching
|
|
|
|
Notepad3 asks Windows to notify it of changes in the **parent directory**
|
|
of the open file. When the current file changes externally, the **File
|
|
Change Notification** dialog offers to reload (or you can configure silent
|
|
reload). The watch is released before *Save* and re-armed afterwards so
|
|
Notepad3 doesn't observe its own writes.
|
|
|
|
### Atomic save
|
|
|
|
With `AtomicFileSave=true` (the default), *Save* writes to a temporary file
|
|
alongside the target and then atomically replaces the original via
|
|
`ReplaceFileW`. ACLs, alternate data streams, and attributes are preserved
|
|
on failure — nothing is lost if the write is interrupted. See
|
|
[`../config/Configuration.md#atomicfilesave-true`](../config/Configuration.md#atomicfilesavetrue)
|
|
to disable on very large files where in-place writing is faster.
|
|
|
|
### MRU (Most-Recently-Used) list
|
|
|
|
The Recent Files list in the File menu is persisted in `Notepad3.ini` under
|
|
`[Recent Files]`. Disable persistence with the `NoSaveRecent` setting.
|
|
Entries can be removed individually from the MRU dialog.
|
|
|
|
### Portable & redirected INI
|
|
|
|
By default `Notepad3.ini` lives next to `Notepad3.exe` (portable mode). The
|
|
file `Notepad3.ini` itself can specify a `Notepad3.ini=<path>` redirect
|
|
under `[Notepad3]` (up to two levels) that points at a per-user location —
|
|
useful for shared installs. The redirected file is auto-created on first
|
|
write.
|
|
|
|
---
|
|
|
|
## 6. Configuration keys that affect path handling
|
|
|
|
All in `Notepad3.ini` under `[Settings2]` unless noted — see
|
|
[`../config/Configuration.md`](../config/Configuration.md) for full
|
|
descriptions.
|
|
|
|
| Key | Effect |
|
|
|---|---|
|
|
| `AtomicFileSave` | Two-phase Save (temp file + ReplaceFileW). |
|
|
| `ResolveUNCPaths` | When opening a UNC path that's actually a mapped drive's share, prefer the drive-letter form for display. |
|
|
| `DefaultDirectory` | Initial directory of the **Open…** dialog. |
|
|
| `OpenWithDir` | Directory used by **Open with…**. |
|
|
| `FavoritesDir` | Where the Favorites list lives. |
|
|
| `GrepWinPath` | Override the grepWin executable lookup. |
|
|
| `HyperlinkShellExURLWithApp` | Open URLs with a specific external app instead of the OS default. |
|
|
| `HyperlinkShellExURLCmdLnArgs` | Argument template for the above. |
|
|
| `HyperlinkFileProtocolVerb` | Override the verb used to ShellExecute `file:` URLs. |
|
|
| `ShowHypLnkToolTip` | Hover tooltip showing the link target. |
|
|
| `MonitoringLog` | `FileWatching.MonitoringLog`; tails the file by default. |
|
|
|
|
---
|
|
|
|
## 7. Troubleshooting
|
|
|
|
**Q. My path has spaces and the resolver only picked up part of it.**
|
|
Wrap it in double quotes or single quotes in the source text, or select the
|
|
full path manually before invoking the command.
|
|
|
|
**Q. `..\..\foo.c:42` opened the wrong file.**
|
|
Save your document first — relative paths anchor to the document's
|
|
directory only after it has been saved. Until then, they anchor to the
|
|
working directory.
|
|
|
|
**Q. A path is highlighted but Alt+Click does nothing.**
|
|
Notepad3 silently does nothing when the resolved path doesn't exist on
|
|
disk. Check the path with **Open Containing Folder of Selection** — it will
|
|
beep if the resolution fails.
|
|
|
|
**Q. `C:\Windows` isn't highlighted as a hotspot.**
|
|
By design — bare paths are only hotspotted when they end in a line spec
|
|
(`:42`, `:42:7`, or `(42)`). For paths without a line number, use the
|
|
selection-based commands instead.
|
|
|
|
**Q. The line jump for `foo.c:42:7` ignores `7`.**
|
|
The column is parsed and accepted but not currently acted on — only the
|
|
line is set. Tracked for a future enhancement.
|
|
|
|
**Q. `file:///D:/docs/readme.md#section-2` doesn't jump to the anchor.**
|
|
Heading-anchor resolution is a Markdown-specific convention and isn't
|
|
implemented — the fragment is stripped and the file opens at the top.
|