Adicionando caixa ao redor do texto sem alterar a largura do texto

9

A documentação de Atributos de face sugere que adicionar um line-widthde -nao atributo box

desenhe uma linha de largura n cujas partes superior e inferior ocupem o espaço do texto subjacente, evitando assim qualquer aumento na altura do caractere.

Então, adicionei a seguinte linha ao meu arquivo de tema pessoal para candidatos a isearch ( lazy-highlight):

`(lazy-highlight ((,class (:box (:line-width -1 :color ,search) :background ,bg1 :foreground ,fg1))))

Isso funciona bem, considerando a altura, no entanto, a largura do texto muda conforme visto no gif abaixo:

insira a descrição da imagem aqui

Existe alguma maneira de fazer a esquerda e a parte direita da caixa também ocuparem o texto subjacente para que não haja alteração na largura do texto?

Pouya
fonte
As colunas permanecem alinhadas se você destacar tudo?
Melioratus 11/01/19
@ Melioratus, sim, a largura adicionada é uniforme e constante.
Pouya

Respostas:

3

Meu caso de uso para este SE é ter uma caixa em volta da regionface, para que a região destacada transient-mark-modeseja visível mesmo quando a região se sobrepuser a outras sobreposições:

(set-face-attribute 'region nil
                    :box '(:line-width -1
                           :color "gtk_selection_bg_color"
                           :style nil))

Por exemplo, com iedit-mode:

sobreposição de região em caixa sobreposta com sobreposição de iedit

Sempre que o texto é destacado com "região em caixa", posso ver a largura do texto descrita piscando.

O truque sujo que encontrei para eliminar essa tremulação é adicionar uma caixa com a cor de fundo à defaultface. Infelizmente, esse hack introduziria vários problemas em outros lugares, como uma lacuna adicional entre linhas ou renderização incorreta de widgets de botão (por exemplo, em buffers de personalização).

A solução definitiva é fornecida no seguinte relatório de bug (consulte o patch anexado no final do thread):

Cintilação de texto movendo o cursor com a caixa ao redor do texto ativada

Essa solução afeta os componentes internos do Emacs e requer a criação personalizada do Emacs após a aplicação do patch.

Vou tentar a solução posterior em breve. O problema, no entanto, é que o meu init.else tornaria incompatível com as compilações do Emacs e precisará usar alguma lógica adicional para descobrir se o patch acima é aplicado.

Felizmente, depois de alguns testes, esse patch seria aceito na fonte do Emacs ...

Acompanhamento 2019-01-21 :

Parece que o patch mencionado acima não é compatível com o código-fonte Emacs mais recente. Eu tive que fazer algumas alterações para fazê-lo funcionar com o ramo principal do gmac do Emacs atual. Em vez de criar outro patch, fiz um fork no github e criei uma ramificação do upstream com o patch da caixa de face:

face-box-patch

Construir o Emacs a partir desse ramo é o mesmo que o Emacs cria.

A seguir está o init.elcódigo que deve ser compatível com as versões Emacs com patch e vanilla:

(unwind-protect
    (condition-case ex
        (set-face-attribute
         'region nil
         :box '(:line-width (-1 . -1)
                            :color "gtk_selection_bg_color"
                            :style nil))
      ('error
       (set-face-attribute
        'region nil
        :box '(:line-width -1
                           :color "gtk_selection_bg_color"
                           :style nil)))))

É testado apenas no Linux com GTK +

Victor Rybynok
fonte
Boa descoberta! Parece que o patch foi há um ano, então não tenho esperanças de que seja aceito.
Amitp
Apliquei o patch e estou felizmente usando a largura da caixa negativa agora :-) Obrigado!
Amitp 18/01/19
@amitp Obrigado por confirmar que o patch de Alexandre funcionou para você! Qual versão do Emacs, SO e GUI você está usando?
Victor Rybynok
Estou usando a versão GUI da "Mac Port" . Emacs 26.1.91. Depois de aplicar o patch, tive que alterar um arquivo específico do Mac (macterm.c) para fazer as mesmas alterações que no restante do código. Eu acho que o patch faz muito mais do que eu realmente quero. Eu acho (mas não testei) que eu deveria poder mudar eabs (s->face->box_line_width)para max (s->face->box_line_width, 0)e nenhuma outra alteração.
Amitp
Depois de usá-lo por um dia, estou vendo pequenas falhas. Não sei se isso se deve ao patch ou às minhas alterações no macterm.c. De qualquer forma, acabei revertendo.
Amitp