Version 1.000
BIN
FiraCode-Bold.otf
Normal file
BIN
FiraCode-Medium.otf
Normal file
BIN
FiraCode-Retina.otf
Normal file
44
README.md
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<img src="https://dl.dropboxusercontent.com/u/561580/imgs/fira_code_logo.svg">
|
<img src="https://dl.dropboxusercontent.com/u/561580/imgs/fira_code_logo.svg">
|
||||||
|
|
||||||
#### [Download Fira Code v0.6](https://github.com/tonsky/FiraCode/releases/download/0.6/FiraCode-Regular.otf)
|
#### [Download Fira Code v1.000](https://github.com/tonsky/FiraCode/releases/download/1.000/FiraCode.zip)
|
||||||
|
|
||||||
### Problem
|
### Problem
|
||||||
|
|
||||||
@ -12,14 +12,8 @@ Programmers use a lot of symbols, often encoded with several characters. For hum
|
|||||||
|
|
||||||
Fira Code is a Fira Mono font extended with a set of ligatures for common programming multi-character combinations. This is just a font rendering feature: underlying code remains ASCII-compatible. This helps to read and understand code faster. For some frequent sequences like `..` or `//` ligatures allow us to correct spacing.
|
Fira Code is a Fira Mono font extended with a set of ligatures for common programming multi-character combinations. This is just a font rendering feature: underlying code remains ASCII-compatible. This helps to read and understand code faster. For some frequent sequences like `..` or `//` ligatures allow us to correct spacing.
|
||||||
|
|
||||||
### Fira Code (with ligatures):
|
|
||||||
|
|
||||||
<img src="./showcases/all_ligatures.png" />
|
<img src="./showcases/all_ligatures.png" />
|
||||||
|
|
||||||
Compare to Fira Mono (without ligatures):
|
|
||||||
|
|
||||||
<img src="./showcases/no_ligatures.png" />
|
|
||||||
|
|
||||||
### Editor support
|
### Editor support
|
||||||
|
|
||||||
Do **not** work:
|
Do **not** work:
|
||||||
@ -52,6 +46,7 @@ Do work:
|
|||||||
- Kate, Konsole, KWrite in Plasma/KDE 5
|
- Kate, Konsole, KWrite in Plasma/KDE 5
|
||||||
- Kate, Konsole, KWrite in KDE 4 using Debian Jessie or OS X
|
- Kate, Konsole, KWrite in KDE 4 using Debian Jessie or OS X
|
||||||
- Mancy
|
- Mancy
|
||||||
|
- TextAdept (Mac)
|
||||||
|
|
||||||
Should work (copied from [Hasklig README](https://github.com/i-tu/Hasklig)):
|
Should work (copied from [Hasklig README](https://github.com/i-tu/Hasklig)):
|
||||||
|
|
||||||
@ -60,7 +55,6 @@ Should work (copied from [Hasklig README](https://github.com/i-tu/Hasklig)):
|
|||||||
- Smultron
|
- Smultron
|
||||||
- Vico
|
- Vico
|
||||||
|
|
||||||
_Note:_ I’m not a font designer, and Fira Code is built in sort of [a hacky way](https://github.com/mozilla/Fira/issues/62) from OTF version of Fira Mono. Please forgive me if it doesn’t work for you. Help will be greatly appreciated.
|
|
||||||
|
|
||||||
### Code examples
|
### Code examples
|
||||||
|
|
||||||
@ -72,7 +66,6 @@ JavaScript:
|
|||||||
|
|
||||||
<img src="./showcases/javascript.png" />
|
<img src="./showcases/javascript.png" />
|
||||||
|
|
||||||
|
|
||||||
Erlang:
|
Erlang:
|
||||||
|
|
||||||
<img src="./showcases/erlang.png" />
|
<img src="./showcases/erlang.png" />
|
||||||
@ -95,12 +88,41 @@ Another monospaced fonts with ligatures:
|
|||||||
|
|
||||||
### Credits
|
### Credits
|
||||||
|
|
||||||
This work is based on OFL-licensed [Fira Mono font](https://github.com/mozilla/Fira). Original Fira Mono font was not changed, only extended
|
This work is based on OFL-licensed [Fira Mono font](https://github.com/mozilla/Fira). Original Fira Mono font was not changed, only extended.
|
||||||
|
|
||||||
Fira Code was inspired by [Hasklig font](https://github.com/i-tu/Hasklig): Ligatures for Haskell code
|
Fira Code was inspired by [Hasklig font](https://github.com/i-tu/Hasklig): Ligatures for Haskell code.
|
||||||
|
|
||||||
|
Thanks Georg Seifert for providing a [Glyphs 2](https://glyphsapp.com) license.
|
||||||
|
|
||||||
### Changelog
|
### Changelog
|
||||||
|
|
||||||
|
**1.000**:
|
||||||
|
|
||||||
|
Added weights:
|
||||||
|
|
||||||
|
- Retina (just slightly bolder than Regular)
|
||||||
|
- Medium
|
||||||
|
- Bold
|
||||||
|
|
||||||
|
Switched to `calt` instead of `liga`. You can now “step inside” the ligature in text editors.
|
||||||
|
|
||||||
|
Fira Code is now drawn and built in Glyps 2 app (should improve compatibility).
|
||||||
|
|
||||||
|
Added:
|
||||||
|
|
||||||
|
`<->` `<~~` `<~` `~~~` `~>` `~~>`
|
||||||
|
`<$` `<+` `<*` `*>` `+>` `$>`
|
||||||
|
`;;;` `:::` `!!!` `???` `%%` `%%%` `##` `###` `####`
|
||||||
|
`.-` `#_(` `=<` `**/` `0x` `www` `[]`
|
||||||
|
|
||||||
|
Redrawn:
|
||||||
|
|
||||||
|
`{-` `-}` `~=` `=~` `=<<` `>>=` `<$>` `<=>` `.=`
|
||||||
|
|
||||||
|
Removed: `?:`
|
||||||
|
|
||||||
|
Total ligatures count: 115
|
||||||
|
|
||||||
**0.6**:
|
**0.6**:
|
||||||
|
|
||||||
Redrawn from Fira Mono 3.204 (slightly heavier weight)
|
Redrawn from Fira Mono 3.204 (slightly heavier weight)
|
||||||
|
125
gen_calt.clj
Executable file
@ -0,0 +1,125 @@
|
|||||||
|
#^:shebang '[
|
||||||
|
exec java -cp "$HOME/.m2/repository/org/clojure/clojure/1.7.0/clojure-1.7.0.jar" clojure.main "$0" "$@"]
|
||||||
|
|
||||||
|
|
||||||
|
(require '[clojure.string :as str])
|
||||||
|
|
||||||
|
(def file "FiraCode.glyphs")
|
||||||
|
|
||||||
|
(println "Looking for ligatures in" file "...\n")
|
||||||
|
|
||||||
|
;; [ ["dash" "greater" "greater"] ... ]
|
||||||
|
(def ligas (->> (slurp file)
|
||||||
|
(re-seq #"glyphname = ([a-z_]+)\.liga;")
|
||||||
|
(map second)
|
||||||
|
set
|
||||||
|
(mapv #(vec (str/split % #"_")))))
|
||||||
|
|
||||||
|
|
||||||
|
; (def ligas
|
||||||
|
; [ ["hyphen" "greater"]
|
||||||
|
; ["greater" "equal"]
|
||||||
|
; ["equal" "greater"]
|
||||||
|
; ["hyphen" "hyphen" "greater"]
|
||||||
|
; ["equal" "equal" "greater"]
|
||||||
|
; ["greater" "hyphen"]])
|
||||||
|
|
||||||
|
; (def ligas
|
||||||
|
; [ ["slash" "asterisk"]
|
||||||
|
; ["slash" "asterisk" "asterisk"]
|
||||||
|
; ["asterisk" "asterisk"]
|
||||||
|
; ["asterisk" "asterisk" "asterisk"]])
|
||||||
|
|
||||||
|
|
||||||
|
(defn liga->rules
|
||||||
|
"[f f i] => { [CR CR i] f_f_i.liga
|
||||||
|
[CR f i] CR
|
||||||
|
[ f f i] CR }"
|
||||||
|
[liga CR]
|
||||||
|
(case (count liga)
|
||||||
|
2 (let [[a b] liga]
|
||||||
|
{ [CR b] (str a "_" b ".liga")
|
||||||
|
[ a b] CR})
|
||||||
|
3 (let [[a b c] liga]
|
||||||
|
{ [CR CR c] (str a "_" b "_" c ".liga")
|
||||||
|
[CR b c] CR
|
||||||
|
[ a b c] CR})
|
||||||
|
4 (let [[a b c d] liga]
|
||||||
|
{ [CR CR CR d] (str a "_" b "_" c "_" d ".liga")
|
||||||
|
[CR CR c d] CR
|
||||||
|
[CR b c d] CR
|
||||||
|
[ a b c d] CR})))
|
||||||
|
|
||||||
|
|
||||||
|
(def all-rules
|
||||||
|
(reduce
|
||||||
|
(fn [generated liga]
|
||||||
|
(merge generated
|
||||||
|
;; looking for smallest i that does not conflict
|
||||||
|
;; with any of previous rules
|
||||||
|
(some (fn [i]
|
||||||
|
(let [CR (str "CR." (String/format "%02d" (to-array [i])))
|
||||||
|
rs (liga->rules liga CR)]
|
||||||
|
(when-not (some generated (keys rs))
|
||||||
|
rs)))
|
||||||
|
(range))))
|
||||||
|
{}
|
||||||
|
ligas))
|
||||||
|
|
||||||
|
|
||||||
|
(defn priority-fn [[from to]]
|
||||||
|
[;; first compare how many CRs are there (more is better)
|
||||||
|
(- (count (filter #(re-matches #"CR\.\d+" %) from)))
|
||||||
|
;; then overal length (more is better)
|
||||||
|
(- (count from))
|
||||||
|
;; then alphabetical sort with coercing each vector to the same length
|
||||||
|
(into from (repeat (- 4 (count from)) "z"))])
|
||||||
|
|
||||||
|
|
||||||
|
(defn replace-keys [replacements coll]
|
||||||
|
(reduce (fn [result [k v]]
|
||||||
|
(conj result [(or (replacements k) k) v]))
|
||||||
|
(empty coll) coll))
|
||||||
|
|
||||||
|
|
||||||
|
(def table (->> all-rules
|
||||||
|
(sort-by priority-fn)
|
||||||
|
vec
|
||||||
|
(replace-keys {["zero" "x"] ["zero" "x" "@HexDigit"]})))
|
||||||
|
|
||||||
|
|
||||||
|
(defn rule->str [[from to]]
|
||||||
|
(loop [res "sub"
|
||||||
|
seen-non-empty? false
|
||||||
|
tokens from]
|
||||||
|
(if-let [token (first tokens)]
|
||||||
|
(let [class? (.startsWith token "@")
|
||||||
|
CR? (.startsWith token "CR.")
|
||||||
|
escaped-token (cond
|
||||||
|
class? token
|
||||||
|
CR? (str "\\" token)
|
||||||
|
seen-non-empty? (str "\\" token)
|
||||||
|
:else (str "\\" token "'"))]
|
||||||
|
(recur (str res " " escaped-token) (not CR?) (next tokens)))
|
||||||
|
(str res " by \\" to ";"))))
|
||||||
|
|
||||||
|
|
||||||
|
(println "feature calt {")
|
||||||
|
(println " " (->> table (map rule->str) (str/join "\n ")))
|
||||||
|
(println "}\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(apply println "Placeholders:\n " (->> table (mapcat first) (filter #(.startsWith % "CR.")) distinct sort))
|
||||||
|
(println)
|
||||||
|
|
||||||
|
|
||||||
|
(println "Total ligatures count:" (count ligas))
|
||||||
|
(println " " (->> ligas
|
||||||
|
(group-by count)
|
||||||
|
(sort-by first)
|
||||||
|
(map (fn [[k v]] (str (count v) (case k 2 " pairs", 3 " triples", 4 " quadruples"))))
|
||||||
|
(str/join ", ")))
|
||||||
|
(println)
|
||||||
|
|
||||||
|
(println "Total rules count:" (count table))
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 211 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 90 KiB |
BIN
showcases/go.png
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 76 KiB |
29
showcases/showcases.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
.= .- := =:=
|
||||||
|
== != === !== =/=
|
||||||
|
|
||||||
|
<<- <-- <- <-> -> --> ->>
|
||||||
|
<=< <<= <== <=> => ==> =>> >=>
|
||||||
|
>>= >>- >- -< -<< =<<
|
||||||
|
<~~ <~ ~~~ ~> ~~>
|
||||||
|
|
||||||
|
<<< << <= <> >= >> >>>
|
||||||
|
<| <|> |>
|
||||||
|
|
||||||
|
<$ <$> $>
|
||||||
|
<+ <+> +>
|
||||||
|
<* <*> *>
|
||||||
|
|
||||||
|
\\ \\\ {- -} // ///
|
||||||
|
/* /** **/ */
|
||||||
|
</ <!-- --> />
|
||||||
|
0xF www []
|
||||||
|
|
||||||
|
;; ;;; :: ::: !! !!!
|
||||||
|
?? ??? %% %%% && &&&
|
||||||
|
|| ||| .. ... ..<
|
||||||
|
-- --- ++ +++ ** ***
|
||||||
|
|
||||||
|
~= ~- -~ =~ ~@
|
||||||
|
^= ?= /= /== |= ||=
|
||||||
|
## ### ####
|
||||||
|
#{ #[ #( #? #_ #_(
|