1

Why major mode is not automatically set to python-mode when I open a .py file (emacs test.py)? Some parts of my .emacs that deal with python are:

(setq
 python-shell-interpreter "ipython"
 python-shell-interpreter-args "--gui=wx --matplotlib=wx --colors=Linux"
)

(defun my-eval-after-load-python()
    (setq initial-frame-alist '((top . 48) (left . 45) (width . 142) (height . 57)))
    (split-window-horizontally (floor (* 0.49 (window-width))))
    (other-window 1)
    (run-python (python-shell-parse-command))
    (python-shell-switch-to-shell)
    (other-window 1)
)
(eval-after-load "python" '(my-eval-after-load-python))

Left window should display the ipython shell and right window the opened file test.py. Everything works but test.py is in fundamental-mode and actually the scratch buffer is set to python-mode.

EDIT

Well, the problem is just the way my eval function deals with windows and buffers, so that this code treats the major-modes correctly:

(defun my-eval-after-load-python()
  (setq initial-frame-alist '((top . 48) (left . 45) (width . 142) (height . 57)))
  (split-window-horizontally (floor (* 0.49 (window-width))))
  (run-python (python-shell-parse-command))
)
(eval-after-load "python" '(my-eval-after-load-python))

The left window shows foo.py (in python-mode) and right window displays the scratch buffer (in text-mode). There are also the message buffer and a python shell buffer (inferior-python-mode). Now it's just a matter of opening the inferior-python-mode on the left window and the foo.py on the right window.

Allan Felipe
  • 201
  • 2
  • 8
  • 2
    One concrete spot you can start is to see if you have modified `auto-mode-alist`. Mine has an entry reading `("\\.pyw?\\'" . python-mode)`; this is why a `.py` file ends up with `python-mode`. – Tom Tromey Nov 09 '16 at 16:23
  • It seems that the simple existence of one `other-window` causes that behavior, I can't understand why. If my defun is just the division of windows and the run-python line then test.py opens in python-mode and the scratch buffer is in Text mode, which is correctly my initial-major-mode. – Allan Felipe Nov 10 '16 at 04:19
  • You probably want to use something like `with-current-window-buffer` instead of `other-window`. – jpkotta Nov 10 '16 at 08:52

3 Answers3

2

Ok, so you tell Emacs to find-file some foo.py file, and Emacs reads it into a new fundamental-mode buffer and then calls python-mode.

That's an autoload, so first it must load python.el, after which your eval-after-load kicks in and you start messing with the selected buffer.

After that, python-mode is actually called -- but you've left some other buffer selected, so the mode gets enabled for that buffer, and foo.py remains in fundamental-mode.

Wrapping your code in save-current-buffer would be a sensible start, but you might also want to be more explicit in your manipulations, rather than relying on other-window to do what you want.

phils
  • 71,335
  • 11
  • 153
  • 198
  • Yes, that's it. Now I'm struggling with a combination of (run-python), (switch-to-buffer (inferior-python-mode)) and (save-current-buffer). – Allan Felipe Nov 11 '16 at 04:16
2

Start with the basics first. Get rid of your python related configurations. Restart emacs and see if opening a .py file opens it in python-mode.

If this does not work, check the value of auto-mode-alist. This is an association list where each element of the list is a cons cell where the car is the key and the cdr is the value associated with that key. Thes cons cells are often written as "dotted pairs" i.e. (key . value). So the auto-mode-alist is just a list of associations where each association is used to associate a filename pattern with an emacs mode. The filename patterns are usually represented as regular expressions.

When you open a file in emacs, it will check the auto-mode-alist to see if any of the keys (regular expressions) match the filename. If one matches, then emacs will start that mode once the file is loaded. When there are no matches, emacs will default to just using fundamental mode.

So, if you find emacs does not put the buffer in python-mode when you open a file with a name which ends in the extension .py, the most likely cause is that therre is no auto-mode-alist entry which a key which matches the filename you are using.

I don't program with python, but I note on my system, there is the following entry in my auto-mode-alist

("\\.pyw?\\'" . python-mode)

When I open test.py, my emacs opens the file in python-mode.

Get this bit working or verify it is working in a vanilla emacs. If it isn't, then add the appropriate entry, test it works and then add back your configuration.

If yo find it works correctly until you add your setup function, then come back and we can look at the function. The way you have defined your function is a bit messy and could certainly be improved, but nothing obvious jumps out as being a problem, which is why I'd like to see if just opeing a pythong file without any other python setup stuff works.

Tim X
  • 4,158
  • 1
  • 20
  • 26
  • It works correctly without my eval. The problem is the way my messy function handles the windows and buffers. – Allan Felipe Nov 11 '16 at 04:08
  • OK, so start with small steps. Define a new function which just deals with setting p the windows. Get rid of the initial-fame-alist, have your emacs open with the overall frame size you want and write the function to spit it horizontally with the appropriate sizes you want (and optionally end up with the cursor in the window you would want it in on completion). Once that bit works, we can then look at what you may need to do to get that working regardless of what the initial frame size or makeup is – Tim X Nov 11 '16 at 04:59
  • Ok, so the function is: (defun my-eval-after-load-python() (split-window-horizontally (floor (* 0.49 (window-width)))) (run-python (python-shell-parse-command))) The result is foo.py on the left (with focus on) and scratch on the right. But I'd like ipython shell on the left and foo.py on the right (with focus on) – Allan Felipe Nov 12 '16 at 04:58
0

Based on the accepted answer given in When window is split on startup, how to open the file on the right side? I was able to implement the desired behavior:

(defun my-eval-after-load-python (buffer alist direction &optional size pixelwise)
  (setq initial-frame-alist '((top . 44) (left . 18) (width . 135) (height . 49)))
  (let ((window
        (cond
        ((get-buffer-window buffer (selected-frame)))
        ((window-in-direction direction))
        (t (split-window (selected-window) size direction pixelwise))
        )
       ))
   (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated) 
   (run-python (python-shell-parse-command))
   (other-window 1) 
   (python-shell-switch-to-shell) 
   (select-window window)
  )
)

(eval-after-load "python" '(my-eval-after-load-python (current-buffer) nil 'right (floor (* 0.49 (window-width)))))
Community
  • 1
  • 1
Allan Felipe
  • 201
  • 2
  • 8