Skip to content

Instantly share code, notes, and snippets.

@sim590
Last active March 11, 2019 08:59
Show Gist options
  • Save sim590/08aa6f8df00f0784f36af96feaa80828 to your computer and use it in GitHub Desktop.
Save sim590/08aa6f8df00f0784f36af96feaa80828 to your computer and use it in GitHub Desktop.
" Désactive les replis des sections par le plugin vim-markdown
set nofoldenable
let g:vim_markdown_folding_disabled = 1
"""""""""""""""""""""""""""""""
" Variables de localisation "
"""""""""""""""""""""""""""""""
" NOTE: Configurer les variables ci-après
" NOTE: Le fichier gabarit peut être téléchargé à l'adresse suivante:
" https://gist.github.com/293f9c32667bfe12a61046dd6664db8c
" Le chemin vers le fichier d'évaluation
let s:base_marking_file_path = "/home/simon/Documents/personnel/education/UQAM/maitrise_info/2019/emploi/INF1070/correction/tp1/évaluation.md"
" NOTE: Configurer
let s:CLASS_GROUP_NUMBER = 12
" NOTE: Configurer
let s:TEACHER_NAME = "Moussa Abdenbi"
""""""""""""""""""""""""""""""""
" Configuration de UltiSnips "
""""""""""""""""""""""""""""""""
" NOTE: Ignorer si le plugin n'est pas installé
let g:UltiSnipsSnippetsDir = "/home/simon/Documents/personnel/education/UQAM/maitrise_info/2019/emploi/INF1070/correction/tp1/Ultisnips"
let g:UltiSnipsSnippetDirectories += [g:UltiSnipsSnippetsDir]
""""""""""""""""""""""""""""""""""""""
" Expressions régulières courantes "
""""""""""""""""""""""""""""""""""""""
let s:GROUP_RE = '\(^-\s*Groupe\s*:\)\s*\(.*\)'
let s:MISSION_NONUM_RE = '^##\s*\(Solution\s\+de\s\+la\s\+\)\?[mM]ission'
let s:MISSION_RE = s:MISSION_NONUM_RE.'\s\+\([0-9]\+\)'
let s:MARK_RE = '\(^\*\*Note\*\*\s*:\s*\)\(-\?\s*[0-9]\+\|X\+\)/\([0-9]\+\)'
let s:PENALITY_RE = '\(\*\*\s*Pénalité\s*\*\*\s*:\)\s*\([0-9]\+\)\s*pts'
let s:COMMENT_RE = '^###\s*Commentaires'
let s:NOTHING_TO_NOTICE = '^Rien à signaler.$'
let s:NOTHING_DONE = "Rien de fait."
fun! s:get_marking_file_path()
let l:path = expand('%')
let l:mdfile_re = '\(.*\)\.md$'
if matchstr(l:path, l:mdfile_re) == "" | return "" | endif
let l:m = matchlist(l:path, l:mdfile_re)
return match(l:m[1], '_ÉVALUATION$') == -1 ? l:m[1]."_ÉVALUATION.md" : l:path
endf
fun! s:create_marking_file(path)
call system("cp '".s:base_marking_file_path."' '".a:path."'")
endf
fun! s:init_marking_file()
" Assurer qu'on se trouve dans le répertoire du fichier (au cas où 'autochdir' n'est pas
" configuré).
let l:mf = s:get_marking_file_path()
if l:mf == ""
echoerr "Ce fichier n'est pas un fichier Markdown."
return
endif
if filereadable(l:mf) == v:false
call s:create_marking_file(l:mf)
call s:apply_identification(l:mf)
endif
endf
fun! s:go_to_bufwin(expr)
let l:wid = getbufinfo(a:expr)
let l:lb = bufnr('%')
if l:wid != [] && l:wid[0]['windows'] != []
call win_gotoid(l:wid[0]['windows'][0])
return l:lb
endif
if match(a:expr, '^[0-9]\+$') == -1
exec "silent argadd ".fnameescape(a:expr)
endif
exec 'silent buffer! '.a:expr
return l:lb
endf
fun! s:apply_identification(path)
let l:cp = getcurpos()
call cursor(1,1)
if search(s:GROUP_RE, 'W') != v:false
" Copie du bloc d'identification dans le registre i
silent normal vip"iy
let l:b = s:go_to_bufwin(a:path)
call cursor(1,1)
if search(s:GROUP_RE, 'W') != v:false
" Remplacement du bloc d'identifcation par le registre i
silent normal vip"ip
let [l:il, l:_] = searchpos('## Identification', 'nb')
let [l:pl, l:_] = searchpos('## Présentation globale', 'n')
let l:subs = {
\ '[`<>]' : '',
\ 'numéro du groupe' : s:CLASS_GROUP_NUMBER,
\ 'nom de votre enseignant' : s:TEACHER_NAME
\ }
for [l:from,l:to] in items(l:subs)
execute 'silent! '.l:il.','.l:pl.'substitute/'.l:from.'/'.l:to.'/g'
unlet l:from l:to
endfor
endif
silent write
call s:go_to_bufwin(l:b)
endif
call setpos('.', l:cp)
endf
fun! s:get_cur_mission()
let l:cp = getcurpos()
let l:mn = 0
if search(s:MISSION_RE, 'bW') != v:false
let l:mn = matchlist(getline('.'), s:MISSION_RE)[2]
endif
call setpos('.', l:cp)
if l:mn < 2 || l:mn > 19
echoerr "Les seules missions notées sont les missions 2 à 19"
return -1
else
return l:mn
endif
endf
fun! s:notice_nothing_done()
call s:init_marking_file()
let l:mf = s:get_marking_file_path()
let l:mn = s:get_cur_mission()
if l:mn == -1 | return | endif
let l:cp = getcurpos()
let l:b = s:go_to_bufwin(l:mf)
if search(s:MISSION_NONUM_RE.' '.l:mn, 'w') == v:false || search(s:COMMENT_RE, 'w') == v:false
return
endif
let l:cline = getcurpos()[1]
let l:endp = line('$')
if search(s:MISSION_NONUM_RE.' '.(l:mn+1), 'w') != v:false
let l:endp = getcurpos()[1]
endif
let l:already_commented = v:false
try
execute 'silent '.l:cline.','.l:endp.'substitute/'.s:NOTHING_TO_NOTICE.'/'.s:NOTHING_DONE.'/g'
silent write
catch /E486/
" La substitution a échouché.
let l:already_commented = v:true
echoerr "La mission est déjà commentée."
finally
call s:go_to_bufwin(l:b)
call setpos('.', l:cp)
normal zz
endtry
if l:already_commented == v:false
echo "Mission ".l:mn." noté comme non-complétée."
endif
endf
fun! s:attribute_mark(mark)
call s:init_marking_file()
let l:mf = s:get_marking_file_path()
let l:mn = s:get_cur_mission()
if l:mn == -1 | return | endif
let l:cp = getcurpos()
" TODO: Penser à utiliser un wrapper pour ces bouts de code répétitifs...
" Voir: https://vi.stackexchange.com/questions/3920/is-it-possible-to-use-a-delegate-or-to-pass-a-function-as-argument-in-vimscript
let l:b = s:go_to_bufwin(l:mf)
if search(s:MISSION_NONUM_RE.' '.l:mn, 'w') != v:false && search(s:MARK_RE) != v:false
let l:m = matchlist(getline('.'), s:MARK_RE)
if l:m[3] < a:mark
echoerr "La note attribué ".l:mn." est plus élevée que le total (".l:m[3].")"
call s:go_to_bufwin(l:b)
call setpos('.', l:cp)
return
endif
call setline(line('.'), l:m[1].a:mark.'/'.l:m[3])
silent write
echo "Mission ".l:mn." noté: ".a:mark."/".l:m[3]
endif
call s:go_to_bufwin(l:b)
call setpos('.', l:cp)
normal zz
endf
fun! s:go_to_comment_section()
call s:init_marking_file()
let l:mf = s:get_marking_file_path()
let l:mn = s:get_cur_mission()
if l:mn == -1 | return | endif
call s:go_to_bufwin(l:mf)
call search(s:MISSION_NONUM_RE.' '.l:mn)
call search(s:COMMENT_RE)
" Le commentaire est deux lignes plus bas.
normal 2jzz
endf
fun s:mark_total()
let l:total = system('paste -sd+ <(grep -oP "\*\*Note\*\*:\s+\K[0-9]{1,3}" "'.expand('%').'") | bc')
let l:cp = getcurpos()
call cursor(1,1)
if search(s:PENALITY_RE, 'W') != v:false
let l:total -= matchlist(getline('.'), s:PENALITY_RE)[2]
endif
let l:total_re = substitute(s:MARK_RE, 'Note', 'Note totale', "")
if search(l:total_re) != v:false
let l:m = matchlist(getline('.'), l:total_re)
call setline(line('.'), l:m[1].l:total.'/'.l:m[3])
endif
noautocmd write
call setpos('.', l:cp)
endf
fun! s:go_to_presentation_evaluation_section()
call s:init_marking_file()
let l:mf = s:get_marking_file_path()
call s:go_to_bufwin(l:mf)
call search('^##\s*Présentation\s*globale')
call search(s:COMMENT_RE)
normal 2jzz
endf
fun s:next_mission(re, flags, c)
let l:max = a:c == 0 ? 1 : a:c
let l:i = 0
let l:beginpos = getcurpos()
while l:i < l:max
if search(a:re, a:flags) == v:false
return
endif
let l:i += 1
endw
let l:cursorp = getcurpos()
let l:endlnum = line('$')
if search(a:re, a:flags) != v:false
let l:endlnum = getcurpos()[1]
elseif a:flags =~ 'b'
call setpos('.', l:beginpos)
return
endif
let l:cursorp[1] += (l:endlnum-l:cursorp[1])/2
call setpos('.', l:cursorp)
normal zz
endf
"""""""""""""""""""""""""""""
" Association des touches "
"""""""""""""""""""""""""""""
nnoremap <leader>gm :<C-U>call <SID>attribute_mark(v:count)<CR>
nmap gm <leader>gm
nnoremap <leader>nd :<C-U>call <SID>notice_nothing_done()<CR>
nnoremap <leader>gc :call <SID>go_to_comment_section()<CR>
nmap gC <leader>gc
nnoremap <leader>gp :call <SID>go_to_presentation_evaluation_section()<CR>
nmap gp <leader>gp
execute "nnoremap <silent> [[ :<C-U>call <SID>next_mission('".s:MISSION_RE."', 'bW', v:count)<CR>"
execute "nnoremap <silent> ]] :<C-U>call <SID>next_mission('".s:MISSION_RE."', 'W', v:count)<CR>"
" calcul du total après chaque modification
au! BufWritePost *_ÉVALUATION.md call <SID>mark_total()
au! BufEnter *_solutions-tp1.md set readonly
if expand('%') =~ '.*_solutions-tp1.md$'
set readonly
endif
" vim: set sts=2 ts=2 sw=2 tw=100 et :
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment