Como obter uma lista de todas as funções fornecidas exclusivamente por um determinado modo principal


8

Esta pergunta foi inspirada em https://stackoverflow.com/q/605785/ . Por M-x describe-function <TAB>posso obter uma lista de todas as funções interativas ou não-atraentes disponíveis no estado atual do emacs. Se um modo específico é ativado (por exemplo, modo látex), obtemos uma lista mais longa, pois as funções disponíveis no modo látex também são listadas.

Minha pergunta é como obter uma lista de todas as funções disponíveis exclusivamente em um modo específico (por exemplo, modo látex)? Em outras palavras, excluindo todas as outras funções não fornecidas por esse modo. Como no link acima, fornecer uma breve descrição das funções também seria útil.


11
O smex tenta isso e fornece uma lista de comandos para o modo principal atual ao usar smex-major-mode-commands.
Wasamasa

@wasamasa obrigado por introduzir o smex. Para os comandos (funções interativas), isso parece funcionar. Permanecem as funções não interativas.
Name

11
Opa, esqueci meu ponto de vista. Estude suas fontes para ter algo para comparar com o código das outras respostas.
wasamasa

Respostas:


2

O que significa para um modo fornecer uma função? Você diz " uma lista de todas as funções disponíveis exclusivamente em um modo específico " e " excluindo todas as outras funções não fornecidas por esse modo ".

Parece que você está confundindo um modo com a biblioteca que o define . Uma biblioteca fornece / define funções. Um modo geralmente não faz isso.

Se você deseja obter uma lista de todas as funções definidas em uma determinada biblioteca , consulte a resposta de @ wvxvw, para começar. Você também pode tentar comparar o prefixo da biblioteca com os nomes das funções - que geralmente são pertinentes, mas não são definitivos.

Se, no entanto, você deseja obter uma lista de todas as funções que podem ser pertinentes a um determinado modo , por exemplo, funções que podem ser usadas apenas ou que são mais úteis quando esse modo está ativado, receio. você precisará examinar a biblioteca onde o modo está definido. E você pode até precisar examinar algumas outras bibliotecas.

Uma determinada biblioteca geralmente define mais do que apenas algumas coisas pertinentes a um determinado modo. E um determinado modo pode muito bem fazer uso de coisas definidas em diferentes bibliotecas e, em alguns casos, coisas que fazem sentido apenas para esse modo determinado ou para um conjunto de modos que o inclui.

Em suma, como atualmente colocado, sua pergunta não é muito clara. Você pode se ajudar a obter melhores respostas, esclarecendo-as.


Você está certo, a pergunta deve ser mais precisa. Por exemplo, para látex, quero dizer todas as funções definidas nos .elarquivos contidos na pasta site-lisp>auctex. Para o modo organizacional, quero dizer todas as funções definidas nos .elarquivos contidos na pasta site-lisp>org. Para muitos modos, a situação é mais direta, pois para eles existe apenas um .elarquivo. Espero que essas explicações tornem claro o motivo da minha pergunta agora.
Name

2

Talvez este código tenha algum efeito educacional:

(defun remove-all-extensions (file-name)
  (let ((go-on t) next)
    (while go-on
      (setq next (file-name-sans-extension file-name))
      (setq go-on (not (string= next file-name))
            file-name next))
    next))

(defun function-symbols-of (library)
  (let ((origin (remove-all-extensions
                 (find-library-name
                  (if (stringp library) library
                    (symbol-name library)))))
        (result))
    (mapatoms (lambda (sym)
                (when (and (symbol-function sym)
                           (symbol-file sym)
                           (string= (remove-all-extensions (symbol-file sym))
                                    origin))
                  (push sym result))))
    result))

O problema

Devido à natureza não determinística da análise e carregamento de código, vários problemas precisam ser abordados:

  1. Quando a função é definida em um arquivo? As funções podem ser definidas condicionalmente e prever se uma condição favorecerá a definição da função ou não é equivalente a resolver o problema de parada. Para ilustrar isso, suponha este código:

    (if (> (random 100) 50)
       (defun foo ())
       (defun bar ()))
    
  2. Geralmente, não é possível dizer se um formulário lisp definiu uma função antes (com êxito) de avaliar o formulário. Isso é, novamente, equivalente a interromper o problema e, portanto, não pode ser solucionado em geral.
  3. Existem alguns casos especiais comuns, como alias e aconselhamento, que (a) criam duplicatas, (b) podem induzi-lo a desviar o arquivo de origem que declarou a função.
  4. Grande fração de funções é declarada no código C (não necessariamente acessível), que não é realmente dividido em bibliotecas no mesmo sentido que o código Emacs Lisp.

Tudo isso dito, você provavelmente deseja buscar find-func.elinspiração, obter uma idéia geral do layout e os problemas relacionados à localização do código fonte das funções do Emacs Lisp.


Deixe-me relatar o seguinte: ao executar este código, recebo o erro Symbol's function definition is void: find-library-name. Também é um pequeno erro de digitação - símbolos.
Name

@Name hm ... mas essa função é muito antiga (acho que foi mencionada no código-fonte em 2002). Você poderia tentar (require 'find-func)antes de executar este código. Obrigado pelo erro de digitação encontrado. Eu vou corrigir isso.
Wdxvw

Obrigado, seria ótimo se o nome da biblioteca pudesse ser dado por expressões regulares.
Name

1

Acabei de adicionar essa funcionalidade ao lispy . O novo comando lispy-goto-elisp-commands,, está vinculado a oge.

O generic g( lispy-goto) fornece uma lista de todas as tags, destacando comandos com uma face diferente, enquanto lispy-goto-elisp-commandsapenas fornece as tags de comando.

Listagem de código

(defun lispy-goto-elisp-commands (&optional arg)
  "Jump to Elisp commands within current file.
When ARG is non-nil, force a reparse."
  (interactive "P")
  (deactivate-mark)
  (let ((lispy-force-reparse arg))
    (lispy--fetch-tags (list (buffer-file-name)))
    (let ((struct (gethash (buffer-file-name) lispy-db)))
      (lispy--select-candidate
       (mapcar #'lispy--format-tag-line
               (delq nil
                     (cl-mapcar
                      (lambda (tag pretty-tag)
                        (when (semantic-tag-get-attribute tag :user-visible-flag)
                          pretty-tag))
                      (lispy-dbfile-plain-tags struct)
                      (lispy-dbfile-tags struct))))
       #'lispy--action-jump))))

Isso é apenas para mostrar que a semântica do CEDET é usada para obter a lista de tags; (semantic-tag-get-attribute tag :user-visible-flag)é usado para determinar se a tag é um comando ou não.

Como usar

  1. Navegue para o arquivo que contém o código. Isso pode ser feito com f1 f. Em vez disso, gosto de usar a função aconselhar-descrever , pois pressionar C-.lá omite a necessidade de passar pelo *Help*buffer.

  2. Torne o ponto especial (mova-o antes de abrir o paren ou ativar a região) e pressione oge. Também é possível apenas usar M-x lispy-goto-elisp-commands.


Estou um pouco confuso, se eu gostaria de obter todas as funções fornecidas pelo modo látex, o que devo fazer usando seu código?
Nome

Abra tex-mode.el. Pressione "oge" para obter uma lista de 23 marcas de comando que este arquivo contém. A seleção de uma das tags navegará até lá.
abo-abo

A execução M-x lispy-goto-elisp-commandsno buffer tex-mode.eldá o errolispy--fetch-tags: Wrong type argument: stringp, ("c:/Program Files/GNU Emacs/share/emacs/24.5/lisp/textmodes/tex-mode.el")
Nome:

Não tenho experiência em executar o CEDET no Windows. O comando deve funcionar bem no GNU / Linux para 24.5.2 e 25.
abo-abo

Sua resposta fala de " comandos ", mas a pergunta do OP é sobre funções , não apenas comandos . Se você realmente quer dizer funções, pode querer corrigir o texto. Se você quer dizer apenas comandos, esta postagem ainda não responde à pergunta, nesse caso, você pode querer corrigi-la (por exemplo, altere o código ou o que for).
21415 Drew

1

O pacote smex possui código para listar todos os comandos de um pacote. Você pode adaptar esse código para obter todas as funções.


Oh sim, desculpe, eu perdi isso.
rumember
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.