У меня есть специальная строка. Я хочу сделать его глубокую копию, чтобы добавить больше свойств, сохраняя при этом свойства в исходной строке. Как я могу это сделать (легко)?
пример
Оцените один за другим:
(setq test-str-1
#(";; This `is' a test"
0 3 (fontified nil face font-lock-comment-delimiter-face)
3 9 (fontified nil face font-lock-comment-face)
9 11 (fontified nil face (font-lock-constant-face font-lock-comment-face))
11 19 (fontified nil face font-lock-comment-face)))
(setq test-str-2 (concat test-str-1))
(add-face-text-property 0 (length test-str-2) 'foobar t test-str-2)
И результат:
test-str-2
;; =>
#(";; This `is' a test" 0 3 (fontified nil face (font-lock-comment-delimiter-face foobar))
3 9 (fontified nil face (font-lock-comment-face foobar))
9 11 (fontified nil face (font-lock-constant-face font-lock-comment-face foobar))
11 19 (fontified nil face (font-lock-comment-face foobar)))
test-str-1
;; =>
#(";; This `is' a test" 0 3 (face font-lock-comment-delimiter-face fontified nil)
3 9 (face font-lock-comment-face fontified nil)
9 11 (face (font-lock-constant-face font-lock-comment-face foobar) ; <= foobar is here
fontified nil)
11 19 (face font-lock-comment-face fontified nil))
add-face-text-property
. Он не должен деструктивно изменять список, поскольку он терпит неудачу, когда на этот список ссылаются другие.Ответы:
Вы можете использовать функцию
font-lock-append-text-property
для добавления свойства текста. Это не изменяет значение разрушительно.Например:
Здесь, в
test-str-1
, сохранил свое первоначальное значение.источник
Я обнаружил, что вы можете сделать это, перебирая свойства текста, копируя данные базовых свойств и перезаписывая существующие свойства новыми копиями.
В моих тестах это было примерно на 20% быстрее, чем ваше
read
решение. Я также написал версию, в которой не использовался временный буфер, и изменил свойства строки, которая была меньше кода, но была медленнее.Глядя на код C, он копирует списки свойств с помощью copy_sequence, который перестраивает структуру списка, но не копирует элементы по значению, поэтому свойства, такие как face в вашем примере, которые имеют значение списка, копируются по ссылке и изменяются. Ошибка или нет, я не знаю
источник
Вы можете использовать
(concat the-original-string)
.Например:
источник
concat
не работает.Нашел (не очень эффективный) обходной путь:
источник
#
персонаж.