Um editor nativo e rápido para plataformas Apple — com pré-visualização Markdown, destaque de sintaxe multilinguagem e um REPL Lisp integrado com gerenciamento de informações pessoais inspirado no Lotus Agenda.
v1.1 · Requer macOS Sonoma ou posterior, iOS 17 ou posterior
Um editor completo, organizador e motor de dados — em um único aplicativo nativo.
Coloração em tempo real para mais de 24 linguagens. Cabeçalhos Markdown, negrito, blocos de código e mais — tudo destacado enquanto você digita.
Renderize Markdown em HTML estilizado com modo escuro/claro. Alterne com um atalho ou toque de botão.
Exporte qualquer documento como PDF A4 pronto para impressão. Diálogo de salvamento no macOS, compartilhamento no iOS.
Crie a nota de hoje com um atalho. Arquivos nomeados YYYY-MM-DD.md e abertos instantaneamente.
Gere planejadores semanais estruturados com cabeçalhos de segunda a domingo e blocos de horário Manhã/Tarde/Noite.
Navegue por arquivos por data de modificação em uma grade mensal. Pontos duplos mostram atividade de arquivos (azul) e itens de agenda (laranja). Clique em um dia para ver arquivos e itens agendados.
Pesquise em todos os arquivos com trechos de contexto, números de linha e contagem de correspondências. Alternância de sensibilidade a maiúsculas.
Localizador de arquivos com busca difusa e navegação por teclado. Encontre e abra qualquer arquivo em milissegundos.
Abra múltiplos arquivos como abas. Fixe favoritos para que persistam entre sessões. Feche todos os não fixados de uma vez.
Alterações salvas automaticamente com debounce de 1 segundo. Seu trabalho nunca é perdido.
Interpretador Lisp integrado com banco de dados SQLite. Defina tabelas, consulte dados e navegue registros em formulários interativos estilo dBASE — direto no editor. Abre como painel lateral direito que permanece aberto enquanto você alterna entre arquivos. O histórico de comandos persiste entre sessões.
Gerenciador de informações pessoais inspirado no Lotus Agenda. Adicione itens com linguagem natural, categorize automaticamente com regras, defina visualizações, itens recorrentes, modelos, múltiplas agendas com exportação/importação. O painel lateral da Agenda mostra Atrasados/Hoje/Próximos de relance.
Incorpore blocos de código cercados ```eelisp no Markdown. Pressione ⌘⇧Return para executá-los e ver um bloco ```result aparecer logo após o fechamento. Formulários e tabelas abrem em um painel lateral.
Leia e escreva arquivos, acesse a área de transferência, manipule o cursor, insira texto e consulte o buffer do editor — tudo a partir do EELisp. Suas notas se tornam programáveis.
Construa formulários interativos com campos calculados, seletores dropdown e suporte opcional a banco de dados. Calculadoras, entrada de dados e CRUD — tudo definido em uma única expressão. Execute do editor para abrir como painel lateral, ou no REPL para exibição inline.
SwiftUI para macOS, iOS e iPadOS. Barra de ações rápidas adaptada para toque no mobile.
Destaque de sintaxe em tempo real com regras para palavras-chave, tipos, strings, números, comentários e pré-processador.
Um interpretador Lisp para gerenciamento de dados pessoais — inspirado no dBASE III e Lotus Agenda. Com motor de banco de dados SQLite completo e rastreamento de itens estilo agenda.
;; Definir funções (defn greet (name) (str "Hello, " name "!")) (greet "world") ; → "Hello, world!" ;; Funções de ordem superior (map inc (range 1 6)) ; → (2 3 4 5 6) (filter even? (range 1 11)) ; → (2 4 6 8 10) (reduce + 0 '(1 2 3 4 5)) ; → 15
;; Criar uma tabela (deftable contacts (name:string email:string age:number)) ;; Inserir registros (insert contacts {:name "Alice" :age 30}) (insert contacts {:name "Bob" :age 25}) ;; Consultar com filtros (query contacts :where "age > ?" :params (list 28) :order "name")
;; Visualização em tabela (grade navegável) (browse contacts) ;; Formulário CRUD (editar/salvar/excluir) (edit contacts :where "age > ?" :params (list 25)) ;; Calculadora com campos calculados (defform interest (principal:number rate:number years:number) :computed ((total (* principal (pow (+ 1 (/ rate 100)) years))) (gain (- total principal))))
;; Regras de auto-categorização (defrule urgent-flag :when (str-contains text "URGENT") :assign "priority/high") (defrule errand-detect :when (str-contains text "buy ") :assign "personal/errands") ;; Aplicar regras automaticamente ao inserir (auto-categorize true) ;; Itens são categorizados automaticamente! (add-item "URGENT: Deploy hotfix") ;; → priority/high atribuído (add-item "Buy groceries") ;; → personal/errands atribuído
;; Definir visualizações salvas (defview work-board :source items :filter (has-category "work") :group-by category :sort-by when) (defview urgent :source items :filter (= priority "1")) (defview overdue :source items :filter (overdue?)) ;; Mostrar uma visualização (show work-board) ;; → ▸ work/meetings (2) ;; Team standup ;; Call with client ;; ▸ work/projects (3) ;; Deploy v2.1 ;; Finish report
;; Criação de itens em linguagem natural (add "Meet Alice tomorrow !!") ;; → data, prioridade, pessoa extraídos (add "Call Bob next Monday") ;; → :when = próxima segunda, :who Bob ;; Pré-visualizar extração (smart-parse "URGENT deploy end of month") ;; → {:text "deploy" :when "..." ;; :priority 1} ;; Builtins JSON e HTTP (json-parse "{\"a\": 1}") ;; → {:a 1} (http-get "https://api.example.com/data") ;; → {:status 200 :body "..."}
;; Incorpore no Markdown, execute com ⌘⇧Return ```eelisp (add-item (smart-parse "tomorrow review report !!")) ``` ```result Added item #42 ``` ;; Cálculos inline nas suas notas ```eelisp (* 24 365) ``` ```result 8760 ```
;; Ler/escrever arquivos no seu workspace (write-file "todo.txt" (str "Generated: " (today))) (read-file "notes.md") ;; Interagir com o editor (insert-at (cursor-pos) (str "Updated: " (today))) (def sel (selection)) ;; Acesso à área de transferência (clipboard-set "copied!") (clipboard-get)
;; Campos de escolha (seletores dropdown) (defform new-task (title:string (priority:choice "low" "medium" "high") (status:choice "todo" "in-progress" "done") notes:memo)) ;; Formulário com tabela e CRUD (defform project-editor (name:string (status:choice "active" "done") budget:number) :source projects)
Cada ação está a um atalho de distância. Todos os atalhos também são mostrados na sobreposição de ajuda do aplicativo.
Tudo o que você precisa saber para aproveitar ao máximo o EEditor.
Ao iniciar o EEditor pela primeira vez, você verá um editor vazio com uma barra lateral. Para começar a trabalhar:
O EEditor oferece um ambiente de escrita livre de distrações com destaque de sintaxe em tempo real.
YYYY-MM-DD HH:mm) na posição do cursor.A barra lateral mostra uma visualização hierárquica da sua pasta. Diretórios são classificados primeiro, depois arquivos em ordem alfabética.
subpasta/arquivo.md para criar arquivos aninhados.A barra lateral tem três modos acessíveis pelo controle segmentado no topo: Arquivos (árvore de arquivos), Calendário (veja a seção 8) e Agenda (veja a seção 8b).
Cada arquivo que você abre aparece como uma aba no topo da área do editor.
Busca em texto completo (⌘⇧F) pesquisa em todos os arquivos do seu workspace:
Abertura Rápida (⌘P) é um localizador de arquivos com busca difusa:
Wiki-links (⌘O): posicione o cursor em um link [[nomedoarquivo]] e pressione ⌘O para abrir o arquivo diretamente. Se nenhum wiki-link for detectado, o diálogo padrão de Abrir Pasta aparece.
Pré-visualização Markdown (⌘⇧P) renderiza seu documento como HTML estilizado:
Exportação PDF (⌘⇧E) gera um documento pronto para impressão:
Nota diária (⌘D):
YYYY-MM-DD.md (ex.: 2026-02-19.md) na sua pasta raiz.# 2026-02-19.Planejador semanal (⌘⇧W):
YYYY-WEEK-WW.md (ex.: 2026-WEEK-08.md) usando numeração de semana ISO 8601.# Week 08 — 2026 ## Monday ### Morning - ### Afternoon - ### Evening - ## Tuesday ...through Sunday
Alterne a barra lateral para o modo Calendário usando o controle segmentado (ícones de pasta / calendário / agenda) no topo da barra lateral.
Alterne a barra lateral para o modo Agenda usando o ícone de prancheta no controle segmentado. O painel da agenda oferece uma visualização rápida da sua programação:
:when anterior a hoje, mostrados com cabeçalho de seção vermelho.(items), (items-on) e (items-between) por trás dos panos. Adicione itens no REPL, depois alterne para a aba Agenda para vê-los organizados por tempo.
O EEditor inclui um interpretador Lisp integrado chamado EELisp — projetado para gerenciamento de dados pessoais.
Abrindo o REPL:
Usando o REPL:
> e pressione ⌘Return para avaliá-la... e aguarda mais entrada. Uma barra de dica mostra ⌘↩ para executar · ⎋ para cancelar.Comportamento da barra lateral:
Comandos de banco de dados:
O EELisp inclui comandos integrados para gerenciamento de banco de dados:
(tables) — listar todas as tabelas no banco de dados atual(describe nomedatabela) — mostrar o esquema de uma tabela(drop-table nomedatabela) — excluir uma tabela:db — mostrar o caminho do banco de dados atual:db <caminho> — alternar para um arquivo de banco de dados diferente:db new <nome> — criar um novo arquivo de banco de dados na pasta atual:db memory — alternar para um banco de dados em memóriaExecutando blocos EELisp no editor:
```eelisp em qualquer arquivo Markdown.edit, defform) ou tabela (browse), ele abre como um painel lateral interativo ao lado do editor.O REPL inclui um motor de banco de dados SQLite. Por padrão, ele usa um banco de dados em memória. Quando você abre uma pasta contendo um arquivo eelisp.db, o REPL se conecta automaticamente a ele para armazenamento persistente (veja Gerenciamento de Banco de Dados). Nomes de tabelas e definições de campos são escritos como símbolos puros (sem necessidade de aspas).
Definir uma tabela:
(deftable tasks (title:string priority:number done:bool due:date))
Tipos de campo: string, number, bool, date, memo.
Inserir registros:
(insert tasks {:title "Write docs" :priority 1 :done false})
Consultar registros:
;; Todos os registros (query tasks) ;; Com filtros (query tasks :where "priority <= ?" :params (list 2)) ;; Ordenados, limitados (query tasks :order "priority" :limit 5) ;; Selecionar colunas específicas (query tasks :select "title, done")
Os resultados das consultas são exibidos como tabelas ASCII formatadas.
Formulários interativos (browse):
;; Abrir um formulário para navegar, editar e gerenciar registros (browse tasks) ;; Navegar com filtros e ordenação (browse tasks :where "done = ?" :params (list false) :order "priority")
O formulário mostra um registro por vez com navegação Anterior/Próximo, edição inline, botões Salvar, Novo e Excluir.
Atualizar e excluir:
;; Atualizar registro por ID (update tasks 1 {:done true}) ;; Exclusão suave (estilo dBASE) (delete tasks 1) ;; Purgar registros excluídos suavemente (pack tasks)
Outros comandos:
| Comando | Descrição |
|---|---|
(tables) | Listar todos os nomes de tabelas |
(describe tasks) | Mostrar esquema da tabela |
(count-records tasks) | Contar registros (com :where opcional) |
(drop-table tasks) | Excluir uma tabela |
(field-get record :name) | Obter um campo de um registro |
(record-id record) | Obter o ID do registro |
(records result-set) | Extrair lista de registros dos resultados da consulta |
(browse table) | Abrir visualização de tabela/grade navegável |
(edit table) | Abrir formulário CRUD interativo |
(defform name (fields) :computed ...) | Criar formulário calculadora com campos calculados |
O EELisp suporta bancos de dados SQLite tanto em memória quanto persistentes.
Conexão automática:
eelisp.db existir na raiz, o REPL se conecta automaticamente a ele.deftable e insert são persistidos no disco.Comandos de banco de dados do REPL:
| Comando | Descrição |
|---|---|
:db | Mostrar o caminho do banco de dados atual |
:db <caminho> | Alternar para um arquivo de banco de dados diferente |
:db new <nome> | Criar um novo arquivo de banco de dados na pasta atual |
:db memory | Alternar para um banco de dados em memória |
:db meudados.db em vez de digitar o caminho completo.
O EELisp inclui um gerenciador de informações pessoais inspirado no Lotus Agenda. Adicione itens de forma livre, categorize automaticamente com regras, defina visualizações dinâmicas, organize com categorias hierárquicas e consulte com filtros — tudo armazenado em SQLite.
Adicionando itens:
;; Texto primeiro — apenas digite o que está em mente (add-item "Finish quarterly report for Sarah") ;; Com metadados (add-item "Call dentist" :when "2026-03-01" :priority 2) (add-item "Buy groceries" :category "personal" :notes "milk, eggs, bread")
Consultando itens:
;; Navegar todos os itens (tabela interativa) (items) ;; Filtrar por categoria, texto, prioridade ou data (items :category "work") (items :search "quarterly") (items :priority 1) (items :when-before "2026-03-01")
Gerenciando itens:
| Comando | Descrição |
|---|---|
(add-item text :when :priority :category :notes) | Criar um novo item |
(items :category :search :priority :when-before :when-after) | Consultar itens com filtros (visualização em tabela) |
(item-get id) | Buscar um único item por ID |
(item-edit id) | Abrir item em formulário para edição |
(item-set id :field val ...) | Atualizar propriedades do item |
(item-done id) | Marcar item como concluído (exclusão suave) |
(item-count :category cat) | Contar itens com filtro opcional |
Categorias:
As categorias são hierárquicas (use separadores /) e podem ser mutuamente exclusivas:
;; Categorias hierárquicas (defcategory work) (defcategory work/projects) (defcategory work/meetings) (defcategory personal) (defcategory personal/errands) ;; Categorias exclusivas (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 a árvore de categorias (categories)
:exclusive true, atribuir um filho (ex.: priority/low) remove automaticamente os irmãos (ex.: priority/high). Isso é ótimo para status, prioridade ou qualquer agrupamento de escolha única.
Regras de Auto-Categorização:
Defina regras que categorizam automaticamente os itens com base no conteúdo — a magia 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") ;; Extração de data via regex (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-categorize true) ;; auto-aplicar em cada add-item
Gerenciamento de regras:
| Comando | Descrição |
|---|---|
(defrule name :when cond :assign cat) | Definir uma regra de categorização |
(defrule name :when cond :action expr) | Definir uma regra com ação personalizada |
(apply-rules) | Aplicar todas as regras a todos os itens |
(apply-rules id) | Aplicar todas as regras a um item específico |
(auto-categorize true/false) | Alternar auto-aplicação na inserção |
(rules) | Listar todas as regras definidas |
(drop-rule name) | Excluir uma regra |
str-contains para correspondência de texto simples, str-matches para padrões regex, has-category para verificar categorias existentes e (get :property) para testar propriedades de itens. Combine com and/or/not para lógica complexa.
Visualizações — Perspectivas Dinâmicas:
Defina consultas salvas que filtram, ordenam e agrupam itens. Mostre uma visualização a qualquer momento para ver os itens correspondentes mais recentes:
;; Definir visualizações com expressões de filtro (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) ;; → agrupado por categoria com contagem de itens (show urgent) ;; → itens filtrados e ordenados
Gerenciamento de visualizações:
| Comando | Descrição |
|---|---|
(defview name :source :filter :group-by :sort-by) | Definir uma visualização salva com expressão de filtro |
(show view-name) | Exibir itens correspondentes de uma visualização |
(views) | Listar todas as visualizações definidas |
(drop-view name) | Excluir uma visualização |
Auxiliares de data:
| Comando | Descrição |
|---|---|
(today) | Retorna a data de hoje como string ISO (ex.: "2026-02-21") |
(date-add date n :days/:weeks/:months) | Adicionar dias, semanas ou meses a uma data |
(date-diff date1 date2) | Diferença em dias entre duas datas |
text, notes, categories, todas as propriedades, além dos auxiliares has-category e overdue?. Itens com propriedades ausentes são silenciosamente excluídos, não geram erros.
Integração com Calendário:
Visualize itens por data e adicione itens rapidamente para hoje:
;; Ver itens para uma data específica (items-on "2026-02-24") ;; Ver itens em um intervalo de datas (items-between "2026-02-24" "2026-02-28") ;; Adicionar rapidamente com data de hoje preenchida (add-item-today "Review pull requests" :priority 1) (add-item-today "Quick grocery run" :notes "milk, bread") ;; Combinar com auxiliares de data (items-on (today)) (items-between (today) (date-add (today) 7 :days))
| Comando | Descrição |
|---|---|
(items-on "date") | Mostrar itens agendados para uma data específica |
(items-between "start" "end") | Mostrar itens em um intervalo de datas (inclusivo) |
(add-item-today text :priority :category :notes) | Adicionar item com data de hoje preenchida automaticamente |
Entrada Inteligente:
O comando add analisa linguagem natural para extrair datas, prioridades e pessoas automaticamente:
;; Criação de itens em linguagem natural (add "Meet Alice tomorrow for coffee !!") ;; → Item com :when = amanhã, :priority 2, :who "Alice" (add "Call Bob next Monday about the project") ;; → Item com :when = próxima segunda, :who "Bob" (add "URGENT fix server crash") ;; → Item com :priority 1 ;; Pré-visualizar sem criar um item (smart-parse "email Sarah March 15 about renewal !!") ;; → {:text "email Sarah about renewal" :when "2026-03-15" :priority 2 :who ("Sarah")}
| Comando | Descrição |
|---|---|
(add "text") | Adição inteligente: analisa linguagem natural, extrai metadados, cria item |
(smart-parse "text") | Pré-visualizar extração sem criar um item |
tomorrow/today/yesterday, next Monday, this weekend, in 3 days, end of week/month, March 15. Prioridade: URGENT/ASAP, !!!/!!/!, high/low priority. Pessoas: @name, with/for/from Name, call/email/meet Name.
HTTP e JSON:
Cliente HTTP genérico e builtins JSON para integração com APIs:
| Comando | Descrição |
|---|---|
(http-get url) | Requisição GET, retorna {:status N :body "..."} |
(http-post url body :content-type "...") | Requisição POST com corpo |
(json-parse string) | Analisar string JSON para dict/list EELisp |
(json-stringify value) | Converter valor EELisp para string JSON |
Itens Recorrentes e Modelos:
Itens com padrões de recorrência criam automaticamente a próxima ocorrência quando marcados como concluídos. Modelos definem blueprints reutilizáveis de itens:
| Comando | Descrição |
|---|---|
(add-item text :recur :weekly) | Criar um item recorrente (:daily, :weekly, :monthly) |
(every N :unit) | Intervalo personalizado, ex.: (every 3 :months) |
(item-done id) | Marcar como concluído; cria próximo automaticamente se recorrente |
(deftemplate name :text "..." :category "..." :priority N) | Definir um modelo reutilizável de item |
(from-template name :when "..." ...) | Criar item a partir de modelo com substituições |
(templates) | Listar todos os modelos definidos |
(drop-template name) | Remover um modelo |
Múltiplas Agendas:
Abra, alterne entre e gerencie múltiplos bancos de dados de agenda. Exporte e importe para backup ou migração:
| Comando | Descrição |
|---|---|
(open-agenda "path/to/file.db") | Abrir um novo banco de dados de agenda e alternar para ele |
(use-agenda name) | Alternar para uma agenda já aberta |
(agendas) | Listar todas as agendas abertas com marcador ativo |
(close-agenda name) | Fechar e remover uma agenda do registro |
(export-agenda name :format :json :path "file.json") | Exportar todas as tabelas da agenda para JSON |
(import-agenda "file.json") | Importar registros de uma exportação JSON |
Variáveis e funções:
(def x 42) (defn square (x) (* x x)) (square 5) ; → 25 ;; Funções anônimas (map (fn (x) (* x x)) '(1 2 3)) ; → (1 4 9) ;; Parâmetros rest (defn sum (first . rest) (reduce + first rest))
Condicionais e loops:
(if (> x 0) "positive" "non-positive") (cond (< x 0) "negative" (= x 0) "zero" else "positive") (let ((x 1) (y 2)) (+ x y)) ; → 3 ;; Loop com estilo named-let (loop ((i 0) (acc 0)) (> i 10) (recur (+ i 1) (+ acc i))) ; → 55
Strings:
(str "hello" ", " "world") ; → "hello, world" (str-split "a,b,c" ",") ; → ("a" "b" "c") (str-join '("a" "b" "c") "-") ; → "a-b-c" (str-upper "hello") ; → "HELLO"
Listas:
(list 1 2 3) ; → (1 2 3) (cons 0 '(1 2)) ; → (0 1 2) (map inc (range 1 6)) ; → (2 3 4 5 6) (filter even? (range 1 11)) ; → (2 4 6 8 10) (reduce + 0 '(1 2 3 4 5)) ; → 15 (sort-by id '(3 1 4 1 5)) ; → (1 1 3 4 5)
Dicionários:
(def d {:name "Alice" :age 30})
(dict-get d :name) ; → "Alice"
(dict-set d :age 31) ; → {:name "Alice" :age 31}
(dict-keys d) ; → (:name :age)
Funções do prelúdio:
| Função | Descrição |
|---|---|
inc / dec | Incrementar / decrementar por 1 |
even? / odd? | Verificações de paridade |
zero? / pos? / neg? | Verificações de sinal |
first / second / third / last | Acesso a listas |
take / drop | Pegar/descartar os primeiros n elementos |
some? / every? | Algum/todos correspondem ao predicado |
pipe | Macro de encadeamento: (pipe 5 inc inc square) |
compose | Composição de funções |
partial | Aplicação parcial |
query, deftable, defn) e um botão de limpar.