Setting a default editor in Microsoft Windows
Notepad is the default text editor on Windows since its first release.
Unfortunately, it did not get updated with the rest of the operating systems. Just very recently some minor features, like support for unix line endings 🗄️, were finally added.
There have been different hacks and techniques for replacing the notepad
executable with a more advanced editor, but they always had the disadvantage that they put the system in an "unspecified" state. In the best case, a Windows Update would reset the system to its original state. In the worst case, the different behavior between notepad
and the new text editor might screw something up.
Windows Explorer also has the disadvantage of not being able to associate programs for opening files without extensions, and always asking how to open them. This is especially unfortunate for files like README
and LICENSE
or configuration files used by command line applications.
It might not be the most well-known feature of Windows, but it does actually offer customization points similar to update-alternatives
provided by Debian and other GNU/Linux systems. The disadvantage of those customization points is that there is no GUI setting, is hardly documented, and you need to edit the registry.
The registry key HKEY_CLASSES_ROOT\Unknown\shell
is responsible for files that have no associations. All files that Windows does not know how to open, such as .bashrc
, .gitignore
, .doc
, .docx
, and so on, are categorized as unknown until opened and associated with a program the first time.
The key HKEY_CLASSES_ROOT\txtfile
is for files registered as text files. For example, those ending in .txt
, but other file endings, like .log
and .scp
, are registered as text files too.
As there are so many different file extensions associated with textual files, it can be very practical to have a text editor opening by default every file.
Long story short, this is how it can be accomplished:
$editor = "`"C:\Program Files\Notepad++\notepad++.exe`""
# Register and set editor for unknown files
$key = "Registry::HKEY_CLASSES_ROOT\Unknown\shell"
If (!(Test-Path $key)) {
New-Item "$key" -Force
}
Set-ItemProperty -Path "$key" -name '(Default)' -Value "editor"
$key = "Registry::HKEY_CLASSES_ROOT\Unknown\shell\editor\command"
If (!(Test-Path $key)) {
New-Item "$key" -Force
}
Set-ItemProperty -Path "$key" -name '(Default)' -Value "$editor `"%1`""
# register editor for known textual files
$key = "Registry::HKEY_CLASSES_ROOT\Unknown\shell\Open\command"
If (!(Test-Path $key)) {
New-Item "$key" -Force
}
Set-ItemProperty -Path "$key" -name '(Default)' -Value "$editor `"%1`""
# reset default editor for already configured textual files
$filetypes = @("txtfile", "inifile", "xmlfile")
foreach ($filetype in $filetypes) {
$key = (Join-Path (Join-Path Registry::HKEY_CLASSES_ROOT $filetype) shell\open\command)
If (!(Test-Path $key)) {
New-Item "$key" -Force
}
Set-ItemProperty -Path "$key" -name '(Default)' -Value "$editor `"%1`""
}
It is also possible to add a context menu to explorer.exe
. Notice that both notepad++
and vim
setups already add a menu entry in explorer.exe
, so for those programs, it’s not necessary.
# Apparently "*" gets expanded, and "`*" does not escape..., thus use a different syntax
$key = (get-item Registry::HKEY_CLASSES_ROOT).CreateSubKey("*\shell\Open with text editor\command")
$key.SetValue('', "$editor `"%1`"");
# In case there is a nice icon, add it to the menu too
$key = (get-item Registry::HKEY_CLASSES_ROOT).OpenSubKey("*\shell\Open with text editor", $true)
$key.SetValue('Icon', "$editor");
For those who use Run Command (through ⊞ Win+R) for executing programs, here is how to register editor
as a new command, without creating an editor
executable and placing it somewhere in PATH
. It does not add the command to the cmd
or PowerShell
environments. This is unfortunate since it adds an inconsistency, but also practical in case you use cygwin or WSL.
# Add editor to "run command"
$key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\editor.exe"
If (!(Test-Path $key)) {
New-Item "$key" -Force
}
Set-ItemProperty -Path "$key" -name '(Default)' -Value "$editor"
As an example, I’ve used notepad++
, of course, other editors, and even command line editors like nano
, vim
or emacs
, can be set exactly the same way.
Those settings also apply to every user. This is especially useful when installing or configuring a new system. The normal user and the administrator account will have the same default settings.
Of course, a single user can still define what programs to execute when opening specific files unless that file has no extension. This is the single drawback I experienced since instead of asking, the file will be opened with a program that maybe the user does not want to use. Other than that, everything works as expected.
Some programs might query an environment variable. For example, programs ported from a Unix-like system might query the optional environment variable EDITOR
in order to choose which editor to start instead of the default one (which probably is notepad.exe
).
It is possible to set a machine-wide environment variable, user are then able to override it, in case they prefer to use another default editor
[System.Environment]::SetEnvironmentVariable('EDITOR','C:\Program Files\Notepad++\notepad++.exe', 'Machine')
Note 📝 | What has been presented here should work at least from Windows XP, but you might not be able to use the snippets in PowerShell provided here. |
Do you want to share your opinion? Or is there an error, some parts that are not clear enough?
You can contact me anytime.