Why I get 1 instead of nil for following function? Am I misunderstanding how text property searching works?

(defun set-properties()
  (add-text-properties 1 6 '(test "em"))
  (message (format "%s" (text-property-not-all 1 6 'test "em"))))

Yet, this function prints "em" as it should:

(defun get-single-property()
  (message (format "%s" (get-text-property 1 'test))))

I was using functions on plain text buffer with 6 letters.


That's because text-properties are compared with eq and

(eq "em" "em")

is nil because those two strings are different heap objects.

C-h f text-property-not-all says:

text-property-not-all is a built-in function in C source code.

(text-property-not-all START END PROPERTY VALUE &optional OBJECT)

Check text from START to END for property PROPERTY not equaling VALUE.

If so, return the position of the first character whose property PROPERTY is not eq to VALUE. Otherwise, return nil.

If the optional fifth argument OBJECT is a buffer (or nil, which means the current buffer), START and END are buffer positions (integers or markers). If OBJECT is a string, START and END are 0-based indices into it.

If you insist on using a string, you should either use something else than text-property-not-all, or make sure you really use the exact same string object. For example:

(defconst my-test-value "em")
(defun set-properties ()
  (add-text-properties 1 6 `(test ,my-test-value))
  (message (format "%s" (text-property-not-all 1 6 'test my-test-value))))
  • (text-property-not-all could be enhanced to accept an optional TEST arg. A more useful example might be a property value that is a cons or other non-symbol sexp - equal might be a reasonable TEST predicate for some such cases.)
    – Drew
    Nov 30 '18 at 20:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.