I just (re)discovered iflipb.el (please review my config) reddit / emacs ---------------------------------------------------------------------- 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- 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 ("" . iflipb-next-buffer) ("" . 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-" . iflipb-next-buffer) ("s-" . 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.