(
Obrigado por nos contatar.
Se você estiver relatando um problema com o resultado da análise, preencha
o seguinte modelo. Como sua configuração CTags personalizada pode
afetar os resultados, use sempre --options=NONE
como o primeiro
opção ao executar ctags
.
Caso contrário, exclua o modelo e escreva seu problema do zero.
Os exemplos podem ajudar os desenvolvedores a entender melhor o seu problema.
Use a interface da web do GitHub e a notação de marcação.
Usar a renderização de texto quebrado dos resultados de e-mail que torna
os desenvolvedores enlouquecem.
)
O nome do analisador:
A linha de comando que você usou para executar ctags:
$ ctags -R
Não tenho nenhuma configuração especial em .ctags
ou em qualquer outro lugar. Esta é uma nova VM em que este teste foi executado.
O conteúdo do arquivo de entrada: https://github.com/pallets/jinja/blob/master/jinja2/_identifier.py
A saída das tags com a qual você não está satisfeito:
Universal-ctags
insere utf-8
caracteres inválidos em certas circunstâncias.
A saída de tags que você espera:
Saída de tag esperada com todos os caracteres valide utf-8
.
A versão das ctags:
$ ctags --version
Universal Ctags 0.0.0(3522685), Copyright (C) 2015 Universal Ctags Team
Universal Ctags is derived from Exuberant Ctags.
Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
Compiled: July 27 1018, 23:16:36
URL: https://ctags.io/
Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath
Como você obtém o binário ctags:
(
O binário ctags é construído em ubuntu-16.04
VM sem nenhuma modificação além da instalação de bibliotecas necessárias, como automate
, autoreconf
para compilar ctags
e bibliotecas necessárias para compilar vim
base em https://github.com/Valloric/YouCompleteMe/wiki/Building-Vim-from-source#a-for-a-debian-like-linux-distribution-like-ubuntu-type
)
@lilydjwg apontou para mim que ctags
estava inserindo utf-8
caracteres inválidos, embora o arquivo usado para gerar as tags tenha todos os caracteres utf-8
válidos aqui:
https://github.com/vim/vim/issues/3213#issuecomment -406961075
A versão compilada de ctags
funciona muito bem em geral.
Descobri recentemente que ctags
tem um bug devido ao qual o
Execuberant ctags
antigo instalado por sudo apt-get install ctags
no Ubuntu
16.04 não insere nenhum caractere utf-8
inválido, mas se eu compilar
Universal-ctags
da fonte e instale-o com base nas instruções aqui:
https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst , it
irá inserir utf-8
caracteres inválidos. Aqui está a evidência:
Com exuberant-ctags
instalado usando apenas sudo apt-get install ctags
:
Com Universal-ctags
compilado da fonte (último commit) a partir deste post,
compilado com instruções a partir daqui:
https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst :
Isso causa muitos problemas no vim, porque se utf-8
inválidos, os caracteres são
passado para vim.eval
, vim.eval
quebras e isso não leva a nenhuma tag retornada em
tudo. Atualmente, há apenas uma maneira de transferir dados contidos em um viml
variável para o espaço python-name
, usando vim.eval
. Então, qualquer outro plugin em
vim ou onde terá problemas semelhantes também. @ludovicchabant para
exemplo teve que pós-processar seu arquivo de tags para impedir tais problemas:
https://ludovic.chabant.com/devblog/2017/02/25/aaa-gamedev-with-vim/
Ele também teve que alterar ctrl-py-matcher
para detectar esse problema.
https://github.com/ludovicchabant/ctrlp-py-matcher/blob/2f6947480203b734b069e5d9f69ba440db6b4698/autoload/pymatcher.py#L22
Existem vários outros arquivos que eu vi que têm problemas semelhantes, mas eu
acabei de fornecer um aqui para diminuir o problema.
Meu palpite é que isso é um bug, e não espero que ctags
faça isso por
Projeto. Isso pode ser corrigido, já que costumava funcionar bem em Exuberant Ctags
em que o Universal-ctags é baseado?
Ref: https://github.com/vim/vim/issues/3213#issuecomment -408727629
Parece # 1275 para mim: a nova opção pattern-length-limit
está cortando em uma posição de byte arbitrária, que por acaso está no meio de uma sequência de caracteres. Consulte # 163, # 640 e # 1018.
Algo como https://github.com/universal-ctags/ctags/issues/1275#issuecomment -274489859 provavelmente deve ser implementado para corrigir isso.
@ alphaCTzo7G veja # 1807, isso corrige isso corretamente para você?
@ b4n , obrigado pela sua resposta rápida ...
No arquivo que postei aqui _identifier.py
, usando o commit # 1805, ctags
não insere mais caracteres / cortes inválidos em um local arbitrário.
Vou experimentar este PR no meu sistema real nos próximos dias para ver se funciona para todos os meus repositórios ou emite outros erros
Como ctrlp
e ctrlp-py-matcher
são plug-ins muito populares, seria ótimo se o # 1807 fosse mesclado para que vim
e outros usuários de editores de texto pudessem usar ctrlp
e ctrlp-py-matcher
sem ter que se preocupar com este problema.
Outro arquivo que encontrei estava causando problemas, com vim.eval
, e continha utf-8
caracteres inválidos, conforme determinado por grep -axv '.*' misc.html
( misc.html
em https: / /github.com/alphaCTzo7G/test). O que percebi é que ctags
inserirá os caracteres inválidos utf-8
no arquivo de tags de misc.html
.
Faz sentido ctags
detectar caracteres inválidos em arquivos e substituí-los por algo como @tonymec sugeriu aqui? (substitua a sequência inválida por uma ou mais instâncias do caractere (U + FFFD REPLACEMENT CHARACTER) que se destina exatamente a esse propósito.): https://github.com/vim/vim/issues/3213#issuecomment -405211243 ?
IIUC, ctags (ctags exuberantes, quero dizer, que é apenas um dos programas ctags disponíveis) é distribuído separadamente do Vim (mesmo que seu autor conheça Bram e mesmo que ocasionalmente trabalhem juntos para fazer o Vim e ctags funcionarem melhor juntos.
Do ponto de vista das ctags, é legítimo tratar o texto do programa apenas como strings de bytes: independentemente de ser UTF-8, Latin1, Latin9 ou algum outro conjunto de caracteres ISO 8859, um espaço é 0x20, uma guia rígida é 0x09, uma quebra de linha é 0x0A possivelmente precedida por 0x0D, etc .; e um byte nulo, que seria 0x00, não deve aparecer em um arquivo de texto. Ctags trata todos os programas da mesma maneira, independentemente da codificação compatível com ASCII em que está escrito e, portanto, não precisa se preocupar com qual é qual. Apenas para alguns conjuntos de caracteres estranhos como EBCDIC é necessário tratar o texto como definitivamente não ASCII (em EBCDIC, IIRC, AI são 0xC1-0xC9, JR são 0xD1-0xD9, SZ são 0xE2-0xE9, 0-9 são 0xF0-0xF9 , e não me lembro quais são os códigos para um espaço, uma tabulação, uma quebra de linha, um travessão, um sublinhado, etc.; mas você vê que do ponto de vista ASCII é realmente estranho).
IMHO, no caso da ctag, o bom e velho princípio se aplica: o lixo entra, o lixo sai.
Atenciosamente,
Tony.
@tonymec .. faz sentido .. Eu percebo que pode haver outros programas de geração de tag, mas universal-ctags
é o mais popular, e entre as pessoas que usam universal-ctags
meu palpite seria que uma grande parte são vim
usuários.
Então, eu me pergunto se esses 2 podem funcionar ou se você tem alguma outra idéia de como lidar com arquivos que possuem utf-8
caracteres ilegais?
ctags
tem esta opção de +iconv
, que permite o uso de libiconv
. Quando usado na linha de comando, iconv
pode remover utf8
caracteres ilegais. Então, eu me pergunto se eu passar --input-enconding=utf-8
e --output-encoding=utf-8
, então todos os caracteres utf-8 ilegais seriam alterados para caracteres utf-8
legais.Isso é explicado na seção 1.3.4 de https://media.readthedocs.org/pdf/ctags/latest/ctags.pdf :
Two new options have been introduced (--input-encoding=IN and --output-encoding=OUT).
Using the encoding specified with these options ctags converts input from IN to OUT. ctags uses the converted
strings when writing the pattern parts of each tag line. As a result the tags output is encoded in OUT encoding.
In addition OUT is specified at the top the tags file as the value for the TAG_FILE_ENCODING pseudo tag. The
default value of OUT is UTF-8.
NOTE: Converted input is NOT passed to language parsers. The parsers still deal with input as a byte sequence.
With --input-encoding-<LANG>=IN, you can specify a specific input encoding for LANG. It overrides the
global default value given with --input-encoding
utf8
caracteres ilegais. Nesse caso, vim.eval
deve ser consertado ou deve haver uma função vimL
que pode analisar e remover utf-8
caracteres ilegais antes de passá-los para vim.eval
..@ alphaCTzo7G Concordo com @tonymec e sua conclusão.
Infelizmente, é muito difícil reconhecer a codificação adequada - e insisto na adequada, porque é fácil encontrar uma codificação em que a entrada seja tecnicamente válida, digamos que a maioria, se não todas as codificações de 8 bits, seriam, mas sabendo se é a correta um é complicado ou impossível: digamos, como podemos ter certeza entre, por exemplo, ISO 8859-1 e 8859-15? As soluções incluem heurística complexa sobre frequência de uso e contexto; ou uma ideia mais ingênua aplicável a algumas linguagens como HTML seria extrair a instrução de codificação dentro do arquivo, mas isso também pode estar incorreto.
Além disso, ctags está em uma posição difícil aqui: muitos, senão a maioria, dos consumidores não lidam com codificações e as tags geradas precisam corresponder no nível de byte. Por exemplo, o grep para um padrão de tag ou mesmo nome não converterá as codificações para você, então a tag deve corresponder ao arquivo no nível de byte. Era fácil quando tudo que tínhamos para nos preocupar era o ASCII, mas não temos mais tanta sorte ... UTF-8 não foi adotado cedo o suficiente.
Isso também se aplica à ideia de substituir por caracteres de espaço reservado: o que o consumidor pode fazer com esse caractere de substituição? Deve pelo menos lidar com isso de uma maneira específica.
No entanto, se você estiver satisfeito em substituir UTF-8 inválido por U + FFFD ou removê-los, talvez você possa simplesmente pós-processar a saída de ctags?
@ b4n , agradeço seu comentário. Na verdade, eu lido principalmente com utf-8
arquivos codificados e tenho utf-8
codificados para os arquivos que eu crio. Infelizmente, como você mencionou, eu uso bibliotecas que tendem a ter codificações às vezes arbitrárias.
Eu uso vim-gutentags
e fornece uma funcionalidade de pós-processamento. Embora eu pudesse pós-processar manualmente o arquivo de tags para resultar em todos os arquivos em utf-8
caracteres, quando tentei usar a funcionalidade post-processing
em vim-gutentags
, não funcionou . Então eu pensei que seria melhor descobrir uma solução mais robusta .. mas se isso não existir, terei que olhar para ela novamente ..
Para detectar a codificação do arquivo, você não pode usar as bibliotecas subjacentes por trás de uma dessas opções: https://stackoverflow.com/questions/805418/how-to-find-encoding-of-a-file-in-unix -via-scripts
como enca
, file
, uchardet
, enguess
? Todas essas são utilidades de linha de comando .. mas deve haver alguma biblioteca em algum lugar que possa ser usada internamente por ctags
talvez. Meu palpite é que, devido ao número de codificações, como você mencionou, pode nunca ser possível prever perfeitamente a codificação, mas uma solução simples que cubra a maior parte dela pode ser melhor do que nada.
Vou experimentar o --input-encoding (and/or --input-encoding-<LANG>) and --output-encoding options
.. Não tenho certeza se vai funcionar o tempo todo, porque é muito possível que certos arquivos tenham codificações diferentes no mesmo repositório, a menos que ctags
descubra o corrija a codificação individualmente e divida-a no formato desejado.