News for hackers. Stuff that matters.
Re:Sorting in Emacs by shepmaster on Saturday August 12, 2023 @07:51AM (#37099245)
I often want to sort within a line:

    [“zoo”, “cow”]
Would become

    [“cow”, “zoo”]
Any tips on how to do that? Ideally using just built in functions…

I usually insert newlines between the elements, use a line-based sort, then recombine the lines. That works but is more tedious than I’d like. I’ve never taken the time to wrap that logic it in a function because it’s infrequent and it seems like it’s always slightly different.

Re:Sorting in Emacs by cle on Saturday August 12, 2023 @08:39AM (#37099575)
If this is Python, I'd just send it to a Python one-liner with C-u M-| and then:

    python -c 'import sys; v=eval(sys.stdin.read().strip()); v.sort(); print(v)'
It's hard to generalize these kinds of things, like if you have a list split across lines with different indentations, single/double quotes, trailing/non-trailing commas on the last value, etc. Probably best to just do the easiest thing to get them sorted and then use a keyboard macro or multiple-cursors to massage the output to your desired format.
Re:Sorting in Emacs by G3rn0ti on Saturday August 12, 2023 @08:16AM (#37099424)
Keyboard macro. You convert the arrays into lines, you sort the result and then turn them back into arrays. If you do this often you could store the macro as an interactive command.
Re:Sorting in Emacs by agumonkey on Saturday August 12, 2023 @08:28AM (#37099505)
and for larger lists maybe a C-u shell-command-on-region to a script
Re:Sorting in Emacs by pasc1878 on Saturday August 12, 2023 @08:44AM (#37099621)
Why bother recombining the lines?
Re:Sorting in Emacs by CanaryLayout on Saturday August 12, 2023 @08:52AM (#37099671)
Mostly to pretty it back up into the original shape (so it matches what was already in git)
Re:Sorting in Emacs by pasc1878 on Sunday August 13, 2023 @05:48AM (#37108310)
Take one hit on format - your change is also only a format change.
Re:Sorting in Emacs by kroger on Saturday August 12, 2023 @08:48AM (#37099648)
I found this on the Emacs Wiki [1]. It seems to work:

    (defun sort-symbols (reverse beg end)
      "Sort symbols in region alphabetically, in REVERSE if negative.
    See `sort-words'."
      (interactive "*P\nr")
      (sort-regexp-fields reverse "\\(\\sw\\|\\s_\\)+" "\\&" beg end))
[1]: https://www.emacswiki.org/emacs/SortWords
Re:Sorting in Emacs by tom_ on Saturday August 12, 2023 @08:57AM (#37099700)
Copy to clipboard, paste into your interactive Python window, and use as the argument to sorted. Copy and paste the interpreter's output back into your code.
Re:Sorting in Emacs by owl57 on Saturday August 12, 2023 @09:47AM (#37100124)
You technically described how to make a word sorting macro execute arbitrary code.

Fascinating to think how that doesn't mean it's bad advice. That is, unless your threat model includes targeted attacks by three-letter-scale adversaries — and then you maybe just don't open untrusted files in Emacs or use advice from strangers on HN.

Re:Sorting in Emacs by tom_ on Saturday August 12, 2023 @10:04AM (#37100292)
That's a good point. My assumption, not that I ever stated it, was that the list would be one you'd typed out yourself, or was one that was just there in code already, and you could verify by eye that it's just string literals.

Using Python's eval with empty globals and locals dicts (consult the docs) could make this safer, though I've only ever had to use that for defending against accidents rather than malice. And now this quick thing is becoming increasingly complicated, and maybe you'd be better off engineering it properly.

Re:Sorting in Emacs by ktm5j on Saturday August 12, 2023 @12:57PM (#37102066)
This is actually a rather common thing to do.. I have functions that run shell commands in my spacemacs config to do things like this. For example I've got one that runs `date` to insert today's date in a particular format.
Re:Sorting in Emacs by lvass on Saturday August 12, 2023 @10:36AM (#37100608)
>Copy to clipboard, paste into your interactive Python window

python-shell-send-statement, it's built into Emacs's python mode.

Re:Sorting in Emacs by tom_ on Saturday August 12, 2023 @12:18PM (#37101704)
I was thinking you'd need it pasteable to pass it into sorted, but, yes, you could probably just evaluate it and then do sorted(_).
Re:Sorting in Emacs by brunoqc on Saturday August 12, 2023 @10:34AM (#37100583)
Re:Sorting in Emacs by natrys on Saturday August 12, 2023 @10:47AM (#37100726)
Probably simplest is to not overthink and just write elisp, which is a fairly normal language.

    (defun my-sort-list ()
      (interactive)
      (when (not (looking-at (rx "[")))
        (search-backward "[" nil t))
      (when-let* ((line (thing-at-point 'sexp t))
                  (items (split-string (substring line 1 -1) (rx ",") t (rx blank)))
                  (sorted (string-join (sort items #'string-lessp) ", ")))
        (kill-sexp)
        (insert "[" sorted "]")))
I don't think I am using any non-builtin function here, though I think a few exceptions like s.el, f.el and dash.el can make things much easier.
Re:Sorting in Emacs by minhm on Saturday August 12, 2023 @11:55PM (#37106540)
"split-string" works well for this situation but for a case where there are commas inside some of the strings it would chop in the middle of those strings. So for the latter case and assuming the commas are consistently formatted, a safer approach might be starting in front of the first s-expression and then traversing to the tail of each s-expression with "forward-sexp" and check to see if a comma is there as expected and then delete the comma there (except for the last item with no comma) .
Re:Sorting in Emacs by natrys on Sunday August 13, 2023 @05:57AM (#37108355)
Yeah that's the classic comma in CSV problem. The solution is to indeed use a proper grammar/parser. The "forward-sexp" understands that as per major-mode rule as you say. Another more modern and declarative solution would be to take advantage of the full parse tree at your disposal thanks to tree-sitter (available in Emacs 29.1). Then you can simply do:

    (let ((list (treesit-thing-at-point "list" 'nested))
          (query "(list (string (string_content) @item))"))
      (cl-loop for (_ . item) in (treesit-query-capture list query)
               collect (treesit-node-text item t)))
Re:Sorting in Emacs by gnuvince on Saturday August 12, 2023 @11:11AM (#37100982)
Select the line, then type

    C-u M-| jq -c sort
Re:Sorting in Emacs by gumby on Saturday August 12, 2023 @11:58AM (#37101504)
I've been using Emacs for over 40 years but still find the shell my go-to sorting approach. Right tool for the job and all that.
Re:Sorting in Emacs by JNRowe on Saturday August 12, 2023 @01:07PM (#37102165)
I lean a fair bit in the opposite direction. If a sort is any more complex than -n or -k<number no flags>, I tend to vipe¹ my sort in my editor.

It feels great when you can use narrow-to-region² to perfect a complex address or write a custom function with all your editor's power at your fingertips. With the sad, but obvious, drawback that the changes aren't linked in your disjoint shell and editor history.

¹ https://manpages.debian.org/jessie/moreutils/vipe.1.en.html

² Nowadays, that is more likely https://github.com/chrisbra/NrrwRgn for me.