smartparens insere caracteres únicos versus caracteres emparelhados?

8

P: como posso ajustar smartparensas regras de decisão de quando inserir um caractere emparelhado ou único?

smartparensparece ser mais inteligente ao inserir aspas simples (por exemplo, em text-modeou org-mode). Portanto, é padrão inserir um par de se 'colocar o cursor entre eles, mas, quando invocado no final de uma palavra, insere apenas um único ' em antecipação às contrações. Então, por exemplo:

  • '=> '*'(onde *está o ponto)
  • can + '=> can'*(para que eu possa continuar escrevendo "não pode")

No entanto, estou tentando resolver um problema. Costumo usar abreviações que terminam em um período, mas gostaria de torná-las possessivas. Por exemplo, eu poderia escrever "so" como uma abreviação de "alguém" e, portanto, "so's" seria "alguém". O problema é que smartparensinsere um par 'após um período:

  • o que eu quero: s.o. + '=>s.o.'*
  • o que eu recebo: s.o. + '=>s.o.'*'

Meu problema específico é com smartparenso comportamento ativado ', mas posso imaginar que esse seja um problema mais geral com outros personagens também.

Então: como posso ajustar smartparensa regra de decisão de expandir o conjunto de caracteres após o qual ele insere apenas um '?

PS: divertidamente, tentar digitar "` smartparens`'s "no emacs dá o mesmo comportamento irritante.

Dan
fonte

Respostas:

2

Sim, com condicionais de emparelhamento:

;; a sample from my .emacs.d
(defun my-sp-pair-function (id action context)
  (if (eq action 'insert)
    ;; t to pair, nil to not pair
    (or (looking-at "[[:space:][:punct:]]")
      (sp-point-before-eol-p id action context))
    t))

(with-eval-after-load 'smartparens
    (sp-pair "(" ")" :when '(my-sp-pair-function) :wrap "C-)")
    (sp-pair "{" "}" :when '(my-sp-pair-function) :wrap "C-}")
    (sp-pair "[" "]" :when '(my-sp-pair-function) :wrap "C-]")
    (sp-pair "\"" "\"" :when '(my-sp-pair-function) :wrap "C-\"")
    (sp-pair "'" "'" :when '(my-sp-pair-function)))
PythonNut
fonte
11
A parte inferior parece totalmente não relacionada. A parte superior parece que não fará nada por si só. Você poderia transformar sua resposta em algo funcional?
wasamasa
Isso é verdade ... falha de copiar e colar. Fixo.
precisa saber é o seguinte
Obrigado pelos pensamentos, mas my-sp-pair-functionnão parece estar fornecendo a funcionalidade desejada. Ele está me dando o mesmo comportamento de antes após a pontuação (inserção emparelhada), mas agora também faz uma inserção emparelhada após caracteres alfanuméricos, interrompendo as contrações.
Dan
@ Dan, isso era para ser uma solução geral. Você pode, por exemplo, substituir a condição por esta:(and (or (looking-at "[[:space:][:punct:]]") (sp-point-before-eol-p id action context)) (not (looking-back "[.`]")))
PythonNut 5/15/15
2

Você pode modificar o comportamento do smartparen usando as funções sp-paire sp-local-pair. O wiki do smartparens explica essas funções em detalhes.

Basicamente, você pode algo como seguir para personalizar o comportamento globalmente

(sp-pair "\"" nil :unless '(my-custom-predicate))

OU para personalizar o comportamento apenas para alguns modos

(sp-local-pair desired-modes "\"" nil :unless '(my-custom-predicate))

onde desired-modeé o modo para o qual você deseja personalizar o comportamento e a my-custom-predicatefunção que os smartparens devem usar para determinar se ele deve inserir o par automaticamente.

Na sp-pairdocumentação de, o predicado personalizado deve aceitar

delimitador de abertura (que determina exclusivamente o par), ação e contexto. O argumento de contexto pode ter valores:

  • string - se point estiver dentro da string.
  • comentário - se o ponto estiver dentro do comentário.
  • código - se o ponto está dentro do código. Esse contexto é reconhecido apenas nos modos de programação que definem a semântica de cadeias.

Portanto, uma função personalizada que pode ser usada como :unlesspredicado no seu caso específico seria algo como o seguinte

(defun predp (id action context)
  (sp--looking-back-p "[[:punct:]]'"))

Observe que estou verificando a regex, <punctuation>'pois o ponto seria .'|quando o predicado está em execução.

Por fim, você pode conectá-lo ao smartparens fazendo

(sp-pair  "'" nil :unless'(predp))
Iqbal Ansari
fonte
Obrigado, isso me faz parte do caminho, mas você poderia dar um exemplo concreto? Eu tentei várias formas da função de predicado (por exemplo, (defun predp () (sp--looking-back-p "[[:space:][:punct:]]"))), mas smartparensignora todas elas.
Dan
Oi @ Dan, eu adicionei a solução para o seu problema específico à resposta. Você não estavam aceitando os argumentos necessários no predicado, também o regex usado foi um pouco fora
Iqbal Ansari