Emacs complaining with invalid function? - emacs

When I press C-c c with the following code on a buffer, Emacs complains with Invalid function: (select-current-line). Why?
(defun select-current-line ()
"Select the current line"
(interactive)
(end-of-line) ; move to end of line
(set-mark (line-beginning-position)))
(defun my-isend ()
(interactive)
(if (and transient-mark-mode mark-active)
(isend-send)
((select-current-line)
(isend-send)))
)
(global-set-key (kbd "C-c c") 'my-isend)
Not that it matters, but for those interested isend-send is defined here.

You are missing a progn form to group statements together:
(defun my-isend ()
(interactive)
(if (and transient-mark-mode mark-active)
(isend-send)
(progn
(select-current-line)
(isend-send))))
Without the progn form, ((select-current-line) (isend-send)) is interpreted as the (select-current-line) function applied to the result of calling isend-send without arguments. But (select-current-line) is not a valid function name. In other LISPs, such a construct could be valid if the return value of select-current-line was itself a function, which would then be applied to (isend-send). But this is not the case of Emacs LISP and this would not do what you wanted to achieve anyway...

Related

(ELisp) automatically nesting next line using brace return

I'm completely new to both Lisp and Emacs. In Emacs, when coding in Java for example, I want to be able to type "{" then hit "ENTER" and have the next line be ready for whatever is nested in the braces. For example, if I have the following line:
public void method()
and I type "{" then hit return I should get this:
public void method() {
// indentation applied, no additional tabbing necessary
}
I'm already able to insert by pairs, for example, typing "{" gives "{}" with my cursor between the braces. I did this by adding these lines to the emacs init file:
;; insert by pairs (parens, quotes, brackets, braces)
(defun insert-pair (leftChar rightChar)
(if (region-active-p)
(let (
(p1 (region-beginning))
(p2 (region-end))
)
(goto-char p2)
(insert rightChar)
(goto-char p1)
(insert leftChar)
(goto-char (+ p2 2))
)
(progn
(insert leftChar rightChar)
(backward-char 1) ) )
)
(defun insert-pair-brace () (interactive) (insert-pair "{" "}") )
(global-set-key (kbd "{") 'insert-pair-brace)
To get the auto-nesting I described above, I added these lines:
;; automatically nest next line
(defun auto-nest ()
(insert "\n\n")
(backward-char 1)
(insert "\t")
)
(defun auto-nest-brace () (interactive) (auto-nest) )
(global-set-key (kbd "{ RET") 'auto-nest-brace)
When I start up Emacs, however, I get this message:
error: Key sequence { RET starts with non-prefix key {
What am I doing wrong, and what can I do to fix it? I don't want to use a different key combination to do this. There are a lot of text editors in which this auto-nesting is standard, and it should be easy enough to code up in ELisp.
It's great that you are trying to add this functionality to Emacs yourself, but there's no need to reinvent the wheel here. Emacs already has a command for the purpose of auto-indenting; it's called newline-and-indent. It is bound to C-j by default, but you can rebind it to RET
globally:
(global-set-key (kbd "RET") 'newline-and-indent)
for a specific mode only:
(require 'cc-mode)
(define-key java-mode-map (kbd "RET") 'newline-and-indent)
java-mode-map is defined in cc-mode.el and not available by default, that's why you have to require cc-mode before you can modify java-mode-map.
Note that newline-and-indent indents according to major mode. That is, if you're e.g. in java-mode and press RET in some random location that's not meaningful w/r/t Java syntax, it won't insert additional whitespace at the beginning of the new line.
To read all there is to know about newline-and-indent do
C-h f newline-and-indent RET
I have something similar in my emacs config which I have been using for a while. It calls 'newline-and-indent twice then moves the point one line up before indenting correctly. Here is the snippet of code to do this from my config file:
;; auto indent on opening brace
(require 'cc-mode)
(defun av/auto-indent-method ()
"Automatically indent a method by adding two newlines.
Puts point in the middle line as well as indent it by correct amount."
(interactive)
(newline-and-indent)
(newline-and-indent)
(forward-line -1)
(c-indent-line-or-region))
(defun av/auto-indent-method-maybe ()
"Check if point is at a closing brace then auto indent."
(interactive)
(let ((char-at-point (char-after (point))))
(if (char-equal ?} char-at-point)
(av/auto-indent-method)
(newline-and-indent))))
(define-key java-mode-map (kbd "RET") 'av/auto-indent-method-maybe)
Pretty straightforward as you can see. Hopefully it will work for you. I have not used it in any other modes except java.
You want a combination of auto pairs (or alternatives) plus auto indentation. Check out the emacswiki on the former: http://www.emacswiki.org/emacs/AutoPairs
And on the latter:
http://www.emacswiki.org/emacs/AutoIndentation

Emacs Copy Current Line

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.

Emacs quicker bookmark-jump?

I have most of my bookmarks prefixed by a letter in a way that
the first letter almost always uniquely determines the bookmark.
This way I can, for instance,
jump to my source folder (bookmarked as "s: source") with M-x bookmark-jump RET s RET.
I have it on a shortcut, so it's actually ~ s RET.
I'd like to get rid of RET in the end,
i.e. get M-x bookmark-quick-jump RET s or ~ s
to do the aforementioned job.
I'd also like it to fall back to the default behavior: to show me all bookmarks
that start with the given letter, in case there's not just one variant.
So far, I've got:
(defun bookmark-do-quick-jump (str)
(let ((completions (all-completions str bookmark-alist)))
(bookmark-jump
(if (eq 1 (length completions))
(car completions)
(completing-read "Jump to bookmark: " bookmark-alist nil t str)))))
There's still two hiccups:
Firstly, I need to jump into minibuffer somehow and stick in there this map (don't know how to do this):
(setq bookmark-quick-jump-map
(let ((map (make-sparse-keymap)))
(mapcar (lambda (key)
(define-key map key
(lambda()
(interactive)
(bookmark-do-quick-jump key))))
(loop for c from ?a to ?z
collect (string c)))
map))
Secondly, when I do a call
(bookmark-do-quick-jump "o")
It comes back with 3 variants (org-capture-last-stored, org-capture-last-stored-marker...).
I'm in minibuffer now, but I still need to press RET RET
to see these 3 variants. I'd like this to be done automatically.
I'd appreciate any responses that either directly answer my two sub-problems,
or an altogether different approach, as long as I can get the behavior and usability
that I described.
UPD:
I've solved the second thing by switching from completing-read to ido-completing-read:
(defun bookmark-do-quick-jump (str)
(let ((completions (all-completions str bookmark-alist)))
(bookmark-jump
(if (eq 1 (length completions))
(car completions)
(ido-completing-read "Jump to bookmark: " completions nil t str)))))
Btw, I forgot to mention that I use bookmark+. I'm not sure if jumping to dired
is supported by the default bookmark-jump.
We can remap self-insert-command during the completing-read to trigger the auto-completion and auto-acceptance behaviour.
I originally used (or (minibuffer-complete-and-exit) (minibuffer-completion-help)) which at first glance worked very nicely but, as noted in the comments, is less than ideal when one bookmark's name is the prefix of another, as it will immediately accept the shorter name, hence making the longer one inaccessible.
Calling minibuffer-complete and minibuffer-completion-help together breaks the completion functionality, however, so instead I've copied the relevant part of minibuffer-complete-and-exit to a new function. Using this resolves all of the earlier problems.
(require 'bookmark)
(defvar bookmark-do-quick-jump-map (copy-keymap minibuffer-local-must-match-map)
"Keymap for `bookmark-do-quick-jump'.
`minibuffer-local-must-match-map' is used by `completing-read' when its
REQUIRE-MATCH argument is t.
In `bookmark-do-quick-jump' we bind this modified copy to use in its place.")
(define-key bookmark-do-quick-jump-map
[remap self-insert-command] 'my-self-insert-complete-and-exit)
(defun bookmark-do-quick-jump ()
"Jump to specified bookmark with auto-completion and auto-acceptance."
(interactive)
(bookmark-maybe-load-default-file)
(let ((minibuffer-local-must-match-map bookmark-do-quick-jump-map))
(bookmark-jump
(completing-read "Jump to bookmark: " bookmark-alist nil t))))
(defun my-self-insert-complete-and-exit (n)
"Insert the character, then attempt to complete the current string,
automatically exiting when only one option remains, and displaying the
completion options otherwise."
(interactive "p")
(self-insert-command n)
(my-minibuffer-complete)
(let ((my-completions (completion-all-sorted-completions)))
(if (and my-completions (eq 0 (cdr my-completions)))
(exit-minibuffer)
(minibuffer-completion-help))))
(defun my-minibuffer-complete ()
"Copied from `minibuffer-complete-and-exit'."
(interactive)
(condition-case nil
(completion--do-completion nil 'expect-exact)
(error 1)))
Edit:
I took another stab at this using ido. It's a little unfortunate that you don't get the next 'important character' highlighted the way that you do with the regular minibuffer completion (as that was a nice indicator of what to type next), but this seems to work nicely in other respects.
(require 'bookmark)
(require 'ido)
(defvar bookmark-ido-quick-jump-map (copy-keymap minibuffer-local-map)
"Keymap for `bookmark-ido-quick-jump'.
Every time `ido-completing-read' is called it re-initializes
`ido-common-completion-map' and sets its parent to be `minibuffer-local-map'.
In `bookmark-ido-quick-jump' we provide this modified copy as a replacement
parent.")
(define-key bookmark-ido-quick-jump-map
[remap self-insert-command] 'my-self-insert-and-ido-complete)
(defun bookmark-ido-quick-jump ()
"Jump to selected bookmark, using auto-completion and auto-acceptance."
(interactive)
(bookmark-maybe-load-default-file)
(let ((minibuffer-local-map bookmark-ido-quick-jump-map)
(ido-enable-prefix t))
(bookmark-jump
(ido-completing-read "Jump to bookmark: "
(loop for b in bookmark-alist collect (car b))))))
(defun my-self-insert-and-ido-complete (n)
"Insert the character, then attempt to complete the current string,
automatically exiting when only one option remains."
(interactive "p")
(self-insert-command n)
;; ido uses buffer-local pre- and post-command hooks, so we need to
;; co-operate with those. We append our post-command function so that
;; it executes after ido has finished processing our self-insert.
(add-hook 'post-command-hook
'my-self-insert-and-ido-complete-post-command t t))
(defun my-self-insert-and-ido-complete-post-command ()
(remove-hook 'post-command-hook
'my-self-insert-and-ido-complete-post-command t)
;; Now that ido has finished its normal processing for the current
;; command, we simulate a subsequent `ido-complete' command.
(ido-tidy) ;; pre-command-hook
(ido-complete)
(ido-exhibit)) ;; post-command-hook
Here's another take:
(defun bookmark-do-quick-jump (str)
(let ((completions (all-completions str bookmark-alist)))
(if (null (cdr completions))
(bookmark-jump (car completions))
(minibuffer-with-setup-hook
(lambda () (insert str)
(minibuffer-completion-help))
(call-interactively 'bookmark-jump)))))
Or yet another (even more guaranteed untested):
(defadvice bookmark-jump (around quick-bookmarks activate)
(minibuffer-with-setup-hook
(lambda ()
(add-hook 'post-self-insert-hook
(lambda ()
(let ((completions
(all-completions (minibuffer-contents)
bookmark-alist)))
(if (cdr completions)
(minibuffer-completion-help)
(minibuffer-complete-and-exit))))
nil t))
ad-do-it))
Sounds like you're doing a lot of extra work. Just use Icicles.
User option icicle-incremental-completion non-nil and non-t means show all matches as soon as you type input.
Option icicle-top-level-when-sole-completion-flag non-nil means accept a solitary match without your needing to hit a key (e.g. RET).
Instead of customizing the options to have these values in general, you can just bind them to the values in your own command.

Emacs run forward char in a hook

I wrote this below to get to search for the next period in tex mode. It works fine except trying to get it to move forward a char after it finds the period. I am not sure how to do this but here was my attempt.
(add-hook 'text-mode-hook (lambda ()
(local-set-key (kbd "s-p")
(lambda () (interactive) ((search-backward "." nil t) (forward-char))))))
Final solution I combined the functions from ajk solution. I couldn't get the other one working without the add-hook. Someone might know how to get the second one working. The below completely works and searches backward for the previous period unless it is currently at a period.
(add-hook 'text-mode-hook
(lambda ()
(local-set-key (kbd "s-p")
(lambda ()
(interactive)
(if (looking-back "\.")
(backward-char))
(search-backward "." nil t)
(forward-char)))))
Thanks for the help.
You have parentheses around the last two function calls in the anonymous function you're assigning to the key, causing Emacs Lisp to think you want to call a function named (search-backward "." nil t). Try
(add-hook 'text-mode-hook
(lambda ()
(local-set-key (kbd "s-p")
(lambda ()
(interactive)
(search-backward "." nil t)
(forward-char)))))
The problem I would have with this binding is it's not repeatable. If you run it a second time, it finds the same period you just found. You might want to check to see if the previous character is a period and if so, skip it. Also, you can simplify it a bit by using define-key to add the binding explicitly to the text-mode keymap:
(define-key text-mode-map (kbd "s-p")
(lambda ()
(interactive)
(if (looking-back "\.")
(backward-char))
(search-backward "." nil t)
(forward-char)))

In Emacs, can we make one keystroke to do different command?

I want to make one keystroke, say C-F12, to do delete-other-windows or winner-undo. I think it's easy if I already learning Emacs Lisp programming, and set a boolean flag. That is, if previously it run delete-other-window, now it'll run winner-undo.
How do you do that in Emacs Lisp?
Thanks
Try something like this
(setq c-f12-winner-undo t)
(define-key (current-global-map) [C-f12]
(lambda()
(interactive)
(if c-f12-winner-undo
(winner-undo)
(delete-other-windows))
(setq c-f12-winner-undo (not c-f12-winner-undo))))
(defun swdev-toggle-sole-window ()
(interactive)
(if (cdr (window-list))
(delete-other-windows)
(winner-undo)))
(global-set-key (kbd "<C-f12>") 'swdev-toggle-sole-window)
The first line starts the declaration of a function called swdev-toggle-sole-window, taking no argument.
This function is declared as interactive, i.e. it can be called with M-x or through a key binding.
If the window list contains more than one element, i.e. if there is more than one window, …
… then delete other windows …
… else undo the window deletion.
Bind the function to the key C-f12.
Here's a solution using the approach taken by Emacs' recenter-top-bottom function:
(defun delete-other-window-or-winner-undo ()
"call delete-other-window on first invocation and winner-undo on subsequent invocations"
(interactive)
(if (eq this-command last-command)
(winner-undo)
(delete-other-windows)))
(global-set-key (kbd "<C-f12>") 'delete-other-window-or-winner-undo)