reddit / emacs
I just (re)discovered iflipb.el (please review my config)
StrangeAstronomer · 2022-04-06 02:22
I tried out [iflipb.el](https://github.com/jrosdahl/iflipb) (installed via melpa) some time ago, but I bound it to obscure keys and forgot all about it.
I came across it again recently in my config, changed the binding and now I love it! The recent file I want is now just a C-<tab> away.
If some kind soul would look at my config and let me know if I've made blues, it would be appreciated. It works but my elisp ain't that good - I want it to ignore '*' buffers like \*scratch\* etc, but not \*elfeed-search\*.
```
(defun bh:iflipb-ignore-buffers (buf)
"what buffers to ignore in iflipb"
(cond
((equal "*elfeed-search*" buf) nil)
((string-match "^[*]" buf) t)))
(use-package iflipb
:config
(setq-default iflipb-ignore-buffers 'bh:iflipb-ignore-buffers)
:bind
("<C-tab>" . iflipb-next-buffer)
("<C-S-iso-lefttab>" . iflipb-previous-buffer))
```
Phil-Hudson · 2022-04-06 12:09
Looks OK to me, but OK-by-accident, if you know what I mean. Your function returns `t` for any buffer other than `*elfeed-search*` that starts with a `*`, and `nil` for any other buffer (which is what you want), but it doesn't **say** so to a human reader. It's good practice to always add an explicit final clause to a `cond` that always matches and describes the default behavior, even if that behavior is just to return `nil` (as it would be here).
(cond
((equal "*elfeed-search*" buf) nil)
((string-match "^[*]" buf) t)
(t nil))
or even my preferred format:
(cond
((equal "*elfeed-search*" buf) nil)
((string-match "^[*]" buf) t)
(:otherwise nil))
which works because `:otherwise` is a keyword, and keywords are "self-quoting", evaluating to themselves, like `t`. All that's needed here is anything other than `nil`, so `:otherwise` works just as well as `t`, with a bit more human-readable meaningfulness, IMO.
StrangeAstronomer · 2022-04-06 21:58
Ah! thanks for that. I had a (t nil) clause in there until I read that (cond) returns nil as the default. I agree - better to be explicit. I didn't see ':otherwise' in the doco for (cond) - evidently it's a generic thing - TIL!
I wonder if ':foobar' would work as well as ':otherwise' ... hmmm, it does!
I found the doco here if anyone is following along at home: https://www.gnu.org/software/emacs/manual/html_node/elisp/Constant-Variables.html
StrangeAstronomer · 2022-04-06 22:02
BTW - having learned something about keywords, I'm wondering if the ':config' and ':bind' keywords in use-package are just human readability labels rather than performing some function. Amiright?
Phil-Hudson · 2022-04-06 23:10
More or less. Lisp keywords are both *constants*, in the sense that most programming languages have them, and also *symbols*, in the Lisp sense. They are important (by convention) in plists (property lists). Macros such as `use-package` that use keywords, and the `&key` parameters in `defun` declarations, both resolve to plists behind the scenes, where those plists are processed to determine which well-known and expected options are to be included and with what values.
by_wicker · 2022-04-07 02:03
They do actually delimit different sections though so they're more than readability. Things found in `:bind` are lists of keybinding definitions, things found in `:config` is elisp. See `C-h f use-package`.
By the way, you may as well put your function in your `:config` section so it isn't evaluated until you first use iswitchb.
Also another aside - in your post triple backticks only render properly on "new" Reddit, and a *lot* of us read on old Reddit. So to make it look right everywhere, your code block in your post should be indented by 4 spaces, rather than surrounded by backticks.
by_wicker · 2022-04-07 02:07
Thanks for this, I have been using an inferior simple defun to just toggle the top two and never got around to improving it. Now I don't have to!
by_wicker · 2022-04-07 02:30
My config, since I didn't like it showing other buffers I already have visible:
(use-package iflipb
:bind
(("s-<tab>" . iflipb-next-buffer)
("s-<iso-lefttab>" . iflipb-previous-buffer))
:custom
(iflipb-buffer-list-function #'my/iflipb-buffer-list)
:config
(defun my/iflipb-buffer-list ()
"Returns list of current buffers excluding those visible in the current frame"
(cl-remove-if
(lambda (buffer) (not (get-buffer-window buffer (selected-frame))))
(buffer-list (selected-frame)))))
StrangeAstronomer · 2022-04-07 04:50
That's also a good idea. Duly snarfed ... thanks!
Phil-Hudson · 2022-04-12 06:54
Nicely put. BTW, the `:preface` section is probably (slightly) better than the `:config` section for custom definitions. It's logically the same as defining them at the top level, outside of `use-package`, but makes the association clear to the reader.