Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Branch: s-suffix-p
Fetching contributors…

Cannot retrieve contributors at this time

308 lines (211 sloc) 7.797 kB

s.el Build Status

The long lost Emacs string manipulation library.


It's available on marlamade:

M-x package-install s

Or you can just dump s.el in your load path somewhere.


Documentation and examples

s-trim (s)

Remove whitespace at the beginning and end of s.

(s-trim "trim ") ;; => "trim"
(s-trim " this") ;; => "this"
(s-trim " only  trims beg and end  ") ;; => "only  trims beg and end"

s-trim-left (s)

Remove whitespace at the beginning of s.

(s-trim-left "trim ") ;; => "trim "
(s-trim-left " this") ;; => "this"

s-trim-right (s)

Remove whitespace at the end of s.

(s-trim-right "trim ") ;; => "trim"
(s-trim-right " this") ;; => " this"

s-collapse-whitespace (s)

Convert all adjacent whitespace characters to a single space.

(s-collapse-whitespace "only   one space   please") ;; => "only one space please"
(s-collapse-whitespace "collapse \n all \t sorts of \r whitespace") ;; => "collapse all sorts of whitespace"

s-lines (s)

Splits s into a list of strings on newline characters.

(s-lines "abc\ndef\nghi") ;; => '("abc" "def" "ghi")

s-join (separator strings)

Join all the strings in strings with separator in between.

(s-join "+" '("abc" "def" "ghi")) ;; => "abc+def+ghi"
(s-join "\n" '("abc" "def" "ghi")) ;; => "abc\ndef\nghi"

s-repeat (num s)

Make a string of s repeated num times.

(s-repeat 10 " ") ;; => "          "
(concat (s-repeat 8 "Na") " Batman!") ;; => "NaNaNaNaNaNaNaNa Batman!"

s-truncate (len s)

If s is longer than len, cut it down and add ... at the end.

(s-truncate 6 "This is too long") ;; => "Thi..."
(s-truncate 16 "This is also too long") ;; => "This is also ..."
(s-truncate 16 "But this is not!") ;; => "But this is not!"

s-word-wrap (len s)

If s is longer than len, wrap the words with newlines.

(s-word-wrap 10 "This is too long") ;; => "This is\ntoo long"
(s-word-wrap 10 "This is way way too long") ;; => "This is\nway way\ntoo long"
(s-word-wrap 10 "It-wraps-words-but-does-not-break-them") ;; => "It-wraps-words-but-does-not-break-them"

s-left (len s)

Returns up to the len first chars of s.

(s-left 3 "lib/file.js") ;; => "lib"
(s-left 3 "li") ;; => "li"

s-right (len s)

Returns up to the len last chars of s.

(s-right 3 "lib/file.js") ;; => ".js"
(s-right 3 "li") ;; => "li"

s-chop-suffix (suffix s)

Remove suffix if it is at end of s.

(s-chop-suffix "-test.js" "penguin-test.js") ;; => "penguin"
(s-chop-suffix "\n" "no newlines\n") ;; => "no newlines"
(s-chop-suffix "\n" "some newlines\n\n") ;; => "some newlines\n"

s-chomp (s)

Remove trailing newline from s.

(s-chomp "no newlines\n") ;; => "no newlines"
(s-chomp "some newlines\n\n") ;; => "some newlines\n"

s-ends-with-p (suffix s)

Does s end in suffix?

(s-ends-with-p ".md" "") ;; => t
(s-ends-with-p ".md" "readme.txt") ;; => nil
(s-ends-with-p ".md" "md") ;; => nil

s-starts-with-p (prefix s)

Does s start with prefix?

(s-starts-with-p "lib/" "lib/file.js") ;; => t
(s-starts-with-p "test/" "lib/file.js") ;; => nil
(s-starts-with-p "lib/" "lib") ;; => nil

s-contains-p (needle s)

Does s contain needle?

(s-contains-p "file" "lib/file.js") ;; => t
(s-contains-p "nope" "lib/file.js") ;; => nil
(s-contains-p "^a" "it's not ^a regexp") ;; => t

s-replace (old new s)

Replaces old with new in s.

(s-replace "file" "nope" "lib/file.js") ;; => "lib/nope.js"
(s-replace "^a" "\\1" "it's not ^a regexp") ;; => "it's not \\1 regexp"

s-split-words (s)

Split s into list of words.

(s-split-words "under_score") ;; => '("under" "score")
(s-split-words "some-dashed-words") ;; => '("some" "dashed" "words")
(s-split-words "evenCamelCase") ;; => '("even" "Camel" "Case")

s-lower-camel-case (s)

Convert s to lowerCamelCase.

(s-lower-camel-case "some words") ;; => "someWords"
(s-lower-camel-case "dashed-words") ;; => "dashedWords"
(s-lower-camel-case "under_scored_words") ;; => "underScoredWords"

s-upper-camel-case (s)

Convert s to UpperCamelCase.

(s-upper-camel-case "some words") ;; => "SomeWords"
(s-upper-camel-case "dashed-words") ;; => "DashedWords"
(s-upper-camel-case "under_scored_words") ;; => "UnderScoredWords"

s-snake-case (s)

Convert s to snake_case.

(s-snake-case "some words") ;; => "some_words"
(s-snake-case "dashed-words") ;; => "dashed_words"
(s-snake-case "camelCasedWords") ;; => "camel_cased_words"

s-dashed-words (s)

Convert s to dashed-words.

(s-dashed-words "some words") ;; => "some-words"
(s-dashed-words "under_scored_words") ;; => "under-scored-words"
(s-dashed-words "camelCasedWords") ;; => "camel-cased-words"

s-capitalized-words (s)

Convert s to Capitalized Words.

(s-capitalized-words "some words") ;; => "Some Words"
(s-capitalized-words "under_scored_words") ;; => "Under Scored Words"
(s-capitalized-words "camelCasedWords") ;; => "Camel Cased Words"


Yes, please do. There's a suite of tests, so remember to add tests for your specific feature, or I might break it later.

You'll find the repo at:


Run the tests with


Create the docs with


I highly recommend that you install these as a pre-commit hook, so that the tests are always running and the docs are always in sync:

cp .git/hooks/pre-commit

Oh, and don't edit directly, it is auto-generated. Change or examples-to-docs.el instead.


Copyright (C) 2012 Magnar Sveen

Authors: Magnar Sveen Keywords: strings

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see

Jump to Line
Something went wrong with that request. Please try again.