rolandwalker / button-lock

clickable text in Emacs
42 stars 6 forks source link

button-lock-set-button causes python/ipython repl to be read-only #9

Open jkitchin opened 6 years ago

jkitchin commented 6 years ago

I think button-lock-set-button is interacting with org-mode in a strange, and undesirable way.

The issue is that in org-mode, if I have a python src block that uses a session, I can type C-c C-v C-z to access the REPL for that session. However, if I have called a button-lock-set-button command before starting the session, then the REPL buffer is read-only, and unusable. I don't know why button-lock does that since there is no obvious read-only code in button-lock, but if I don't use it then everything is fine.

Steps to reproduce:

Use this init.el file:

(setq user-emacs-directory "./sandbox/")

(require 'package)

(setq package-archives
      '(("org" . "https://orgmode.org/elpa/")
    ("gnu" . "http://elpa.gnu.org/packages/")
    ("melpa" . "http://melpa.org/packages/")))

(package-initialize)
(package-refresh-contents)

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(require 'use-package)
(setq use-package-always-ensure t)

(use-package org-plus-contrib)
(use-package button-lock)

(setq org-confirm-babel-evaluate nil)

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (python . t)
   (python . t)))

Create these two org files:

test.org:

Run this block and then C-c C-v C-z opens repl fine.

#+BEGIN_SRC python :results output org drawer :session
5  # cursor here, type C-c C-v C-z and get interactive repl
#+END_SRC

#+RESULTS:
:RESULTS:
7)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
5
python.el: native completion setup loaded
:END:

Now run this one to add a hook function that defines a button..

#+BEGIN_SRC emacs-lisp
  (require 'button-lock)
  (global-button-lock-mode +1)
  (add-hook 'org-mode-hook
        (lambda ()
          (button-lock-set-button
           "<run>"
           (lambda () (interactive) (message "running"))
           :face (list 'link)
           :help-echo "Click to run me")))
#+END_SRC

#+RESULTS:
| (lambda nil (button-lock-set-button <run> (lambda nil (interactive) (message running)) :face (list (quote link)) :help-echo Click to run me)) | #[0 \300\301\302\303\304$\207 [add-hook change-major-mode-hook org-show-block-all append local] 5] | #[0 \300\301\302\303\304$\207 [add-hook change-major-mode-hook org-babel-show-result-all append local] 5] | org-babel-result-hide-spec | org-babel-hide-all-hashes | org-eldoc-load |

Click on this to open it.

[[./test2.org]]

test2.org

<run> 

#+BEGIN_SRC python :results output org drawer :session sesson2
55  # cursor here, type C-c C-v C-z and get readonly repl
#+END_SRC

#+RESULTS:
:RESULTS:
55
:END:

Launch emacs: emacs -Q -l init.el test.org

the first block in the first file works as expected. When you add the hook function though, the block in the second file gives a read-only repl. I don't know why.

rolandwalker commented 6 years ago

Truly interesting bug! I'm way behind on my GH issues but will try to get to this one.

The great report makes it easier.

jkitchin commented 6 years ago

I don't know if this helps, but I have tracked this down to this line:

(set (make-local-variable 'comint-prompt-read-only) t) in the call to (inferior-python-mode) in L2746 of python-shell-make-comint, which is eventually called when you try to get the repl from an org src block.

It is really weird. before I make a button, that line is run, the variable is set, and seems to have no effect as I get an interactive repl I can type in. But after I make a button, I get a read-only repl. It is interactive until that line gets run, and after that, it becomes read-only.

sshaw commented 6 years ago

Same problem. Very confusing.

In my case I opened ielm after setting a button in another buffer *ielm* became readonly.

sshaw commented 6 years ago

Setting :rear-sticky t does not cause this.