Elmord's Magic Valley

Software, lingüística e rock'n'roll. Sometimes in English.

Managing windows and taking notes from Emacs

2018-02-14 00:02 -0200. Tags: comp, emacs, in-english

EXWM and Org mode are two entirely unrelated pieces of Emacs software. However, by virtue of both running in Emacs, they can be combined in some interesting ways.

EXWM

EXWM is a window manager written in Emacs Lisp. I think this is the craziest thing I've seen written in Emacs Lisp so far, and yet it moves. It basically turns Emacs into a tiling window manager. Your windows become Emacs buffers, and you can manage them with the usual Emacs commands for splitting windows, changing focus, switching buffers, and so on. (I learned about it here.)

As a window manager, I don't think it does anything very interesting compared to other tiling window managers. Its real power comes from being integrated into Emacs. This means I can always use Emacs commands no matter what window I am in (for example, if I want to open a file, I can hit C-x C-f no matter what program currently has focus).

This also means it can be customized and scripted in Emacs Lisp. For example, one thing I did with it is make it display "urgent" windows (those that would usually blink in the taskbar) in my Emacs mode line. So far, that's not very interesting, because with a conventional desktop environment I would already have windows highlighted in the taskbar. But what I have also done is customize it so that some windows are detected as "urgent" even though they don't set the urgency window manager hint. For example, I have windows with titles like (1) Skype (i.e., windows with unread messages) tagged as urgent as well.

Another nice trick you can do with EXWM is send fake keypresses to windows. For example, one thing I did was to make a variant of Emacs' insert-char command (which allows entering characters by their Unicode name or hex codepoint) which can be called from any window, by asking for the character name, putting it into the clipboard, and then sending a fake C-v to the application.

My EXWM config file is here. It has grown a bit complex, and some things are still a bit kludgy/glitchy, but I've been using it for some 3-4 months for now. Take the parts you like from it.

Org-capture

Org is an Emacs mode for managing structured data in plain-text format, though that description doesn't really do justice to the thing. It can manage to-do lists, agendas, handle tables in awesome ways, and many more things. It can also export files to various formats, including Beamer presentations, which I've written about before. I'm still learning how to use it and all of its features, and I'm trying to use it for more things, including blogging. (I wrote some kludgy code to export Org files to blog posts, but I found out afterwards that it would be better to create a new export backend inheriting from the built-in HTML export backend. Still have to learn more about this though.)

One cool feature of Org mode is org-capture, a command for taking notes with little flow interruption from what you are currently doing. Once you have it all configured, you can hit something like C-c c j to create an entry using the journal template. The entry will be pre-filled according to the template, and can include, for example, a link to the place you called the command from. For example, if you call it from a w3m buffer, the new note will contain a link to the web page you were visiting. If you call it from some source code, it will create a link to the place you were in the source code file. Org can recognize a variety of different buffer types, and create links appropriate to the context you called it from. You can easily make it recognize new kinds of context by defining new functions and adding them to org-store-link-functions.

Combining the two things

The most immediately observable advantage of using Org-capture in conjunction with EXWM is that you can call it from anywhere, not just regular Emacs buffers, because now Emacs commands work from any window. No matter whether you are seeing a file or reading something in Firefox, you can just type C-c c j to take a note. I find this really nice.

Another advantage is that because you can add new functions to org-store-link-functions, and all your windows are now Emacs buffers, you can actually make org-capture recognize the context of non-Emacs windows too. This is especially useful for browser windows: you can make the link inserted in the note reflect the page you are visiting. Although I'm not aware of a clean way to extract the current URL from a browser window, you can make do by faking the keypresses of C-l (to select the address bar) followed by C-c (to copy the contents to the clipboard), and then reading the clipboard contents from Emacs. Like this:

;; Grab address from the browser.
(defun elmord-exwm-get-firefox-url ()
  (exwm-input--fake-key ?\C-l)
  (sleep-for 0.05)                      ; Wait a bit for the browser to respond.
  (exwm-input--fake-key ?\C-c)
  (sleep-for 0.05)
  (gui-backend-get-selection 'CLIPBOARD 'STRING))

;; org-store-link functions must either return nil (if they don't recognize
;; the context), or call `org-store-link-props' with the appropriate link
;; properties and return non-nil.

(defun elmord-exwm-org-store-link ()
  (when (and (equal major-mode 'exwm-mode)
             (member exwm-class-name '("Firefox" "Firefox-esr")))
    (org-store-link-props
     :type "http"
     :link (elmord-exwm-get-firefox-url)
     :description exwm-title)))         ; Use window title as link description.

;; Finally, we add the new function to the list of known store-link functions.
(add-to-list 'org-store-link-functions 'elmord-exwm-org-store-link)

I find this really cool.

That's all, folks

I have more things I'd like to write about Emacs, but that's it for now.

2 comentários

Criando apresentações de slides em LaTeX/Beamer usando o Org mode

2015-08-19 00:27 -0300. Tags: comp, editor, emacs, latex

Já pensou em poder escrever seus slides assim:

* Recovering memory safety

- How can we recover memory safety in C programs?
- Traditional solution: add metadata to allow checking
- This has a number of drawbacks:
  - It *changes memory representation* of objects
    - requires recompilation of everything (external libraries, OS syscalls)
  - C pointers can point to any part of an object
    - No simple/cheap way to find metadata from an arbitrary pointer
    - Pointers themselves must carry bounds, \\
      or separate data structure must be looked up
    - Changes representation and/or is expensive
- But there is another way...

E eles ficarem assim?

[Slide produzido pelo backend de exportação para Beamer do Org mode]

Pois isso é possível usando o backend de exportação do Org mode do Emacs para Beamer, um pacote LaTeX para criação de slides.

Ingredientes

Você vai precisar de:

Org mode

Explicar o que é o Org mode é um tanto quanto complicado, porque ele faz uma porção de coisas. Segundo o site do projeto, "Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text system". Se você nunca usou o Emacs, um modo basicamente define um conjunto de funções, keybindings e comportamentos para edição de um certo tipo de arquivo. Por exemplo, existe um c-mode, html-mode, etc. O Org mode é bem mais mágico que isso, mas para o objetivo deste post, o Org mode é basicamente um modo para editar arquivos em um formato de plain-text estruturado (a la Markdown). O Org mode permite exportar esses documentos para diversos formatos usando uma variedade de backends de exportação, entre eles o beamer.

O backend beamer não é carregado por padrão. Você pode configurar quais backends são carregados por padrão executando M-x customize-variable RET org-export-backends RET (i.e., tecle Meta+X (i.e., Alt+X), digite customize-variable (usando TAB para completar, se desejar), dê Enter, digite org-export-backends, e dê Enter novamente). Selecione a checkbox beamer e clique em "Apply and save". Tecle q para sair da janela de Customize.

Para criar um documento, crie um arquivo com a extensão .org (e.g., tecle C-x C-f exemplo.org RET (i.e., tecle Ctrl+X, Ctrl+F, digite o nome do arquivo e dê Enter)). O Emacs deverá entrar no modo Org automaticamente.

Para ter uma idéia do markup utilizado, dê uma olhada no arquivo de exemplo linkado no começo do post. Basicamente:

Exportando o arquivo

Para exportar, tecle C-c C-e. Isso abrirá o "Org Export Dispatcher", um painel com dúzias de opções de exportação. Tecle l ("Export to LaTeX"), e depois P ("As a PDF file (Beamer)"). Alternativamente, você pode selecionar B ao invés de P, o que coloca a saída em LaTeX em um novo buffer, ao invés de gerar o PDF diretamente. Se ocorrer algum erro durante a exportação, você pode ver a saída do pdflatex no buffer *Org PDF LaTeX Output* (você pode ir para o buffer usando o menu "Buffers" na interface gráfics, ou teclando C-x b e digitando o nome do buffer (usando TAB para completar se desejado)).

Resumindo: C-c C-e l P (i.e., Ctrl+C, Ctrl+E, letra L, Shift+P).

Miscelânea

Por padrão, quando um arquivo Org é aberto, ele é mostrado com as seções colapsadas. Use Shift+TAB para expandir (ou re-colapsar) todos os títulos, ou TAB sobre um título para expandir aquele título específico.

Mais informações

Eu sou novo tanto no uso do Org mode quanto do Beamer, então não tenho muito mais o que dizer no momento. Mais informações podem ser encontradas no manual do Org mode dentro do próprio Emacs (C-h i, procure por Org mode) e no site do Org mode.

Customizações na aparência da apresentação são realizadas primariamente incluindo os comandos LaTeX apropriados usando linhas #+LATEX_HEADER. Para mais informações, você pode procurar diretamente por informação sobre o Beamer, ao invés de especificamente sobre o Org Mode.

Se você nunca usou o Emacs, pode querer dar uma olhada no How to Learn Emacs: A Hand-drawn One-pager for Beginners.

3 comentários

Emacs, again

2015-06-05 02:30 -0300. Tags: comp, editor, emacs

No último sábado eu resolvi experimentar usar o Emacs de novo. O plano era ficar usando durante um mês e depois escrever um post relatando a experiência. Porém, como ao longo dos três anos de blog eu observei que em geral quando eu deixo um post para escrever depois eu acabo não escrevendo, em parte porque eu acabo esquecendo o que eu ia escrever, resolvi escrever um post inicial agora. (Além disso, quando eu comecei a escrever esse post eu não estava conseguindo dormir e precisava passar o tempo.)

So far, estou curtindo horrores.

Da primeira vez que eu tentei usar o Emacs, eu larguei de mão em dois ou três dias. Acho que o principal fator de diferença foi que dessa vez eu resolvi usar a versão gráfica do Emacs. Assim, quando eu não consigo fazer alguma coisa pelos comandos de teclado eu posso recorrer ao mouse e get stuff done. Dito isso, como eu não sou exatamente um fã do mouse, na prática eu acabo me motivando a aprender os comandos anyway.

(Um vício bem mais difícil de eu me livrar é usar as setas, Home/End e afins ao invés dos comandos "tradicionais" do Emacs. Right now eu larguei um pano de prato por cima do lado não-alfabético do teclado para ver se me habituo a não usar essas teclas.)

Mas por quê?

Tudo começou porque eu estava meio de saco cheio do Claws Mail, experimentei o Thunderbird e não gostei muito (não lembro mais por quê), e aí lembrei do Gnus e resolvi experimentar. No fim das contas eu consegui resolver o problema que eu estava tendo com o Claws comentando fora um teste no código-fonte e não curti muito o Gnus, mas a essas alturas eu já tinha mexido um bocado no Emacs e ressurgiu o interesse, reforçado pelos seguintes acontecimentos:

E aqui estamos.

Coming from Vim...

Em alguns aspectos, o Emacs pode ser mais "difícil" de usar do que o Vim. Seguem algumas observações nesse sentido.

Enquanto usar o Vim sem nenhuma customização é relativamente ok, usar o Emacs sem nenhuma customização não é uma experiência tão agradável. Desde que eu comecei a usar o Emacs, quase todo dia eu adiciono alguma coisa no meu ~/.emacs, que provavelmente vai continuar crescendo na mesma taxa por um bom tempo. (De certa forma o ponto do editor é ser customizado/reprogramado to death, então eu desconfio que enquanto eu usar o Emacs eu não vou parar de mexer no ~/.emacs; porém, eu espero mexer nele com menos freqüência depois de algum tempo de uso.)

Além disso, embora o Emacs ganhe bonito em flexibilidade, certas configurações simples são mais fáceis de fazer no Vim do que no Emacs. Por exemplo, no Vim define-se um keybinding novo em termos das teclas que teriam que ser pressionadas para realizar o comando desejado. No Emacs, cada tecla é associada a uma função que é executada quando a tecla é pressionada, o que por um lado é bem mais limpo do que a maneira como o Vim faz as coisas (definir uma ação complexa em termos de keypresses pode ser um inferno), mas por outro lado exige que uma função em Emacs Lisp seja definida sempre que se quer associar uma seqüência de comandos a uma tecla.

Dito isso, Emacs Lisp é uma linguagem infinitamente mais agradável de usar do que Vimscript. Além disso, é fácil descobrir qual é o nome da função associada a cada tecla, usando os comandos Ctrl-h k (describe-key) e Ctrl-h c (describe-key-briefly), o que facilita na hora de definir funções novas em termos das funções das teclas existentes.

Além disso, embora eu tenha mudado as cores do editor para texto branco no fundo preto, o restante do esquema de cores se adaptou sozinho, e eu achei o esquema de cores tão bom que nem desativei o syntax highlighting (que normalmente é a primeira coisa que eu faço quando uso o Vim em outro computador). A única exceção foi o AUCTeX, que escolheu umas cores diferentes do resto do editor por alguma razão.

Comandos

Enquanto o Vim possui um modo específico para dar comandos (o Normal mode), o que permite que os comandos sejam teclas simples1, o Emacs possui apenas um "modo" (no sentido Vim da palavra2), e os comandos de edição normalmente são introduzidos por um keystroke envolvendo Control ou Alt (Meta no linguajar emacsístico). Muitos comandos exigem uma seqüência de keystrokes: o comando para abrir um arquivo é Ctrl-x Ctrl-f, por exemplo, e o comando para abrir um arquivo em uma nova janela é Ctrl-x 4 Ctrl-f. Da primeira vez que eu experimentei o Emacs eu achei esses comandos totalmente bizarros e meio que larguei ele de mão por causa disso. Porém, agora que eu resolvi usar o editor de novo com a mente em um modo (heh) mais propenso a aceitar coisas novas (e com a interface gráfica para me salvar nos momentos difíceis), eu tenho me adaptado aos comandos novos relativamente fácil.

Embora seja tentador logo no começo alterar o keymap para usar comandos mais intuitivos, eu resolvi fazer um esforço para aprender os comandos convencionais do editor, e só definir keybindings novas para comandos que eu mesmo criei ou que não têm uma keybinding padrão, for most part. Até agora tem sido relativamente tranqüilo. Se depois de mais tempo de uso eu vir que algum keybinding realmente não me agrada, eu mudo. O mais difícil tem sido lembrar de usar Ctrl-s no Emacs e Ctrl-f no Firefox para procurar texto, e usar Ctrl-f (forward) para avançar um caractere e Ctrl-b (back) para voltar um caractere, e analogamente Meta-f e Meta-b para avançar e voltar uma palavra. Esses aí eu sou capaz de acabar rebindando para Ctrl-. e Ctrl-, ou algo do tipo (ou me conformar em usar as setas mesmo), se não me habituar nas próximas semanas.

O Emacs usa uma notação especial para descrever keystrokes. Basicamente, C-x significa Ctrl-x, M-x significa Meta-x (Alt-x), C-M-x significa Ctrl-Meta-x, RET é o Enter, SPC é o espaço, DEL é o backspace, e seqüências de teclas são escritas separadas por espaço (C-x C-f significa "tecle Ctrl-x, e depois tecle Ctrl-f"). Eu vou usar essa notação no restante do post.

Uma coisa legal do Emacs é que todo comando possui um nome (o nome da função Lisp que o implementa). Mesmo quando não se sabe o atalho de teclado que ativa o comando, é possível dar M-x e digitar o nome do comando (que freqüentemente é relativamente fácil de adivinhar, pois a nomenclatura é mais ou menos consistente; além disso é possível usar TAB para completar os nomes). Se o comando possui um atalho associado, após executar o comando o Emacs mostra uma mensagem como You can run the command `mark-paragraph' with M-h, e assim você aprende a tecla do comando.

Outra coisa que ajuda é que o help do Emacs é muito bom de usar. Todos os comandos de ajuda começam com C-h; C-h ? mostra todas as opções de ajuda. C-h f mostra a documentação de uma função ou comando, C-h k mostra a documentação do comando associado a uma tecla, C-h c mostra o nome do comando associado à tecla, C-h m mostra a documentação do modo atual, C-h r abre o manual do Emacs, entre outros. Como já mencionado, a documentação de uma função vem com um link para o código-fonte, quando disponível (no Debian, é necessário instalar o pacote emacs24-el). O link não é parte do texto da documentação, mas sim uma funcionalidade do próprio Emacs: se você pedir o help de uma função que você mesmo definiu no seu ~/.emacs, o Emacs vai mostrar um link para o ponto da definição no arquivo. (Até as poucas funções definidas em C têm links para a definição no fonte, mas nesse caso o Emacs abre uma janela perguntando o diretório onde se encontra o fonte C do Emacs, que eu não tenho aqui.)

Uma coisa um pouco ruim é que quase todos os keystrokes já têm um comando associado, seja por padrão, seja pelo modo em uso, o que limita as escolhas para novos keybindings que não conflitem com os existentes. Por convenção, o Emacs reserva C-c seguido por uma letra para o usuário, mas C-c seguido por outras coisas são reservados para os modos. Porém, existe um refúgio: a tecla C-z por padrão vem associada ao comando suspend-frame, que suspende o Emacs em modo texto e minimiza a janela no modo gráfico. Eu basicamente não uso esse comando no modo gráfico anyway (e ele também fica acessível via C-x C-z), então o que eu fiz foi rebindar ele como uma "prefix key" e colocar os comandos novos que eu defino sob o C-z (por exemplo, C-z C-z para salvar e fechar o arquivo e C-z d para inserir a data atual). Como C-z é um comando padrão do Emacs, isso tem a vantagem de que basicamente nenhum modo usa essa tecla.

Emacs as a daemon

Enquanto o modo de uso normal do Vim (e editores de texto em geral) é abrir o editor, editar arquivos e fechar, o modo de uso normal do Emacs (e sistemas operacionais em geral) é deixar o editor aberto o tempo inteiro enquanto se está trabalhando, em parte porque o editor tende a acumular estado (arquivos e aplicativos abertos, modos em uso), em parte porque ele demora um pouco mais para carregar do que o Vim (especialmente a versão gráfica, e especialmente se o ~/.emacs faz mil coisas na inicialização). Porém, é possível rodar o Emacs como um daemon, e aí pode-se usar o comando emacsclient para abrir um novo "frame" (janela) do Emacs conectado à sessão já em execução, o que é mais rápido do que iniciar o editor do zero. emacsclient -a "" inicia um daemon automaticamente se já não houver um rodando, e conecta-se a um existente se houver. Além disso, é possível passar as opções -t para rodar no terminal e -c para criar uma nova janela gráfica (por padrão ele abre o arquivo passado na linha de comando em uma janela existente, se houver). É um comando bem útil para setar como o valor da variável de ambiente EDITOR, que programas como git, crontab, etc., usam para determinar o editor a ser usado.

Shell mode

O Emacs possui um "modo shell" (M-x shell), que executa o bash ou afim dentro de um buffer do Emacs, onde os comandos normais de edição do Emacs ficam disponíveis. O modo tem algumas bizarrices (o texto é um buffer normal, o que significa que é possível editar a saída dos comandos que já foram executados, apagar o prompt [update: isso é controlável pela variável comint-prompt-read-only; mais informações no help da variável (C-h v comint-prompt-read-only)], etc.), mas é interessante se você quer realizar o máximo de tarefas possível sem sair do Emacs.

O shell mode toma conta do completion de nomes de arquivos e comandos, mas ele usa a função de completion do Emacs, que por padrão exclui certos tipos de arquivos que normalmente não se tem interesse em abrir num editor de textos (e.g., arquivos .o), o que não faz muito sentido em um shell. A solução que eu encontrei foi adicionar um "hook" (função que roda quando um modo é iniciado) no meu ~/.emacs que anula a lista de extensões a ignorar no buffer do shell.

Outro "gotcha" é que como o buffer usa os comandos normais do Emacs, coisas como Ctrl-C, seta para cima, etc., não têm o comportamento normal do terminal. Os comandos Ctrl-* devem ser precedidos de C-c (e.g., C-c C-c para interromper o processo, C-c C-z para suspender, etc.). Manipulação de histórico é feita através de M-p e M-n (de "previous" e "next", análogo ao C-p e C-n para trocar de linha no buffer).

Como trata-se de um buffer simples, coisas que exigem poderes "gráficos" do terminal, como aplicativos de tela cheia, não funcionam no shell mode. Porém, é possível adicionar suporte a cores no buffer (para coisas como ls --color) rodando a função ansi-color-for-comint-mode-on (seja via M-x, seja no ~/.emacsrc (lembrando de pôr parênteses em volta do comando nesse caso)). Vale ainda notar que o shell mode seta a variável de ambiente TERM para dumb, o que faz com que ls, grep e companhia não usem cores por default. É possível contornar isso alterando o ~/.bashrc para mudar o valor de TERM (para vt100, por exemplo) se a variável INSIDE_EMACS estiver setada, mas aí os programas que usam TERM para decidir se vão operar em modo tela cheia ou não vão incorretamente assumir que podem rodar em tela cheia dentro do shell mode. Não sei se há algum valor de TERM que indique suporte a cores mas não às demais funções gráficas do terminal.

Também existe um "modo terminal" (M-x term), que é um emulador de terminal de verdade (não apenas um buffer com um shell) onde se pode rodar qualquer programa de terminal, mas aí perdem-se os comandos normais do Emacs. Além disso, pelo que eu testei o emulador é pra lá de lento (o alsamixer leva uns três ou quatro segundos para abrir com o processador a 800MHz3).

M-x finish-post RET

Por hoje ficamos por aqui. Eu provavelmente hei de postar mais coisas à medida em que for descobrindo funções novas no editor, e atualizar meu ~/.emacs no GitHub ocasionalmente.

_____

1 Na verdade, faz uns cinco anos que eu uso o Vim com keybindings especiais para não ter que trocar de modo para os comandos de edição mais freqüentes, então eu já usava um editor não-modal for most part, o que significa que de certa forma eu não aproveitava muito das vantagens de usar o Vim.

2 O que o Emacs chama de modos são coisas como o html-mode, latex-mode, c-mode, etc., chamados major modes, que alteram o comportamento do editor (como comandos e syntax highlighting) para facilitar a edição de um certo tipo de arquivo, ou aplicações como o Gnus. Também há os minor modes, que são usados em conjunto com os major modes e se comportam mais ou menos como algumas opções ativadas com :set no Vim.

3 Normalmente eu uso a máquina em modo de economia de energia e só seto o governor do cpufreq para performance quando vou fazer alguma coisa mais pesada, primariamente porque com a freqüência baixa o fan faz menos barulho.

9 comentários

Main menu

Posts recentes

Comentários recentes

Tags

comp (114) prog (51) life (44) unix (32) random (27) lang (27) about (24) mind (22) mundane (21) pldesign (20) in-english (19) lisp (17) web (17) ramble (15) img (13) rant (12) privacy (10) scheme (8) freedom (8) lash (7) music (7) esperanto (7) bash (7) academia (7) home (6) mestrado (6) shell (6) conlang (5) copyright (5) misc (5) worldly (4) book (4) php (4) latex (4) editor (4) politics (4) etymology (3) wrong (3) android (3) film (3) tour-de-scheme (3) kbd (3) c (3) security (3) emacs (3) network (3) poem (2) cook (2) physics (2) comic (2) llvm (2) treta (2) lows (2) audio (1) wm (1) philosophy (1) kindle (1) pointless (1) perl (1)

Elsewhere

Quod vide


Copyright © 2010-2018 Vítor De Araújo
O conteúdo deste blog, a menos que de outra forma especificado, pode ser utilizado segundo os termos da licença Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.

Powered by Blognir.