Double Commander

2.15. Scripts Lua

Conteúdo

1. Introdução
2. DLLs necessárias
3. Bibliotecas de funções do Double Commander
3.1. Biblioteca DC
3.1.1. Exemplo de uso de DC.ExecuteCommand
3.2. Biblioteca do Sistema
3.2.1. Detalhes dos valores de retorno de SysUtils.FileGetAttr
3.2.2. Exemplo de uso de SysUtils.FileGetAttr
3.2.3. Exemplo de uso de FindFirst, FindNext e FindClose
3.3. Biblioteca da Área de Transferência
3.3.1. Exemplo de uso da biblioteca da Área de Transferência
3.4. Biblioteca de Diálogos
3.4.1. Botões exibidos em Dialogs.MessageBox
3.4.2. Estilos de janela de Dialogs.MessageBox
3.4.3. Botão padrão ativo de Dialogs.MessageBox
3.4.4. Valores de retorno de Dialogs.MessageBox
3.4.5. Exemplo de uso de Dialogs.MessageBox
3.4.6. Exemplo de uso de Dialogs.InputQuery
3.5. Biblioteca UTF-8
3.6. Biblioteca de Caracteres
3.7. Biblioteca do Sistema Operacional
4. Índice

1. Introdução

Para informações detalhadas sobre a linguagem de programação de scripts Lua, visite o site da Lua.

O Double Commander pode executar scripts Lua através do comando cm_ExecuteScript.
Os parâmetros do script devem ser passados como estão, sem escape (sem aspas ou "\"), para isso precisamos usar a variável %"0: por exemplo, para o arquivo sob o cursor use %"0%p0 em vez de %p0, para o diretório atual use %"0%D em vez de %D. Caso contrário, se o Double Commander adicionar aspas automaticamente, elas serão passadas como parte do parâmetro e você terá que considerar isso.
Para obter uma lista de todos os arquivos selecionados, podemos usar variáveis (%LU, %FU ou %RU) ou comandos internos (cm_SaveSelectionToFile, cm_SaveFileDetailsToFile, cm_CopyFullNamesToClip ou cm_CopyFileDetailsToClip). Por exemplo, podemos usar %p: neste caso, o Double Commander passará os nomes de todos os arquivos selecionados em uma única linha, separados por espaços.

Também é possível escrever plugins de conteúdo usando scripts Lua; exemplos podem ser encontrados na pasta do programa (plugins/wdx/scripts). Existe uma página dedicada ao desenvolvimento de plugins no Wiki. Limitação: apenas os seguintes tipos de dados são suportados:

A lista acima contém os nomes nos arquivos de cabeçalho; nos scripts Lua devemos usar os valores numéricos especificados entre parênteses.


Sobre a codificação de texto

Todas as funções adicionais descritas abaixo aceitam argumentos de string codificados em UTF-8 e retornam strings nesta codificação (exceto a função LazUtf8.ConvertEncoding).

Algumas funções das bibliotecas padrão Lua foram substituídas por funções do Double Commander ou Free Pascal/Lazarus (ou novas funções foram escritas), o que fornece suporte a UTF-8.

Ao escrever plugins, também devemos usar UTF-8 para dados de texto (ft_multiplechoice, ft_string e ft_fulltext).

Ao salvar scripts, use a codificação UTF-8 sem BOM.


Notas de cautela

O uso de Lua para automação oferece grandes possibilidades, mas em alguns casos pode ser necessário prestar atenção a alguns detalhes. Vamos tentar reunir esses itens nesta subseção.

1. Se as opções Atualização automática e Carregar listas de arquivos em uma thread separada estiverem habilitadas, a função de atualização funcionará de forma assíncrona. Ao mesmo tempo, o script é executado na thread principal do Double Commander, portanto, em alguns casos, tudo isso pode afetar a execução do seu script. Por exemplo, às vezes a execução consecutiva de comandos de navegação pode não funcionar (por exemplo, diretórios grandes, discos lentos), neste caso tente desabilitar Carregar listas de arquivos em uma thread separada ou procure por soluções alternativas.

Se o seu script cria novos arquivos ou renomeia os existentes no painel atual, mas depois não termina e executa algumas ações adicionais (por exemplo, selecionar arquivos ou mover o cursor), em alguns casos essas ações não surtirão efeito: nem todos os arquivos podem já estar no painel e você precisa chamar o comando cm_Refresh primeiro. Sob as condições descritas, cm_Refresh também será executado de forma assíncrona e o Double Commander pode não ter tempo de atualizar completamente a lista de arquivos após as suas alterações.

A atualização automática e o carregamento de listas de arquivos em uma thread separada são funções convenientes do gerenciador de arquivos, então um método de trabalho estável foi encontrado através de experimentação, ou seja, retornar temporariamente o controle ao programa e permitir que a lista de arquivos seja completamente atualizada:

DC.ExecuteCommand("cm_Refresh")
i = 10
while i > 0 do
  SysUtils.Sleep(10)
  DC.ExecuteCommand("")
  i = i - 1
end

2. A função Lua io.open usa a função C padrão fopen: no modo de texto, esta função pode converter tipos de final de linha (CRLF, LF ou CR) ao ler e escrever, o que pode levar a resultados inesperados. Se você encontrar arquivos com diferentes tipos de finais de linha ou estiver escrevendo scripts multiplataforma, deve considerar isso ou, o que é mais prático, preferir o uso do modo binário.

3. No Linux e outros sistemas operacionais tipo Unix, para o diálogo de Propriedades do arquivo, a função ContentGetValue é chamada com a flag CONTENT_DELAYIFSLOW (o quarto parâmetro, valor igual a 1), o que evita atrasos ao abrir janelas: se a recuperação de dados for lenta, podemos excluir esses dados simplesmente adicionando uma verificação do valor da flag e retornando nil para esses campos ou plugins.

4. Se o plugin deve retornar uma string vazia, passar nil é mais rápido do que passar "".

2. DLLs necessárias

Para poder interpretar arquivos de script Lua, precisamos de um arquivo DLL Lua, o Double Commander suporta as versões 5.1 - 5.4.

Podemos usar arquivos DLL do projeto LuaJIT. O LuaJIT combina um interpretador de alta velocidade escrito em assembler com um compilador JIT avançado. Além disso, obtemos a biblioteca FFI, que permite chamar funções C externas e usar estruturas de dados C a partir de código Lua puro.

As versões Windows do DC incluem a DLL Lua por padrão (a partir do DC 0.9.7 do projeto LuaJIT), em outros casos podemos encontrá-la e instalá-la via gerenciador de pacotes ou compilá-la nós mesmos. Se estivermos usando a versão de 64 bits do DC, a DLL também deve ser de 64 bits.

Por padrão, o DC procurará nos seus diretórios e diretórios do sistema por arquivos chamados lua5.1.dll (Windows), liblua5.1.so.0 (Unix ou GNU/Linux) ou liblua5.1.dylib (macOS). Podemos alterar o nome do arquivo (e o caminho) no parâmetro Arquivo de biblioteca Lua a ser usado.

3. Bibliotecas de funções do Double Commander

O Double Commander fornece algumas bibliotecas de funções para nossos scripts Lua.

Abaixo está a lista dessas bibliotecas.

Lista de bibliotecas
Nome da bibliotecaNome no scriptBreve descrição
DCFunções específicas do Double Commander
SysUtilsVárias funções do sistema
ClipbrdFornece funcionalidade de área de transferência externa
DialogsInteração com o usuário
LazUtf8Funções de string UTF-8
CharObter informações de caracteres
osFunções relacionadas ao sistema operacional

3.1. Biblioteca DC

Esta biblioteca contém funções específicas do Double Commander.

Ela fornece todas as funções na tabela DC.

Biblioteca DC
Nome da funçãoDescrição

DC.LogWrite(sMessage, iMsgType, bForce, bLogFile)

Escreve uma mensagem na janela de log:

  • sMessage : texto da mensagem.
  • iMsgType : tipo da mensagem: 0 - informação, 1 - sucesso, 2 - erro.
  • bForce : booleano, se verdadeiro, a janela de log será exibida se não estiver visível.
  • bLogFile : booleano, se verdadeiro, a mensagem também será gravada no arquivo de log.

iPanel = DC.CurrentPanel()

Obtém o painel ativo: retorna 0 se o painel esquerdo estiver ativo, 1 caso contrário.

DC.CurrentPanel(iPanel)

Define o painel ativo: o painel esquerdo quando iPanel é igual a 0, o painel direito quando igual a 1.

DC.ExecuteCommand(sCommand, Param1, Param2,...,ParamX)

Isso permite que o script chame os comandos internos do Double Commander.

sCommand é o nome real do comando interno.

Podemos fornecer qualquer número de argumentos Param... suportados pelo comando.

Além dos comandos internos, nos scripts também podemos usar o comando especial cm_ExecuteToolBarItem, que permite chamar um botão da barra de ferramentas através de um identificador (no programa, este recurso fornece a funcionalidade de usar atalhos para botões da barra de ferramentas). O comando é usado de forma semelhante a um comando interno normal (veja exemplo abaixo) e possui os seguintes parâmetros:

Parâmetro Valor Descrição
ToolBarID TfrmOptionsToolbar Botões da barra de ferramentas principal
TfrmOptionsToolbarMiddle Botões da barra de ferramentas do meio
(não existente) Botões da barra de ferramentas principal
ToolItemID identificador Identificador único do botão

O identificador único é armazenado na tag ID, temos várias formas de obtê-lo: o botão pode ser encontrado no arquivo doublecmd.xml, no arquivo de backup da barra de ferramentas ou simplesmente copiar o botão para a área de transferência e colar seu código em um editor de texto.

Nota: Identificadores são gerados automaticamente e não precisam corresponder a identificadores de botões semelhantes em outra cópia do programa, mas podemos definir nossos próprios valores manualmente, se necessário.

3.1.1. Exemplo de uso de DC.ExecuteCommand

Neste exemplo, escrevemos um script simples que fará o seguinte:

  1. Focar no painel direito
  2. Fechar todas as abas abertas
  3. Mudar para uma pasta específica
  4. Focar no painel esquerdo
  5. Fechar todas as abas abertas
  6. Mudar para uma pasta específica
  7. Abrir uma nova aba
  8. Mudar para uma pasta específica
-- 1. Focar no painel direito.
DC.ExecuteCommand("cm_FocusSwap", "side=right")

-- 2. Fechar todas as abas.
DC.ExecuteCommand("cm_CloseAllTabs")

-- 3. Mudar para um diretório específico.
DC.ExecuteCommand("cm_ChangeDir", "E:\\FakeKey\\Documents\\Music")

-- 4. Focar no painel esquerdo.
DC.ExecuteCommand("cm_FocusSwap", "side=left")

-- 5. Fechar todas as abas.
DC.ExecuteCommand("cm_CloseAllTabs")

-- 6. Mudar para um diretório específico.
DC.ExecuteCommand("cm_ChangeDir", "C:\\Users\\Public\\Music")

-- 7. Abrir uma nova aba.
DC.ExecuteCommand("cm_NewTab")

-- 8. Mudar para um diretório específico.
DC.ExecuteCommand("cm_ChangeDir", "E:\\VirtualMachines\\ShareFolder")

Usando o comando interno cm_ExecuteScript, podemos configurar um botão na barra de ferramentas para executar nosso script.

Supondo que este arquivo de script seja E:\scripts\lua\music.lua, poderíamos configurar o botão desta forma:

Chamando script Lua da barra de ferramentas

Além disso, também podemos usar o editor interno do Double Commander para editar scripts. Se o nome do arquivo tiver a extensão .lua, o editor interno o reconhecerá e fornecerá realce de sintaxe para a linguagem Lua:

Realce de sintaxe Lua usando o editor interno

3.2. Biblioteca do Sistema

Esta biblioteca contém várias funções do sistema.

Ela fornece todas as funções na tabela SysUtils.

Biblioteca do Sistema
Nome da funçãoDescrição

SysUtils.Sleep(iMilliseconds)

Pausa a execução do script pelo número especificado de milissegundos iMilliseconds.
Após o tempo especificado, a execução do script continuará.

SysUtils.GetTickCount()

Retorna uma contagem crescente de ticks do relógio. Pode ser usada para medição de tempo, mas não se deve assumir o intervalo entre os ticks.

bExists = SysUtils.FileExists(sFileName)

Verifica a existência de um arquivo específico no sistema de arquivos.

Se um arquivo com o nome sFileName existir no disco, retorna o valor true em bExists, caso contrário retorna false.

bExists = SysUtils.DirectoryExists(sDirectory)

Verifica se sDirectory existe no sistema de arquivos e se é realmente um diretório.

Se for o caso, a função retornará o valor true em bExists, caso contrário retornará false.

iAttr = SysUtils.FileGetAttr(sFileName)

Retorna as configurações de atributos do arquivo sFileName em iAttr.

Consulte aqui para uma explicação detalhada do valor de retorno.

Handle, FindData = SysUtils.FindFirst(sPath)

Encontra arquivos que correspondem ao sPath, geralmente usando curingas.

Se nenhum arquivo for encontrado, Handle será nil.

Quando pelo menos um item é encontrado, o Handle retornado pode ser usado para chamadas subsequentes a SysUtils.FindNext para encontrar outros correspondentes ao mesmo padrão.

A tabela FindData contém informações sobre o arquivo ou diretório encontrado.

Os campos da tabela FindData são os seguintes:

  • Name : Nome do arquivo (não incluindo o caminho).
  • Attr : Atributos do arquivo (veja aqui para detalhes).
  • Size : Tamanho do arquivo em bytes.
  • Time : Carimbo de data/hora do arquivo (segundos desde 1º de janeiro de 1970).

Result, FindData = SysUtils.FindNext(Handle)

Encontra a próxima ocorrência da sequência de busca iniciada por FindFirst, reutilizando o Handle retornado anteriormente.

Se um arquivo ou diretório for encontrado, o Result retornado não será nulo, caso contrário será nil.

As mesmas notas de SysUtils.FindFirst aplicam-se aqui.

Observação: A última chamada a SysUtils.FindNext deve ser sempre seguida por uma chamada a SysUtils.FindClose usando o mesmo Handle. Caso contrário, ocorrerá vazamento de memória.

SysUtils.FindClose(Handle)

Encerra uma série de chamadas SysUtils.FindFirst/SysUtils.FindNext.

Libera qualquer memória usada por essas chamadas.

É imperativo fazer esta chamada, caso contrário pode ocorrer vazamento de memória.

bResult = SysUtils.CreateDirectory(sDirectory)

Cria uma sequência de diretórios, onde sDirectory é o caminho completo para o diretório.

Retorna true se sDirectory já existia ou foi criado com sucesso. Retorna false se a criação de qualquer parte falhar.

bResult = SysUtils.CreateHardLink(sFileName, sLinkName)

Cria um hard link sLinkName para o arquivo sFileName.

Retorna true se for bem-sucedido, false caso contrário.

bResult = SysUtils.CreateSymbolicLink(sFileName, sLinkName)

Cria um link simbólico sLinkName para o arquivo ou diretório sFileName.

Retorna true se for bem-sucedido, false caso contrário.

sTarget = SysUtils.ReadSymbolicLink(sLinkName, bRecursive)

Lê o destino do link simbólico sLinkName.

Se bRecursive for true e o link apontar para outro link, ele o resolverá recursivamente até que um nome de arquivo válido que não seja um link seja encontrado.

Retorna o caminho apontado pelo link simbólico sLinkName, ou uma string vazia no caso de um link inválido ou se o arquivo apontado não existir e bRecursive for true.

sName = SysUtils.ExtractFileName(sFileName)

Extrai a parte do nome do arquivo de um nome de arquivo com caminho completo.

O nome do arquivo consiste em todos os caracteres após o último caractere separador de diretório ("/" ou "\") ou letra de unidade.

sExt = SysUtils.ExtractFileExt(sFileName)

Retorna a extensão do nome do arquivo (todos os caracteres após o último "." (ponto), incluindo o caractere ".").

sPath = SysUtils.ExtractFilePath(sFileName)

Extrai o caminho (incluindo a letra da unidade) do nome do arquivo.

O caminho consiste em todos os caracteres antes do último caractere separador de diretório ("/" ou "\"), incluindo o próprio separador de diretório.

sDir = SysUtils.ExtractFileDir(sFileName)

Extrai apenas a parte do diretório de sFileName, incluindo a letra da unidade.

O nome do diretório não possui um separador de diretório final, diferentemente de SysUtils.ExtractFilePath.

sDrive = SysUtils.ExtractFileDrive(sFileName)

Extrai a parte da unidade do nome do arquivo.

Note que alguns sistemas operacionais não suportam letras de unidade.

sName = SysUtils.GetAbsolutePath(sFileName, sBaseDirectory)

Retorna o caminho absoluto (completo) para um arquivo:

  • sFileName : nome do arquivo com caminho relativo.
  • sBaseDirectory : diretório usado como diretório base para sFileName.

Se o caminho absoluto não puder ser obtido, a função retornará o valor de sFileName.

sName = SysUtils.GetRelativePath(sFileName, sBaseDirectory)

Retorna o nome do arquivo em relação ao diretório especificado:

  • sFileName : nome de arquivo completo (absoluto).
  • sBaseDirectory : diretório que será usado como diretório base para sFileName.

Se sFileName e sBaseDirectory contiverem o mesmo valor, a função retornará uma string vazia (""). Se o nome do arquivo com caminho relativo não puder ser obtido, a função retornará o valor de sFileName.

bResult = SysUtils.MatchesMask(sFileName, sMask, iMaskOptions)

Retorna true se o sFileName corresponder à máscara passada sMask.

iMaskOptions (parâmetro opcional, o valor padrão é 0) é definido como a soma dos seguintes valores:

Valor Descrição
1
Diferenciar maiúsculas/minúsculas
2
Ignorar acentos e ligaduras
4
Filtro estilo Windows: "*.*" também corresponde a arquivos sem extensão, etc.
8
Habilitar suporte a Pinyin (o arquivo pinyin.tbl será usado)

bResult = SysUtils.MatchesMaskList(sFileName, sMaskList, sSeparator, iMaskOptions)

Retorna true se o sFileName corresponder a pelo menos uma das máscaras passadas em sMaskList, separadas por sSeparator (o padrão é ";").

sSeparator e iMaskOptions (veja acima) são parâmetros opcionais.

sTempFileName = SysUtils.GetTempName()

Retornará um nome de arquivo para ser usado como nome de arquivo temporário (no diretório de arquivos temporários do sistema), semelhante à função os.tmpname, mas o arquivo será criado em um subdiretório que será excluído automaticamente quando o Double Commander for fechado.
Se a função não conseguir criar um nome único, ela retornará uma string vazia.

SysUtils.PathDelim

O caractere usado pelo sistema operacional atual para separar nomes de diretórios no nome de arquivo completo.

Em sistemas Unix/Linux, o separador de diretório será "/", no Windows será "\".

3.2.1. Detalhes dos valores de retorno de SysUtils.FileGetAttr

FileGetAttr retorna as configurações de atributos para o arquivo sFileName.

Os atributos são uma combinação OR das seguintes constantes:

Constantes usadas no valor de retorno de SysUtils.FileGetAttr
ValorSignificado
0x00000001
faReadOnly
O arquivo é somente leitura.
0x00000002
faHidden
O arquivo está oculto.
No Unix/Linux, isso significa que o nome do arquivo começa com um ponto.
0x00000004
faSysFile
O arquivo é um arquivo de sistema.
No Unix/Linux, isso significa que o arquivo é um dispositivo de caractere ou bloco, ou um pipe nomeado (FIFO).
0x00000008
faVolumeId
Rótulo de volume.
Aplicável apenas em sistemas de arquivos FAT comuns (não VFAT ou FAT32) no DOS/Windows.
0x00000010
faDirectory
O arquivo é um diretório.
0x00000020
faArchive
O arquivo foi arquivado.
Impossível no Unix/Linux.
0x00000400
faSymLink
O arquivo é um link simbólico.
Observação: Se ocorrer um erro, -1 será retornado.

Veja o exemplo na próxima seção.

3.2.2. Exemplo de uso de SysUtils.FileGetAttr

O seguinte script é um exemplo do uso de SysUtils.FileGetAttr.

Quando detectado que o argumento é um diretório, ele abrirá uma nova aba no painel ativo e mudará para esse diretório.

local params = {...}
local iAttr

if #params == 1 then -- obtivemos pelo menos um argumento?
  iAttr = SysUtils.FileGetAttr(params[1])
  if iAttr > 0 then -- obtivemos um atributo válido?
    if math.floor(iAttr / 0x00000010) % 2 ~= 0 then
      -- O 4º bit está definido? Então é um diretório.
      DC.ExecuteCommand("cm_NewTab")
      DC.ExecuteCommand("cm_ChangeDir", params[1])
    end
  end
end

No exemplo acima, params[1] é o primeiro argumento passado para o script.

Ao usar o comando interno cm_ExecuteScript, ele será o primeiro parâmetro passado após o nome do arquivo do script.

Portanto, no nosso exemplo, poderíamos configurar um botão na barra de ferramentas como abaixo:

Parâmetros usando cm_ExecuteScript

Neste exemplo, o parâmetro %"0%p será passado para o script. Isso representará o nome do arquivo do item atualmente sob o cursor no painel ativo sem aspas.

3.2.3. Exemplo de uso de FindFirst, FindNext e FindClose

No exemplo de script abaixo, vamos escanear o conteúdo do diretório recebido como parâmetro e armazenar os dados resultantes em um arquivo de texto com o nome passado como segundo parâmetro.

Isso nos dará uma boa ideia do uso de FindFirst, FindNext e FindClose.

local params = {...}

if #params == 2 then -- obtivemos dois argumentos?
  local Result = nil
  local hOutputFile = nil

  hOutputFile = io.output(params[2])

  local Handle, FindData = SysUtils.FindFirst(params[1] .. "\\*")
  if Handle ~= nil then
    repeat
      io.write(FindData.Name .. "\r")
      io.write(FindData.Size .. "\r")
      io.write("---------------\r")

      Result, FindData = SysUtils.FindNext(Handle)
    until Result == nil

    SysUtils.FindClose(Handle)
    io.close(hOutputFile)
  end
end

No exemplo acima, precisamos passar dois parâmetros para o script:

  1. params[1] - o diretório cujo conteúdo queremos
  2. params[2] - o nome do arquivo de saída para armazenar o resultado

Portanto, é muito fácil fazer tudo isso configurando um botão na barra de ferramentas com o comando interno cm_ExecuteScript e passando os parâmetros.

Parâmetros usando cm_ExecuteScript

Neste exemplo, o parâmetro %"0%Ds será passado para o script como o primeiro argumento. Isso representará o diretório exibido pelo painel ativo sem aspas.

3.3. Biblioteca da Área de Transferência

O Double Commander pode fornecer funcionalidade de área de transferência externa para nossos scripts Lua.

A tabela abaixo apresenta as funções relacionadas:

Biblioteca da Área de Transferência
Nome da funçãoDescrição

Clipbrd.Clear()

Limpa o conteúdo da área de transferência.

sVar = Clipbrd.GetAsText()

Obtém o conteúdo de texto atual da área de transferência e o atribui a sVar. Se a área de transferência não contiver texto, a função retornará uma string vazia.

Clipbrd.SetAsText(sVar)

Armazena o conteúdo de texto de sVar na área de transferência.

Clipbrd.SetAsHtml(sHtml)

Adiciona o texto formatado em html sHtml à área de transferência (formato de área de transferência CF_HTML).

Esses conteúdos serão inseridos em aplicativos que suportam este formato de área de transferência, como MS Word, LO Writer, etc.

É correto usar tanto Clipbrd.SetAsText quanto Clipbrd.SetAsHtml para armazenar dados. Quando colarmos, o aplicativo usará o melhor formato que suporta.

Por exemplo, poderíamos ter o seguinte:

  • Clipbrd.SetAsText("Bem-vindo ao Double Commander!")
  • Clipbrd.SetAsHtml("Bem-vindo ao <b>Double Commander</b>!")

Se mudarmos para o Bloco de Notas e tentarmos colar algo, ele colará a mensagem que copiamos com Clipbrd.SetAsText em texto simples. Mas se mudarmos para o Microsoft Word e colarmos algo, ele colará a segunda, ou seja, Double Commander aparecendo em negrito porque o Microsoft Word reconhece e suporta esse tipo de conteúdo da área de transferência.

3.3.1. Exemplo de uso da biblioteca da Área de Transferência

O seguinte exemplo utiliza as três funções relacionadas à área de transferência: Clear, GetAsText e SetAsText.

É um script relativamente longo, mas combina bem algumas das funções que vimos acima.

Assume que nosso painel ativo está atualmente localizado em um diretório que contém muitos arquivos de texto de origem.

Também assume que temos atualmente uma palavra na área de transferência e que receberá a pasta ativa atual como parâmetro único.

O script escaneará os arquivos no nível atual do diretório e lerá seu conteúdo um por um para detectar as linhas de texto que contêm a palavra que estava na área de transferência.

Então, o nome do arquivo que contém pelo menos uma linha com essa palavra será colocado na área de transferência.

O script então usará o comando interno cm_LoadSelectionFromClip e os arquivos que contêm a palavra serão selecionados.

Além disso, ao final, colocaremos a palavra original que precisávamos pesquisar de volta na área de transferência.

local params = {...}
local Result = nil
local iAttr
local bFound = false
local sCompleteFilename = ""
local hInputFile = nil
local sLine = ""
local iPosS
local iPosE
local sFileToSelect = ""
local sSearchString = ""

if #params == 1 then -- obtivemos o parâmetro?
  sSearchString = Clipbrd.GetAsText() -- obter a expressão a ser pesquisada.
  Clipbrd.Clear() -- certificar que não há nada na área de transferência.
  DC.ExecuteCommand("cm_MarkUnmarkAll") -- certificar que nada está selecionado.

  -- vamos escanear todos os arquivos do diretório um por um.
  local Handle, FindData = SysUtils.FindFirst(params[1] .. "\\*")
  if Handle ~= nil then
    repeat
      sCompleteFilename = params[1] .. "\\" .. FindData.Name
      iAttr = SysUtils.FileGetAttr(sCompleteFilename)
      if iAttr > 0 then -- obtivemos um atributo válido?
        -- precisamos de arquivos, não diretórios!
        if math.floor(iAttr / 0x00000010) % 2 == 0 then

          -- agora vamos ler o arquivo linha por linha até o fim ou encontrar.
          hInputFile = io.open(sCompleteFilename, "r")
          bFound = false

          while bFound == false do
            sLine = hInputFile:read()
            if sLine == nil then break end
            iPosS, iPosE = string.find(sLine, sSearchString)
            if iPosS ~= nil then bFound = true end
          end

          if bFound == true then
            sFileToSelect = sFileToSelect .. FindData.Name .. "\n"
          end

          io.close(hInputFile)
        end
      end
      Result, FindData = SysUtils.FindNext(Handle)
    until Result == nil

    SysUtils.FindClose(Handle)
  end

  -- se encontramos algo, selecione!
  if sFileToSelect ~= "" then
    Clipbrd.SetAsText(sFileToSelect)
    DC.ExecuteCommand("cm_LoadSelectionFromClip")
  end

  Clipbrd.SetAsText(sSearchString) -- restaurar o que tínhamos na área de transferência.
end

3.4. Biblioteca de Diálogos

Esta biblioteca permite que nossos scripts interajam com o usuário, exibindo mensagens, solicitando respostas, etc.

A tabela abaixo lista as funções relacionadas:

Biblioteca de Diálogos
Nome da funçãoDescrição

iButton = Dialogs.MessageBox(sMessage, sTitle, iFlags)

Exibe uma caixa de mensagem, solicitando ao usuário que clique em um botão, que será retornado pela função:

  • sMessage : texto na caixa de mensagem.
  • sTitle : título da caixa de mensagem.
  • iFlags : valor bitwise OR de constantes que determinam os botões exibidos, o estilo da janela e o botão padrão. Consulte as tabelas abaixo para botões exibidos, estilo da janela ou botão padrão.
  • iButton : valor de retorno, indicando o botão pressionado pelo usuário (consulte esta tabela).

bResult, sAnswer = Dialogs.InputQuery(sTitle, sMessage, bMask, sDefault)

Exibe uma caixa de solicitação onde o usuário pode inserir uma string:

  • sTitle : título da caixa de solicitação.
  • sMessage : texto na caixa de solicitação.
  • bMask : booleano, se verdadeiro, serão exibidos "asteriscos" para ocultar os caracteres.
  • sDefault : texto padrão sugerido, que o usuário pode modificar se desejar.
  • bResult : retorna um valor booleano indicando se o usuário realmente inseriu algo.
  • sAnswer : retorna a string quando o usuário insere algo e clica em OK.

sItem, iItem = Dialogs.InputListBox(sTitle, sMessage, aItems, sDefault)

Exibe um diálogo que permite ao usuário escolher entre uma lista de itens:

  • sTitle : título do diálogo.
  • sMessage : texto no diálogo.
  • aItems : uma tabela Lua, onde cada elemento da tabela deve ser uma string.
  • sDefault : o item da lista selecionado por padrão.
  • sItem : retorna o item selecionado como uma string, ou nil se o diálogo foi cancelado.
  • iItem : o índice do item selecionado (começando em 1, seguindo o hábito das tabelas Lua).

3.4.1. Botões exibidos em Dialogs.MessageBox

Os botões exibidos pela função Dialogs.MessageBox são controlados pelos valores bitwise OR das seguintes constantes:

Constantes ButFlags para exibição de botões em Dialogs.MessageBox
Valor da constanteBotões exibidos, da esquerda para a direita
0x0000
MB_OK
Botão OK
0x0001
MB_OKCANCEL
Botão OK Botão CANCEL
0x0002
MB_ABORTRETRYIGNORE
Botão ABORT Botão RETRY Botão IGNORE
0x0003
MB_YESNOCANCEL
Botão YES Botão NO Botão CANCEL
0x0004
MB_YESNO
Botão YES Botão NO
0x0005
MB_RETRYCANCEL
Botão RETRY Botão CANCEL

3.4.2. Estilos de janela de Dialogs.MessageBox

Os estilos de janela exibidos pela função Dialogs.MessageBox são controlados pelos valores bitwise OR das seguintes constantes:

Constantes ButFlags para ícones e estilos de Dialogs.MessageBox
Valor da constanteEstilo da janela
0x0040
MB_ICONINFORMATION
Ícone INFORMATION Janela de informação
0x0030
MB_ICONWARNING
Ícone WARNING Janela de aviso
0x0020
MB_ICONQUESTION
Ícone QUESTION Janela de confirmação
0x0010
MB_ICONERROR
Ícone ERROR Janela de erro

3.4.3. Botão padrão ativo de Dialogs.MessageBox

O botão padrão ativo exibido pela função Dialogs.MessageBox é controlado pelos valores bitwise OR das seguintes constantes:

Constantes ButFlags para botão padrão de Dialogs.MessageBox
Valor da constanteBotão padrão
0x0000
MB_DEFBUTTON1
O primeiro botão à esquerda é o padrão
0x0100
MB_DEFBUTTON2
O segundo botão à esquerda é o padrão
0x0200
MB_DEFBUTTON3
O terceiro botão à esquerda é o padrão

3.4.4. Valores de retorno de Dialogs.MessageBox

O número retornado pela função Dialogs.MessageBox indica o botão que o usuário pressionou, conforme abaixo:

Valores ButPressed retornados ao pressionar botões em Dialogs.MessageBox
Valor da constanteBotão pressionado
0x0000
mrNone
Nenhum botão pressionado
0x0001
mrOK
Resultado OK
0x0002
mrCancel
Resultado CANCEL
0x0003
mrAbort
Resultado ABORT
0x0004
mrRetry
Resultado RETRY
0x0005
mrIgnore
Resultado IGNORE
0x0006
mrYes
Resultado YES
0x0007
mrNo
Resultado NO

Nota: se você fechar a janela pressionando o "x" no canto superior direito ou pressionando Esc, o valor do botão "Cancelar" será retornado.

3.4.5. Exemplo de uso de Dialogs.MessageBox

Abaixo está um pequeno script usando Dialogs.MessageBox e a janela resultante que será exibida:

-- Botões exibidos
MB_OK = 0x0000
MB_OKCANCEL = 0x0001
MB_ABORTRETRYIGNORE = 0x0002
MB_YESNOCANCEL = 0x0003
MB_YESNO = 0x0004
MB_RETRYCANCEL = 0x0005

-- Estilo da janela
MB_ICONINFORMATION = 0x0040
MB_ICONWARNING = 0x0030
MB_ICONQUESTION = 0x0020
MB_ICONERROR = 0x0010

-- Botão padrão
MB_DEFBUTTON1 = 0x0000
MB_DEFBUTTON2 = 0x0100
MB_DEFBUTTON3 = 0x0200

-- Retorno do botão pressionado
mrNone = 0x0000
mrOK = 0x0001
mrCancel = 0x0002
mrAbort = 0x0003
mrRetry = 0x0004
mrIgnore = 0x0005
mrYes = 0x0006
mrNo = 0x0007

iFlags = MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2
iButton = Dialogs.MessageBox("Você deseja sair?", "Questão", iFlags)

if iButton == mrYes then
  DC.ExecuteCommand("cm_Exit")
end

Exemplo de uso de Dialogs.MessageBox

3.4.6. Exemplo de uso de Dialogs.InputQuery

Abaixo está um pequeno script usando Dialogs.InputQuery e a janela resultante que será exibida:

bResult, sAnswer = Dialogs.InputQuery("Autenticação", "Por favor, insira seu nome:", false, "João")

if bResult == true then
  Dialogs.MessageBox("Olá " .. sAnswer .. "!", "Bem-vindo!", 0x0040)
end

Exemplo de uso de Dialogs.InputQuery

3.5. Biblioteca UTF-8

Esta biblioteca fornece suporte básico para codificação UTF-8.

Ela fornece todas as funções na tabela LazUtf8.

Biblioteca UTF-8
Nome da funçãoDescrição

iResult = LazUtf8.Pos(SearchText, SourceText, Offset)

Procura por uma substring em uma string começando de uma posição especificada. A busca diferencia maiúsculas/minúsculas.

Retorna a posição da primeira ocorrência da substring SearchText na string SourceText, a busca começa na posição Offset (o padrão é 1).

Se SearchText não for encontrado em SourceText após o Offset fornecido, zero será retornado.

LazUtf8.Next(String)

Uma função iteradora que retorna o próximo caractere em String e a posição inicial desse caractere (em bytes) a cada chamada.

Exemplo:

-- imprimir pares de valores na forma "posição : caractere"
for iPos, sChar in LazUtf8.Next(String) do
  DC.LogWrite(iPos .. " : " .. sChar)
end

sResult = LazUtf8.Copy(String, iIndex, iCount)

Copia uma parte da string.

Copy retorna uma string que é uma cópia de iCount caracteres de String começando na posição iIndex.

Se iCount for maior que o comprimento da string String, o resultado será truncado. Se iIndex for maior que o comprimento da string String, uma string vazia será retornada.

iResult = LazUtf8.Length(String)

Retorna o número de caracteres UTF-8 na string.

sResult = LazUtf8.UpperCase(String)

Recebe uma string e retorna uma cópia dessa string com todas as letras minúsculas alteradas para maiúsculas.

sResult = LazUtf8.LowerCase(String)

Recebe uma string e retorna uma cópia dessa string com todas as letras maiúsculas alteradas para minúsculas.

sResult = LazUtf8.ConvertEncoding(String, FromEnc, ToEnc)

Converte a codificação da String de FromEnc para ToEnc.

Lista de valores de codificação suportados:

  • Codificação padrão do sistema (depende da localidade do sistema): "default".
  • Codificação ANSI (Windows) padrão (depende da localidade do sistema): "ansi".
  • Codificação OEM (DOS) padrão (depende da localidade do sistema): "oem".
  • Unicode: "utf8", "utf8bom", "ucs2le", "ucs2be".
  • ANSI (Windows): "cp1250", "cp1251", "cp1252", "cp1253", "cp1254", "cp1255", "cp1256", "cp1257", "cp1258".
  • OEM (DOS): "cp437", "cp850", "cp852", "cp865", "cp866", "cp874", "cp932", "cp936", "cp949", "cp950".
  • ISO 8859: "iso88591", "iso88592", "iso88593", "iso88594", "iso88595", "iso88597", "iso88599", "iso885910", "iso885913", "iso885914", "iso885915", "iso885916".
  • Outras: "macintosh", "koi8r", "koi8u", "koi8ru".
Significado das codificações especiais (exemplos).

No Windows (em inglês ou português):
  • "default" - cp1252 ou cp1251
  • "ansi" - cp1252 ou cp1251
  • "oem" - cp850 ou cp866
No Linux (em inglês ou português):
  • "default" - utf8
  • "ansi" - cp1252 ou cp1251
  • "oem" - cp850 ou cp866

sEnc = LazUtf8.DetectEncoding(String)

Retorna o valor da codificação do texto transmitido.
A lista de codificações suportadas é semelhante à lista usada na função LazUtf8.ConvertEncoding.

3.6. Biblioteca de Caracteres

Esta biblioteca contém funções para verificar se os caracteres pertencem a certas categorias Unicode, bem como funções para obter a categoria do caractere.

Lista de funções disponíveis nesta biblioteca:

Biblioteca de Caracteres
Nome da funçãoDescrição

iResult = Char.GetUnicodeCategory(Character)

Retorna a categoria Unicode do caractere Character, um dos seguintes valores:

ValorDescrição
  Letra:
0Letra maiúscula (Lu)
1Letra minúscula (Ll)
2Letra de título (Lt)
3Letra modificadora (Lm)
4Outra letra (Lo)
  Marca:
5Marca sem espaçamento (Mn)
6Marca de combinação de espaçamento (Mc)
7Marca envolvente (Me)
  Número:
8Número decimal (Nd)
9Número de letra (Nl)
10Outro número (No)
  Pontuação:
11Pontuação de conexão (Pc)
12Pontuação de travessão (Pd)
13Pontuação de abertura (Ps)
14Pontuação de fechamento (Pe)
15Pontuação inicial (Pi)
16Pontuação final (Pf)
17Outra pontuação (Po)
  Símbolo:
18Símbolo matemático (Sm)
19Símbolo monetário (Sc)
20Símbolo modificador (Sk)
21Outro símbolo (So)
  Separador:
22Separador de espaço (Zs)
23Separador de linha (Zl)
24Separador de parágrafo (Zp)
  Outro:
25Controle (Cc)
26Formato (Cf)
27Substituto (Cs)
28Uso privado (Co)
29Não atribuído (Cn)

bResult = Char.IsDigit(Character)

Retorna true se o caractere Character estiver na categoria Nd.

bResult = Char.IsLetter(Character)

Retorna true se o caractere Character estiver na categoria Lu, Ll, Lt, Lm ou Lo.

bResult = Char.IsLetterOrDigit(Character)

Retorna true se o caractere Character estiver na categoria Lu, Ll, Lt, Lm, Lo, Nd ou Nl.

bResult = Char.IsLower(Character)

Retorna true se o caractere Character estiver na categoria Ll.

bResult = Char.IsUpper(Character)

Retorna true se o caractere Character estiver na categoria Lu.

Além disso, essas funções suportam o uso de dois parâmetros: podemos especificar uma string e a posição do caractere nessa string, em vez de um único caractere.

3.7. Biblioteca do Sistema Operacional

Esta biblioteca contém funções relacionadas ao sistema operacional no qual o Double Commander está sendo executado.

Abaixo está a lista de funções disponíveis nesta biblioteca:

Biblioteca do Sistema Operacional
Nome da funçãoDescrição

iResultCode = os.execute(sCommand)

Executará sCommand, como se tivesse sido inserido na linha de comando, e retornará o código de resultado da operação.

sCommand pode ser:

  • comando do terminal, por exemplo os.execute("dir > all.txt")
  • um arquivo executável, por exemplo os.execute("C:\\Windows\\System32\\calc.exe")
  • um executável com parâmetros:
    os.execute("C:\\Utils\\fsum.exe -md5 test.bin > md5.txt")

sTempFileName = os.tmpname()

Retornará um nome de arquivo para ser usado como nome de arquivo temporário (no diretório de arquivos temporários do sistema).
Se a função não conseguir criar um nome único, ela retornará uma string vazia.

bResult, sError, iError = os.remove(sFileName)

Excluirá o arquivo ou diretório com o nome sFileName.

Se for bem-sucedida, a função retornará true.

Se falhar, a função retornará três coisas:

  1. nil indicando a falha
  2. sError sendo a descrição da mensagem de erro
  3. iError sendo o número do código do erro

bResult, sError, iError = os.rename(sOldName, sNewName)

Renomeará o arquivo sOldName com o novo nome sNewName.

AVISO: Se um arquivo chamado sNewName já existir, ele será substituído!

Se for bem-sucedida, a função retornará true.

Se falhar, a função retornará três coisas:

  1. nil indicando a falha
  2. sError sendo a descrição da mensagem de erro
  3. iError sendo o número do código do erro

Value = os.getenv(VariableName)

Retornará o Value da variável de ambiente VariableName passada como argumento.
Retornará nil se não houver tal variável com esse nome.

os.setenv(VariableName, Value)

Adiciona ou altera a variável de ambiente VariableName. No caso de um erro, a função retorna -1.

os.unsetenv(VariableName)

Remove a variável de ambiente VariableName. No caso de um erro, a função retorna -1.

4. Índice

Biblioteca DC

DC.CurrentPanel
DC.ExecuteCommand
DC.LogWrite


Biblioteca do Sistema

SysUtils.CreateDirectory
SysUtils.CreateHardLink
SysUtils.CreateSymbolicLink
SysUtils.DirectoryExists
SysUtils.ExtractFileDir
SysUtils.ExtractFileDrive
SysUtils.ExtractFileExt
SysUtils.ExtractFileName
SysUtils.ExtractFilePath
SysUtils.FileExists
SysUtils.FileGetAttr
SysUtils.FindClose
SysUtils.FindFirst
SysUtils.FindNext
SysUtils.GetAbsolutePath
SysUtils.GetRelativePath
SysUtils.GetTempName
SysUtils.GetTickCount
SysUtils.MatchesMask
SysUtils.MatchesMaskList
SysUtils.PathDelim
SysUtils.ReadSymbolicLink
SysUtils.Sleep


Biblioteca da Área de Transferência

Clipbrd.Clear
Clipbrd.GetAsText
Clipbrd.SetAsHtml
Clipbrd.SetAsText


Biblioteca de Diálogos

Dialogs.InputListBox
Dialogs.InputQuery
Dialogs.MessageBox


Biblioteca UTF-8

LazUtf8.ConvertEncoding
LazUtf8.Copy
LazUtf8.DetectEncoding
LazUtf8.Length
LazUtf8.LowerCase
LazUtf8.Next
LazUtf8.Pos
LazUtf8.UpperCase


Biblioteca de Caracteres

Char.GetUnicodeCategory
Char.IsDigit
Char.IsLetter
Char.IsLetterOrDigit
Char.IsLower
Char.IsUpper


Biblioteca do Sistema Operacional

os.execute
os.getenv
os.remove
os.rename
os.setenv
os.tmpname
os.unsetenv


HTML 4.0 Transitional Válido CSS Válido!