O que é um argumento de prefixo bruto? (P maiúsculo em interativo)

9

E para que eles podem ser usados?

(interactive "p")leva um argumento numérico da universal argumentdireita? E o argumento universal é apenas um int de qualquer maneira, então o que o capital (interactive "P")faz?

24HrRevengeTherapist
fonte

Respostas:

11

É difícil acreditar que as pessoas tenham descrito isso aqui sem também fornecer links para as próprias descrições do Emacs sobre isso:

"Ask Emacs!":, C-h i Escolha um manuali prefix argument RET,.

Em poucas palavras, embora isso seja dito bem o suficiente por outras respostas aqui e seja descrito em detalhes no manual:

  • O prefixo "bruto" arg fornece valores Lisp de diferentes tipos e, em particular, distingue se o usuário realmente usou ou não um argumento de prefixo (de qualquer tipo).

    Com ele, um programa pode distinguir se o usuário utilizar um dos { -, M--, C--} ou um dos { M-- 1, C-- 1, C-u -1} (sendo que ambos têm o mesmo valor de prefixo numérico -1), e distinguir se s? Ele usou C-u C-uou um dos { M-16, C-16, C-u 16} (ambos com valor numérico 16) - entre muitas outras distinções.

    Porém, a distinção mais importante é nilvs não nil: muitos comandos agem de maneira diferente dependendo se o usuário usa um prefixo arg.

  • O prefixo "numérico" arg é realmente apenas o valor que a função prefix-numeric-valueretorna quando aplicado ao prefixo bruto arg. IOW, é melhor pensar em um mapeamento da interação real bruta do usuário para um número inteiro.

    Ele não pode dizer se o usuário realmente usou um argumento prefixo, porque o padrão de nenhum argumento prefixo mapeia para o número inteiro 1, assim como faz o uso de C-u 1, M-1ou C-1.

Desenhou
fonte
9

Quando o código interativo do prefixo bruto "P"é usado, o argumento é passado como está, enquanto "p"converte o argumento em um número.

Depois de avaliar o elisp abaixo, tente C-u M-x my/fn-with-num-arge depois C-u M-x my/fn-with-raw-argveja a diferença, porque C-upassa um argumento de lista (4).

(defun my/debug-fn (arg)
  (let ((msg))
    (if (numberp arg)
        (setq msg (format "Argument is number %s. " (pp arg)))
      (setq msg "Argument is not a number. "))
    (if (listp arg)
        (setq msg (concat msg (format "Arg is %s." (pp arg))))
      (setq msg (concat msg "Argument is not a list.")))
    (message msg)))

(defun my/fn-with-num-arg (arg)
  (interactive "p")
  (my/debug-fn arg))
;; Result of C-u M-x my/fn-with-num-arg :
;; Argument is number 4. Argument is not a list.

(defun my/fn-with-raw-arg (arg)
  (interactive "P")
  (my/debug-fn arg))
;; Result of C-u M-x my/fn-with-raw-arg :
;; Argument is not a number. Arg is (4)
;; .

Também os padrões de argumento para 1para o argumento numérico ( "p"), mas o padrão é nilou ()para o argumento matéria ( "P").

Meus poucos centavos: Às vezes, o fator decisivo para usar "p"ou "P"é se você deseja que o argumento padrão seja 1ou nil.

;; Result of M-x my/fn-with-num-arg :
;; Argument is number 1. Argument is not a list.

;; Result of M-x my/fn-with-raw-arg :
;; Argument is not a number. Arg is nil.
Kaushal Modi
fonte
Obrigado. Eu entendo que às vezes é melhor conseguir do nilque 1, mas nunca que ter um embrulho inté preferível a um desembrulhado int. (Não posso votar até eu conseguir 15 pontos, btw).
24HrRevengeTherapist
@ 24HrRevengeTherapist: acabei de votar em você, ultrapassando o limite mágico de 15 pontos. Faça uma votação antecipada nos itens que o ajudarão!
Dan
Não se trata de ints embrulhados ou não embrulhados. Não tem nada a ver com ints. E +1 para @kaushalmodi, por enfatizar que você pode dizer se o usuário usou um prefixo arg apenas usando o argumento bruto (verificando se o valor é nilou não).
Tirou
7

Apenas para adicionar um pouco mais de detalhe à resposta de @ kaushalmodi (e caso de teste útil):

O argumento bruto permite distinguir entre os argumentos fornecidos com universal-argumente digit-argument.

Com um prefixo numérico arg, não há como distinguir o argumento universal C-ude um prefixo arg de 4 (ie C-4). Com o argumento cru estes são diferentes: (4)vs 4.

O mesmo se aplica a negative-argument. Como argumento bruto, você pode distinguir entre C--e C-- 1: o primeiro fornecerá você -enquanto o segundo -1. Quando convertidos em um argumento numérico, ambos serão -1.

Portanto, o benefício de usar um argumento bruto é que ele fornece mais valores possíveis. Você pode escrever comandos que se comportam de maneira diferente, dependendo de como o argumento é especificado.

Como exemplo, dê uma olhada na sequência de documentos para yank. Este comando trata C-ue de maneira C-4diferente:

Com apenas Cu como argumento, coloque o ponto no início e marque no final. Com o argumento N, reinsira a enésima morte mais recente.

glucas
fonte