2015-10-01 3 views
1

Итак, я пытаюсь добавить что-то в некоторые переходы режима elisp - в частности, я хотел бы определитьhook и затем активировать его по телефону prettify-symbols-mode.Использование локальных переменных elisp вместо глобальных переменных для добавления функции в режим-крючок

В любом случае, я получаю org-babel экспортировать значения в пару списков из таблицы, используя pairlis, чтобы связать их вместе, как ALIST и add-hook его в нужный режим, используя анонимную функцию.

Итак, вещь, прямо сейчас, если я использую глобальную переменную, как следующий, он работает:

(let ((token (quote ("not" "*" "/" "->" "map" "/=" "<=" ">=" "lambda"))) 
     (code (quote (172 215 247 8594 8614 8800 8804 8805 955)))) ; Generated automatically using org-babel 

    (require 'cl) 

    (setq *globalvar (pairlis token code)) 

    (add-hook 'emacs-lisp-mode-hook 
      (lambda() 
       (setq prettify-symbols-alist *globalvar) 
       (prettify-symbols-mode 1)))) 

Но если я стараюсь не использовать глобальную переменную, делая это таким образом, он не работает:

(let ((token (quote ("not" "*" "/" "->" "map" "/=" "<=" ">=" "lambda"))) 
     (code (quote (172 215 247 8594 8614 8800 8804 8805 955)))) ; Generated automatically using org-babel 
    (let (localv) 
    (require 'cl) 

    (setq localv (pairlis token code)) 

    (add-hook 'emacs-lisp-mode-hook 
       (lambda() 
       (setq prettify-symbols-alist localv) 
       (prettify-symbols-mode 1)))) 

Я вроде знаю почему: если I C-h v emacs-lisp-mode-hook, я вижу, что это относится к любой переменной я использовал в let форме, которая работает, когда переменная существует, как и в *globalvar , но не тогда, когда я использую localvar, w который больше не существует за пределами его формы let. Но я не уверен, как принудительно оценивать локальную переменную, поскольку я все еще борюсь с множеством концепций в elisp, которые мне не сразу понятны.

Что мне не хватает? Где я здесь не так?

+0

Установите 'lexical-binding' для non-'nil' или' localv' будет свободной переменной в вашей функции hook. Предпочтительно установить «лексическое связывание» в качестве локальной локальной переменной. – Drew

+0

tariqk: Вы хотите прочитать немного о динамической привязке к лексической привязке. Динамическое связывание является значением по умолчанию, и в этом случае ваша 'let'-bound' localv' variable * * привязана (безрезультатно), в то время как ваша форма лямбда * определена *, но больше не связана, когда эта функция выполняется в несколько позже. Вы ожидаете лексического закрытия, которое вы получите, только если вы включите лексическую привязку для библиотеки. – phils

+0

Кроме того, не цитируйте '' (lambda ...) 'like this. См. Http://emacs.stackexchange.com/q/3595/454 – phils

ответ

2

Начните с установки lexical-binding до nil, иначе localv будет свободной переменной в вашей функции крючка. Предпочтительно установить lexical-binding в качестве локальной локальной переменной.

Кроме того, в вашем коде не содержится ничего, что делает localvbuffer-local. Предположительно, вы хотите дать ему значение, которое является локальным для буфера, который находится в этом режиме. Код, который его связывает, должен оцениваться в режиме (то есть в буфере), о котором идет речь.

+0

Я не совсем понимаю, что вы понимаете, создавая локальный локатор, и почему, потому что из моего понимания как 'prettify-symbol-mode', так и' prettify-symbol-alist' уже являются буфером-локальным и ' localv' именно в этот момент местозаполнитель. – tariqk

+0

Под динамическим связыванием значение, видимое для 'localv', когда ваша лямбда-функция * исполняет *, будет значением * global * для этой переменной - если только это не буфер-локальный. – phils

+0

Ну, если я проверю 'prettify-symbol-mode' и' prettify-symbol-alist' на 'C-h v', он сообщает мне, что оба автоматически становятся буферами-локальными при установке. 'localv' нигде не встречается с' C-h v', когда используется 'lexical-let', поэтому я не знаю, действительно ли это актуально. – tariqk

1

Хорошо, вот что я сделал в конце:

(let ((token (quote ("not" "*" "/" "->" "map" "/=" "<=" ">=" "lambda"))) 
     (code (quote (172 215 247 8594 8614 8800 8804 8805 955)))) 
    (require 'cl) 

    (lexical-let (localv) 
    (setq localv (pairlis token code)) 
    (add-hook 'emacs-lisp-mode-hook 
       (lambda() 
        (setq prettify-symbols-alist localv) 
        (prettify-symbols-mode 1))))) 

Я закончил с использованием phils «предложением использовать lexical-let вместо Drew» s рекомендации в основном потому, что я в настоящее время с помощью org-babel запутать блоки кода в мой исходный код (в основном я использую org-mode для упорядочивания файлов настроек), и, похоже, не существует способа установить локальную переменную lexical-binding - согласно странице this, вам необходимо установить ее как первую строку (используя ;; -*- lexical-binding: t -*-), и я пока не могу найти способ сделать это.

В любом случае, спасибо всем, кто помог мне решить этот вопрос!

1

Мне нравится это решение. С lexical-let звонок в lambda (внутри add-hook) генерирует закрытие, как вы можете видеть, введите ли вы M-x ielm RET и emacs-lisp-mode-hook RET, чтобы изучить его значение.

Вы также можете использовать старую школу стиля, как это обратные одиночные кавычки:

(add-hook 'emacs-lisp-mode-hook 
      `(lambda() 
       (setq prettify-symbols-alist ',localv) 
       (prettify-symbols-mode 1))) 

(EDIT)

Обратите внимание на backtick до lambda и (как tarikq упоминалось) quote-comma перед тем localv.

Я думаю, что вы поняли смысл!

На самом деле вместо «развернуть это, а затем процитировать», я бы сказал «вставьте его значение (из лексической среды), а затем процитируйте его».

Если вы пытаетесь что-то вроде:

(macroexpand '`(lambda() 
        (setq prettify-symbols-alist ',localv) 
        (prettify-symbols-mode 1))) 

тогда вы получите то, что сюсюкать на самом деле будет делать во время выполнения:

(cons 'lambda 
     (cons nil 
      (cons 
      (list 'setq 'prettify-symbols-alist (list 'quote localv)) 
      '((prettify-symbols-mode 1))))) 

, и вы увидите, как весь список строится, и как localv является обычно оценен, то есть не котируется (сравните с символами 'setq и 'prettify-symbols-alist и список)

+0

Я действительно замечаю цитату, за которой следует запятая.Обратное выражение означает «цитируйте это, кроме всего, с запятой перед ним», а цитата-запятая означает «развернуть это, а затем процитировать», верно? – tariqk

 Смежные вопросы

  • Нет связанных вопросов^_^