Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# vim
*.swp
114 changes: 106 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,110 @@
# vim-deckset

Deckset is a mac application for rendering markdown as presentation. It has
a nifty feature of a preview window that can float on top of things. This
window can be scripted using AppleScript, and this plugin will change the
contents of the preview window as you move around in your presentation md file.
_Originally based upon [omega/vim-deckset](https://github.com/omega/vim-deckset) but mostly rewritten_

## Note
Contents:
1. [About](#about)
2. [Installation](#installation)
3. [Implementation Notes](#implementation-notes)

This is by no means complete. It is currently enabled for all markdown files,
and the osascript call happens for all files, so depending on the speed of that
it might anoy you. It doesn't anoy me yet.
## About

[Deckset](http://decksetapp.com) is an OS X application for rendering markdown
as presentation.

It has a nifty floating preview window that shows up in edit mode, and by default
updates the view when the markdown file is saved. By default it makes a best guess
as to what the last modified section is, and tries to update the preview to that
slide.

It turns out however, that Deckset's preview window can be scripted using AppleScript and JavaScript Automation.

For us [Vim](http://www.vim.org) users, we can do a bit better than
the default behavior. This Vim plugin will, under the right
circumstances, update the contents of the preview window
__as you move your VIM cursor__ around in the Markdown file.

## Installation

Best way is to use [Pathogen](https://github.com/tpope/vim-pathogen), and simply checkout this git repo under your Pathogen bundle directory (typically `~/.vim/bundle`). If you've set Pathogen up properly it will automatically load at Vim boot.

Otherwise, by hand:

- Copy `vim-deckset/after/ftplugin/deckset.vim` to `~/.vim/after/ftplugin/deckset.vim`
- Copy `vim-deckset/after/ftdetect/deckset.vim` to `~/.vim/after/ftdetect/deckset.vim`
- Copy `vim-deckset/syntax/deckset.vim` to `~/.vim/syntax/deckset.vim`

## Implementation Notes

In order to avoid conflicting with your existing Markdown plugins & syntax
detectors when you _are not_ running Deckset, the plugin takes a few extra
safety steps.

- It checks both if Deckset is running, and the file you're editing is _open inside of Deckset_.
- If these conditions are met, your Vim filetype is set to ‘deckset’.
- Apart from the syntax highlighting files, this plugin should be run out of the `.vim/after` folders, so that it makes sure to pick up and set the ‘deckset’ filetype without it later being overridden by other Markdown detectors (assuming those aren't _also_ loaded in `after`).

In addition, there's an enhanced Vim syntax file based on
[tpope/vim-markdown](https://github.com/tpope/vim-markdown), which attempts
to specifically support all of the Deckset Markdown, including LaTeX
recognition inside formula blocks (If you have the optional Formula plugin
for Deckset).

Brilliantly, Tim Pop's Markdown code supports replacing the code inside of
fenced code blocks with proper Syntax highlighting (it seems the sub-highlighting only shows up on _some_ colorschemes). This works only for languages set in the global
setting (placed in your `~/.vimrc`) `g:markdown_fenced_languages`. To add
support for Scala code highlighting, add the following:

```vim
let g:markdown_fenced_languages = ["scala"]
```

It is an array, so you can add many languages. I've preserved the same
variable name as Tim Pope's Markdown as there's no conflict, so you only need
one global setting for both Tim Pope's markdown and deckset-markdown.

Additonally, as long as you have a `tex` syntax highlighting plugin in your
Vim setup, Deckset formulas will syntax highlight similarly-you do not need to
add `tex` to the `g:markdown_fenced_languages` setting.

I've seen issues with terminal based Vim acting odd & glitchy when the plugin is activated. As a result, by default I have the plugin set to only execute only when the GUI mode (aka MacVim) is running. If you'd like to change it you can set the following in your `.vimrc` file:

```vim
let g:DecksetRequireGUI = 0
```

In order to not totally overload your Vim session by running everytime you
move through the file, `vim-deckset` updates the preview window on the following conditions:

- `CursorHold` – In Command mode, if the Cursor hasn't moved in `g:DecksetPreviewPauseTime` milliseconds
- `CursorHoldI` - In Insert mode, if the Cursor hasn't moved in `g:DecksetPreviewPauseTime` milliseconds
- `BufRead` - The file is read from disk (such as when we first open)
- `BufWrite` - When the file is saved
- `FocusGained` - The Vim window is brought to the foreground
- `InsertLeave` - Insert mode is exited

The default for `g:DecksetPreviewPauseTime` is 500 milliseconds. You can
change that by setting a new value (in milliseconds) in your
`.vimrc`:


```vim
let g:DecksetPreviewPauseTime = 750
```

Additionally, `vim-deckset` is set to automatically save the file if any of the
above conditions trigger & the file buffer is modified. If you'd like to
disable that behavior, you can turn it off in your `.vimrc`:

```vim
let g:DecksetAutosave = 0
```

Finally, if you'd like to force an update to the Deckset Preview window, you
can either run:

```vim
:call UpdateDecksetPreview()
```

Or, if `<leader>` is set, `<leader>R`.
36 changes: 36 additions & 0 deletions after/ftdetect/deckset.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
let s:path = fnamemodify(resolve(expand('<sfile>:p')), ':h:h')

" Should we only run when a GUI VIM is running (i.e. MacVim)
" I've seen really odd performance & glitching on CLI VIM
" when the Deckset support is running
if !exists('g:DecksetRequireGUI')
let g:DecksetRequireGUI = 1
endif


function! IsDecksetFile()
if (!g:DecksetRequireGUI || has("gui_running"))
let l:output = system('osascript '.s:path.'/support/is-deckset-file.js '.shellescape(expand('%:p')))


if v:shell_error == 1
" So we only skim the app runthrough once per vim session
" Many markdown implementations want 4 space tabs
set filetype=deckset sw=4 ts=4 backupcopy=yes
let g:IsDecksetRunning = 1
let g:IsDecksetOpenFile = 1
elseif v:shell_error == 0
let g:IsDecksetRunning = 1
let g:IsDecksetOpenFile = 0
else
let g:IsDecksetRunning = 0
endif

endif
endfunction


au! BufRead,BufNewFile * if &ft == ("markdown" || "ghmarkdown") | call IsDecksetFile() | endif

"set filetype=deckset ts=4 sw=4

45 changes: 45 additions & 0 deletions after/ftplugin/deckset.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
noremap <silent> <buffer> <leader>R :call s:UpdateDecksetPreview()<CR>
command! -nargs=0 -bar DecksetUpdate call s:UpdateDecksetPreview()

let s:path = fnamemodify(resolve(expand('<sfile>:p')), ':h:h')


" Pause on CursorHold before update, in milliseconds
if !exists('g:DecksetPreviewPauseTime')
let g:DecksetPreviewPauseTime = 500
endif

" Automatically save on update if buffer modified?
if !exists('g:DecksetAutosave')
let g:DecksetAutosave = 1
endif

function! s:UpdateDecksetPreview()
" todo - should we check if it's a deckset file as detected?
if (!g:DecksetRequireGUI || has("gui_running")) && g:IsDecksetRunning == 1
if &modified && g:DecksetAutosave
" Should save?
write
endif
silent !clear


let l:charPos = line2byte(search('^---$', 'bnW')) + 4
silent let l:output = system('osascript '.s:path.'/support/update-deckset.js '
\ . shellescape(expand('%:p')) . ' '
\ . shellescape(l:charPos)
\)
echo l:output
endif
endfunction


augroup Deckset
autocmd!
" TODO - detect if this file is even open in deckset to cut
" down on performance issues for non-deckset editing
" adjust me for CursorHold Tweaks
execute "set updatetime=".g:DecksetPreviewPauseTime
autocmd CursorHold,CursorHoldI,BufRead,BufWrite,FocusGained,InsertLeave * if &ft == "deckset" | call s:UpdateDecksetPreview() | endif

augroup END
81 changes: 81 additions & 0 deletions after/support/is-deckset-file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* JavaScript for Mac Automation of Deckset.app
* (what do you call JavaScript used like Applescript?)
*
* http://github.com/bwmcadams/vim-deckset
* Author: Brendan McAdams <brendan@evilmonkeylabs.com>
*
* Based upon http://github.com/omega/vim-deckset
*
*
* Checks if a markdown file is open in Deckset, so we can decide
* if we set the filetype to Deckset and run the preview update
* or set it to standard Markdown
*
* Arguments:
* filePath - a String containing the path + filename of the Markdown file for the slide deck (we'll check if it's a slide deck rather.
*/

// Look for a running instance of Deckset
ObjC.import('stdlib')
ObjC.import('AppKit')

var isRunning = false

var apps = $.NSWorkspace.sharedWorkspace.runningApplications // Note these never take () unless they have arguments

apps = ObjC.unwrap(apps) // Unwrap the NSArray instance to a normal JS array

var app, deckset

for (var i = 0, j = apps.length; i < j; i++) {
app = apps[i]

// Another option for comparison is to unwrap app.bundleIdentifier
// ObjC.unwrap(app.bundleIdentifier) === 'org.whatever.Name'

// Some applications do not have a bundleIdentifier as an NSString
if (typeof app.bundleIdentifier.isEqualToString === 'undefined') {
continue
}

if (app.bundleIdentifier.isEqualToString('com.unsignedinteger.Deckset')) {
isRunning = true
break
}
}

if (!isRunning) {
$.exit(-1)
}

deckset = Application('Deckset')

function run(argv) {
var filePath = argv[0]

deckset.includeStandardAdditions = true

// This is terrible code but my javascript-fu is weak these days
if (typeof filePath === 'undefined') {
$.exit(0)
} else {

var documents = deckset.documents

var files = deckset.documents.whose({ file: filePath })

if (files.length != 1) {
/* turn off preview window if we aren't editing
* a deckset file.
* You may want to comment this out if it
* isn't to your preference.
* TODO: VIM Setting for this.
*/
deckset.preview = false
}

$.exit(files.length)
}
}

37 changes: 37 additions & 0 deletions after/support/open-deckset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* JavaScript for Mac Automation of Deckset.app
* (what do you call JavaScript used like Applescript?)
*
* http://github.com/bwmcadams/vim-deckset
* Author: Brendan McAdams <brendan@evilmonkeylabs.com>
*
* Based upon http://github.com/omega/vim-deckset
*
*
* Toggles open Deckset, and opens the given file in it.
*
* Arguments:
* filePath - a String containing the path + filename of the Markdown file for the slide deck (we'll check if it's a slide deck rather.
*/

// Look for a running instance of Deckset
ObjC.import('stdlib')
ObjC.import('AppKit')


function run(argv) {
var filePath = argv[0]

var deckset = Application("Deckset")
deckset.includeStandardAdditions = true

// This is terrible code but my javascript-fu is weak these days
if (typeof filePath === 'undefined') {
console.log("WARNING: No file specified.")
$.exit(0)
} else {
deckset.open(Path(filePath))

$.exit(1)
}
}
58 changes: 58 additions & 0 deletions after/support/update-deckset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* JavaScript for Mac Automation of Deckset.app
* (what do you call JavaScript used like Applescript?)
*
* http://github.com/bwmcadams/vim-deckset
* Author: Brendan McAdams <brendan@evilmonkeylabs.com>
*
* Based upon http://github.com/omega/vim-deckset
*
* When called with appropriate arguments, updates the preview window &
* main Deckset view for a given slide deck to the appropriate slide for
* whatever 'position' corresponds to in 'filePath'
*
* Arguments:
* filePath - a String containing the path + filename of the Markdown file for the slide deck
* position - an Integer containing the position (line number?) in the slide deck to update view to
*/

ObjC.import('stdlib')
ObjC.import('AppKit')

function run(argv) {
var filePath = argv[0]
var position = argv[1]


deckset = Application('Deckset')
deckset.includeStandardAdditions = true

// This is terrible code but my javascript-fu is weak these days
if (typeof filePath === 'undefined') {

console.log("Invalid use of VIM Deckset: Must provide path of markdown file being edited.")

} else if (typeof position === 'undefined') {

console.log("Invalid use of VIM Deckset: Must provide current position in markdown file.")

} else {

/* turn on preview window.
* You may want to comment this out if it
* isn't to your preference
*/
deckset.preview = true


var files = deckset.documents.whose({ file: filePath })

if (files.length != 1) {
$.exit(0)
} else {
files[0].position = position

$.exit(1)
}
}
}
Loading