Notes about open source software, computers, other stuff.

Tag: Emacs (Page 1 of 2)

Using Emacs key bindings in Gnome, Firefox and other applications

As an avid Emacs user, I love to have my Emacs key bindings available in as many places as possible. For example, even though I still regularly use the arrow keys to move the cursor around, I also use Emacs’ Alt-f and Alt-b to move one word forward or back, respectively. Similarly, Ctrl-a to me doesn’t mean “select all”, but rather “go to the beginning of line” (like the Home key). And especially this latter keybinding has a huge potential to mess things up, e.g. when you follow it by typing text, because that will then overwrite the selected text, i.e. all text. And the only thing I really intended to do was to go to the beginning of the line.

Another clash: in Emacs Ctrl-k means “kill to end of line”, i.e. “delete everything from the cursor position up to the end of the current line”, but in Firefox it sends your cursor to the Search box (for those of you who, like me, still use that for searching instead of just typing your query in the address bar). Similarly, Ctrl-n moves one character forward in Emacs, but in Firefox it opens a new window.

Luckily for me, I have managed to tailor the settings of various tools and the Gnome desktop environment to accommodate at least some of the more common Emacs key bindings. Unfortunately, applications built using other frameworks, like the Signal and Mattermost desktop apps, don’t follow these settings.

Below are the settings I’m currently using. Most of them have been with me for several years at this point and have been migrated various Ubuntu Linux upgrades, so I hope they are complete. For the record, I’m currently running the 24.04 Noble Numbat release.

Gnome

Let’s start with the Gnome desktop environment. My Linux desktop of choice for roughly the past twenty years has been Ubuntu, which uses Gnome. There is a gsettings entry that allows you to enable Emacs key bindings in most Gnome/Gtk applications, including Thunderbird. The entry can be set by setting the “Emacs input” toggle in the Keyboard section of the Gnome Tweak tool, or directly on the command line with

gsettings get org.gnome.desktop.interface gtk-key-theme "Emacs"

The current value can be checked like this:

$ gsettings get org.gnome.desktop.interface gtk-key-theme
'Emacs'

The Arch Linux wiki also lists options for GTK-2.0 and GTK-3.0, but I haven’t got those configured (any more).

Gnome terminal

By default, Gnome terminal steals the Alt key and uses e.g. Alt-f to open the file menu. This can be turned off by going to the hamburger menu in the top right corner and under “Global” — “General” uncheck the box for “Enable mnemonics (such as Alt-F to open the File menu)”.

Shells (Bash, Zsh)

As Emacs has been around for so many years, many shells (well, actually, the readline library if I’m not mistaken) support the basic Emacs key bindings for editing the commands you type on the command line. Both Bash and Zsh use the Emacs bindings by default (others might do too, but I don’t have any experience with other shells, except tcsh a long long time ago). In fact, you have to run set -o vi on order to be able to use Vim key bindings.

Byobu & Screen

I often use byobo as a terminal multiplexer. Like screen it likes to “steal” Ctrl-a as “attention” or “escape” key. Luckily, when the user presses Ctrl-a for the first time in Byobu, they are asked whether they’d like to use Emacs key bindings or not. My answer is obvious, and I generally give them Ctrl-o to use instead. This can be done via a menu by pressing F9 and selecting “Change escape sequence”.

Alternatively, this can be changed in the ~/.byoby/keybindings file by adding the following code:

# replace ctrl-A by ctrl-o
escape ^Oo

For screen the same line should be added to ~/.screenrc .

Firefox

My solution for Firefox is to replace the Ctrl key with the Alt key. This way, I can open new tabs with Alt-t, new windows with Alt-n, etc. Together with the Gnome settings for Emacs key bindings (see above), this means I can use Ctrl-a, Ctrl-f, Ctrl-b, etc. for moving the cursor in text fields, Ctrl-d for delete, etc. Interestingly enough, Alt-f and Alt-b — for “move one word forward” and “move one word backward”, respectively — keep working in text fields as well. Note that this also means that “Undo” is handled by Alt-z instead of Ctrl-z, which is fine with me because Ctrl-z is normally used to let applications run in the background (in the shell).

Unfortunately, some sites seem to define their own extra keybindings that interfere with my settings. For example, when creating or commenting on a Github issue, Ctrl-e inserts a backtick (`), instead of going to the end of line. I haven’t yet found out how to disable or overwrite that. I’m glad that I mainly use Gitlab, as it behaves properly.

To change the key, point to about:config in the address bar of the browser and find the entry ui.key.accelKey and change its value to 18. This is the code for the Alt key (see the documentation). You may want to set the entries ui.key.generalAccessKey and ui.key.menuAccessKey to 0 to disable e.g. using Alt for accessing the menus, but I haven’t done so myself.

Additional documentation about Emacs key bindings in Firefox can be found in the Mozilla knowledgebase article.

There are, and have been, various Firefox extensions or other methods that allow(-ed) one to use Emacs for editing text in textfields like those used in forum posts, etc. However, the last one I used, “Emacs Everywhere” unfortunately doesn’t work yet with the Wayland window manager, although work seems to be on the way to fix that.

LibreOffice

Unfortunately I regularly have to edit MS Word documents (or their LibreOffice counterpart). Fortunately, Marcus Nitzschke created a customisation list for LibreOffice Writer that sets a series of basic Emacs movement key bindings! On his site he links to a Zip file that can be imported via Tools — Customize — Keyboard — Load. After that, the following keys should work in LibreOffice Writer (thanks to Marcus for this list):

Binding Function
C-f forward-char
C-b backward-char
C-n next-line
C-p previous-line
M-f forward-word
M-b backward-word
C-v next page
M-v previous page
C-a beginning-of-line
C-e end-of-line
C-k kill-line
M-d kill-word
M-backspace backward-kill-word

Related Images:

Upgrading nodejs to the latest LTS release on Ubuntu 21.10

Today I upgraded the Bash language server (to v3.0.3), after which I noticed that it stopped working. When loading a .bash file, the language server didn’t load and told me to look in the error output for more information. In Emacs, the errors of the Bash language server can be found in the *bash-ls::stderr* buffer, which showed me:

/home/lennart/.emacs.d/.cache/lsp/npm/bash-language-server/lib/node_modules/bash-language-server/node_modules/vscode-jsonrpc/lib/common/linkedMap.js:40
        return this._head?.value;
                          ^

SyntaxError: Unexpected token '.'
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/home/lennart/.emacs.d/.cache/lsp/npm/bash-language-server/lib/node_modules/bash-language-server/node_modules/vscode-jsonrpc/lib/common/api.js:37:21)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)

I re-ran lsp-install-server, which pointed out that I had nodejs v12.22.5 installed and the language server required v14 or higher.

Time to figure out how to install a newer nodejs version on my Ubuntu 21.10 machine. It turns out that v12 is no longer maintained. The current LTS version of nodejs is v16. Here I found instructions on how to install a given version of nodejs on Ubuntu. For v16, this boils down to running

curl -sL https://deb.nodesource.com/setup_16.x | sudo bash -

The script that this command fetches (and executes as root) is quite elaborate, but in the end it simply creates the file /etc/apt/sources.list.d/nodesource.list, with the following contents:

deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x impish main
deb-src [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x impish main

After that, a simple apt upgrade didn’t suffice. The nodejs upgrade was held back because of a dependency problem. Even an explicit upgrade of the nodejs package didn’t work:

$ sudo apt upgrade nodejs
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies.
 libnode72 : Conflicts: nodejs-legacy
E: Broken packages

So, I resorted to a full apt dist-upgrade, which worked fine. After that, I reopened a Bash script and all was fine.

Related Images:

Opening Emacs (-client) windows with full screen height

I usually want my Emacs windows, including those opened via emacsclient, to be opened using the full screen height. It turns out that Emacs has a command line option for this:

emacs --fullheight

Now, for emacsclient this option doesn’t exist, so how can we solve this? Looking around the web, I found this answer on Emacs StackExchange that explained how to do this from within Emacs (see also the fullscreen option on the corresponding page in the Emacs manual). Combined with this answer on StackOverflow that shows how to use the -F/--frame-parameters option of emacsclient I managed to open a full-height Emacs client window:

emacsclient --create-frame --frame-parameters="'(fullscreen . fullheight)"

Most of the time I open new Emacs (-client) windows using the button in Ubuntu’s/Gnome shell’s dock. So how do we incorporate the aforementioned options in the relevant .desktop file? Before explaining how I did this, I have to mention that I don’t use a pre-packaged version of Emacs. As of this writing Emacs v27.2 is the latest official release, but I have been compiling Emacs from source for about two years now. About a month ago I compiled Emacs from the emacs-28 branch 1, which contains what will become Emacs v28. In this branch the .desktop files used by Gnome for its list of applications (including the icons/launchers that end up in the Gnome shell dock) have received some love. For example, the emacsclient.desktop file now opens a regular Emacs at first launch, but subsequent clicks on the icon will launch an Emacs client window. Right-clicking on the icon shows an option called “New Instance”, which will do as it says: launch a new Emacs instance. Well done Emacs maintainers! This perfectly fits my workflow, where most of the time I want to open a client window, but sometimes want to open a new Emacs instance (e.g. when I don’t want to clutter my regular workspaces).

So, getting back to the fullheight topic, editing the emacsclient.desktop file seemed like the way to go. Given that I compile Emacs from source and do not install it system-wide (I used the --prefix=/home/$USER/.local option when running ./configure), the .desktop files can be found in ~/.local/share/applications. This is the contents of the emacsclient.desktop file before I edited it:

[Desktop Entry]
Name=Emacs (Client)
GenericName=Text Editor
Comment=Edit text
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
Exec=sh -c "if [ -n \\"\\$*\\" ]; then exec emacsclient --alternate-editor= --display=\\"\\$DISPLAY\\" \\"\\$@\\"; else exec emacsclient --alternate-editor= --create-frame; fi" %F
Icon=emacs
Type=Application
Terminal=false
Categories=Development;TextEditor;
StartupNotify=true
StartupWMClass=Emacs
Keywords=emacsclient;
Actions=new-window;new-instance;

[Desktop Action new-window]
Name=New Window
Exec=/home/lennart/.local/bin/emacsclient --alternate-editor= --create-frame %F

[Desktop Action new-instance]
Name=New Instance
Exec=emacs %F

After my edits, this is the contents of the file:

[Desktop Entry]
Name=Emacs (Client)
GenericName=Text Editor
Comment=Edit text
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
Exec=sh -c "if [ -n \\"\\$*\\" ]; then exec emacsclient --alternate-editor=  --frame-parameters=\\"'(fullscreen . fullheight)\\" --display=\\"\\$DISPLAY\\" \\"\\$@\\"; else exec emacsclient --alternate-editor= --create-frame --frame-parameters=\\"'(fullscreen . fullheight)\\"; fi" %F
Icon=emacs
Type=Application
Terminal=false
Categories=Development;TextEditor;
StartupNotify=true
StartupWMClass=Emacs
Keywords=emacsclient;
Actions=new-window;new-instance;

[Desktop Action new-window]
Name=New Window
Exec=/home/lennart/.local/bin/emacsclient --alternate-editor= --create-frame --frame-parameters="'(fullscreen . fullheight)" %F

[Desktop Action new-instance]
Name=New Instance
Exec=emacs --fullheight %F

The diff is:

@@ -3,7 +3,7 @@
 GenericName=Text Editor
 Comment=Edit text
 MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
-Exec=sh -c "if [ -n \\"\\$*\\" ]; then exec emacsclient --alternate-editor= --display=\\"\\$DISPLAY\\" \\"\\$@\\"; else exec emacsclient --alternate-editor= --create-frame; fi" %F
+Exec=sh -c "if [ -n \\"\\$*\\" ]; then exec emacsclient --alternate-editor=  --frame-parameters=\\"'(fullscreen . fullheight)\\" --display=\\"\\$DISPLAY\\" \\"\\$@\\"; else exec emacsclient --alternate-editor= --create-frame --frame-parameters=\\"'(fullscreen . fullheight)\\"; fi" %F
 Icon=emacs
 Type=Application
 Terminal=false
@@ -15,8 +15,8 @@

 [Desktop Action new-window]
 Name=New Window
-Exec=/home/lennart/.local/bin/emacsclient --alternate-editor= --create-frame %F
+Exec=/home/lennart/.local/bin/emacsclient --alternate-editor= --create-frame --frame-parameters="'(fullscreen . fullheight)" %F

 [Desktop Action new-instance]
 Name=New Instance
-Exec=emacs %F
+Exec=emacs --fullheight %F

One final note: for those who don’t use the Emacs client, there is also the emacs.desktop file, with the same icon. You can find out which one is in your Gnome shell dock by running:

gsettings get org.gnome.shell favorite-apps

which returns a list like this:

['org.gnome.Terminal.desktop', 'thunderbird.desktop', 'firefox.desktop', 'emacsclient.desktop']

If you’d like to edit this variable manually, you can use either dconf-editor to edit org/gnome/shell/favorite-apps, or set it directly:

gsettings set org.gnome.shell favorite-apps "['org.gnome.Terminal.desktop', 'thunderbird.desktop', 'firefox.desktop', 'emacs.desktop']"

Note, the order of the list matters!

Footnotes:

1

The commit I used was d86b2e59c.

Related Images:

Fixing Emacs tramp mode when using zsh

Today I finally took some time to fix a long-standing problem: when trying to edit a file on a remote host using Emacs tramp mode, long time-outs occurred when typing the remote file name (after hitting C-x C-f). These time-outs were so long and occurred after each key press that tramp was effectively useless.

After some digging (e.g. excluding helm as the problem source) I found this entry in the Emacs Wiki which basically told my that using zsh (the Z shell) on the remote host could be the culprit. Indeed, after adding

[[ $TERM == "dumb" ]] && unsetopt zle && PS1='$ ' && return

at the top of my ~/.zshrc file solved the problem instantly. What this line does is simply replacing the shell prompt with a very simple one (a $ followed by a space) if the terminal is of the dumb type (which is the case for tramp).

Related Images:

Configuring Org2blog

Yesterday I installed Org2blog, which allows me to write my blog posts in Emacs org-mode and push them to my WordPress blog from within Emacs. So far I like it a lot! One less reason to leave Emacs :-), and hopefully also a reason to blog more often. Other good things about keeping your blog posts in Emacs are:

  • You can simply export them to e.g. PDF. In my current setup it’s a easy as adding the line

    #+LATEX_CLASS: lckartcl
    

    somewhere at the top of the file (before the actual text of the post starts) to tell org-mode that it should use my personal LaTeX export style, followed by C-c C-e l o and a nicely formatted PDF of my blog post pops up.

  • You keep all your blog posts in plain text format, so if you would decide to change to a different blogging platform, uploading the old posts should be fairly easy.

Org2blog’s GitHub page mentions C-c p as prefix key for Org2blog’s functions, but in my case this prefix is already used by Projectile, and looking in Org2blog’s Customize Group I noticed that C-c M-p is an alternative prefix, so I’m using that to get the following functionality:

C-c M-p p publish buffer
C-c M-p P post buffer as page and publish
C-c M-p d post buffer as draft
C-c M-p D post buffer as page draft
C-c M-p t complete category

This is the Org2blog configuration in my .emacs file (note that I’m using John Wiegley’s use-package macro):

;;;;;;;;;;;;;;;;;;;;
;; Configure Org2blog, which allows me to write blog posts in org-mode
;; and then push them to my WordPress blog.
(use-package org2blog
  :config
  (require 'org2blog-autoloads)
  (setq org2blog/wp-blog-alist
        '(("blog.karssen.org"
           :url "https://blog.karssen.org/xmlrpc.php"
           :username "xxxxxx"
           :default-title "New blog post"
           :default-categories "Linux"
           :tags-as-categories nil)))
  )

Related Images:

Upgrading to Org-mode 8.3 via the package repository: fixing an error

Today I tried to upgrade Emacs Org-mode to version 8.3. I used the regular package upgrade, but got the following error:

Invalid function: org-babel-header-args-safe-fn

Unfortunately, Irreal’s advice to byte-compile ob-R.el (twice) didn’t work out for me (by the way: thanks Planet Emacsen for aggregating so many useful posts!).

Browsing through some discussions on the emacs-orgmode mailing list it seemed that the error was due to org-mode being loaded while reinstalling the package. So I did the following:

  • I started emacs without loading my personal settings: emacs -Q
  • Next I ran the following code from my .emacs file in the scratch buffer (M-x eval-region) to set up the package manager:

    (require 'package)
    (package-initialize)
    ;; Add the original Emacs Lisp Package Archive
    (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
    ;; Add the user-contributed repository
    (add-to-list 'package-archives
                 '("marmalade" . "http://marmalade-repo.org/packages/"))
    
  • And finally I used the package manager to remove and then install the latest org package.

    Now all is fine again! 🙂

    And by the way: this is my first blog post using Org2blog!

Related Images:

Using Magit to commit only some of the changes in a file

As I discussed here, git allows you to commit only some of the changes you made to a given file. If you are working in Emacs you probably already know the wonders of Magit. In order to do the same partial committing of a file you can simply open magit-status and go to the file you’re interested in. This will highlight the changed parts of the text. With your cursor in the changed block you’d like to commit simply press s and that change will be staged. If this is all you want press c to commit and you’re done!

Source

Related Images:

Hiding columns in LaTeX export of org-mode tables

Today I was working on an Emacs org-mode document that I wanted to export to PDF. The document contained several tables and for the PDF export I wanted to hide one of the columns in the table. Of course I could have removed the column in the org source, but since I might need it in the future that wasn’t really an option.

Searching the internet I came across this e-mail discussion on the org-mode mailing list, where radio tables were suggested. I briefly tried to get that working, but it seems that this is more of an option if you are working in e.g. a LaTeX document and want to use org-style formatted tables.

So I tried another search, this time on how to hide columns in LaTeX, having the idea in mind that I could then use that to fix the org-mode export. Thanks to question on tex.stackexchange.com I came up with the followin solution:

First add the following lines at the top of the org file, after the regular org-mode header (if you have one):

#+LATEX_HEADER: \usepackage{array}
#+LATEX_HEADER: \newcolumntype{H}{>{\setbox0=\hbox\bgroup}c<{\egroup}@{}}

This defines a new column type with the name H (for ‘hidden’). Next, just before the table, simply add an #+ATTR_LATEX: attribute (see the org-mode manual):

#+ATTR_LATEX: :align lHl
| col 1 | to be hidden | col3   |
|-------+--------------+--------|
|     1 | secret       | info 1 |
|     2 | private      | info 2 |
|     3 | hidden       | info 3 |

When you export this to PDF (via C-c C-e lo) the table in the PDF only contains the first and last column.

Related Images:

Changing the default mode of the Emacs scratch buffer

After starting Emacs you end up in the *scratch* buffer (assuming you’ve disabled the startup message in your .emacs file). The *scratch* can be used for writing down notes and some Lisp experiments (since it uses the Emacs Lisp major mode by default).

Now, I’m not very much of a Lisp programmer, but I do use Org-mode a lot. Consequently, I found myself changing the buffer’s major mode to org-mode regularly. And Emacs wouldn’t be Emacs if you couldn’t change this to a default. So, thanks to Bozhidar Batsov over at Emacs Redux, I’ve added the following lines to my Emacs configuration file:

;; Set the default mode of the scratch buffer to Org
(setq initial-major-mode 'org-mode)
;; and change the message accordingly
(setq initial-scratch-message "\
# This buffer is for notes you don't want to save. You can use
# org-mode markup (and all Org's goodness) to organise the notes.
# If you want to create a file, visit that file with C-x C-f,
# then enter the text in that file's own buffer.
 
")

Related Images:

Fixing the compose key in Emacs on Ubuntu 13.10

After upgrading to Ubuntu 13.10 some time ago I noticed that my compose key (i.e. the key that you press followed by e.g. c and , to create a ç) didn’t work anymore in Emacs. I found two bug reports on this issue [1, 2], both effectively suggesting the same solution: start Emacs like this

XMODIFIERS=@im=none emacs

So I added the following line to my ~/.zshrc and ~/.bashrc files:

alias emacs='XMODIFIERS=@im=none emacs'

(of course somewhere before I set my EDITOR variable). I also changed the command in the launcher I use (GLX-Dock/Cairo-Dock).
This doesn’t make it a system-wide (or even user-wide) fix, e.g. the Firefox add-on “It’s all text” doesn’t get it, but it covers most of my use cases.

Related Images:

« Older posts

© 2024 Lennart's weblog

Theme by Anders NorénUp ↑