From 4d47c79bafbd6d261bd8e8de9a471838942a42c7 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 6 Aug 2012 19:33:21 +0200 Subject: vim plugin: incremental printing of search results. Inspired by the same feature in the ruby plugin by Felipe Contreras. --- vim/plugin/nm_vim.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/vim/plugin/nm_vim.py b/vim/plugin/nm_vim.py index ef1dfb3..582ccae 100644 --- a/vim/plugin/nm_vim.py +++ b/vim/plugin/nm_vim.py @@ -26,10 +26,12 @@ import mailcap import mimetypes import notmuch import os, os.path +import Queue import shlex import smtplib import subprocess import tempfile +import threading import vim #### classes #### @@ -126,6 +128,14 @@ class Search(NMBuffer): This buffer displays results of a db search -- a list of found threads. """ + # a fifo of pending results that should be inserted into vim buffer + # written to by _refresh_thread, read by process_results + _results = None + + _search_thread = None + + _finish = 0 + def __init__(self, querystr = '', parent = None): super(Search, self).__init__() @@ -143,14 +153,30 @@ class Search(NMBuffer): self.refresh() def refresh(self): + if self._search_thread: + self._finish = 1 + self._search_thread.join() + self._finish = 0 + self.objects = [] - b = vim.current.buffer + self._results = Queue.Queue() + + vim.command('augroup nm_vimpy') + vim.command('autocmd CursorMoved python nm_vim.get_current_buffer().process_results()') + vim.command('augroup END') + + self._search_thread = threading.Thread(target = self._refresh_thread) + self._search_thread.start() + + def _refresh_thread(self): db = notmuch.Database() q = db.create_query(self.id) q.set_sort(q.SORT.NEWEST_FIRST) # FIXME allow different search orders for t in q.search_threads(): - start = len(b) + if self._finish: + break + datestr = get_relative_date(t.get_newest_date()) authors = t.get_authors() @@ -165,9 +191,29 @@ class Search(NMBuffer): subj = t.get_subject() tags = str(t.get_tags()) - b.append((u'%-12s %3s/%3s %-20.20s | %s (%s)'%(datestr, t.get_matched_messages(), t.get_total_messages(), - authors, subj, tags)).encode('utf-8')) - self.objects.append(NMBufferElement(start, len(b) - 1, t.get_thread_id())) + line = (u'%-12s %3s/%3s %-20.20s | %s (%s)'%(datestr, t.get_matched_messages(), t.get_total_messages(), + authors, subj, tags)).encode('utf-8') + self._results.put((line, t.get_thread_id())) + + def process_results(self): + b = vim.current.buffer + + vim.command('setlocal modifiable') + try: + while True: + start = len(b) + line, tid = self._results.get(block = False) + + b.append(line) + self.objects.append(NMBufferElement(start, len(b) - 1, tid)) + except Queue.Empty: + pass + vim.command('setlocal nomodifiable') + + if self._search_thread and not self._search_thread.is_alive(): + vim.command('autocmd! nm_vimpy') + self._results = None + self._search_thread = None def __repr__(self): return ''%(self.id) -- cgit v1.2.3