Skip to content

Instantly share code, notes, and snippets.

@Fuco1
Created July 26, 2014 19:44
Show Gist options
  • Save Fuco1/9cb28ee9288f7a350ab4 to your computer and use it in GitHub Desktop.
Save Fuco1/9cb28ee9288f7a350ab4 to your computer and use it in GitHub Desktop.
Text property api for emacs
All these operations are very natural for buffer objects as well as
strings, which leads me to the conclusion we should provide two
flavours for each function, for buffers and for strings. The way
emacs does it is by specifying an =object= argument. I find this
suboptimal, but it is also possible solution (and would reduce the
number of functions in half). /Note that there are also different
indexing conventions, see the Question below./
All functions come in buffer and string flavours. The "current
position" is called =point= in buffer versions and =offset= in string
versions. In fact, buffer implementation is the "default" one, the
wrapper for strings is added like so
#+BEGIN_SRC emacs-lisp
(with-temp-buffer
(insert string)
(goto-char (point-min))
(call-buffer-flavour-of-function))
#+END_SRC
Insertion into buffers is very fast so there is virtually no performance hit.
Question: should be number everything from 0, from 1, or should we
adhere to the "convention" in emacs (strings from 0, buffers from 1).
All range functions come with optional arguments =beg= and
=end=. Since we most of the time want to operate on the entire
string/buffer, these are put to the end to not bother us.
Naming conventions:
- The suffix -p indicates a predicate. Functions marked so should have no side effects.
- The suffix -at indicates the function takes a point, or defaults to position under cursor.
- The suffix -with or -where indicates that we take name of a property. We use two suffices to make the name more natural in english.
- The suffix -value indicates that we also take a value of the property and only operate on regions where property's value match this.
- The suffix -by indicates that we also take a predicate and only operate on regions where property's value satisfies this.
- [ ] s-property-at =prop= &optional =point=
- Return value of property =prop= at =point=.
- [ ] s-properties-at &optional =point= # text-properties-at
- Return a plist of properties at =point=.
- [ ] s-property-at-p =prop= &optional =point=
- Return non-nil if =prop= is set at =point=.
- [ ] s-properties-at-p =props= &optional =point=
- Return non-nil if any property from =props= is set at =point=.
- [ ] s-property-value-at-p
- [ ] s-properties-value-at-p
- [ ] s-property-by-at-p
- [ ] s-properties-by-at-p
- [ ] s-get-regions-with-property =prop= &optional =beg= =end= # message-text-with-property, gnus-find-text-property-region
- Return list of =(beg . end)= values describing regions where =prop= is set.
- [ ] s-get-regions-with-property-value
- [ ] s-get-regions-with-property-by
- [ ] s-alter-property =prop= =fn= &optional =beg= =end= # alter-text-property
- Replace text property =prop= with result of calling =fn= on this property.
=fn= takes two arguments: =prop= and its value.
- [ ] s-alter-property-value
- [ ] s-alter-property-by
- [ ] s-map-regions-with-property =prop= =fn= &optional =beg= =end= # this can be used to implement s-alter-property
- Replace all regions having =prop= with results of calling =fn= on these regions.
- [ ] s-map-regions-with-property-value
- [ ] s-map-regions-with-property-by
- [ ] s-add-property =prop= =value= &optional =beg= =end=
- Add =prop= with =value=.
- [ ] s-add-properties =props= &optional =beg= =end=
- Add =props=.
=props= is a plist of property/value pairs.
- [ ] s-add-property-at =prop= =value= &optional =point=
- Add =prop= with =value= at =point=.
- [ ] s-add-properties-at =props= &optional =point=
- Add =props= at =point=.
=props= is a plist of property/value pairs.
- [ ] s-add-property-where =prop= =new-prop= =val= &optional =beg= =end= # gnus-add-text-properties-when
- Add =new-prop= with =val= to all regions where =prop= is set.
- [ ] s-add-property-where-value
- [ ] s-add-property-where-by
- [ ] s-add-properties-where =prop= =props= &optional =beg= =end=
- Add =props= to all regions where =prop= is set.
=props= is a plist of property/value pairs.
- [ ] s-add-properties-where-value
- [ ] s-add-properties-where-by
- [ ] *do we also want -set- flavours here?*
- It is the same as doing -remove- and then corresponding -add-
- [ ] s-remove-property =old-prop= &optional =beg= =end=
- [ ] s-remove-property-where =prop= =old-prop= &optional =beg= =end= # gnus-remove-text-properties-when
- Remove =old-prop= from all regions where =prop= is set.
- [ ] s-remove-property-where-value
- [ ] s-remove-property-where-by
- [ ] s-remove-properties =props= &optional =beg= =end=
- Remove =props=.
- [ ] s-remove-properties-where =prop= =props= &optional =beg= =end=
- Remove =props= from all regions where =prop= is set.
- [ ] s-remove-properties-where-value
- [ ] s-remove-properties-where-by
- [ ] s-strip-properties &optional =beg= =end=
- Remove all properties.
- [ ] s-has-property =prop= &optional =beg= =end=
- Return the first position where =prop= is set or nil if it is never set.
- [ ] s-has-property-p =prop= &optional =beg= =end=
- Return non-nil if =prop= is set anywhere between =beg= and =end= or nil if it is never set.
- [ ] s-has-property-value
- [ ] s-has-property-value-p
- [ ] s-has-property-by
- [ ] s-has-property-by-p
- [ ] s-lacks-property =prop= &optional =beg= =end=
- Return the first position where =prop= is not set or nil if it is always set.
- [ ] s-lacks-property-p =prop= &optional =beg= =end=
- Return non-nil if =prop= is not set somewhere or nil if it is always set.
- [ ] s-lacks-property-value
- [ ] s-lacks-property-value-p
- [ ] s-lacks-property-by
- [ ] s-lacks-property-by-p
- [ ] s-find-property =prop= &optional =point= =limit=
- Return the first non-nil value of =prop= after =point= or nil if it is never set.
- [ ] s-find-property-backward =prop= &optional =point= =limit=
- Return the first non-nil value of =prop= before =point= or nil if it is never set.
- [ ] s-next-property-change &optional =point= =limit=
- Return the position of next property change or nil if none occurs.
- [ ] s-previous-property-change &optional =point= =limit=
- Return the position of previous property change or nil if none occurs.
- [ ] s-next-property-change-where =prop= &optional =point= =limit=
- [ ] s-previous-property-change-where
- [ ] s-next-property-change-where-value
- [ ] s-previous-property-change-where-value
- [ ] s-next-property-change-where-by
- [ ] s-previous-property-change-where-by
- [ ] s-equal-including-properties-p
- Return non-nil if two strings are equal, including properties.
More exotic properties we can implement later
- font-lock-fillin-text-property
- gnus-put-text-property-excluding-characters-with-faces ;; put property everywhere except on blocks with property (and value)
- font-lock-prepend-text-property ;; add more general 'map property'
- font-lock-append-text-property
- circe-highlight-extend-properties ;; this can also be implemented using a map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment