[I believe you meant sort-lines
, not sort
- that's the only way the question makes sense, so I am going to assume it.]
Both sort-lines
and delete-duplicate-lines
operate on the selected region. You must select a region before calling them, otherwise they will complain that there is no region. So you are going to have to do the same thing in your function: assume that you are given a region and complain if there is none.
A region is specified by two positions in the buffer, conventionally named BEG
and `END. So your function will look like this:
(defun sort-and-dedup (beg end)
(interactive <mumble>)
(sort-lines nil beg end)
(delete-duplicate-lines beg end))
The first argument to sort lines tells it whether to sort in reverse order.
When you call the function interactively, you specify a region by setting a mark at one end and then moving point to the other end (or by starting at one end and dragging with the mouse to the other end). So how do you communicate those positions to the function? By giving an argument to interactive
: if you look at its doc string (with C-h f interactive RET
), you will find that r
is what you need in order to specify a region - Emacs will arrange to translate the region you chose (however you chose it) into a pair of positions (BEG and END) that will be passed to your function.
So the function looks like this:
(defun sort-and-dedup (beg end)
(interactive "r")
(sort-lines nil beg end)
(delete-duplicate-lines beg end))
Alternatively, as @Dan suggests, you can use call-interactively
and let each function figure out what it needs. But you will still have to specify a region beforehand:
(defun sort-and-dedup ()
(interactive)
(call-interactively #'sort-lines)
(call-interactively #'delete-duplicate-lines))
EDIT: incorporating @phil's suggestion (and now I see that you have actually implemented this and added it to your question), you can write a function that calls (the first definition of) sort-and-dedup
with the necessary arguments to operate on the whole buffer:
(defun sort-and-dedup-whole-buffer()
(interactive)
(sort-and-dedup (point-min) (point-max)))
You can bind it to a key sequence if you are going to do that frequently:
(define-key global-map (kbd "M-S-<f10>" #'sort-and-dedup-whole-buffer)
although I would personally not do that: key sequences are a scarce commodity, so I would try it using M-x sort-and-dedup-whole-buffer RET
for a while; if that becomes a nuisance, then I would bind it to a key sequence.
I also revisit all my key defs every couple of years and reclaim ones that I don't use any more. I keep them in their own file, loaded explicitly by my init file, so I can find and review them easily.
C-h f
and then ask forsort
ordelete-duplicate-lines
. (C-h f
is the default keybinding for the commanddescribe-function
.)call-interactively
to call these functions from your elisp code as interactive commands.Symbol's value as variable is void: sort
interactive
form to supply those arguments (which may or may not involve prompting the user for any of the values, but which necessarily must result in values for all of the required arguments.)