I'm trying to write a small lisp function to run flyspell in a single org-mode branch. I have added this to my .emacs file:
(defun flyspell-current-tree()
(interactive)
(org-mark-subtree)
(flyspell-region))
(global-set-key (kbd "S-<f8>") 'flyspell-current-tree)
But when running it I get the following error:
flyspell-current-tree: Wrong number of arguments
Any ideas?
You need to provide beg and end to flyspell-region for it to work properly. The error is coming from that and not actually from your function.
If you include (point) and (mark) as arguments to flyspell-region it will work properly.
(defun flyspell-current-tree()
(interactive)
(org-mark-subtree)
(flyspell-region (point) (mark)))
Related
I want to call the function markdown-back-to-heading, which is native in Markdown mode in Emacs. I understand that interactive turns non-interactive functions interactive, or formally functions into commands:
Special Form: interactive arg-descriptor
This special form declares that a function is a command, and that it may therefore be called interactively (via M-x or by entering a key sequence bound to it).
I tried:
(define-key markdown-mode-map (kbd "C-c C-h") 'markdown-back-to-heading)
This throws an error: Wrong type argument: commandp, markdown-back-to-heading.
So I wrapped it with an interactive function, and it works:
(defun my-markdown-back-to-heading ()
"Wrap function to be called interactively."
(interactive)
(markdown-back-to-heading))
(define-key markdown-mode-map (kbd "C-c C-h") 'my-markdown-back-to-heading)
Is there a better way to turn the native function into an interactive command?
You can alternatively use the interactive-form symbol property.
For details see C-hig (elisp)Using Interactive
Here's a simple example:
;; Enable M-x kill-process (to kill the current buffer's process).
;; (This is not normally a command, but it is useful as one.)
(put 'kill-process 'interactive-form '(interactive))
The more complex version that I actually use is:
(put 'kill-process 'interactive-form
'(interactive
(let ((proc (get-buffer-process (current-buffer))))
(if (process-live-p proc)
(unless (yes-or-no-p (format "Kill %S? " proc))
(error "Process not killed"))
(error (format "Buffer %s has no process" (buffer-name))))
(list proc))))
If want to make markdown-back-to-heading interactive, you have a few different good options:
file a bug report to get upstream to make it so. Including a patch along with the bug-report can help speed up the process.
use an advice such as:
(advice-add 'markdown-back-to-heading :before
(lambda () (interactive "^") nil))
If instead you want to improve the interactivity of a function, e.g. if you want to support shift-selection, you can add the interactive code ^ with (interactive "^") instead of (interactive) so that Emacs knows this is a navigation command (and hence if you use it with a shifted-binding it will select the corresponding text). Here is a manual page with the list of interactive codes, and other options for interactivity at the manual page you mentioned.
Following #Stefan's suggestion, I filed a Github issue and submitted a patch, which adds the line (interactive "P") in the source code:
(defun markdown-back-to-heading (&optional invisible-ok)
"Move to previous heading line, or beg of this line if it's a heading.
Only visible heading lines are considered, unless INVISIBLE-OK is non-nil."
(interactive "P")
(markdown-move-heading-common #'outline-back-to-heading invisible-ok))
and now I can keybind it with
(define-key markdown-mode-map (kbd "C-c C-h") 'markdown-back-to-heading)
I had installed markdown-mode from MELPA, so this change required uninstalling the package, then these steps from the repo README. I forked the repo and cloned the repo locally:
git clone git#github.com:miguelmorin/markdown-mode
and added these lines to Emacs initialization:
(add-to-list 'load-path (expand-file-name "~/code/markdown-mode"))
(autoload 'markdown-mode "markdown-mode"
"Major mode for editing Markdown files" t)
(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))
(autoload 'gfm-mode "markdown-mode"
"Major mode for editing GitHub Flavored Markdown files" t)
(add-to-list 'auto-mode-alist '("README\\.md\\'" . gfm-mode))
(require 'markdown-mode)
I am trying to customize my Emacs init file in such a way that Emacs opens with two windows split and the ansi-term opened in one side and my init file on the other side. Now, the function I wrote (switch-to-next-window) works perfectly if Emacs is open already.
I was hoping to make the cursor switch to the other window and then open my init file there. However, if I try to run this upon start-up (actually after start up, at least this is what I am thinking) I get the following error: window-live-p, nil
I am gessing that there is no "next window". But I just don't know a work around here since I do think that I am only calling my function after Emacs has fully started up? If anyone could point me to where I am going wrong in my logic, that would be great!
(split-window-horizontally)
(setq initial-buffer-choice "*ansi-term*")
(defun switch-to-next-window ()
(interactive)
(let* ((next-window (get-buffer-window (other-buffer (current-buffer) t))))
(select-window next-window)))
(add-hook 'emacs-startup-hook (lambda ()(ansi-term "/bin/bash")))
(with-eval-after-load "~/.emacs.d/init.el"
(switch-to-next-window)
(setq initial-buffer-choice "~/.emacs.d/init.el"))
Changing initial-buffer-choice after the initial buffer has been opened won't have any effect.
What helps is putting everything into the emacs-startup-hook and using the find-file-other-window function:
(add-hook 'emacs-startup-hook
(lambda ()
(ansi-term "/bin/bash")
(split-window-horizontally)
(find-file-other-window "~/.emacs.d/init.el")))
I'm a recent convert from vim to emacs (spacemacs). Spacemacs comes with yapf as the standard code reformatter tool for python. I find autopep8 to work better on python code when the code is broken. I can't figure out how to make autopep8 reformat a selected region, rather than an entire buffer. In vim this is equivalent to running gq function on a selection or an object. How do we do that in emacs/spacemacs?
I don't know how you're invoking autopep8, but this particular wrapper already works with the region or marks the current function: https://gist.github.com/whirm/6122031
Save the gist anywhere you keep personal elisp code, such as ~/elisp/autopep8.el.
In .emacs ensure your lisp directory is on the load path, load the file, and override the key binding:
(add-to-list 'load-path "~/elisp") ; or wherever you saved the elisp file
(require 'autopep8)
(define-key evil-normal-state-map "gq" 'autopep8)
The version in the gist defaults to formatting the current function if no region is active. To default to the whole buffer, rewrite the autopep8 function in the file like this:
(defun autopep8 (begin end)
"Beautify a region of python using autopep8"
(interactive
(if mark-active
(list (region-beginning) (region-end))
(list (point-min) (point-max))))
(save-excursion
(shell-command-on-region begin end
(concat "python "
autopep8-path
autopep8-args)
nil t))))
The above setup assumes you are starting from scratch with autopep8 in Emacs. If you already have autopep8 in Emacs from some other package that almost does what you want, the ultimate answer to how to customize that will depend on where the code is coming from and what arguments and variables it supports. Type C-h f autopep8 to view the help for an existing function.
For example, if an existing autopep8 function takes arguments for the region to format, then you could use the interactive region and point logic from the code above and define a new function that wraps the existing function on your system.
(define-key evil-normal-state-map "gq" 'autopep8-x)
(defun autopep8-x (begin end)
"Wraps autopep8 from ??? to format the region or the whole buffer."
(interactive
(if mark-active
(list (region-beginning) (region-end))
(list (point-min) (point-max))))
(autopep8 begin end)) ; assuming an existing autopep8 function taking
; region arguments but not defaulting to the
; whole buffer itself
That snippet could all go in .emacs or wherever you keep your customizations.
For some reason, copying lines in Emacs is very unintuitive and difficult. If I'm doing something wrong here, please let me know. It is surprising that Emacs does not have this by default somewhere.
I am trying to write a function that copies a line. I always used to have:
(global-set-key (kbd "C-x c") "\C-a\C- \C-n\M-w")
This is a little annoying since it copies any new line after the line. I decided to change it to:
(global-set-key (kbd "C-x c") "\M-m\C- \C-e\M-w")
Now, I saw: http://www.emacswiki.org/emacs/CopyingWholeLines and it appears that their copy-line function prints a message with the number of lines it copied. I am trying to insert that message into my global-set-key above but it is not working. Basically, I am unable to run a raw sequence as above in a function. So I conveyed each keystroke into a function and did this:
(defun copy-line ()
(interactive)
(kill-ring-save
(back-to-indentation)
(move-end-of-line 1))
(message "1 line copied"))
;; optional key binding
(global-set-key "\C-c\C-k" 'copy-line)
This however, throws a wrong number of arguments error.
My first question: How can I put (message "1 line copied") into my global-set-key above?
My second question: using the standard copy-line found in the link above:
(defun copy-line (arg)
"Copy lines (as many as prefix argument) in the kill ring"
(interactive "p")
(kill-ring-save (line-beginning-position)
(line-beginning-position (+ 1 arg)))
(message "%d line%s copied" arg (if (= 1 arg) "" "s")))
From the message, it appears that you can have multiple lines copied. However, when selecting multiple lines and copying, only one is copied. Why is the message structured in this way? How can it select multiple lines?
Here's your function, fixed:
(defun copy-line ()
(interactive)
(save-excursion
(back-to-indentation)
(kill-ring-save
(point)
(line-end-position)))
(message "1 line copied"))
The problem was that back-to-indentation doesn't return point.
As for the other function, it will copy multiple lines when called with
a prefix argument, e.g. C-u or M-5.
Here's a shorter version of the simple function:
(defun copy-line ()
(interactive)
(kill-ring-save (point-at-bol) (point-at-eol))
(message "1 line copied"))
For the multiline copy version that you cited, use the prefix to indicate how many lines you want copied (as the other answer suggests). So, with your keybinding of C-c C-k, do the following to copy, say, 3 lines: C-u 3 C-c C-k.
I have been using emacs for a while but not so familiar with lisp programming. Its been just couple of days I started coding Python on emacs. I found python-mode to be quite useful and I want to explore it further. I found a few emacs lips functions on internet, tewaked them a bit to make the interface userfriendly. I am trying to achieve following actions
I usually start emacs with 2 vertical windows, one with python source and other is a shell. I should be able to do following using keyboard bindings
switch between buffers (working)
execute a region (working)
but replaces the source buffer with shell buffer. I want to execute selected region in original shell buffer.
execute a line (working)
but same issue as above. when i pres say , the line should be executed in python shell without replacing any buffers. so copy the line, switch to python shell, execute line, switch back to python source buffer.
I am not able to achieve switching action above. Following is my code from my init.el file
(defun goto-python-shell ()
"Go to the python command window (start it if needed)"
(interactive)
(setq current-python-script-buffer (current-buffer))
(if (boundp 'current-python-shell-buffer)
(switch-to-buffer-other-window current-python-shell-buffer)
(py-shell))
(end-of-buffer)
)
(defun goto-python-source ()
"switch back to source window"
(interactive)
(setq current-python-shell-buffer (current-buffer))
(switch-to-buffer-other-window current-python-script-buffer)
)
(defun py-execute-statement-and-step ()
"select a statement, submit as a region and then step forward"
(interactive)
(beginning-of-line 1)
(let ((beg (point)))
(py-next-statement 1)
; if last statement.
(if (= (point) beg) (end-of-buffer ))
; (switch-to-buffer-other-window current-python-shell-buffer)
(py-execute-region beg (point))
(switch-to-buffer-other-window current-python-script-buffer)
)
)
; some key bindings
(define-key python-mode-map (quote [f9]) 'py-execute-statement-and-step)
;(define-key python-mode-map (quote [f10]) `py-execute-region)
;py-shell-switch-buffers-on-execute
(define-key python-mode-map (quote [f10]) `py-shell-switch-buffers-on-execute)
(define-key python-mode-map (quote [f11]) `py-execute-buffer)
(define-key python-mode-map (quote [f12]) `goto-python-shell)
(define-key py-shell-map (quote [f12]) `goto-python-source)
Please advice.
Also since i am new to python-mode, can someone share nice initializations for using python-mode similar to above?
thanks much for your help.
Regards,
AJ
You should take a look at the first answer to this question and customize the py-shell-switch-buffers-on-execute variable.
This way you won't need all your custom functions to make python-mode work like you want (i.e. keeping the source buffer active)
I think that you are trying to reinvent what is available in Emacs 24 (at least with evaluation stuff). Try Emacs 24. When you are editing a Python source code, you can press C-c C-c to evaluate a buffer and press C-c C-r to evaluate a region. You don't have to explicitly start a Python shell.
I don't think that there is a direct support for evaluate a line and step. You can achieve it by the keystrokes C-SPC C-n C-c C-r. Your focus will remain in the source code and there is no need to switch explicitly between the source code and the shell.
FWIW, I have been using Emacs 24 for a reasonable amount of time on a daily basis and I haven't encountered any stability issues.
following changes are working like a charm. f9 does line by line execute and f10 does region based execution. curser remains in the script window after i disabled py-shell-switch-buffers-on-execute.
(defun py-execute-statement-and-step ()
"select a statement, submit as a region and then step forward"
(interactive)
(beginning-of-line 1)
(let ((beg (point)))
(py-next-statement 1)
; if last statement.
(if (= (point) beg) (end-of-buffer ))
(py-execute-region beg (point))
(next-line)
)
)
(custom-set-variables
'(py-shell-switch-buffers-on-execute nil))
(define-key python-mode-map (quote [f9]) 'py-execute-statement-and-step)
(define-key python-mode-map (quote [f10]) `py-execute-region)