Emacs: Why major mode is not set correctly when file is opened?

1.1k views Asked by At

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.

3

There are 3 answers

0
Allan Felipe On BEST ANSWER

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)))))
1
phils On

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.

3
Tim X On

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.