diff --git a/bin/run.py b/bin/run.py index b30ac6b..a3f30a7 100644 --- a/bin/run.py +++ b/bin/run.py @@ -1,5 +1,5 @@ """ -Usage: python3 bin/run.py [--all] +Usage: python3 bin/run.py [--all] [--skip-pushing] """ import sys, itertools, json, logging, os, datetime @@ -111,8 +111,8 @@ def persisted_posts(): return json.load(f) -def main(): - all_posts = "--all" in sys.argv +def run(all_posts, skip_pushing): + LOGGER.info("Fetching posts...") fetched_posts = get_posts(all_posts) LOGGER.info("Found %d applicable posts", len(fetched_posts)) existing_posts = persisted_posts() @@ -127,9 +127,17 @@ def main(): with open(OUT, "w") as f: f.write(s) - if new_posts > 0: + if skip_pushing: + LOGGER.info("Skipping pushing to git repo") + elif new_posts > 0: LOGGER.info("Pushing to git repo...") update_git_repo() LOGGER.info("Done") else: LOGGER.info("Not pushing to git repo since no new posts were found") + + +def main(): + all_posts = "--all" in sys.argv + skip_pushing = "--skip-pushing" in sys.argv + run(all_posts, skip_pushing) diff --git a/out.md b/out.md index 46d428b..bdaa77b 100644 --- a/out.md +++ b/out.md @@ -5,28 +5,28 @@ Do you think it might be good to make this a little less frequently refreshed? T I think monthly would be better, given the modest size of this subreddit. -## u/celeritasCelery [πŸ”—](https://www.reddit.com/r/emacs/comments/gienra/comment/fqe6yop) +## u/gausby [πŸ”—](https://www.reddit.com/r/emacs/comments/e5dzv6/comment/f9jp341) **Votes:** 36 +Shouldn't it be `/etc/tips/trick` ? + +(…I'll show myself out) + +## u/celeritasCelery [πŸ”—](https://www.reddit.com/r/emacs/comments/gienra/comment/fqe6yop) +**Votes:** 34 + > I had received the advice to not install anything and just start with plain emacs so I can learn emacs. ... it was miserable. > Enter Doom Emacs. I decided to give Doom Emacs a try because it was also highly recommended in my initial RFC, especially since it is designed for Vim users. In short I love it. This is why I disagree with the subreddits de facto advice to β€œlearn vanilla first”. People who have used emacs for a long time don’t realize how much **time** it takes to get it to level of a normal modern editor people are used to. I recommend distros to *everyone* who is new unless they are that certain personality type that wants to do everything themselves. ## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/10qo7vb/comment/j6rmvvf) -**Votes:** 35 +**Votes:** 33 When you have an active region, `undo` will only undo changes in that region instead of the whole file. -## u/gausby [πŸ”—](https://www.reddit.com/r/emacs/comments/e5dzv6/comment/f9jp341) -**Votes:** 34 - -Shouldn't it be `/etc/tips/trick` ? - -(…I'll show myself out) - ## u/zupatol [πŸ”—](https://www.reddit.com/r/emacs/comments/xdw6ok/comment/iodig8c) -**Votes:** 30 +**Votes:** 28 After years of using emacs, I wrote my second ever elisp function to open on github the code I'm browsing in emacs. @@ -55,18 +55,23 @@ After years of using emacs, I wrote my second ever elisp function to open on git ``` ## u/unbelievable_sc2 [πŸ”—](https://www.reddit.com/r/emacs/comments/dyhkcd/comment/f81dslh) -**Votes:** 29 +**Votes:** 27 I often use the compile feature to compile and run my projects to see the results in the compilation buffer. This works well unless you are waiting for user input in your terminal. I recently found out that you can invoke the compile with an additional non nil value to start compilation in comint-mode which allows for user input! The drawback is, that you then no longer can press q to close the window or g to recompile. Because of that I added a simple lambda, that switches to compilation-mode to the compilation-finish-functions. So I can give input while compiling and running, and after compilation I can close the window as usual with q. ## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/txh85s/comment/i3m1liu) -**Votes:** 24 +**Votes:** 26 [removed] +## u/howardthegeek [πŸ”—](https://www.reddit.com/r/emacs/comments/xdw6ok/comment/ioeh1ly) +**Votes:** 21 + +I just learned that in eshell, $$ is replaced with the output from the last command. + ## u/Gangsir [πŸ”—](https://www.reddit.com/r/emacs/comments/pxqvtm/comment/hepqmq1) -**Votes:** 23 +**Votes:** 21 back-to-indentation. Before I found this function I would always do some awkward triple key combo like C-a M-f M-b. @@ -76,16 +81,6 @@ It still works even on lines that aren't indented, same as C-a in that case. So useful, especially for resetting point during macros that need to start at the first char on the line. -## u/howardthegeek [πŸ”—](https://www.reddit.com/r/emacs/comments/xdw6ok/comment/ioeh1ly) -**Votes:** 22 - -I just learned that in eshell, $$ is replaced with the output from the last command. - -## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/112t0uo/comment/j8m9rlj) -**Votes:** 20 - -With an active region, you can freely toggle between rectangle mark mode and normal, you don't need to get rid of your active region to switch between the two. - ## u/AndreaSomePostfix [πŸ”—](https://www.reddit.com/r/emacs/comments/12cd23k/comment/jf167qh) **Votes:** 19 @@ -95,37 +90,13 @@ I discovered \`org-copy-visible\` the other day, when I wanted to send somebody That function (which is bound to C-c C-x v by default) let you copy just the outline for the selected region: very useful! -## u/thehaas [πŸ”—](https://www.reddit.com/r/emacs/comments/e5dzv6/comment/f9k6yyf) +## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/112t0uo/comment/j8m9rlj) **Votes:** 19 -After using Emacs for maybe 10 years I finally started using registers and I really should have started earlier. For those who don't know: - -​ - -* Highlight text and C-x r s to save to register -* C-x r i to put the contents of the register at the cursor point. The text is still there -- use it over and over again - -It seems like quite a few keystrokes but it's really not. Of course you can re-assign them to other keys if you don't like the defaults. - -## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/12rlq4a/comment/jgwlxuw) -**Votes:** 18 - -Often when literate programming I want to split up a code block, maybe copy-pasted with multiple functions in it, into separate blocks so I can put some text in between them. The command, with cursor within a `BEGIN_SRC` block, is `org-babel-demarcate-block` `(C-c C-v d)`. - -## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/x27yc9/comment/imi3kzz) -**Votes:** 18 - -Update from a couple of weeks ago: after some grinding, I've set the parsing of past comments from this thread to auto update on a weekly basis here: [https://github.com/LaurenceWarne/reddit-emacs-tips-n-tricks/blob/master/out.md](https://github.com/LaurenceWarne/reddit-emacs-tips-n-tricks/blob/master/out.md) - -I've also fixed the broken highlighting of some code snippets, and hopefully parsed all past threads. There's 200+ comments there (sorted by upvotes), so ctrl-f ing e.g. \`magit\` may help you if you're looking for something specific - -## u/tryptych [πŸ”—](https://www.reddit.com/r/emacs/comments/v2by7z/comment/iauyzbl) -**Votes:** 18 - -It's not worth a separate post, but after spending some pleasant yak-shaving time optimising my startup using use-package, I wrote a [post about it](https://blog.markhepburn.com/posts/understanding-use-package-optimisations/). There's a few posts around suggesting features of `use-package` to optimise startup, but none of them really explained how they tied back to `autoload`, `eval-after-load`, etc so I was trying to encourage people to dig out `macroexpand` and find out. +With an active region, you can freely toggle between rectangle mark mode and normal, you don't need to get rid of your active region to switch between the two. ## u/TeMPOraL_PL [πŸ”—](https://www.reddit.com/r/emacs/comments/txh85s/comment/i3ov7vq) -**Votes:** 18 +**Votes:** 19 `shortdoc` - one of the new things in Emacs 28.1 - is great for maintaining your own "cheat sheets" of Elisp functions as you discover them. For example, eval this in your Emacs session: @@ -154,37 +125,25 @@ After this, the `my-datetime` group will show as an option in `M-x shortdoc-disp The example used here is a cheatsheet I just started writing for myself, as I've been researching the built-in time functions. For additional instructions on use, see `define-short-documentation-group` macro. For use examples, jump to the source of `define-short-documentation-group` and scroll down a bit - the default shortdoc groups are defined there. -## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/1758wua/comment/k4g09iw) -**Votes:** 17 - -`(delete-blank-lines)` `(C-x C-o)` is massively useful; I use it every day for text cleanup. Press it once and it deletes all but one blank line. Press it twice and it deletes that one, too. - -## u/alvarogonzalezs [πŸ”—](https://www.reddit.com/r/emacs/comments/12jexep/comment/jg34ody) -**Votes:** 17 - -I'm a big user of `ffap`. I use this function with `M-x` each time I want to open a file whose name is under the cursor. +## u/thehaas [πŸ”—](https://www.reddit.com/r/emacs/comments/e5dzv6/comment/f9k6yyf) +**Votes:** 19 -But this week I discovered `ffap-bindings`. This function replaces some key bindings to use `ffap` when it makes sense. For example, it replaces `find-file` with `find-file-at-point`, so the usual keybindings are enriched at no cost. +After using Emacs for maybe 10 years I finally started using registers and I really should have started earlier. For those who don't know: -## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/vnals8/comment/ie7p6ja) -**Votes:** 17 +​ -I recently discovered `thing-at-point-looking-at`, which seems much easier to use on its own than to fully define a new kind of "thing." +* Highlight text and C-x r s to save to register +* C-x r i to put the contents of the register at the cursor point. The text is still there -- use it over and over again -For a while I've been wanting to conveniently identify a Jira ticket identifier at point so I can browse to it. Ticket IDs are basically a sequence of letters, a hyphen, and a sequence of digits. First I tried using `symbol-at-point`, but that can include extraneous neighboring characters, like `/` when the ticket ID is part of a URL. Eventually, while poring over the `thingatpt` source, I found `thing-at-point-looking-at`, which quickly led to: +It seems like quite a few keystrokes but it's really not. Of course you can re-assign them to other keys if you don't like the defaults. -```elisp -(defun browse-ticket-at-point () - (interactive) - (if (thing-at-point-looking-at (rx (+ alpha) "-" (+ digit))) - (browse-url (format "https://jirahost/browse/%s" (match-string 0))) - (error "No ticket at point"))) +## u/tryptych [πŸ”—](https://www.reddit.com/r/emacs/comments/v2by7z/comment/iauyzbl) +**Votes:** 18 -``` -Easy peasy! +It's not worth a separate post, but after spending some pleasant yak-shaving time optimising my startup using use-package, I wrote a [post about it](https://blog.markhepburn.com/posts/understanding-use-package-optimisations/). There's a few posts around suggesting features of `use-package` to optimise startup, but none of them really explained how they tied back to `autoload`, `eval-after-load`, etc so I was trying to encourage people to dig out `macroexpand` and find out. ## u/SamTheComputerSlayer [πŸ”—](https://www.reddit.com/r/emacs/comments/sijcap/comment/hvbbnjq) -**Votes:** 17 +**Votes:** 18 Just figured this out, maybe a bit of a hack... @@ -192,30 +151,13 @@ In flyspell, I was annoyed I had to use mouse-2 when I wanted to correct a word, But the fact you can attach keymaps to overlays just seems so useful, will definitely use in the future. -## u/AffectionateAd8985 [πŸ”—](https://www.reddit.com/r/emacs/comments/sd10q9/comment/hu9xfed) -**Votes:** 17 - -`(add-hook 'org-mode-hook (lambda () (org-next-visible-heading 1)))` - -Move to first heading when open org files, with `org-use-speed-commands`, I can quick browse org file with only `n/p` keys. - -## u/TeMPOraL_PL [πŸ”—](https://www.reddit.com/r/emacs/comments/rbmfwk/comment/hnx4z28) -**Votes:** 17 - -If you're like me, and your day ends way past midnight, handling those last few tasks in your Org Mode agenda gets tricky. Fortunately, it turns out Org Mode has what I call "25th hour mode". - -```elisp -;; consider the current day to end at 3AM -(setq org-extend-today-until 3) - -;; make timestamp processing functions aware of this -(setq org-use-effective-time t) +## u/github-alphapapa [πŸ”—](https://www.reddit.com/r/emacs/comments/p6mwx2/comment/h9e6uqq) +**Votes:** 18 -``` -Combined, this allows to extend the day past midnight, with things like agenda views, scheduling commands, repeaters, etc. thinking the current time is 23:59 up until the `org-extend-today-until` limit. With this enabled, if I have a task that has a repeater of and complete it at 01:00, I no longer have to then manually reschedule the task back one day. +Here's a popular Emacs config I just rediscovered. Some cool stuff here. https://github.com/angrybacon/dotemacs ## u/oantolin [πŸ”—](https://www.reddit.com/r/emacs/comments/o68i0v/comment/h2rizey) -**Votes:** 17 +**Votes:** 18 I have two org mode link tips: @@ -261,31 +203,59 @@ I have two org mode link tips: (add-hook 'org-mode-hook #'echo-area-tooltips) ``` -## u/gopar [πŸ”—](https://www.reddit.com/r/emacs/comments/k4gv0x/comment/ge9det9) +## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/12rlq4a/comment/jgwlxuw) **Votes:** 17 -A very simple thing I've done is remap ";" (semicolon) to to "\_" (underscore) in almost all modes. Since I work with mainly Python, this is so much easier than always doing SHIFT-DASH every couple of keystrokes. And if I want a regular semicolon, I just do "C-u ;" and insert a semicolon +Often when literate programming I want to split up a code block, maybe copy-pasted with multiple functions in it, into separate blocks so I can put some text in between them. The command, with cursor within a `BEGIN_SRC` block, is `org-babel-demarcate-block` `(C-c C-v d)`. -I also set this in modes such as C/C++, etc. This works by automatically setting the last character (if it was an underscore) to a semicolon on enter. +## u/alvarogonzalezs [πŸ”—](https://www.reddit.com/r/emacs/comments/12jexep/comment/jg34ody) +**Votes:** 17 -eg. "|" is cursor +I'm a big user of `ffap`. I use this function with `M-x` each time I want to open a file whose name is under the cursor. -int a = 10\*10\_| +But this week I discovered `ffap-bindings`. This function replaces some key bindings to use `ffap` when it makes sense. For example, it replaces `find-file` with `find-file-at-point`, so the usual keybindings are enriched at no cost. -turns into +## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/x27yc9/comment/imi3kzz) +**Votes:** 17 -int a = 10\*10; +Update from a couple of weeks ago: after some grinding, I've set the parsing of past comments from this thread to auto update on a weekly basis here: [https://github.com/LaurenceWarne/reddit-emacs-tips-n-tricks/blob/master/out.md](https://github.com/LaurenceWarne/reddit-emacs-tips-n-tricks/blob/master/out.md) -| (cursor on new line) +I've also fixed the broken highlighting of some code snippets, and hopefully parsed all past threads. There's 200+ comments there (sorted by upvotes), so ctrl-f ing e.g. \`magit\` may help you if you're looking for something specific -​ +## u/pathemata [πŸ”—](https://www.reddit.com/r/emacs/comments/un4wf8/comment/i86hwzi) +**Votes:** 17 -Pretty simple time saver \\o/ +Something amazin that I have been using recently is `ripgrep-all` as the `consult-ripgrep` command to search in pdfs. -## u/TheDrownedKraken [πŸ”—](https://www.reddit.com/r/emacs/comments/jn6m14/comment/gazzdyz) +It is amazing with the `orderless` dispatchers to control the search filtering. +I use `!` to exclude a string and `=` to match exactly. + +Also amazing with `embark-collect` which allows collapsing features. +Or within the collect buffer use `consult-line` to further filter. +And even open the pdf. + +## u/AffectionateAd8985 [πŸ”—](https://www.reddit.com/r/emacs/comments/sd10q9/comment/hu9xfed) **Votes:** 17 -It would be good to archive the questions and tips put in here. I feel like I always find cool stuff in here, but then it becomes very hard to find it later. +`(add-hook 'org-mode-hook (lambda () (org-next-visible-heading 1)))` + +Move to first heading when open org files, with `org-use-speed-commands`, I can quick browse org file with only `n/p` keys. + +## u/laralex [πŸ”—](https://www.reddit.com/r/emacs/comments/domrl6/comment/f5pgfu3) +**Votes:** 17 + +A small basic thing, but once I'd discovered it, I started using dired. +```C-x C-j``` is most likely bound to ```dired-jump```, and this function opens dired for this window's file, without promting for directory (and this prompt was an issue for my workflow when using ```C-x d```). That makes finding and switching files just as convenient as in OS GUI. I've also bound a few keys when in dired mode (I find them decent): + +```a``` - prompt a name and create empty file + +```d``` - prompt a name and create empty dir + +```u``` - go to parent dir (the key is a mnemonic to "go Up in directory tree) + +```j``` - if it's a dir go into it, otherwise find this file (key is near to 'u' so jumping up and down is not a big deal with one hand, also the 'j' is the easiest key for me as a touchtyper) + +```n```/```p``` - move one entry down/up, which resembles ```C-n```/```C-p``` ## u/vkazanov [πŸ”—](https://www.reddit.com/r/emacs/comments/1bdm6mc/comment/kuo1f9y) **Votes:** 16 @@ -304,50 +274,80 @@ A dump of my Emacs-related principles after 18 years of tinkering: I am a beginner though, things might change. -## u/slinchisl [πŸ”—](https://www.reddit.com/r/emacs/comments/xw4muy/comment/ir96qmu) +## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/1758wua/comment/k4g09iw) **Votes:** 16 -I finally got around to writing a small README for my Emacs config, highlighting some homegrown parts that I really like. I reckon most of these things are pretty standard, but maybe some people here still find it useful: - - https://gitlab.com/slotThe/dotfiles/-/tree/master/emacs/.config/emacs +`(delete-blank-lines)` `(C-x C-o)` is massively useful; I use it every day for text cleanup. Press it once and it deletes all but one blank line. Press it twice and it deletes that one, too. -## u/pathemata [πŸ”—](https://www.reddit.com/r/emacs/comments/un4wf8/comment/i86hwzi) +## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/vnals8/comment/ie7p6ja) **Votes:** 16 -Something amazin that I have been using recently is `ripgrep-all` as the `consult-ripgrep` command to search in pdfs. +I recently discovered `thing-at-point-looking-at`, which seems much easier to use on its own than to fully define a new kind of "thing." -It is amazing with the `orderless` dispatchers to control the search filtering. -I use `!` to exclude a string and `=` to match exactly. +For a while I've been wanting to conveniently identify a Jira ticket identifier at point so I can browse to it. Ticket IDs are basically a sequence of letters, a hyphen, and a sequence of digits. First I tried using `symbol-at-point`, but that can include extraneous neighboring characters, like `/` when the ticket ID is part of a URL. Eventually, while poring over the `thingatpt` source, I found `thing-at-point-looking-at`, which quickly led to: -Also amazing with `embark-collect` which allows collapsing features. -Or within the collect buffer use `consult-line` to further filter. -And even open the pdf. +```elisp +(defun browse-ticket-at-point () + (interactive) + (if (thing-at-point-looking-at (rx (+ alpha) "-" (+ digit))) + (browse-url (format "https://jirahost/browse/%s" (match-string 0))) + (error "No ticket at point"))) -## u/github-alphapapa [πŸ”—](https://www.reddit.com/r/emacs/comments/p6mwx2/comment/h9e6uqq) +``` +Easy peasy! + +## u/hxlr666 [πŸ”—](https://www.reddit.com/r/emacs/comments/rvagin/comment/hr4bbl5) **Votes:** 16 -Here's a popular Emacs config I just rediscovered. Some cool stuff here. https://github.com/angrybacon/dotemacs +Use org capture -## u/freesteph [πŸ”—](https://www.reddit.com/r/emacs/comments/eoigxl/comment/fed40nx) +## u/TeMPOraL_PL [πŸ”—](https://www.reddit.com/r/emacs/comments/rbmfwk/comment/hnx4z28) **Votes:** 16 -If you needed more reasons to love Magit I've just found out can add the Git meta-fields in the commit message (`Co-authored-by`, `Signed-off-by`, etc, which I can never remember correctly) by typing `C-c TAB` which will interactively ask you for the field (`C-a` -> `Co-authored-by`) and then also interactively fill the relevant team member with their name and e-mail (probably from the repo's list of committers). Awesome! +If you're like me, and your day ends way past midnight, handling those last few tasks in your Org Mode agenda gets tricky. Fortunately, it turns out Org Mode has what I call "25th hour mode". -## u/laralex [πŸ”—](https://www.reddit.com/r/emacs/comments/domrl6/comment/f5pgfu3) +```elisp +;; consider the current day to end at 3AM +(setq org-extend-today-until 3) + +;; make timestamp processing functions aware of this +(setq org-use-effective-time t) + +``` +Combined, this allows to extend the day past midnight, with things like agenda views, scheduling commands, repeaters, etc. thinking the current time is 23:59 up until the `org-extend-today-until` limit. With this enabled, if I have a task that has a repeater of and complete it at 01:00, I no longer have to then manually reschedule the task back one day. + +## u/gopar [πŸ”—](https://www.reddit.com/r/emacs/comments/k4gv0x/comment/ge9det9) **Votes:** 16 -A small basic thing, but once I'd discovered it, I started using dired. -```C-x C-j``` is most likely bound to ```dired-jump```, and this function opens dired for this window's file, without promting for directory (and this prompt was an issue for my workflow when using ```C-x d```). That makes finding and switching files just as convenient as in OS GUI. I've also bound a few keys when in dired mode (I find them decent): +A very simple thing I've done is remap ";" (semicolon) to to "\_" (underscore) in almost all modes. Since I work with mainly Python, this is so much easier than always doing SHIFT-DASH every couple of keystrokes. And if I want a regular semicolon, I just do "C-u ;" and insert a semicolon -```a``` - prompt a name and create empty file +I also set this in modes such as C/C++, etc. This works by automatically setting the last character (if it was an underscore) to a semicolon on enter. -```d``` - prompt a name and create empty dir +eg. "|" is cursor -```u``` - go to parent dir (the key is a mnemonic to "go Up in directory tree) +int a = 10\*10\_| -```j``` - if it's a dir go into it, otherwise find this file (key is near to 'u' so jumping up and down is not a big deal with one hand, also the 'j' is the easiest key for me as a touchtyper) +turns into -```n```/```p``` - move one entry down/up, which resembles ```C-n```/```C-p``` +int a = 10\*10; + +| (cursor on new line) + +​ + +Pretty simple time saver \\o/ + +## u/TheDrownedKraken [πŸ”—](https://www.reddit.com/r/emacs/comments/jn6m14/comment/gazzdyz) +**Votes:** 16 + +It would be good to archive the questions and tips put in here. I feel like I always find cool stuff in here, but then it becomes very hard to find it later. + +## u/slinchisl [πŸ”—](https://www.reddit.com/r/emacs/comments/xw4muy/comment/ir96qmu) +**Votes:** 15 + +I finally got around to writing a small README for my Emacs config, highlighting some homegrown parts that I really like. I reckon most of these things are pretty standard, but maybe some people here still find it useful: + + https://gitlab.com/slotThe/dotfiles/-/tree/master/emacs/.config/emacs ## u/meain [πŸ”—](https://www.reddit.com/r/emacs/comments/wwdpju/comment/ilotsc5) **Votes:** 15 @@ -362,42 +362,16 @@ I use the following snippet to change background color of compilation buffer to (add-to-list 'compilation-finish-functions 'meain/compilation-colorcode) ``` -## u/hxlr666 [πŸ”—](https://www.reddit.com/r/emacs/comments/rvagin/comment/hr4bbl5) +## u/rucci99 [πŸ”—](https://www.reddit.com/r/emacs/comments/r69w7i/comment/hmryv5o) **Votes:** 15 -Use org capture +I just found out that Magit can backup changes of uncommitted files automatically. Here's the link to online manual: +[Magit Wip Modes](https://magit.vc/manual/magit/Wip-Modes.html#Wip-Modes). -## u/el_tuxo [πŸ”—](https://www.reddit.com/r/emacs/comments/rbmfwk/comment/hnp5rhn) +## u/globalcandyamnesia [πŸ”—](https://www.reddit.com/r/emacs/comments/ooldn6/comment/h67qge6) **Votes:** 15 -Working on a remote server with Tramp in eshell it's so easy that I'm always worried that I could run by mistake a command on the wrong machine. - -So I implemented a small function that makes me aware that I'm in a Tramp session by changing the prompt color. - -```elisp -(require 'subr-x) -(defun tuxo/prompt-color-tramp () -"Change prompt color if a tramp session is open" - (if (file-remote-p default-directory) - (set-face-foreground 'eshell-prompt "red") - (set-face-foreground 'eshell-prompt "green"))) - -(use-package eshell - :hook (eshell-post-command . tuxo/prompt-color-tramp)) - -``` -Do you have any suggestions on how I could improve this issue? - -## u/rucci99 [πŸ”—](https://www.reddit.com/r/emacs/comments/r69w7i/comment/hmryv5o) -**Votes:** 15 - -I just found out that Magit can backup changes of uncommitted files automatically. Here's the link to online manual: -[Magit Wip Modes](https://magit.vc/manual/magit/Wip-Modes.html#Wip-Modes). - -## u/globalcandyamnesia [πŸ”—](https://www.reddit.com/r/emacs/comments/ooldn6/comment/h67qge6) -**Votes:** 15 - -I'm trying to feminize my voice and org mode has been invaluable. +I'm trying to feminize my voice and org mode has been invaluable. ```elisp (org-babel-do-load-languages 'org-babel-load-lanuages @@ -423,6 +397,16 @@ I'm trying to feminize my voice and org mode has been invaluable. ``` This requires 'SoX' for linux. You can go into the record src block and press \`C-c C-c\` to start recording and \`C-g\` to end. To play back the recording, press \`C-c C-c\` within the play src block. I imagine this might be useful beyond the trans community for basic voice journaling. +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/hqxm5v/comment/fy1rq34) +**Votes:** 15 + +Migrated to native compiled emacs branch this week. Some hiccups but everything seems to work out of box, including pdf-tools. Great performance improvement. + +## u/freesteph [πŸ”—](https://www.reddit.com/r/emacs/comments/eoigxl/comment/fed40nx) +**Votes:** 15 + +If you needed more reasons to love Magit I've just found out can add the Git meta-fields in the commit message (`Co-authored-by`, `Signed-off-by`, etc, which I can never remember correctly) by typing `C-c TAB` which will interactively ask you for the field (`C-a` -> `Co-authored-by`) and then also interactively fill the relevant team member with their name and e-mail (probably from the repo's list of committers). Awesome! + ## u/agumonkey [πŸ”—](https://www.reddit.com/r/emacs/comments/y7wrdn/comment/isze25m) **Votes:** 14 @@ -434,54 +418,6 @@ hope you enjoy it warning: poop emoji -## u/com4 [πŸ”—](https://www.reddit.com/r/emacs/comments/xq6rpa/comment/iqb2fci) -**Votes:** 14 - -In preparation for the inclusion of eglot into Emacs core I've switched away from lsp-mode. As a result I've also switched from flycheck and to flymake. One nice thing about flycheck is that it allowed for stacking checkers. When coding Python I liked to stack flake8 for styles and mypy for types (plus the LSP's since it's already there). - -Flymake allows for stacking checkers but it turns out eglot clobbers these checkers when "adding" the LSP's checker. To get stacked Flymake checkers with Eglot you can simply add them back after Eglot has done it's thing. - -For example, here is a simple setup for Python which includes Pyright's type checking and flake8 style checking - -```elisp -;; Use flake8 as the python style checker by default -(setq python-flymake-command '("flake8" "-")) - -(use-package eglot - :hook ((python-mode . eglot-ensure) - (eglot-managed-mode - . (lambda () - ;; re-enable flymake checkers because eglot clobbers - ;; them when starting - (when (derived-mode-p 'python-mode) - (add-hook 'flymake-diagnostic-functions - 'python-flymake nil t))))) - - :custom - ;; shutdown server after killing last managed buffer - (eglot-autoshutdown t) - :bind - (("C-c l r" . eglot-rename)) - :config - (add-to-list 'eglot-server-programs - `(python-mode "pyright-langserver" "-w" "--stdio"))) - -``` -Now all that's left is mypy. Flymake originally used a ["Proc"](https://www.gnu.org/software/emacs/manual/html_mono/flymake.html#The-legacy-Proc-backend) method for creating checkers which existing mypy ones use. So for a bonus tip & trick [I've written a mypy checker in the new style](http://github.com/com4/flymake-mypy). It can be enabled when using eglot like this: - -```elisp -(use-package flymake-mypy - :straight (flymake-mypy - :type git - :host github - :repo "com4/flymake-mypy") - :hook ((eglot-managed-mode . (lambda () - (when (derived-mode-p 'python-mode) - (flymake-mypy-enable)))))) - -``` -After opening a Python buffer and executing `M-x flymake-running-backends` we are greeted with a list of stacked checkers: `Running backends: eglot-flymake-backend, flymake-mypy--run, python-flymake`. - ## u/thr33body [πŸ”—](https://www.reddit.com/r/emacs/comments/wqjare/comment/ikqxn0r) **Votes:** 14 @@ -514,157 +450,73 @@ Of course for the emojis to show up correctly I use this: ``` I am sure a lot of you know about these, please share your customization -## u/oantolin [πŸ”—](https://www.reddit.com/r/emacs/comments/ofen99/comment/h4dxjbz) +## u/el_tuxo [πŸ”—](https://www.reddit.com/r/emacs/comments/rbmfwk/comment/hnp5rhn) **Votes:** 14 -If you want to search and replace but with preview for the matches, don't use `query-replace-regexp` directly. Instead start by searching for your regexp in `isearch-forward-regexp`, which highlights the matches interactively, and once you have the correct regexp, run `isearch-query-replace` (bound to `M-%` in `isearch-mode-map`). - -Note that there is also an `isearch-query-replace-regexp` command but you don't need it: `isearch-query-replace` will automatically detect if your isearch session was for regexps. The docstring for `isearch-query-replace` doesn't seem to mention this nice feature. - -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/mujxm7/comment/gv8jxz5) -**Votes:** 14 +Working on a remote server with Tramp in eshell it's so easy that I'm always worried that I could run by mistake a command on the wrong machine. -I use, and love, [transient](https://github.com/magit/transient). I have a ton of commands set up, but the below command is for window manipulation. Personally, I bind it to `s-w`. I use [buffer-move](https://github.com/lukhas/buffer-move) for rearranging windows in a frame. +So I implemented a small function that makes me aware that I'm in a Tramp session by changing the prompt color. ```elisp -(define-transient-command transient-window () - "Most commonly used window commands" - [["Splits" - ("s" "Horizontal" split-window-below) - ("v" "Vertical" split-window-right) - ("b" "Balance" balance-windows) - ("f" "Fit" fit-window-to-buffer) - ["Window" - ("c" "Clone Indirect" clone-indirect-buffer) - ("t" "Tear Off" tear-off-window) - ("k" "Kill" delete-window) - ("K" "Kill Buffer+Win" kill-buffer-and-window) - ("o" "Kill Others" delete-other-windows) - ("m" "Maximize" maximize-window)] - ["Navigate" - ("" "←" windmove-left :transient t) - ("" "β†’" windmove-right :transient t) - ("" "↑" windmove-up :transient t) - ("" "↓" windmove-down :transient t)] - ["Move" - ("S-" "S-←" buf-move-left :transient t) - ("S-" "S-β†’" buf-move-right :transient t) - ("S-" "S-↑" buf-move-up :transient t) - ("S-" "S-↓" buf-move-down :transient t)] - ["Undo/Redo" - ("s-z" "Winner Undo" winner-undo :transient t) - ("s-Z" "Winner Redo" winner-redo :transient t)]]) +(require 'subr-x) +(defun tuxo/prompt-color-tramp () +"Change prompt color if a tramp session is open" + (if (file-remote-p default-directory) + (set-face-foreground 'eshell-prompt "red") + (set-face-foreground 'eshell-prompt "green"))) + +(use-package eshell + :hook (eshell-post-command . tuxo/prompt-color-tramp)) + ``` +Do you have any suggestions on how I could improve this issue? -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/mg98ki/comment/gstteeo) +## u/Stefan-Kangas [πŸ”—](https://www.reddit.com/r/emacs/comments/q76kok/comment/hgk3wik) **Votes:** 14 -I just discovered the [selected](https://github.com/Kungsgeten/selected.el) package, which is brilliant. It creates a keymap that becomes active any time you have an active region. I have bindings for next-line, previous-line, rectangle-mark-mode, end-of-line, upcase-dwim, exchange-point-and-mark, etc. It makes editing and acting on the active region super easy. Sort of like god-mode or Vim's visual mode. +This is pretty neat: scrolling up/down one line at a time while keeping the position of point: -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/hqxm5v/comment/fy1rq34) +`(setq scroll-preserve-screen-position 1)` +`(global-set-key (kbd "M-n") (kbd "C-u 1 C-v"))` +`(global-set-key (kbd "M-p") (kbd "C-u 1 M-v"))` + + +From: http://pragmaticemacs.com/emacs/scrolling-and-moving-by-line/ + +## u/oantolin [πŸ”—](https://www.reddit.com/r/emacs/comments/ofen99/comment/h4dxjbz) **Votes:** 14 -Migrated to native compiled emacs branch this week. Some hiccups but everything seems to work out of box, including pdf-tools. Great performance improvement. +If you want to search and replace but with preview for the matches, don't use `query-replace-regexp` directly. Instead start by searching for your regexp in `isearch-forward-regexp`, which highlights the matches interactively, and once you have the correct regexp, run `isearch-query-replace` (bound to `M-%` in `isearch-mode-map`). -## u/mullikine [πŸ”—](https://www.reddit.com/r/emacs/comments/heaoiu/comment/fwbtnte) +Note that there is also an `isearch-query-replace-regexp` command but you don't need it: `isearch-query-replace` will automatically detect if your isearch session was for regexps. The docstring for `isearch-query-replace` doesn't seem to mention this nice feature. + +## u/Tatrics [πŸ”—](https://www.reddit.com/r/emacs/comments/n9q662/comment/gxpeh9v) **Votes:** 14 -## Use chrome DOM for eww +I'm slowly working on an alternative shell: [https://github.com/TatriX/tshell](https://github.com/TatriX/tshell) -Basically, a lot of websites these days generate the DOM using javascript. You can dump the DOM from chrome and inject it into eww just before it renders. +Instead of using repl-like interface, all the commands go to one buffer (and file if you want) and output goes to another buffer. Like if you put your elisp code in \*scratch\* buffer and then evaluate it with \`C-x C-e\`. -It's set to wait 3 seconds before dumping the DOM. This allows many pages to load. +It's in a very early stage, but it already allows me to solve most tasks I usually do with more traditional shells. -Since I'm using the `unbuffer` program, this requires `expect` to be installed on your system. It creates a tty so that chrome doesn't crash when run in this way. +Let me know what is your first impression, what can be improved and what do you think in general! -`dump-dom` shell script +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/mg98ki/comment/gstteeo) +**Votes:** 14 -```elisp -#!/bin/bash - -url="$1" -test -n "$url" || exit 1 - -0/dev/null" +I just discovered the [selected](https://github.com/Kungsgeten/selected.el) package, which is brilliant. It creates a keymap that becomes active any time you have an active region. I have bindings for next-line, previous-line, rectangle-mark-mode, end-of-line, upcase-dwim, exchange-point-and-mark, etc. It makes editing and acting on the active region super easy. Sort of like god-mode or Vim's visual mode. -``` -Make these modifications to `eww-display-html`. +## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/lapujj/comment/glr8pkr) +**Votes:** 14 -`eww-display-html` +You can use EWW to bypass pay-walls on news sites, and other Javascript-enabled nastiness. Plus, eww can copy from what it sees into equivalent orgmode syntax, and it's also compatible with SPRAY for speed-reading. In otherwords, EWW is great for when you just need to READ the internet. -```elisp -(defun eww-display-html (charset url &optional document point buffer encode) - (unless (fboundp 'libxml-parse-html-region) - (error "This function requires Emacs to be compiled with libxml2")) - (unless (buffer-live-p buffer) - (error "Buffer %s doesn't exist" buffer)) - ;; There should be a better way to abort loading images - ;; asynchronously. - (setq url-queue nil) - ;; If document exists then the html is already parsed into a DOM - (let* ((html (shell-command-to-string (concat "dom-dump " (shell-quote-argument url)))) - (document - (or nil ;; document - (list - 'base (list (cons 'href url)) - (progn - (setq encode (or encode charset 'utf-8)) - (condition-case nil - (decode-coding-region (point) (point-max) encode) - (coding-system-error nil)) - (save-excursion - ;; Remove CRLF before parsing. - (while (re-search-forward "\r$" nil t) - (replace-match "" t t))) - (save-mark-and-excursion - ;; Delete from here to the end. Replace with the new html - (kill-region (point) (point-max)) - (insert (encode-coding-string html 'utf-8))) - (libxml-parse-html-region (point) (point-max)))))) - (source (and (null document) - (buffer-substring (point) (point-max))))) - (with-current-buffer buffer - (setq bidi-paragraph-direction nil) - (plist-put eww-data :source html) - (plist-put eww-data :dom document) - (let ((inhibit-read-only t) - (inhibit-modification-hooks t) - (shr-target-id (url-target (url-generic-parse-url url))) - (shr-external-rendering-functions - (append - shr-external-rendering-functions - '((title . eww-tag-title) - (form . eww-tag-form) - (input . eww-tag-input) - (button . eww-form-submit) - (textarea . eww-tag-textarea) - (select . eww-tag-select) - (link . eww-tag-link) - (meta . eww-tag-meta) - (a . eww-tag-a))))) - (erase-buffer) - (shr-insert-document document) - (cond - (point - (goto-char point)) - (shr-target-id - (goto-char (point-min)) - (let ((point (next-single-property-change - (point-min) 'shr-target-id))) - (when point - (goto-char point)))) - (t - (goto-char (point-min)) - ;; Don't leave point inside forms, because the normal eww - ;; commands aren't available there. - (while (and (not (eobp)) - (get-text-property (point) 'eww-form)) - (forward-line 1))))) - (eww-size-text-inputs)))) +## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/fs93hk/comment/fm1fw1x) +**Votes:** 14 -``` -Demonstration: -https://asciinema.org/a/UAAVfp5O8SofJZvKBusTOP8QQ +For me, learning about `kill-whole-line` (control-shift-delete) was a revelation. Compared to the "classic" Emacs method of deleting lines (C-a to go to the beginning of the line if not already there, C-k once to kill to the end of line, C-k again to kill the newline), it feels like a major speedup. + +I still use C-k frequently, but it's effectively just a kill-to-end-of-line command. ## u/mullikine [πŸ”—](https://www.reddit.com/r/emacs/comments/eeyhdz/comment/fc1u840) **Votes:** 14 @@ -716,25 +568,56 @@ Enable `use-package-compute-statistics` right after you load `use-package`: ``` Restart emacs, and then invoke `use-package-report`. You'll get a table of the load times for each package that `use-package` manages. I discovered this and found an immediate way to cut my startup time in half by fixing a few packages that weren't deferred properly by adding the right `:hook` keyword. -## u/eleven_cupfuls [πŸ”—](https://www.reddit.com/r/emacs/comments/10ktqj0/comment/j5umed8) +## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/11rq2gl/comment/jc9t4tc) **Votes:** 13 -I jump into the built-in Elisp files a lot to see how things work. The indentation there is GNU standard, which uses a mix of tabs and spaces for alignment. The tabs have to be rendered as 8 spaces wide for the alignment to work, and I don't actually want that setting anywhere else. Since the files on Mac are inside the application bundle, I don't want to just add a .dir-locals.el file next to them, either. +Plain old `query-replace` has many cool features, first of all it respects the active region (if it's active it will only query for replacements in the active region). There are many useful keys in addition to plain `y`/`n`: -[Directory classes](https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html) to the rescue! My config makes a new directory variable class, `builtin-elisp`, with a list saying that `emacs-lisp-mode` should use a `tab-width` of 8. Then it applies that class to the Elisp files in the application bundle: +`!`: replaces all remaning matches + +`u`: undo last replacement + +`E`: changes replacement string on the fly + +And many more you can see using `?`. + +## u/geza42 [πŸ”—](https://www.reddit.com/r/emacs/comments/11lqkbo/comment/jbe06qv) +**Votes:** 13 + +You can toggle vertico's height between 15 and "almost full frame" with this. When vertico is invoked, it will always have a height of 15. But if you have a lot of matches, and like to have a better overview, press the binding, and vertico will show a full frame of matches. This is useful for example when `consult-buffer` presents a lot of buffers. ```elisp -(use-package elisp-mode - :config - (dir-locals-set-class-variables - 'builtin-elisp - '((emacs-lisp-mode . ((tab-width . 8))))) - (dir-locals-set-directory-class - (file-name-directory (directory-file-name (invocation-directory))) - 'builtin-elisp)) +(advice-add 'vertico--setup :before (lambda () (setq vertico-count 15))) +(define-key minibuffer-local-map (kbd "s-'") (lambda () + (interactive) + (let ((vertico-resize t)) + (setq vertico-count (if (= vertico-count 15) (- (frame-height) 5) 15)) + (vertico--exhibit)))) ``` -And now when I visit one of those files, the alignment is always correct. +Another useful feature is to kill buffers in `consult-buffer` without manually invoking `embark-act`. I miss this feature from Helm, where you can do actions using only one binding (no need to press an intermediate binding which invokes `embark-act`). Note, I just blindly copied some of the logic from `embark`, maybe there are some unnecessary things here. + +```elisp +(defun my-embark-M-k (&optional arg) + (interactive "P") + (require 'embark) + (if-let ((targets (embark--targets))) + (let* ((target + (or (nth + (if (or (null arg) (minibufferp)) + 0 + (mod (prefix-numeric-value arg) (length targets))) + targets))) + (type (plist-get target :type))) + (cond + ((eq type 'buffer) + (let ((embark-pre-action-hooks)) + (embark--act 'kill-buffer target))))))) + +(define-key minibuffer-local-map (kbd "M-k") 'my-embark-M-k) + +``` +I'm not sure whether these two can be achieved out-of-the box, but I didn't find these functionalities, so I created them. ## u/gusbrs [πŸ”—](https://www.reddit.com/r/emacs/comments/y1y0kq/comment/is1ygyw) **Votes:** 13 @@ -914,149 +797,231 @@ Not that it matters much, but the corresponding capture template is: :empty-lines 1) ``` -## u/Stefan-Kangas [πŸ”—](https://www.reddit.com/r/emacs/comments/q76kok/comment/hgk3wik) +## u/com4 [πŸ”—](https://www.reddit.com/r/emacs/comments/xq6rpa/comment/iqb2fci) **Votes:** 13 -This is pretty neat: scrolling up/down one line at a time while keeping the position of point: +In preparation for the inclusion of eglot into Emacs core I've switched away from lsp-mode. As a result I've also switched from flycheck and to flymake. One nice thing about flycheck is that it allowed for stacking checkers. When coding Python I liked to stack flake8 for styles and mypy for types (plus the LSP's since it's already there). -`(setq scroll-preserve-screen-position 1)` -`(global-set-key (kbd "M-n") (kbd "C-u 1 C-v"))` -`(global-set-key (kbd "M-p") (kbd "C-u 1 M-v"))` +Flymake allows for stacking checkers but it turns out eglot clobbers these checkers when "adding" the LSP's checker. To get stacked Flymake checkers with Eglot you can simply add them back after Eglot has done it's thing. +For example, here is a simple setup for Python which includes Pyright's type checking and flake8 style checking -From: http://pragmaticemacs.com/emacs/scrolling-and-moving-by-line/ +```elisp +;; Use flake8 as the python style checker by default +(setq python-flymake-command '("flake8" "-")) + +(use-package eglot + :hook ((python-mode . eglot-ensure) + (eglot-managed-mode + . (lambda () + ;; re-enable flymake checkers because eglot clobbers + ;; them when starting + (when (derived-mode-p 'python-mode) + (add-hook 'flymake-diagnostic-functions + 'python-flymake nil t))))) + + :custom + ;; shutdown server after killing last managed buffer + (eglot-autoshutdown t) + :bind + (("C-c l r" . eglot-rename)) + :config + (add-to-list 'eglot-server-programs + `(python-mode "pyright-langserver" "-w" "--stdio"))) -## u/Tatrics [πŸ”—](https://www.reddit.com/r/emacs/comments/n9q662/comment/gxpeh9v) -**Votes:** 13 +``` +Now all that's left is mypy. Flymake originally used a ["Proc"](https://www.gnu.org/software/emacs/manual/html_mono/flymake.html#The-legacy-Proc-backend) method for creating checkers which existing mypy ones use. So for a bonus tip & trick [I've written a mypy checker in the new style](http://github.com/com4/flymake-mypy). It can be enabled when using eglot like this: -I'm slowly working on an alternative shell: [https://github.com/TatriX/tshell](https://github.com/TatriX/tshell) +```elisp +(use-package flymake-mypy + :straight (flymake-mypy + :type git + :host github + :repo "com4/flymake-mypy") + :hook ((eglot-managed-mode . (lambda () + (when (derived-mode-p 'python-mode) + (flymake-mypy-enable)))))) -Instead of using repl-like interface, all the commands go to one buffer (and file if you want) and output goes to another buffer. Like if you put your elisp code in \*scratch\* buffer and then evaluate it with \`C-x C-e\`. +``` +After opening a Python buffer and executing `M-x flymake-running-backends` we are greeted with a list of stacked checkers: `Running backends: eglot-flymake-backend, flymake-mypy--run, python-flymake`. -It's in a very early stage, but it already allows me to solve most tasks I usually do with more traditional shells. +## u/vatai [πŸ”—](https://www.reddit.com/r/emacs/comments/ojzv53/comment/h5584no) +**Votes:** 13 -Let me know what is your first impression, what can be improved and what do you think in general! +The emacs lisp tutorial is the real tutorial for emacs ;) -## u/emacs-noob [πŸ”—](https://www.reddit.com/r/emacs/comments/kvmmq3/comment/gj1kn9i) +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/mujxm7/comment/gv8jxz5) **Votes:** 13 -I use Emacs for React development and it's usually great (rjsx-mode). We recently introduced styled components into our app and while they're very handy, not having proper css support inside rjsx-mode was pretty annoying. I was looking for solutions, maybe extending rjsx-mode, but I wasn't up to that task. I then realized the built-in emacs commands and buffers themselves could solve my problem! What I want is for css inside a styled component, which always looks something like this: +I use, and love, [transient](https://github.com/magit/transient). I have a ton of commands set up, but the below command is for window manipulation. Personally, I bind it to `s-w`. I use [buffer-move](https://github.com/lukhas/buffer-move) for rearranging windows in a frame. ```elisp -const myDiv = styled.div` // notice the backtick - Some css... - ` // ending backtick - +(define-transient-command transient-window () + "Most commonly used window commands" + [["Splits" + ("s" "Horizontal" split-window-below) + ("v" "Vertical" split-window-right) + ("b" "Balance" balance-windows) + ("f" "Fit" fit-window-to-buffer) + ["Window" + ("c" "Clone Indirect" clone-indirect-buffer) + ("t" "Tear Off" tear-off-window) + ("k" "Kill" delete-window) + ("K" "Kill Buffer+Win" kill-buffer-and-window) + ("o" "Kill Others" delete-other-windows) + ("m" "Maximize" maximize-window)] + ["Navigate" + ("" "←" windmove-left :transient t) + ("" "β†’" windmove-right :transient t) + ("" "↑" windmove-up :transient t) + ("" "↓" windmove-down :transient t)] + ["Move" + ("S-" "S-←" buf-move-left :transient t) + ("S-" "S-β†’" buf-move-right :transient t) + ("S-" "S-↑" buf-move-up :transient t) + ("S-" "S-↓" buf-move-down :transient t)] + ["Undo/Redo" + ("s-z" "Winner Undo" winner-undo :transient t) + ("s-Z" "Winner Redo" winner-redo :transient t)]]) ``` -to *actually* use scss-mode when editing, and then return to rjsx-mode when finished. The elisp is very simple and leads to a trivial workflow: + +## u/b3n [πŸ”—](https://www.reddit.com/r/emacs/comments/lvw44q/comment/gpeb8n3) +**Votes:** 13 + +Here's a nice eshell command: ```elisp -;; The following 2 functions allow editing styled components with all scss mode features. -(defun edit-styled-component () +(defun eshell/history () (interactive) - (progn - (save-excursion - (let ((start (search-backward "`")) - (end (search-forward "`" nil nil 2))) ; second occurrence, since first is `start' - (narrow-to-region start end))) - (scss-mode))) + (insert + (completing-read "History: " (delete-dups (ring-elements eshell-history-ring))))) -(spacemacs/set-leader-keys-for-major-mode 'rjsx-mode - "ms" 'edit-styled-component) +``` +It lets you use your normal completion framework to select an item from history. Suddenly fzf-like history! -;; When editing is done, use the same key sequence to return to the original file. -(defun return-from-styled-component () - (interactive) - (progn - (widen) - (rjsx-mode))) +## u/mullikine [πŸ”—](https://www.reddit.com/r/emacs/comments/heaoiu/comment/fwbtnte) +**Votes:** 13 -(spacemacs/set-leader-keys-for-major-mode 'scss-mode - "ms" 'return-from-styled-component) +## Use chrome DOM for eww +Basically, a lot of websites these days generate the DOM using javascript. You can dump the DOM from chrome and inject it into eww just before it renders. -``` -So now when I edit a styled component I just hit **, m s**, which narrows the region to whatever is enclosed by backticks (i.e. all the css) and actually treats it as a bona fide css buffer, with all my snippets, completion, etc. Then when I'm done I just got **, m s** again to widen back to the original (rjsx) buffer! +It's set to wait 3 seconds before dumping the DOM. This allows many pages to load. -## u/rhmatthijs [πŸ”—](https://www.reddit.com/r/emacs/comments/gzivu3/comment/ftgqnbp) -**Votes:** 13 +Since I'm using the `unbuffer` program, this requires `expect` to be installed on your system. It creates a tty so that chrome doesn't crash when run in this way. -Working in education, I often find myself having to assign students into groups. This week I made a function in ELisp that helps me do this. Select a region in a buffer that contains a list of students (presumably), call this function, say how many students should be in each group and the function then randomly assigns groups. +`dump-dom` shell script ```elisp -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Shuffling things. ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defun mcj/shuffle (input) - " Shuffle a list in place. For some reason does not exist in -Emacs by default. Uses Fisher-Yates shuffle. -" - (let ((swap (lambda (list-to-swap i1 i2) - (let ((tmp (elt list-to-swap i1))) - (setf (elt list-to-swap i1) (elt list-to-swap i2)) - (setf (elt list-to-swap i2) tmp))))) - (dotimes (i (length input) input) - (funcall swap input i (random (+ i 1)))))) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Pairing off things (students, say). ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defun mcj/pair-off (input num) - "Return the elements of input paired off into pairs of length - num" - (cond ((< (length input) (* num 2)) (list input)) - (t - (cons (butlast input (- (length input)num)) (mcj/pair-off (nthcdr num input) num))))) - +#!/bin/bash +url="$1" +test -n "$url" || exit 1 -(defun mcj/pair-off-region (num) - " Pair off lines in a region" - (interactive (list - (read-number "Members per pair (num):" 2))) - (let ((newcontents - (mapconcat (lambda (item-pair) - (mapconcat (lambda (item) item) item-pair " + ")) - (mcj/pair-off - (mcj/shuffle - (split-string - (buffer-substring-no-properties (mark) (point)) "[\n]" t )) - num) - "\n"))) - (delete-region (mark) (point)) - (insert newcontents))) -``` - -## u/_hmenke [πŸ”—](https://www.reddit.com/r/emacs/comments/gqsz8u/comment/fruqs1k) -**Votes:** 13 - -Any **BibTeX** users here? +0/dev/null" -- Tired of journals forcing you to download a file to get the BibTeX record of an article? -- Tired of their usually broken formatting? -- The journal doesn't offer BibTeX download in the first place? (Looking at you Nature) +``` +Make these modifications to `eww-display-html`. -Did you know that doi.org has query interface that gives you the BibTeX record when you call it with the article DOI? Of course you can access this via Emacs: +`eww-display-html` ```elisp -(require 'url) -(defun user/url-bibtex-from-doi (doi) - (interactive "sDOI: ") - (let* ((url (concat "https://doi.org/" doi)) - (url-mime-accept-string "application/x-bibtex")) - (insert - (with-current-buffer (url-retrieve-synchronously url) - (let* ((start url-http-end-of-headers) - (end (point-max)) - (all (buffer-string)) - (body (buffer-substring start end))) +(defun eww-display-html (charset url &optional document point buffer encode) + (unless (fboundp 'libxml-parse-html-region) + (error "This function requires Emacs to be compiled with libxml2")) + (unless (buffer-live-p buffer) + (error "Buffer %s doesn't exist" buffer)) + ;; There should be a better way to abort loading images + ;; asynchronously. + (setq url-queue nil) + ;; If document exists then the html is already parsed into a DOM + (let* ((html (shell-command-to-string (concat "dom-dump " (shell-quote-argument url)))) + (document + (or nil ;; document + (list + 'base (list (cons 'href url)) + (progn + (setq encode (or encode charset 'utf-8)) + (condition-case nil + (decode-coding-region (point) (point-max) encode) + (coding-system-error nil)) + (save-excursion + ;; Remove CRLF before parsing. + (while (re-search-forward "\r$" nil t) + (replace-match "" t t))) + (save-mark-and-excursion + ;; Delete from here to the end. Replace with the new html + (kill-region (point) (point-max)) + (insert (encode-coding-string html 'utf-8))) + (libxml-parse-html-region (point) (point-max)))))) + (source (and (null document) + (buffer-substring (point) (point-max))))) + (with-current-buffer buffer + (setq bidi-paragraph-direction nil) + (plist-put eww-data :source html) + (plist-put eww-data :dom document) + (let ((inhibit-read-only t) + (inhibit-modification-hooks t) + (shr-target-id (url-target (url-generic-parse-url url))) + (shr-external-rendering-functions + (append + shr-external-rendering-functions + '((title . eww-tag-title) + (form . eww-tag-form) + (input . eww-tag-input) + (button . eww-form-submit) + (textarea . eww-tag-textarea) + (select . eww-tag-select) + (link . eww-tag-link) + (meta . eww-tag-meta) + (a . eww-tag-a))))) + (erase-buffer) + (shr-insert-document document) + (cond + (point + (goto-char point)) + (shr-target-id + (goto-char (point-min)) + (let ((point (next-single-property-change + (point-min) 'shr-target-id))) + (when point + (goto-char point)))) + (t + (goto-char (point-min)) + ;; Don't leave point inside forms, because the normal eww + ;; commands aren't available there. + (while (and (not (eobp)) + (get-text-property (point) 'eww-form)) + (forward-line 1))))) + (eww-size-text-inputs)))) + +``` +Demonstration: +https://asciinema.org/a/UAAVfp5O8SofJZvKBusTOP8QQ + +## u/_hmenke [πŸ”—](https://www.reddit.com/r/emacs/comments/gqsz8u/comment/fruqs1k) +**Votes:** 13 + +Any **BibTeX** users here? + +- Tired of journals forcing you to download a file to get the BibTeX record of an article? +- Tired of their usually broken formatting? +- The journal doesn't offer BibTeX download in the first place? (Looking at you Nature) + +Did you know that doi.org has query interface that gives you the BibTeX record when you call it with the article DOI? Of course you can access this via Emacs: + +```elisp +(require 'url) +(defun user/url-bibtex-from-doi (doi) + (interactive "sDOI: ") + (let* ((url (concat "https://doi.org/" doi)) + (url-mime-accept-string "application/x-bibtex")) + (insert + (with-current-buffer (url-retrieve-synchronously url) + (let* ((start url-http-end-of-headers) + (end (point-max)) + (all (buffer-string)) + (body (buffer-substring start end))) (replace-regexp-in-string "^\t" " " (url-unhex-string body))))))) ``` @@ -1082,12 +1047,20 @@ Here is how I bind it in `bibtex-mode` (plus my other bindings for good measure) If you're not using [`native-comp`](http://akrl.sdf.org/gccemacs.html) feature yet, I strongly recommend you to try it out! Have been using it for two weeks for now and everything seem to run pretty smooth and rock solid! The speed difference is quite noticeable in some interactive aspects like completion, although my machine is quite slow, so this may not be that noticeable on newer machines. -## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/fs93hk/comment/fm1fw1x) +## u/zoechi [πŸ”—](https://www.reddit.com/r/emacs/comments/fwgpkd/comment/fmo9d5v) **Votes:** 13 -For me, learning about `kill-whole-line` (control-shift-delete) was a revelation. Compared to the "classic" Emacs method of deleting lines (C-a to go to the beginning of the line if not already there, C-k once to kill to the end of line, C-k again to kill the newline), it feels like a major speedup. +I (Emacs rookie) just found out that native/fast JSON support is not guaranteed when emacs 27+ is used. jansson-dev needs to be installed when Emacs is built https://github.com/emacs-lsp/lsp-mode/issues/1557#issuecomment-608409056 -I still use C-k frequently, but it's effectively just a kill-to-end-of-line command. +## u/xu_chunyang [πŸ”—](https://www.reddit.com/r/emacs/comments/fo1fm3/comment/flcwsu4) +**Votes:** 13 + +Happy Birthday from Emacs, let's assume March 24 is your birthday, put this to your init file, when you open Emacs on your birthday, you'll receive a birthday present from Emacs + +```elisp +(when (string= "03-24" (format-time-string "%m-%d")) + (animate-birthday-present user-full-name)) +``` ## u/loopsdeer [πŸ”—](https://www.reddit.com/r/emacs/comments/f972tf/comment/fiqj0dn) **Votes:** 13 @@ -1117,88 +1090,34 @@ I quit Emacs, made an edit in my .git elsewhere, opened Emacs back up and jumped It's funny how excited I am to remove two keystrokes from the beginning of my day. Probably I am also excited that my random experiment worked. Obviously it's not so random as magit knew exactly what I wanted. Magit is life! -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/f25er5/comment/fhar795) +## u/clemera [πŸ”—](https://www.reddit.com/r/emacs/comments/drw8i3/comment/f6ncyes) **Votes:** 13 -Make a `.desktop` file for emacsclient and make sure to include `-c` in the command line ([my .desktop](https://github.com/cadadr/configuration/blob/master/candy/emacsclient.desktop)). Then, you can associate Emacs with many filetypes with emacsclient, and view them in Emacs. E.g., this is how I view PDF files. `-c` is useful because it opens in a new frame, thus your window setup is left intact and the OS window is always in the current workspace (useful if you've set up your WM to not focus urgent windows automatically). - -In a similar vein, I use [this script](https://github.com/cadadr/configuration/blob/master/emacs.d/extras/mailto.el.in) to redirect `mailto:` links to Emacs so that I can write my mails in `message-mode` within Emacs. I've set it as the mail program in Firefox. It's probably possible to write a `.desktop` file for this so that you can set it in `mimeapps.list` or whatever as the global mail composer, but IDK how to do that. - -With emacsclient and a bit of Elisp, it's really easy to integrate Emacs to a FreeDesktop environment. I can't speak for Windows or Mac OS tho, because I don't use those often. - -## u/MCHerb [πŸ”—](https://www.reddit.com/r/emacs/comments/e8nv40/comment/fadjl3w) -**Votes:** 13 -A narrowing toggle that does what I need most of the time so a single key can do all narrowing and un-narrowing. ```elisp -(defun narrow-dwim () - "Toggle narrowing." - (interactive) - (cond ((region-active-p) - ;; If region is highlighted, narrow to that - (call-interactively #'narrow-to-region) - (deactivate-mark t)) - ((buffer-narrowed-p) - ;; Otherwise widen if narrowed - (widen)) - ((derived-mode-p 'org-mode) - (call-interactively #'org-narrow-to-subtree)) - (t - (message "Do not know what to narrow to.") - (call-interactively #'narrow-to-defun)))) +emacs --batch -l cl-lib --eval "(cl-loop (print (eval (read))))" ``` -## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/11rq2gl/comment/jc9t4tc) -**Votes:** 12 - -Plain old `query-replace` has many cool features, first of all it respects the active region (if it's active it will only query for replacements in the active region). There are many useful keys in addition to plain `y`/`n`: - -`!`: replaces all remaning matches - -`u`: undo last replacement - -`E`: changes replacement string on the fly - -And many more you can see using `?`. - -## u/geza42 [πŸ”—](https://www.reddit.com/r/emacs/comments/11lqkbo/comment/jbe06qv) +## u/eleven_cupfuls [πŸ”—](https://www.reddit.com/r/emacs/comments/10ktqj0/comment/j5umed8) **Votes:** 12 -You can toggle vertico's height between 15 and "almost full frame" with this. When vertico is invoked, it will always have a height of 15. But if you have a lot of matches, and like to have a better overview, press the binding, and vertico will show a full frame of matches. This is useful for example when `consult-buffer` presents a lot of buffers. - -```elisp -(advice-add 'vertico--setup :before (lambda () (setq vertico-count 15))) -(define-key minibuffer-local-map (kbd "s-'") (lambda () - (interactive) - (let ((vertico-resize t)) - (setq vertico-count (if (= vertico-count 15) (- (frame-height) 5) 15)) - (vertico--exhibit)))) +I jump into the built-in Elisp files a lot to see how things work. The indentation there is GNU standard, which uses a mix of tabs and spaces for alignment. The tabs have to be rendered as 8 spaces wide for the alignment to work, and I don't actually want that setting anywhere else. Since the files on Mac are inside the application bundle, I don't want to just add a .dir-locals.el file next to them, either. -``` -Another useful feature is to kill buffers in `consult-buffer` without manually invoking `embark-act`. I miss this feature from Helm, where you can do actions using only one binding (no need to press an intermediate binding which invokes `embark-act`). Note, I just blindly copied some of the logic from `embark`, maybe there are some unnecessary things here. +[Directory classes](https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html) to the rescue! My config makes a new directory variable class, `builtin-elisp`, with a list saying that `emacs-lisp-mode` should use a `tab-width` of 8. Then it applies that class to the Elisp files in the application bundle: ```elisp -(defun my-embark-M-k (&optional arg) - (interactive "P") - (require 'embark) - (if-let ((targets (embark--targets))) - (let* ((target - (or (nth - (if (or (null arg) (minibufferp)) - 0 - (mod (prefix-numeric-value arg) (length targets))) - targets))) - (type (plist-get target :type))) - (cond - ((eq type 'buffer) - (let ((embark-pre-action-hooks)) - (embark--act 'kill-buffer target))))))) - -(define-key minibuffer-local-map (kbd "M-k") 'my-embark-M-k) +(use-package elisp-mode + :config + (dir-locals-set-class-variables + 'builtin-elisp + '((emacs-lisp-mode . ((tab-width . 8))))) + (dir-locals-set-directory-class + (file-name-directory (directory-file-name (invocation-directory))) + 'builtin-elisp)) ``` -I'm not sure whether these two can be achieved out-of-the box, but I didn't find these functionalities, so I created them. +And now when I visit one of those files, the alignment is always correct. ## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/wf0t0d/comment/iirl0ea) **Votes:** 12 @@ -1211,138 +1130,178 @@ This inserts all export keywords with default values at beginning of line. This command is not documented in `info emacs` (v27.1). -## u/b3n [πŸ”—](https://www.reddit.com/r/emacs/comments/lvw44q/comment/gpeb8n3) +## u/Stefan-Kangas [πŸ”—](https://www.reddit.com/r/emacs/comments/pxqvtm/comment/hf1gzs2) **Votes:** 12 -Here's a nice eshell command: +Read [SICP](https://mitpress.mit.edu/sites/default/files/sicp/index.html). Preferably in Info, installable through MELPA or: [https://github.com/webframp/sicp-info](https://github.com/webframp/sicp-info) + +## u/emacs-noob [πŸ”—](https://www.reddit.com/r/emacs/comments/kvmmq3/comment/gj1kn9i) +**Votes:** 12 + +I use Emacs for React development and it's usually great (rjsx-mode). We recently introduced styled components into our app and while they're very handy, not having proper css support inside rjsx-mode was pretty annoying. I was looking for solutions, maybe extending rjsx-mode, but I wasn't up to that task. I then realized the built-in emacs commands and buffers themselves could solve my problem! What I want is for css inside a styled component, which always looks something like this: ```elisp -(defun eshell/history () - (interactive) - (insert - (completing-read "History: " (delete-dups (ring-elements eshell-history-ring))))) +const myDiv = styled.div` // notice the backtick + Some css... + ` // ending backtick ``` -It lets you use your normal completion framework to select an item from history. Suddenly fzf-like history! +to *actually* use scss-mode when editing, and then return to rjsx-mode when finished. The elisp is very simple and leads to a trivial workflow: -## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/lapujj/comment/glr8pkr) -**Votes:** 12 +```elisp +;; The following 2 functions allow editing styled components with all scss mode features. +(defun edit-styled-component () + (interactive) + (progn + (save-excursion + (let ((start (search-backward "`")) + (end (search-forward "`" nil nil 2))) ; second occurrence, since first is `start' + (narrow-to-region start end))) + (scss-mode))) -You can use EWW to bypass pay-walls on news sites, and other Javascript-enabled nastiness. Plus, eww can copy from what it sees into equivalent orgmode syntax, and it's also compatible with SPRAY for speed-reading. In otherwords, EWW is great for when you just need to READ the internet. +(spacemacs/set-leader-keys-for-major-mode 'rjsx-mode + "ms" 'edit-styled-component) -## u/jimm [πŸ”—](https://www.reddit.com/r/emacs/comments/heaoiu/comment/fvqvedf) -**Votes:** 12 +;; When editing is done, use the same key sequence to return to the original file. +(defun return-from-styled-component () + (interactive) + (progn + (widen) + (rjsx-mode))) -I can't say how often I use `dabbrev-expand` (`M-/`) to complete words. Saves me a ton of time. +(spacemacs/set-leader-keys-for-major-mode 'scss-mode + "ms" 'return-from-styled-component) -## u/celeritasCelery [πŸ”—](https://www.reddit.com/r/emacs/comments/gi70ye/comment/fqdnyhk) -**Votes:** 12 -Shells in emacs like `shell-mode` and `eshell` can write multi line input using `comint-accumulate`. Normally bound to `C-c SPC`. +``` +So now when I edit a styled component I just hit **, m s**, which narrows the region to whatever is enclosed by backticks (i.e. all the css) and actually treats it as a bona fide css buffer, with all my snippets, completion, etc. Then when I'm done I just got **, m s** again to widen back to the original (rjsx) buffer! -## u/hale314 [πŸ”—](https://www.reddit.com/r/emacs/comments/gi70ye/comment/fqg7qys) +## u/rhmatthijs [πŸ”—](https://www.reddit.com/r/emacs/comments/gzivu3/comment/ftgqnbp) **Votes:** 12 -I tend to have a lot of function that is defined solely to be added to a hook. Turns out I can customize `defun-declarations-alist` to define a new `hook` property in the `declare` form. Now I can specify the hook that the function is intended for right inside the function definition. +Working in education, I often find myself having to assign students into groups. This week I made a function in ELisp that helps me do this. Select a region in a buffer that contains a list of students (presumably), call this function, say how many students should be in each group and the function then randomly assigns groups. ```elisp -;; Need to be done during compilation as well if your functions are getting compiled -(eval-and-compile - (setf (alist-get 'hook defun-declarations-alist) - (list (lambda (fun _args hook &optional depth) - `(add-hook ',hook #',fun ,@(when depth (list depth))))))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Shuffling things. ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun ask-about-scratch-buffer () - "Confirm that user want to discard the content of the scratch buffer." - (declare (hook kill-emacs-query-functions)) - (let ((scratch (get-buffer "*scratch*"))) - (or (zerop (buffer-size scratch)) - (progn (pop-to-buffer scratch) - (y-or-n-p "Scratch buffer is not empty, discard?"))))) -;; no longer needed -;; (add-hook 'kill-emacs-query-functions #'ask-about-scratch-buffer) +(defun mcj/shuffle (input) + " Shuffle a list in place. For some reason does not exist in +Emacs by default. Uses Fisher-Yates shuffle. +" + (let ((swap (lambda (list-to-swap i1 i2) + (let ((tmp (elt list-to-swap i1))) + (setf (elt list-to-swap i1) (elt list-to-swap i2)) + (setf (elt list-to-swap i2) tmp))))) + (dotimes (i (length input) input) + (funcall swap input i (random (+ i 1)))))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Pairing off things (students, say). ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun mcj/pair-off (input num) + "Return the elements of input paired off into pairs of length + num" + (cond ((< (length input) (* num 2)) (list input)) + (t + (cons (butlast input (- (length input)num)) (mcj/pair-off (nthcdr num input) num))))) + + + +(defun mcj/pair-off-region (num) + " Pair off lines in a region" + (interactive (list + (read-number "Members per pair (num):" 2))) + (let ((newcontents + (mapconcat (lambda (item-pair) + (mapconcat (lambda (item) item) item-pair " + ")) + (mcj/pair-off + (mcj/shuffle + (split-string + (buffer-substring-no-properties (mark) (point)) "[\n]" t )) + num) + "\n"))) + (delete-region (mark) (point)) + (insert newcontents))) ``` -## u/zoechi [πŸ”—](https://www.reddit.com/r/emacs/comments/fwgpkd/comment/fmo9d5v) +## u/celeritasCelery [πŸ”—](https://www.reddit.com/r/emacs/comments/gi70ye/comment/fqdnyhk) **Votes:** 12 -I (Emacs rookie) just found out that native/fast JSON support is not guaranteed when emacs 27+ is used. jansson-dev needs to be installed when Emacs is built https://github.com/emacs-lsp/lsp-mode/issues/1557#issuecomment-608409056 +Shells in emacs like `shell-mode` and `eshell` can write multi line input using `comint-accumulate`. Normally bound to `C-c SPC`. -## u/clemera [πŸ”—](https://www.reddit.com/r/emacs/comments/drw8i3/comment/f6ncyes) +## u/hale314 [πŸ”—](https://www.reddit.com/r/emacs/comments/gi70ye/comment/fqg7qys) **Votes:** 12 - +I tend to have a lot of function that is defined solely to be added to a hook. Turns out I can customize `defun-declarations-alist` to define a new `hook` property in the `declare` form. Now I can specify the hook that the function is intended for right inside the function definition. ```elisp -emacs --batch -l cl-lib --eval "(cl-loop (print (eval (read))))" +;; Need to be done during compilation as well if your functions are getting compiled +(eval-and-compile + (setf (alist-get 'hook defun-declarations-alist) + (list (lambda (fun _args hook &optional depth) + `(add-hook ',hook #',fun ,@(when depth (list depth))))))) + +(defun ask-about-scratch-buffer () + "Confirm that user want to discard the content of the scratch buffer." + (declare (hook kill-emacs-query-functions)) + (let ((scratch (get-buffer "*scratch*"))) + (or (zerop (buffer-size scratch)) + (progn (pop-to-buffer scratch) + (y-or-n-p "Scratch buffer is not empty, discard?"))))) +;; no longer needed +;; (add-hook 'kill-emacs-query-functions #'ask-about-scratch-buffer) ``` -## u/ProfessorSexyTime [πŸ”—](https://www.reddit.com/r/emacs/comments/dlethf/comment/f4wdyaf) +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/f25er5/comment/fhar795) **Votes:** 12 -I feel like a lot of us average Emacs users miss out on a lot of functionality Emacs provides outside of the box. So some things you might find interesting: - -#### [Registers](https://www.gnu.org/software/emacs/manual/html_node/emacs/Registers.html) - -Someone posted this in a weekly tips/trick/etc thread a few weeks ago, but I thought I'd mention it again. - -Registers just let you store *things* in them. This can be - -- Cursor positions in buffers (`C-x r SPC [name you want to give the register]`) -- Text in a region (`C-x r s [name you want to give the register]`) -- Rectangles (`C-x r r [name you want to give the register]`) -- State of windows in frames (`C-x r w [name you want to give the register]`) -- State of all frames and their windows (`C-x r f [name you want to give the register]`) -- Numbers (`C-x r n [name you want to give the register]`) and you can increment those numbers (`C-x r + [name of register you want to increment`] -- Whole file names (it's not bound, but you can do `M-: (set-register ?z '(file . "/some_file/somewhere/some_text.txt"))`) -- Keyboard macros instead of saving them (` C-x C-k x [name you want to give the register]`) - -You can insert text, registers, or numbers with `C-x r i [name of register with stuff to insert]`. You can also append or prepend stuff to registers with `append-to-register` or `prepend-to-register`. - -`C-x r j [name of register]` can jump to a point, restore a window or frame configuration, or visit a file with a specific name. +Make a `.desktop` file for emacsclient and make sure to include `-c` in the command line ([my .desktop](https://github.com/cadadr/configuration/blob/master/candy/emacsclient.desktop)). Then, you can associate Emacs with many filetypes with emacsclient, and view them in Emacs. E.g., this is how I view PDF files. `-c` is useful because it opens in a new frame, thus your window setup is left intact and the OS window is always in the current workspace (useful if you've set up your WM to not focus urgent windows automatically). -You could always use [bookmarks](https://www.gnu.org/software/emacs/manual/html_node/emacs/Bookmarks.html#Bookmarks). +In a similar vein, I use [this script](https://github.com/cadadr/configuration/blob/master/emacs.d/extras/mailto.el.in) to redirect `mailto:` links to Emacs so that I can write my mails in `message-mode` within Emacs. I've set it as the mail program in Firefox. It's probably possible to write a `.desktop` file for this so that you can set it in `mimeapps.list` or whatever as the global mail composer, but IDK how to do that. -One thing I would like to do is automatically give registers names, say like a1, a2, et cetera then b1, b2 et cetera, and then A1, A2 and yaddah yaddah. +With emacsclient and a bit of Elisp, it's really easy to integrate Emacs to a FreeDesktop environment. I can't speak for Windows or Mac OS tho, because I don't use those often. -I'm an idiot though and generating that sort of collection escapes me a bit. +## u/MCHerb [πŸ”—](https://www.reddit.com/r/emacs/comments/e8nv40/comment/fadjl3w) +**Votes:** 12 -I'd rather not do just +A narrowing toggle that does what I need most of the time so a single key can do all narrowing and un-narrowing. ```elisp -(loop n from 0 to 99 - collect (concat "a" n)) - +(defun narrow-dwim () + "Toggle narrowing." + (interactive) + (cond ((region-active-p) + ;; If region is highlighted, narrow to that + (call-interactively #'narrow-to-region) + (deactivate-mark t)) + ((buffer-narrowed-p) + ;; Otherwise widen if narrowed + (widen)) + ((derived-mode-p 'org-mode) + (call-interactively #'org-narrow-to-subtree)) + (t + (message "Do not know what to narrow to.") + (call-interactively #'narrow-to-defun)))) ``` -for every alphabetical character. Then it'd be a matter of going through those collections for every register created and making sure they use different names. Was wondering if I could get some help. -#### [Isearch](https://www.emacswiki.org/emacs/IncrementalSearch) and [Query Replace](https://www.gnu.org/software/emacs/manual/html_node/emacs/Query-Replace.html) - -Not much to say here, just that I might recommend that one go over the default keys for [isearch](https://www.emacswiki.org/emacs/IncrementalSearch#toc2) and query-replace. - -Also I would switch `C-s` and `C-r` to use `isearch-forward-regex` and `isearch-backward-regex`, and `M-%` to use `query-replace-regex` because you can disable the use of regex for both. You can even start a query-replace from isearch with `M-%` or `C-M-%`. - -#### `event-apply-*` Keys - -I don't really know what I can use these keys for, but with which-key you can press `C-x @` to see them. They allow you to apply control, shift, alt, meta, super, or hyper keys. - -## u/badmaxton [πŸ”—](https://www.reddit.com/r/emacs/comments/19ec8v5/comment/kjcu7vp) +## u/bopboa [πŸ”—](https://www.reddit.com/r/emacs/comments/1aky57w/comment/kphrvz3) **Votes:** 11 -Just added this to the `:init` section of my embark configuration: +This is how to have a beacon without installing any packages. ```elisp -(define-key minibuffer-local-map [C-tab] 'embark-select) - + (defun pulse-line (_) + (pulse-momentary-highlight-one-line (point))) + (setq window-selection-change-functions '(pulse-line)) ``` -This allows super-convenient marking of entries for later `embark-all` using control-tab, instead of having to go first through the `embark` menu. (By default, this key binding is mapped to `file-cache-minibuffer-complete`, which I never use.) - -## u/JDRiverRun [πŸ”—](https://www.reddit.com/r/emacs/comments/1933co6/comment/khe4dq6) -**Votes:** 11 - -I have long had convenience bindings for `org-emphasize` like `super-i` for /italic/, that match system bindings. But I always wanted these to *be smarter*, i.e. do something useful when there is no text selected. Something like intelligently toggling emphasis depending on whether you were already in the right kind of emphasized text, or just emphasize the word at point if not. - -[Check out my solution](https://gist.github.com/jdtsmith/55e6a660dd4c0779a600ac81bf9bfc23) (scroll down to see how it acts). Will miss this behavior in other apps! ## u/ayy_ess [πŸ”—](https://www.reddit.com/r/emacs/comments/18hc301/comment/kdobd72) **Votes:** 11 @@ -1365,78 +1324,115 @@ Do you want a key binding to wrap the selection in some kind of delimiter? Here' ``` This setups up `C-S-w` to be a prefix map, `insert-pair-map`. The only key binding in `insert-pair-map` is for `[t]`, which means it is the default key binding and any key after the prefix will run the same command: `insert-pair`. Now, `insert-pair` looks at which key was used to invoke it and if it is an opening delimiter it inserts both it and the corresponding closing delimiter (and if the region is active it insert the opening delimiter at the start and the closing delimiter at the end, wrapping the region). -## u/ainstr [πŸ”—](https://www.reddit.com/r/emacs/comments/vcpk6u/comment/ichiccu) +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/s21457/comment/hsgj7a6) **Votes:** 11 -The other day I discovered that you can access Spotify through dbus. Most of my use-case for spotify is hitting shuffle on ~20 of my playlists; not much searching, discovering, charts, etc. So, I didn't need any of the existing packages that require an auth token or extra local server. +Prevent horizontal scrolling from going too far left. + +I use Emacs on a laptop and quite often scroll with a touchpad. I also don't use line wrapping, as in code it usually looks misleading, so lines can sometimes exceed window width, either because of some long names or because the current window configuration is too narrow. + +However, when scrolling text sideways, there's a small annoyance that the scroll can go way too far to the left. E.g. if this is your window, and your text exceeds it: -This basically wraps `completing-read` over the alist stored in spotify-playlists. You can probably translate the qdbus call to dbus-send or whatever. ```elisp -;; Inspired by sp.sh: https://gist.github.com/wandernauta/6800547 -;; Could use https://codeberg.org/jao/espotify, but don't need all the functionalities -;; Potential Issues: https://community.spotify.com/t5/Desktop-Linux/DBus-OpenUri-issue/td-p/1376397 - -;; Could just write a fn to extract the ID, and use that in spotify-playlists -;; Current way with full uri allows for playlist vs artist, etc. -;; but probably don't need flexiblity for my use case -(defun spotify--clean-uri (raw-uri) - "Clean RAW-URI into a dbus-acceptable uri." - (let* ((url-fields (split-string - raw-uri - (rx (or "/" "?")))) - (type (nth 3 url-fields)) - (id (nth 4 url-fields))) - (concat "spotify:" type ":" id))) - -(defvar spotify-playlists - '(("Artist" . "https://open.spotify.com/playlist/1v4UqI9mEEB4ry3a3uaorO?si=bc675402c7384080")) - "Alist of spotify playlists for spotify-playlists to select from. - RAW-URI is from right-click on playlist > Share > Copy Link to Playlist.") - -(defun spotify--open-uri (raw-uri) - "Open RAW-URI." - (let ((prefix "qdbus org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.OpenUri ") - (uri (spotify--clean-uri raw-uri))) - (shell-command (concat prefix uri)))) - -(defun spotify--open-playlist () - "Prompt to select and play a playlist from spotify-playlists." - (let* ((key (completing-read "Playlist: " spotify-playlists)) - (raw-uri (cdr (assoc key spotify-playlists)))) - (spotify--open-uri raw-uri) - (message (format "Now Playing: %s" key)))) - -(defun spotify-open-playlist () - "Wrapper around `spotify--open-playlist`, to check if spotify is running." - (interactive) - (pcase - (shell-command "pgrep spotify") - (1 (message "Spotify not running.")) - (0 (spotify--open-playlist)))) +|Short line | +|Some really long line o| +|Another short line | + ``` +What I'd like to is to prevent scrolling any further than that: -## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/r69w7i/comment/hmst3ih) -**Votes:** 11 +```elisp +|line | +|eally long line of text| +|r short line | -macros in emacs are like a secret, forgotten art, but I use them with regexp search, orgmode commands to tweak repeating events (or any number of other uses). Learn macros; they gave emacs its name! One usage here: https://orys.us/ug +``` +But Emacs actually allows to scroll as far as one would want to, like here: -## u/yogsototh [πŸ”—](https://www.reddit.com/r/emacs/comments/qgrpte/comment/hi8crmc) -**Votes:** 11 +```elisp +| | +|t | +| | -I just made this nice combination of emacs packages and personal theme to achieve the cool effect of iAWriter +``` +This doesn't make sense to me, as you can't see anything at all. +Probably handy, when you write in really long lines, and you wish to have some buffer for adding more text without triggering scrolling, but I never needed that. So I wrote such predicate: -See here: https://her.esy.fun/posts/0021-ia-writer-clone-within-doom-emacs/index.html +```elisp +(defun truncated-lines-p () + "Non-nil if any line is longer than `window-width' + `window-hscroll'. + +Returns t if any line exceeds the right border of the window. +Used for stopping scroll from going beyond the longest line. +Based on `so-long-detected-long-line-p'." + (save-excursion + (goto-char (point-min)) + (let* ((window-width + ;; this computes a more accurate width rather than `window-width', and respects + ;; `text-scale-mode' font width. + (/ (window-body-width nil t) (window-font-width))) + (hscroll-offset + ;; `window-hscroll' returns columns that are not affected by + ;; `text-scale-mode'. Because of that, we have to recompute the correct + ;; `window-hscroll' by multiplying it with a non-scaled value and + ;; dividing it with a scaled width value, rounding it to the upper + ;; boundary. Since there's no way to get unscaled value, we have to get + ;; a width of a face that is not scaled by `text-scale-mode', such as + ;; `window-divider' face. + (ceiling (/ (* (window-hscroll) (window-font-width nil 'window-divider)) + (float (window-font-width))))) + (line-number-width + ;; compensate line numbers width + (if (bound-and-true-p display-line-numbers-mode) + (- display-line-numbers-width) + 0)) + ;; subtracting 2 for extra space in case some calculations were imprecise + (threshold (+ window-width hscroll-offset line-number-width -2))) + (catch 'excessive + (while (not (eobp)) + (let ((start (point))) + (save-restriction + (narrow-to-region start (min (+ start 1 threshold) + (point-max))) + (forward-line 1)) + (unless (or (bolp) + (and (eobp) (<= (- (point) start) + threshold))) + (throw 'excessive t)))))))) + +``` +This function can calculate window width, and line width, and check if any line in the buffer exceeds the window width screen-wise. By screen-wise I mean that if you've scrolled text to the left, it will begin to return `nil` once all lines don't exceed the right border of the window, thus achieving the described behavior in the diagrams. I then define advice around the `scroll-left` function, and it works pretty good: + +```elisp +(define-advice scroll-left (:around (foo &optional arg set-minimum)) + (when (and truncate-lines + (not (memq major-mode '(vterm-mode term-mode))) + (truncated-lines-p)) + (funcall foo arg set-minimum))) + +``` +Though it's not very accurate when using `text-scale-adjust`, as line width is not the same as before, the function, that reports how much the window was scrolled to the left still returns unscaled values. You can see my thoughts in the function's comments. Any suggestions on how to make it more accurate? ## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/q76kok/comment/hghtyfo) **Votes:** 11 before you load evil `(setq evil-want-minibuffer t)` to use evil-mode in the minibuffer. -## u/vatai [πŸ”—](https://www.reddit.com/r/emacs/comments/ojzv53/comment/h5584no) +## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/ojzv53/comment/h55vkl6) **Votes:** 11 -The emacs lisp tutorial is the real tutorial for emacs ;) +I often find myself wanting to be able to switch between `master` and a feature branch in magit quickly: + +```elisp +(defun lw-magit-checkout-last (&optional start-point) + (interactive) + (magit-branch-checkout "-" start-point)) +(transient-append-suffix 'magit-branch "w" + '("-" "last branch" lw-magit-checkout-last)) + +``` +So that `C-x g b -` switches to the last branch I was on, similar to `cd -`. ## u/PotentiallyAlice [πŸ”—](https://www.reddit.com/r/emacs/comments/n9q662/comment/gxx6frj) **Votes:** 11 @@ -1449,6 +1445,18 @@ I thought it might be a fun project to make a package to expose org-capture temp ``` Now I can hit "localhost:8080/capture/t/test reminder" and it'll put a "* TODO test reminder" line into my todo.org. Neat! +## u/Bodertz [πŸ”—](https://www.reddit.com/r/emacs/comments/lfww57/comment/gmtk79e) +**Votes:** 11 + +From the mailing list, I've just learned of `generic-x.el`, which provides syntax highlighting for `/etc/fstab` or `/etc/passwd` and the like. I appreciated that vim provided that out of the box and I was surprised that emacs also does, but it's just disabled. + +`(require 'generic-x)` to enable it. + +## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/kvmmq3/comment/gj9ioly) +**Votes:** 11 + +Just a cool concept: if you have a keypad on your keyboard which you rarely use, bind its nums to something useful. The results are numlock-sensitive and are NOT the same keycodes as regular numbers, so they're just free keys. For example, `(define-key map (kbd "") 'winum-select-window-1)` + ## u/Krautoni [πŸ”—](https://www.reddit.com/r/emacs/comments/ja97xs/comment/g8pgyy1) **Votes:** 11 @@ -1480,141 +1488,77 @@ When you commit with (ma)git, the pair programmer is inserted as a co-author. Additionally, line number mode is enabled." :global t :lighter " PP" - (if pair-programming-mode - (enable-pair-programming-mode) -(disable-pair-programming-mode))) - -(defun insert-pair-programmer-as-coauthor () - "Insert your pair programer into the current git commit." - (when (and pair-programming-mode git-commit-mode) -(pcase pair-programming--pair-programmer - (`(,name ,email) (git-commit-insert-header "Co-authed-by" name email)) - (_ (error "No pair programmer found or wrong content"))))) - -(add-hook 'git-commit-setup-hook 'insert-pair-programmer-as-coauthor) -``` - -It sets up a co-authored-by for git commits, and enables line numbers. - -## u/Rotatop [πŸ”—](https://www.reddit.com/r/emacs/comments/hij4ga/comment/fwi4ikt) -**Votes:** 11 - -I've made it ! - -After 6 month of emacs, I m able to open a side buffer when I m on ivy without using C-c C-O or hydra or alt-enter but directly with shift + arrow (except for Up because I need to go on buffer) - - -```elisp -;; Auto create new window -(setq windmove-create-window t) -;; thanks to https://people.gnome.org/~federico/blog/bringing-my-emacs-from-the-past.html -;; Let me switch windows with shift-arrows instead of "C-x o" all the time -(windmove-default-keybindings) - -;; Ugly hack : -;; What I want is to Shift arrow, then it open the selection on a new splitted window (up left right, down) -(defun tim/ivy-down-other () - (interactive) - (ivy-exit-with-action #'tim/ivy-down-exit)) - -(defun tim/ivy-left-other () - (interactive) - (ivy-exit-with-action #'tim/ivy-left-exit)) - -(defun tim/ivy-right-other () - (interactive) - (ivy-exit-with-action #'tim/ivy-right-exit)) - -(defun tim/ivy-down-exit (ivy-body) - (split-window-below) - (other-window 1) - (tim/reuse-open-goto-line ivy-body)) - -(defun tim/ivy-left-exit (ivy-body) - (split-window-right) - (tim/reuse-open-goto-line ivy-body)) - -(defun tim/ivy-right-exit (ivy-body) - (split-window-right) - (other-window 1) - (tim/reuse-open-goto-line ivy-body)) - - -;; Thanks to -;; https://github.com/abo-abo/swiper/blob/master/doc/ivy.org#actions and -;; https://www.reddit.com/r/emacs/comments/efg362/ivy_open_selection_vertically_or_horizontally/ -(defun tim/reuse-open-goto-line (ivy-body) - (message "reuse-open-goto-line ivy-body: %s" ivy-body) - (let* ((tim/list (split-string ivy-body ":")) - (file (car tim/list)) - (tim/number (car (cdr tim/list)))) - - (condition-case err - (counsel-projectile-find-file-action file) - (void-function ; <- that s the error handler name - (message "open fail with projectile, try find-file. Error was: %s" err) - (find-file file))) - ;; Thanks to https://stackoverflow.com/questions/3139970/open-a-file-at-line-with-filenameline-syntax - (when tim/number - ;; goto-line is for interactive use - (goto-char (point-min)) - (forward-line (1- (string-to-number tim/number)))))) - ;; (ivy-resume)) ; It s strange but ivy-resume here change the way that 'ENTER' or ivy-done works afterwards - ;; Try, as a workaround , in a timer ; no luck - ;; (run-with-timer 0.1 nil 'ivy-resume)) - -(use-package! ivy - :bind (:map ivy-minibuffer-map - ("C-p" . ivy-previous-history-element) - ("" . tim/ivy-down-other) - ;; no up to avoid changing buffer problems - ("" . tim/ivy-left-other) - ("" . tim/ivy-right-other)) + (if pair-programming-mode + (enable-pair-programming-mode) +(disable-pair-programming-mode))) + +(defun insert-pair-programmer-as-coauthor () + "Insert your pair programer into the current git commit." + (when (and pair-programming-mode git-commit-mode) +(pcase pair-programming--pair-programmer + (`(,name ,email) (git-commit-insert-header "Co-authed-by" name email)) + (_ (error "No pair programmer found or wrong content"))))) +(add-hook 'git-commit-setup-hook 'insert-pair-programmer-as-coauthor) ``` -Emacs is good +It sets up a co-authored-by for git commits, and enables line numbers. -## u/rhmatthijs [πŸ”—](https://www.reddit.com/r/emacs/comments/h9zoy9/comment/fuzucay) +## u/jimm [πŸ”—](https://www.reddit.com/r/emacs/comments/heaoiu/comment/fvqvedf) **Votes:** 11 -On a Mac: make Emacs detect if you have light or dark mode enabled system wide. +I can't say how often I use `dabbrev-expand` (`M-/`) to complete words. Saves me a ton of time. -If you have two themes, a light one and a dark one, and you want the dark theme by default unless you have light mode enabled, add this to your init.el: +## u/oantolin [πŸ”—](https://www.reddit.com/r/emacs/comments/g5bat3/comment/fo362s8) +**Votes:** 11 -```elisp -;; If we're on a Mac and the file "~/bin/get_dark.osascript" exists -;; and it outputs "false", activate light mode. Otherwise activate -;; dark mode. -(cond ((and (file-exists-p "~/bin/get_dark.osascript") - (string> (shell-command-to-string "command -v osascript") "") - (equal "false\n" - (shell-command-to-string "osascript ~/bin/get_dark.osascript"))) - (mcj/theme-set-light)) - (t (mcj/theme-set-dark))) +`rx` isn't just an (extensible!) sexp syntax for regexps, it's an optimizing compiler! + +Examples: +- `(rx (or "dude@home.org" "dude@work.com"))` produces +```elisp +`"\\(?:dude@\\(?:home\\.org\\|work\\.com\\)\\)"` ``` -(mcj/theme-set-light and mcj/theme-set-light are functions that enable the light and the dark theme, respectively). +- `(rx (intersection (any (?g . ?z)) (any (?a . ?p))))` produces `"[g-p]"` -~/bin/get_dark.osascript contains the following: +And from Lisp code it's easy to plug in computed portions, using `eval`. +For example I recently used this in some silly code to count mentions +of animals in the bible :P: ```elisp -tell application "System Events" - tell appearance preferences - get dark mode - end tell -end tell +(defun plural (word) + (pcase word + ("mouse" "mice") + ("wolf" "wolves") + ("fish" "fishes") + (word (concat word "s")))) + +(defun bible-count (word) + "Count number of times WORD or its plural appears in the bible." + (with-current-buffer "king-james-bible.txt" + (count-matches + (rx-to-string `(word-start (or ,word ,(plural word)) word-end))))) + ``` +Which I used to make an Org mode table with an Emacs Lisp column formula: -## u/xu_chunyang [πŸ”—](https://www.reddit.com/r/emacs/comments/fo1fm3/comment/flcwsu4) -**Votes:** 11 +```elisp +#+TBLFM: $2='(bible-count $1) -Happy Birthday from Emacs, let's assume March 24 is your birthday, put this to your init file, when you open Emacs on your birthday, you'll receive a birthday present from Emacs +``` +**EDIT**: A previous version of the `bible-count` function used the `rx` macro and the `eval` construct: ```elisp -(when (string= "03-24" (format-time-string "%m-%d")) - (animate-birthday-present user-full-name)) +(defun bible-count (word) + "Count number of times WORD or its plural appears in the bible." + (with-current-buffer "king-james-bible.txt" + (count-matches (rx word-start + (or (eval word) (eval (plural word))) + word-end)))) + ``` +This version is incorrect: `eval` is meant to be used only for value known at compile time. It's actual [behavior is very complicated](https://www.reddit.com/r/emacs/comments/g5bat3/weekly_tipstricketc_thread/fo7qdas) and depends on plenty of seemingly extraneous circumstances. ## u/oantolin [πŸ”—](https://www.reddit.com/r/emacs/comments/fgahb2/comment/fk3in25) **Votes:** 11 @@ -1635,87 +1579,109 @@ Most people probably know that `M-t` (`transpose-words`) when used between two w That last trick works with the other `transpose-` commands as well, not just words: `transpose-chars`, `transpose-lines`, `transpose-paragraphs`, `transpose-sentences`, and `transpose-sexps`. Of course, if that `C-0` trick can't be used with any of those commands to swap the two things you want, there is always `transpose-regions`. -## u/primitiveinds [πŸ”—](https://www.reddit.com/r/emacs/comments/erro41/comment/ff90d5b) +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/domrl6/comment/f5qf3jw) **Votes:** 11 -I just now figured out that you can interactively pass flags to commands like `counsel-rg` by putting the `--` separator between the flags and the search string, so something like `-g '*.txt' -- whatever` will search for `whatever` only in `txt` files. `counsel` uses a function called `counsel--split-command-args` to split the parts before and after the `--`. +[deleted] -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/1aky57w/comment/kpct4cp) -**Votes:** 10 +## u/ProfessorSexyTime [πŸ”—](https://www.reddit.com/r/emacs/comments/dlethf/comment/f4wdyaf) +**Votes:** 11 -Many of you probably know of this, but I found "indirect buffers" useful. +I feel like a lot of us average Emacs users miss out on a lot of functionality Emacs provides outside of the box. So some things you might find interesting: -When I'm in Vim, I've found it useful to sometimes split a buffer into two windows, and use code folding to view different parts of the same file in the two windows. But this doesn't work in Emacs, because the "folding" and "narrow" states of the buffer are synced between the windows in contrast to Vim. One concrete use case I had: I have a huge Org file, and wanted to narrow `C-x n s` into different headings of the file in different windows. +#### [Registers](https://www.gnu.org/software/emacs/manual/html_node/emacs/Registers.html) -Indirect buffers solve this. It makes two buffers for one file, and these buffers have separate settings for folding, narrowing, etc. But the buffer contents are still synced, so there's no risk of diverging file states. With default keybindings, I found that `C-x 4 c C-x n s` did what I wanted. +Someone posted this in a weekly tips/trick/etc thread a few weeks ago, but I thought I'd mention it again. -## u/bopboa [πŸ”—](https://www.reddit.com/r/emacs/comments/1aky57w/comment/kphrvz3) -**Votes:** 10 +Registers just let you store *things* in them. This can be -This is how to have a beacon without installing any packages. +- Cursor positions in buffers (`C-x r SPC [name you want to give the register]`) +- Text in a region (`C-x r s [name you want to give the register]`) +- Rectangles (`C-x r r [name you want to give the register]`) +- State of windows in frames (`C-x r w [name you want to give the register]`) +- State of all frames and their windows (`C-x r f [name you want to give the register]`) +- Numbers (`C-x r n [name you want to give the register]`) and you can increment those numbers (`C-x r + [name of register you want to increment`] +- Whole file names (it's not bound, but you can do `M-: (set-register ?z '(file . "/some_file/somewhere/some_text.txt"))`) +- Keyboard macros instead of saving them (` C-x C-k x [name you want to give the register]`) + +You can insert text, registers, or numbers with `C-x r i [name of register with stuff to insert]`. You can also append or prepend stuff to registers with `append-to-register` or `prepend-to-register`. + +`C-x r j [name of register]` can jump to a point, restore a window or frame configuration, or visit a file with a specific name. + +You could always use [bookmarks](https://www.gnu.org/software/emacs/manual/html_node/emacs/Bookmarks.html#Bookmarks). + +One thing I would like to do is automatically give registers names, say like a1, a2, et cetera then b1, b2 et cetera, and then A1, A2 and yaddah yaddah. + +I'm an idiot though and generating that sort of collection escapes me a bit. + +I'd rather not do just ```elisp - (defun pulse-line (_) - (pulse-momentary-highlight-one-line (point))) - (setq window-selection-change-functions '(pulse-line)) +(loop n from 0 to 99 + collect (concat "a" n)) + ``` +for every alphabetical character. Then it'd be a matter of going through those collections for every register created and making sure they use different names. Was wondering if I could get some help. -## u/algor512 [πŸ”—](https://www.reddit.com/r/emacs/comments/18xebux/comment/kg4ni5d) -**Votes:** 10 +#### [Isearch](https://www.emacswiki.org/emacs/IncrementalSearch) and [Query Replace](https://www.gnu.org/software/emacs/manual/html_node/emacs/Query-Replace.html) -Recently I discovered that `C-h C-q` (or `M-x help-quick`) opens a small window showing \*Quick Help\* buffer with a nice overview of some basic keybindings. It seems that the content of this buffer is configurable via the variable `help-quick-sections`. +Not much to say here, just that I might recommend that one go over the default keys for [isearch](https://www.emacswiki.org/emacs/IncrementalSearch#toc2) and query-replace. -I intend to use it as a cheatsheet, reminding me about rare keybindings I always forget; I believe it is easy to make it context-dependent, just by changing the value of `help-quick-sections`. +Also I would switch `C-s` and `C-r` to use `isearch-forward-regex` and `isearch-backward-regex`, and `M-%` to use `query-replace-regex` because you can disable the use of regex for both. You can even start a query-replace from isearch with `M-%` or `C-M-%`. -## u/leothrix [πŸ”—](https://www.reddit.com/r/emacs/comments/17qh1hn/comment/k8dlt4c) -**Votes:** 10 +#### `event-apply-*` Keys -Need to remove an element from a list when you're tinkering with elisp? +I don't really know what I can use these keys for, but with which-key you can press `C-x @` to see them. They allow you to apply control, shift, alt, meta, super, or hyper keys. -Sometimes when I'm adding and removing elements from hooks or variables like `completion-at-point-functions` I'll often need to tinker with the symbols I've added. You could evaluate some form somewhere, but I like to be lazy and just: +## u/badmaxton [πŸ”—](https://www.reddit.com/r/emacs/comments/19ec8v5/comment/kjcu7vp) +**Votes:** 10 + +Just added this to the `:init` section of my embark configuration: ```elisp -M-x remove-hook +(define-key minibuffer-local-map [C-tab] 'embark-select) ``` -And you've got an interactive interface (using `completing-read`) for removing arbitrary elements from any list-like variable. It's _technically_ for altering hooks, but you can abuse it to fool around with lists, too. +This allows super-convenient marking of entries for later `embark-all` using control-tab, instead of having to go first through the `embark` menu. (By default, this key binding is mapped to `file-cache-minibuffer-complete`, which I never use.) -## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/15sjm3k/comment/jwff8bw) +## u/JDRiverRun [πŸ”—](https://www.reddit.com/r/emacs/comments/1933co6/comment/khe4dq6) **Votes:** 10 -I've been slowly accumulating cases for "flexing" the thing at point as a more general `capitalize-word` replacement: +I have long had convenience bindings for `org-emphasize` like `super-i` for /italic/, that match system bindings. But I always wanted these to *be smarter*, i.e. do something useful when there is no text selected. Something like intelligently toggling emphasis depending on whether you were already in the right kind of emphasized text, or just emphasize the word at point if not. + +[Check out my solution](https://gist.github.com/jdtsmith/55e6a660dd4c0779a600ac81bf9bfc23) (scroll down to see how it acts). Will miss this behavior in other apps! + +## u/algor512 [πŸ”—](https://www.reddit.com/r/emacs/comments/18xebux/comment/kg4ni5d) +**Votes:** 10 + +Recently I discovered that `C-h C-q` (or `M-x help-quick`) opens a small window showing \*Quick Help\* buffer with a nice overview of some basic keybindings. It seems that the content of this buffer is configurable via the variable `help-quick-sections`. + +I intend to use it as a cheatsheet, reminding me about rare keybindings I always forget; I believe it is easy to make it context-dependent, just by changing the value of `help-quick-sections`. + +## u/camel_case_t [πŸ”—](https://www.reddit.com/r/emacs/comments/18xebux/comment/kgce54q) +**Votes:** 10 + +This is maybe more a macOS tip than an Emacs tip, but it always bothered me that `C-f`, `C-b`, etc worked in any text box, but not `M-f`, etc -- turns out that you can easily change that throughout the OS! + +I created this file and now Emacs keybindings work everywhere: ```elisp -;; Stolen from the wiki somewhere -(defun increment-number-at-point () - "Increment the number at point." - (interactive) - (skip-chars-backward "0-9") - (or (looking-at "[0-9]+") - (error "No number at point")) - (replace-match (number-to-string (1+ (string-to-number (match-string 0)))))) - -(defun lw-flex () - "Perform smart flexing at point. - -E.g. capitalize or decapitalize the next word, increment number at point." - (interactive) - (let ((case-fold-search nil)) - (call-interactively - (cond ((looking-at "[0-9]+") #'increment-number-at-point) - ((looking-at "[[:lower:]]") #'capitalize-word) - ((looking-at "==") (delete-char 1) (insert "!") (forward-char 2)) - ((looking-at "!=") (delete-char 1) (insert "=") (forward-char 2)) - ((looking-at "+") (delete-char 1) (insert "-") (forward-char 1)) - ((looking-at "-") (delete-char 1) (insert "+") (forward-char 1)) - ((looking-at "<=") (delete-char 2) (insert ">=") (forward-char 2)) - ((looking-at ">=") (delete-char 2) (insert "<=") (forward-char 2)) - ((looking-at "<") (delete-char 1) (insert ">") (forward-char 1)) - ((looking-at ">") (delete-char 1) (insert "<") (forward-char 1)) - (t #'downcase-word))))) +/* ~/Library/KeyBindings/DefaultKeyBinding.dict */ +{ + /* Additional Emacs bindings */ + "~f" = "moveWordForward:"; + "~b" = "moveWordBackward:"; + "~<" = "moveToBeginningOfDocument:"; + "~>" = "moveToEndOfDocument:"; + "~v" = "pageUp:"; + "~d" = "deleteWordForward:"; + "~^h" = "deleteWordBackward:"; + "~\010" = "deleteWordBackward:"; /* Option-backspace */ + "~\177" = "deleteWordBackward:"; /* Option-delete */ +} ``` -I bind it to `M-c`. +You can read more here: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/TextDefaultsBindings/TextDefaultsBindings.html ## u/gusbrs [πŸ”—](https://www.reddit.com/r/emacs/comments/14l3jn8/comment/jpwn2ts) **Votes:** 10 @@ -1748,66 +1714,14 @@ I found myself debugging [JWTs](https://jwt.io) earlier this week and whomped up I'd forgotten about `with-output-to-temp-buffer` which is pretty handy. The `t` at the end is there just to suppress an overly large echo area message. -(This should be obvious but note that the JWT is not validated or verified. This is intended for debugging only and the JWT should not be trusted.) - -## u/noi-gai [πŸ”—](https://www.reddit.com/r/emacs/comments/112t0uo/comment/j8mo1bz) -**Votes:** 10 - -Put the control keys next to space, mimicking mac's command key (which is effectively used as the equivalent of ctrl yet next to the space it's easier to press) - -Win - Alt - Ctrl - Space - Ctrl - Alt - Win - -## u/AnugNef4 [πŸ”—](https://www.reddit.com/r/emacs/comments/112t0uo/comment/ja41lso) -**Votes:** 10 - -How I got my Info Directory node `C-h i` to display all my installed .info files living under `/opt/homebrew` on an M1 Mac. I run emacs-plus@29 from [d12frosted on github](https://github.com/d12frosted/homebrew-emacs-plus). - -init.el snippet - -```elisp -(require 'info) -(info-initialize) -(push "/opt/homebrew/share/info" Info-directory-list) - -``` -run this shell script to update the Directory node. - -```elisp -#!/usr/bin/env bash - -INFO_DIR="/opt/homebrew/share/info" -while read -r f; do - install-info --debug --keep-old "$f" "$INFO_DIR"/dir -done <<< $(find /opt/homebrew/Cellar -name \*.info) -``` - -## u/Nondv [πŸ”—](https://www.reddit.com/r/emacs/comments/108zin2/comment/j4ct1y1) -**Votes:** 10 - -Maybe not new for anyone but I only recently found out that `C-c ` is conventionally reserved for user bindings. I was constantly afraid to define my own bindings bc of a potential clash so tended to use M-x instead. Now I finally bind my most used commands. - -With the above in mind, Im also afraid to forget my bindings. I use which-key package so I wrote a function "define-my-keybinding letter fn" which binds the letter to `C-c ` and to "my-bindings" keyset (prefix) which itself is bound to `C-c m`. Basically, if i forget what bindings I use, I just press C-c m and which-key shows me all of MY bindings (yes, it shows them with C-c too but it's mixed with mode bindings so not helpful) - -## u/luiggi_oasis [πŸ”—](https://www.reddit.com/r/emacs/comments/zred55/comment/j14grej) -**Votes:** 10 - -What's the deal with all these completion framework I keep hearing about? Vertical elm ivy company and whatnot. - -I think I have company in my init.el but I'm not even sure I'm actually using it (maybe I am and I'm just unaware). But why are they everywhere? I see them mentioned in at least every any two emacs threads. - -## u/kickingvegas1 [πŸ”—](https://www.reddit.com/r/emacs/comments/x7zfs2/comment/innk62a) -**Votes:** 10 - -TIL when working with an Org table that `S-RET` will fill the current cell value with the value above it. +(This should be obvious but note that the JWT is not validated or verified. This is intended for debugging only and the JWT should not be trusted.) -## u/hairlesscaveman [πŸ”—](https://www.reddit.com/r/emacs/comments/wqjare/comment/ikwhvfs) +## u/noi-gai [πŸ”—](https://www.reddit.com/r/emacs/comments/112t0uo/comment/j8mo1bz) **Votes:** 10 -Question: I generally work with 3 vertical panes, with my preferred layout as left for code, middle for related test file, and right for test output or magit. However, keeping this layout is tricky; sometimes magit will open in the first pane, or the current pane when I'm focused in the middle, and deadgrep will open just anywhere… well, it's quite hectic and feels random. - -Is there any way I can get files to open in panes 1 or 2, and always have things like magit/test-output/deadgrep/etc on pane 3? I've tried "shackle" but I've had no success with it; everything seems to open in a horizontal pane at the bottom of my screen regardless of config. +Put the control keys next to space, mimicking mac's command key (which is effectively used as the equivalent of ctrl yet next to the space it's easier to press) -Any suggestions would be appreciated! +Win - Alt - Ctrl - Space - Ctrl - Alt - Win ## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/wqjare/comment/ikrx30z) **Votes:** 10 @@ -1829,6 +1743,57 @@ That sounds like great news! Does anyone know what went into it? (edit to add: this was added some time this week. I rebuild from master weekly, and check out the NEWS diff each time) +## u/ainstr [πŸ”—](https://www.reddit.com/r/emacs/comments/vcpk6u/comment/ichiccu) +**Votes:** 10 + +The other day I discovered that you can access Spotify through dbus. Most of my use-case for spotify is hitting shuffle on ~20 of my playlists; not much searching, discovering, charts, etc. So, I didn't need any of the existing packages that require an auth token or extra local server. + +This basically wraps `completing-read` over the alist stored in spotify-playlists. You can probably translate the qdbus call to dbus-send or whatever. + +```elisp +;; Inspired by sp.sh: https://gist.github.com/wandernauta/6800547 +;; Could use https://codeberg.org/jao/espotify, but don't need all the functionalities +;; Potential Issues: https://community.spotify.com/t5/Desktop-Linux/DBus-OpenUri-issue/td-p/1376397 + +;; Could just write a fn to extract the ID, and use that in spotify-playlists +;; Current way with full uri allows for playlist vs artist, etc. +;; but probably don't need flexiblity for my use case +(defun spotify--clean-uri (raw-uri) + "Clean RAW-URI into a dbus-acceptable uri." + (let* ((url-fields (split-string + raw-uri + (rx (or "/" "?")))) + (type (nth 3 url-fields)) + (id (nth 4 url-fields))) + (concat "spotify:" type ":" id))) + +(defvar spotify-playlists + '(("Artist" . "https://open.spotify.com/playlist/1v4UqI9mEEB4ry3a3uaorO?si=bc675402c7384080")) + "Alist of spotify playlists for spotify-playlists to select from. + RAW-URI is from right-click on playlist > Share > Copy Link to Playlist.") + +(defun spotify--open-uri (raw-uri) + "Open RAW-URI." + (let ((prefix "qdbus org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.OpenUri ") + (uri (spotify--clean-uri raw-uri))) + (shell-command (concat prefix uri)))) + +(defun spotify--open-playlist () + "Prompt to select and play a playlist from spotify-playlists." + (let* ((key (completing-read "Playlist: " spotify-playlists)) + (raw-uri (cdr (assoc key spotify-playlists)))) + (spotify--open-uri raw-uri) + (message (format "Now Playing: %s" key)))) + +(defun spotify-open-playlist () + "Wrapper around `spotify--open-playlist`, to check if spotify is running." + (interactive) + (pcase + (shell-command "pgrep spotify") + (1 (message "Spotify not running.")) + (0 (spotify--open-playlist)))) +``` + ## u/char1zard4 [πŸ”—](https://www.reddit.com/r/emacs/comments/v2by7z/comment/iarzi1s) **Votes:** 10 @@ -1847,43 +1812,10 @@ https://joaotavora.github.io/yasnippet/snippet-development.html#org41a4ac7 [deleted] -## u/jimm [πŸ”—](https://www.reddit.com/r/emacs/comments/tfcmcx/comment/i0vtxte) +## u/diamondnbond [πŸ”—](https://www.reddit.com/r/emacs/comments/us7zae/comment/i928gaj) **Votes:** 10 -The `git grep` git command is great for finding a regex (or a simple string) everywhere in a git repo. I define the following functions and bind the `git-grep` function to `F2`. It will prompt for a regex and search for that in the repo or, if you give it a numeric prefix like `C-u` it will read the current symbol at point (the word under the cursor) and search for that. Results appear in a grep buffer, so you can use `C-g C-n` and `C-g C-p` to navigate from one result to the next. - -```elisp -(defun git-root-dir () - "Returns the current directory's root Git repo directory, or -NIL if the current directory is not in a Git repo." - (let ((dir (locate-dominating-file default-directory ".git"))) - (when dir - (file-name-directory dir)))) - -(defun git-grep (arg) - "Runs 'git grep', starting the search in the current -directory's root git repo directory. - -By default, reads the regex from the minibuffer. With a prefix -argument, initializes the search string with the current symbol -at point." - (interactive "P") - (let* ((symbol-at-point (thing-at-point 'symbol)) - (regexp (if (and arg (symbol-at-point)) - (regexp-quote symbol-at-point) - (read-from-minibuffer - "Search regexp: " nil nil nil 'grep-find-history))) - - (default-directory (git-root-dir)) - (case-ignore-flag (and (isearch-no-upper-case-p regexp t) "-i")) - (cmd (concat "git grep --extended-regexp --line-number --full-name" - " --untracked " case-ignore-flag " -- \"" regexp "\"" - " | cut -c -240"))) - (while (equal "" regexp) - (setq regexp (read-from-minibuffer - "Search regexp (must not be the empty string): " nil nil nil 'grep-find-history))) - (grep-find cmd))) -``` +[I Recently discovered engine-mode.](https://github.com/DiamondBond/emacs/blob/master/config.org#initialize-engine-mode) ## u/shitterwithaclitter [πŸ”—](https://www.reddit.com/r/emacs/comments/s7lac1/comment/htnz373) **Votes:** 10 @@ -1896,6 +1828,11 @@ I recently had the idea to start emacs in org-mode but have a src block at the t initial-scratch-message "#+begin_src emacs-lisp\n;; This block is for text that is not saved, and for Lisp evaluation.\n;; To create a file, visit it with \\[find-file] and enter text in its buffer.\n\n#+end_src\n\n") ``` +## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/r69w7i/comment/hmst3ih) +**Votes:** 10 + +macros in emacs are like a secret, forgotten art, but I use them with regexp search, orgmode commands to tweak repeating events (or any number of other uses). Learn macros; they gave emacs its name! One usage here: https://orys.us/ug + ## u/SamTheComputerSlayer [πŸ”—](https://www.reddit.com/r/emacs/comments/qbvyza/comment/hhinrm4) **Votes:** 10 @@ -1936,10 +1873,15 @@ It's very similar to define-minor-mode, but with all the hooks, keymaps, and lig (load-theme 'dracula t))) ``` -## u/Stefan-Kangas [πŸ”—](https://www.reddit.com/r/emacs/comments/pxqvtm/comment/hf1gzs2) +## u/github-alphapapa [πŸ”—](https://www.reddit.com/r/emacs/comments/q2g1gq/comment/hfldw8n) **Votes:** 10 -Read [SICP](https://mitpress.mit.edu/sites/default/files/sicp/index.html). Preferably in Info, installable through MELPA or: [https://github.com/webframp/sicp-info](https://github.com/webframp/sicp-info) +One of the most useful bindings for me: + +```elisp +(use-package avy + :bind* (("C-j" . avy-goto-char-timer))) +``` ## u/Stefan-Kangas [πŸ”—](https://www.reddit.com/r/emacs/comments/pxqvtm/comment/hexdfiq) **Votes:** 10 @@ -1959,37 +1901,6 @@ With a prefix argument, `M-(` wraps in parenthesis that number of sexps. For exa There's more information in EmacsWiki: https://www.emacswiki.org/emacs/InsertPair -## u/oantolin [πŸ”—](https://www.reddit.com/r/emacs/comments/p28rl5/comment/h8utmh2) -**Votes:** 10 - -Imenu is pretty adictive and it's disappointing when some major mode doesn't support it. Luckily, it's fairly easy to cook up some regexps to provide imenu support in a new major mode. For example I recently noticed that customize buffers didn't have imenu support add I wrote this: - -```elisp -(defun configure-imenu-Custom () - (setq imenu-generic-expression - '(("Faces" "^\\(?:Show\\|Hide\\) \\(.*\\) face: \\[sample\\]" 1) - ("Variables" "^\\(?:Show Value\\|Hide\\) \\([^:\n]*\\)" 1)))) - -(add-hook 'Custom-mode-hook #'configure-imenu-Custom) - -``` -One subtlety with writing this is that the customize buffers show little triangles instead of the words "Show", "Hide" or "Show Value". To figure out what text is really in the buffer you can use `C-u C-x =` which tells you about any overlays at point. - -## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/ojzv53/comment/h55vkl6) -**Votes:** 10 - -I often find myself wanting to be able to switch between `master` and a feature branch in magit quickly: - -```elisp -(defun lw-magit-checkout-last (&optional start-point) - (interactive) - (magit-branch-checkout "-" start-point)) -(transient-append-suffix 'magit-branch "w" - '("-" "last branch" lw-magit-checkout-last)) - -``` -So that `C-x g b -` switches to the last branch I was on, similar to `cd -`. - ## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/o0zvb5/comment/h1znz1s) **Votes:** 10 @@ -2012,17 +1923,6 @@ Then I remembered `pcase`: ``` Much more readable! -## u/11fdriver [πŸ”—](https://www.reddit.com/r/emacs/comments/mpwapo/comment/gufsfeu) -**Votes:** 10 - -Sometimes I'm working on programs with functions a few pages long, and `follow-mode` means that I can open two windows of the same buffer side-by-side and have the text flow like a book between them. I can double or even triple the amount of lines I can view at one time. - -This has largely superseded what I might have used those code-overview map things for, which is difficult anyway, since I like to use Emacs from the terminal. - -It will keep the text aligned as you move through the file, and pairs well with binding `` and `` to the `scroll-up/down-line` commands in `xterm-mouse-mode`. - -If I'm studying/notetaking, I often end up with a few Emacs-windows arranged in a vertical stack. `winner-mode` or `window-configuration-to-register` are great, but if I want to quickly regain some vertical screen-real-estate without messing up the layout, then it's pretty intuitive to use `follow-mode` and just switch multiple windows to the same buffer, now they behave like one. - ## u/b3n [πŸ”—](https://www.reddit.com/r/emacs/comments/ml4wql/comment/gtkc524) **Votes:** 10 @@ -2079,53 +1979,151 @@ Related docs are [here](https://www.gnu.org/software/auctex/manual/auctex/Error- This totally changes the way you can handle errors messages. -## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/kvmmq3/comment/gj9ioly) +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/ikgfxd/comment/g3zeprg) **Votes:** 10 -Just a cool concept: if you have a keypad on your keyboard which you rarely use, bind its nums to something useful. The results are numlock-sensitive and are NOT the same keycodes as regular numbers, so they're just free keys. For example, `(define-key map (kbd "") 'winum-select-window-1)` +**Suggestion for moderators** - Consider putting a note in the weekly announcement for this thread that using 3 backquotes or tildes to make code blocks doesn't work for those of us using old reddit (so the code people post that way is almost unreadable) - and that indenting by 4 spaces is better for compatibility. +(Am I the only one who still uses old reddit? :-) ) -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/ixjcau/comment/g69no38) +## u/kastauyra [πŸ”—](https://www.reddit.com/r/emacs/comments/ibwzcu/comment/g1zlh2t) **Votes:** 10 -org-variable-pitch.el users might want to give [`valign`](https://github.com/casouri/valign) a look. It aligns your tables nicely, even with pictures (e.g. LaTeX previews) and links. The significance in context of OVP specifically is that you don't need to add `org-link` to `org-variable-pitch-fixed-faces` because valign-mode handles variable pitch links neatly in tables. +# 27.1 do GC if no frame has focus + +I am porting my [config](https://github.com/laurynas-biveinis/dotfiles) from 26.3 to 27.1, which had the tweak to do GC whenever a frame loses focus, originally from [MatthewZMD's config](https://github.com/MatthewZMD/.emacs.d) I think: +```elisp +(add-hook 'focus-out-hook #'garbage-collect) +```elisp +27.1 NEWS say more generic (and more correct) `after-focus-change-function` should be used instead. Which pointed out that I do not want to GC on just any frame going out of focus, if another frame is being focused instead. It might be a better idea to GC if no frames at all are focused. Somewhat surprisingly I was not able to find any public dotfiles repo implementing this to copy paste from, so I tried to write my own: +```elisp +(defun dotfiles--gc-on-last-frame-out-of-focus () + "GC if all frames are inactive." + (if (seq-every-p #'null (mapcar #'frame-focus-state (frame-list))) + (garbage-collect))) + +(add-function :after after-focus-change-function + #'dotfiles--gc-on-last-frame-out-of-focus) +``` + +## u/Rotatop [πŸ”—](https://www.reddit.com/r/emacs/comments/hij4ga/comment/fwi4ikt) +**Votes:** 10 + +I've made it ! + +After 6 month of emacs, I m able to open a side buffer when I m on ivy without using C-c C-O or hydra or alt-enter but directly with shift + arrow (except for Up because I need to go on buffer) + + +```elisp +;; Auto create new window +(setq windmove-create-window t) +;; thanks to https://people.gnome.org/~federico/blog/bringing-my-emacs-from-the-past.html +;; Let me switch windows with shift-arrows instead of "C-x o" all the time +(windmove-default-keybindings) + +;; Ugly hack : +;; What I want is to Shift arrow, then it open the selection on a new splitted window (up left right, down) +(defun tim/ivy-down-other () + (interactive) + (ivy-exit-with-action #'tim/ivy-down-exit)) + +(defun tim/ivy-left-other () + (interactive) + (ivy-exit-with-action #'tim/ivy-left-exit)) + +(defun tim/ivy-right-other () + (interactive) + (ivy-exit-with-action #'tim/ivy-right-exit)) + +(defun tim/ivy-down-exit (ivy-body) + (split-window-below) + (other-window 1) + (tim/reuse-open-goto-line ivy-body)) + +(defun tim/ivy-left-exit (ivy-body) + (split-window-right) + (tim/reuse-open-goto-line ivy-body)) + +(defun tim/ivy-right-exit (ivy-body) + (split-window-right) + (other-window 1) + (tim/reuse-open-goto-line ivy-body)) + + +;; Thanks to +;; https://github.com/abo-abo/swiper/blob/master/doc/ivy.org#actions and +;; https://www.reddit.com/r/emacs/comments/efg362/ivy_open_selection_vertically_or_horizontally/ +(defun tim/reuse-open-goto-line (ivy-body) + (message "reuse-open-goto-line ivy-body: %s" ivy-body) + (let* ((tim/list (split-string ivy-body ":")) + (file (car tim/list)) + (tim/number (car (cdr tim/list)))) + + (condition-case err + (counsel-projectile-find-file-action file) + (void-function ; <- that s the error handler name + (message "open fail with projectile, try find-file. Error was: %s" err) + (find-file file))) + ;; Thanks to https://stackoverflow.com/questions/3139970/open-a-file-at-line-with-filenameline-syntax + (when tim/number + ;; goto-line is for interactive use + (goto-char (point-min)) + (forward-line (1- (string-to-number tim/number)))))) + ;; (ivy-resume)) ; It s strange but ivy-resume here change the way that 'ENTER' or ivy-done works afterwards + ;; Try, as a workaround , in a timer ; no luck + ;; (run-with-timer 0.1 nil 'ivy-resume)) + +(use-package! ivy + :bind (:map ivy-minibuffer-map + ("C-p" . ivy-previous-history-element) + ("" . tim/ivy-down-other) + ;; no up to avoid changing buffer problems + ("" . tim/ivy-left-other) + ("" . tim/ivy-right-other)) + +``` + +Emacs is good -If you don't use OVP but use e.g. latex fragments in tables or just pictures, this one is still very helpful. +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/heaoiu/comment/fvqq7ck) +**Votes:** 10 -Kudos to the author, great little package. +Undo-tree and kill-ring are two of the best features in Emacs / packages. Change your life today. -## u/kastauyra [πŸ”—](https://www.reddit.com/r/emacs/comments/ibwzcu/comment/g1zlh2t) +## u/rhmatthijs [πŸ”—](https://www.reddit.com/r/emacs/comments/h9zoy9/comment/fuzucay) **Votes:** 10 -# 27.1 do GC if no frame has focus +On a Mac: make Emacs detect if you have light or dark mode enabled system wide. + +If you have two themes, a light one and a dark one, and you want the dark theme by default unless you have light mode enabled, add this to your init.el: -I am porting my [config](https://github.com/laurynas-biveinis/dotfiles) from 26.3 to 27.1, which had the tweak to do GC whenever a frame loses focus, originally from [MatthewZMD's config](https://github.com/MatthewZMD/.emacs.d) I think: -```elisp -(add-hook 'focus-out-hook #'garbage-collect) -```elisp -27.1 NEWS say more generic (and more correct) `after-focus-change-function` should be used instead. Which pointed out that I do not want to GC on just any frame going out of focus, if another frame is being focused instead. It might be a better idea to GC if no frames at all are focused. Somewhat surprisingly I was not able to find any public dotfiles repo implementing this to copy paste from, so I tried to write my own: ```elisp -(defun dotfiles--gc-on-last-frame-out-of-focus () - "GC if all frames are inactive." - (if (seq-every-p #'null (mapcar #'frame-focus-state (frame-list))) - (garbage-collect))) +;; If we're on a Mac and the file "~/bin/get_dark.osascript" exists +;; and it outputs "false", activate light mode. Otherwise activate +;; dark mode. +(cond ((and (file-exists-p "~/bin/get_dark.osascript") + (string> (shell-command-to-string "command -v osascript") "") + (equal "false\n" + (shell-command-to-string "osascript ~/bin/get_dark.osascript"))) + (mcj/theme-set-light)) + (t (mcj/theme-set-dark))) -(add-function :after after-focus-change-function - #'dotfiles--gc-on-last-frame-out-of-focus) ``` +(mcj/theme-set-light and mcj/theme-set-light are functions that enable the light and the dark theme, respectively). -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/heaoiu/comment/fvqq7ck) -**Votes:** 10 +~/bin/get_dark.osascript contains the following: -Undo-tree and kill-ring are two of the best features in Emacs / packages. Change your life today. +```elisp +tell application "System Events" + tell appearance preferences + get dark mode + end tell +end tell +``` -## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/heaoiu/comment/fvrlu40) +## u/primitiveinds [πŸ”—](https://www.reddit.com/r/emacs/comments/erro41/comment/ff90d5b) **Votes:** 10 -I've been using `M-|` (`shell-command-on-region`) frequently for years, and I only just stumbled on the fact that the region need not be active to use it. If it isn't, the command operates on the text from point to the end of the buffer. That's very reasonable and in line with various other commands, but the documentation doesn't mention it and so I never thought to try it. - -That saves me a call to `C-x h` (`mark-whole-buffer`) whenever I want to process the entire buffer, which is most of the time. Also, it's a minor distraction for the entire buffer to be highlighted when I'm composing my shell command, so it's nice to avoid that. - -Edited to add: Sorry folks, this doesn't work like I thought it did. See the coments below for details. +I just now figured out that you can interactively pass flags to commands like `counsel-rg` by putting the `--` separator between the flags and the search string, so something like `-g '*.txt' -- whatever` will search for `whatever` only in `txt` files. `counsel` uses a function called `counsel--split-command-args` to split the parts before and after the `--`. ## u/ji99 [πŸ”—](https://www.reddit.com/r/emacs/comments/eeyhdz/comment/fbxf389) **Votes:** 10 @@ -2157,44 +2155,45 @@ Update your hosts file to block internet ads with this function: (buffer-string)))))) ``` -## u/human_banana [πŸ”—](https://www.reddit.com/r/emacs/comments/eeyhdz/comment/fbyevye) +## u/primitiveinds [πŸ”—](https://www.reddit.com/r/emacs/comments/domrl6/comment/f5oz3bp) **Votes:** 10 -Have multiple machines where some things are available and other aren't? - -`when-available` takes a function name and if it exists, executes the rest. - +This is one of the things that I'm sure exists somewhere but I can't find it so I wrote a few lines. I work in a big monorepo and depend on `projectile` for navigation by adding `.projectile` files here and there, in subdirectories that I consider "projects". However there are some directories that e.g. contain libraries. If I want to work on all of them for e.g. refactoring, going into a project then locks me in that (I mean `projectile-find-file`) and I have to manually go into another project. Also I flood my projectile cache with little things that I might not use a lot. What I did was add some logic to create temporary root directories for projects, where I can then use `counsel-file-jump` and `counsel-ag`. I have some keybindings and with a prefix argument I am prompted to change the temp root. Here's the code: ```elisp -(defmacro when-available (func cmd) - "Execute CMD if FUNC exists as a function." - `(when (fboundp ,func) ,cmd)) - -``` -So you can deal with different environments. - -I mostly use this for things that are nice to have, but aren't required and don't need to be installed if they aren't already. +(defvar my/temp-project-root nil) -## u/clemera [πŸ”—](https://www.reddit.com/r/emacs/comments/drw8i3/comment/f6ys5ae) -**Votes:** 10 +(defun my/get-or-set-temp-root (reset) + (let* ((reset-root (if reset my/temp-project-root nil)) + (root + (if (or reset + (null my/temp-project-root) + (not (file-directory-p my/temp-project-root))) + (read-directory-name "Temp root dir: " reset-root) + my/temp-project-root))) +(setq my/temp-project-root root))) -My fav org-bullets config, looks nice and you immediately know which headline level you have: +(defun my/counsel-file-jump-temp-root (reset) + (interactive "P") + (my/get-or-set-temp-root reset) + (let ((current-prefix-arg nil)) +(counsel-file-jump nil my/temp-project-root))) -```elisp - (setq org-bullets-bullet-list - '("β“ͺ" "β‘ " "β‘‘" "β‘’" "β‘£" "β‘€" "β‘₯" "⑦" "⑧" "⑨")) +(defun my/counsel-ag-temp-root (reset) + (interactive "P") + (my/get-or-set-temp-root reset) + (let ((current-prefix-arg nil)) +(counsel-ag "" my/temp-project-root))) ``` +Also `counsel-file-jump` is so good -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/domrl6/comment/f5qf3jw) -**Votes:** 10 - -[deleted] +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/1aky57w/comment/kpct4cp) +**Votes:** 9 -## u/c17g [πŸ”—](https://www.reddit.com/r/emacs/comments/domrl6/comment/f65iky4) -**Votes:** 10 +Many of you probably know of this, but I found "indirect buffers" useful. -I just found out the great variable `org-extend-today-until`. Basically it defines when your day really ends. If you sleep late, check it out. +When I'm in Vim, I've found it useful to sometimes split a buffer into two windows, and use code folding to view different parts of the same file in the two windows. But this doesn't work in Emacs, because the "folding" and "narrow" states of the buffer are synced between the windows in contrast to Vim. One concrete use case I had: I have a huge Org file, and wanted to narrow `C-x n s` into different headings of the file in different windows. -Goodbye to the days using `M-x org-todo-yesterday` at midnight, clocking off items before sleep.. +Indirect buffers solve this. It makes two buffers for one file, and these buffers have separate settings for folding, narrowing, etc. But the buffer contents are still synced, so there's no risk of diverging file states. With default keybindings, I found that `C-x 4 c C-x n s` did what I wanted. ## u/lesliesrussell [πŸ”—](https://www.reddit.com/r/emacs/comments/198rnkj/comment/kibmgv2) **Votes:** 9 @@ -2213,30 +2212,18 @@ This is a neat way to create a custom, modal-like interface for movement within I didn't want to drop code in the thread so i put it in a gist -## u/camel_case_t [πŸ”—](https://www.reddit.com/r/emacs/comments/18xebux/comment/kgce54q) +## u/leothrix [πŸ”—](https://www.reddit.com/r/emacs/comments/17qh1hn/comment/k8dlt4c) **Votes:** 9 -This is maybe more a macOS tip than an Emacs tip, but it always bothered me that `C-f`, `C-b`, etc worked in any text box, but not `M-f`, etc -- turns out that you can easily change that throughout the OS! +Need to remove an element from a list when you're tinkering with elisp? -I created this file and now Emacs keybindings work everywhere: +Sometimes when I'm adding and removing elements from hooks or variables like `completion-at-point-functions` I'll often need to tinker with the symbols I've added. You could evaluate some form somewhere, but I like to be lazy and just: ```elisp -/* ~/Library/KeyBindings/DefaultKeyBinding.dict */ -{ - /* Additional Emacs bindings */ - "~f" = "moveWordForward:"; - "~b" = "moveWordBackward:"; - "~<" = "moveToBeginningOfDocument:"; - "~>" = "moveToEndOfDocument:"; - "~v" = "pageUp:"; - "~d" = "deleteWordForward:"; - "~^h" = "deleteWordBackward:"; - "~\010" = "deleteWordBackward:"; /* Option-backspace */ - "~\177" = "deleteWordBackward:"; /* Option-delete */ -} +M-x remove-hook ``` -You can read more here: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/TextDefaultsBindings/TextDefaultsBindings.html +And you've got an interactive interface (using `completing-read`) for removing arbitrary elements from any list-like variable. It's _technically_ for altering hooks, but you can abuse it to fool around with lists, too. ## u/Netherus [πŸ”—](https://www.reddit.com/r/emacs/comments/17qh1hn/comment/k8c4mz7) **Votes:** 9 @@ -2252,19 +2239,42 @@ If you have two buffers open in one frame, where one contains just a few lines a And if you want to balance these two buffers again just use `C-x +` -## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/12cd23k/comment/jf3ohpv) +## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/15sjm3k/comment/jwff8bw) **Votes:** 9 -I work with multiple Git repositories in my day job, but one in particular occupies 95% of my time. I've often wished I could set up Projectile so that if I run one of its commands while not in any repo, it will behave as if I'd changed to that main repo first. I couldn't find a built-in way to do that, but got the effect I wanted with some advice: +I've been slowly accumulating cases for "flexing" the thing at point as a more general `capitalize-word` replacement: ```elisp -(defun default-to-main-project (dir) - (or dir *main-project-dir*)) - -(advice-add 'projectile-ensure-project :override #'default-to-main-project) +;; Stolen from the wiki somewhere +(defun increment-number-at-point () + "Increment the number at point." + (interactive) + (skip-chars-backward "0-9") + (or (looking-at "[0-9]+") + (error "No number at point")) + (replace-match (number-to-string (1+ (string-to-number (match-string 0)))))) + +(defun lw-flex () + "Perform smart flexing at point. + +E.g. capitalize or decapitalize the next word, increment number at point." + (interactive) + (let ((case-fold-search nil)) + (call-interactively + (cond ((looking-at "[0-9]+") #'increment-number-at-point) + ((looking-at "[[:lower:]]") #'capitalize-word) + ((looking-at "==") (delete-char 1) (insert "!") (forward-char 2)) + ((looking-at "!=") (delete-char 1) (insert "=") (forward-char 2)) + ((looking-at "+") (delete-char 1) (insert "-") (forward-char 1)) + ((looking-at "-") (delete-char 1) (insert "+") (forward-char 1)) + ((looking-at "<=") (delete-char 2) (insert ">=") (forward-char 2)) + ((looking-at ">=") (delete-char 2) (insert "<=") (forward-char 2)) + ((looking-at "<") (delete-char 1) (insert ">") (forward-char 1)) + ((looking-at ">") (delete-char 1) (insert "<") (forward-char 1)) + (t #'downcase-word))))) ``` -I lose some of the functionality of `projectile-ensure-project`, but I never used it anyway. +I bind it to `M-c`. ## u/slinchisl [πŸ”—](https://www.reddit.com/r/emacs/comments/11rq2gl/comment/jca66k0) **Votes:** 9 @@ -2291,125 +2301,151 @@ For example, I recently wanted a function that prints a set of predefined dates insert))) ``` -## u/andyjda [πŸ”—](https://www.reddit.com/r/emacs/comments/yqciht/comment/iw00xhx) +## u/AnugNef4 [πŸ”—](https://www.reddit.com/r/emacs/comments/112t0uo/comment/ja41lso) +**Votes:** 9 + +How I got my Info Directory node `C-h i` to display all my installed .info files living under `/opt/homebrew` on an M1 Mac. I run emacs-plus@29 from [d12frosted on github](https://github.com/d12frosted/homebrew-emacs-plus). + +init.el snippet + +```elisp +(require 'info) +(info-initialize) +(push "/opt/homebrew/share/info" Info-directory-list) + +``` +run this shell script to update the Directory node. + +```elisp +#!/usr/bin/env bash + +INFO_DIR="/opt/homebrew/share/info" +while read -r f; do + install-info --debug --keep-old "$f" "$INFO_DIR"/dir +done <<< $(find /opt/homebrew/Cellar -name \*.info) +``` + +## u/luiggi_oasis [πŸ”—](https://www.reddit.com/r/emacs/comments/zred55/comment/j14grej) +**Votes:** 9 + +What's the deal with all these completion framework I keep hearing about? Vertical elm ivy company and whatnot. + +I think I have company in my init.el but I'm not even sure I'm actually using it (maybe I am and I'm just unaware). But why are they everywhere? I see them mentioned in at least every any two emacs threads. + +## u/andyjda [πŸ”—](https://www.reddit.com/r/emacs/comments/yqciht/comment/iw00xhx) +**Votes:** 9 + +I started using `god-mode`, but I found it hard to get used to it at first: there was no easy way to check what command would be triggered by what key-sequence. + +I wrote up a `god-mode`\-specific `describe-key`, which translates `god-mode` key-sequences into commands and shows their usual description. I think it's a great way to get familiar with how the package handles keys, and it allows users to invoke `describe-key` without leaving god-mode (previously, most keys would just show information about the generic `god-mode-self-insert-command`) + +I also reached out to the package's maintainers, and this feature (after some tweaking) [just got added to the master branch](https://github.com/emacsorphanage/god-mode). It was a great way to get familiar with `god-mode` code and its behavior, and I'm happy to have made my first contribution to an Emacs package. + +## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/xdw6ok/comment/iodmtzu) +**Votes:** 9 + +I find it pretty useful (for debugging etc) to override the default projectile mode line indicator and show the projectile project type of the buffer instead, which can be done pretty easily if you're a use-package user with https://elpa.gnu.org/packages/delight.html: + +```elisp +(use-package projectile + :delight '(:eval (format " P[%s]" (projectile-project-type))) + :config + (setq foo "bar")) +``` + +## u/kickingvegas1 [πŸ”—](https://www.reddit.com/r/emacs/comments/x7zfs2/comment/innk62a) +**Votes:** 9 + +TIL when working with an Org table that `S-RET` will fill the current cell value with the value above it. + +## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/x7zfs2/comment/inqralq) +**Votes:** 9 + +I use follow-mode (built-in to #emacs) to split reading buffers across modern wide screens to use all the real estate. The mode keeps the panes in sync with eachother. http://images.toryanderson.com/follow-mode.gif + +## u/jimm [πŸ”—](https://www.reddit.com/r/emacs/comments/tfcmcx/comment/i0vtxte) +**Votes:** 9 + +The `git grep` git command is great for finding a regex (or a simple string) everywhere in a git repo. I define the following functions and bind the `git-grep` function to `F2`. It will prompt for a regex and search for that in the repo or, if you give it a numeric prefix like `C-u` it will read the current symbol at point (the word under the cursor) and search for that. Results appear in a grep buffer, so you can use `C-g C-n` and `C-g C-p` to navigate from one result to the next. + +```elisp +(defun git-root-dir () + "Returns the current directory's root Git repo directory, or +NIL if the current directory is not in a Git repo." + (let ((dir (locate-dominating-file default-directory ".git"))) + (when dir + (file-name-directory dir)))) + +(defun git-grep (arg) + "Runs 'git grep', starting the search in the current +directory's root git repo directory. + +By default, reads the regex from the minibuffer. With a prefix +argument, initializes the search string with the current symbol +at point." + (interactive "P") + (let* ((symbol-at-point (thing-at-point 'symbol)) + (regexp (if (and arg (symbol-at-point)) + (regexp-quote symbol-at-point) + (read-from-minibuffer + "Search regexp: " nil nil nil 'grep-find-history))) + + (default-directory (git-root-dir)) + (case-ignore-flag (and (isearch-no-upper-case-p regexp t) "-i")) + (cmd (concat "git grep --extended-regexp --line-number --full-name" + " --untracked " case-ignore-flag " -- \"" regexp "\"" + " | cut -c -240"))) + (while (equal "" regexp) + (setq regexp (read-from-minibuffer + "Search regexp (must not be the empty string): " nil nil nil 'grep-find-history))) + (grep-find cmd))) +``` + +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/rgu8dp/comment/hoqrg9e) **Votes:** 9 -I started using `god-mode`, but I found it hard to get used to it at first: there was no easy way to check what command would be triggered by what key-sequence. - -I wrote up a `god-mode`\-specific `describe-key`, which translates `god-mode` key-sequences into commands and shows their usual description. I think it's a great way to get familiar with how the package handles keys, and it allows users to invoke `describe-key` without leaving god-mode (previously, most keys would just show information about the generic `god-mode-self-insert-command`) - -I also reached out to the package's maintainers, and this feature (after some tweaking) [just got added to the master branch](https://github.com/emacsorphanage/god-mode). It was a great way to get familiar with `god-mode` code and its behavior, and I'm happy to have made my first contribution to an Emacs package. +`bs-show` is an interesting command, it shows a pop-up-like buffer that you can use to quickly act on open buffers. There are a ton of customizations you can make and a bunch of convenient bindings. I've been trying it out instead of `list-buffers` and `ibuffer` and I like it so far, very fast. -## u/attento_redaz [πŸ”—](https://www.reddit.com/r/emacs/comments/wqjare/comment/iku77h0) +## u/blankspruce [πŸ”—](https://www.reddit.com/r/emacs/comments/rbmfwk/comment/hnrdt9x) **Votes:** 9 -Using [zotra](https://github.com/mpedramfar/zotra), [citar](https://github.com/emacs-citar/citar) and some parts of the Org-cite ecosystem I hacked together a highly experimental but pretty comfortable environment for working with "org-biblatex bibliographies" which are basically like [org-bibtex](http://gewhere.github.io/org-bibtex) but with biblatex entries represented as headings with suitable properties instead of bibtex. I have a function which retrieves a biblatex entry corresponding to an url using zotra and adds a corresponding Org heading with the biblatex fields as properties, and the entry becomes available in Citar as soon as I save the document. Citing these entries then works anywhere, even in the same document with a suitable `#+bibliography: my-org-biblatex-file.org` declaration. Exporting the citations also works with the CSL exporter, no conversion is necessary to a proper biblatex bibliography file (but can be easily done if one needs biblatex-based export). Since the bibliography is an Org document, tagging, agenda commands, column view etc. can all be used with the bibliography entries. In a way it's frightening how much can be achieved building on already existing stuff and with a few lines of Emacs Lisp. +Is there a package similar to wdired or wgrep that would work on magit diffs? -## u/diamondnbond [πŸ”—](https://www.reddit.com/r/emacs/comments/us7zae/comment/i928gaj) -**Votes:** 9 +Particular use cases I have in mind are: -[I Recently discovered engine-mode.](https://github.com/DiamondBond/emacs/blob/master/config.org#initialize-engine-mode) +1. You've prepared a commit for pull request and during review someone spotted a mistake that's present in multiple files of that commit. Usually I grep the mistake and edit only affected files with wgrep (there might be some arbitrary reason to not fix similar issue in files not present in the commit). +2. In C++ it happens sometimes that you want to separate declaration and definition and in your commit you forgot to move some definitions to .cpp. +Usually I switch to `foobar.hpp`, kill the necessary part, switch to `foobar.cpp`, yank that part. -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/s21457/comment/hsgj7a6) +## u/tryptych [πŸ”—](https://www.reddit.com/r/emacs/comments/qgrpte/comment/hicheof) **Votes:** 9 -Prevent horizontal scrolling from going too far left. - -I use Emacs on a laptop and quite often scroll with a touchpad. I also don't use line wrapping, as in code it usually looks misleading, so lines can sometimes exceed window width, either because of some long names or because the current window configuration is too narrow. - -However, when scrolling text sideways, there's a small annoyance that the scroll can go way too far to the left. E.g. if this is your window, and your text exceeds it: - - -```elisp -|Short line | -|Some really long line o| -|Another short line | - -``` -What I'd like to is to prevent scrolling any further than that: - -```elisp -|line | -|eally long line of text| -|r short line | - -``` -But Emacs actually allows to scroll as far as one would want to, like here: - -```elisp -| | -|t | -| | +A colleague just showed me Intellij's "[compare with clipboard](https://www.jetbrains.com/help/idea/comparing-files-and-folders.html#clipboard)" feature: it's fairly neat, you select a region, invoke compare-with-clipboard and get a diff of the two selections. -``` -This doesn't make sense to me, as you can't see anything at all. -Probably handy, when you write in really long lines, and you wish to have some buffer for adding more text without triggering scrolling, but I never needed that. So I wrote such predicate: +It didn't take me long to implement something similar: ```elisp -(defun truncated-lines-p () - "Non-nil if any line is longer than `window-width' + `window-hscroll'. - -Returns t if any line exceeds the right border of the window. -Used for stopping scroll from going beyond the longest line. -Based on `so-long-detected-long-line-p'." +(defun ediff-compare-region-clipboard (begin end) + (interactive "r") (save-excursion - (goto-char (point-min)) - (let* ((window-width - ;; this computes a more accurate width rather than `window-width', and respects - ;; `text-scale-mode' font width. - (/ (window-body-width nil t) (window-font-width))) - (hscroll-offset - ;; `window-hscroll' returns columns that are not affected by - ;; `text-scale-mode'. Because of that, we have to recompute the correct - ;; `window-hscroll' by multiplying it with a non-scaled value and - ;; dividing it with a scaled width value, rounding it to the upper - ;; boundary. Since there's no way to get unscaled value, we have to get - ;; a width of a face that is not scaled by `text-scale-mode', such as - ;; `window-divider' face. - (ceiling (/ (* (window-hscroll) (window-font-width nil 'window-divider)) - (float (window-font-width))))) - (line-number-width - ;; compensate line numbers width - (if (bound-and-true-p display-line-numbers-mode) - (- display-line-numbers-width) - 0)) - ;; subtracting 2 for extra space in case some calculations were imprecise - (threshold (+ window-width hscroll-offset line-number-width -2))) - (catch 'excessive - (while (not (eobp)) - (let ((start (point))) - (save-restriction - (narrow-to-region start (min (+ start 1 threshold) - (point-max))) - (forward-line 1)) - (unless (or (bolp) - (and (eobp) (<= (- (point) start) - threshold))) - (throw 'excessive t)))))))) - -``` -This function can calculate window width, and line width, and check if any line in the buffer exceeds the window width screen-wise. By screen-wise I mean that if you've scrolled text to the left, it will begin to return `nil` once all lines don't exceed the right border of the window, thus achieving the described behavior in the diagrams. I then define advice around the `scroll-left` function, and it works pretty good: - -```elisp -(define-advice scroll-left (:around (foo &optional arg set-minimum)) - (when (and truncate-lines - (not (memq major-mode '(vterm-mode term-mode))) - (truncated-lines-p)) - (funcall foo arg set-minimum))) + (let ((selected-region (buffer-substring begin end)) + (clipboard-buffer (get-buffer-create "*ediff-clipboard*")) + (region-buffer (get-buffer-create "*ediff-region*"))) + (with-current-buffer clipboard-buffer + (insert (car kill-ring))) + (with-current-buffer region-buffer + (insert selected-region)) + (ediff-buffers clipboard-buffer region-buffer)))) ``` -Though it's not very accurate when using `text-scale-adjust`, as line width is not the same as before, the function, that reports how much the window was scrolled to the left still returns unscaled values. You can see my thoughts in the function's comments. Any suggestions on how to make it more accurate? +It's not ideal though. In particular, is there a better way to insert the "clipboard"? One thing I quickly found was that you might copy the region to compare but then so many editing commands will add to the kill-ring, so I might want to make that part of the process interactive. -## u/blankspruce [πŸ”—](https://www.reddit.com/r/emacs/comments/rbmfwk/comment/hnrdt9x) +## u/yogsototh [πŸ”—](https://www.reddit.com/r/emacs/comments/qgrpte/comment/hi8crmc) **Votes:** 9 -Is there a package similar to wdired or wgrep that would work on magit diffs? - -Particular use cases I have in mind are: +I just made this nice combination of emacs packages and personal theme to achieve the cool effect of iAWriter -1. You've prepared a commit for pull request and during review someone spotted a mistake that's present in multiple files of that commit. Usually I grep the mistake and edit only affected files with wgrep (there might be some arbitrary reason to not fix similar issue in files not present in the commit). -2. In C++ it happens sometimes that you want to separate declaration and definition and in your commit you forgot to move some definitions to .cpp. -Usually I switch to `foobar.hpp`, kill the necessary part, switch to `foobar.cpp`, yank that part. +See here: https://her.esy.fun/posts/0021-ia-writer-clone-within-doom-emacs/index.html ## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/q76kok/comment/hghp1e4) **Votes:** 9 @@ -2435,19 +2471,22 @@ This is requires giving the coordinates you want the text placed at, which I use (format "(%.1fcm,%.1fcm)" (f (car pt)) (f (cdr pt))))))))) ``` -## u/Bodertz [πŸ”—](https://www.reddit.com/r/emacs/comments/p28rl5/comment/h8iin6r) +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/mpwapo/comment/gudoljm) **Votes:** 9 -Meta: +**Create Rectangular Selection with Meta+Click+Drag** -Apparently, the `&c.` in the title is an abbreviation of the abbreviation `etc.`, which is fine except that the sidebar's link to past threads of this kind is in fact a link to a reddit search which includes as a search term `etc.` but not `&c.`, so this thread will not show up. +By default, when you click and drag with the Meta key Emacs creates what it calls a "secondary selection" which is super interesting and useful, but not what this tip is about. In most editors (on the Mac anyway) option+click+drag is used to create a rectangular selection. Emacs, of course, supports this, you just need to remap it. -## u/globalcandyamnesia [πŸ”—](https://www.reddit.com/r/emacs/comments/o68i0v/comment/h31xz50) -**Votes:** 9 +```elisp +(global-set-key [M-down-mouse-1] #'mouse-drag-region-rectangle) +(global-set-key [M-drag-mouse-1] #'ignore) +(global-set-key [M-mouse-1] #'mouse-set-point) -If you're using the mark setting commands to expand a selection like `M-@` (mark next word) or `C-M-@` (mark next sexp), you can swap the point and mark (`C-x C-x`) and the selection will be expanded to the left rather than the right. +``` +You can also create a rectangular selection with the command `rectangle-mark-mode`. -So if you're in the middle of a sentence, you can press `M-@` a few times to select some words to the right, press `C-xx`, and press `M-@` a few more times to add words before the selection. +Don't forget to bind `replace-rectangle` to something convenient for super easy editing. ## u/a-k-n [πŸ”—](https://www.reddit.com/r/emacs/comments/mg98ki/comment/gsvlfku) **Votes:** 9 @@ -2467,13 +2506,6 @@ If you want helpful mode to completely take over all help functions, and be able (advice-add 'describe-symbol :override #'helpful-symbol) ``` -## u/Bodertz [πŸ”—](https://www.reddit.com/r/emacs/comments/lfww57/comment/gmtk79e) -**Votes:** 9 - -From the mailing list, I've just learned of `generic-x.el`, which provides syntax highlighting for `/etc/fstab` or `/etc/passwd` and the like. I appreciated that vim provided that out of the box and I was surprised that emacs also does, but it's just disabled. - -`(require 'generic-x)` to enable it. - ## u/geza42 [πŸ”—](https://www.reddit.com/r/emacs/comments/kqsw1k/comment/gi66krb) **Votes:** 9 @@ -2585,16 +2617,14 @@ Here's the code, maybe there can be a lot of improvements: (define-key c-mode-base-map (kbd "") (lambda () (interactive) (my-cc-mode-M-RET t))) ``` -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/ikgfxd/comment/g3zeprg) +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/ixjcau/comment/g69no38) **Votes:** 9 -**Suggestion for moderators** - Consider putting a note in the weekly announcement for this thread that using 3 backquotes or tildes to make code blocks doesn't work for those of us using old reddit (so the code people post that way is almost unreadable) - and that indenting by 4 spaces is better for compatibility. -(Am I the only one who still uses old reddit? :-) ) +org-variable-pitch.el users might want to give [`valign`](https://github.com/casouri/valign) a look. It aligns your tables nicely, even with pictures (e.g. LaTeX previews) and links. The significance in context of OVP specifically is that you don't need to add `org-link` to `org-variable-pitch-fixed-faces` because valign-mode handles variable pitch links neatly in tables. -## u/Timesweeper_00 [πŸ”—](https://www.reddit.com/r/emacs/comments/ijmgtx/comment/g3fdvf7) -**Votes:** 9 +If you don't use OVP but use e.g. latex fragments in tables or just pictures, this one is still very helpful. -FYI lsp-mode has added support for pyright as a language server, Microsoft is deprecating the c# python language server in favor of pylance (proprietary and closed source), which uses pyright. +Kudos to the author, great little package. ## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/hv3kzf/comment/fyrgnk7) **Votes:** 9 @@ -2651,82 +2681,137 @@ I've added `try-expand-google-completion` to the bottom of my `hippie-expand-try Registers: in Emacs from the beginning, so simple you forget how insanely useful they can be. I use them to save text, windows, and locations. https://orys.us/tv -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/gi70ye/comment/fqczes1) +## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/heaoiu/comment/fvrlu40) **Votes:** 9 -[A beginers guide to emacs 24 or later by sasha chua](https://sachachua.com/blog/wp-content/uploads/2013/05/How-to-Learn-Emacs-v2-Large.png) this helped me tremendously to get started with emacs. +I've been using `M-|` (`shell-command-on-region`) frequently for years, and I only just stumbled on the fact that the region need not be active to use it. If it isn't, the command operates on the text from point to the end of the buffer. That's very reasonable and in line with various other commands, but the documentation doesn't mention it and so I never thought to try it. -## u/oantolin [πŸ”—](https://www.reddit.com/r/emacs/comments/g5bat3/comment/fo362s8) -**Votes:** 9 +That saves me a call to `C-x h` (`mark-whole-buffer`) whenever I want to process the entire buffer, which is most of the time. Also, it's a minor distraction for the entire buffer to be highlighted when I'm composing my shell command, so it's nice to avoid that. -`rx` isn't just an (extensible!) sexp syntax for regexps, it's an optimizing compiler! +Edited to add: Sorry folks, this doesn't work like I thought it did. See the coments below for details. -Examples: +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/gmkg4g/comment/fr65b4d) +**Votes:** 9 + +TIL that I can disable ``company`` for some modes, I needed to do it because completion was really slow for the shell and eshell which have vanilla shell completion anyway. Thus -- `(rx (or "dude@home.org" "dude@work.com"))` produces ```elisp -`"\\(?:dude@\\(?:home\\.org\\|work\\.com\\)\\)"` +(use-package company + :after ispell + :diminish + :config + . + . + . + (setq company-global-modes '(not eshell-mode shell-mode)) + (global company-mode 1)) + ``` -- `(rx (intersection (any (?g . ?z)) (any (?a . ?p))))` produces `"[g-p]"` +works as intended -And from Lisp code it's easy to plug in computed portions, using `eval`. -For example I recently used this in some silly code to count mentions -of animals in the bible :P: +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/gi70ye/comment/fqczes1) +**Votes:** 9 + +[A beginers guide to emacs 24 or later by sasha chua](https://sachachua.com/blog/wp-content/uploads/2013/05/How-to-Learn-Emacs-v2-Large.png) this helped me tremendously to get started with emacs. + +## u/shiroghost [πŸ”—](https://www.reddit.com/r/emacs/comments/g11mp9/comment/fnd2p6p) +**Votes:** 9 + +I use `mu4e` as email client. I guess that it is common to send some email to later discover that you forgot the attachment. + +This routines check if a mail **likely** needs an attachment by matching a simple regexp. If this is the case and there is no attach, we are asked to confirm that this is what we want to do. ```elisp -(defun plural (word) - (pcase word - ("mouse" "mice") - ("wolf" "wolves") - ("fish" "fishes") - (word (concat word "s")))) + ;; + ;; Auto-detect if there is a missing attachment in the + ;; mail and warn before sending. + ;; + ;; See https://notmuchmail.org/pipermail/notmuch/2018/026414.html + ;; + (defcustom message-likely-needs-attach-regex "attach\\|file\\|adjunto\\|fichero" + "regex that matches if a mail likely needs an attach. In + most cases this just matches a few keywords" + :type '(regexp)) + + (defun message-narrow-to-body() + "Narrow the compose buffer to the body of the mail" + (interactive) + (widen) + (goto-char (point-min)) + (narrow-to-region + (re-search-forward "--text follows this line--" nil t 1) + (point-max))) + + (defun mail-needs-attach-p () + "Count number of attach keywords in buffer and return t + if there is any" + (interactive) + (save-excursion + (message-narrow-to-body) + (let ( + (res (count-matches message-likely-needs-attach-regex))) + (widen) + (> res 0)))) + + (defun mail-number-of-attach () + "Count number of attach in buffer." + (interactive) + (save-excursion + (goto-char (point-min)) + (count-matches "<#part [^>]*filename=[^>]*>"))) + + (defun check-mail-and-send () + "Check if mail will likely have a missing attachment. + If yes ask for confirmation, if no send it." + (interactive) + (if (mail-needs-attach-p) + (if (> (mail-number-of-attach) 0) + (message-send-and-exit) + (if (y-or-n-p "Mail has NO attach. Send it anyway? ") + (message-send-and-exit))) + (message-send-and-exit))) -(defun bible-count (word) - "Count number of times WORD or its plural appears in the bible." - (with-current-buffer "king-james-bible.txt" - (count-matches - (rx-to-string `(word-start (or ,word ,(plural word)) word-end))))) - -``` -Which I used to make an Org mode table with an Emacs Lisp column formula: - -```elisp -#+TBLFM: $2='(bible-count $1) - + (define-key mu4e-compose-mode-map (kbd "C-c C-c") 'check-mail-and-send) ``` -**EDIT**: A previous version of the `bible-count` function used the `rx` macro and the `eval` construct: -```elisp -(defun bible-count (word) - "Count number of times WORD or its plural appears in the bible." - (with-current-buffer "king-james-bible.txt" - (count-matches (rx word-start - (or (eval word) (eval (plural word))) - word-end)))) +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/g11mp9/comment/fns15ub) +**Votes:** 9 -``` -This version is incorrect: `eval` is meant to be used only for value known at compile time. It's actual [behavior is very complicated](https://www.reddit.com/r/emacs/comments/g5bat3/weekly_tipstricketc_thread/fo7qdas) and depends on plenty of seemingly extraneous circumstances. +There is a [request](https://www.reddit.com/r/bugs/comments/g3c1go/might_gweneorg_be_whitelisted/) (created by /u/Amonwilde) for the Reddit team to whitelist [gwene.org](https://gwene.org) to be able to parse RSS feeds from different subreddits (right now, it does not work properly due to exceeded rate-limits). Upvote, please, if you use GNUS to consume RSS feeds and miss updates from Reddit. Thanks! -## u/xu-chunyang [πŸ”—](https://www.reddit.com/r/emacs/comments/fwgpkd/comment/fmochkh) +## u/zkryrmr [πŸ”—](https://www.reddit.com/r/emacs/comments/fgahb2/comment/fk567v4) **Votes:** 9 -Prettify the minibuffer prompt on the default value +Here is how you can calculate how many times larger an objects shadow is at solar noon. I was surprised to see how many quality functions related to astronomical calculations come with Emacs. ```elisp -(setq minibuffer-eldef-shorten-default t) -(minibuffer-electric-default-mode) - +(require 'solar) +(defun height-of-sun-at-noon (date) +"Calculates the height of at solar noon on DATE as '(M D YYYY)." + (let* ((exact-local-noon (solar-exact-local-noon date)) + (t0 (solar-julian-ut-centuries (car exact-local-noon))) + (ut (cadr exact-local-noon)) + (hnoon (solar-horizontal-coordinates (list t0 ut) + (calendar-latitude) + (calendar-longitude) t))) + hnoon)) + +(defun deg-to-rad (x) + "Convert X from radians to degrees." + (/ (* x float-pi) 180)) + +(defun length-of-shadow-at-noon (date) + "Calculates the relative length of an objects shadow at solar noon on DATE." + (let ((hn (cadr (height-of-sun-at-noon date)))) + (/ 1 (tan (deg-to-rad hn))))) ``` -Then try eval -```elisp -(read-string "Year (default 2019): " nil nil "2019") +## u/fabiopapa [πŸ”—](https://www.reddit.com/r/emacs/comments/f972tf/comment/firc94m) +**Votes:** 9 -``` -You will notice "Year (default 2019): " is shorten to "Year [2019]: ", and when -you enter anything, the prompt is shorten further to "Year: ". Next time, you -use the minibuffer api, if you provide the default value, don't forget to format -the prompt using that specfic format. +This may be common knowledge, but I’m always surprised at how few people know about this. + +If you have an `ALTERNATE_EDITOR=''`environment variable, and start emacsclient with no emacs server running, it will start an emacs server and try starting emacsclient again. Also works with a `-a` flag on emacsclient command. ## u/kastauyra [πŸ”—](https://www.reddit.com/r/emacs/comments/ev2q9q/comment/fftpfj0) **Votes:** 9 @@ -2832,6 +2917,17 @@ I use Emacs on my laptop either undocked, either with external screens connected ``` Some things here might be overkill (cl-defstruct, seq?), but this was also an Emacs lisp exercise. +## u/ji99 [πŸ”—](https://www.reddit.com/r/emacs/comments/el8oq7/comment/fdggv7n) +**Votes:** 9 + +```elisp +(defun repeat-last-shell-command () + (interactive) + (let ((last-cmd (cadr (assoc 'shell-command command-history)))) + (when (y-or-n-p (concat "execute " last-cmd)) + (async-shell-command last-cmd)))) +``` + ## u/ji99 [πŸ”—](https://www.reddit.com/r/emacs/comments/ei02j1/comment/fcmosxh) **Votes:** 9 @@ -2884,6 +2980,23 @@ Add the magic filenames to init.el so that emacs will know when to use the handl (add-to-list 'file-name-handler-alist '("\\(\\.\\(?:epub\\|pdf\\)\\)$" . mupdf-file-handler)) ``` +## u/human_banana [πŸ”—](https://www.reddit.com/r/emacs/comments/eeyhdz/comment/fbyevye) +**Votes:** 9 + +Have multiple machines where some things are available and other aren't? + +`when-available` takes a function name and if it exists, executes the rest. + +```elisp +(defmacro when-available (func cmd) + "Execute CMD if FUNC exists as a function." + `(when (fboundp ,func) ,cmd)) + +``` +So you can deal with different environments. + +I mostly use this for things that are nice to have, but aren't required and don't need to be installed if they aren't already. + ## u/itistheblurstoftimes [πŸ”—](https://www.reddit.com/r/emacs/comments/dyhkcd/comment/f8978oj) **Votes:** 9 @@ -3005,55 +3118,22 @@ A simple ivy function to play soma.fm with mpv in emacs: (kill-buffer "*soma.fm*")) ``` -## u/primitiveinds [πŸ”—](https://www.reddit.com/r/emacs/comments/domrl6/comment/f5oz3bp) +## u/clemera [πŸ”—](https://www.reddit.com/r/emacs/comments/drw8i3/comment/f6ys5ae) **Votes:** 9 -This is one of the things that I'm sure exists somewhere but I can't find it so I wrote a few lines. I work in a big monorepo and depend on `projectile` for navigation by adding `.projectile` files here and there, in subdirectories that I consider "projects". However there are some directories that e.g. contain libraries. If I want to work on all of them for e.g. refactoring, going into a project then locks me in that (I mean `projectile-find-file`) and I have to manually go into another project. Also I flood my projectile cache with little things that I might not use a lot. What I did was add some logic to create temporary root directories for projects, where I can then use `counsel-file-jump` and `counsel-ag`. I have some keybindings and with a prefix argument I am prompted to change the temp root. Here's the code: -```elisp -(defvar my/temp-project-root nil) - -(defun my/get-or-set-temp-root (reset) - (let* ((reset-root (if reset my/temp-project-root nil)) - (root - (if (or reset - (null my/temp-project-root) - (not (file-directory-p my/temp-project-root))) - (read-directory-name "Temp root dir: " reset-root) - my/temp-project-root))) -(setq my/temp-project-root root))) - -(defun my/counsel-file-jump-temp-root (reset) - (interactive "P") - (my/get-or-set-temp-root reset) - (let ((current-prefix-arg nil)) -(counsel-file-jump nil my/temp-project-root))) +My fav org-bullets config, looks nice and you immediately know which headline level you have: -(defun my/counsel-ag-temp-root (reset) - (interactive "P") - (my/get-or-set-temp-root reset) - (let ((current-prefix-arg nil)) -(counsel-ag "" my/temp-project-root))) +```elisp + (setq org-bullets-bullet-list + '("β“ͺ" "β‘ " "β‘‘" "β‘’" "β‘£" "β‘€" "β‘₯" "⑦" "⑧" "⑨")) ``` -Also `counsel-file-jump` is so good -## u/T_Verron [πŸ”—](https://www.reddit.com/r/emacs/comments/qlpvgu/comment/hjfbuae) +## u/c17g [πŸ”—](https://www.reddit.com/r/emacs/comments/domrl6/comment/f65iky4) **Votes:** 9 -(Nothing too fancy, I'm sure a lot of people have a similar thing in their toolbox, but it was useful to me again today.) - -When writing elisp packages, the compiler expects that all variables and functions are declared. Declaring variables defined somewhere else is easy, one just needs to \`defvar\` them, but declaring functions should mention the file where it is defined. - -Inserting all those forms is tedious, especially if the function comes from a package with several files. But emacs already knows where the function comes from, so we can just ask it. - -```elisp -(defun tv/add-declare-function (fun) - (interactive "a") - (let* ((buf (car (find-function-noselect fun))) - (name (file-name-base (buffer-file-name buf)))) - (insert (format "(declare-function %s "%s")\n" fun name)))) +I just found out the great variable `org-extend-today-until`. Basically it defines when your day really ends. If you sleep late, check it out. -``` -Call it with M-x, insert the name of the function you want to declare (with completion), and voilΓ . +Goodbye to the days using `M-x org-todo-yesterday` at midnight, clocking off items before sleep.. ## u/hairlesscaveman [πŸ”—](https://www.reddit.com/r/emacs/comments/gmkg4g/comment/fr4gdm6) **Votes:** 9 @@ -3066,22 +3146,17 @@ The advice below quiets this warning, and inserts a dash whenever space is press (advice-add 'magit-whitespace-disallowed :around (lambda (orig-fun &rest args) (interactive) (insert "-"))) ``` -## u/itistheblurstoftimes [πŸ”—](https://www.reddit.com/r/emacs/comments/el8oq7/comment/fdh3fyn) +## u/w0ntfix [πŸ”—](https://www.reddit.com/r/emacs/comments/11ey9ft/comment/jajfxc9) **Votes:** 9 -I had previously written a function to replace org-beginning-of-line to behave this way, but later found `org-special-ctrl-a/e` which does exactly what I wanted for C-a (and C-e). The default behavior drove me crazy and I didn't know there was a built-in fix. +turning off org-elements cache speeds up input latency for me (found from profiling): ```elisp - "Non-nil means `C-a' and `C-e' behave specially in headlines and items. When t, `C-a' will bring back the cursor to the beginning of the headline text, i.e. after the stars and after a possible TODO keyword. In an item, this will be the position after bullet and check-box, if any. When the cursor is already at that position,another `C-a' will bring it to the beginning of the line.`C-e' will jump to the end of the headline, ignoring the presence of tags in the headline. A second `C-e' will then jump to the true end of the line, after any tags. This also means that, when this variable is non-nil, `C-e' also will never jump beyond the end of the heading of a folded section, i.e. not after the ellipses.When set to the symbol `reversed', the first `C-a' or `C-e' works normally, going to the true line boundary first. Only a directly following, identical keypress will bring the cursor to the special positions.This may also be a cons cell where the behavior for `C-a' and`C-e' is set separately. - -"When t, `C-a' will bring back the cursor to the beginning of the headline text, i.e. after the stars and after a possible TODO keyword. In an item, this will be the position after bullet and check-box, if any. When the cursor is already at that position,another `C-a' will bring it to the beginning of the line.`C-e' will jump to the end of the headline, ignoring the presence of tags in the headline. A second `C-e' will then jump to the true end of the line, after any tags. This also means that, when this variable is non-nil, `C-e' also will never jump beyond the end of the heading of a folded section, i.e. not after the ellipses.When set to the symbol `reversed', the first `C-a' or `C-e' works normally, going to the true line boundary first. Only a directly following, identical keypress will bring the cursor to the special positions. This may also be a cons cell where the behavior for `C-a' and `C-e' is set separately." - -When t, `C-a' will bring back the cursor to the beginning of the headline text, i.e. after the stars and after a possible TODO keyword. In an item, this will be the position after bullet and check-box, if any. When the cursor is already at that position,another `C-a' will bring it to the beginning of the line. - -`C-e' will jump to the end of the headline, ignoring the presence of tags in the headline. A second `C-e' will then jump to the true end of the line, after any tags. This also means that, when this variable is non-nil, `C-e' also will never jump beyond the end of the heading of a folded section, i.e. not after the ellipses. - -When set to the symbol `reversed', the first `C-a' or `C-e' works normally, going to the true line boundary first. Only a directly following, identical keypress will bring the cursor to the special positions. This may also be a cons cell where the behavior for `C-a' and `C-e' is set separately." +(setq org-element-use-cache nil) + + ``` +it seems (at least on my org 9.6.1) to update the cache after calls to `org-self-insert-command` (so, a lot!) ## u/jcubic [πŸ”—](https://www.reddit.com/r/emacs/comments/1b20xgn/comment/ksoij65) **Votes:** 8 @@ -3117,6 +3192,20 @@ This makes stack-outputs of debug-buffers much more readable: It is the only thing that keeps me sane in a Windows shop. +## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/12cd23k/comment/jf3ohpv) +**Votes:** 8 + +I work with multiple Git repositories in my day job, but one in particular occupies 95% of my time. I've often wished I could set up Projectile so that if I run one of its commands while not in any repo, it will behave as if I'd changed to that main repo first. I couldn't find a built-in way to do that, but got the effect I wanted with some advice: + +```elisp +(defun default-to-main-project (dir) + (or dir *main-project-dir*)) + +(advice-add 'projectile-ensure-project :override #'default-to-main-project) + +``` +I lose some of the functionality of `projectile-ensure-project`, but I never used it anyway. + ## u/SlowValue [πŸ”—](https://www.reddit.com/r/emacs/comments/112t0uo/comment/j8u1ebf) **Votes:** 8 @@ -3244,6 +3333,13 @@ echo "[[file:${output_file}]]" rm -rf $tmp_dir/emacs_excel_to_png ``` +## u/Nondv [πŸ”—](https://www.reddit.com/r/emacs/comments/108zin2/comment/j4ct1y1) +**Votes:** 8 + +Maybe not new for anyone but I only recently found out that `C-c ` is conventionally reserved for user bindings. I was constantly afraid to define my own bindings bc of a potential clash so tended to use M-x instead. Now I finally bind my most used commands. + +With the above in mind, Im also afraid to forget my bindings. I use which-key package so I wrote a function "define-my-keybinding letter fn" which binds the letter to `C-c ` and to "my-bindings" keyset (prefix) which itself is bound to `C-c m`. Basically, if i forget what bindings I use, I just press C-c m and which-key shows me all of MY bindings (yes, it shows them with C-c too but it's mixed with mode bindings so not helpful) + ## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/z8ltei/comment/izxi6ie) **Votes:** 8 @@ -3302,27 +3398,24 @@ I had the [defrepeater](https://github.com/alphapapa/defrepeater.el) package for ``` Something similar is actually in the readme, but I guess I glossed over it back then. -## u/PriorOutcome [πŸ”—](https://www.reddit.com/r/emacs/comments/xdw6ok/comment/iodmtzu) +## u/HM0880 [πŸ”—](https://www.reddit.com/r/emacs/comments/wwdpju/comment/illuprk) **Votes:** 8 -I find it pretty useful (for debugging etc) to override the default projectile mode line indicator and show the projectile project type of the buffer instead, which can be done pretty easily if you're a use-package user with https://elpa.gnu.org/packages/delight.html: - -```elisp -(use-package projectile - :delight '(:eval (format " P[%s]" (projectile-project-type))) - :config - (setq foo "bar")) -``` +In Org Mode, what is the reason to use `~` for in-line code vs. `=` for monospace text? I use `=` for both code and monospace since (afaict) Org renders both code and monospace the same way in LaTeX PDF and HTML output, and `=` does not require using shift (unlike `~`). -## u/WorldsEndless [πŸ”—](https://www.reddit.com/r/emacs/comments/x7zfs2/comment/inqralq) +## u/hairlesscaveman [πŸ”—](https://www.reddit.com/r/emacs/comments/wqjare/comment/ikwhvfs) **Votes:** 8 -I use follow-mode (built-in to #emacs) to split reading buffers across modern wide screens to use all the real estate. The mode keeps the panes in sync with eachother. http://images.toryanderson.com/follow-mode.gif +Question: I generally work with 3 vertical panes, with my preferred layout as left for code, middle for related test file, and right for test output or magit. However, keeping this layout is tricky; sometimes magit will open in the first pane, or the current pane when I'm focused in the middle, and deadgrep will open just anywhere… well, it's quite hectic and feels random. -## u/HM0880 [πŸ”—](https://www.reddit.com/r/emacs/comments/wwdpju/comment/illuprk) +Is there any way I can get files to open in panes 1 or 2, and always have things like magit/test-output/deadgrep/etc on pane 3? I've tried "shackle" but I've had no success with it; everything seems to open in a horizontal pane at the bottom of my screen regardless of config. + +Any suggestions would be appreciated! + +## u/attento_redaz [πŸ”—](https://www.reddit.com/r/emacs/comments/wqjare/comment/iku77h0) **Votes:** 8 -In Org Mode, what is the reason to use `~` for in-line code vs. `=` for monospace text? I use `=` for both code and monospace since (afaict) Org renders both code and monospace the same way in LaTeX PDF and HTML output, and `=` does not require using shift (unlike `~`). +Using [zotra](https://github.com/mpedramfar/zotra), [citar](https://github.com/emacs-citar/citar) and some parts of the Org-cite ecosystem I hacked together a highly experimental but pretty comfortable environment for working with "org-biblatex bibliographies" which are basically like [org-bibtex](http://gewhere.github.io/org-bibtex) but with biblatex entries represented as headings with suitable properties instead of bibtex. I have a function which retrieves a biblatex entry corresponding to an url using zotra and adds a corresponding Org heading with the biblatex fields as properties, and the entry becomes available in Citar as soon as I save the document. Citing these entries then works anywhere, even in the same document with a suitable `#+bibliography: my-org-biblatex-file.org` declaration. Exporting the citations also works with the CSL exporter, no conversion is necessary to a proper biblatex bibliography file (but can be easily done if one needs biblatex-based export). Since the bibliography is an Org document, tagging, agenda commands, column view etc. can all be used with the bibliography entries. In a way it's frightening how much can be achieved building on already existing stuff and with a few lines of Emacs Lisp. ## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/w3gx6o/comment/igyt3ff) **Votes:** 8 @@ -3399,11 +3492,6 @@ I wanted to be able to expand yasnippets within other yasnippets (so here tab wo So C- expands a snippet within a snippet, and everything just worked as I'd hoped. Once I'm done with the nested expansion just moves on to the outer one. \*shrug\* -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/rgu8dp/comment/hoqrg9e) -**Votes:** 8 - -`bs-show` is an interesting command, it shows a pop-up-like buffer that you can use to quickly act on open buffers. There are a ton of customizations you can make and a bunch of convenient bindings. I've been trying it out instead of `list-buffers` and `ibuffer` and I like it so far, very fast. - ## u/rberaldo [πŸ”—](https://www.reddit.com/r/emacs/comments/rbmfwk/comment/hnvaab8) **Votes:** 8 @@ -3413,43 +3501,33 @@ I created an `enumerate` environment and immediately changed my mind. By chance, EDIT: markdown -## u/tryptych [πŸ”—](https://www.reddit.com/r/emacs/comments/qgrpte/comment/hicheof) +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/pg69k8/comment/hbc84y3) **Votes:** 8 -A colleague just showed me Intellij's "[compare with clipboard](https://www.jetbrains.com/help/idea/comparing-files-and-folders.html#clipboard)" feature: it's fairly neat, you select a region, invoke compare-with-clipboard and get a diff of the two selections. - -It didn't take me long to implement something similar: - -```elisp -(defun ediff-compare-region-clipboard (begin end) -(interactive "r") -(save-excursion -(let ((selected-region (buffer-substring begin end)) -(clipboard-buffer (get-buffer-create "*ediff-clipboard*")) -(region-buffer (get-buffer-create "*ediff-region*"))) -(with-current-buffer clipboard-buffer -(insert (car kill-ring))) -(with-current-buffer region-buffer -(insert selected-region)) -(ediff-buffers clipboard-buffer region-buffer)))) - -``` -It's not ideal though. In particular, is there a better way to insert the "clipboard"? One thing I quickly found was that you might copy the region to compare but then so many editing commands will add to the kill-ring, so I might want to make that part of the process interactive. +[deleted] -## u/github-alphapapa [πŸ”—](https://www.reddit.com/r/emacs/comments/q2g1gq/comment/hfldw8n) +## u/oantolin [πŸ”—](https://www.reddit.com/r/emacs/comments/p28rl5/comment/h8utmh2) **Votes:** 8 -One of the most useful bindings for me: +Imenu is pretty adictive and it's disappointing when some major mode doesn't support it. Luckily, it's fairly easy to cook up some regexps to provide imenu support in a new major mode. For example I recently noticed that customize buffers didn't have imenu support add I wrote this: ```elisp -(use-package avy - :bind* (("C-j" . avy-goto-char-timer))) +(defun configure-imenu-Custom () + (setq imenu-generic-expression + '(("Faces" "^\\(?:Show\\|Hide\\) \\(.*\\) face: \\[sample\\]" 1) + ("Variables" "^\\(?:Show Value\\|Hide\\) \\([^:\n]*\\)" 1)))) + +(add-hook 'Custom-mode-hook #'configure-imenu-Custom) + ``` +One subtlety with writing this is that the customize buffers show little triangles instead of the words "Show", "Hide" or "Show Value". To figure out what text is really in the buffer you can use `C-u C-x =` which tells you about any overlays at point. -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/pg69k8/comment/hbc84y3) +## u/Bodertz [πŸ”—](https://www.reddit.com/r/emacs/comments/p28rl5/comment/h8iin6r) **Votes:** 8 -[deleted] +Meta: + +Apparently, the `&c.` in the title is an abbreviation of the abbreviation `etc.`, which is fine except that the sidebar's link to past threads of this kind is in fact a link to a reddit search which includes as a search term `etc.` but not `&c.`, so this thread will not show up. ## u/oantolin [πŸ”—](https://www.reddit.com/r/emacs/comments/oxo1xh/comment/h88ph29) **Votes:** 8 @@ -3460,22 +3538,23 @@ This isn't a tip or trick, so I guess it is covered by &c. The Init File section (setq user-mail-address "cheney@torture.gov") ``` -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/mpwapo/comment/gudoljm) +## u/globalcandyamnesia [πŸ”—](https://www.reddit.com/r/emacs/comments/o68i0v/comment/h31xz50) **Votes:** 8 -**Create Rectangular Selection with Meta+Click+Drag** +If you're using the mark setting commands to expand a selection like `M-@` (mark next word) or `C-M-@` (mark next sexp), you can swap the point and mark (`C-x C-x`) and the selection will be expanded to the left rather than the right. -By default, when you click and drag with the Meta key Emacs creates what it calls a "secondary selection" which is super interesting and useful, but not what this tip is about. In most editors (on the Mac anyway) option+click+drag is used to create a rectangular selection. Emacs, of course, supports this, you just need to remap it. +So if you're in the middle of a sentence, you can press `M-@` a few times to select some words to the right, press `C-xx`, and press `M-@` a few more times to add words before the selection. -```elisp -(global-set-key [M-down-mouse-1] #'mouse-drag-region-rectangle) -(global-set-key [M-drag-mouse-1] #'ignore) -(global-set-key [M-mouse-1] #'mouse-set-point) +## u/11fdriver [πŸ”—](https://www.reddit.com/r/emacs/comments/mpwapo/comment/gufsfeu) +**Votes:** 8 -``` -You can also create a rectangular selection with the command `rectangle-mark-mode`. +Sometimes I'm working on programs with functions a few pages long, and `follow-mode` means that I can open two windows of the same buffer side-by-side and have the text flow like a book between them. I can double or even triple the amount of lines I can view at one time. -Don't forget to bind `replace-rectangle` to something convenient for super easy editing. +This has largely superseded what I might have used those code-overview map things for, which is difficult anyway, since I like to use Emacs from the terminal. + +It will keep the text aligned as you move through the file, and pairs well with binding `` and `` to the `scroll-up/down-line` commands in `xterm-mouse-mode`. + +If I'm studying/notetaking, I often end up with a few Emacs-windows arranged in a vertical stack. `winner-mode` or `window-configuration-to-register` are great, but if I want to quickly regain some vertical screen-real-estate without messing up the layout, then it's pretty intuitive to use `follow-mode` and just switch multiple windows to the same buffer, now they behave like one. ## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/k8zjx5/comment/gf1msbr) **Votes:** 8 @@ -3630,6 +3709,11 @@ considered. If still no suitable word is found, then look in the This command is essentially omni-autocomplete. Chances are, the term you're trying to complete is in the buffer you're using or another buffer, and you can hit multiple times to cycle through different completions. I find the expander to be quicker and more deterministic than language autocomplete about 70% of the time. It's especially useful in writing, if you use Emacs for things other than programming, as you can complete proper names and specalized vocabulary quickly. +## u/Timesweeper_00 [πŸ”—](https://www.reddit.com/r/emacs/comments/ijmgtx/comment/g3fdvf7) +**Votes:** 8 + +FYI lsp-mode has added support for pyright as a language server, Microsoft is deprecating the c# python language server in favor of pylance (proprietary and closed source), which uses pyright. + ## u/aartist111 [πŸ”—](https://www.reddit.com/r/emacs/comments/heaoiu/comment/fvrw4cu) **Votes:** 8 @@ -3746,25 +3830,6 @@ Each person gets a different colour to indicate the part of the file they’re e https://imgur.com/a/zvfLpdH -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/gmkg4g/comment/fr65b4d) -**Votes:** 8 - -TIL that I can disable ``company`` for some modes, I needed to do it because completion was really slow for the shell and eshell which have vanilla shell completion anyway. Thus - -```elisp -(use-package company - :after ispell - :diminish - :config - . - . - . - (setq company-global-modes '(not eshell-mode shell-mode)) - (global company-mode 1)) - -``` -works as intended - ## u/ji99 [πŸ”—](https://www.reddit.com/r/emacs/comments/gi70ye/comment/fqcycvb) **Votes:** 8 @@ -3842,110 +3907,32 @@ If you want to switch between two themes, depending on time of day (e.g. a light ``` This selects the correct theme when starting Emacs and automatically switch when the times come. -## u/shiroghost [πŸ”—](https://www.reddit.com/r/emacs/comments/g11mp9/comment/fnd2p6p) +## u/xu-chunyang [πŸ”—](https://www.reddit.com/r/emacs/comments/fwgpkd/comment/fmochkh) **Votes:** 8 -I use `mu4e` as email client. I guess that it is common to send some email to later discover that you forgot the attachment. - -This routines check if a mail **likely** needs an attachment by matching a simple regexp. If this is the case and there is no attach, we are asked to confirm that this is what we want to do. +Prettify the minibuffer prompt on the default value ```elisp - ;; - ;; Auto-detect if there is a missing attachment in the - ;; mail and warn before sending. - ;; - ;; See https://notmuchmail.org/pipermail/notmuch/2018/026414.html - ;; - (defcustom message-likely-needs-attach-regex "attach\\|file\\|adjunto\\|fichero" - "regex that matches if a mail likely needs an attach. In - most cases this just matches a few keywords" - :type '(regexp)) - - (defun message-narrow-to-body() - "Narrow the compose buffer to the body of the mail" - (interactive) - (widen) - (goto-char (point-min)) - (narrow-to-region - (re-search-forward "--text follows this line--" nil t 1) - (point-max))) - - (defun mail-needs-attach-p () - "Count number of attach keywords in buffer and return t - if there is any" - (interactive) - (save-excursion - (message-narrow-to-body) - (let ( - (res (count-matches message-likely-needs-attach-regex))) - (widen) - (> res 0)))) - - (defun mail-number-of-attach () - "Count number of attach in buffer." - (interactive) - (save-excursion - (goto-char (point-min)) - (count-matches "<#part [^>]*filename=[^>]*>"))) - - (defun check-mail-and-send () - "Check if mail will likely have a missing attachment. - If yes ask for confirmation, if no send it." - (interactive) - (if (mail-needs-attach-p) - (if (> (mail-number-of-attach) 0) - (message-send-and-exit) - (if (y-or-n-p "Mail has NO attach. Send it anyway? ") - (message-send-and-exit))) - (message-send-and-exit))) - - (define-key mu4e-compose-mode-map (kbd "C-c C-c") 'check-mail-and-send) -``` - -## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/g11mp9/comment/fns15ub) -**Votes:** 8 - -There is a [request](https://www.reddit.com/r/bugs/comments/g3c1go/might_gweneorg_be_whitelisted/) (created by /u/Amonwilde) for the Reddit team to whitelist [gwene.org](https://gwene.org) to be able to parse RSS feeds from different subreddits (right now, it does not work properly due to exceeded rate-limits). Upvote, please, if you use GNUS to consume RSS feeds and miss updates from Reddit. Thanks! - -## u/zkryrmr [πŸ”—](https://www.reddit.com/r/emacs/comments/fgahb2/comment/fk567v4) -**Votes:** 8 +(setq minibuffer-eldef-shorten-default t) +(minibuffer-electric-default-mode) -Here is how you can calculate how many times larger an objects shadow is at solar noon. I was surprised to see how many quality functions related to astronomical calculations come with Emacs. +``` +Then try eval ```elisp -(require 'solar) -(defun height-of-sun-at-noon (date) -"Calculates the height of at solar noon on DATE as '(M D YYYY)." - (let* ((exact-local-noon (solar-exact-local-noon date)) - (t0 (solar-julian-ut-centuries (car exact-local-noon))) - (ut (cadr exact-local-noon)) - (hnoon (solar-horizontal-coordinates (list t0 ut) - (calendar-latitude) - (calendar-longitude) t))) - hnoon)) - -(defun deg-to-rad (x) - "Convert X from radians to degrees." - (/ (* x float-pi) 180)) - -(defun length-of-shadow-at-noon (date) - "Calculates the relative length of an objects shadow at solar noon on DATE." - (let ((hn (cadr (height-of-sun-at-noon date)))) - (/ 1 (tan (deg-to-rad hn))))) +(read-string "Year (default 2019): " nil nil "2019") + ``` +You will notice "Year (default 2019): " is shorten to "Year [2019]: ", and when +you enter anything, the prompt is shorten further to "Year: ". Next time, you +use the minibuffer api, if you provide the default value, don't forget to format +the prompt using that specfic format. ## u/Desmesura [πŸ”—](https://www.reddit.com/r/emacs/comments/fgahb2/comment/fki3lrc) **Votes:** 8 Any Emacs Mode for dealing with Coronavirus? -## u/fabiopapa [πŸ”—](https://www.reddit.com/r/emacs/comments/f972tf/comment/firc94m) -**Votes:** 8 - -This may be common knowledge, but I’m always surprised at how few people know about this. - -If you have an `ALTERNATE_EDITOR=''`environment variable, and start emacsclient with no emacs server running, it will start an emacs server and try starting emacsclient again. Also works with a `-a` flag on emacsclient command. - ## u/github-alphapapa [πŸ”—](https://www.reddit.com/r/emacs/comments/f972tf/comment/fipuizk) **Votes:** 8 @@ -4018,17 +4005,6 @@ A couple of examples: (load-file "~/.emacs.d/init.el"))) ``` -## u/ji99 [πŸ”—](https://www.reddit.com/r/emacs/comments/el8oq7/comment/fdggv7n) -**Votes:** 8 - -```elisp -(defun repeat-last-shell-command () - (interactive) - (let ((last-cmd (cadr (assoc 'shell-command command-history)))) - (when (y-or-n-p (concat "execute " last-cmd)) - (async-shell-command last-cmd)))) -``` - ## u/sauntcartas [πŸ”—](https://www.reddit.com/r/emacs/comments/dyhkcd/comment/f82dxoa) **Votes:** 8 @@ -4036,20 +4012,20 @@ I just put together this little function that kills a buffer's process if there' ```elisp (defun kill-buffer-process-after-idle (buffer seconds) -(let (timer) -(cl-labels -((set-timer () -(setq timer (run-at-time seconds nil #'done))) -(reset-timer (_ _) -(cancel-timer timer) -(set-timer)) -(done () -(with-current-buffer buffer -(remove-hook 'before-change-functions #'reset-timer t)) -(kill-process (get-buffer-process buffer)))) -(with-current-buffer buffer -(add-hook 'before-change-functions #'reset-timer nil t)) -(set-timer)))) + (let (timer) + (cl-labels + ((set-timer () + (setq timer (run-at-time seconds nil #'done))) + (reset-timer (_ _) + (cancel-timer timer) + (set-timer)) + (done () + (with-current-buffer buffer + (remove-hook 'before-change-functions #'reset-timer t)) + (kill-process (get-buffer-process buffer)))) + (with-current-buffer buffer + (add-hook 'before-change-functions #'reset-timer nil t)) + (set-timer)))) ``` The context is that I occasionally use Spark throughout the day, but having a Spark shell open keeps a substantial amount of resources reserved, and my co-workers and I are encouraged to close our shells when not using them. This way, I don't have to bother remembering. @@ -4078,6 +4054,25 @@ Just discovered 'desktop-environment-mode', really useful, particularly if you a Thanks Damien ! +## u/T_Verron [πŸ”—](https://www.reddit.com/r/emacs/comments/qlpvgu/comment/hjfbuae) +**Votes:** 8 + +(Nothing too fancy, I'm sure a lot of people have a similar thing in their toolbox, but it was useful to me again today.) + +When writing elisp packages, the compiler expects that all variables and functions are declared. Declaring variables defined somewhere else is easy, one just needs to \`defvar\` them, but declaring functions should mention the file where it is defined. + +Inserting all those forms is tedious, especially if the function comes from a package with several files. But emacs already knows where the function comes from, so we can just ask it. + +```elisp +(defun tv/add-declare-function (fun) + (interactive "a") + (let* ((buf (car (find-function-noselect fun))) + (name (file-name-base (buffer-file-name buf)))) + (insert (format "(declare-function %s "%s")\n" fun name)))) + +``` +Call it with M-x, insert the name of the function you want to declare (with completion), and voilΓ . + ## u/slinchisl [πŸ”—](https://www.reddit.com/r/emacs/comments/pt2xws/comment/hdtoivy) **Votes:** 8 @@ -4250,6 +4245,23 @@ end ``` Basically, if I am already inside Emacs (Fish shell in a Vterm), `e filename` will open a file for editing in a window split next to my Vterm. If I'm not in Emacs (separate terminal), it will instead run `emacsclient` to edit the file in a new Emacs frame. +## u/itistheblurstoftimes [πŸ”—](https://www.reddit.com/r/emacs/comments/el8oq7/comment/fdh3fyn) +**Votes:** 8 + +I had previously written a function to replace org-beginning-of-line to behave this way, but later found `org-special-ctrl-a/e` which does exactly what I wanted for C-a (and C-e). The default behavior drove me crazy and I didn't know there was a built-in fix. + +```elisp + "Non-nil means `C-a' and `C-e' behave specially in headlines and items. When t, `C-a' will bring back the cursor to the beginning of the headline text, i.e. after the stars and after a possible TODO keyword. In an item, this will be the position after bullet and check-box, if any. When the cursor is already at that position,another `C-a' will bring it to the beginning of the line.`C-e' will jump to the end of the headline, ignoring the presence of tags in the headline. A second `C-e' will then jump to the true end of the line, after any tags. This also means that, when this variable is non-nil, `C-e' also will never jump beyond the end of the heading of a folded section, i.e. not after the ellipses.When set to the symbol `reversed', the first `C-a' or `C-e' works normally, going to the true line boundary first. Only a directly following, identical keypress will bring the cursor to the special positions.This may also be a cons cell where the behavior for `C-a' and`C-e' is set separately. + +"When t, `C-a' will bring back the cursor to the beginning of the headline text, i.e. after the stars and after a possible TODO keyword. In an item, this will be the position after bullet and check-box, if any. When the cursor is already at that position,another `C-a' will bring it to the beginning of the line.`C-e' will jump to the end of the headline, ignoring the presence of tags in the headline. A second `C-e' will then jump to the true end of the line, after any tags. This also means that, when this variable is non-nil, `C-e' also will never jump beyond the end of the heading of a folded section, i.e. not after the ellipses.When set to the symbol `reversed', the first `C-a' or `C-e' works normally, going to the true line boundary first. Only a directly following, identical keypress will bring the cursor to the special positions. This may also be a cons cell where the behavior for `C-a' and `C-e' is set separately." + +When t, `C-a' will bring back the cursor to the beginning of the headline text, i.e. after the stars and after a possible TODO keyword. In an item, this will be the position after bullet and check-box, if any. When the cursor is already at that position,another `C-a' will bring it to the beginning of the line. + +`C-e' will jump to the end of the headline, ignoring the presence of tags in the headline. A second `C-e' will then jump to the true end of the line, after any tags. This also means that, when this variable is non-nil, `C-e' also will never jump beyond the end of the heading of a folded section, i.e. not after the ellipses. + +When set to the symbol `reversed', the first `C-a' or `C-e' works normally, going to the true line boundary first. Only a directly following, identical keypress will bring the cursor to the special positions. This may also be a cons cell where the behavior for `C-a' and `C-e' is set separately." +``` + ## u/agumonkey [πŸ”—](https://www.reddit.com/r/emacs/comments/ei02j1/comment/fcu8ksy) **Votes:** 8 @@ -4361,4 +4373,205 @@ Recursive edit to the rescue: ``` -With this you can do `(setq files (read-file-names-with-dired+))` mark the files you are interested in and finish with `C-M-c` which exits the recursive edit. \ No newline at end of file +With this you can do `(setq files (read-file-names-with-dired+))` mark the files you are interested in and finish with `C-M-c` which exits the recursive edit. + +## u/vjgoh [πŸ”—](https://www.reddit.com/r/emacs/comments/18149ql/comment/kahspwz) +**Votes:** 8 + +I used to have a problem where eglot would decide that many mid-hierarchy directories were the project root and spin up a separate instance of clangd for each one (sometimes 10 or 12 total). This was almost certainly due to using emacs' built-in `project` to handle project discovery. At that point, I switched to lsp-mode because I generally find `project` to be impenetrable and poorly documented compared to projectile. + +I was forced to go back to eglot, however, because lsp-mode has been failing to parse things well for a while. + +Long story short, here's how you force `project` to find the actual project root if the automatic detection doesn't work. With this, eglot started working great, didn't spin up 10 instances of clangd, and has generally been ticking over just fine. + +`(setq project-vc-extra-root-markers '(".project.el" ".projectile" ".dir-locals.el"))` + +## u/slinchisl [πŸ”—](https://www.reddit.com/r/emacs/comments/pfpgm9/comment/hb765zp) +**Votes:** 8 + +This is a very simple function, but it has saved me from countless of "do I have to do _this_ again now?" moments. + +When editing LaTeX files I often find myself wanting to convert inline math to display math, in order for equations to "pop out" more. I could not find anything already implemented, so I wrote something that does this whenever the point is inside an inline math (`$`-based, sorry `\( \)` gang) environment: + +```elisp +(defun slot/inline-to-display-math () + "Transform inline math to display math." + (interactive) + (when (and (texmathp) (equal "$" (car texmathp-why))) ; inline math? + (let* ((beg (save-excursion (search-backward "$"))) + (end-$ (search-forward "$")) + (end (if (-contains? '(?. ?,) (char-after end-$)) + (1+ end-$) ; put punctuation into display-maths + end-$))) + (kill-region beg end) + ;; insert display math + (TeX-newline) + (insert "\\[") + (TeX-newline) + (insert-for-yank (string-replace "$" "" (current-kill 0))) + (TeX-newline) + (insert "\\]") + (TeX-newline)))) + +``` +For example, this would transform + +```elisp +The cowedge $\iota \colon P \xRightarrow{\; .. \;} C$ is easily seen to be unique up to unique isomorphism. + +``` +into + +```elisp +The cowedge +\[ + \iota \colon P \xRightarrow{\; .. \;} C +\] +is easily seen to be unique up to unique isomorphism. + +``` +I'm a bit surprised by my not finding any function to already insert some string into the simple `\[ \]`-based display math; everything I could find just inserted dollars instead. I suppose one could insert a `displaymath` environment, but I've never like the look of that. Oh well. + +## u/jumpUpHigh [πŸ”—](https://www.reddit.com/r/emacs/comments/nlefvx/comment/gzjal45) +**Votes:** 8 + +Considering the ongoing freenode to librea.chat movement, I tried to use erc for the *n*th time to connect to the debian channel on oftc. I want to authenticate automatically but it doesn't happen. I still need to use `/msg NickServ IDENTIFY mypass`. Can you tell me what to do? + + + +```elisp + (use-package erc + :custom + (erc-autojoin-channels-alist '(("OFTC" "#debian" ))) + (erc-prompt-for-nickserv-password nil) + (erc-prompt-for-password nil) + + :config + (add-to-list 'erc-modules 'services) + (erc-update-modules) + (erc-autojoin-enable) + (defun erc-start() + "Start ERC." + (interactive) + (erc :server "irc.oftc.net" :nick "mynick")) + ) + +``` +and my `~/.authinfo` file has an entry + +```elisp + machine irc.oftc.net login "mynick" password "mypass" + +``` +Edit: Using GNU Emacs 27.1 + +## u/StrangeAstronomer [πŸ”—](https://www.reddit.com/r/emacs/comments/kqsw1k/comment/gi8tvp8) +**Votes:** 8 + +Here's a really simple one, but I find it invaluable. + +It took me about 30 years to realise that using C-u with `buffer-menu` (C-x C-b) doesn't show 'special' buffers like `*Messages*`. Less clutter when I want to switch to a file, which is most of the time. + +It then took me a few more years to realise that that's my preferred mode, so I created this simple thing to invert the sense - now C-x C-b only shows me files, and I prefix that with C-u to show special buffers too. Sounds stupid and trivial but it floats my boat. + +```elisp +(global-set-key (kbd "C-x C-b") '(lambda (&optional arg) + "runs buffer-menu but with the sense of C-u inverted (ie files-only unless C-u is given)" + (interactive "P") + (setq arg (not arg)) + (buffer-menu arg))) +``` + +## u/martinslot [πŸ”—](https://www.reddit.com/r/emacs/comments/kdgv43/comment/gfwlm9q) +**Votes:** 8 + +I need to try to do something custom to eshell so it feels more like home: http://www.modernemacs.com/post/custom-eshell/. Also set som aliases up. + +How does your eshell look like? + +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/kdgv43/comment/gfxbwgy) +**Votes:** 8 + +I tried [marginalia](https://github.com/minad/marginalia) with light annotation and selectrum, it works well. It displays commands' keybindings in the minibuffer. It's especially useful for modes I don't use daily and for which I haven't memorized the keybindings. + +## u/??? [πŸ”—](https://www.reddit.com/r/emacs/comments/gmkg4g/comment/fr9whmq) +**Votes:** 8 + +[deleted] + +## u/oantolin [πŸ”—](https://www.reddit.com/r/emacs/comments/g11mp9/comment/fnjep17) +**Votes:** 8 + +If you call `occur` with a numeric prefix argument it provides lines of context around each match: if the number is positive it provides that many lines before and after each match, if it is negative, it provides that many lines before each match (in absolute value). + +And if you call `occur` with the universal prefix argument, `C-u`, it does something slightly different: it prompts you for a regexp as usual, but instead of collecting entire lines containing matches for the regexp, it collects either matches of the regexp (if it contains no captures), or it prompts you for a replace-like string to format each regexp match (where you can use the capture groups). + +For example, I can easily get a list of the packages I configure in my init file with: + +```elisp +C-u M-s o (use-package \(\S-+\) RET \1 RET + +``` +The `\1` is even there by default, so really only `RET` is needed in this case. + +**EDIT**: I previously had the regexp `(use-package \(\<.*?\>\)`, which as u/Bodertz pointed out, doesn't do what I want. + +## u/SlowValue [πŸ”—](https://www.reddit.com/r/emacs/comments/f972tf/comment/fis4vb9) +**Votes:** 8 + +Setting up **org-mode LaTeX export configuration** will be much easier, if you include a `*.tex` file with your settings. like so: + +```elisp +(setq org-latex-classes '(("mydocclass" + "\\input{my-org-template.tex}" ;; <---- HERE -- + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))) + +``` +The `my-org-template.tex` has to be located where LaTeX can find it. (i.e in directory `$HOME/texmf/tex/`) + +Content of the file can be all things you normaly have to define before the `\begin{document}` statement in a tex document. + +Creating a nice LaTeX export theme that way, is much more convenient, debugable and robust. + +I hope to see some cool org-LaTeX-export themes popping up. Imagine custom headers and footers with logos and stuff. ;) + +## u/ji99 [πŸ”—](https://www.reddit.com/r/emacs/comments/erro41/comment/ff5q5px) +**Votes:** 8 + +Org mode is amazing. I was looking for a way to move an item from a plain list to another heading in the same file. Here's what I wrote, it's working well for me. Requires the ivy package. + +```elisp +(defun org-refile-list-item () + (interactive) + (unless (org-in-item-p) + (error "not in item")) + (ivy-read + "move to heading: " + (org-map-entries + (lambda () + (nth 4 (org-heading-components)))) + :history 'org-headings + :action + (lambda (x) + (save-excursion + (org-beginning-of-item) + (let ((struct (org-list-struct))) + (kill-region + (point)(org-list-get-item-end-before-blank (point) struct)) + (delete-region + (point)(progn (forward-visible-line 1)(point))) + (org-list-write-struct + (org-list-struct)(org-list-parents-alist struct))) + (goto-char (point-min)) + (search-forward x) + (org-end-of-subtree) + (newline) + (yank) + (org-beginning-of-item) + (let ((struct (org-list-struct))) + (org-list-write-struct struct (org-list-parents-alist struct))))))) +``` \ No newline at end of file diff --git a/posts.json b/posts.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/posts.json @@ -0,0 +1 @@ +{}