<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><![CDATA[Einar's blog - windows]]></title>
<description><![CDATA[Einar's blog - windows]]></description>
<link>https://einar.codeberg.page//tag-windows.html</link>
<lastBuildDate>Thu, 07 May 2026 23:39:02 +0200</lastBuildDate>
<item>
  <title><![CDATA[Fix Emacs python-mode REPL and org code block with python evaluation problems]]></title>
  <description><![CDATA[
<p>
For a while now, the python shell in Python mode in Emacs has not worked properly on my work laptop. I get some strange glyphs in the top of the python shell buffer when opening it from a file with C-c C-p and when I tried importing a file with C-c C-c, I would get an error saying stringp was nil and every character in what I tried to import was written first once, then together with the next, then the next three and so on. It looked somewhat psychedelic and was more or less unusable.
</p>

<p>
I also had trouble evaluating python code blocks in org mode which has been annoying when presenting with <a href="https://codeberg.org/einar/inter-present-mode">inter-present-mode</a> for my students or exporting from org files I used for presentations to PDF or docx to upload to our school's learning platform (it's learning). In org, I would get the same error saying stringp was nil when evaluating code blocks that I would get when trying to import files to the REPL in python mode.
</p>

<p>
I first thought the problem was related to my <a href="https://codeberg.org/einar/.dotfiles/src/branch/main/.emacs.d/config.org#headline-32">einar-python-virtualenv function</a> which locally changes the python-shell-interpreter for a file if it is in a project with a virtual environment since I made that quite recently, but the strange thing was that it worked perfectly on GNU Guix on my main machine at home. I then thought maybe it was a Windows 11 problem since I only experienced it at work, so I tried on a Raspberry Pi 4 at work with the latest Raspberry Pi OS and I had the same problem.
</p>

<p>
I then tried launching Emacs with -q to see if the problem was related to my config or not. When I then launched the python shell from a file with C-c C-p, the REPL itself worked slightly better, but I still got some strange glyphs at the top. I then spent some time trying to figure out where in my config the problem appeared and removed first the einar-python-virtualenv and then my configuration for python-mode, but the problem persisted. I also looked into whether some setting for comint-mode might cause the problem.
</p>

<p>
After spending one and a half hour trying to troubleshoot this on Monday, I today realised I updated Python to 3.14 on my work Windows 11 laptop a while ago. I checked the python version on the Raspberry Pi and it was 3.13. I checked packages.guix.gnu.org and Guix uses version 3.11. I thought maybe something changed in one of the newer versions. I had a look at news for version 3.14 and did not find anything promising. I then checked out what was new in 3.13 and one of the first things was a new and improved python shell.
</p>

<p>
Luckily, you can get the old shell that python mode in Emacs works with by setting the environment variable PYTHON_BASIC_REPL to something. When I added this function call to <a href="https://codeberg.org/einar/.dotfiles/src/branch/main/.emacs.d/config.org#headline-85">my Emacs config for python mode</a>, the python REPL works in python mode again and it is possible to evaluate org code blocks and export files that will evaluate them on export again:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(setenv <span style="color: #79a8ff;">"PYTHON_BASIC_REPL"</span> <span style="color: #79a8ff;">"1"</span>)
</pre>
</div>

<p>
I write this so others experiencing the same problem can find a solution. In the long term, python-mode, python-ts-mode and org mode needs to work with the new and improved python shell since the old shell will probably be removed at some point in the future, but for now, just setting the environment variable is enough to get both the REPL and org code blocks working again.
</p>
<div class="taglist"><a href="https://einar.codeberg.page/tags.html">Tags</a>: <a href="https://einar.codeberg.page/tag-emacs.html">emacs</a> <a href="https://einar.codeberg.page/tag-computers.html">computers</a> <a href="https://einar.codeberg.page/tag-windows.html">windows</a> <a href="https://einar.codeberg.page/tag-gnulinux.html">gnulinux</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[computers]]></category>
  <category><![CDATA[windows]]></category>
  <category><![CDATA[gnulinux]]></category>
  <link>https://einar.codeberg.page/fix-python-mode-repl-problem.html</link>
  <guid>https://einar.codeberg.page/fix-python-mode-repl-problem.html</guid>
  <pubDate>Tue, 28 Apr 2026 20:55:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Rethink about the prefix for my Emacs keymap]]></title>
  <description><![CDATA[
<p>
I wrote a blog post about binding &lt;menu&gt; as the prefix key to my own Emacs keymap and swapping CapsLock for Menu on GNU/Linux and its closest equivalent, &lt;apps&gt; on Windows. (I have deleted that blog post since I realised doing that was dumb, and I don't want to steer others down that path.) It worked as long as I used Emacs in its GUI on Windows 11 or Wayland. However, when I installed Guix on my laptop and was trying to figure out how to get Sway running on Guix, I naturally used Emacs in the TTY where it works just as well as in a graphical session except some limitations around showing pictures, using multiple faces and keybindings. TTYs and graphical terminals doesn't send through every key to Emacs and one of the many newer keys they don't send to Emacs is &lt;menu&gt;. So I was left with none of my own keybindings. It made me realise that using any special key not usable in a TTY for my own keymap is not very smart.
</p>

<p>
There is always M-x, so I could do everything I wanted to do, but without using my own keymap. The advantage of having a keymap that works everywhere is that it makes using commonly used functions a lot faster than using M-x. If the keymap isn't available everywhere, the advantage of having a keymap at all is severely limited and you have to think about in which situations it is usable and in which it isn't. Training oneself to remember the keychords through muscle memory also make little sense if it is only available some of the time.
</p>

<p>
I had a quick think about which possible prefix keys I could use that would work everywhere and in theory, every combo with ctrl or meta is usable except a few that has special meaning in a terminal like C-i and C-m. However, it is important not to remove a keychord I already use a lot for its original functionality to use it as the prefix for my own keymap instead, and I don't want a situation where a keychord both has its own functionality that I sometimes use and also is the prefix key for my keymap. That would be confusing and annoying to work with. I don't use C-z to iconify GUI Emacs or stop TTY Emacs, so I thought it was a keychord I could unbind and then use as my prefix.
</p>

<p>
Below is the code from my Emacs config for my keymap. It has just a few functions I use often that doesn't have a keybinding by default and a few of my own functions. Using it makes me faster than using M-x.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(global-unset-key (kbd <span style="color: #79a8ff;">"C-z"</span>))
(define-prefix-command 'emo-map)
(global-set-key (kbd <span style="color: #79a8ff;">"C-z"</span>) 'emo-map)
(define-key emo-map (kbd <span style="color: #79a8ff;">"a"</span>) 'tempo-complete-tag)
(define-key emo-map (kbd <span style="color: #79a8ff;">"b"</span>) 'tempo-backward-mark)
(define-key emo-map (kbd <span style="color: #79a8ff;">"c"</span>) 'org-insert-structure-template)
(define-key emo-map (kbd <span style="color: #79a8ff;">"d"</span>) 'org-display-inline-images)
(define-key emo-map (kbd <span style="color: #79a8ff;">"e"</span>) 'elfeed)
(define-key emo-map (kbd <span style="color: #79a8ff;">"C-e"</span>) 'eshell)
(define-key emo-map (kbd <span style="color: #79a8ff;">"f"</span>) 'tempo-forward-mark)
(define-key emo-map (kbd <span style="color: #79a8ff;">"h"</span>) 'emo-hjemmeside)
(define-key emo-map (kbd <span style="color: #79a8ff;">"i"</span>) 'emo-ispell-toggle)
(define-key emo-map (kbd <span style="color: #79a8ff;">"l"</span>) 'org-toggle-link-display)
(define-key emo-map (kbd <span style="color: #79a8ff;">"m"</span>) 'mu4e)
(define-key emo-map (kbd <span style="color: #79a8ff;">"o"</span>) 'emo-dired-convert-to-org)
(define-key emo-map (kbd <span style="color: #79a8ff;">"C-s"</span>) '(lambda () (<span style="color: #b6a0ff;">interactive</span>) (emo-present 'toggle)))
(define-key emo-map (kbd <span style="color: #79a8ff;">"s"</span>) 'shell)
(define-key emo-map (kbd <span style="color: #79a8ff;">"t"</span>) '(lambda () (<span style="color: #b6a0ff;">interactive</span>) (ansi-term <span style="color: #79a8ff;">"bash"</span>)))
(define-key emo-map (kbd <span style="color: #79a8ff;">"y"</span>) 'emo-systemcrafters)
</pre>
</div>
<div class="taglist"><a href="https://einar.codeberg.page/tags.html">Tags</a>: <a href="https://einar.codeberg.page/tag-emacs.html">emacs</a> <a href="https://einar.codeberg.page/tag-computers.html">computers</a> <a href="https://einar.codeberg.page/tag-gnulinux.html">gnulinux</a> <a href="https://einar.codeberg.page/tag-windows.html">windows</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[computers]]></category>
  <category><![CDATA[gnulinux]]></category>
  <category><![CDATA[windows]]></category>
  <link>https://einar.codeberg.page/rethink-about-the-prefix-for-my-emacs-keymap.html</link>
  <guid>https://einar.codeberg.page/rethink-about-the-prefix-for-my-emacs-keymap.html</guid>
  <pubDate>Fri, 03 Oct 2025 23:46:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Emacs on Windows]]></title>
  <description><![CDATA[
<p>
<b>Updated: March 11th, 2026</b>
</p>

<p>
I use Emacs as my text editor. At work, I have a laptop with Windows 11. I use <a href="https://codeberg.org/einar/inter-present-mode">inter-present-mode</a> for interactive presentations every day. Since I sometimes have pictures in my presentations and inter-present-mode changes face height, I need to use GUI Emacs. (Emacs is also available in the TTY and terminal emulators.) There are two ways to get GUI Emacs on Windows. The first is through WSL2 with the graphical features Microsoft calls WSLg.
</p>

<p>
Unfortunately, the Wayland stack is implemented in a non-standard way in WSLg that doesn't currently work properly. Previously, there were two bugs related to Wayland-native programs: <a href="https://github.com/microsoft/WSL/issues/11261">the first bug</a> makes Wayland native programs use XWayland instead of Wayland. The community found a fix for that bug in 2023 and told Microsoft about it in a GitHub Issues thread where a representative for Microsoft said they applied the fix to the codebase, but did not ship the fix for many years. There was another bug that made Wayland windows unresponsive after locking the screen and unlocking it again. (There were also a similar bug for X windows where the windows disappear after screen locking, but if you open a new X window, you can alt-tab to the original window and use it.)
</p>

<p>
Microsoft fixed those two bugs with a release of Windows 11 recently, but when I tried Emacs with WSLg in March 2026 again, I found two other bugs. The first was the every time I launched Emacs, the first time, it would become unresponsive and I had to kill it. The second time, the window would respond normally. Having to launch a program twice is really annoying. The other bug was that Windows 11 window snapping did not work predictably with my Emacs window. As a user of a tiling window manager, I find snapping to be an annoyingly slow workaround made by people who think pressing keys or mousing around is the same as things happening automatically, which they are not, but not having snapping means manually having to resize the window to fit different screens (and I work with 5 different screen setups with my work laptop regularly) which is just unforgivably impractical and slow. Even if snapping is not tiling, it is better than nothing. The combination of these two bugs meant using WSLg Emacs was unpredictable, slow and annoying, even compared to the somewhat slower Windows-native Emacs which nonetheless works predictably and like a normal window.
</p>

<p>
This was the fifth or sixth time I have hoped WSLg actually worked since Microsoft released it. Microsoft is one of the richest tech companies, but is unable to ship working software three years after they started marketing the feature. I don't think I will try WSLg ever again. I have wasted enough time, energy and hope. So, if you need GUI Emacs, don't waste your time with WSLg. If you can use Emacs in a graphical terminal and don't need the Wayland GUI, then WSL2 with its superior package managers and all the packages that just work out of the box with Emacs on GNU/Linux is better.
</p>

<p>
Since I need GUI Emacs and WSLg doesn't properly work, I have opted to use native Emacs on Windows. Unfortunately, all the free software tools that integrate with Emacs and that is just an easy install away on GNU/Linux (and its WSL2 lookalike) is hard to come by as native Windows programs. There are also some extra configuration needed in Emacs to get features that just work on POSIX to work on Windows. I gradually discovered how to get the necessary external packages and how to configure Emacs on Windows to get as similar an experience as possible to the one I have on GNU/Linux. I use <a href="https://codeberg.org/einar/emacs_config">the same literate configuration</a> on both OSes to keep things as similar as possible.
</p>

<p>
People use Emacs in different ways, so you may find that you need something I don't, but I hope this blog post can give you a starting point. (It is also useful for me in case I need to set things up again.) Some other good starting points are <a href="https://ludicmanager.org/productivity/emacs-windows/">Using Emacs on Windows 11: An Installation Guide</a> by Dr. Peter Prevos and <a href="https://emeacselements/notes-videos/installing-emacs-windows.html">Properly Installing Emacs on Windows</a>, <a href="https://emeacselements/notes-videos/setup-emacsclient-on-windows.html">Properly Setting up Emacsclient on Windows</a>, <a href="https://emeacselements/notes-videos/printing-directly-from-emacs-on-windows.html">Printing Directly from Emacs on Windows</a> and <a href="https://emeacselements/notes-videos/getting-spelling-to-work-on-windows.html">Getting spelling to work in Emacs on Windows</a> by Dr. Raoul Comninos on the EmacsElements website and YouTube channel. I have used their ideas in my setup, but tweaked things to my own liking.
</p>
<div id="outline-container-orgc3f0417" class="outline-2">
<h2 id="orgc3f0417">Installation and basic use</h2>
<div class="outline-text-2" id="text-orgc3f0417">
<p>
I use the Windows installer from <a href="http://ftpmirror.gnu.org/emacs/windows">a nearby mirror of GNU.org</a> as recommended on the Emacs website. Make sure to use runemacs.exe since it does not open an empty terminal before opening the Emacs GUI, unlike emacs.exe. It is a good idea to add runemacs.exe to your start menu and task bar to have it easily available. I have runemacs.exe as the leftmost icon in my task bar which means that I can launch it with Super-1.
</p>

<p>
You may also consider adding runemacs.exe as the default program to open .org, .md, .py, .js etc files. I find it easier to do so in File Explorer by right-cliking a file of that type and choosing Properties&#x2026; and setting the application to open that file type instead of using the Settings app which doesn't work by file type, but by program which always seems a bit backwards to me. The way I use Emacs, I tend to have a frame open at all times and visit files from inside Emacs, but when I use File Explorer, I often want files to open in other programs, usually because I want to show my students the files in the programs they use (Thonny, VSCode, Word, Excel, MySQL Workbench&#x2026;) even if I usually would use the files of the same file types inside Emacs, so I have only set a few file types to open with runemacs.exe. Since I don't use emacsclientw.exe on Windows, I don't want to double click files in File Explorer or open them through the start menu since that opens a new Emacs frame if runemacs.exe is set to open those file types. I like to almost always work in just one Emacs frame.
</p>

<p>
I have stopped using Emacsclient on Windows since it doesn't work the same way as on GNU/Linux. It does not respect my settings for faces (fonts) or scroll bars from my config. If I open Emacsclientw on Windows directly, it complains that I haven't opened it with a file. On GNU/Linux, if I open Emacsclient without a file, it opens up with the scratch buffer. Since I want to have an Emacs frame open at all times and more frequently open files from inside Emacs than from the File Explorer, I quite often want to open emacsclientw without a file. Another weird thing is that when I kill the buffer with the file I opened emacsclientw with, Emacsclient quits. It doesn't do that on GNU/Linux. Since I want to keep the frame for further work through the day, this behaviour makes emacsclientw more or less unusable for me. The third annoyance is that if I forget to use M-x kill-emacs before restarting or turning off the Windows machine, it uses forever to turn off. Together, these annoyances were just too much, so I went back to open an Emacs frame after booting the machine and continue to use it until I turn the machine off.
</p>
</div>
</div>
<div id="outline-container-org3abfbe2" class="outline-2">
<h2 id="org3abfbe2">Installation of tools that interact with Emacs</h2>
<div class="outline-text-2" id="text-org3abfbe2">
<p>
Below is a table that shows useful programs I use on Windows to get the functionality I need or want from Emacs. More details can be found in the relevant sections below.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Package</th>
<th scope="col" class="org-left">What it supplies</th>
<th scope="col" class="org-left">Where to get it</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">chocolatey</td>
<td class="org-left">Package manager</td>
<td class="org-left"><a href="https://chocolatey.org/install">https://chocolatey.org/install</a> Use Individual install.</td>
</tr>

<tr>
<td class="org-left">Hack</td>
<td class="org-left">Free programming font</td>
<td class="org-left"><a href="https://github.com/source-foundry/Hack-windows-installer">https://github.com/source-foundry/Hack-windows-installer</a></td>
</tr>

<tr>
<td class="org-left">Liberation</td>
<td class="org-left">Free variable pitch fonts</td>
<td class="org-left">Come with LibreOffice</td>
</tr>

<tr>
<td class="org-left">imagemagick</td>
<td class="org-left">For showing pictures</td>
<td class="org-left">Install with Chocolatey</td>
</tr>

<tr>
<td class="org-left">Pandoc</td>
<td class="org-left">Export org with ox-pandoc</td>
<td class="org-left">Install with Chocolatey</td>
</tr>

<tr>
<td class="org-left">MikTex</td>
<td class="org-left">Export org via LaTex</td>
<td class="org-left">Install miktex.install with Chocolatey</td>
</tr>

<tr>
<td class="org-left">Strawberry Perl</td>
<td class="org-left">MikTex needs Perl</td>
<td class="org-left"><a href="https://strawberryperl.com/">https://strawberryperl.com/</a></td>
</tr>

<tr>
<td class="org-left">mupdf</td>
<td class="org-left">PDFs in doc-view-mode</td>
<td class="org-left">Install with Chocolatey</td>
</tr>

<tr>
<td class="org-left">unoconv</td>
<td class="org-left">MS365 &amp; ODF in doc-view-mode</td>
<td class="org-left">Come with LibreOffice</td>
</tr>

<tr>
<td class="org-left">git</td>
<td class="org-left">Version control</td>
<td class="org-left"><a href="https://git-scm.com/downloads">https://git-scm.com/downloads</a></td>
</tr>

<tr>
<td class="org-left">hunspell</td>
<td class="org-left">Spell checking program</td>
<td class="org-left"><a href="https://sourceforge.net/projects/ezwinports/hunspell-1.3.2-3-w32.bin.zip/download">https://sourceforge.net/projects/ezwinports/hunspell-1.3.2-3-w32.bin.zip/download</a></td>
</tr>

<tr>
<td class="org-left"><code>nb_NO.aff</code>, <code>nb_NO.dic</code></td>
<td class="org-left">Bokmål hunspell dictionary</td>
<td class="org-left">Come with Libreoffice</td>
</tr>

<tr>
<td class="org-left">Node.js and npm</td>
<td class="org-left">NPM to install LSP servers</td>
<td class="org-left"><a href="https://nodejs.org/en/download">https://nodejs.org/en/download</a></td>
</tr>

<tr>
<td class="org-left">Python</td>
<td class="org-left">Pip to install LSP servers</td>
<td class="org-left">NPM installs Chocolatey and Python as well, otherwise Chocolatey</td>
</tr>

<tr>
<td class="org-left">LSP servers</td>
<td class="org-left">Completions, errors, linting</td>
<td class="org-left">pip and/or npm</td>
</tr>

<tr>
<td class="org-left">LibreOffice</td>
<td class="org-left">See above</td>
<td class="org-left"><a href="https://www.libreoffice.org/download/download-libreoffice/">https://www.libreoffice.org/download/download-libreoffice/</a></td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org322cd9d" class="outline-2">
<h2 id="org322cd9d">Setup of environment variables</h2>
<div class="outline-text-2" id="text-org322cd9d">
<p>
Emacs looks for a <code>.emacs.d</code> directory or a <code>.config/emacs/</code> directory or a <code>.emacs</code> file in <code>$HOME</code>. To set <code>$HOME</code>, press the Windows key, write environment and you should see the <code>Edit Environment Variables</code> program (<code>Rediger systemmiljøvariabler</code> if you use Norwegian Bokmål). Set the User variables for <code>HOME</code> to wherever you want it. I also found that it was useful for git to set <code>LANG</code> and <code>LC_ALL</code> since git and other programs compiled with MSYS2 respects the text encoding from those. I did this as part of my trial and error process to find ways around git's default conversion of text encoding and line endings, but I am not certain it is necessary after setting the system locale to UTF-8 and/or setting Git Bash's text encoding in the GUI (see the dealing with text-encoding section for more on this).
</p>


<figure id="orgdecb6d2">
<img src="https://einar.codeberg.page/media/windowsenv.jpg" alt="windowsenv.jpg">

</figure>
</div>
</div>
<div id="outline-container-org783dc10" class="outline-2">
<h2 id="org783dc10">Dealing with text-encoding</h2>
<div class="outline-text-2" id="text-org783dc10">
<p>
Windows uses UTF-16 under the hood, but on the surface it uses different text encodings depending on your locale. (GNU/Linux, BSD and MacOS use UTF-8 unless you configure them to use something else.) Windows uses CR and LF to end lines while GNU/Linux, BSD and MacOS X use LF. (Mac OS &lt; 10 used CR.) There are different strategies to deal with this:
</p>
<ol class="org-ol">
<li>Use the locale's encoding on Windows and have git convert line endings on clone, pull and push.</li>
<li>Use UTF-8 and Unix line endings for every buffer and file inside Emacs, but configure Emacs to work with yanking (pasting) and killing (cutting) to and from the clipboard in Windows locale's text encoding. Tell git to not convert files and line endings.</li>
<li>Set Windows 11 to use UTF-8, set Emacs to use UTF-8 and Unix line endings and tell git to use UTF-8 and not convert line endings.</li>
</ol>

<p>
If you do 1, then you don't have to configure git, because that is its default behaviour on Windows. This supposes that you use your text editor(s) with Windows line endings, and possible also your locale's text encoding which makes writing a lot of glyphs, like emojis, Hangul, Hiragana etc,  impossible. Even VSCode defaults to UTF-8, even on Windows. I think there is absolutely no advantages to this approach unless you never use any other platform than Windows.
</p>

<p>
If you do 2, then you have files with only UTF-8 and Unix line ending in your repos, but you have to configure Emacs to convert text when yanking and killing to/from the system clipboard. You also have to configure git not to convert CRLF to LF. (See the below section on how to do this.) Below is how you configure yanking and killing to work to and from iso-latin-1 which is the common text encoding for Windows in Northern Europe and North America. I tried this approach for a while, but would rather avoid another if-statement in my config if I could avoid it to keep things as similar as possible between Windows and GNU/Linux.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #b6a0ff;">if</span> (eq system-type 'windows-nt)
   (set-clipboard-coding-system 'iso-latin-1)
  (set-clipboard-coding-system 'utf-8))
</pre>
</div>
</div>
<div id="outline-container-org195708a" class="outline-3">
<h3 id="org195708a">My strategy</h3>
<div class="outline-text-3" id="text-org195708a">
<p>
I use the third strategy now. Windows 11 has a beta feature where you can choose to use UTF-8. You can set it up by following the step-by-step instruction from <a href="https://geekrewind.com/how-to-change-system-locale-in-windows-11/">geekrewind.com</a>. You still have to configure git not to convert CR LF to LF and vise versa on push and pull, but you don't have to configure Emacs to do anything when yanking and killing. To configure git to use UTF, I set the user environment variables <code>LANG</code> and <code>LC_ALL</code> since git and other programs compiled with MSYS2 respects the text encoding from those. In addition, I opened Git Bash, right-clicked the window title, selected Options&#x2026;, selected Text, chose <code>nb_NO</code> and <code>UTF-8</code> (you may want something else than <code>nb_NO</code> which is Norwegian Bokmål) since I read somewhere that git uses the settings set in Git Bash. I am not certain if you need to do both, but I did and it works. In my <code>.gitconfig</code> in my <code>$HOME</code>, I made a section called <code>[core]</code> and on the next line wrote <code>autocrlf = false</code>. This means that git will not convert line endings on push and pull from Unix (LF) to Windows (CRLF). Since all my files use Unix line endings anyway, this is no longer necessary.
</p>

<p>
I still have configuration to always use UTF-8 and Unix line endings inside Emacs and save every file as UTF-8 with Unix line endings. This is useful for getting rid of other encodings in previously made files. (In case I want that other encoding, for example for files I want to use under emulation of older systems, I can omit saving and they would still be in their original encoding.) I hope Microsoft will make UTF-8 and Unix line endings standard in Windows 12. The only small problem I have seen since switching to UTF-8 is that a few Norwegian glyphs in HP's notification about driver updates don't display properly. Otherwise, I have had no problems. Below is the configuration I use to set Emacs to use UTF-8 and Unix line endings and write every file with UTF-8 and Unix line endings.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(prefer-coding-system 'utf-8-unix)
(set-default-coding-systems 'utf-8-unix)
(set-language-environment 'utf-8)
(<span style="color: #b6a0ff;">setq-default</span> coding-system-for-write 'utf-8-unix)
(<span style="color: #b6a0ff;">setq-default</span> buffer-file-coding-system 'utf-8-unix)
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org5d2b3fb" class="outline-2">
<h2 id="org5d2b3fb">Spell checking</h2>
<div class="outline-text-2" id="text-org5d2b3fb">
<p>
I used to use aspell with aspell-en and aspell-nb (or -no) depending on whether the distro ships both Nynorsk and Bokmål in the same package or have separate packages (nb = Norwegian Bokmål, nn = Norwegian Nynorsk, no = both Nynorsk and Bokmål). I did not find aspell-no or nb on chocolatey or msys2 and I had the same problem with the hunspell package available for Windows which comes with British and American English which I sometimes use, but not Norwegian Bokmål.
</p>

<p>
For a while, I turned off spelling on Windows, but I recently looked into it again and found that I could copy over the .dic and .aff files I get with LibreOffice since it uses hunspell as well. The LO installer installs Norwegian dictionaries with a "typical install" if you downloaded the installer by browsing to the download page with a Norwegian IP address. To use the dictionaries from LibreOffice, go to <code>C:\Program Files\LibreOffice\share\extensions\dict-no\</code> and copy the files <code>nb_NO.aff</code> and <code>nb_NO.dic</code>. If you use another language, have a look in the extensions folders to find the folder with your relevant dictionaries. Go to the <code>share\hunspell</code> directory under where you installed hunspell. I use <code>C:\Program Files\Hunspell\share\hunspell\</code> and paste the files there.
</p>

<p>
In addition I have taken the settings suggested by <a href="https://emeacselements/notes-videos/getting-spelling-to-work-on-windows.html">Getting spelling to work in Emacs on Windows</a> and modified them slightly for my use. I now also use hunspell on GNU/Linux. I have also made a convenient function in <a href="https://codeberg.org/einar/emacs_config#headline-56">my Emacs config</a> to toggle between Norwegian Bokmål and British English, and bound it in my keymap to C-z i. 
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #b6a0ff;">use-package</span> flyspell
  <span style="color: #f78fe7;">:hook</span> ((prog-mode . flyspell-prog-mode)
         (text-mode . flyspell-mode))
  <span style="color: #f78fe7;">:init</span>
  (<span style="color: #b6a0ff;">when</span> (eq system-type 'windows-nt)
    (<span style="color: #b6a0ff;">setq</span> ispell-program-name <span style="color: #79a8ff;">"C:/Program Files/Hunspell/bin/hunspell.exe"</span>))
  (<span style="color: #b6a0ff;">setq</span> ispell-dictionary <span style="color: #79a8ff;">"nb_NO"</span>)
  (<span style="color: #b6a0ff;">setq</span> ispell-dictionary-alist
    '((<span style="color: #79a8ff;">"nb_NO"</span> <span style="color: #79a8ff;">":alpha"</span> <span style="color: #79a8ff;">"[</span><span style="color: #ff5f59; font-weight: bold;">^</span><span style="color: #79a8ff;">[:alpha:]]"</span> <span style="color: #79a8ff;">"[']"</span> nil (<span style="color: #79a8ff;">"-d"</span> <span style="color: #79a8ff;">"nb_NO"</span>) nil utf-8)))
  (<span style="color: #b6a0ff;">setq</span> hunspell-default-dict <span style="color: #79a8ff;">"nb_NO"</span>))
</pre>
</div>
</div>
</div>
<div id="outline-container-orga57fd70" class="outline-2">
<h2 id="orga57fd70">Dictionary lookup</h2>
<div class="outline-text-2" id="text-orga57fd70">
<p>
On my GNU/Linux systems, I install a dictd server and some dictionaries so I don't need to be connected to the internet to use dictionary-lookup-definition. Since there is no dictd server package for Windows, I first tried to use dict.org to look up words. When I tried dictionary-lookup-definition, Emacs just froze. It did not use a lot of CPU, but it just did not respond do anything, including C-g. I had to kill it with the three-finger salute (Ctrl-Alt-Delete). Maybe the relevant ports are blocked by my network at work, so it might work for you even if it did not for me. Below, you see my configuration for dictionary mode. I check if I am on GNU/Linux and otherwise, don't load it since I cannot get it to work at work.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #b6a0ff;">use-package</span> dictionary
   <span style="color: #f78fe7;">:if</span> (eq system-type 'gnu/linux)
   <span style="color: #f78fe7;">:config</span>
   (<span style="color: #b6a0ff;">setq</span> dictionary-server <span style="color: #79a8ff;">"localhost"</span>))
</pre>
</div>
</div>
</div>
<div id="outline-container-org3a91c30" class="outline-2">
<h2 id="org3a91c30">Viewing MS365 and Open Document Format documents</h2>
<div class="outline-text-2" id="text-org3a91c30">
<p>
Emacs can show .xlsx, .docx, .pptx, .odt, .odp and other MS365 (Formerly Microsoft Office) and LibreOffice (Open Document Format) files in doc-view-mode. It is very practical to go directly from dired to doc-view-mode in stead of waiting for LibreOffice or MS365 to start. To show these files it needs a python script called unoconv that comes with LibreOffice. You also need to set the path to that script to get it to work. Since newer versions of LibreOffice stalls when you open them on Windows 11, either if you launch Writer or use unoconv from Emacs, I had to install version 24.2.0.3 to get this to work properly. You find it with the Archive link on the LibreOffice download page.
</p>
</div>
</div>
<div id="outline-container-orgccf07b5" class="outline-2">
<h2 id="orgccf07b5">Pandoc and LaTex for export and import from Org mode</h2>
<div class="outline-text-2" id="text-orgccf07b5">
<p>
I use pandoc with Emacs and also ox-pandoc to be able to export from Org mode to .docx format. Upper Secondary schools in Norway use MS365, so it is useful to be able to write .docx documents occasionally. I use LaTex a lot for export of PDFs from org files I have used with inter-present-mode in class. Both pandoc and LaTex can be installed with Chocolatey, but when using LaTex to export PDFs on Windows 11, I always got an error that wrapfig.sty was not installed. It probably doesn't come with the LaTex package from Chocolatey. The solution is to use MikTex instead. Install the package miktex.install with chocolatey. MikTex needs Perl to function, so you also need to install Strawberry Perl from its website to get the export functionality to work. As with any external programs, you also need to set the exec paths (see further down this blog post) to get the actual functionality, unlike on GNU/Linux where it just works.
</p>
</div>
</div>
<div id="outline-container-org3a696e8" class="outline-2">
<h2 id="org3a696e8">PowerShell in Shell mode</h2>
<div class="outline-text-2" id="text-org3a696e8">
<p>
I prefer to use Eshell for most of my Shell needs. Since it is built in Elisp, it works just as well on Windows as on GNU/Linux. It is a much more pleasant experience than PowerShell and it integrates well into the rest of Emacs. However, sometimes it is useful to have PowerShell in Shell mode for doing something in Windows that you can only do through PowerShell, like turn on or off Hyper-V or delete a WSL2 distro.
</p>

<p>
By default, you get <code>cmd.exe</code> in Shell mode on Windows. I had some trouble finding good documentation of how to set it up with PowerShell. Some people suggest just setting PowerShell to <code>explicit-shell-file-name</code>, but that only partially worked since it gave me an error that PowerShell was invoked with a wrong argument. A lot of people pointed to someone on the Microsoft blogs that set up PowerShell in Shell mode, but in a way that removed the prompt. He had made an Elisp workaround to get the prompt back, but it seemed like there should be an easier way. The trouble is that comint mode, the mode shell mode is built on, sends <code>-i</code> by default to the shells it interacts with as an argument. I tried a couple of things and it turns out the solution is really simple.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #b6a0ff;">use-package</span> shell
  <span style="color: #f78fe7;">:config</span>
  (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
  (add-to-list 'comint-output-filter-functions 'ansi-color-process-output)
  (add-hook 'comint-output-filter-functions 'comint-osc-process-output)
  (add-hook 'shell-mode-hook (<span style="color: #b6a0ff;">lambda</span>() (company-mode 0)))
  (<span style="color: #b6a0ff;">when</span> (eq system-type 'windows-nt)
    (<span style="color: #b6a0ff;">setq</span> explicit-shell-file-name <span style="color: #79a8ff;">"C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"</span>)
    (<span style="color: #b6a0ff;">setq</span> explicit-powershell.exe-args '(<span style="color: #79a8ff;">""</span>)))
  (<span style="color: #b6a0ff;">when</span> (eq system-type 'gnu/linux)
     (<span style="color: #b6a0ff;">setq</span> explicit-shell-file-name <span style="color: #79a8ff;">"/bin/bash"</span>)
     (<span style="color: #b6a0ff;">setq</span> system-uses-terminfo t)
     (<span style="color: #b6a0ff;">setq</span> comint-terminfo-terminal <span style="color: #79a8ff;">"xterm"</span>)))
</pre>
</div>

<p>
In the code block above, if on Windows, I tell Emacs to run PowerShell and give it the arguments <code>""</code> (ie, nothing) which remove the default <code>-i</code> argument, but adds nothing else. And now I have PowerShell in Shell mode. The rest of the configuration turns off company since the shells have their own tab-completion and turns on ansi-colours which both Bash and PowerShell can work with. If you prefer to use PowerShell 7 instead, use the path to it instead of the path to the built-in Windows PowerShell.
</p>
</div>
</div>
<div id="outline-container-org1a615ad" class="outline-2">
<h2 id="org1a615ad">Language Server Protocol servers</h2>
<div class="outline-text-2" id="text-org1a615ad">
<p>
LSP is a standard Microsoft made for adding IDE-like language support to text editors. It was made for VSCode, but can also be used in other editors. In Emacs, you have to have the LSP servers you want installed and eglot, company and eldoc, if turned on, makes use of them in the mode for the associated programming or markup language. I tend not to like documentation constantly popping up with eldoc-mode since I find it visually distracting, but use the completions and warnings from LSP servers through eglot and company. Below is a table of the LSP servers I use and how to install them on Windows.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Language</th>
<th scope="col" class="org-left">LSP-server names</th>
<th scope="col" class="org-left">install with</th>
<th scope="col" class="org-left">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Python</td>
<td class="org-left">python-lsp-server (pylsp)</td>
<td class="org-left">pip or npm i -g</td>
<td class="org-left">FOSS, flake8 is an optional dependency</td>
</tr>

<tr>
<td class="org-left">Bash / Shell</td>
<td class="org-left">shellcheck, bash-language-server</td>
<td class="org-left">npm i -g</td>
<td class="org-left">FOSS</td>
</tr>

<tr>
<td class="org-left">JavaScript, TS, JSX</td>
<td class="org-left">typescript-language-server, typescript</td>
<td class="org-left">npm i -g</td>
<td class="org-left">Microsoft, LSP depends on typescript</td>
</tr>

<tr>
<td class="org-left">CSS</td>
<td class="org-left">vscode-css-languageserver-bin</td>
<td class="org-left">npm i -g</td>
<td class="org-left">Microsoft</td>
</tr>

<tr>
<td class="org-left">HTML</td>
<td class="org-left">vscode-html-languageserver-bin</td>
<td class="org-left">npm i -g</td>
<td class="org-left">Microsoft</td>
</tr>

<tr>
<td class="org-left">JSON</td>
<td class="org-left">vscode-json-languageserver</td>
<td class="org-left">npm i -g</td>
<td class="org-left">Microsoft</td>
</tr>
</tbody>
</table>

<p>
The Microsoft LSP servers give you the same completions, documentation and warnings as in VSCode. You may find more LSP servers at <a href="https://langserver.org/">https://langserver.org/</a>.
</p>

<p>
In addition, you have to turn eglot on in the relevant modes. I turn it on for all programming modes.
</p>
<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #b6a0ff;">use-package</span> eglot
  <span style="color: #f78fe7;">:hook</span> (prog-mode . eglot-ensure))  
</pre>
</div>
</div>
</div>
<div id="outline-container-org20b9f1a" class="outline-2">
<h2 id="org20b9f1a">Python Shell</h2>
<div class="outline-text-2" id="text-org20b9f1a">
<p>
Python mode in Emacs on GNU/Linux works out of the box with no setup if you have Python installed on your system. On Windows, you have to set python-shell-interpreter (even if the exec path includes the path to Python). In the code below, I also set the docstring-style to Django which I prefer over the default pep-257.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #b6a0ff;">setq</span> python-fill-docstring-style 'django)
(<span style="color: #b6a0ff;">when</span> (eq system-type 'windows-nt)
  (<span style="color: #b6a0ff;">setq</span> python-shell-interpreter <span style="color: #79a8ff;">"c:/Python313/python.exe"</span>))
</pre>
</div>
</div>
</div>
<div id="outline-container-org1ea57bd" class="outline-2">
<h2 id="org1ea57bd">Paths that need adding</h2>
<div class="outline-text-2" id="text-org1ea57bd">
<p>
For Emacs to integrate with external packages on Windows, the exec path needs to include the file path to those packages. Below is my extra configuration for adding exec-paths in Windows. You may have placed the programs you have installed manually, like Hunspell, in other places, so adjust accordingly. You may also do this with customize, but I want to have it as part of my config since sometimes I let the custom-vars file where I keep the changes from customize drift a little bit away from the upstream <code>emacs_config</code> repo on some machines.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #b6a0ff;">when</span> (eq system-type 'windows-nt)
  (custom-set-variables
 '(exec-path
   '(<span style="color: #79a8ff;">"C:/Program Files/MiKTeX"</span> <span style="color: #79a8ff;">"C:/Program Files/ImageMagick-7.1.2-Q16-HDRI"</span> <span style="color: #79a8ff;">"C:/Python313/"</span>
     <span style="color: #79a8ff;">"C:/ProgramData/chocolatey/lib/findutils/tools/install/bin/"</span> <span style="color: #79a8ff;">"C:/WINDOWS/system32"</span>
     <span style="color: #79a8ff;">"C:/WINDOWS"</span> <span style="color: #79a8ff;">"C:/WINDOWS/System32/Wbem"</span> <span style="color: #79a8ff;">"C:/WINDOWS/System32/WindowsPowerShell/v1.0/"</span>
     <span style="color: #79a8ff;">"C:/WINDOWS/System32/OpenSSH/"</span> <span style="color: #79a8ff;">"C:/Program Files/dotnet/"</span> <span style="color: #79a8ff;">"C:/Program Files/Git/cmd"</span>
     <span style="color: #79a8ff;">"C:/Program Files/nodejs/"</span> <span style="color: #79a8ff;">"C:/ProgramData/chocolatey/bin"</span> <span style="color: #79a8ff;">"C:/ProgramData/chocolatey/lib/mpv/"</span>
     <span style="color: #79a8ff;">"C:/ProgramData/chocolatey/lib/mupdf"</span> <span style="color: #79a8ff;">"C:/Users/AFK01217/AppData/Local/Microsoft/WindowsApps"</span>
     <span style="color: #79a8ff;">"C:/texlive/2025/bin/windows"</span> <span style="color: #79a8ff;">"C:/Users/AFK01217/AppData/Local/Programs/Microsoft VS Code/bin"</span>
     <span style="color: #79a8ff;">"C:/Users/AFK01217/AppData/Roaming/npm"</span> <span style="color: #79a8ff;">"C:/Users/AFK01217/AppData/Local/Pandoc/"</span> <span style="color: #79a8ff;">"."</span>
     <span style="color: #79a8ff;">"C:/Program Files/Hunspell/bin"</span> <span style="color: #79a8ff;">"c:/Strawberry/perl/bin/"</span> <span style="color: #79a8ff;">"C:/Program Files/LibreOffice/program"</span>))
 '(image-load-path
   '(<span style="color: #79a8ff;">"c:/Program Files/Emacs/emacs-30.1/share/emacs/30.1/etc/images/"</span> data-directory load-path <span style="color: #79a8ff;">"c:/python313/"</span>)))
)
</pre>
</div>
</div>
</div>
<div class="taglist"><a href="https://einar.codeberg.page/tags.html">Tags</a>: <a href="https://einar.codeberg.page/tag-emacs.html">emacs</a> <a href="https://einar.codeberg.page/tag-computers.html">computers</a> <a href="https://einar.codeberg.page/tag-windows.html">windows</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[computers]]></category>
  <category><![CDATA[windows]]></category>
  <link>https://einar.codeberg.page/emacs-on-windows.html</link>
  <guid>https://einar.codeberg.page/emacs-on-windows.html</guid>
  <pubDate>Tue, 03 Jun 2025 16:30:00 +0200</pubDate>
</item>
</channel>
</rss>
