Atom es un editor de texto open source, multiplataforma, modular y hackeable creado en HTML, CSS (Less) y JavaScript (CoffeeScript, Node.js). Diseñado por Github utilizando el Framework Electron y desarrollado sobre el Chromium Engine .
Atom, el editor de texto hackeable del siglo 21.
Mientras que Sublime y TextMate son practicos, su extensibilidad es limitada. Por otro lado Emacs y Vim son flexibles pero dificiles de aprender, Atom pretende encontrar un punto de equilibrio entre conveniencia y extensibilidad.
Para instalar en Windows se descarga AtomSetup.exe desde el sitio principal o desde su repositorio en Github. El instalador añade los comandos atom
y apm
al PATH
del entorno. En este caso Atom es el programa principal y Apm es el administrador de paquetes (Atom Package Manager).
Aplication Folder: %LOCALAPPDATA%\atom
Configuration Folder: %USERPROFILE%\.atom
Dev Source and Config: %USERPROFILE%/github/atom
Cache Folder: %APPDATA%\Atom
Registro: HKEY_CLASSES_ROOT\Directory\Background\shell
Registro: HKEY_CLASSES_ROOT\Directory\shell
Registro: HKEY_CLASSES_ROOT*\shell
Para usar el programa de forma portable se extraen los contenidos de atom-windows.zip
en la carpeta deseada y agregando un directorio denominado .atom
. La variable ATOM_HOME
es la encargada de guardar la ubicación de dicho directorio, por defecto en %USERPROFILE%
. Tambien se recomienda agregar el switch --portable
al ejecutable.
Si se desea instalar desde el código fuente se necesita Node, Python, Visual Studio con Visual C++ y Windows SDK. Se recomienda que la variable GYP_MSVS_VERSION
corresponda a la versión de Visual Studio.
cd C:\
git clone https://github.com/atom/atom.git
cd atom
script\build --create-windows-installer
El ultimo comando genera los mismos instaladores que en el sitio principal. La carpeta Bin del código fuente debe ser agregada al PATH
para poder utilizar atm
correctamente. Comandos del script “build”:
${dir}\Atom\app-dev
en donde Div es por defecto %LOCALAPPDATA%
.En caso de que el firewall produsca errores de instalación SSL, utilizar el comando apm config set strict-ssl false
. En el caso de que el proxy produzca errores de HTTPS, utilizar el comando apm config set https-proxy (Proxy Adress)
. Se puede comprobar la correcta configuración del proxy con apm config get https-proxy
.
Los paquetes se pueden instalar de forma manual clonando su repositorio a la carpeta %USERPROFILE%\.atom
y en algunos casos ejecutando el comando atm install
. Para utilizar el buscador de simbolos en todo el proyecto se debe instalar la utilidad Ctags y configurar el archivo en la carpeta %USERPROILE%\.ctags
.
Los Snippets son una herramienta que nos permite aumentar la productividad al autocompletar lo que escribimos con la tecla Tab
. Podemos definir nuestros propios Snippets dentro de snippets.cson
.
Primero se define el Scope del lenguaje (Editor: Log Cursor Scope
), despues su nombre, descripcion, prefijo y contenido. La posicion del cursor se puede personalizar con el uso numerado de $1
o $(1: texto )
.
Si el contenido es multilinea se encierra en triples comillas mientras que los caracteres especiales se escapan con dobles diagonales. Para ver los snippets definidos en el Scope actual se ejecuta Snippets: Available
.
'.source.js':
'console.log':
'prefix': 'log'
'body': 'console.log(${1:"string"});$2'
Los Keybinds nos permiten vincular una secuencia de teclas con un selector CSS y un comando predefinido atom.commands
. El modulo encargado de resolver cual es el Keybind más importante para cada circunstancia es el keybinding-resolver
accesible desde Ctrl+.
. Se pueden agregar Keybindings personalizados al archivo keymap.cson
en la carpeta de configuraciones.
Cuando el usuario presiona una secuencia de teclas, el engine la detecta y las envia al Keymap Module en forma de un evento JS. El modulo se encarga de subir al evento por el DOM (Bubbling) comenzando por el elemento activo e intentando encontrar una coincidencia con el selector CSS. De encontrarla, termina la busqueda y se aplica el comando correspondiente al elemento. Si multiples elementos coinciden se utiliza al Keybinding Resolver para elegir al elemento con el selector más especifico.
Si se desea ejecutar dos o mas comandos aplicando un solo Keybind es necesario encapsularlos en un solo comando. Si por ejemplo quisieramos combinar los comandos de seleccionar linea y cortar en un solo Keybind escribiriamos:
atom.commands.add 'atom-text-editor', 'custom:cut-line', ->
editor = atom.workspace.getActiveTextEditor()
editor.selectLinesContainingCursors()
editor.cutSelectedText()
Para utilziar el nuevo comando de atom.commands
necesitamos agragarlo al archivo keymap.cson
:
'atom-text-editor':
'alt-cmd-z': 'custom:cut-line'
Si se agrega el keybinding unset!
a una secuencia de letras, el modulo ignorara las coincidencias de dicho nivel. Si se agrega el keybinding abort!
el modulo dejara de buscar en el resto del DOM. Si algun keybinding se interpone con el funcionamiento de algun paquete se puede agregar el keybind native!
o la clase .native-key-bindings
.
Si Atom tiene problemas con el layout de tu teclado puedes definir explicitamente las teclas que presionas y el resultado que esperas:
#Decir que Alt + Ctrl + Q signfica explicitamente Ctrl + @;
atom.keymaps.addKeystrokeResolver ({event}) ->
if event.code is 'KeyQ' and event.altKey and event.ctrlKey and event.type isnt 'keyup'
return 'ctrl-@'
Si queremos agregar comandos o funciones a Atom simplemente las escribimos dentro del Script init.coffee
, este archivo se ejecuta al inicio del programa. Por ejemplo:
# Comando para convertir el texto seleccionado y un URI del clipboard en un link de Markdown.
atom.commands.add 'atom-text-editor', 'markdown:paste-as-link', ->
return unless editor = atom.workspace.getActiveTextEditor()
selection = editor.getLastSelection()
clipboardText = atom.clipboard.read()
selection.insertText("[#{selection.getText()}](#{clipboardText})")
En el caso de que se agregen multiples comandos y una interfaz grafica es recomendable agruparlos dentro de un paquete. Para crear un paquete se utiliza el comando Generate Package
. El nuevo paquete se guardara dentro de %USERPROFILE%\.atom\packages
y estara constituido por carpetas de keymaps, lib, menus, spec, styles y un package.json
.
El archivo JSON contiene el metadata del paquete, por ejemplo:
{
"name": "Nombre del Paquete",
"main": "Directorio del Paquete",
"version": "1.0.0",
"description": "Descripcion del Paquete",
"keywords": [
"PrimerKeyword",
"SegundoKeyword",
],
"repository": "URI del repositorio en Github",
"license": "Licencia como MIT",
"engines": {
"atom": ">=1.0.0 <2.0.0"
},
"dependencies": {
"NombrePaquete": "^15.6.1",
},
"devDependencies": {
"NombrePaqueteParaDev": "^3.0.1",
}
"consumedServices": {
"NombreOtroPaquete": {
"versions": {
"^1.0.0": "ServicioAConsumir"
}
}
},
"providedServices": {
"NombreEstePaquete": {
"versions": {
"1.0.0": "ServicioAProveer"
}
}
},
"activationHooks": [
"core:loaded-shell-environment",
"language-javascript:grammar-used"
],
"activationCommands": {
"atom-workspace": [
"NombrePaquete:NombreComandoUno",
"NombrePaquete:NombreComandoDos"
]
},
"configSchema": {
"NombreDeConfiguracion": {
"type": "JS DataType",
"default": ValorPorDefecto,
"title": "Titulo de la Configuracion",
"description": "Que efecto tiene este valor en el paquete"
}
}
}
El modulo principal es generalmente un archivo [PackageName].coffee
dentro de la carpeta lib
, siendo el punto de entrada del modulo y el encargado de la logica principal. De requerir una interfaz grafica esta se divide en otro archivo denominado [PackageName]-view.coffee
. El modulo principal tiene acceso a los siguientes metodos:
Los activationCommands
y activationHooks
activan el paquete y ejecutan el metodo activate()
dentro del modulo principal. El primero define comandos, el segundo grammars o cuando termine de cargar el environment. Si no se define ninguno entonces activate()
sera ejecutado tan pronto termine de cargar el paquete.
Algunas veces los paquetes necesitan utilizar componentes o funciones de otros paquetes. Para tomar prestadas estas funciones se recomienda que interactuen utilizando el API de servicios. El uso de servicios le permite a los paquetes cambiar su implementacion entre versiones (version semantica) pero manteniendo una interfaz consistente desde la cual otros paquetes pueden tomar prestada su funcionalidad.
Para ofrecer un servicio se agrega la siguiente logica al paquete de origen:
module.exports =
activate: -> # ...
provideMyServiceV1: ->
adaptToLegacyAPI(myService)
provideMyServiceV2: ->
myService
Para usar un servicio se utiliza la siguiente logica en el paquete final:
{Disposable} = require 'atom'
module.exports =
activate: -> # ...
consumeAnotherServiceV1: (service) ->
useService( adaptServiceFromLegacyAPI(service) )
new Disposable -> stopUsingService(service)
consumeAnotherServiceV2: (service) ->
useService(service)
new Disposable -> stopUsingService(service)
Para mayor informacion sobre la creacion de paquetes:
Los paquetes de Atom realizan sus Tests mediante el Jasmine Framework. Para ello se necesita leer la Documentacion.
describe "when the user presses the A key", ->
it "writes the letter A in the editor", ->
expect("A").toEqual("A")
expect("A").not.toEqual("B")
El keyword describe
toma dos argumentos, un string y una funcion. Si el String describe un comportamiento inicial comienza con when
, si describe un Unit Test comienza con el nombre del metodo. Luego el keyword it
tambien toma un string y una funcion. El String describe el comportamiento esperado a causa del comportamiento inicial o del metodo.
Finalmente el Matcher expect
describe las pruebas concretas sobre los resultados. Otros matchers son: toBeInstanceOf
, toHaveLength
, toExistOnDisk
, toHaveFocus
y toShow
; implementados por spec-helper.coffee. Todas estas pruebas se realizan de forma sincrona. Si se requiere de pruebas asincronas es recomendable el uso de promises.
Una vez que los specs fueron definidos se pueden ejecutar automaticamente con el comando Window: Run Package Specs
. Tambien se recomienda ejecutar Deprecation Cop
para encontrar incopatibilidad con el API más reciente.
Por defecto Atom crea nuevos archivos Plain Text
con la extencion txt
. Si queremos cambiar el tipo de archivo que crea por defecto, por ejemplo a javascript, agregamos el siguiente codigo al init.coffee
:
# Al abrir un archivo capturar el objeto (editor) y obtener su gramatica.
# Si y solo si la gramatica es igual a la que tiene atom por defecto (text.plan.null).
# Entonces cambiar la gramatica del archivo por la que queramos.
atom.workspace.observeTextEditors (editor) ->
original = editor.getGrammar()
if original? and original is atom.grammars.grammarForScopeName('text.plain.null-grammar')
editor.setGrammar(atom.grammars.grammarForScopeName('source.js'))
Todos los componentes de Atom, incluido el Core, guardan variables importantes que modifican su comportamiento dentro de archivos de configuracion. Los valores de Core estan declarados dentro de este archivo y modifica los dos namespaces globales admitidos: core
y editor
.
En el mismo nivel que los valores globales se pueden agregar scopes por lenguaje como .python.source
o .html.text
, seguida de las modificaciones que se quieran realizar a core
y editor
. Por ser más especificas estas tienen prioridad sobre las globales en *
.
Los paquetes pueden definir sus propios valores de configuracion dentro de su package.json
. Por ejemplo Autocomplete define sus opciones de configuracion como parte de su configSchema
en este archivo. Si se quieren agregar u obtener los valores se utiliza el Config API que define las funciones atom.config.get
y atom.config.set
.
Si queremos modificar los estilos de Atom simplemente los escribimos dentro del archivo styles.less
, este archivo se ejecuta al inicio del programa. Por ejemplo:
atom-text-editor .syntax--link,.syntax--hyperlink {
color: #c678dd;
text-decoration: underline;
}
Si se agregan demaciados estilos se recomienda agruparlos dentro de un paquete. Los paquetes que modifican estilos se dividen en modificadores de UI (Para los componentes de Atom) y modificadores de Syntax (Solo para el texto).
Para generar un paquete de Syntax se utiliza el comando Generate Syntax Theme
. El archivo package.json
debera contener una llave theme
con el valor ui
o syntax
. Para modificar los selectores del theme editamos el archivo base.less
, mientras que la paleta de colores se encuentra en colors.less
.
En el caso de generar un paquete UI es necesario copiar el repositorio de ejemplo y abrirlo con atom --dev
. Una vez abierto podemos vincularlo al ambiente para desarrolladores atom link --dev
, esto aplicara los cambios instantaneamente. Finalmente abrir el Styleguide con Styleguide: Show
para observar rapidamente todos los elementos UI.
Todos los Theme de UI deben de proporcionar forzozamente dos archivos con los valores que utilizaran el resto de los paquetes para adaptarse al theme: ui-variables.less y syntax-variables.less.
Todos los paquetes deben tener acceso a los valores de estos archivos, ya que deberan utilizarlos para coincidir con el estilo del Theme:
@import "ui-variables";
@import "syntax-variables";
.miSelector {
background-color: @base-background-color;
padding: @component-padding;
}
.miOtroSelector {
background-color: @syntax-background-color;
}
Nota: No se recomienda cambiar el font-family
ya que este es un setting por defecto dentro de Core. Si es necesario puedes recomendar una fuente preferida en tu archivo readme.md
.
atom --safe
.atom --clear-window-state
.Utilizar atom --safe
evita que se cargen paquetes de %LOCALAPPDATA%\atom\packages\
, no carga init.coffee
, ni cualquier tema personalizado.
Para ver en que gasta tiempo Atom al iniciar se puede activar la funcion Timecop mediante el comando Timecop: View
. Tambien se pueden activar el inspector de elementos con Ctrl+Shift+I
.
Para contribuir al proyecto o reportar Issues se siguen las reglas de este documento.
Para realizar un Pull Request:
atom --test spec
y Window: Run Package Specs
.Para realizar un Issue:
atom -v
y apm -v
.Accion | Teclas | Accion | Teclas |
---|---|---|---|
Seleccionar Palabra | Ctrl + d | Seleccionar Sig. Palabra | Ctrl + d + Ctrl + d |
Palabras Iguales a la Seleccionada | Alt + F3 | Seleccionar Linea | Ctrl + l |
Seleccionar Documento | Ctrl + A | Seleccionar Bloque | Alt + Ctrl + , |
Cerrar Tag HTML | Alt + Ctrl + , | Colapsar Bloque Codigo | Alt + Ctrl + [ |
Expandir Bloque | Alt + Ctrl + ] | Colapsar Seleccion | Alt + Ctrl + f |
Ir Final o Inicio Palabra | Ctrl + Flechas Derecha Izquierda | Ir Inicio Linea | Inicio |
Ir Final Linea | Fin | Ir Inicio Documento | Ctrl + Inicio |
Ir Final Documento | Ctrl + Fin | Ir Linea o Caracter | Ctrl + g + (Fila:Columna) |
Ir a Simbolo (Metodo o Definición) | Ctrl + r | Siguiente llave o corchete | Ctrl + m |
Agregar Marcador | Alt + Ctrl + F2 | Siguiente Marcador | F2 |
Marcador Anterior | Shift + F2 | Buscar Marcador | Ctrl + F2 |
Buscar Buffer Archivo | Ctrl + f | Buscar Buffer Proyecto | Ctrl + Shift + f |
Abrir Archivo | Ctrl + o | Abrir Settings | Ctrl + , |
Abrir Buscador Archivos | Ctrl + t | Abrir Paleta Comandos | Ctrl + Shift + p |
Buscar Archivos Abiertos | Ctrl + b | Buscar Archivos Modificados | Ctrl + Shift + b |
Abrir Tree View | Ctrl + k + b | Abrir Directorio | Ctrl + Shift + a |
Abrir Dev Tools | Ctrl + Shift + i | Abrir Styleguide Panel | Ctrl + Shift + g |
Abrir Hyperlink | Alt + o | Abrir Keybind Resolver | Ctrl + . |
Abrir Scope Actuales | Ctrl + Alt + p | Abrir Git Panel | Ctrl + 9 |
Abrir Github Panel | Ctrl + 8 | Guardar Cambios | Ctrl + s |
Guardar Como | Ctrl + Shift + s | Cambiar Encoding | Ctrl + Shift + u |
Clonar Ventana (Direccion) | Ctrl + k (soltar) Flechas | Cambiar Ventana Activa | Ctrl + k + Ctrl + Flechas |
Cerrar Ventanas Clonadas | Ctrl + w | Abrir Preview Markdown | Ctrl + Shift + m |
Añadir Cursor | Ctrl + Click | Mover Linea Abajo-Arriba | Ctrl + Flechas |
Indentar Linea | Ctrl + [ | Quitar Indentado Linea | Ctrl + ] |
Insertar Linea Abajo | Ctrl + Enter | Insertar Linea Arriba | Ctrl + Shift + Enter |
Duplicar Linea Abajo | Ctrl + Shift + d | Combinar con Linea Abajo | Ctrl + j |
Palabra en Mayusculas | Ctrl + k + u | Palabra a Minusculas | Ctrl + k + l |
Borrar Linea | Ctrl + Shift + k | Borrar Hasta Inicio Palabra | Ctrl + Backspace |
Borrar Hasta Final Palabra | Ctrl + Del | Seleccionar Tipo de Archivo | Ctrl + Shift + l |
.markup.underline.link.hyperlink
. Abrir con Alt + o
.apm init --convert
al shell, esto nos permitio convertir todos los lenguajes desde TextMate Bundles a paquetes individuales de Atom.onDid
y onWill
. Para quitar la suscripcion utilizamos el metododispose
.atom-text-editor
. Para modificar los estilos de estos elementos es necesario hacerlo de forma explicita con ::shadow
.atom-text-editor
y .editor
.transparent
del BrowserWindow
.webFrame.registerUrlSchemeAsSecure
.disable-http-cache
.webFrame.setSpellCheckProvider
.ipc.sendToHost
."use babel";
al inicio de tu script.Ctrl+Shift+O
.TextEditorPresenter
.TextEditor
puede generar el siguiente frame.transform
para cambiar la posicion vertical de los Tiles.Ctrl+Tab
cambia pestañas correctamente. Keyup Event. Crash Recovery.atom-text-editor
y los selectores de algunos paquetes.atom-text-editor
en otros paquetes y un aumento en la complejidad del codigo con el uso de pseudoselectores ::shadow /deep/
..syntax--
.Ctrl+Tab
.require
. Tambien nos permitieron guardar el estado varias instancias del objeto atom
construidas a partir del AtomEnviroment
.