The Stack Overflow podcast is back! Listen to an interview with our new CEO.

Hot answers tagged

33

The standard Emacs Lisp approach is regular expression matching: (string-match-p (regexp-quote needle) haystack)


24

A lot of things in Emacs operate on the current buffer. You need to change the current buffer and restore it when you're done. Use with-current-buffer for simple cases where you just need to do something in another buffer, and save-current-buffer for more complex cases where you need to navigate between several buffers. (defun buffer-string* (buffer) (...


16

Re-writing this answer gives another solution: (format-spec "%a %a %a %b %b %b" (format-spec-make ?a "a" ?b "b")) Edit: Another format-spec solution As Malabarba gives another solution in comments: (format-spec "%a %a %a %b %b %b" '((?a . "a") (?b . "b"))) Edit 2: Evaluation before substitution: Here are examples with evaluation before substitution: (...


15

You're looking for prin1-to-string. Also, set print-escape-newlines to a true value to get the "\n" behavior you specified. I.e.: (let ((print-escape-newlines t)) (prin1-to-string "foo\nbar")) => "\"foo\\nbar\""


15

[Your propertized string looks wrong - perhaps you copied it wrong. foo has only 3 characters, so it is impossible for it to be fontified on chars 0 to 4 (i.e., chars 0, 1, 2, and 3 - that's 4 chars). I use 3 instead of 4 in the example here.] (let* ((foo #("foo" 0 3 (fontified t face font-lock-function-name-face))) (start 0) (end (...


14

cl-search can do that (and also returns the index of the substring, if found): ELISP> (cl-search "f t" "df tj") 1 (#o1, #x1, ?\C-a) ELISP> (cl-search "ft" "df tj") nil


13

Magnar Sveen's string manipulation library s.el provides a variety of ways to do this. For example: (require 's) (s-format "${name} ${name} ${name}" 'aget '(("name" . "test"))) ;; ==> "test test test" Note that s-format can take any replacer function, but provides special handling for aget, elt, and gethash. So you could use a list of tokens and ...


12

Emacs 25 or newer You want C-M-u which runs the command backward-up-list. Move backward out of one level of parentheses. This command will also work on other parentheses-like expressions defined by the current language mode. If ESCAPE-STRINGS is non-nil (as it is interactively), move out of enclosing strings as well.


10

You may be misinterpreting what's going on. The insert function inserts its argument verbatim. The problem is that the string you've included in your program is not \documentclass but ␡ocumentclass where ␡ is ASCII character number 127 (which is unprintable). The string literal "\documentclass" represents the string ␡ocumentclass. Notice how two things ...


9

What's the idiomatic (or best) way to trim surrounding whitespace from a string? The built-in library subr-x.el has included the inline functions string-trim-left, string-trim-right, and string-trim since Emacs 24.4: (eval-when-compile (require 'subr-x)) (string-trim "\n\r\s\tfoo\n\r\s\t") ; => "foo" Since Emacs 26.1 these inline functions also accept ...


7

In Emacs Lisp, backslashes inside strings start escape sequences. For example, \n means a newline, and \a means a bell character. If a string contains an unknown escape sequence, an error is signalled. \A is an unknown escape sequence, and it seems like this leads to the rest of the init file not being loaded. You can either specify the path with forward ...


7

Depending on your application, concat might be of use: (concat "live long " nil "and prosper") ;; => "live long and prosper" This works because concat acts on sequences, and nil is an empty list.


7

Yes, you can use a literal string that does not include the newline, so that the newline shows only for your code. Use \ to escape the newline, so that it is not included in the string: (setq foo "hello \ world") C-h v foo "hello world" One place where this is often used is in a doc string, where the literal string uses \\<...> or \\[...] ...


7

There is the string manipulation library s.el where trimming whitespace and newlines at the beginning and the end of a string is implemented as function s-trim. I cite that function here with its dependencies: (defun s-trim-left (s) "Remove whitespace at the beginning of S." (declare (pure t) (side-effect-free t)) (save-match-data (if (string-...


6

Ordinary Emacs Lisp strings are multi-line-capable. You can simply put newlines in them. Glancing at cl-heredoc, it sounds like what you are looking for is "raw" strings. There was a proposal to add these to elisp a while back, but unfortunately it was rejected. (I hope rather than expect it could be resurrected.) Nor does elisp have the reader ...


6

This is not exactly the purpose it was invented for, but seems to be useful: (require 'json) (json-encode-string "a neat\nstring\" with tab\t and feed \f, also vertical tab \v") "\"a neat\\nstring\\\" with tab\\t and feed \\f, also vertical tab \\u000b\""


6

The easiest way is to use the Common Lisp compatibility layer: (require 'cl-seq) (cl-member "ap" '("foo" "apa" "bar") :test #'string-match) ==> ("apa" "bar") PS. This is not directly relevant to your question, but if you have a few minutes to kill, keep reading. ;-) Note that Emacs maintainers have traditionally eschewed CL (starting with the original ...


6

For occasional use, you can do with query-replace-regexp (C-M-%). Replace .\{32\} with \&^J. This means, replace all chunks of 32 characters, with the same thing followed by a newline. To type the newline into the replacemnt, use C-q C-j. If you want to apply this only to binary strings, use [01]\{32\} for matching. This will protect other text from ...


6

It is for the same reason that: (eql "foo" "foo") => nil Along with the other cl-lib sequence functions generally, set-difference (aka cl-set-difference) defaults to using eql for its equality test, and therefore in your example none of the members of the first set are present in the second set. You can tell it what to use for its equality test, ...


5

You need to double the backslash in a Lisp string: (replace-regexp-in-string ": \\w" #'upcase ": really") See the Elisp manual, node Syntax for Strings. And a char class has chars inside [], so put [:alpha:] inside []. (replace-regexp-in-string ": [[:alpha:]]" #'upcase ": really") See the Elisp manual, node Regexp Special.


5

The special form or is useful here. This macro returns the value of the first argument, unless it's nil in which case it returns the second. So, assuming the variable you want to check is foo, the following will do what you want: (format "%s.el" (or foo "")) In some ways it's better than a magic tag since it makes it clear what value should be returned if ...


5

Use (type-of EXPRESSION) to determine the type of an expression. In your case you are confusing the value being inserted into a buffer by a function with its return value. shell-command inserts the textual output of the command, but it returns the exit status of the command (which, of course, is an integer). The simplest solution to your problem is ...


4

A slightly less verbose version of the one suggested by kaushalmodi: (replace-regexp-in-string "..$" ":\\&" (format-time-string "%z"))


4

If you like to use elisp regexp, you can do the below. For example, it returns "-05:00" if (format-time-string "%z") returns "-0500". (replace-regexp-in-string "\\([-+][0-9]\\{2\\}\\)\\([0-9]\\{2\\}\\)" "\\1:\\2" (format-time-string "%z"))


4

I'm afraid Emacs is rubbish at string manipulation, which is pretty amazing since Emacs is a text editor. It may not be awesome, but personally feel this reads better than using with-temp-buffer. (let ((time (format-time-string "%z"))) (concat (substring time 0 3) ":" (substring time 3)))


4

Perhaps a shorter example, using cl library: (defun chop (string separator) (cl-loop with seplen = (length separator) with len = (length string) with start = 0 with next = seplen for end = (or (cl-search separator string :start2 next) len) for chunk = (substring string start end) collect ...


4

Here's some code for you. This is a slightly modified split-string. I've removed trim option for simplicity and added keep-sep option. The diff is basically 2 lines, so you could say that this code is idiomatic: (defun split-string (string &optional separators omit-nulls keep-sep) "Split STRING into substrings bounded by matches for SEPARATORS." (...


4

This might not be quite the answer you want, but use printenv -0 instead. This puts a NUL between each "line" of output, which in this case will be between each var=value pair: TMUX_PANE=%0^@test=foo bar baz ^@SHLVL=2 Parsing that will be much easier. Code: (split-string (shell-command-to-string "printenv -0") "\0" t)


4

The change is not in concat, but in yas-snippet-dirs. In earlier versions, yas-snippet-dirs could be either a single directory (a string) or a list of directories. The line (setq yas-snippet-dirs (concat user-emacs-directory "snippets")) is working, it's setting yas-snippet-dirs to the string "~/Dropbox/emacs/snippets". The error message byte-code: Wrong ...


4

The backslash character is special both in string literals (strings typed in Emacs Lisp, surrounded by double quotes) and in regular expressions as well as replacement specifications. Backslash followed by 1–3 octal digits stands for the character with this value, that's why you're seeing ^A (it's the character with the value 1). Since you want the ...


Only top voted, non community-wiki answers of a minimum length are eligible