6

Some buffers are created by Emacs and is set in fundamental mode, like the *Org-Babel results*. I think it is more convenient to set them in special mode, which can be closed with key q. How do set the mode for those automatic buffers or if the name contains *?

Lawlist and Drew's comments below show possible ways to do it, what I want is a special-display buffers for some buffers with *...* names. The appropriate way of course is to find the function for creating the buffer and change it in the package, but it doesn't suit everybody.

Since special-display-regexps is obsolete, can anyone help me on an display-buffer-alist with a custom function to look for *Org-Babel Results* and set it to special mode?

Drew
  • 75,699
  • 9
  • 109
  • 225
godblessfq
  • 1,177
  • 8
  • 21
  • Do you want to set the mode or bind a key? – Dan Jun 16 '15 at 22:58
  • 2
    It would be better, in my opinion, to locate each of the functions responsible for creating the buffers in the first place and enable the custom mode at that point -- i.e., modify the functions directly responsible. Anything else is just an after-the-fact-hack (in my opinion). It is really easy to find with grep -- i.e., just look for the name of the buffer in the source code, and things like `get-buffer-create`, `display-buffer`, `pop-to-buffer`, etc. – lawlist Jun 16 '15 at 23:56
  • For example, my first grep led me to `ob-core.el` and a line of code that looks like: `(pop-to-buffer (get-buffer-create "*Org-Babel Results*"))` Now, I don't use that library and have no idea what it is used for, but I'll bet my lunch money that either that line or something similar to that line would be a prospective location to make modifications. A new function can be created in the `.emacs` file by having a preceding require statement -- e.g., `(require 'ob-core)` and then the new function with the *same* name -- i.e., `(defun org-babel-open-src-block-result (&optional re-run) . . .` – lawlist Jun 17 '15 at 00:07
  • 1
    For example, after `(pop-to-buffer (get-buffer-create "*Org-Babel Results*"))` or after the next line -- i.e., `(delete-region (point-min) (point-max))` -- you could add a line `(with-current-buffer (get-buffer "*Org-Babel Results*") (enable-my-custom-major-mode))` In my opinion, this is much more precise/localized than customizing the `display-buffer-alist` with a custom function to look for `*Org-Babel Results*`, which is another possibility, but I don't recommend broad brush approaches like that. – lawlist Jun 17 '15 at 00:18
  • The question is unclear, IMO, and risks being closed for that reason. Are you looking for special-display buffers (e.g. setting `special-display-regexps` to `("[ ]?[*][^*]+[*]")`, for buffers with `*...*` names? Are you looking for buffers whose mode inherits from `special-mode`, so that `q` quits them? There's no guessing what you are really asking for? What happened to software people being able to *specify* something? ;-) – Drew Jun 17 '15 at 01:21
  • 1
    Personally, I don't find the question unclear, he wants special-mode to be activated on org-results buffers (and other buffers with similar name). – Malabarba Jun 17 '15 at 07:45
  • 1
    @godblessfq The question in your title (major mode for non-file buffers) is a duplicate [of this one](http://emacs.stackexchange.com/q/2497/50). Would you consider editing your question and title to be more specific to org-results buffers? (because I don't think any of the answers on the other question would work on the org-results buffer) – Malabarba Jun 17 '15 at 07:50
  • One way would be to advice/redefine the functions that create the buffers of your interest and add `(special-mode)` at the right location in the elisp code after the buffer is created. – Kaushal Modi Jun 17 '15 at 17:14
  • [Example from the `paradox` package](https://github.com/Malabarba/paradox/blob/a0283bd7485eb422ab4aecfef5fb8d2fa8dd5aff/paradox-execute.el#L141) of what I am talking about above. – Kaushal Modi Jun 17 '15 at 17:24
  • The following link contains a complex example using the `display-buffer-alist` on a let-bound basis to examine (among other criteria) the buffer name matching certain predefined regexp -- the comments indicate how to set this globally using `setq` -- the thread title is **How to intercept a file before it opens and decide which frame**: http://stackoverflow.com/a/18371427/2112489 – lawlist Jun 17 '15 at 17:28

2 Answers2

3

Thanks to lawlist. I finally got it working.

(defun db-regexp-match-p (regexps string)
  (and string
       (catch 'matched
         (let ((inhibit-changing-match-data t))
           (dolist (regexp regexps)
             (when (string-match regexp string)
               (throw 'matched t)))))))
(defvar special-buffer-regexp
  '("[*].*results.*[*]" "[*].*out.*[*]")
  "Regexp of special mode buffer names")
(defun set_special_mode (buffer alist)
  (interactive)
  (if (db-regexp-match-p special-buffer-regexp (buffer-name buffer))
  (with-current-buffer buffer 
      (special-mode))))

(add-to-list 'display-buffer-alist '(".*" . (set_special_mode)))
godblessfq
  • 1,177
  • 8
  • 21
  • `(setq display-buffer-alist '((".*" . (set_special_mode))))` -- it *may* [?] be possible to use `add-to-list` instead of `setq`, but you are missing two (2) pairs of parentheses and a period in either event. – lawlist Jun 24 '15 at 00:12
  • Fixed. Thank you! But it appear to work before the fix. Apparently I need to learn more elisp. :-) – godblessfq Jun 25 '15 at 01:51
  • If you look at your edit history, you'll see that you had it essentially right (just with a more restrictive regexp that isn't really needed since the `db-regexp-match-p` is doing the work), but then you accidentally broke it when you used `add-to-list` -- at that point in the edit history, you *lost* a period and you *lost* a couple of pairs of parentheses. – lawlist Jun 25 '15 at 02:21
  • The latex output buffer doesn't work even after the fix. – godblessfq Jun 25 '15 at 13:48
  • You can use *either* of the following examples: `(add-to-list 'display-buffer-alist '(".*" . (set_special_mode)))` **or** `(setq display-buffer-alist '((".*" . (set_special_mode))))` You can test either example by evaluating `(display-buffer (get-buffer-create "*filename output*"))` If running a test with `add-to-list`, be sure to return the variable `display-buffer-alist` to a `nil` value so that you don't end up stacking your tests one on top of the other -- e.g., evaluating `(setq display-buffer-alist nil)` will reset the variable to a value of `nil`. – lawlist Jun 25 '15 at 14:55
  • You can use `M-x describe-variable RET display-buffer-alist RET` to check the value of the `display-buffer-alist`; or, `C-h v` – lawlist Jun 25 '15 at 15:05
  • The latex output buffer generated by C-c C-l still doesn't work. – godblessfq Jun 26 '15 at 13:15
  • Are you able to duplicate the basic test indicated above -- i.e., evaluating in a `*Scratch*` buffer the expression?: `(display-buffer (get-buffer-create "*filename output*"))` -- you can place the cursor at the end of that expression and type `C-x C-e` and it should pop open a buffer in Special Mode. You will need to pay particular attention to the two examples in my previous comment -- the number of surrounding parentheses are different depending upon whether you use `setq` or `add-to-list`. After we establish that the basic test works as expected, then you can broaden your debugging. – lawlist Jun 26 '15 at 14:22
  • I was able to duplicate the basic test. Maybe the latex output buffer set the mode differently. – godblessfq Jun 27 '15 at 15:32
  • You have successfully completed the first step of your journey by creating a working draft that can easily be tested. The next step in debugging would be to open up the latex source code and examine it to ascertain why the behavior is not as you expect. Take a crack at figuring it out -- if you need help, then I believe that should be a new question since your basic setup is now complete. Keep in mind that my original recommendation remains the same -- modify the original functions at the source instead of using this particular method to set `special-mode`. – lawlist Jun 27 '15 at 16:24
1

Below is another solution which is more elegant

(setq-default major-mode
  (lambda ()
  (if (db-regexp-match-p special-buffer-regexp (buffer-name))
      (special-mode)(fundamental-mode))))
godblessfq
  • 1,177
  • 8
  • 21
  • This solution *may* cause problems somewhere down the line because the C-source code has `major-mode` set up as a **symbol**, *not* necessarily a function (although it could be the **symbol** of a function). It so happens that `fundamental-mode` is a function defined within `simple.el` – lawlist Jun 22 '15 at 21:53
  • Even though I have enabled both solutions, I still don't have the latex output buffer (C-c C-l) in special mode. The buffer name is \*filename output\*. – godblessfq Jun 23 '15 at 22:38
  • I posted my comment underneath the other answer as it relates to just that one. – lawlist Jun 23 '15 at 23:59