# Melhorar o &kate;

## Introdução

Como em qualquer editor de texto avançado, o &kate; oferece uma grande diversidade de formas para ampliar a sua funcionalidade. Poderá criar programa simples para adicionar funcionalidades com o JavaScript, adicionar funcionalidades melhoradas ao componente de edição com os 'Plugins' do Componente de Edição, ou adicionar ainda mais funcionalidades ao editor propriamente dito com os 'plugins' da aplicação &kate;, feitos em C++ ou os 'plugins' do &pate;, feitos em Python. Finalmente, assim que tiver melhorado o &kate;, está à vontade para se juntar a nós e partilhar as suas melhorias com o mundo!

## Programar em JavaScript

Desde o &kappname; 3.4, no &kde; 4.4, o componente de edição do &kappname; é facilmente extensível, através da criação de programas. A linguagem de programação é o ECMAScript (vulgarmente conhecido como JavaScript). O &kappname; suporta dois tipos de programas: os de indentação e os de linha de comandos.

### Programas de Indentação

Programas de indentação - também conhecidos por indentadores - formatam automaticamente o código-fonte enquanto escreve o texto. Por exemplo, depois de carregar na tecla Return, o nível de indentação costuma aumentar.

As seguintes secções descrevem, passo-a-passo, como criar o esqueleto de um módulo de indentação simples. Como primeiro passo, crie um novo ficheiro `*.js`, chamado ⪚ `javascript.js` na pasta pessoal local `$KDEHOME/share/apps/katepart/script/indentation`.

#### O Cabeçalho do Programa de Indentação

O cabeçalho do ficheiro `javascript.js` está incorporado num comentário e tem o seguinte formato

    /* kate-script
     * name: JavaScript
     * author: Nome de Exemplo <nome.exemplo@um.endereco.org>
     * license: BSD
     * revision: 1
     * kate-version: 3.4
     * type: indentation
     * required-syntax-style: javascript
     * indent-languages: javascript
     * priority: 0
     * i18n-catalog: meu-catalogo
     *
     * Uma linha sem o símbolo ':' interrompe o processamento do cabeçalho. Isto é, poderá
     * adicionar mais algum texto aqui como, por exemplo, uma licença detalhada.
     */

Cada item será agora explicado em detalhe:

- `kate-script` [obrigatório]: Este texto tem de aparecer na primeira linha do ficheiro `*.js`, caso contrário o &kappname; irá ignorar o programa.

- `name` [obrigatório]: Este é o nome do modo de indentação que aparece no menu Ferramentas Indentação e na janela de configuração.

- `author` [opcional]: O nome e a informação de contacto do autor.

- `license` [opcional]: Forma curta da licença, como por exemplo BSD ou LGPLv3.

- `revision` [obrigatório]: A versão do programa. Este número deverá ser aumentado sempre que o programa for modificado.

- `kate-version` [obrigatório]: A versão mínima do &kappname; necessária.

- `required-syntax-style` [opcional]: Uma lista, separada por vírgulas, dos estilos de realce de sintaxe obrigatórios. Isto é importante para os módulos de indentação que se baseiam em alguma informação específica de realce no documento. Se for indicado um estilo de sintaxe obrigatório, o módulo só ficará disponível quando estiver o realce apropriado seleccionado. Isto evita algum comportamento indefinido causado pela utilização da indentação sem o esquema de realce esperado. Por exemplo, a indentação de Ruby tira partido disto nos ficheiros `ruby.js` e `ruby.xml`.

- `indent-languages` [opcional]: Uma lista, separada por vírgulas, de estilos de sintaxe que este módulo consegue indentar correctamente, ⪚: c++, java.

- `priority` [opcional]: Se existirem vários módulos de indentação adequados para um determinado ficheiro de realce, este campo decide qual deverá ser usado por omissão.

- `i18n-catalog` [opcional]: Catálogo de mensagens adicional (ficheiro `.po`) carregado para a tradução de indentações de terceiros.

O &kappname; lê todos os pares no formato `chave`:`valor` até que não consiga encontrar mais nenhum símbolo de ':'. Isto implica que o cabeçalho poderá conter texto arbitrário, como uma licença, tal como aparece no exemplo.

#### O Código-Fonte da Indentação

Tendo definido o cabeçalho, esta secção explica como é que funciona a programação de indentações em si. O esqueleto básico do código parece-se com o seguinte:

    require("range.js");
    caracteresActivacao = "{}/:;";
    function indent(linha, larguraIndentacao, carácter)
    {
        // invocado para cada linha nova (carácter == '\n') e todos os caracteres indicados na
        // variável global 'caracteresActivacao'. Ao invocar o FerramentasAlinhar
        // a variável 'carácter' está em branco, i.e. carácter == ''.
        //
        // ver também: API de Programação
        return -2;
    }

A função `indent()` tem três parâmetros:

- `linha`: a linha que tem de ser indentada

- `larguraIndentacao`: o número de espaços correspondentes a cada indentação

- `carácter`: ou um carácter de mudança de linha (`ch == '\n'`), algum dos caracteres de activação indicados em `caracteresActivacao` ou vazio, caso o utilizador tenha invocado a acção Ferramentas Alinhar.

O valor devolvido pela função `indent()` define como é que a linha será indentada. Se o valor devolvido for um número inteiro, é interpretado da seguinte forma:

- valor devolvido `-2`: não fazer nada

- valor devolvido `-1`: mantém a indentação (procura pela linha não-vazia anterior)

- valor devolvido `0`: números >= 0 definem a largura de indentação em espaços

Em alternativa, poderá ser devolvida uma lista com dois elementos:

- `return [ indentação, alinhamento ];`

Nesse caso, o primeiro elemento é a profundidade de indentação, tendo o mesmo significado que os valores especiais. Contudo, o segundo elemento é um valor absoluto que representa uma coluna para o alinhamento. Se este valor for maior que o valor de indentação, a diferença representa um número de espaços a adicionar após a indentação do primeiro parâmetro. Caso contrário, o segundo número será ignorado. A utilização de tabulações e espaços na indentação é normalmente referida como sendo um modo misto.

Considere o seguinte exemplo: Assuma que usa as tabulações para indentar, e que o tamanho da tabulação é de 4. Aqui, o <tab> representa uma tabulação e o '.' representa um espaço:

    1: <tab><tab>xpto("olá",
    2: <tab><tab>......."mundo");

Ao indentar a linha 2, a função `indent()` devolve [8, 15]. Em função disso, são introduzidas duas tabulações para indentar até à coluna 8, e são introduzidos 7 espaços para alinhar o segundo parâmetro com o primeiro, de modo a permanecer alinhado, caso o ficheiro seja visto com outro tamanho de tabulação.

Uma instalação predefinida do &kde; fornece o &kappname; com vários módulos de indentação. O código-fonte correspondente em JavaScript poderá ser encontrado em `$KDEDIR/share/apps/katepart/script/indentation`.

A criação de um módulo de indentação necessita que actualize os programas, de modo a ver se as alterações se comportam de forma adequada. Em vez de reiniciar a aplicação, basta ir para a linha de comandos e invocar o comando `reload-scripts`.

Se criar programas úteis, por favor considere a hipótese de contribuir com eles para o Projecto do &kappname;, contactando para tal a lista de correio.

### Programas da Linha de Comandos

Como é difícil satisfazer as necessidades de todos, o &kappname; suporta algumas ferramentas auxiliares para manipular rapidamente o texto, usando para tal a linha de comandos incorporada. Por exemplo, o comando `sort` está implementado como um programa. Esta secção explica como criar ficheiros `*.js` que melhoram o &kappname; com algumas funções auxiliares arbitrárias.

Os programas da linha de comandos estão localizados na mesma pasta que os programas de indentação. Como tal, como primeiro passo, crie um ficheiro `*.js` novo, chamado `utilitários.js` na pasta pessoal local, em `$KDEHOME/share/apps/katepart/script/commands`.

#### O Cabeçalho do Programa da Linha de Comandos

O cabeçalho de cada programa da linha de comandos está incorporado como um comentário e encontra-se no seguinte formato

    /* kate-script
     * author: Nome de Exemplo <nome.exemplo@um.endereco.org>
     * license: BSD
     * revision: 1
     * kate-version: 3.4
     * type: commands
     * functions: sort, format-paragraph
     * i18n-catalog: meu-catalogo
     *
     * Uma linha sem o símbolo ':' interrompe o processamento do cabeçalho. Isto é, poderá adicionar
     * algum texto opcional aqui como, por exemplo, uma licença detalhada.
     */

Cada um dos elementos será explicado em detalhe:

- `kate-script` [obrigatório]: Este texto tem de aparecer na primeira linha do ficheiro `*.js`, caso contrário o &kappname; irá ignorar o programa.

- `author` [opcional]: O nome e a informação de contacto do autor.

- `license` [opcional]: Forma curta da licença, como por exemplo BSD ou LGPLv3.

- `revision` [obrigatório]: A versão do programa. Este número deverá ser aumentado sempre que o programa for modificado.

- `kate-version` [obrigatório]: A versão mínima do &kappname; necessária.

- `functions` [obrigatório]: Uma lista, separada por vírgulas, dos comandos do programa.

- `i18n-catalog` [opcional]: Catálogo de mensagens adicional (ficheiro `.po`) carregado para a tradução dos programas de terceiros.

O &kappname; lê todos os pares no formato `chave`:`valor`, até que não consiga encontrar mais nenhum símbolo de dois-pontos. Isto implica que o cabeçalho possa conter algum texto arbitrário, como a licença que aparece no exemplo.O valor da chave 'functions' é uma lista, separada por vírgulas, de comandos para a linha de comandos. Isto significa que um único programa poderá conter um conjunto arbitrário de comandos. Cada uma das funções está disponível no &kappname; através da linha de comandos incorporada.

#### O Código-Fonte do Programa

Todas as funções indicadas no cabeçalho terão de estar implementadas no programa. Por exemplo, o ficheiro de programa do exemplo acima tem de implementar as duas funções `ordenar` e `formatar-paragrafo`. Todas as funções têm a seguinte sintaxe:

    // bibliotecas necessárias do Katepart, p.ex. o range.js se usar o Range
    require ("range.js");

    function <nome>(arg1, arg2, ...)
    {
        // ... implementação, ver também: API de Programação
    }

Os argumentos na linha de comandos são passados à função como `arg1`, `arg2`, etc. Para poder fornecer a documentação para cada comando, basta implementar a função '`help`' da seguinte forma:

    function help(comando)
    {
        if (comando == "ordenar") {
            return i18n("Ordena o texto seleccionado.");
        } else if (cmd == "...") {
            // ...
        }
    }

Se executar `help ordenar` na linha de comandos, irá invocar esta função 'help' com o argumento `comando` configurado com o comando indicado, &ie; `comando == "ordenar"`. O &kappname; irá então apresentar o texto devolvido como documentação para o utilizador. Certifique-se que traduz os textos.

##### Associar Combinações de Teclas

Para poder atribuir atalhos de teclado, o programa terá de fornecer uma chamada chamada `action` da seguinte forma:

    function action(comando)
    {
        var a = new Object();
        if (comando == "ordenar") {
            a.text = i18n("Ordenar o Texto Seleccionado");
            a.icon = "";
            a.category = "";
            a.interactive = false;
            a.shortcut = "";
        } else if (comando == "descerLinhas") {
            // repetir para a acção seguinte
        }
        return a;
    }

O parâmetro `comando` da função indica qual o comando para o qual se pede o atalho de teclado respectivo. Existem vários campos que terá de indicar no objecto de JavaScript devolvido:

- `a.text` [obrigatório]: O texto que aparece no menu Ferramentas > Programas. Certifique-se que usa o `i18n` para as traduções.

- `a.icon` [opcional]: O ícone aparece a seguir ao texto no menu. Todos os nomes de ícones do &kde; poderão ser aqui usados.

- `a.category` [opcional]: Se for indicada uma categoria, o programa aparece num submenu. Certifique-se que usa o `i18n` para as traduções.

- `a.interactive` [opcional]: Se o programa precisa de interacção por parte do utilizador, configure este valor como `true` (verdadeiro).

- `a.shortcut` [opcional]: A combinação de teclas indicada aqui é o atalho de teclado predefinido. Por exemplo: Ctrl+Alt+T. Veja a documentação do Qt para mais detalhes.

Criar um programa para a linha de comandos obriga a actualizar os programas, de modo a ver se as alterações funcionam apropriadamente. Em vez de reiniciar a aplicação, basta mudar para a linha de comandos e invocar o comando `reload-scripts`.

Se criar programas úteis, por favor considere a hipótese de contribuir com eles para o Projecto do &kappname;, contactando para tal a lista de correio.

### API de Programação

A API de programação aqui apresentada está disponível em todos os programas, &ie; os programas de indentação e os comandos da consola. O `Cursor` e o `Range` são fornecidos através de ficheiros de bibliotecas no `$KDEDIR/share/apps/katepart/libraries`. Se quiser usá-los no seu programa, o que será necessário para usar algumas das funções do `Document` ou do `View`, inclua por favor a biblioteca necessária, usando:

    // bibliotecas em JS do katepart necessárias, p.ex. o "range.js" se usar o Range
    require ("range.js");

Para extender a API-padrão de programação com funções e protótipos próprio, basta criar um ficheiro novo na pasta de configuração local do &kde;, em `$KDEHOME/share/apps/katepart/libraries` e inclua-a no seu programa, usando:

    require ("nome-do-meu-programa.js");

Para extender os protótipos existentes, como o `Cursor` ou o `Range`, a forma recomendada é não modificar os ficheiros `*.js` globais. Em vez disso, altere o protótipo do `Cursor` em JavaScript, após o `cursor.js` que é incluído no seu programa com o `require`.

#### Cursores e Intervalos

Como o &kappname; é um editor de texto, toda a API de programação é baseada em cursores e intervalos, sempre que possível. Um cursor é um simples tuplo `(linha, coluna)` que representa uma posição de texto no documento. Um Range (Intervalo) corresponde a uma área de texto coberta desde uma posição inicial do cursor até outra posição de fim. A API é explicada em detalhe nas secções seguintes.

##### O Protótipo do Cursor

    Cursor();

- Construtor. Devolve um Cursor na posição `(0, 0)`.

  Exemplo: `var cursor = new Cursor();`

    Cursor(int linha, int coluna);

- Construtor. Devolve um Cursor na posição (linha, coluna).

  Exemplo: `var cursor = new Cursor(3, 42);`

    Cursor(Cursor outro);

- Construtor de cópia. Devolve uma cópia do cursor `outro`.

  Exemplo: `var copia = new Cursor(outro);`

    Cursor Cursor.clone();

- Devolve uma cópia do cursor.

  Exemplo: `var clone = cursor.clone();`

    Cursor.setPosition(int linha, int coluna);

- Configura a posição do cursor em `linha` e `coluna`.

  Desde: &kde; 4.11

    bool Cursor.isValid();

- Verifica se o cursor é válido. O cursor é inválido no caso em que a linha e/ou coluna sejam iguais a `-1`.

  Exemplo: `var valido = cursor.isValid();`

    Cursor Cursor.invalid();

- Devolve um novo cursor inválido, localizado em `(-1, -1)`.

  Exemplo: `var cursorInvalido = cursor.invalid();`

    int Cursor.compareTo(Cursor outro);

- Compara este cursor com o cursor `outro`. Devolve

  - `-1`, se este cursor for localizado antes do cursor `outro`,

  - `0`, se ambos os cursores forem iguais e

  - `+1`, se este cursor se localizar a seguir ao cursor `outro`.

    bool Cursor.equals(Cursor outro);

- Devolve `true` (verdadeiro), se este o cursor e o `outro` forem iguais, caso contrário devolve `false` (falso).

    String Cursor.toString();

- Devolve o cursor como um texto no formato `Cursor(linha, coluna)`.

##### O Protótipo do Intervalo

    Range();

- Construtor. A invocação de `new Range()` devolve um intervalo Range de (0, 0) - (0, 0).

    Range(Cursor inicio, Cursor fim);

- Construtor. A invocação de `new Range(`início`, `fim`)` devolve o intervalo (`início`, `fim`).

    Range(int linhaInicial, int colunaInicial, int linhaFinal, int colunaFinal);

- Construtor. A invocação de `new Range(`linhaInicial`, `colunaInicial`, `linhaFinal`, `colunaFinal`)` devolve um intervalo Range de (`linhaInicial`, `colunaInicial`) até (`linhaFinal`, `colunaFinal`).

    Range(Range outro);

- Construtor de cópia. Devolve uma cópia do intervalo Range `outro`.

    Range Range.clone();

- Devolve uma cópia do intervalo.

  Exemplo: `var clone = intervalo.clone();`

    bool Range.isEmpty();

- Devolve `true` (verdadeiro), se tanto o cursor de início como o de fim forem iguais.

  Exemplo: `var vazio = intervalo.isEmpty();`

  Desde: &kde; 4.11

    bool Range.isValid();

- Devolve `true` (verdadeiro), se tanto o cursor de início como o de fim forem válidos, caso contrário devolve `false` (falso).

  Exemplo: `var valido = intervalo.isValid();`

    Range Range.invalid();

- Devolve o intervalo Range de (-1, -1) até (-1, -1).

    bool Range.contains(Cursor cursor);

- Devolve `true` (verdadeiro) se este intervalo contiver a posição do cursor, caso contrário devolve `false`.

    bool Range.contains(Range outro);

- Devolve `true` (verdadeiro), se este intervalo contiver o intervalo Range `outro`, caso contrário devolve `false` (falso).

    bool Range.containsColumn(int coluna);

- Devolve `true` (verdadeiro), se a `coluna` estiver no intervalo semi-aberto `[início.coluna, fim.coluna)`, caso contrário devolve `false` (falso).

    bool Range.containsLine(int linha);

- Devolve `true` (verdadeiro) se a `linha` estiver no intervalo semi-aberto `[início.linha, fim.linha)`, caso contrário devolve `false` (falso).

    bool Range.overlaps(Range outro);

- Devolve `true` (verdadeiro), se este intervalo e o intervalo `outro` partilharem uma região em comum, caso contrário devolve `false` (falso).

    bool Range.overlapsLine(int linha);

- Devolve `true` (verdadeiro), se a `linha` estiver no intervalo `[início.linha, fim.linha]`, caso contrário devolve `false` (falso).

    bool Range.overlapsColumn(int coluna);

- Devolve `true` (verdadeiro), se a `coluna` estiver no intervalo `[início.coluna, fim.coluna]`, caso contrário devolve `false` (falso).

    bool Range.onSingleLine();

- Devolve `true` (verdadeiro), se o intervalo começar e acabar na mesma linha, &ie; se `Range.start.line == Range.end.line`.

  Desde: &kde; 4.9

    bool Range.equals(Range outro);

- Devolve `true` (verdadeiro), se este intervalo e o intervalo `outro` forem iguais, caso contrário devolve `false` (falso).

    String Range.toString();

- Devolve o intervalo como um texto no formato `Range(Cursor(linha, coluna), Cursor(linha, coluna))`.

#### Funções Globais

Esta secção apresenta todas as funções globais.

##### Ler & Incluir os Ficheiros

    String read(String ficheiro);

- Irá procurar pelo `ficheiro` indicado em relação à pasta `katepart/script/files` e irá devolver o seu conteúdo como texto.

    void require(String ficheiro);

- Irá procurar pelo `ficheiro` indicado em relação à pasta `katepart/script/libraries` e este será avaliado. O `require` está protegido internamente contra inclusões múltiplas do mesmo `ficheiro`.

  Desde: &kde; 4.10

##### Depuração

    void debug(String texto);

- Imprime o `texto` no `stdout`, mais precisamente na consola que lança a aplicação.

##### Tradução

Para um suporte regional completo, existem diversas funções para traduzir os textos nos programas, nomeadamente o `i18n`, o `i18nc`, o `i18np` e o `i18ncp`. Estas funções comportam-se exactamente como as funções de tradução do &kde;.

As funções de tradução convertem os textos indicados ao sistema de traduções do &kde; para a língua usada na aplicação. Os textos nos programas que são desenvolvidos no âmbito do código oficial do &kappname; são automaticamente extraídos e preparados para traduções. Por outras palavras, como programador do &kappname;, não terá de se preocupar com a extracção e tradução das mensagens. Contudo, para programas de terceiros, desenvolvidos fora do &kde;, terá de extrair e traduzir você mesmo a as mensagens. Em conjunto com os seus programas, terá de distribuir também um catálogo de traduções que inclui todos os textos traduzidos. Para além disso, o cabeçalho do seu programa terá de indicar explicitamente o catálogo a carregar com a indicação do `i18n-catalog`.

    void i18n(String texto, arg1, ...);

- Traduz o `texto` na língua usada pela aplicação. Os argumentos `arg1`, ..., são opcionais e usados para substituir os itens `%1`, `%2`, etc.

    void i18nc(String contexto, String texto, arg1, ...);

- Traduz o `texto` na língua usada pela aplicação. Para ale´m disso, o texto do `contexto` fica visível aos tradutores para que possam dar uma tradução mais adequada. Os argumentos `arg1`, ..., são opcionais e são usados para substituir os itens de substituição `%1`, `%2`, etc.

    void i18np(String singular, String plural, int número, arg1, ...);

- Traduz tanto o texto `singular` como o `plural` para a língua usada pela aplicação, dependendo do `número` indicado. Os argumentos `arg1`, ..., são opcionais e usados para substituir os itens de substituição `%1`, `%2`, etc.

    void i18ncp(String contexto, String singular, String plural, int número, arg1, ...);

- Traduz tanto o texto `singular` como o `plural` para a língua usada pela aplicação, dependendo do `número` indicado. Adicionalmente, o texto do `contexto` é visível para as tradutores, para que possam fornecer uma tradução mais adequada. Os argumentos `arg1`, ..., são opcionais e são usados para substituir os itens `%1`, `%2`, etc.

#### A API do View

Sempre que um programa está a ser executado, existe uma variável global `view` que representa a área de edição activa no momento. Segue-se uma lista com todas as funções disponíveis para o View.

    Cursor view.cursorPosition()

- Devolve a posição actual do cursor na janela.

    void view.setCursorPosition(int linha, int coluna);
    void view.setCursorPosition(Cursor cursor);

- Altera a posição actual do cursor para uma (linha, coluna) qualquer ou para o cursor indicado.

    Cursor view.virtualCursorPosition();

- Devolve a posição virtual do cursor com cada tabulação a corresponder ao número indicado de espaços, dependente da largura de tabulação actual.

    void view.setVirtualCursorPosition(int linha, int coluna);
    void view.setVirtualCursorPosition(Cursor cursor);

- Altera a posição actual do cursor virtual para uma (linha, coluna) qualquer ou para o cursor indicado.

    String view.selectedText();

- Devolve o texto seleccionado. Se não estiver nenhum texto seleccionado, o texto devolvido vem vazio.

    bool view.hasSelection();

- Devolve `true` (verdadeiro) se a janela contiver algum texto seleccionado, caso contrário devolve `false`.

    Range view.selection();

- Devolve o intervalo de texto seleccionado. O intervalo devolvido é inválido, caso não esteja seleccionado nenhum texto.

    void view.setSelection(Range intervalo);

- Altera o texto seleccionado para o intervalo indicado.

    void view.removeSelectedText();

- Remove o texto seleccionado. Se a janela não tiver nenhuma selecção feita, isto não faz nada.

    void view.selectAll();

- Selecciona o texto por inteiro no documento.

    void view.clearSelection();

- Limpa a selecção de texto actual, sem remover o texto.

#### A API do Document

Sempre que está a executar um programa, existe uma variável global `document` que representa o documento activo no momento. Segue-se uma lista com todas as funções disponíveis para o Document.

    String document.fileName();

- Devolve o nome do ficheiro do documento, ou então um texto vazio para as janelas de texto ainda por gravar.

    String document.url();

- Devolve o URL completo do documento, ou então um texto vazio para as janelas de texto ainda por gravar.

    String document.mimeType();

- Devolve o tipo MIME do documento, ou então o tipo `application/octet-stream` se não for encontrado qualquer tipo MIME apropriado.

    String document.encoding();

- Devolve a codificação usada actualmente para gravar o ficheiro.

    String document.highlightingMode();

- Devolve o modo de realce global usado para todo o documento.

    String document.highlightingModeAt(Cursor posição);

- Devolve o modo de realce usado na posição do cursor indicada do documento.

    Array document.embeddedHighlightingModes();

- Devolve uma lista com os modos de realce incorporados neste documento.

    bool document.isModified();

- Devolve `true` (verdadeiro) se o documento tiver algumas alterações por gravar, caso contrário devolve `false`.

    String document.text();

- Devolve o conteúdo inteiro do documento numa única sequência de texto. As mudanças de linha estão marcadas com o carácter de mudança de linha `\n`.

    String document.text(int daLinha, int daColuna, int ateLinha, int ateColuna);
    String document.text(Cursor de, Cursor ate);
    String document.text(Range intervalo);

- Devolve o texto no intervalo indicado. Recomenda-se que use a versão baseada nos cursores e nos intervalos, de modo a ter uma melhor visibilidade do código-fonte.

    String document.line(int linha);

- Devolve a linha de texto indicada como uma sequência de texto. O texto devolvido fica em branco, caso a linha pedida esteja fora do intervalo.

    String document.wordAt(int linha, int coluna);
    String document.wordAt(Cursor cursor);

- Devolve a palavra na posição do cursor indicada.

    Range document.wordRangeAt(int linha, int coluna);
    Range document.wordRangeAt(Cursor cursor);

- Devolve o intervalo da palavra na posição indicada do cursor. O intervalo devolvido é inválido (ver com Range.isValid()), caso a posição do texto esteja após o fim de uma linha. Se não existir nenhuma palavra no cursor indicado, é devolvido um intervalo vazio.

  Desde: &kde; 4.9

    String document.charAt(int linha, int coluna);
    String document.charAt(Cursor cursor);

- Devolve o carácter na posição do cursor indicada.

    String document.firstChar(int linha);

- Devolve o primeiro carácter da `linha` indicada que não seja um espaço em branco. O primeiro carácter encontra-se na coluna 0. Se a linha estiver em branco ou só tiver espaços em branco, o texto devolvido vem vazio.

    String document.lastChar(int linha);

- Devolve o último carácter da `linha` indicada que não seja um espaço em branco. O primeiro carácter encontra-se na coluna 0. Se a linha estiver em branco ou só tiver espaços em branco, o texto devolvido vem vazio.

    bool document.isSpace(int linha, int coluna);
    bool document.isSpace(Cursor cursor);

- Devolve `true` (verdadeiro), se o carácter na posição indicada do cursor for um espaço em branco, caso contrário devolve `false` (falso).

    bool document.matchesAt(int linha, int coluna, String texto);
    bool document.matchesAt(Cursor cursor, String texto);

- Devolve `true` (verdadeiro) se o `texto` indicado corresponder à posição indicada do cursor, caso contrário devolve `false` (falso).

    bool document.startsWith(int linha, String texto, bool ignorarEspacos);

- Devolve `true` (verdadeiro) se a linha começar por `texto`, caso contrário devolve `false` (falso). O argumento `ignorarEspacos` controla se os espaços envolventes são ignorados ou não.

    bool document.endsWith(int linha, String texto, bool ignorarEspacos);

- Devolve `true` (verdadeiro), caso a linha termine em `texto`, caso contrário devolve `false` (falso). O argumento `ignorarEspacos` controla se os espaços envolventes são ignorados.

    bool document.setText(String texto);

- Altera o texto do documento por inteiro.

    bool document.clear();

- Limpa o texto no documento por inteiro.

    bool document.truncate(int linha, int coluna);
    bool document.truncate(Cursor cursor);

- Trunca a linha indicada, na coluna ou posição do cursor indicadas. Devolve `true` (verdadeiro) em caso de sucesso ou `false` (falso) se a linha não estiver dentro do intervalo do documento.

    bool document.insertText(int linha, int coluna, String texto);
    bool document.insertText(Cursor cursor, String texto);

- Insere o `texto` na posição do cursor indicada. Devolve `true`, em caso de sucesso, ou `false` (falso), se o documento estiver apenas para leitura.

    bool document.removeText(int daLinha, int dacoluna, int ateLinha, int ateColuna);
    bool document.removeText(Cursor de, Cursor ate);
    bool document.removeText(Range intervalo);

- Remove o texto no intervalo indicado. Devolve `true` (verdadeiro), em caso de sucesso, ou `false` (falso), se o documento estiver no modo apenas para leitura.

    bool document.insertLine(int linha, String texto);

- Insere o texto na linha indicada. Devolve `true` (verdadeiro), em caso de sucesso, ou `false` (falso), caso o documento esteja apenas para leitura ou se a linha não estiver no intervalo do documento.

    bool document.removeLine(int linha);

- Remove a linha de texto indicada. Devolve `true` (verdadeiro), em caso de sucesso, ou `false` (falso), caso o documento esteja no modo apenas para leitura ou se a linha não estiver no intervalo do documento.

    bool document.wrapLine(int linha, int coluna);
    bool document.wrapLine(Cursor cursor);

- Reparte a linha na posição indicada pelo cursor. Devolve `true` (verdadeiro) em caso de sucesso ou `false` (falso) se ⪚ a linha < 0.

  Desde: &kde; 4.9

    void document.joinLines(int linhaInicial, int linhaFinal);

- Junta as linhas de `linhaInicial` até `linhaFinal`. Duas linhas de texto sucessivas estão sempre separadas por um espaço em branco.

    int document.lines();

- Devolve o número de linhas do documento.

    int document.length();

- Devolve o número de caracteres do documento.

    int document.lineLength(int linha);

- Devolve o comprimento da `linha`.

    void document.editBegin();

- Inicia um grupo de edição para agrupar operações a desfazer/refazer. Certifique-se que invoca sempre o `editEnd()` tantas vezes como invoca o `editBegin()`. A invocação do `editBegin()` usa um contador de referências interno, &ie; esta chamada pode ser encadeada.

    void document.editEnd();

- Termina um grupo de edição. A última invocação do `editEnd()` (&ie;, a correspondente à primeira chamada do `editBegin()`) termina o passo de edição.

    int document.firstColumn(int linha);

- Devolve a primeira coluna não em branco para a `linha` indicada. Se só existirem espaços em branco na linha, o valor devolvido é `-1`.

    int document.lastColumn(int linha);

- Devolve a última coluna que não esteja em branco para a `linha` indicada. Se só existirem espaços em branco na linha, o valor devolvido é `-1`.

    int document.prevNonSpaceColumn(int linha, int coluna);
    int document.prevNonSpaceColumn(Cursor cursor);

- Devolve a coluna com caracteres não-brancos que começa na posição de cursor indicada e pesquisa para trás.

    int document.nextNonSpaceColumn(int linha, int coluna);
    int document.nextNonSpaceColumn(Cursor cursor);

- Devolve a coluna com caracteres não-brancos que começa na posição de cursor indicada e pesquisa para a frente.

    int document.prevNonEmptyLine(int linha);

- Devolve a primeira linha não-vazia que contém caracteres não-nulos, pesquisando depois para trás.

    int document.nextNonEmptyLine(int linha);

- Devolve a primeira linha não-vazia que contém caracteres não-nulos, pesquisando depois para a frente.

    bool document.isInWord(String carácter, int atributo);

- Devolve `true` (verdadeiro), caso o `carácter` e `atributo` indicados possam fazer parte de uma palavra, caso contrário devolve `false` (falso).

    bool document.canBreakAt(String carácter, int atributo);

- Devolve `true` (verdadeiro) se o `carácter` indicado com o `atributo` indicado for adequado para mudar de linha, caso contrário devolve `false`.

    bool document.canComment(int atributoInicial, int atributoFinal);

- Devolve `true` (falso), caso um intervalo que começa e termina com os atributos indicados possa ser comentado; caso contrário, devolve `false` (falso).

    String document.commentMarker(int atributo);

- Devolve o marcador de comentários, usado em linhas únicas, para um determinado `atributo`.

    String document.commentStart(int atributo);

- Devolve o marcador de início de comentários, usado em linhas múltiplas, para um determinado `atributo`.

    String document.commentEnd(int atributo);

- Devolve o marcador de fim de comentários, usado em linhas múltiplas, para um determinado `atributo`.

    int document.attribute(int linha, int coluna);
    int document.attribute(Cursor cursor);

- Devolve o atributo na posição do cursor indicada.

    bool document.isAttribute(int linha, int coluna, int atributo);
    bool document.isAttribute(Cursor cursor, int atributo);

- Devolve `true` (verdadeiro), se o atributo na posição do cursor indicada for igual a `atributo`, caso contrário devolve `false` (falso).

    String document.attributeName(int linha, int coluna);
    String document.attributeName(Cursor cursor);

- Devolve o nome do atributo como um texto legível. Isto é igual ao nome `itemData` dos ficheiros de realce de sintaxe.

    bool document.isAttributeName(int linha, int coluna, String nome);
    bool document.isAttributeName(Cursor cursor, String nome);

- Devolve `true` (verdadeiro), se o nome do atributo, numa dada posição do cursor, corresponder ao `nome` indicado, caso contrário devolve `false` (falso).

    String document.variable(String chave);

- Devolve o valor da variável do documento identificada pela `chave`. Se a variável do documento não existir, o valor devolvido é um texto em branco.

    String document.setVariable(String chave, String valor);

- Altera o valor da variável do documento identificada pela `chave`. Devolve o valor da variável alterada.

  Ver também: Variáveis de documento do Kate

  Desde: &kde; 4.8

    int document.firstVirtualColumn(int linha);

- Devolve a coluna virtual do primeiro carácter não-nulo na linha indicada, ou então `-1` se a linha estiver em branco ou só tiver caracteres de espaços em branco.

    int document.lastVirtualColumn(int linha);

- Devolve a coluna virtual do último carácter não-nulo na linha indicada, ou então `-1` se a linha estiver em branco ou só tiver caracteres de espaços em branco.

    int document.toVirtualColumn(int linha, int coluna);
    int document.toVirtualColumn(Cursor cursor);
    Cursor document.toVirtualCursor(Cursor cursor);

- Converte a posição do cursor real para uma posição virtual, devolvendo um objecto inteiro ou um Cursor.

    int document.fromVirtualColumn(int linha, int colunaVirtual);
    int document.fromVirtualColumn(Cursor cursorVirtual);
    Cursor document.fromVirtualCursor(Cursor cursorVirtual);

- Converte a posição virtual do cursor para uma posição do cursor real, devolvendo um objecto inteiro ou um Cursor.

    Cursor document.anchor(int linha, int coluna, Char carácter);
    Cursor document.anchor(Cursor cursor, Char carácter);

- Pesquisa para trás pelo carácter indicado, começando na posição do cursor indicada. Por exemplo, se for passado o '(', como carácter, esta função irá devolve a posição do '(' de abertura. Isto implica uma contagem das referências, &ie; os outros '(...)' são ignorados.

    Cursor document.rfind(int linha, int coluna, String texto, int atributo = -1);
    Cursor document.rfind(Cursor cursor, String texto, int atributo = -1);

- Pesquisa para trás pelo texto indicado, com o `atributo` apropriado. O argumento `atributo` é ignorado se for igual a `-1`. O cursor devolvido é inválido, caso o texto não tenha sido encontrado.

    int document.defStyleNum(int linha, int coluna);
    int document.defStyleNum(Cursor cursor);

- Devolve o estilo predefinido que é usado na posição do cursor indicada.

    bool document.isCode(int linha, int coluna);
    bool document.isCode(Cursor cursor);

- Devolve `true` (verdadeiro) se o atributo na posição do cursor indicada não for igual a todos os seguintes estilos: `dsComment`, `dsString`, `dsRegionMarker`, `dsChar`, `dsOthers`.

    bool document.isComment(int linha, int coluna);
    bool document.isComment(Cursor cursor);

- Devolve `true` se o atributo do carácter na posição do cursor for `dsComment`; caso contrário devolve `false`.

    bool document.isString(int linha, int coluna);
    bool document.isString(Cursor cursor);

- Devolve `true` (verdadeiro) se o atributo do carácter na posição do cursor for `dsString`, caso contrário devolve `false` (falso).

    bool document.isRegionMarker(int linha, int coluna);
    bool document.isRegionMarker(Cursor cursor);

- Devolve `true` (verdadeiro) se o atributo do carácter na posição do cursor for `dsRegionMarker`, caso contrário devolve `false` (falso).

    bool document.isChar(int linha, int coluna);
    bool document.isChar(Cursor cursor);

- Devolve `true` (verdadeiro) se o atributo do carácter na posição do cursor for `dsChar`, caso contrário devolve `false` (falso).

    bool document.isOthers(int linha, int coluna);
    bool document.isOthers(Cursor cursor);

- Devolve `true` (verdadeiro) se o atributo do carácter na posição do cursor for `dsOthers`, caso contrário devolve `false` (falso).

## Extensões do Componente de Edição

As Extensões do Componente de Edição ampliam o KatePart, o componente de Edição de Texto Avançada que é usado em muitas aplicações do &kde;, como o &kate;, o &kwrite;, o Kile e o KDevelop. A criação de um 'plugin' do componente de edição permitir-lhe-á ampliar a funcionalidade do editor em qualquer um destes programas.

Para começar, veja o Tutorial do 'Plugin' do KTextEditor na Base Técnica do &kde;. Para saber ainda mais, veja o Tutorial Avançado, também na Base Técnica.

Poderá encontrar a documentação completa da API na Referência de API's do &kde;.

## 'Plugins' da Aplicação &kate; (C++)

Os 'Plugins' da Aplicação Kate melhoram as funcionalidades do editor &kate; propriamente dito, de forma que imaginar, usando a mesma linguagem de programação em que o &kate; é feito - o C++.

Para começar, veja o tutorial de criação de um 'plugin' do &kate; na página Web do &kate;. Também existe um 'plugin' de exemplo Olá mundo! clássico, que vem incluído no código-fonte do &kate;.

## 'Plugins' em Python do &pate;

Os 'Plugins' do &pate; também lhe permitem aumentar a funcionalidade do &kate; de qualquer forma que desejar, usando a linguagem de programação Python.

Para começar, veja o guia de desenvolvimento de 'plugins' em Python na página Web do &kate;.

Também poderá aceder à referência da API no ecrã de Configuração do &pate;.