Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The one thing I consistently do in emacs that shocks my coworkers -- is running this (custom) function, that I call "arrayify":

  (defun arrayify (start end quote)
    "Turn strings on newlines into a QUOTEd, comma-separated one-liner."
    (interactive "r\nMQuote: ")
    (let ((insertion
           (mapconcat
            (lambda (x) (format "%s%s%s" quote x quote))
            (split-string (buffer-substring start end)) ", ")))
      (delete-region start end)
      (insert insertion)))
What it does: Given a list of strings separated by newlines (commonly, something copy-pasted from a table) like:

  josh
  sam
  jed
  C.J.
  toby
You select the text, and run "arrayify". You can optionally provide a quote character and, in about half a second, get to:

  "josh", "jed", "sam", "C.J.", "toby"
  
This is incredibly useful for taking lists of IDs, or email addresses, or whatever, and transforming them for pasting into documents, or emails, or "in" clauses in SQL, etc.

It is unbelievably useful.



I achieve the same by running two consecutive regex search and replace and a single backspace click

    s/^/"/
    s/\n/“, /
(Change all beginning of line to double pling. Change all new lines to double pling, comma, space)

I don’t even store this as a procedure, I just ctr-f and do it from whatever text editor I’m in (I’m not an Emacs user)

The nice thing about search and replacing your way out of problems is that it works on coworkers machines.

I’m not saying it’s better than a stored procedure or a macro but once you’re into it, it’s easy to regex your way out of all sorts of adhoc problems :)


arrayify will also work on co-workers machines. You can open files on remote machines with tramp mode, and screenshare via zoom or something


I also prefer a more universal method. Arrayify is the equivalent of those useless specialized vegetable cutters and carvers in the kitchen that Alton Brown so hates. Search/Replace with Regex is universal.

Arrayify breaks down with the slightest change in requirements.


That's the whole point of a system like emacs: it enables the users to easily write solutions to their specific problems. It doesn't have to be general, it has to be easy to solve the problem at hand. It's the same with bash and unix tools. Writing general bash scripts is a nightmare, but datamunging particular problems works really well.


And then you write some more elisp


Yes, indeed. You can also do that, and other small variations on it depending on the context, with a macro.

You go to the end of "josh", press F3, add a comma and a space and you delete the rest of the line, until "sam" is now the next symbol after your cursor. Then you go to the end of the line (C-e) and press F4. Your macro is now recorded. To call it, press F4 repeatedly until everything is on one line.

As a bonus, you can actually name your macro, assign a keybinding to it, and can also save it as Lisp code.


Works well for a few dozen entries...less so for a few hundred or a few thousand :)


Emacs keyboard macros can easily operate on thousands of things. Just give it a prefix argument like C-u 1000 <macro-key-combo>.


Or use the C-u 0 prefix to repeat till there is an error, possibly at the end of buffer. And if you don't want to go on to the end of the buffer, narrow to the required region (C-x n n) and widen afterwards (C-x n w).


hell yeah, this is what I'm on about, I'm still learning stuff about emacs tricks here. I love this, thanks for bringing this up!


In vim:

    :'<,'>!awk '{printf("\"\%s\", ",$0)}'
or to do the whole file:

    :%!awk '{printf("\"\%s\", ",$0)}'

What I find nice about this approach is that I can use my knowledge of awk in other non-vim contexts. Similarly I can use my knowledge of other text processing commands to do things in vim, like reformat text into columns (:%!column -t) for example.

Of course you could use vim commands to do the same thing:

   0<ctrl-v>GI"<esc>$<ctrl-v>GA", <esc>VGJ
Which would have the benefit of making it more customizable at the expense of....well you can see what you have to type.


The way I'd do it in vim is to record a macro of doing it interactively by hand once, then play back that macro. I have space bound to @q to make playing back the macro in the q register easy (using the q register because q is also how you start and stop recording a macro.)

    noremap <Space> @q
These days I do this from evil-mode:

    (define-key evil-normal-state-map " " "@q")


Of course you can do the same shell thing easily enough with emacs, too.


You can use your knowledge of emacs in other non-emacs contexts as well! Elisp is a reasonably capable, if sprawling, programming language and comes with a lot of useful text and code munging stuff, as well as with cross-platform networking and filesystem support, and more esoteric stuff like calendar and symbolic/aribtrary precision math. And that's before installing any extra packages. I've written shebang scripts with Emacs (rather than say python or bash) on multiple occasions. Prior to windows growing linux support it probably also used to be one of the easier ways to write some unixy-feeling but cross-platform scripts; you can even craft a "shebang line" that works for both windows and unix. Having said that, due to general eco-systems advances, writing scripts in emacs has probably become less attractive than it used to be.


I really dig that about emacs. Having a programming language that is geared toward text processing is super useful. Doubly so when your editor is extensible in the same language.


> I can use my knowledge

That’s a great point. On the other hand, truly, “What happens in emacs, stays in emacs.”


I am developing a headache now, after trying this out, because I'm remembering all the times I have done this by hand. Or even writing an awk script, etc.


hm, I just select the text and do

     xclip -o | awk '{ print "\"" $0 "\"," }'
find it simpler than 10 lines of lisp but what do I know :p


Once you bind it to a key, though, it's a lot quicker. There is something to be said for emacs as a unified computing environment when compared to the UNIX way of doing things. Instead of wrangling different parts of the filesystem and tying them together with aliases and shell scripts, you can just version-control the productivity software (i.e. your emacs config) you write in the course of using emacs.


And now since I'm sucked into the cult of the helm-o-verse I find I am binding many fewer keys. Just start typing 'M-x ar' and now it's the second item. Add another 'r' brings it to the fore. Less (for me) to remember.

I note this mainly because it took me quite a long time to grok helm. Keep working with it!


You don't need Helm for that: smart M-x aka "smex" accomplished that for me and let me stay with ido, as I find Helm too intrusive.


Oh I really really loved smex. That's probably why it took me so long to get helm. helm doesn't improve on smex for this use case, I think. At least the stupid simple way I'm only going to use helm. But helm improves on other things spectacularly.


A lot quicker to do something specific. What if your problem involves text, but is always changing? Then you need general tools and a way to compose them together. Just like general Unix command and Awk which automatically loop through files. I would go crazy if I had to write actual code to do that kind of work 50 times a week.


A difference between emacs functions and awk one-liners is that the former are highly composable. Over the course of weeks you can build whole libraries of custom text-manipulation functionality for your particular domain, all integrated seamlessly into your editor. The thought of calling out to tools like awk for this is really galling. Could just be me, though.


Yeah...I was thinking about just writing a bunch of Powershell or TCL to make an expert shell. Sounds like a similar idea.


I'll be that guy ;)

In vim/unix you can run this command (keybinding not included but simple enough):

  :'<,'>%!awk 'BEGIN {ORS=" "} {print "\" $1 "\"," }
As for a unified computing environment, it is unified with the OS and not a world unto itself, there is no need to have one way of doing things within the editor and another if you want to script something. Both work just as well with version control, plus it gives you the flexibility to change text editor, like from vim to kak.

Speaking of kak, multiple cursors > any of these scripted options.


Yes, vim has a multiple cursor plugin that is useful for things like this: https://github.com/terryma/vim-multiple-cursors.

It's not as good as sublime in my experience, and I haven't used kakoune, but it's very serviceable.


Just put the following in your bashrc and it will simplify everything:

Alias emacs=‘vim’

:)


> Once you bind it to a key, though, it's a lot quicker.

but that's something any IDE in the world can do ?


Easier: C-u M-| will run a console program against the text.

It's great for running sort, awk, sed, etc.


Doesn't sound crazy at all to me! I do this all the time using multiline editing in Sublime Text. It's the one part of a more modern IDE I have a hard time giving up (transitioning to Spacemacs currently). Will have to try out this script and see if it helps bridge the gap!


If emacs keyboard macros haven't bridged the gap for you, try https://github.com/magnars/multiple-cursors.el

Keyboard macros: https://www.emacswiki.org/emacs/KeyboardMacros


I’ve been using this for a few things, and while it’s a little more unwieldy than Sublime’s it works fine for most of my uses so I’d definitely recommend giving it a go.


multiple-cursors is AMAZING and i use it all the time, but it does NOT work well for more than a few hundred lines of text. It gets incredibly slow.


Perfect - I'll try this out. Thanks for helping me out despite my newby-ness!


I tend to do it in sublime with a regex:

Find/replace all:

  ^(.*)$\n
with

  "$1",


That also works well in Emacs:

    C-M-% runs the command query-replace-regexp (found in global-map),
    which is an interactive compiled Lisp function in ‘replace.el’.

    It is bound to C-M-%, <menu-bar> <edit> <replace>
    <query-replace-regexp>.

    (query-replace-regexp REGEXP TO-STRING &optional DELIMITED START END
    BACKWARD REGION-NONCONTIGUOUS-P)

    Replace some things after point matching REGEXP with TO-STRING.
    As each match is found, the user must type a character saying
    what to do with it.  For directions, type <help> at that time.


I've been using Emacs for a very long time, and I do this on a fairly regular basis. I always used macros, but this function wins, hands down. Great job!


I'd always write a basic macro by hand in such a situation: F3, ", END, ", comma, DEL, space, right arrow, F4 however many times I need.


To run the macro as many times as possible, M-0, F4 (Alt-0, F4).


Just turned this into a Visual Studio Code extension: https://marketplace.visualstudio.com/items?itemName=Korfoo.a... Always wanted to try making an extension, but never had a good idea, thanks! :)


That's fantastic! I'm definitely adding that to my spacemacs setup.

I usually end up doing that in two steps, with the first being a recursive macro to quote each line:

    q y s $ " A , <escape> 0 j @ q
Then visually selecting and replacing new lines with spaces:

    V G :s/CTRL+Q CTRL+J/ /g


Love this. Adding to my `.emacs` now :)


I have used Excel's TEXTJOIN function for such cases.


I have a similar function. I find the inverse also very useful - especially for diffing things


I use a VIM macro for this.


Yup, same here. @aI"<esc>A",<esc>j off the top of my head and then something like 1000@a. I'd then just add brackets and remove the trailing comma.

Showing off macros (in my case evil mode, but I suppose it's the same for emacs) is a nice party trick that has impressed some of my coworkers.

Sadly it does not really do so well at actual parties...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: