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.