I am new to Emacs. I have googled this but no good answer there. One of them is
Ctrl-n Ctrl-a Backspace
This works but is stupid. Is there a quick and simple way to join a block of lines into a single line?
Actually, I can use Esc-q to auto-fill a paragraph now, but how could I get it to revert without UNDO?
Place point anywhere on the last line of the group of lines that need joining and call
M-^
repeatedly until all the lines are merged.
Note: It leaves one space between all of the now joined lines.
M-x join-line will join two lines. Just bind it to a convenient keystroke.
Multiple Cursors combined with M-^ will collapse all selected lines into one with all extraneous white-space removed.
For example to select an entire buffer, invoke multiple cursors mode, collapse into one line, and then disable multiple cursors mode:
C-x h
M-x mc/edit-lines
M-^
C-g
The Emacs conventional name for "join" is "fill". Yes, you can join
two lines with M-^ -- and that's handy -- but more generally you'll
want to join n lines. For this, see the fill* commands, such as
fill-region, fill-paragraph, etc.
See this for more info
on selecting things which can then be filled.
Also, you can join multiple lines with M-^ by selecting those lines first. (Note that the universal argument does not work with this.)
Just replace newlines with nothing.
I like the way Sublime text Join line with Command J so I do it this way:
(defun join-lines (arg)
(interactive "p")
(end-of-line)
(delete-char 1)
(delete-horizontal-space)
(insert " "))
You could define a new command for this, temporarily adjusting the fill width before using the the Esc-q command:
;; -- define a new command to join multiple lines together --
(defun join-lines () (interactive)
(setq fill-column 100000)
(fill-paragraph nil)
(setq fill-column 78)
)
Obviously this only works, if your paragraph has less than 100000 characters.
I use the following function and bind it to 'M-J'.
(defun concat-lines ()
(interactive)
(next-line)
(join-line)
(delete-horizontal-space))
If you prefer to keep your cursor position, you can use save-excursion.
The most simplest way ever:
Select paragraph/lines by M-h or C-SPC
Press M-q
Witness the Emagics (Emacs Magic)!!
Because join-line will left one space between two lines, also it only support join two lines. In case of you want to join plenty of lines without one space left, you can use "search-replace" mode to solve, as follows:
C-%
Query: input C-q C-j Enter
Replace: Enter
Run the replacement. Enter
Done.
Two ways come to mind:
Once you think of it, the most obvious (or at least easiest to remember) way is to use M-q format-paragraph with a long line length C-x-f 1000.
There is also a built-in tool M-^ join-line. More usefully, if you select a region then it will combine them all into one line.
"how could I get it to revert without UNDO?":
(defun toggle-fill-paragraph ()
;; Based on http://xahlee.org/emacs/modernization_fill-paragraph.html
"Fill or unfill the current paragraph, depending upon the current line length.
When there is a text selection, act on the region.
See `fill-paragraph' and `fill-region'."
(interactive)
;; We set a property 'currently-filled-p on this command's symbol
;; (i.e. on 'toggle-fill-paragraph), thus avoiding the need to
;; create a variable for remembering the current fill state.
(save-excursion
(let* ((deactivate-mark nil)
(line-length (- (line-end-position) (line-beginning-position)))
(currently-filled (if (eq last-command this-command)
(get this-command 'currently-filled-p)
(< line-length fill-column)))
(fill-column (if currently-filled
most-positive-fixnum
fill-column)))
(if (region-active-p)
(fill-region (region-beginning) (region-end))
(fill-paragraph))
(put this-command 'currently-filled-p (not currently-filled)))))
(global-set-key (kbd "M-q") 'toggle-fill-paragraph)
From EmacsWiki: Unfill Paragraph
;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
;; This would override `fill-column' if it's an integer.
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
A basic join of 2 lines:
(delete-indentation)
I like to line below to be joined to the current without moving the cursor:
("C-j" .
(lambda (iPoint)
"Join next line onto current line"
(interactive "d")
(next-line)
(delete-indentation)
(goto-char iPoint)))
This one behaves like in vscode. So it add space only if join line consisted something else than whitespace. And I bind it to alt+shift+j.
Shorter version based on crux-top-join-line:
(global-set-key (kbd "M-J") (lambda () (interactive) (delete-indentation 1)))
Longer version based on https://stackoverflow.com/a/33005183/588759.
;; https://stackoverflow.com/questions/1072662/by-emacs-how-to-join-two-lines-into-one/68685485#68685485
(defun join-lines ()
(interactive)
(next-line)
(join-line)
(delete-horizontal-space)
(unless (looking-at-p "\n") (insert " ")))
(global-set-key (kbd "M-J") 'join-lines)
Related
The function delete-indentation, usually bound to (M-^), joins the current line to the next one and deletes any indentation.
How do I apply this function to a whole region to join multiple lines in a region?
Or is there another way to achieve the desired result?
Thanks
Try unfill-paragraph, taken from the Emacs wiki.
;;; An unfill-paragraph that works in lisp modes
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
If you're willing to give up the prefix argument of the standard M-^, you could bind the following function to that keyboard shortcut like so:
(defun join-line-or-unfill-paragraph (&optional unfill)
(interactive "P")
(if unfill (unfill-paragraph) (delete-indentation)))
(global-set-key (kbd "M-^") 'join-line-or-unfill-paragraph)
This way, whenever you type C-u before M-^ the full paragraph will be joined.
Here's the bigger picture of what I'm trying to do:
With a keypress, it will insert an opening and closing parenthesis right after/before the innermost closing/opening delimiter (bracket, brace, parenthesis, whatever).
But if it is pressed immediately after, it will undo the last insertions, seek out the next closing delimiter, and put it after that, and so on.
I have a working version of the first part, but am looking for "best practices" for the second part (where it undoes and moves outwards)
As a motivator and concrete example, this is a typical scenario when coding in Python. I work with list comprehensions a lot, and often I construct the list, and then decide I want to sum all elements, etc. So I would first type:
[x*x for x in some_lst if is_prime(x)]
and then I'll want to encapsulate this list with a "sum" command:
sum([x*x for x in some_lst if is_prime(x)])
I don't want to have to keep moving the cursor to both the beginning and the end just to insert the parentheses. I'd rather have the point in the list, press a keystroke, have it figure out the delimiters, and place the mark just before the opening inserted parenthesis so that I can type "sum". My function below seems to work (piggybacking on the "expand-region" package):
(defun add-paren ()
(interactive)
(er/mark-outside-pairs)
(exchange-point-and-mark)
(insert-string ")")
(exchange-point-and-mark)
(insert-string "(")
(left-char 1)
)
What's the best practice for the 2nd step?
(Any suggestions/improvements to the above would also be appreciated. This is my first "real" function in Elisp.)
Thanks.
Update: Thanks everyone for the tips. I'll probably use some of them in my final solution. My original question still stands: Is there a standard pattern of "undoing and redoing at a larger scale", or will each problem have its own custom solution? Suppose I use smartparens as suggested to do it all in one keystroke, but I want it to occur on the 3rd level out. What I want is to press the keystroke 3 times and have it place the parentheses there.
So after the first keystroke, it places the parentheses at the innermost level. Pressing it again should remove the inserted parentheses, and place them in the next level up, and so on...
(BTW, not trying to reinvent the wheel. I suspect some of the packages listed may have exactly what I need - I just want practice coding in Elisp).
Update 2:
I guess there is no best practice for this? Anyway, I solved the problem using both expand-region and smartparens:
(defun add-paren ()
(interactive)
(if (eq last-command 'add-paren)
;; (message "AAAA")
(delete-paren)
)
(setq currpoint (point))
(er/mark-outside-pairs)
(if (eq currpoint (point))
(er/mark-outside-pairs)
)
(sp-wrap-with-pair "(")
(left-char 1)
)
(global-set-key (kbd "<f5>") 'add-paren)
(defun delete-paren ()
(interactive)
(setq currloc (point))
(sp-unwrap-sexp)
(goto-char currloc)
(left-char 1)
)
You're already using expand-region. Why not combine that with one of the many "surround region with..." modes?
I personally like smartparens (available via Marmalade or MELPA), but there are many other similar tools.
Use er/expand-region until you've got an appropriate selection, then
( to wrap in parentheses.
When programming, there are several hundred slightly different edit-tasks of this kind. Therefor created a toolkit for it.
In example given, the form might be described as delimited, more precisely bracketed.
ar-bracketed-atpt would mark it.
It's set here like this:
(global-set-key [(super \])] 'ar-bracketed-atpt)
Then comes in another class of commands which do several things on active region. In this case:
M-x ar-parentize-or-copy-atpt RET
It is bound to C-c )
A tarball for all this stuff is available here:
https://launchpad.net/s-x-emacs-werkstatt/
FWIW, I'd do it as follows:
go before the open bracket.
type sum C-M-SPC (
The C-M-SPC selects the parenthesized (well, "bracketized") expression, and the subsequent ( wraps it in parens (because of electric-pair-mode).
I guess there is no best practice for this? Anyway, I solved the problem using both expand-region and smartparens:
(defun add-paren ()
(interactive)
(if (eq last-command 'add-paren)
;; (message "AAAA")
(delete-paren)
)
(setq currpoint (point))
(er/mark-outside-pairs)
(if (eq currpoint (point))
(er/mark-outside-pairs)
)
(sp-wrap-with-pair "(")
(left-char 1)
)
(global-set-key (kbd "<f5>") 'add-paren)
(defun delete-paren ()
(interactive)
(setq currloc (point))
(sp-unwrap-sexp)
(goto-char currloc)
(left-char 1)
)
Any such function or elisp script? I want the equivalent function as vi" sequence in vim.
Try the key sequence C-M-u C-M-SPC (i.e., while holding the Control and Meta keys, press u and Space in sequence), which executes the commands backward-up-sexp and mark-sexp.
Edit:
I made a mistake: backward-up-sexp doesn't exist in standard Emacs. I wrote it exactly because of the problem mentioned in lkahtz's comment, that the existing function backward-up-list won't work when point is between double quotes.
(defun backward-up-sexp (arg)
(interactive "p")
(let ((ppss (syntax-ppss)))
(cond ((elt ppss 3)
(goto-char (elt ppss 8))
(backward-up-sexp (1- arg)))
((backward-up-list arg)))))
(global-set-key [remap backward-up-list] 'backward-up-sexp)
expand-region (which is bound to C-=) works great.
Xah Lee has an emacs-lisp function which achieves this called xah-select-text-in-quote. It is available from his website:
Select text between the nearest left and right delimiters.
Delimiters here includes the following chars: \"<>(){}[]“”‘’‹›«»「」『』【】〖〗《》〈〉〔〕().
This command does not properly deal with nested brackets.
When I hit C-k, Emacs kills to end-of-line. When I hit C-k again, it "kills the newline" and brings the next line up. However, the next line's indentation remains intact, and you can end up with a line that has lots of spaces in the middle.
So, from this:
previous line material
next line material
to this:
previous line material next line material
I understand I can use M-^ to join lines properly, but that requires the cursor to be on the next line. How do I modify C-k so that when it kills the newline, also kills the next line's indentation?
For C-k I don't know, but you could use the just-one-space function to transform any number of space into juste one space (it's bound on M-space)
If you give M-^ an argument (for example C-u M-^), it will join the next line to the current line.
Here's a way to plug in the behavior (I think) you want into kill-line: when killing a newline, also kill the indentation that follows. Note that this may result in no space being present after the cursor, which is why I think I'd go with M-1 M-^ or C-k M-SPC instead.
(defadvice kill-line (around kill-indentation
activate compile)
"When killing a line break, also kill any subsequent indentation."
(let ((f-v-l (symbol-function 'forward-visible-line)))
(flet ((forward-visible-line (arg)
(funcall f-v-l arg)
(skip-chars-forward " \t")))
ad-do-it)))
I have this in my .emacs:
(defun pull-line ()
"Pull the next line that contains anything up to the end of this one"
(interactive)
(save-excursion
(end-of-line)
(while (looking-at "[ \n\r\t]")
(delete-char 1))
(if (looking-back "^[[:blank:]]*[[:punct:][:alnum:]].*")
(fixup-whitespace)
(indent-according-to-mode))))
(global-set-key "\C-cp" 'pull-line)
It pulls the next non-blank line up to the this one, and if there is anything on this line it makes calls (fixup-whitespace) which does the right thing about 95% of the time, otherwise it indents it to what emacs thinks is the right level. I think I copied the concept from vim?
I use it all the time, anyway.
I just realized I also have this in my .emacs, it is more exactly what you want, although I forget that I have it since I use pull-line much more often. I think I stole this from emacswiki:
(defun kill-and-join-forward (&optional arg)
"If at end of line, join with following; otherwise kill line.
Deletes whitespace at join."
(interactive "P")
(if (and (eolp) (not (bolp)))
(progn
(delete-indentation t)
(if (looking-at " $")
(delete-char 1)))
(kill-line arg)))
(global-set-key "\C-k" 'kill-and-join-forward)
This will do it:
(defun my-kill-line (&optional arg)
(interactive "P")
(if arg
(kill-line arg)
(when (prog1 (eolp) (kill-line))
(just-one-space 1))))
I don't know if there's something wrong with my settings but when I press M-f (forward a word)
it doesn't matter where I am, it never place the cursor in the next word (just between words). This doesn't happen with M-b which place my cursor in the beginning of the previous word.
Is this a normal behavior? How do I place my cursor at the beginning of the following word?
The macro solution described is a great way to get this behavior in a session, but it's a little inconvenient if that's the default behavior you want, since you have to define it every time you start emacs. If you want M-f to work like this all the time, you can define an elisp function and bind it to the key. Put this in your .emacs file:
(defun next-word (p)
"Move point to the beginning of the next word, past any spaces"
(interactive "d")
(forward-word)
(forward-word)
(backward-word))
(global-set-key "\M-f" 'next-word)
Ok, just so we're clear, Im going to assume you are talking about the commands forward-word and backward-word these are bound by default to Alt+f and Alt+b
eg string: "Hello dolly I am here"
If your cursor is on the "H" of "Hello", and you do forward-word the cursor will move to the space between "Hello" and "dolly", but it sounds like you want the cursor to be on the letter "d" of "dolly" instead of in-front of it.
So, do forward-word twice, then backward-word once.
That will put your cursor on the "d" of "dolly".
This can be automated with a macro.
;; = comments, do not type them
Ctrl+x ( ;;start macro
Alt+f Alt+f Alt+b
Ctrl+x ) ;;end macro
Then to run last defined macro do this:
Ctrl+x e
EDIT: as pascal mentioned in a comment, this can also just be done with
Alt+f Ctrl+f
You could put that into a macro as well, either way the result is the same.
That is correct behavior. According to the Emacs manual, "[f]orward motion stops right after the last letter of the word, while backward motion stops right before the first letter."
Why is it this way? Perhaps to be consistent with kill-word (M-d).
Moving forward twice and backwards once is fine unless you are at the beginning of a line with spaces in the front. Then going forward twice and back once will move you to the next word not the first word. The code below will mimic vi's "w" command perfectly. I've written this quite fast so this code can be cleaned up further.
(defun forward-word-to-beginning (&optional n)
"Move point forward n words and place cursor at the beginning."
(interactive "p")
(let (myword)
(setq myword
(if (and transient-mark-mode mark-active)
(buffer-substring-no-properties (region-beginning) (region-end))
(thing-at-point 'symbol)))
(if (not (eq myword nil))
(forward-word n))
(forward-word n)
(backward-word n)))
(global-set-key (kbd "M-C-f") 'forward-word-to-beginning)
Try something like following:
;; replace common word-operations on same-syntax-operations
(require 'thingatpt)
(global-set-key "\M-f" 'forward-same-syntax)
(global-set-key "\M-b" (lambda()
(interactive)
(forward-same-syntax -1)))
(defun kill-syntax (&optional arg)
"Kill ARG sets of syntax characters after point."
(interactive "p")
(let ((opoint (point)))
(forward-same-syntax arg)
(kill-region opoint (point))))
(global-set-key "\M-d" 'kill-syntax)
(global-set-key [(meta backspace)] (lambda()
(interactive)
(kill-syntax -1)))
You can achieve this behavior by using the forward-to-word and backward-to-word found in misc.el. I have these bound to Meta-F/Meta-B (i.e. with Shift pressed). These are equivalent to Meta-f/Meta-b for forward-word/backward-word
My .emacs has the following bindings
(global-set-key (kbd "M-F") #'forward-to-word)
(global-set-key (kbd "M-B") #'backward-to-word)