Entrada
Preview Image

Crear esquemas personalizados con archivos .sublime-color-scheme

SublimeText: Crear esquemas personalizados con archivos .sublime-color-scheme

Más allá de instalar paquetes o modificar configuraciones básicas, Sublime Text permite ajustar la capa visual con un nivel de detalle sorprendente, moldeable fácilmente a tu flujo de trabajo.

Antes de profundizar en la personalización, es importante entender cómo se organiza su interfaz. De forma general, podemos dividirla en dos áreas principales:

1. El área de edición, donde escribes y trabajas directamente con el código.

Area de edicion

2. La interfaz de soporte, que incluye elementos como la barra lateral, las pestañas, la barra de estado y otros componentes del entorno.

Area de interfaz de soporte

Los archivos .sublime-color-scheme se encargan de modificar principalmente el área de edición, es decir, cómo se renderiza el código: colores de sintaxis, fondo, selección y otros elementos visuales relacionados con la lectura del texto.

¿Qué es un archivo .sublime-color-scheme?

Es un archivo en JSON que describe la apariencia del editor a nivel de sintaxis. Permite controlar:

  • Colores globales del editor
  • Estilos tipográficos por tipo de token
  • Resaltado de elementos activos

Este formato es el reemplazo de los archivos .tmThemes.

Dónde se guardan estos archivos

Sublime Text carga los esquemas desde dos lugares. La aplicación incluye sus propios esquemas dentro de los paquetes instalados, normalmente comprimidos en archivos .sublime-package. Sin embargo, cualquier modificación o esquema personalizado debe colocarse en la carpeta del usuario, ya que Sublime siempre prioriza esa ruta sobre lo que venga preinstalado.

  • En sistemas Windows por lo general se ubica en %AppData%/Roaming/Sublime Text/Packages/User/:

     C:\Users\mcherrera> cd %AppData%\Roaming\Sublime Text\Packages\User
    

    Otra forma de llegar a la carpeta es buscarla desde el editor: Browse Package

  • En Linux en ~/.config/sublime-text/Packages/User/:

    1
    
    cd ~/.config/sublime-text/Packages/User/
    
  • En macOS dentro de ~/Library/Application Support/Sublime Text/Packages/User/:

    1
    
    cd ~/Library/Application\ Support/Sublime\ Text/Packages/User/
    

    Otra forma de llegar a la carpeta es buscarla desde el editor: Browse Package

Basta crear un archivo nuevo con extensión .sublime-color-scheme en esa carpeta para que Sublime lo reconozca inmediatamente (aunque nos advertirá que tiene errores). Te sugiero arrastrar la carpeta al editor para poder editar el archivo de manera más rápida y sencilla:

Move folder user

Lo primero que podemos hacer es definir un nombre para este nuevo esquema:

1
2
3
{
    "name": "Demo Color Scheme"
}

Seleccionar el esquema de colores

Para seleccionar un esquema de colores en Sublime Text tienes 3 formas de hacerlo:

1. Desde el menú (el más fácil)

  1. Abre Sublime Text
  2. Ve a Preferences
  3. Haz clic en Color Scheme…
  4. Se abrirá una lista de temas instalados
  5. Selecciona el esquema

Seleccionar esquema

2. Desde Command Palette

  1. Presiona Ctrl + Shift + P (o Cmd + Shift + P en macOS)
  2. Escribe: UI: Select Color Scheme
  3. Enter
  4. Selecciona el esquema de colores

3. Editando el archivo de preferencias

Si quieres establecer el esquema por el nombre exacto:

  1. Ve a Preferences → Settings
  2. En la parte derecha agrega/modifica esto:
1
2
3
{
    "color_scheme": "demo.sublime-color-scheme",
}

Secciones del archivo

1. Variables

La sección variables actúa como la paleta interna del esquema y permite declarar colores reutilizables para todo el archivo. Su función es centralizar valores y evitar repetir definiciones en cada regla. Sublime admite colores en formato hex, rgba y funciones como blend() o alpha(). A continuación, se muestra un ejemplo típico de cómo se declaran colores base y derivados:

1
2
3
4
5
6
7
8
9
10
{
  "name": "Demo Color Scheme",
  "variables": {
    "background": "#1e1e1e",
    "foreground": "#d4d4d4",
    "accent": "#569cd6",
    "accentDim": "alpha(var(accent), 0.6)",
    "stringColor": "#ce9178"
  }
}

2. Globals

La sección globals define el comportamiento visual general del editor, determinando el fondo, el color principal del texto, las selecciones, el cursor, las guías y los resaltados de búsqueda. No depende de ninguna sintaxis: se aplica a todo el documento abierto. Un ejemplo habitual describe el ambiente completo del editor:

1
2
3
4
5
6
7
8
9
  "globals": {
    "background": "var(background)",
    "foreground": "var(foreground)",
    "caret": "var(accent)",
    "selection": "var(accentDim)",
    "line_highlight": "alpha(var(accent), 0.15)",
    "guide": "#333333",
    "active_guide": "var(accent)"
  }

3. Rules

La sección rules es donde realmente se define cómo se colorean los distintos elementos del código según los scopes que asigna Sublime Text. Cada regla modifica un componente sintáctico específico, como cadenas, palabras clave, comentarios o funciones. El sistema acepta múltiples propiedades como foreground, font_style, background y funciones de color. Un conjunto de reglas básico podría verse así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  "rules": [
    {
      "scope": "comment",
      "foreground": "#6a9955",
      "font_style": "italic"
    },
    {
      "scope": "string",
      "foreground": "var(stringColor)"
    },
    {
      "scope": "keyword",
      "foreground": "var(accent)",
      "font_style": "bold"
    },
    {
      "scope": "entity.name.function",
      "foreground": "#dcdcaa"
    }
  ]

Estructura completa de ejemplo

A modo de referencia, este es un .sublime-color-scheme funcional, limpio y listo para usarse en cualquier instalación:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
  "variables": {
    "background": "#1e1e1e",
    "foreground": "#d4d4d4",
    "accent": "#569cd6",
    "stringColor": "#ce9178"
  },

  "globals": {
    "background": "var(background)",
    "foreground": "var(foreground)",
    "caret": "var(accent)",
    "selection": "alpha(var(accent), 0.25)"
  },

  "rules": [
    {
      "scope": "comment",
      "foreground": "#6a9955",
      "font_style": "italic"
    },
    {
      "scope": "string",
      "foreground": "var(stringColor)"
    },
    {
      "scope": "keyword",
      "foreground": "var(accent)",
      "font_style": "bold"
    },
    {
      "scope": "entity.name.function",
      "foreground": "#dcdcaa"
    }
  ]
}

Más esquemas para sublime

A continuación, puedes ver varios archivos de ejemplo para utilizar en sublime:

FOLDERS
    Sin archivo x
              
            
                // view.settings().set("color_scheme", "mcherrera.sublime-color-scheme")
    {
      "name": "mcherrera-iron", 
      "variables":{
        "main_fg": "#EFA128",
        "second_fg": "rgb(240, 240, 160)",
        "operator": "#F54006",
        "constants": "#F3ED1B",
        "select_fg" : "#FFF",
        "integrate_func": "rgb(255, 120, 110)",
        "parameters": "#E2E2E0"
      },
      "globals":{
        "background": "#141B22",  // fondo
        "foreground": "rgb(255, 255, 255)", // texto
        "caret": "var(main_fg)", // cursor
        "accent": "#FF9003",
        "selection": "#900510", // selección
      },	
      "rules":[
        // (General)
        {
          "name" : "Comment", 
          "scope": "comment", // (Afecta a los comentarios)
          "foreground": "#6CA61D",
          "selection_foreground": "white",
          "font_style": "italic"
        },	
        {
          "name": "String",
          "scope": "string", // (Afecta a las cadenas de texto)
          "foreground": "#D6C248",
        },
        {
          "scope": "keyword",  // (Afecta a las palabras reservadas)
          "foreground": "var(main_fg)",
          "font_style" : "bold",
        },
        {
          "scope": "entity.name", // (Afecta a nombres de clases)
          "foreground": "var(second_fg)",
          "font_style" : "",
        },		
        {
          "scope": "variable.function", // (Afecta a métodos y funciones)
          "foreground": "var(integrate_func)",
          "font_style" : "bold",
        },
    
        // (Python)
        {
          // (magic_method_variable)
          "scope": "support.variable.magic.python",
          "foreground": "var(second_fg)",
          "font_style": "bold",
        },
        {
          "scope": "support.function.builtin.python", // (Afecta a funciones integradas de Python. Ej: print(), len(), etc)
          "foreground": "var(integrate_func)",
          "selection_foreground": "var(select_fg)",
          "font_style": "bold",
        },
        {
          // (as)
          "include": "name",
                "scope": "keyword.control.import.as.python",
                "foreground": "var(operator)",
                "selection_foreground": "var(select_fg)",
                "font_style": "bold",
    
        },
        
        {
          // (if)
                "scope": "keyword.control.conditional.if.python",
                "foreground": "var(operator)",
                "selection_foreground": "var(select_fg)",
                "font_style": "bold",
    
        },
        {
          // (tuple empty)
                "scope": "meta.sequence.tuple.empty.python",
                "foreground": "var(second_fg)",
                "selection_foreground": "var(select_fg)",
                "font_style": "bold",
    
        },
        {
          // (tuple '('a,2,3) and list '['a,2,4])
                "scope": "punctuation.section.sequence.begin.python",
                "foreground": "var(second_fg)",
                "selection_foreground": "var(select_fg)",
                "font_style": "bold",
        },
        {
          // (tuple (a,2,3')' and list [a,2,4']')
                "scope": "punctuation.section.sequence.end.python",
                "foreground": "var(second_fg)",
                "selection_foreground": "var(select_fg)",
                "font_style": "bold",
        },
        {
          // (tuple (a,2','3) and list [a','2,4])
                "scope": "punctuation.separator.sequence.python",
                "foreground": "var(operator)",
                "selection_foreground": "var(select_fg)",
                "font_style": "bold",
    
        },
        {
          // (Docstring)
                "name": "Python docstrings",
                "scope": "comment.block.documentation.python",
                "foreground": "#E8C49A",
                "font_style": "italic",
    
        },
        {
          // (class)
          "scope": "meta.class.python",
          "foreground": "var(main_fg)",
          "font_style" : "bold"
        },
        {
          // (def)
          "scope":"meta.function.python",
          "foreground": "var(main_fg)",
          "font_style": "bold"
        },
        {
          // (continue)
          "scope":"keyword.control.flow.continue.python",
          "foreground": "var(operator)",
          "font_style": "bold"
        },
        {
          // (break)
          "scope":"keyword.control.flow.break.python",
          "foreground": "var(operator)",
          "font_style": "bold"
        },
        {
          // (pass)
          "scope":"keyword.control.flow.pass.python",
          "foreground": "var(operator)",
          "font_style": "bold"
        },
        {
          // (yield)
          "scope":"keyword.control.flow.yield.python",
          "foreground": "var(operator)",
          "font_style": "bold"
        },
    
        {
          // (None|True|False|Ellipsis|NotImplemented|__debug__)
          "scope":"constant.language.python",
          "foreground": "var(constants)",
          "font_style": "bold"
        },
        {
          //(=)
          "scope": "keyword.operator.assignment.python",
          "foreground": "var(operator)",
          "selection_foreground": "var(select_fg)",
        },
        {
          // (*)
          "scope": "constant.language.import-all.python",
          "foreground": "var(operator)",
          "font_style" : "bold",
        },
        {
          //(p,p2,p3)
          "scope": "punctuation.separator.parameters.python",
          "foreground": "var(operator)",
          "selection_foreground": "white",
        },
        {
          //(def 'name')
          "name": "Functions name",
          "scope": "entity.name.function",
          "foreground": "var(second_fg)",
        },
        {
          // (return)
          "scope": "keyword.control.flow.return.python",
          "foreground": "var(operator)",
          "font_style" : "bold",
        },
        {
          // ('param')
          "scope": "meta.function.parameters.python",
          "foreground": "var(parameters)",
          "font_style" : "",
        },
        {
          //Setting python function (lambda :)
          "scope": "meta.function.inline.python",
          "foreground": "var(second_fg)",
          "font_style": "",
          "selection_foreground": "white",
        },
        {
          // (lambda)
          "scope": "storage.type.function.inline.python",
          "foreground": "var(operator)",
          "font_style": "italic",
          "selection_foreground": "white",
        },
      ]
    }
    
            
          
              
            
                {
      "variables": {
        "bg": "#16181a",
        "fg": "#d0d0d0",
        "red": "#ef5350",
        "orange": "#ff9800",
        "green": "#8bc34a",
        "blue": "#42a5f5",
        "purple": "#ab47bc",
        "comment": "#5c6370"
      },
    
      "globals": {
        "background": "var(bg)",
        "foreground": "var(fg)",
        "caret": "var(blue)",
        "selection": "#2c313a",
        "line_highlight": "#1e2227",
        "accent": "var(blue)"
      },
    
      "rules": [
        { "scope": "comment", "foreground": "var(comment)" },
        { "scope": "string", "foreground": "var(green)" },
        { "scope": "keyword", "foreground": "var(red)" },
        { "scope": "entity.name.class", "foreground": "var(orange)" },
        { "scope": "entity.name.function", "foreground": "var(blue)" },
        { "scope": "constant.numeric", "foreground": "var(purple)" }
      ]
    }
    
            
          

    Selecciona un archivo para ver su contenido

    Esta entrada está licenciada bajo CC BY 4.0 por el autor.