reddit / emacs

What are the kinds of things you've written Emacs Lisp for?

gollyned · 2022-09-10 20:29
Hi, I've been using Doom Emacs for about a year. I want to learn Emacs Lisp. The advice I've read is to solve an actual problem I have with Emacs Lisp. But my mind draws a blank when I think of problems I'd like to solve. What have you written elisp for recently? What problems have you solved by writing an elisp function or mode? Thank you.
oantolin · 2022-09-10 20:53
Well, I've written some general purpose Emacs packages ([orderless](https://github.com/oantolin/orderless) and [embark](https://github.com/oantolin/embark)) that I use *a lot*, but I also write Emacs Lisp for one-off tasks. For example, one time I organized a session at a conference and had to select talks among the submissions and schedule them. The conference had a website I could log into to see all the submitted abstracts, but it seemed a little awkward to use so I wrote some code to download all the abstracts and create an Org buffer with all the information (did you know Emacs *comes with an HTML parser?*, it's called `libxml-parse-html-region`). Then, once I chose the talks to accept I needed to schedule them. For that I wanted a nice compact table that fit all at once on screen and since the conference's system assigned each talk an ID, I decided to make the timetable as an Org table of talk ID's. But then I wanted a quick way to enter the ID in a table cell by typing a bit of either the speaker's name or talk title and selecting from the matches, and also a quick way to jump to the talk information for the ID at point. So I wrote two more functions for those purposes and bound them to keys. Editing the timetable was a breeze that way! All in all it was about 70 lines of code for a bespoke talk-scheduling UI that was quick and easy to write *and* fun to use. Oh, and Org let me neatly keep all the code together with the submitted abstracts, the timetable and my notes in a single easy to navigate file. Sadly I later had to enter all those talk IDs into the conference's web system manually. I wish they had let me upload a CSV file...
Patrick-Poitras · 2022-09-10 21:00
I had a problem where SLIME would fuck the indentation of any code I wrote in the REPL, if there was something in the previous lines that indicated that the code I was writing was actually a comment, like a " character. In digging into the code to see what was going on, I found out that it was using (lisp-indent-line), which reads the entire buffer, taking my error messages as code to evaluate. This was very sad. I decided that I was done trying to debug this and decided to modify the lisp-indent-line function to work for me. Thankfully, this can be done via an around macro (advice-add). I made a function that prior to indenting the line, checks whether or not I'm in repl mode. If it is not, then it calls (lisp-indent-line), and if it is, it calls my own special function that basically just uses a slime function to figure out whether or not it's inside a comment, before calling (lisp-indent-line) on a reduced section of code. I was able to do the entire process of troubleshooting by using emacs' internal helpers. C-h k, showed me the path to lisp-indent-line. I went deeper in the code by simply pressing M-. on functions. Figured out the error, and modified emacs' own internal functions. I'm pretty sure I moved entirely over to emacs that week. Since then I've written a bunch of different functions to automate tasks that I find annoying to do. The other day I was making a theme and I was spending a lot of time converting RGB to RGBA and doing additions using a calculator, and I made a function to do that. Now I mouse over a hex code, M-x whatever-ive-named-this, and it gives me the answer.
donio · 2022-09-10 21:09
Surely you must have encountered some situations where you thought "I wish this worked in a certain way but there doesn't seem to be a configuration option for it"? Start small, create some interactive functions that you can bind to keys. Or functions you can use in hooks from base emacs or packages you use. Or advise existing functions (using `advice-add`) to change their behaviors. To give a specific recent example, I wanted to show notmuch mail counts in the mode line so I've come up with this to be used from `display-time-string-forms`: (defun my-notmuch-count-format (name query face) (let* ((default-directory "/tmp") (count (string-to-number (shell-command-to-string (concat "notmuch count " query))))) (if (zerop count) "" (propertize (format "%s:%d" name count) 'face face)))) Also, when it comes to learning reading lots of code is just as important as writing code. One of my favorite things about Emacs is that it's so easy to dig into how everything works. The definitions of the functions you use all the time are just a `C-h f` or `C-h k` away (you can click on the filename in the first line of the descriptions). Explore, go where your curiosity takes you. For example look at how text navigation functions like `forward-sentence` work. Or look at a small package you use all the time and understand how the code works. Make sure you know how to use the built-in documentation, both the function and variable descriptions mentioned above and the texinfo manuals: [GNU Emacs manual](https://www.gnu.org/software/emacs/manual/html_node/emacs/index.html) [An Introduction to Programming in Emacs Lisp](https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html) <- found this one very helpful when I first started out [Emacs Lisp Reference Manual](https://www.gnu.org/software/emacs/manual/html_node/elisp/index.html) You should already have the Info version (C-h i) but linking them in case you are not comfortable with that yet.
arthurno1 · 2022-09-10 21:16
I wrote a little [addon to dired](https://github.com/amno1/dired-auto-readme) to automatically display readme files in directories if there is one. I use it all the time, autoloads with my dired. I also wrote an init file generator and manager that I use every day, as long as some small packages to cleanup org mode noise, summarized in [org-view-mode](https://github.com/amno1/org-view-mode). Generally I use elisp instead of bash to cleanup directories, batch rename files in some special folders according to some specific naming rules etc. I also wrote an elisp script to re-build emacs, lots of other small stuff I haven't published on my github. You can [check here](https://github.com/amno1/.emacs.d/tree/main/lisp) some small extras I wrote or adapted from others for my personal use.
craftkiller · 2022-09-10 21:28
I wrote a function that generates a github permalink to the line my cursor is at. This way if people find my old links in the company slack history, I know they'll always continue to point to the same line that I intended. I used the standard built-in functions (I think it was called vc mode or vcs mode) to extract the git commit hash and the remote URL. I then bound this function to a hotkey and made it write the result to my clipboard so now I just hit my hotkey and paste my link into slack or whatever.
thevoidzero · 2022-09-10 21:42
https://github.com/Atreyagaurav/litex-mode This was for converting lisp expressions to latex. Useful for homeworks as I use lisp in org blocks to calculate and this to make latex. https://github.com/Atreyagaurav/units-mode This is wrote recently to just can units binary to convert units. Also useful for doing homeworks.
laurits · 2022-09-10 21:47
I wrote a thing that posts content and changes from some of my text note files to Account records in Microsoft Dynamics 365 cloud.
YakumoYoukai · 2022-09-10 21:59
I make supertitles for live opera performances, which involves manipulating lots of text to break it up into appropriately sized groups of lines. Additionally, we often do both the original language & the English translation side-by-side. The input files for the supertitling app I use are text, but the formatting is very annoying to work with directly. So I wrote a major mode which lets you author the text lines in a natural way (e.g., Italian line, then English translation, then next Italian, English, etc), and indicate where the transitions are, with comments on where in the music each transition should occur. Then I can convert it all into the expected format for use by the app. The app is still pretty janky & annoying to work with though, so I'm going to extend my mode so that Emacs itself will present the titles, no conversion necessary.
owmagow · 2022-09-10 22:06
I wrote a program to evaluate the contents of a buffer for SEO relevance ... basically to guide me in tweaking my website.
thevoidzero · 2022-09-10 22:11
The readme one is perfect. You should put it in melpa. Or maybe make a pull request to dired.
ideasman_42 · 2022-09-10 22:26
Moving documentation from implementation to headers (when this became our projects policy): [https://gitlab.com/ideasman42/emacs-relocate-docs](https://gitlab.com/ideasman42/emacs-relocate-docs) To pick another package at random: [https://codeberg.org/ideasman42/emacs-cycle-at-point](https://codeberg.org/ideasman42/emacs-cycle-at-point) ... which I use regularly to switch true/false ... cycle A,B,C, D .. etc.
arthurno1 · 2022-09-10 22:43
Thank you! Unfortunately it is not. I have to rework it. It is just a hack-ish prototype (as most of my ideas). If someone is interested to rework it as a framework, I would be happy to get a PR. By the, when it happens that Dired shows just blank buffer, just press 'g" to revert the buffer. In some cases it crashes on some files, but it is very occasionally so I didn't bother to fix it 😀.
sachac · 2022-09-10 22:45
This sounds like a ton of fun. I'd love to read more details about it, especially if you manage to present it from Emacs!
alcanost · 2022-09-10 23:14
I wanted to seamlessly capture some org-mode TODOs for whatever project I'm currently working on, so I wrote [a small package](https://github.com/delehef/org-project) doing exactly that. It offers two functions that let the user capture TODOs, either a ine of a text or the result of a more complex org-capture process, and stuff them in a file that can readily be accessed later on, displayed in your agenda, or whatever else.
tangonov · 2022-09-10 23:32
I use Emacs lisp primarily for changing how Emacs works for me. Over many, many years I've gradually improved my experience* and enhanced my own configuration. It's these changes that make Emacs fun and useful for me. My modeline shows me what I want to know in a way that I want to see it. I have bent god-mode into the mode that I can use pretty consistently in many places. I set the terms for which keybinds work and when. More than that, I have used elisp to bend org-mode further to my whim and it's opened the door for me to explore other actual Lisps (Common Lisp, Scheme) and other lisp-alikes. My current system runs on Guile scheme and my window manager runs on Common Lisp. It's relatively simple to get all three working together.
Bobbias · 2022-09-11 00:29
Just a heads-up, you seem to have accidentally replied to the main post instead of the intended comment.
Bobbias · 2022-09-11 00:30
You accidentally pasted the same link twice.
mmontone · 2022-09-11 00:39
A snippet to make ERT run the test at cursor: https://lists.gnu.org/archive/html/emacs-devel/2022-09/msg00606.html
CannibalismIsNatural · 2022-09-11 00:43
Are you using GUIX by chance?
arthurno1 · 2022-09-11 01:01
Yes, indeed, my phone & bacon reader have a life of their own 😀. Thanks, I'll fix it later, if it isn't obvious for everyone anyway 😀
tangonov · 2022-09-11 01:06
On purpose, even!
thevoidzero · 2022-09-11 01:11
Thanks. Edited.
lj-read-it · 2022-09-11 01:14
I wrote a function to make Dired do different things with the file at point depending on what it is--a folder (open in Dired), a file associated with an app (open with that app), or other (open in a righthand Emacs window). I then bound it to Enter and, together with a code snippet I found online that suppresses the default new window on async command, Dired has become my file manager for everyday use. A code I swiped from online, maybe from this sub, and modified was a function hook that makes Evil Mode remember the language input from the last time it was in insert mode and return to that input when insert mode is entered again. Absolutely essential for me when writing in Korean.
7890yuiop · 2022-09-11 01:23
> The advice I've read is to solve an actual problem I have with Emacs Lisp. But my mind draws a blank when I think of problems I'd like to solve. I have the perfect solution for you (and I am 100% serious about this, to be clear). Create a user account at https://emacs.stackexchange.com/ if you don't already have one, and keep a regular eye on the questions. Every time you see a question that sounds interesting, see if you can figure out an answer. If you know an answer already, great; but the important thing is to attempt to answer questions that you *don't* already know the answer to -- see if you can work out out how to solve that person's problem for them. This gives you specific practical problems to work on. You will learn endlessly by doing this over and over. You will learn by doing, tackling many different problems. You will learn further by comparing what you'd figured out with any other answers that other people post, often connecting the dots between features. It doesn't matter who's answer is better, as you're learning things either way. And you're helping the community into the bargain. And even if you're still not thinking of projects of your own, occasionally a thing you figured out for someone else will go straight into your own config when you realise you'd also like that thing.
soulhacker · 2022-09-11 01:25
While you writing Emacs config and/or init scripts you'are learning Emacs Lisp. Just try to understand those code and feel free to play here and there.
rontan · 2022-09-11 01:29
I wrote a small package for storing the result of a ping pong match at work, and also mail the result to the opponent with a summary about previous matches. Nothing complicated really but a fun elisp exercise. Also now everybody can easily keep track of the total score so there is no more guesswork about who won the most matches.
astro · 2022-09-11 01:29
I wrote some functions to run in dired to audition audio samples and do basic transformations on them. It was a convenient and simple way to select a bunch of sound fx out of a library, organize them, process them, etc. Other simple things: * Insert debug statements based on the symbol at point. * Insert my name, email, and timestamp at point (for commenting in code). * Email the current region to my home email or my work email.
MunsterPlop · 2022-09-11 01:45
Guix and another guess: stumpwm? :)
bagtowneast · 2022-09-11 01:59
Yes! I have similar. Unmodified, it `browse-url`s to the current line in the repo. Modified, it just copies it to the clipboard. Super handy.
tangonov · 2022-09-11 02:13
Ding ding ding!
kamui78 · 2022-09-11 03:10
Thank you very much!! I use your packages daily. They are amazing!!
FOSSbflakes · 2022-09-11 03:55
That's fun, I'd be curious to see the code if you were comfortable sharing. Or any off hand guidance to replicate it. I'm new to coding in elisp and this sounds like something good to needle with as an exercise.
CannibalismIsNatural · 2022-09-11 04:48
That's good. I fell into it on accident and now I don't want out.
plm314 · 2022-09-11 06:21
A long time ago I wrote a simple package to create named bash shells with separate saved histories and then routinely started having several dozens of named shells in each Emacs session. I then created another package to automatically split and populate a frame into a grid of windows with different buffers each. I rediscovered project.el recently and adjusted the named shell package to also work with it. I decided that in some projects I want a fixed type of split frame so I added bookmark features to the named shells. Understanding the basics of elisp and browsing/fixing the code of others is really useful and allows you to create your own livable space. Often it is a bottom up process: you encounter a micro optimization and it leads to additional improvements and ideas. This tinkering is fun on its own and the spent time pays back with dividends. If you are careful to not fall into the rabbit hole :-)
AuroraDraco · 2022-09-11 09:48
Personally I do a lot of notetaking for university, and after reading "How to take smart notes" I wanted to try the zettelkasten method. I have definitely written a bunch of elisp for this purpose to customise parts of my workflow more deeply, such as my dailies for example which are org roam nodes but can be archived from the system easily, or my capture templates. I have also written a full package to extend org roam with an idea borrowed from the aforementioned book (zetteldesk.el) and a few extensions for it, which was arguably quite a bit of lisp I wrote from scratch. I use lisp often when I need to change something or hack an idea I have in Emacs (there are definitely a lot of small snippets in my config for this purpose). So yeah, my general consensus is I have written elisp for changing behaviours I don't like or creating behaviours I want to try
Horrih · 2022-09-11 10:05
Some simple tasks i did recently - call a bash function on the current file - insert include guards in the current c++ header - save current file and apply a formatter like prettier.js or clangd. Bind this function to a shortcut - open a log file and use the built in outline-mode to be able to navigate by sections/subsections
AresAndy · 2022-09-11 11:29
Math. Like, straight simple math expressions that I evaluate in the `*scratch*` buffer. When I have no references or anything, I use `calc`, but if I'm doing things where stuff is referenced (i.e. a list of strings I want to count the elements w/o repetition) I use ELisp. In short, every time an accountant would use XLS, I would use ELisp (+ `orgmode` tables if needed) I also often override functions provided by the packages, because you can and because sometimes doing a proper fork of a package for just one procedure is too much. I've overridden for instance the default shell for M$ to powershell. For some reason it is not properly detected, nor the standard config works, so I went "f\*ck it, I'll fix it myself". Another example is to manage complex projects with Projectile, where `make` or other conventional build systems are not used. Also TAGS generation, etc... The idea, the TL;DR if you will is: use Emacs as much as possible. Eventually you will stumble on things that need fine-tuning, and then you will use and practice ELisp. Make your objective a requirement, *flow with it*
deaddyfreddy · 2022-09-11 12:04
Actually, for generic tasks not related to Emacs directly, I prefer Babashka these days, as a more modern Lisp dialect, Clojure is just more pleasant (and easy, actually) to write one-off scripts. So, the last piece of code I wrote in Elisp was a prototype of a library to simplify working with Babashka scripts.
deaddyfreddy · 2022-09-11 12:11
> save current file and apply a formatter like prettier.js or clangd. Bind this function to a shortcut https://github.com/lassik/emacs-format-all-the-code
oantolin · 2022-09-11 12:54
Thank you for the kind words!
dotancohen · 2022-09-11 14:18
This is how I learned Magento. There's nothing like real-world problems to solve.
Schievel1 · 2022-09-11 16:22
At work we are testing software for a new product. So to optimize this product we need to try different parameters, change them a bit, try again, rinse, repeat. My colleagues collect and track these defines in a excel sheet. I wrote a function in elisp, that let's me choose such a excel sheet, choose a C header file and then it changes the values of those defines automatically. And then there is the usual config hacking. Eg I have my org data on a USB drive. Windows changes those USB drive letters every now and then and I don't have admin rights to set them to something I need or to mount the USB like a directory in Linux. So I wrote a small function to change my org-directory, org agenda files, org roam directory and so on
rontan · 2022-09-11 16:29
Sure, I'll try to just read through it tomorrow to make sure it is presentable! Don't expect a masterpiece though, it was my first "real" elisp project and there's plenty of room for improvements ;) I don't have it on GitHub, so if you dm me your email I could send the file there if that's ok?
dj_goku · 2022-09-11 20:21
https://melpa.org/#/git-link Might check out this package. I have had good luck with GitHub, bitbucket and enterprise github.
drteeth80 · 2022-09-12 13:53
I just recently made a video in which I implemented an idea I had to display the contents of a note file (really just a short org file in a specific directory) in a as-small-as-possible buffer. I still consider myself pretty new to writing my own elisp and I encounter bugs and look into documentation in the video itself. It may help you learn ways to do your own coding. https://www.youtube.com/watch?v=hRjZ3NUT9JE
arthurgleckler · 2022-09-12 17:34
Back in the mid-1990s, when Python wasn't yet popular on Windows (at least in my circles), I wrote two big packages in Emacs Lisp for a start-up I worked for. One package generated Java code to implement our object model using the object-oriented database Objectivity. The official Java API for Objectivity wasn't released for another year, but we wanted to use Objectivity, so I whipped up an API in Emacs Lisp. We ended up using it in production for quite a while. The second package generated code to implement RPC over Java Object Serialization for C++ client code on Windows to match our server's Java object model. There had been a plan to use CORBA, but the implementation of that plan failed to materialize for months, so I finally jumped in and whipped together the JOS implementation. At the time, JOS's binary format had changed, and the new format hadn't yet been documented. I discovered that half-way through the implementation, and reverse-engineered the format in the process. That code generator was also used in production for some time. Both times, it seemed crazy to use Emacs Lisp for something completely unrelated to editing — for a code generator. Both times, however, the productivity that Emacs Lisp gave made it all worth it. It kept our start-up going twice when things had almost come to a standstill.
unhammer · 2022-09-12 19:50
Back in 2009 or thereabouts, I started working with Constraint Grammar, a system for disambiguating/parsing/annotating natural language. I was already using Emacs, but there wasn't any syntax highlighting for CG files, so I figured out how to do that by copying something from I forget where and tweaking it. After a while I started missing goto-definition from other prog-modes, so I made a quick hack which ended up in my cg.el. Then I noticed I kept switching to the terminal to enter input text and also the output in the terminal wasn't syntax highlighted, so why not do all that in Emacs with some handy keyboard shortcuts and then I could just click on the trace output to get back to the right rule in the grammar and oh folding would be handy for large outputs etc. etc. I think this ended up being my largest Emacs project. Emacs is now the best of the Constraint Grammar editors out there (I've tried all three!). And I'm probably the only user of cg.el :) but I've gotten so much out of it compared to the time I put into it.
Tristan401 · 2022-09-13 02:46
Mine doesn't quite work yet, but I'm loving StumpWM so far.
rswgnu · 2022-09-13 10:33
I wrote something that turns any type of cross-reference in any kind of buffer into an active hyperlink, so one key navigates links everywhere. Like Emacs, it solves general problems for people who like abstract solutions rather than many more point tools.
tangonov · 2022-09-13 17:19
As with anything it takes some getting used to. If you want a window manager that is more-or-less just a multi-threaded way to live in Emacs, it's great. If I do something stupid or a package does something unfortunate, I can still fire up a separate instance of Emacs immediately, fire up kitty, keep browsing in firefox, etc.
Tristan401 · 2022-09-13 19:36
It does take some getting used to, especially new WMs. My current issue is I'm trying to make StumpWM use the same kind of keybinds as General.el from Emacs. General lets you make keybinds like "SPC a b c d e" and you just hit each key one after another, whereas in normal Emacs you get stuff like "C-x C-d" or "C-c C-c" where you have to hit multiple keys. I want that in StumpWM.
tangonov · 2022-09-13 19:53
Sorta related but it's worth noting that `general.el` is a keybind DSL. It's just using what's already built-in to make describing your keybindings easier. I have not configured any deeply nested prefixes of my own in StumpWM yet but I am open to trying it out. There are already some prefixes that seem simple. Remember that you can get help at any stage of a key combination with the `?` key. Take for example: the default groups prefix of (`prefix g`). My prefix is `s-p` (Super p). If I go `s-p g ?` I get to see what's in that keymap. I then learn that to create a new group, I need only `s-p g c`. Same goes for the exchange map. I can `s-p x b` to swap frames back or `s-p x f` for forward. This feels terse already. But how do you do this without a general.el abstraction for Stump? The key is learning how to create and invoke a sparse keymap. This is true for both Emacs and StumpWM. The documentation describes this really well: https://stumpwm.github.io/git/stumpwm-git_2.html#Binding-Keys You can make a sparse keymap with `stumpwm:make-sparse-keymap`, assign your terse bindings to that keymap, then set up a keybind to invoke your sparse keymap on either the `*root-map*` (this is where the default prefix commands live) or the `*top-map*` which is precedes the `*root-map*`. With the `*top-map*` you could make your own "leader" keybind space.
Tristan401 · 2022-09-13 21:15
Holy crap, thanks! That's exactly what I've been needing.
Tenn1518 · 2022-09-14 20:44
Your story reminds me a lot of [this](https://www.reddit.com/r/emacs/comments/lly7po/do_you_use_emacs_lisp_as_a_general_purpose/gnvzisy/).
github-alphapapa · 2022-09-16 02:12
That sounds like it could make a good blog post.
AliensReleasedMe · 2022-09-16 16:46
Very unique and cool usage environment!