Referência completa para o aplicativo EEditor e a linguagem EELisp. Abrange todos os recursos, todas as funções embutidas e todos os atalhos de teclado.
Ao iniciar o EEditor pela primeira vez, você vê um editor vazio com uma barra lateral. Três passos para começar:
Use ⌘⇧O para abrir um único arquivo de qualquer lugar no disco. O diretório pai do arquivo se torna a pasta ativa.
O EEditor oferece um ambiente de escrita sem distrações com destaque de sintaxe em tempo real para Markdown e mais de 24 linguagens de programação.
YYYY-MM-DD HH:mm na posição do cursor.[[nome-do-arquivo]] e pressione ⌘O para abrir o arquivo.A barra lateral mostra uma visualização hierárquica da sua pasta. Diretórios aparecem primeiro, depois arquivos em ordem alfabética.
subpasta/arquivo.md para criar arquivos aninhados..el ou .lisp para executá-lo.A barra lateral possui três modos através do controle segmentado: Arquivos, Calendário e Agenda.
Cada arquivo abre como uma aba no topo do editor.
| Ação | Atalho | Observações |
|---|---|---|
| Próxima aba | ⌘⌥→ | Volta ao início |
| Aba anterior | ⌘⌥← | Volta ao início |
| Fechar aba | ⌘W | Salva automaticamente se houver alterações |
| Fechar todas as não fixadas | ⌘⌥W | |
| Fixar / Desfixar | ⌘⇧K | Abas fixadas persistem entre sessões |
Abas fixadas exibem um ícone de pino, aparecem primeiro (ordenadas alfabeticamente) e não podem ser fechadas até serem desfixadas. Elas são restauradas automaticamente ao reiniciar.
Posicione o cursor em um link [[nome-do-arquivo]] e pressione ⌘O para abrir o arquivo diretamente.
YYYY-MM-DD.md na raiz do projeto, pré-preenchido com um título de data.Week of YYYY-MM-DD.md (segunda-feira da semana atual).Alterne a barra lateral para o modo Calendário usando o controle segmentado.
Alterne para o modo Agenda pelo ícone de prancheta. O painel mostra sua programação em três seções:
:when anterior a hoje.Cada item mostra um ponto de prioridade (vermelho = urgente, laranja = alta, amarelo = média, cinza = normal), texto, categorias e data formatada. Toque em atualizar para recarregar após adicionar itens no REPL.
O REPL é um painel na barra lateral direita que coexiste com o editor. Alterne-o com ⌘⇧L ou o ícone de terminal na barra de ferramentas.
Incorpore código EELisp executável diretamente nos seus arquivos Markdown usando blocos de código delimitados:
```eelisp
(+ 1 2 3)
```
```eelisp.```result logo abaixo.```eelisp
(+ 1 2 3)
```
```result
6
```
Reexecutar substitui o resultado existente. O resultado é inserido como texto simples (não em um bloco de código) e é selecionado automaticamente para que você possa imediatamente ⌘C para copiar ou ⌘X para recortar.
Quando um bloco EELisp retorna um formulário (edit, defform) ou tabela (browse), ele abre como um painel lateral interativo ao lado do editor em vez de inserir texto simples. Você pode interagir com o formulário — navegar registros, editar campos, salvar — mantendo seu documento visível. Uma linha de resumo ainda é inserida no documento.
Casos de uso incluem cálculos inline, adição de itens de agenda a partir de entradas de diário, consulta de dados e operações com arquivos:
```eelisp
(add-item (smart-parse "tomorrow review quarterly report !!"))
```
```eelisp
(write-file "todo.txt" "Buy groceries\nCall dentist")
```
Pressione ⌘? no aplicativo para ver a folha completa de atalhos. Aqui está a referência completa:
| Ação | Atalho |
|---|---|
| Novo arquivo | ⌘N |
| Abrir pasta | ⌘O |
| Abrir arquivo | ⌘⇧O |
| Salvar | ⌘S |
| Atualizar árvore | ⌘⇧R |
| Nota diária | ⌘D |
| Planejador semanal | ⌘⇧W |
| Ação | Atalho |
|---|---|
| Abertura Rápida | ⌘P |
| Buscar nos arquivos | ⌘⇧F |
| Buscar e Substituir | ⌘F |
| Focar no editor | ⌘\ |
| Abrir wiki-link | ⌘O |
| Ação | Atalho |
|---|---|
| Próxima aba | ⌘⌥→ |
| Aba anterior | ⌘⌥← |
| Fechar aba | ⌘W |
| Fechar todas as não fixadas | ⌘⌥W |
| Fixar / Desfixar aba | ⌘⇧K |
| Ação | Atalho |
|---|---|
| Inserir data/hora | ⌘I |
| Desfazer | ⌘Z |
| Refazer | ⌘⇧Z |
| Ação | Atalho |
|---|---|
| Visualizar | ⌘⇧P |
| Exportar PDF | ⌘⇧E |
| Alternar Barra Lateral do REPL | ⌘⇧L |
| Enviar para o REPL | ⌘R |
| Executar Bloco EELisp | ⌘⇧Return |
| Inserir Bloco EELisp | ⌘⇧C |
| Executar (no REPL) | ⌘Return |
| Ajuda de atalhos | ⌘? |
O EEditor inclui um interpretador Lisp embutido chamado EELisp — projetado para gerenciamento de dados pessoais, cálculos e scripts.
> e pressione ⌘Return para avaliar... e aguarda mais. Uma barra de dica mostra ⌘↩ para executar · ⎋ para cancelar.Selecione texto no editor e pressione ⌘R ou ⌘⇧L. A barra lateral do REPL abre com sua seleção pré-preenchida no campo de entrada, pronta para você pressionar ⌘Return para avaliar.
O EELisp inclui funções embutidas e comandos do REPL para gerenciamento de bancos de dados:
| Comando | Descrição |
|---|---|
(tables) | Listar todas as tabelas no banco de dados atual |
(describe tablename) | Mostrar o esquema de uma tabela |
(drop-table tablename) | Excluir uma tabela |
:db | Mostrar o caminho do banco de dados atual |
:db <path> | Alternar para um arquivo de banco de dados diferente |
:db new <name> | Criar um novo arquivo de banco de dados na pasta atual |
:db memory | Alternar para um banco de dados em memória |
Use :load path/to/file.el para carregar e avaliar um script EELisp. No iOS, toque no botão Carregar na barra de ferramentas ou clique com botão direito em um arquivo .el na barra lateral.
No iOS/iPadOS, uma barra de ferramentas aparece com: navegação de histórico (↑/↓), snippets rápidos (query, deftable, defn), Carregar Arquivo e Limpar.
Comandos prefixados com dois-pontos controlam o próprio REPL (não são expressões EELisp):
| Comando | Alias | Descrição |
|---|---|---|
:help | :h | Mostrar referência de comandos e exemplos rápidos |
:load <file> | :l | Carregar e avaliar um arquivo .el / .lisp |
:db | Mostrar caminho do banco de dados atual (:memory: ou caminho do arquivo) | |
:db <path> | Alternar para um arquivo de banco de dados diferente | |
:db new <name> | Criar um novo banco de dados na pasta atual | |
:db memory | Alternar para um banco de dados em memória | |
:env | :e | Listar todos os símbolos definidos no ambiente |
:clear | :c | Limpar histórico de saída do REPL |
:reset | :r | Reiniciar interpretador (ambiente limpo, mesmo banco de dados) |
eelisp.db, o REPL conecta-se automaticamente a ele para armazenamento persistente. Dados criados com deftable e insert são salvos em disco.
Todos os operadores aritméticos são variádicos (aceitam múltiplos argumentos) e funcionam com inteiros e números de ponto flutuante.
| Função | Assinatura | Descrição |
|---|---|---|
+ | (+ num ...) | Adição. (+ 1 2 3) → 6 |
- | (- num ...) | Subtração ou negação. (- 10 3) → 7, (- 5) → -5 |
* | (* num ...) | Multiplicação. (* 2 3 4) → 24 |
/ | (/ num num ...) | Divisão. (/ 100 3) → 33.333... |
mod | (mod a b) | Módulo. (mod 10 3) → 1 |
abs | (abs num) | Valor absoluto. (abs -42) → 42 |
min | (min num ...) | Mínimo. (min 3 1 4) → 1 |
max | (max num ...) | Máximo. (max 3 1 4) → 4 |
floor | (floor num) | Arredondar para baixo. (floor 3.7) → 3 |
ceil | (ceil num) | Arredondar para cima. (ceil 3.2) → 4 |
pow | (pow base exp) | Exponenciação. (pow 2 10) → 1024 |
round | (round num [places]) | Arredondar. (round 3.14159 2) → 3.14 |
;; Exemplos de aritmética (+ 1 2 3 4) ; → 10 (* 6 7) ; → 42 (/ 100 3) ; → 33.333... (pow 2 10) ; → 1024 (round 3.14159 2) ; → 3.14 ;; Aninhamento (+ (* 3 4) (- 10 5)) ; → 17
| Função | Assinatura | Descrição |
|---|---|---|
= | (= a b) | Igualdade. Funciona com números, strings, booleanos |
!= | (!= a b) | Desigualdade |
< | (< a b) | Menor que |
> | (> a b) | Maior que |
<= | (<= a b) | Menor ou igual |
>= | (>= a b) | Maior ou igual |
Estes são formas especiais (avaliação em curto-circuito):
(and true false) ; → false (or false true) ; → true (not true) ; → false ;; Curto-circuito: (or) retorna o primeiro valor verdadeiro (or nil false 42 99) ; → 42
(def x 42) (def greeting "Hello, world!") (def pi 3.14159)
(defn square (x) (* x x)) (square 5) ; → 25 ;; Corpo com múltiplas expressões (último valor é retornado) (defn greet (name) (def msg (str "Hello, " name "!")) (println msg) msg)
(map (fn (x) (* x x)) '(1 2 3)) ; → (1 4 9)
(defn sum (first . rest) (reduce + first rest)) (sum 1 2 3 4 5) ; → 15
(let ((x 1) (y 2)) (+ x y)) ; → 3
(if (> x 0) "positive" "non-positive")
(cond (< x 0) "negative" (= x 0) "zero" else "positive")
;; Executa o corpo somente se a condição for verdadeira (when (> x 0) (println "positive!") x)
;; Soma de 0 a 10 (loop ((i 0) (acc 0)) (> i 10) (recur (+ i 1) (+ acc i))) ; → 55
;; Avalia múltiplas expressões, retorna a última (begin (def a 10) (def b 20) (+ a b)) ; → 30
| Função | Assinatura | Exemplo → Resultado |
|---|---|---|
str | (str val ...) | (str "a" "b" "c") → "abc" |
str-len | (str-len s) | (str-len "hello") → 5 |
str-upper | (str-upper s) | (str-upper "hello") → "HELLO" |
str-lower | (str-lower s) | (str-lower "HELLO") → "hello" |
str-contains | (str-contains s sub) | (str-contains "hello" "ell") → true |
str-starts-with | (str-starts-with s prefix) | (str-starts-with "hello" "he") → true |
str-ends-with | (str-ends-with s suffix) | (str-ends-with "hello" "lo") → true |
str-split | (str-split s sep) | (str-split "a,b,c" ",") → ("a" "b" "c") |
str-join | (str-join sep list) | (str-join "-" '("a" "b")) → "a-b" |
str-trim | (str-trim s) | (str-trim " hi ") → "hi" |
str-replace | (str-replace s target repl) | (str-replace "hello" "l" "r") → "herro" |
str-matches | (str-matches s regex) | Retorna lista de grupos de captura ou nil |
substr | (substr s start [end]) | (substr "hello" 1 3) → "el" |
| Função | Assinatura | Exemplo → Resultado |
|---|---|---|
list | (list val ...) | (list 1 2 3) → (1 2 3) |
cons | (cons val list) | (cons 0 '(1 2)) → (0 1 2) |
car / head | (car list) | (car '(1 2 3)) → 1 |
cdr / tail | (cdr list) | (cdr '(1 2 3)) → (2 3) |
nth | (nth list n) | (nth '(a b c) 1) → b |
length | (length seq) | (length '(1 2 3)) → 3 |
append | (append list ...) | (append '(1) '(2 3)) → (1 2 3) |
reverse | (reverse list) | (reverse '(1 2 3)) → (3 2 1) |
map | (map fn list) | (map inc '(1 2 3)) → (2 3 4) |
filter | (filter fn list) | (filter even? '(1 2 3 4)) → (2 4) |
reduce | (reduce fn init list) | (reduce + 0 '(1 2 3)) → 6 |
range | (range [start] end [step]) | (range 1 6) → (1 2 3 4 5) |
flatten | (flatten list) | (flatten '(1 (2 3) (4))) → (1 2 3 4) |
sort-by | (sort-by fn list) | (sort-by id '(3 1 2)) → (1 2 3) |
zip | (zip list list) | (zip '(1 2) '(a b)) → ((1 a) (2 b)) |
empty? | (empty? val) | (empty? '()) → true |
;; Encadeando operações de lista (def nums (range 1 11)) (filter even? nums) ; → (2 4 6 8 10) (map (fn (x) (* x x)) (filter even? nums)) ; → (4 16 36 64 100) (reduce + 0 (range 1 101)) ; → 5050
Dicionários usam chaves de palavra-chave (:name) e são imutáveis — operações retornam novos dicionários.
| Função | Assinatura | Exemplo → Resultado |
|---|---|---|
dict | (dict :key val ...) | (dict :a 1 :b 2) → {:a 1 :b 2} |
dict-get | (dict-get d key [default]) | (dict-get d :name) → valor ou nil |
dict-set | (dict-set d key val) | Retorna novo dicionário com a chave definida |
dict-keys | (dict-keys d) | (dict-keys {:a 1 :b 2}) → (:a :b) |
dict-values | (dict-values d) | (dict-values {:a 1 :b 2}) → (1 2) |
dict-has | (dict-has d key) | (dict-has {:a 1} :a) → true |
dict-merge | (dict-merge d ...) | Mescla dicionários; chaves posteriores sobrescrevem |
(def person {:name "Alice" :age 30}) (dict-get person :name) ; → "Alice" (dict-set person :age 31) ; → {:name "Alice" :age 31} (dict-merge person {:city "NYC"}) ; → {:name "Alice" :age 30 :city "NYC"}
| Função | Retorna verdadeiro quando |
|---|---|
string? | O valor é uma string |
number? | O valor é um número |
bool? | O valor é um booleano |
list? | O valor é uma lista |
nil? | O valor é nil/null |
symbol? | O valor é um símbolo |
keyword? | O valor é uma palavra-chave |
fn? | O valor é uma função |
dict? | O valor é um dicionário |
date? | O valor é uma data |
record? | O valor é um registro de banco de dados |
item? | O valor é um item de agenda |
(type 42) ; → "number" (type "hello") ; → "string" (type '(1 2)) ; → "list"
| Função | Descrição |
|---|---|
->string | Converter qualquer valor para sua representação em string |
->number | Converter string para número, booleano para 0/1 |
->bool | Veracidade: nil, false, 0, "" → false; todo o resto → true |
| Função | Descrição |
|---|---|
(print val ...) | Imprime valores sem nova linha final |
(println val ...) | Imprime valores com nova linha final |
| Função | Assinatura | Descrição |
|---|---|---|
now | (now) | Objeto de data/hora atual |
today | (today) | Hoje como string ISO "YYYY-MM-DD" |
date-format | (date-format date [fmt]) | Formata uma data. Padrão: "yyyy-MM-dd HH:mm" |
date-add | (date-add date n :unit) | Adiciona dias/semanas/meses. Unidades: :days, :weeks, :months |
date-diff | (date-diff d1 d2) | Diferença em dias entre duas strings de data ISO |
(today) ; → "2026-02-23" (date-add (today) 7 :days) ; → "2026-03-02" (date-add "2026-01-31" 1 :months) ; → "2026-02-28" (date-diff "2026-01-01" "2026-12-31") ; → 364
Essas funções são definidas no próprio EELisp e carregadas automaticamente na inicialização:
| Função | Descrição | Exemplo |
|---|---|---|
inc | Incrementa por 1 | (inc 5) → 6 |
dec | Decrementa por 1 | (dec 5) → 4 |
even? | Verdadeiro se par | (even? 4) → true |
odd? | Verdadeiro se ímpar | (odd? 3) → true |
zero? | Verdadeiro se zero | (zero? 0) → true |
pos? | Verdadeiro se positivo | (pos? 5) → true |
neg? | Verdadeiro se negativo | (neg? -3) → true |
first | Primeiro elemento | (first '(a b c)) → a |
second | Segundo elemento | (second '(a b c)) → b |
third | Terceiro elemento | (third '(a b c)) → c |
last | Último elemento | (last '(a b c)) → c |
take | Pega os primeiros n | (take 2 '(a b c)) → (a b) |
drop | Descarta os primeiros n | (drop 1 '(a b c)) → (b c) |
some? | Algum corresponde? | (some? even? '(1 2 3)) → true |
every? | Todos correspondem? | (every? pos? '(1 2 3)) → true |
pipe | Encadeamento | (pipe 5 inc inc square) → 49 |
compose | Compõe funções | ((compose inc square) 5) → 26 |
partial | Aplicação parcial | ((partial + 10) 5) → 15 |
id | Função identidade | (id 42) → 42 |
| Função | Assinatura | Descrição |
|---|---|---|
http-get | (http-get url) | Requisição GET. Retorna {:status N :body "..."} |
http-post | (http-post url body [:content-type "..."]) | Requisição POST com corpo |
json-parse | (json-parse string) | Analisa JSON para dict/lista EELisp |
json-stringify | (json-stringify value) | Converte valor EELisp para string JSON |
;; Buscar dados de uma API (def resp (http-get "https://api.example.com/data")) (def data (json-parse (dict-get resp :body))) ;; Enviar JSON via POST (http-post "https://api.example.com/items" (json-stringify {:name "test"}) :content-type "application/json")
| Função | Descrição |
|---|---|
(eval expr) | Avalia uma expressão não avaliada |
(parse string) | Analisa uma string como código EELisp |
O EELisp pode ler e escrever arquivos na sua pasta aberta. Todos os caminhos são relativos ao diretório do workspace atual.
| Função | Descrição |
|---|---|
(read-file path) | Lê o conteúdo do arquivo como uma string |
(write-file path content) | Escreve conteúdo em um arquivo (cria ou sobrescreve) |
(append-file path content) | Adiciona conteúdo ao final de um arquivo existente |
(file-exists? path) | Verifica se um arquivo existe |
(list-files [path]) | Lista nomes de arquivos em um diretório (padrão: raiz do workspace) |
(current-dir) | Obtém o caminho raiz do workspace |
;; Ler um arquivo (def content (read-file "notes.md")) ;; Escrever resultados em um arquivo (write-file "output.txt" (str "Report: " (today))) ;; Adicionar a um log (append-file "log.txt" (str (today) " - Done\n")) ;; Listar arquivos do workspace (list-files) ; → ("README.md" "notes.md" ...) (list-files "src") ; → ("main.el" "utils.el" ...)
Esses builtins permitem que o código EELisp interaja com o buffer ativo do editor.
| Função | Descrição |
|---|---|
(cursor-pos) | Obtém a posição atual do cursor (offset de caractere) |
(set-cursor-pos pos) | Move o cursor para uma posição |
(insert-at pos text) | Insere texto em uma posição |
(replace-range start end text) | Substitui texto entre início e fim |
(selection) | Obtém o texto selecionado atualmente (ou nil) |
(current-file) | Obtém o caminho do arquivo ativo |
(buffer-text) | Obtém o texto completo do editor ativo |
;; Inserir texto na posição do cursor (insert-at (cursor-pos) (str "Updated: " (today))) ;; Obter o que está selecionado (def sel (selection)) ;; Ler o buffer inteiro (def text (buffer-text)) (println (str "Length: " (str-len text)))
| Função | Descrição |
|---|---|
(clipboard-get) | Lê texto da área de transferência |
(clipboard-set text) | Copia texto para a área de transferência |
;; Copiar um resultado para a área de transferência (clipboard-set (str "Total: $" (reduce + 0 '(10 20 30)))) ;; Colar e processar conteúdo da área de transferência (str-upper (clipboard-get))
O EELisp inclui um mecanismo de banco de dados SQLite integrado. As tabelas são definidas com esquemas tipados.
(deftable contacts (name:string email:string age:number))
| Tipo | Descrição | Valores de exemplo |
|---|---|---|
string | Dados de texto | "Alice", "hello@example.com" |
number | Inteiro ou float | 42, 3.14 |
bool | Booleano | true, false |
date | String de data ISO | "2026-02-23" |
memo | Texto longo | Conteúdo multilinha |
choice | Seletor dropdown | Lista de opções predefinidas |
| Função | Descrição |
|---|---|
(tables) | Lista todos os nomes de tabelas |
(describe table) | Mostra o esquema da tabela |
(drop-table table) | Exclui uma tabela e todos os seus dados |
(pack table) | Remove permanentemente registros excluídos por soft-delete |
;; Exemplo completo (deftable tasks (title:string priority:number done:bool due:date)) (tables) ; → (tasks) (describe tasks) ; → detalhes do esquema
(insert tasks {:title "Write docs" :priority 1 :done false}) (insert tasks {:title "Fix bug" :priority 2 :done false :due "2026-03-01"})
;; Todos os registros (query tasks) ;; Com cláusula WHERE (query tasks :where "priority <= ?" :params (list 2)) ;; Ordenado e limitado (query tasks :order "priority" :limit 5) ;; Selecionar colunas específicas (query tasks :select "title, done") ;; Ordem decrescente (query tasks :order "priority" :asc false)
;; Atualizar por ID (update tasks 1 {:done true}) ;; Soft-delete (estilo dBASE, pode ser recuperado) (delete tasks 1) ;; Remover permanentemente registros com soft-delete (pack tasks) ;; Contar registros (count-records tasks) (count-records tasks :where "done = ?" :params (list false))
| Função | Descrição |
|---|---|
(field-get record :field) | Obtém o valor de um campo de um registro |
(field-set record :field val) | Retorna novo registro com campo atualizado |
(record-id record) | Obtém o ID numérico do registro |
(records result-set) | Extrai lista de registros de um resultado de consulta |
;; Trabalhando com resultados de consulta programaticamente (def results (query tasks :where "done = ?" :params (list false))) (def recs (records results)) (map (fn (r) (field-get r :title)) recs) ; → ("Write docs" "Fix bug")
O EELisp pode renderizar componentes de UI interativos diretamente na saída do REPL.
;; Navegar por todos os registros em uma grade rolável (browse tasks) ;; Com filtros e ordenação (browse tasks :where "done = ?" :params (list false) :order "priority")
;; Abrir um formulário interativo para criar/ler/atualizar/excluir (edit tasks) ;; Com filtros (edit tasks :where "priority = ?" :params (list 1))
O formulário mostra um registro por vez com navegação Anterior/Próximo, edição inline, e botões Salvar, Novo e Excluir.
;; Formulário de calculadora independente com campos computados (defform loan-calc (principal:number rate:number years:number) :computed ( (monthly-payment (let ((r (/ rate 1200)) (n (* years 12))) (round (/ (* principal r (pow (+ 1 r) n)) (- (pow (+ 1 r) n) 1)) 2))) (total-paid (round (* monthly-payment (* years 12)) 2))))
Campos computados são atualizados automaticamente quando os campos de entrada mudam.
Use a sintaxe (name:choice "opt1" "opt2" ...) para criar um seletor dropdown:
(defform new-task (title:string (priority:choice "low" "medium" "high" "urgent") (status:choice "todo" "in-progress" "done") notes:memo))
Campos de escolha são renderizados como um menu dropdown na interface do formulário.
Vincule um formulário a uma tabela de banco de dados existente com :source para habilitar CRUD completo:
;; Criar uma tabela primeiro (deftable projects (name:string status:string budget:number)) (insert projects {:name "Alpha" :status "active" :budget 50000}) ;; Formulário vinculado à tabela com dropdown para status (defform project-editor (name:string (status:choice "planning" "active" "completed") budget:number) :source projects)
O formulário carrega registros da tabela de origem com navegação Anterior/Próximo, e botões Salvar, Novo e Excluir — como (edit table) mas com tipos de campo personalizados.
eelisp.db, o REPL conecta automaticamente a ele.| Comando | Descrição |
|---|---|
:db | Mostra o caminho do banco de dados atual |
:db <path> | Alterna para um arquivo de banco de dados diferente (relativo à pasta) |
:db new <name> | Cria um novo banco de dados na pasta atual |
:db memory | Alterna para um banco de dados em memória |
:db mydata.db em vez de digitar o caminho completo.
O sistema de agenda é um gerenciador de informações pessoais inspirado no Lotus Agenda. Itens são entradas de texto livre com metadados opcionais.
(add-item "Finish quarterly report") ;; Com metadados (add-item "Call dentist" :when "2026-03-01" :priority 2) (add-item "Buy groceries" :category "personal" :notes "milk, eggs") ;; Adicionar com a data de hoje (add-item-today "Review pull requests" :priority 1)
(items) ; todos os itens (visualização em tabela) (items :category "work") ; filtrar por categoria (items :search "quarterly") ; busca por texto (items :priority 1) ; filtrar por prioridade (items :when-before "2026-03-01") ; vencimento antes da data
| Função | Descrição |
|---|---|
(item-get id) | Busca um único item por ID |
(item-edit id) | Abre item na visualização de formulário para edição |
(item-set id :field val ...) | Atualiza campos do item |
(item-done id) | Marca item como concluído (soft-delete) |
(item-count) | Conta todos os itens |
(item-count :category "work") | Conta itens em uma categoria |
As categorias são hierárquicas (use separadores /) e opcionalmente exclusivas (o item pode estar em apenas um filho).
;; Categorias hierárquicas (defcategory work) (defcategory work/projects) (defcategory work/meetings) (defcategory personal) (defcategory personal/errands) ;; Exclusiva: item pode estar em apenas um filho (defcategory priority :exclusive true :children (high medium low)) ;; Atribuir / desatribuir (assign 1 "work/projects") (assign 1 "priority/high") (unassign 1 "personal") ;; Ver árvore de categorias (categories)
:exclusive true, atribuir um filho (ex.: priority/low) remove automaticamente os irmãos (ex.: priority/high). Perfeito para status, prioridade ou qualquer agrupamento de escolha única.
Regras categorizam automaticamente itens com base em seu conteúdo — o recurso principal do Lotus Agenda.
;; Regras de correspondência de texto (defrule urgent-flag :when (str-contains text "URGENT") :assign "priority/high") (defrule meeting-detect :when (or (str-contains text "meeting") (str-contains text "call with")) :assign "work/meetings") ;; Regex com extração de data (defrule date-extract :when (str-matches text "\\b(\\d{4}-\\d{2}-\\d{2})\\b") :action (item-set id :when (match 1))) ;; Aplicar regras (apply-rules) ; aplicar em lote a todos os itens (apply-rules 42) ; aplicar ao item #42 ;; Auto-aplicar em cada add-item (auto-categorize true)
| Função | Descrição |
|---|---|
(rules) | Lista todas as regras definidas |
(drop-rule name) | Exclui uma regra |
(auto-categorize bool) | Alterna auto-aplicação na inserção |
text, notes, categories, todas as propriedades do item, além de auxiliares como has-category e overdue?. Combine com and/or/not.
Visualizações são consultas salvas que filtram, ordenam e agrupam itens dinamicamente.
(defview work-board :source items :filter (has-category "work") :group-by category :sort-by when) (defview urgent :source items :filter (= priority "1") :sort-by when) (defview inbox :source items :filter (= (length categories) 0)) ;; Mostrar uma visualização (show work-board) (show urgent)
| Função | Descrição |
|---|---|
(views) | Lista todas as visualizações definidas |
(drop-view name) | Exclui uma visualização |
;; Itens para uma data específica (items-on "2026-02-24") ;; Itens em um intervalo de datas (items-between "2026-02-24" "2026-02-28") ;; Usando auxiliares de data (items-on (today)) (items-between (today) (date-add (today) 7 :days))
O comando add analisa linguagem natural para extrair datas, prioridades e pessoas automaticamente.
(add "Meet Alice tomorrow for coffee !!") ; → :when = tomorrow, :priority 2, :who "Alice" (add "Call Bob next Monday about the project") ; → :when = next Monday, :who "Bob" (add "URGENT fix server crash") ; → :priority 1 ;; Visualizar sem criar (smart-parse "email Sarah March 15 about renewal !!") ; → {:text "email Sarah about renewal" :when "2026-03-15" :priority 2 :who ("Sarah")}
tomorrow/today/yesterday, next Monday, this weekend, in 3 days, end of week/month, March 15URGENT/ASAP, !!!/!!/!, high/low priority@name, with/for/from Name, call/email/meet Name;; Intervalos integrados (add-item "Team standup" :when (today) :recur :daily) (add-item "Weekly review" :when (today) :recur :weekly) (add-item "Monthly report" :when (today) :recur :monthly) ;; Intervalo personalizado (add-item "Check filters" :when (today) :recur (every 3 :months)) ;; Quando você marca como concluído, a próxima ocorrência é criada automaticamente (item-done 1) ; cria a próxima recorrência automaticamente
;; Definir um modelo reutilizável de item (deftemplate weekly-review :text "Weekly review" :category "work" :priority 2 :recur :weekly) ;; Criar a partir do modelo com substituições (from-template weekly-review :when "2026-03-01") ;; Gerenciar modelos (templates) ; listar todos (drop-template weekly-review) ; excluir
Abra, alterne entre e gerencie múltiplos bancos de dados de agenda. Útil para separar agendas de trabalho e pessoais.
;; Abrir uma nova agenda (open-agenda "work.db") (open-agenda "personal.db") ;; Alternar entre agendas (use-agenda "work") ;; Listar todas as agendas abertas (agendas) ; mostra marcador ativo (*) ;; Fechar uma agenda (close-agenda "personal")
;; Exportar para backup ou migração (export-agenda "work" :format :json :path "work-backup.json") ;; Importar de uma exportação anterior (import-agenda "work-backup.json")
A interface gráfica do EEditor se integra com o EELisp através do método eval() do interpretador. Todos os dados fluem através de expressões EELisp — a GUI nunca acessa o SQLite diretamente.
┌─────────────────────────┐
│ SwiftUI Views │
│ (Sidebar, Calendar, │
│ Agenda, REPL) │
├─────────────────────────┤
│ ViewModels │
│ (call interpreter.eval)│
├─────────────────────────┤
│ EELisp Interpreter │
│ (builtins, prelude) │
├─────────────────────────┤
│ SQLite Database │
│ (eelisp.db) │
└─────────────────────────┘
(items), (items-on), (items-between) para carregar itens para exibição.(items-between start end) para contar itens da agenda por dia.browse e edit retornam valores .tableView / .formView que o REPL renderiza como componentes SwiftUI.;; 1. Usuário adiciona itens no REPL (add-item "Review PRs" :when (today) :priority 1) ;; 2. Alterna para a barra lateral da Agenda → GUI chama: ;; interpreter.eval("(items-between startKey endKey)") ;; Analisa resultados em structs AgendaDisplayItem ;; 3. Alterna para o Calendário → GUI chama: ;; interpreter.eval("(items-on \"2026-02-23\")") ;; Conta itens por dia para indicadores de ponto