diff --git a/README.markdown b/README.markdown index b7c3560..58b317d 100644 --- a/README.markdown +++ b/README.markdown @@ -5,9 +5,9 @@ * Groups global settings (like colorscheme) into ‘themes’ * Stays out of your way, except where you want it * No predefined key mappings to interfere with your other mappings -* [vim-thematic-gui](https://github.com/reedes/vim-thematic-gui) extension - available with GUI-based support for: font, fullscreen, etc. * Integrates with [airline](https://github.com/bling/vim-airline) +* Support for GUI-based Vim includes support for font, linespace, fullscreen, + transparency, and screen columns/lines ## Why thematic? @@ -31,6 +31,15 @@ Managing such an multi-theme environment in Vim has traditionally been a hassle. The thematic plugin is intended to solve that problem, providing you flexibility and convenience. +GUI-based Vim users can complement a colorscheme with a particular typeface. +For example, the lightweight anti-aliased typeface like Adobe's _Source Code +Pro ExtraLight_ may look great against a black background but be unreadable +against a white one, so you’ll only pair it with an appropriate colorscheme. + +Or for a particular typeface you may want a larger +[leading](http://en.wikipedia.org/wiki/Leading) to reduce crowding of +lines. See the `linespace` option. + ## Requirements May require a recent version of Vim. @@ -89,6 +98,48 @@ that you aren't explicitly setting through your thematic configuration. For example, you can `set guifont=` in your .gvimrc independent of your thematic configuration. +GUI-based Vim users have additional options available in theming. For example, + +```vim +let g:thematic#defaults = { +... +\ 'font-size': 20, +\ 'transparency': 0, +\ } +``` + +```vim +let g:thematic#themes = { +\ 'bubblegum' : { 'typeface': 'Cutive Mono', +\ 'linespace': 9, +\ }, +\ 'matrix' : { 'colorscheme': 'base16-greenscreen', +\ 'font-size': 24, +\ 'linespace': 9, +\ 'typeface': 'Dot Matrix', +\ 'transparency': 10, +\ }, +\ 'solar_dark' : { 'colorscheme': 'solarized', +\ ... +\ 'typeface': 'Source Code Pro Light', +\ }, +\ 'solar_lite' : { 'colorscheme': 'solarized', +\ ... +\ 'font-size': 20, +\ 'linespace': 8, +\ 'typeface': 'Source Code Pro', +\ }, +\ 'iawriter' : { 'colorscheme': 'reede_light', +\ ... +\ 'columns': 75, +\ 'font-size': 20, +\ 'fullscreen': 1, +\ 'linespace': 8, +\ 'typeface': 'Menlo', +\ }, +\ } +``` + ### Commands Running `:ThematicFirst` invoke thematic and chooses the first theme, @@ -114,7 +165,7 @@ nnoremap T ThematicNext For each theme you specify one or more properties. -For console or GUI Vim: +For console or GUI-based Vim: * `laststatus` (0, 1, or 2) - controls the visibility of the status bar * `ruler` - as alternative to status bar, shows minimal position details in lower right @@ -130,15 +181,33 @@ For console or GUI Vim: * `fold-column-color-mute` - temporarily modifies colorscheme to hide indicators in foldcolumn -For GUI-based options, see the -[vim-thematic-gui](https://github.com/reedes/vim-thematic-gui) plugin. -Here’s a summary: +The following options are for GUI-based Vim only: -* `typeface`, `font-size`, and `linespace` - be specific about typography -* `fullscreen` and `fullscreen-background-color-fix` - force a switch to - fullscreen, with optional change of color of the background (or border) -* `columns` and `lines` - manage the width of margins in `fullscreen` mode -* `transparency` (0-100) - view details of window and desktop beneath Vim +Typography-related: + +* `typeface` - name of font +* `font-size` - point size of font +* `linespace` (0+) - additional pixel spacing between lines + +Screen-related: + +* `fullscreen` - if 1, force a switch to fullscreen +* `fullscreen-background-color-fix` - optional change of color of the + background (or border) to match text background +* `columns` and `lines` - you’ll mostly use these to manage the height and + width the text area in `fullscreen` mode +* `transparency` (0=none, 100=fully transparent) - view details of window + and desktop beneath Vim + +## GUI fullscreen capabilities + +thematic supports fullscreen capabilities for GUI-based Vim, including +typeface, font-size, lines, columns, linespace, transparency and even the +fullscreen background. + +Note that once invoked, thematic will override your fullscreen settings, +specifically `fuoptions` to get better control over screen lines and columns +and the fullscreen background. ## FAQ @@ -199,6 +268,48 @@ with a narrow `textwidth`: autocmd FileType markdown set foldcolumn=12 textwidth=74 ``` +### Q: Using MacVim, the fullscreen background color isn't working as expected. How do I change its behavior? + +To have the fullscreen background's color set by thematic, enter the +following in OS X Terminal: + +``` +$ defaults write org.vim.MacVim MMNativeFullScreen 0 +``` + +Or, if you prefer your fullscreen window to float against a standard +background: + +``` +$ defaults write org.vim.MacVim MMNativeFullScreen 1 +``` + +## Monospaced fonts + +Whether using console or GUI-based Vim, a good monospaced font can improve your +editing experience. Many are available for free: + +* [Anonymous Pro](https://www.google.com/fonts/specimen/Anonymous+Pro) +* [CosmicSansNeueMono](https://github.com/belluzj/cosmic-sans-neue) +* [Courier Prime](http://quoteunquoteapps.com/courierprime/) +* [Cousine](http://www.google.com/fonts/specimen/Cousine) +* [Cutive Mono](http://www.google.com/fonts/specimen/Cutive+Mono) +* [DejaVu Sans Mono](http://dejavu-fonts.org/wiki/Download) +* [Droid Sans Mono](http://www.google.com/fonts/specimen/Droid+Sans+Mono) +* [Hermit](https://pcaro.es/p/hermit/) +* [Inconsolata](http://www.google.com/fonts/specimen/Inconsolata) +* [Linux Libertine Mono O](http://sourceforge.net/projects/linuxlibertine/) +* [Liberation](https://fedorahosted.org/liberation-fonts/) +* [Luxi Mono Regular](http://www.fontsquirrel.com/fonts/Luxi-Mono) +* [Meslo](https://github.com/andreberg/Meslo-Font) +* [Oxygen Mono](https://www.google.com/fonts/specimen/Oxygen+Mono) +* [PT Mono](http://www.google.com/fonts/specimen/PT+Mono) +* [Share Tech Mono](http://www.google.com/fonts/specimen/Share+Tech+Mono) +* [Source Code Pro](http://www.google.com/fonts/specimen/Source+Code+Pro) +* [Ubuntu Mono](https://www.google.com/fonts/specimen/Ubuntu+Mono) + +Note that you already have a few installed, such as `Menlo` on OS X. + ## Related projects If this project is not to your liking, you might enjoy: @@ -215,7 +326,6 @@ If you like this plugin, you might like these others from the same author: * [vim-lexical](http://github.com/reedes/vim-lexical) - Building on Vim’s spell-check and thesaurus/dictionary completion * [vim-litecorrect](http://github.com/reedes/vim-litecorrect) - Lightweight auto-correction for Vim * [vim-quotable](http://github.com/reedes/vim-quotable) - extends Vim to support typographic (‘curly’) quotes -* [vim-thematic-gui](http://github.com/reedes/vim-thematic-gui) — A GUI-based extension to the thematic plugin for Vim * [vim-writer](http://github.com/reedes/vim-writer) - Extending Vim to better support writing prose and documentation ## Future development diff --git a/autoload/thematic.vim b/autoload/thematic.vim index 055d83a..5e2b8bc 100644 --- a/autoload/thematic.vim +++ b/autoload/thematic.vim @@ -141,20 +141,35 @@ function! thematic#init(mode) if thematic#getThemeValue(l:th, 'sign-column-color-fix', 0) " Ensure the gutter matches the text background - hi! SignColumn guifg=fg guibg=bg ctermfg=fg ctermbg=bg + if has('gui_running') + hi! SignColumn guifg=fg guibg=bg + else + hi! SignColumn ctermfg=fg ctermbg=bg + endif endif if thematic#getThemeValue(l:th, 'diff-color-fix', 0) " Override diff colors - hi! DiffAdd guifg=darkgreen guibg=bg cterm=bold ctermbg=bg ctermfg=119 - hi! DiffDelete guifg=darkorange guibg=bg cterm=bold ctermbg=bg ctermfg=167 - hi! DiffChange guifg=darkyellow guibg=bg cterm=bold ctermbg=bg ctermfg=227 - hi! DiffText guifg=fg guibg=bg cterm=none ctermbg=fg ctermfg=fg + if has('gui_running') + hi! DiffAdd guifg=darkgreen guibg=bg + hi! DiffDelete guifg=darkorange guibg=bg + hi! DiffChange guifg=darkyellow guibg=bg + hi! DiffText guifg=fg guibg=bg + else + hi! DiffAdd cterm=bold ctermbg=bg ctermfg=119 + hi! DiffDelete cterm=bold ctermbg=bg ctermfg=167 + hi! DiffChange cterm=bold ctermbg=bg ctermfg=227 + hi! DiffText cterm=none ctermbg=fg ctermfg=fg + endif endif if thematic#getThemeValue(l:th, 'fold-column-color-mute', 0) " Ensure the fold column is blank, for non-distracted editing - hi! FoldColumn guifg=bg guibg=bg cterm=bold ctermbg=bg ctermfg=bg + if has('gui_running') + hi! FoldColumn guifg=bg guibg=bg + else + hi! FoldColumn cterm=bold ctermbg=bg ctermfg=bg + endif endif " ------ Set sign column for all buffers ------ @@ -197,7 +212,7 @@ function! thematic#init(mode) " ------ Set GUI-only settings ------ - if has('gui_running') && exists('*thematic#gui#init') + if has('gui_running') call thematic#gui#init(l:th) endif diff --git a/autoload/thematic/gui.vim b/autoload/thematic/gui.vim new file mode 100644 index 0000000..15e1e96 --- /dev/null +++ b/autoload/thematic/gui.vim @@ -0,0 +1,250 @@ +" ============================================================================ +" File: autoload/gui.vim +" Description: autoload script for vim-thematic-gui plugin +" Maintainer: Reed Esau +" Last Change: December 30, 2013 +" License: The MIT License (MIT) +" ============================================================================ + +" Credit for some font regex/functions: +" https://github.com/drmikehenry/vim-fontsize + +if exists("autoloaded_thematic_gui") | finish | endif +let autoloaded_thematic_gui = 1 + +" # FONT REGEXES +" Regex values for each platform split guifont into three +" sections (\1, \2, and \3 in capturing parentheses): +" - prefix +" - size (possibly fractional) +" - suffix (possibly including extra fonts after commas) + +if has("gui_macvim") + " gui_macvim: Courier\ New:h11 + let s:regex = '\(.\{-}\):h\(\d\+\)' +elseif has("gui_gtk2") + " gui_gtk2: Courier\ New\ 11 + let s:regex = '\(.\{-} \)\(\d\+\)\(.*\)' +elseif has("gui_photon") + " gui_photon: Courier\ New:s11 + let s:regex = '\(.\{-}\):s\(\d\+\)\(.*\)' +elseif has("gui_kde") + " gui_kde: Courier\ New/11/-1/5/50/0/0/0/1/0 + let s:regex = '\(.\{-}\)\/\(\d\+\)\(.*\)' +"elseif has("x11") +" " gui_x11: -*-courier-medium-r-normal-*-*-180-*-*-m-*-* +" let s:regex = '\(.\{-}-\)\(\d\+\)\(.*\)' +else + " gui_other: Courier_New:h11:cDEFAULT + let s:regex = '\(.\{-}\):h\(\d\+\)\(.*\)' +endif + + +function! s:encodeFont(font) + if has("iconv") && exists("g:thematic#encoding") + let encodedFont = iconv(a:font, &enc, g:thematic#encoding) + else + let encodedFont = a:font + endif + return encodedFont +endfunction + + +function! s:decodeFont(font) + if has("iconv") && exists("g:thematic#encoding") + let decodedFont = iconv(a:font, g:thematic#encoding, &enc) + else + let decodedFont = a:font + endif + return decodedFont +endfunction + + +function! s:getSize(font, fallback) + let l:decodedFont = s:decodeFont(a:font) + if match(l:decodedFont, s:regex) != -1 + " Add zero to convert to integer. + let l:size = 0 + substitute(l:decodedFont, s:regex, '\2', '') + else + let l:size = 0 + fallback + endif + return l:size +endfunction + + +function! s:getTypeface(font, fallback) + let decodedFont = s:decodeFont(a:font) + if match(decodedFont, s:regex) != -1 + let l:typeface = substitute(decodedFont, s:regex, '\1', '') + else + let l:typeface = a:fallback + endif + return l:typeface +endfunction + + +" Note that bgcolor may not be available at initial program load +function! s:updateFullscreenBackground() + " #123456 => #00123456 + let l:bgcolor=synIDattr(hlID('Normal'), 'bg#') + if l:bgcolor =~ '#[0-9a-fA-F]\+' + let l:border_color = substitute(l:bgcolor, '#', '#00', '') + " Note that this will blow away existing options, such + " as maxhorz and maxvert, but we removed those earlier. + execute 'set fuoptions=background:' . l:border_color + endif +endfunction + + +function! s:composeGuifontString(typeface, fontsize) + " TODO need support for platform-specific suffixes + let l:encoded_typeface = s:encodeFont(a:typeface) + if has('gui_macvim') + "set guifont=Courier\ New\:h11 + let l:gf = substitute(l:encoded_typeface, ' ', '\\ ', 'g') . '\:h' . a:fontsize + elseif has('gui_gtk') || has('gui_gtk2') || has('gui_gnome') + "set guifont=Courier\ New\ 11 + let l:gf = substitute(l:encoded_typeface, ' ', '\\ ', 'g') . '\ ' . a:fontsize + elseif has('gui_photon') + "set guifont=Courier\ New:s11 + let l:gf = substitute(l:encoded_typeface, ' ', '\\ ', 'g') . ':s' . a:fontsize + elseif has('gui_kde') "|| has('gui_qt') + "set guifont=B&H\ LucidaTypewriter/9/-1/5/50/0/0/0/1/0 + "set guifont=Courier\ New/11/-1/5/50/0/0/0/1/0 + let l:gf = substitute(l:encoded_typeface, ' ', '\\ ', 'g') . '/' . a:fontsize + "elseif has("x11") && !(has("gui_gtk2") || has("gui_kde") || has("gui_photon")) + " "set guifont=-*-courier-medium-r-normal-*-*-180-*-*-m-*-* + " " 18.0pt Courier + " "set gfn=-*-lucidatypewriter-medium-r-normal-*-*-95-*-*-m-*-* + " " 9.5pt LucidaTypewriter + " let l:gf = '-*-' . tolower(l:tf) . '-medium-r-normal-*-*-' . (l:fs*10) . '-*-*-m-*-*' + elseif has('win32') || has('win64') "|| has('gui_win32') || has('gui_win64') + "set guifont=courier_new:h11 + "set guifont=Lucida_Console:h8:cANSI + let l:gf = substitute(l:encoded_typeface, ' ', '_', 'g') . ':h' . a:fontsize + else + echoerr 'GUI platform not yet supported' + let l:gf = '' + endif + return l:gf +endfunction + + +function! s:setGuifont(gf) + if strlen(a:gf) + try + execute 'set guifont=' . a:gf + return 1 + catch /E596/ + echohl ErrorMsg + echo 'Unable to set guifont=' . a:gf + echohl None + endtry + endif + return 0 +endfunction + + +function! thematic#gui#setFont(th) + " attempt to preserve original font if not yet set + if !has_key(g:thematic#original, 'typeface') + let l:typeface = s:getTypeface(&guifont, '') + if l:typeface != '' + let g:thematic#original['typeface'] = l:typeface + endif + endif + if !has_key(g:thematic#original, 'font-size') + let l:size = s:getSize(&guifont, 0) + if l:size != 0 + let g:thematic#original['font-size'] = l:size + endif + endif + + let l:tf = thematic#getThemeValue(a:th, 'typeface', '') + let l:fs = thematic#getThemeValue(a:th, 'font-size', -1) + + " TODO support list of typefaces with most desired as first in list + let l:gf = s:composeGuifontString(l:tf, l:fs) + if l:gf != '' + call s:setGuifont(l:gf) + endif +endfunction + + +function! thematic#gui#setTransparency(th) + let l:tr = thematic#getThemeValue(a:th, 'transparency', -1) + if l:tr > 100 + let l:tr = 100 + endif + if l:tr > 0 + try + execute 'set transparency=' . l:tr + catch + echohl ErrorMsg + echo 'Unable to set transparency=' . l:tr + echohl None + endtry + endif +endfunction + + +function! thematic#gui#setLinespace(th) + let l:ls = thematic#getThemeValue(a:th, 'linespace', -1) + if l:ls != -1 + try + execute 'set linespace=' . l:ls + catch + echohl ErrorMsg + echo 'Unable to set linespace=' . l:ls + echohl None + endtry + endif +endfunction + + +function! thematic#gui#setFullscreen(th) + if has('fullscreen') + " Because it can be jarring to see fullscreen disable, + " we'll only enable it. + if !&fullscreen && thematic#getThemeValue(a:th, 'fullscreen', -1) == 1 + try + set fullscreen + catch + echohl ErrorMsg + echo 'Fullscreen not supported' + echohl None + endtry + endif + + " Have the fullscreen background match the text background + if thematic#getThemeValue(a:th, 'fullscreen-background-color-fix', 0) + call s:updateFullscreenBackground() + endif + endif +endfunction + + +" If no explicit settings on lines and columns in +" either the theme or the defaults, then leave alone. +function! thematic#gui#setColumnsAndLines(th) + let l:columns = thematic#getThemeValue(a:th, 'columns', 0) + if l:columns > 0 + execute 'set columns=' . l:columns + elseif thematic#getThemeValue(a:th, 'maxhorz', 0) + set columns=999 + endif + let l:lines = thematic#getThemeValue(a:th, 'lines', 0) + if l:lines > 0 + execute 'set lines=' . l:lines + elseif thematic#getThemeValue(a:th, 'maxvert', 0) + set lines=999 + endif +endfunction + + +function! thematic#gui#adjustColumns(delta) + let l:nu_cols = &columns + a:delta + silent execute "set columns=" . l:nu_cols +endfunction + +" vim:ts=2:sw=2:sts=2 diff --git a/plugin/thematic.vim b/plugin/thematic.vim index 49b00eb..f03294e 100644 --- a/plugin/thematic.vim +++ b/plugin/thematic.vim @@ -17,10 +17,12 @@ let g:thematic#theme_name = '' " Preserve original settings -let g:thematic#original = { - \ 'laststatus': &laststatus, - \ 'ruler': &ruler, - \ } +let g:thematic#original = {} +let g:thematic#original.laststatus = &laststatus +let g:thematic#original.ruler = &ruler +if has('fullscreen') + call thematic#gui#initFullscreen() +endif " Defaults if !exists('g:thematic#defaults') diff --git a/plugin/thematic/gui.vim b/plugin/thematic/gui.vim new file mode 100644 index 0000000..fa5cc91 --- /dev/null +++ b/plugin/thematic/gui.vim @@ -0,0 +1,50 @@ +" ============================================================================ +" File: plugin/gui.vim +" Description: script for vim-thematic-gui plugin +" Maintainer: Reed Esau +" Last Change: December 30, 2013 +" License: The MIT License (MIT) +" ============================================================================ + +if exists('g:loaded_thematic_gui') || &cp | finish | endif +let g:loaded_thematic_gui = 1 + +" Save 'cpoptions' and set Vim default to enable line continuations. +let s:save_cpo = &cpo +set cpo&vim + +function! thematic#gui#init(...) + let l:th = a:0 ? a:1 : {} + call thematic#gui#setFont(l:th) + call thematic#gui#setTransparency(l:th) + call thematic#gui#setLinespace(l:th) + call thematic#gui#setFullscreen(l:th) + call thematic#gui#setColumnsAndLines(l:th) +endfunction + +function! thematic#gui#initFullscreen() + " Take control of fullscreen behavior from Vim, specifically to + " override its default behavior of maximizing columns and lines + " in fullscreen Vim. + if has('fullscreen') + let l:fuopts = split(&fuoptions, ',') + if index(l:fuopts, 'maxvert') != -1 + let g:thematic#original.maxvert = 1 + " NOTE removing maxvert results in a screen redraw problem + " if Ctrl+Command+F hit before switching themes, + " so we'll remove it here. + "set fuoptions-=maxvert + endif + if index(l:fuopts, 'maxhorz') != -1 + let g:thematic#original.maxhorz = 1 + set fuoptions-=maxhorz + endif + endif +endfunction + +command -nargs=0 ThematicNarrow call thematic#gui#adjustColumns(-5) +command -nargs=0 ThematicWiden call thematic#gui#adjustColumns(5) + +let &cpo = s:save_cpo +unlet s:save_cpo +" vim:ts=2:sw=2:sts=2