reddit / emacs

Weekly Tips, Tricks, &c. Thread

AutoModerator · 2022-04-13 08:15
This is a thread for smaller, miscellaneous items that might not warrant a full post on their own. [See this search for previous "Weekly Tips, Tricks, &c." Threads.](https://www.reddit.com/r/emacs/search?q=Weekly+tips&restrict_sr=on&sort=new&t=all) Don't feel constrained in regards to what you post, just keep your post vaguely, generally on the topic of emacs.
recencyeffect · 2022-04-13 12:31
Working on a project that has two programs running in parallel on a remote host, I figured I can start two tunnels on the remote host and connect two slimes. It works so beautifully! ``` lisp (defun start-tunnels () (interactive) (start-process "tunnel-internal" "*tunnel-internal*" "ssh" "-v" "-L" "4005:127.0.0.1:4005" "example.com") (switch-to-buffer "*tunnel-internal*") (comint-mode) (comint-simple-send "*tunnel-internal*" "sbcl --load ~/start-swank.lisp 4005") (start-process "tunnel-external" "*tunnel-external*" "ssh" "-v" "-L" "4006:127.0.0.1:4006" "example.com") (switch-to-buffer "*tunnel-external*") (comint-mode) (comint-simple-send "*tunnel-external*" "sbcl --load ~/start-swank.lisp 4006")) (defun connect-slime () (interactive) (progn (let ((conn (slime-net-connect "127.0.0.1" 4005))) (setf (slime-connection-name conn) "connection-internal") (slime-init-output-buffer conn)) (let ((conn (slime-net-connect "127.0.0.1" 4006))) (setf (slime-connection-name conn) "connection-external") (slime-init-output-buffer conn)))) ```
AffectionateAd8985 · 2022-04-14 01:36
```elisp (defun dired-dim-git-ignores () "Dim out .gitignore contents" (when-let ((_ (require 'vc)) (ignores (vc-default-ignore-completion-table 'git ".gitignore")) (exts (make-local-variable 'completion-ignored-extensions))) (dolist (item ignores) (add-to-list exts item)))) (add-hook 'dired-mode-hook #'dired-dim-git-ignores) ``` Show git ignored files in `dired-ignored` face. I thought this should be a builtin functionality, but I couldn't find it, so wrote this piece of code (folder/glob not handled)
paretoOptimalDev · 2022-04-14 01:46
Nice! You can also use autossh for this if you need them up all the time.
recencyeffect · 2022-04-14 07:28
Oooh thanks I did not know that. I don't want them on all the time, but it would be nice to have a better interface to manage them. There *is* a package `ssh-tunnels`, but it did nothing when I tried it. Perhaps I'll go back and fix it at some point.
Phil-Hudson · 2022-04-14 12:02
Sounds like a good idea, and I was just about to copy to my init when I thought, hang on, isn't there a slight difference in meaning between the documented purpose of `dired-ignore-face` and this? And if so, is it important/relevant/meaningful enough to warrant a separate face, maybe one that just inherits from `dired-ignored-face`? Maybe life's too short, I don't know.
Phil-Hudson · 2022-04-14 12:08
What a hugely educational seven LOC! I'm astonished and ashamed to discover `when-let`/`if-let`/etc. How did I not know about these?! RTFMing, would you agree that (when-let ((_ (require 'vc)) ... could/should be written: (when-let ((require 'vc nil t) ... That is, a) preventing throwing an error and b) using the `if-let` ability to simply test a plain value for `nil` without assigning that value to anything.
Phil-Hudson · 2022-04-14 12:15
Next TIL from this (I guess they appear in reverse order on this page): `vc-default-ignore-completion-table` is another interesting find, not such a big deal but still useful, except... AFAICT it only works with git! Using `locate` I tracked down some `.bzrignore` (Bazaar/Breezy) and `.hgignore` (Mercurial) files, and I get `nil` as output from both. No error using `'bzr` and `'hg` respectively, whereas I get errors when using `'bazaar` and `'mercurial`, so it looks like `vc` *thinks* it knows how to deal with these ignore files... but it doesn't!
defenestre · 2022-04-14 13:03
Has anyone figured out how to get global evil markers to persist across emacs sessions? It seems like this has been an unsolved problem for a very long time, and the following solutions don't seem to work (nor does using desktop-save-mode/sessions on `evil-markers-alist`): * https://emacs.stackexchange.com/questions/9374/how-to-persist-evil-markers * http://blog.binchen.org/posts/enhance-emacs-evil-global-markers/
[deleted] · 2022-04-14 14:42
[deleted]
[deleted] · 2022-04-14 15:10
[deleted]
pwnedary · 2022-04-14 15:21
Ah, yes sorry. Tired eyes and miscounted the parentheses since it is a single line when reading on old reddit.
nicholas_hubbard · 2022-04-14 17:09
I created a package [reckmac.el](https://github.com/NicholasBHubbard/reckmac.el) that allows you to define recursive keyboard macros. By default in emacs you cannot call another kbd macro while you are currently defining a macro unless you already named that macro. Reckmac solves this problem. Reckmac allows you (forces you) to store your kbd macros in registers denoted by a single character just like in vim. When you are recording a macro you can then call `reckmac-execute-macro` to execute a previously defined macro and it will be inserted into the current macro. I have been using this package for a few weeks now and it works great but I am going to hold off on making a dedicated reddit post about reckmac until I am more sure there aren't any bugs. Whoever wrote the kbd macro functionality never intended for this to be possible so it took a bit of hackery to get it work so it is actually kind of complex. Let me know what you think!
tryptych · 2022-04-15 01:05
What an awesome snippet, thanks! I don't think `completion-ignored-extensions` handles anything other than suffixes, does it? (the first directory I tested it on had mostly absolutely-pathed patterns, eg "/eln-cache")
AffectionateAd8985 · 2022-04-15 02:03
vc is a builtin package, it's always there, actually `(require 'vc)` before `when-let` is all right
AffectionateAd8985 · 2022-04-15 02:08
You're right, `extensions` just means file suffix, folders (like `__pycache__/`) and glob patterns (like `data.*.gz`) are not handled
Phil-Hudson · 2022-04-15 03:37
True enough, that both covers a) and makes b) irrelevant in this particular case. For the general case I was addressing in b), though, I've just checked in IELM and it looks to me like the assignment to `_` for an unused value in `when-let` is indeed unnecessary, as documented. A tiny point, but I like to get everything straight if I can, just for my own understanding.
konrad1977 · 2022-04-15 07:56
Do you know if we could get projectile to hide those files as well? (like when finding file, etc)?
shaqfooVA · 2022-04-15 14:03
If I have a region highlighted, and insert a left parenthesis "(", the cursor moves to the right of the inserted left paren. I normally use the left paren on a region, though, in order to have that region's symbol called in a function, so I want to start typing to the left of the inserted parent. start (pipe is cursor position): REGION_TEXT| after pressing "(": (|REGION_TEXT) desired after pressing "(": |(REGION_TEXT) I'm using electric pair mode, i've tried smartparens but it just never works that well for me. Dumbparens didn't work that well out of the box, either, and is less customizable
justlearn2code · 2022-04-16 01:46
I'm coming here completely new to both emacs and programming. I recently installed portacle for coding in common lisp. ​ Obviously there's a ton of stuff I can learn about emacs but I wanted to ask a question that's less a question of the documentation: what should my emacs workflow look like doing basic lisp programming from my intro class? ​ I know one answer is "however you want" but I don't know anything so I'm looking for an experienced suggestion until I understand what I would want. If I'm going in blind there's no reason to learn bad habits, right? I just don't know what the right workflow habits are. ​ I read about using the REPL but I'm assuming I don't want to actually be writing code in the REPL? How I set it up is a .lisp file in one window where I write the code and then I send it to REPL in the other buffer window I have open. Does this make sense for now? [https://i.imgur.com/q4JdvH5.png](https://i.imgur.com/q4JdvH5.png) ​ I still don't understand when I want to compile, etc. so I'm just faking it for now. Was just going to start doing some exercises and testing functions in the REPL after I try to write them out. That's about all I got.
bhrgunatha · 2022-04-16 06:33
This is so trivial, but I keep forgetting the name `flush-lines` for something I do quite often. `(defalias 'remove-lines #'flush-lines)` For me the name `remove-lines` complements `keep-lines` so much better. The nice thing is that using `defalias` means that all the introspection available to emacs also works so `C-h f` `M-x` etc are all aware of it too. Sometimes it's the little things.
Phil-Hudson · 2022-04-16 09:09
Maybe bind `(` to your own function which first calls whatever you currently have it bound to then calls `(backward-char)`?
Phil-Hudson · 2022-04-16 09:13
Love to help, but this question seems too general and vague. More targeted and specific questions get better answers. WRT the REPL, yes, use it for exploratory, iterative, incremental development. As and when you hammer each function/form into the shape you want, copy it into a file.
Phil-Hudson · 2022-04-16 09:19
This precise issue was recognized quite a long time ago by the dev team. The workaround they offer is `(defalias 'delete-matching-lines 'flush-lines)`, defined in file "replace.el".
bhrgunatha · 2022-04-17 06:02
I wasn't aware of that, thanks. `delete-matching-lines` and `delete-non-matching-lines` are definitely more rational names.
AffectionateAd8985 · 2022-04-18 01:12
Not a projectile user. AFAIK project.el is not deeply coupled with dired.
lafrenierejm · 2022-04-18 01:36
Just published a small package with some helpers I use for operating on the current buffer: https://github.com/lafrenierejm/current-buffer.el
crawsphi · 2022-04-18 17:13
Some of this might be built in now; Emacs 28 added a "buffer" keymap under `C-x x`. For example `C-x x g` is `revert-buffer`.
karouh · 2022-04-18 19:55
Is it possible to apply a command on the current buffer?
lafrenierejm · 2022-04-18 22:28
Not sure I understand what you’re asking. Can you give an example of the sort of thing you’re wanting to do?
_noctuid · 2022-04-19 02:17
Yeah, desktop.el will only work for local markers. AFAIK, no one has done anything to support global markers. See here: https://github.com/emacs-evil/evil/issues/674
karouh · 2022-04-19 02:56
I mean, I want to prettify the contents of the buffer using an external tool such as pretty.
lafrenierejm · 2022-04-19 04:22
For formatting specifically, I’d highly recommend https://github.com/purcell/emacs-reformatter.
karouh · 2022-04-19 06:12
https://github.com/bard/emacs-run-command is what I was looking for
PuercoPop · 2022-04-19 13:37
> How I set it up is a .lisp file in one window where I write the code and then I send it to REPL in the other buffer window I have open I normally use either C-c C-c to compile the expression at point or C-c C-k to compile the entire file. You can read the evaluation and compilation commands in Slime manual. https://slime.common-lisp.dev/doc/html/Evaluation.html#Evaluation You start a lisp REPL by calling M-x slime iirc (I use sly).
crawsphi · 2022-04-19 17:24
In general you can use `shell-command-on-region` after marking all the text. 1. `C-x h` (`mark-whole-buffer`) 2. `C-u M-|` (`shell-command-on-region` with prefix arg meaning "replace") 3. Input the command to run 4. Done There might be a package for the specific thing you want, though.