2015年7月26日日曜日

一日一ファイル形式のテキストメモ


あいさつ



つかさです。
xyzzyで一日一ファイル形式のメモを取れるようにしてみる。

以下を site-lispフォルダに保存。

onedaymemo.l
; -*- Mode: Lisp -*-
;
;  メモファイルを引数のディレクトリに作成する
;
;  キーバインド
;      C-x,C-x     新たな見出し
;
;  Installation:
;
;      ~/.xyzzy または $XYZZY/site-lisp/siteinit.l に以下のコードを追加
;
;              (require "onedaymemo")

(defun make-onedaymemo-file (memo-dir)
  (let* ((filename (format-date-string "%Y-%m-%d.txt"))
  (filepath (merge-pathnames filename memo-dir))
  (directory (directory-namestring filepath)))
    (if (not (file-directory-p directory))
 (create-directory directory))
    (find-file filepath)
    (if (eq (point-max) (point-min))
 (insert (format-date-string "%d %b %Y %H:%M:%S\n\n  * : "))
      (progn
 (goto-char (point-max))
 (insert (format-date-string "\n\n  * : "))))))

(defun onedaymemo ()
  (interactive)
  (if si:*command-line-args* (setq x (pop si:*command-line-args*))(setq x nil))
  (make-onedaymemo-file x)
  (onedaymemo-mode))

(defun onedaymemo-mode ()
  (interactive)
  (kill-all-local-variables)
  (setq buffer-mode 'onedaymemo-mode)
  (setq mode-name "One Day Memo")
  (use-keymap *onedaymemo-mode-map*))

(defvar *onedaymemo-mode-map* nil)
(unless *onedaymemo-mode-map*
  (setq *onedaymemo-mode-map* (make-sparse-keymap))
  (define-key *onedaymemo-mode-map* '(#\C-x #\C-x)
       #'(lambda ()
    (interactive)
    (goto-char (point-max))
    (insert (format-date-string "\n\n  * : ")))))

次いで.xyzzyに以下を追加。
(require "onedaymemo")

引数として指定したフォルダに、特定の書式でメモファイルを作るスクリプトです。

その日に一度もメモを取っていなければ、メモファイルを新規作成。ファイル名は2015-07-25.txtのように日時から自動で付けられる。その日に既にメモを取っていれば、その日のメモファイルを開き、新しい見出しからはじめる。内容は
25 Jul 2015 17:03:46

  * : Changelogのテスト

書式をChangeLogっぽく変えてみる

  * : 日付

日付とかはどうせファイルで分かるから不要?最初に起動するときだけにするとか。
あとは時間。これは本当に必要か?時間的なことが書きたいのなら、文中でやればいいだけかも。タイトルの区切りだけ入れるとか。
また、起動時に新規に作成するようにするか。
日付が必要な場合と不要な場合。あまり使わないだろうか。
あとはキーバインドをどうするか。C_x2度押しとか単純なのでいいかも。

  * : PPvの一時コマンド

なぜか中に入っていない。

みたいになる。

また、C_x二回押しで、カーソルを末尾に移動し、次の見出しをコピペする。

PPxへの登録


これを、PPxから起動できるようにする。

以下を編集して取込。
KC_main = { ; PPcメイン窓
^Z ,*setnextkey K_launcher
}

K_launcher = { ** comment **
C ,%Ob D:\bin\xyzzy\xyzzy.exe -e (onedaymemo) D:\Work\Log
}

C_z c(Ctrl+Zを押したあとにCを押す)

で起動します。フォルダパスは適宜変更を。

何で作ったか


僕は普段、howm形式でメモを取っているのだが、本を読みながらのメモ、作業してる時のちょっとしたメモ、誰かに出会った時の記録等については、howmはあまり適していないと思っていた。そこで、一ファイル形式の時系列順でメモれる方法を探していた。

この用途として以前使ってたのはCatMemoNoteだった。メモ間の区切りは区切り線で。日付についてはホットキーを設定し、適宜挟み込むというようにしていた。



これはこれで悪くはなかったのだが、時たま新規にメモを作成しないと、1ファイルが非常に長くなってしまうのが嫌だった。だが、新規メモを適宜作るようにすると、以前作ったメモが残ったままになるので、それはそれで鬱陶しい。

そこで、それを解消し、かつ僕が追求してる「すべての動作をPPx基点で行う」にあわせた方法を考えて、このスクリプトを作ってみた。書式はchangelog.lを参考にしてます。


2015年7月17日金曜日

初期化とPPXDEF.CFG

PPxの初期化時、PPxフォルダにPPXDEF.CFGがあれば、それによる初期カスタマイズが自動で行われる。
だから、初期化時でも消したくない設定があれば、PPXDEF.CFGをエディタで編集して、末尾に追加しておけばいいわけだ。

僕は、カスタマイズ用メニューを追加している。初期化したあと、必要なCFGファイルのみをマークして、取り込むということをしているのだが、その時にカスタマイズ用メニューが使えると楽だからだ。
KC_main = { ; PPcメイン窓
F12 ,%M_cust,C
}
KV_main = { ; PPvメイン窓
F12 ,%M_cust,C
}

-|M_cust =
M_cust    = { ** comment **
カスタマイザ(&C) = %K"@CUSTOMIZE"
編集して取込(&E) = %Ob *PPCUST /edit
-- = 
取り込み(&1) = %Q"%FCを取り込みます"%:%Ob *PPCUST CS "%FCD"
追加(&2) = %Q"追加取込します"%:*customize @%FCD
-- = 
PPX.CFGを取り込み(&3) = %Q"PPX.CFGを取り込みます"%:%Ob *PPCUST CS "%0\PPX.CFG"
PPX.CFGに書き出し(&4) = %Q"PPX.CFGに書き出します"%:%Ob *PPCUST CD "%0\PPX.CFG"
指定書き出し(&5) = %"指定ファイルに書き出します"%Ob *PPCUST CD %{%1\PPX-%*nowdatetime(y-N-D)%|.CFG%}
-- = 
初期化(&I) =  %Q"初期化します"%:%Ob *PPCUST CINIT
-- = 
アップデート(&U) = %Ob *checkupdate p
バージョン情報(&V) = %K"@ABOUT"
}

カスタマイズで色々なところをいじってて、状態を元に戻したいなと思ったら、F12を押してカスタマイズ用メニューを出し、初期化する。
そして、CFGフォルダに行って、必要なCFGファイルをマーク。再びF12を押して、メニューから追加を選択。これで、その設定を取り込むことができる。

2015年7月14日火曜日

ブックマークリストをローテート


挨拶


僕は、ブックマークをリストファイルの形で管理しており、それをメニューで呼び出せるようにしている(参考:ブックマークをリストファイルにして保存)。




今回は、ブックマークリストの切り替えを、メニューを介さずに行う方法を考察する。ちなみに、ブックマーク自体については


を参照のこと。

準備


上に載せたリンクから、

  • setalias.js
  • resetalias.js
  • rotateExecute3.js
  • alias2file.js
  • file2allias.js
  • bookmarkmenu.js

をScriptフォルダに保存しておく。

今回、新しく導入するのは、次のスクリプト。これもScriptフォルダに保存する。


RotateSubFile.js


//!*script

// フォルダ内のファイルパスを順番に返す
// 第一引数:フォルダパス
// 第二引数:識別子

// 引数がなければ終了
if (PPx.Arguments.Length < 2){
  PPx.SetPopLineMessage("引数が正しくありません。");
  PPx.Quit(-1);
}

fs = PPx.CreateObject("Scripting.FileSystemObject");
var objFileSys = new ActiveXObject("Scripting.FileSystemObject");
var fn = PPx.Arguments.Item(0);
var id = PPx.Arguments.Item(1);
var CurrentFile;

// フォルダが存在しなければ終了
if (objFileSys.FolderExists(fn) == false) {
  PPx.SetPopLineMessage(fn+"は存在しません");
  PPx.Quit(-1);
}

// 同階層のフォルダのリストを取得
objFolder = objFileSys.GetFolder(fn);
e = new Enumerator(objFolder.Files); 
flds = new Array(); 
for( ; !e.atEnd(); e.moveNext()) {
  flds.push(e.item().Name);
}
// フォルダが空なら終了
if (!flds[0]) {
  PPx.SetPopLineMessage("ファイルは存在しません");
  PPx.Quit(-1);
}
// 識別子が空ならリストの一番目を代入
if (!PPx.Extract("%'"+id+"'")){
  CurrentFile = flds[0];
} else {
  CurrentFile = PPx.Extract("%'"+id+"'");
}

// ファイルの位置を取得
for(i = 0; i < flds.length; i++) {
  if( flds[i] == CurrentFile ) break;
}

var nextFile = flds[Math.min(i+1, flds.length-1)]; // 次のファイルを取得

// カレントフォルダがリスト最後なら最初にループ
if (nextFile == CurrentFile) {
  nextFile = flds[0];
}

PPx.Execute("*set "+id+" = "+ nextFile); // 識別子に次のファイルをセット
PPx.Result = fs.BuildPath(fn,nextFile); // 値を返す


スクリプトの説明


このスクリプトは、

  • フォルダパス
  • 識別子

の二つの引数を取る。与えられたフォルダパス内にあるファイルパスを、1つずつ順番に返すスクリプトだ。

%0\Script\RotateSubFile.js,%0\bookmark,blistid
 
とすると、PPxフォルダのBookmarkフォルダ内のファイルを、順番に返す。例えば、Bookmarikフォルダ内が以下のようだとする。



すると、このスクリプトを実行する度に、

default.txt → 基本.txt → メモ.txt → 画像フォルダ.txt → default.txt → 基本.txt ……


の順番で、フルパスを返す。

このスクリプトと、file2alias.jsを組み合わせる。file2alias.jsは、第一引数にリストファイルのパスを、第二引数に変更したいエイリアスを取るスクリプト。そこで、この第一引数として、RotateSubFile.jsを与えれば、Bookmarkフォルダにあるリストを切り替えることができるわけだ。


*script %0\Script\file2alias.js,%*script("%0\Script\RotateSubFile.js","%0\bookmark","blistid"),bookmark

こんな感じですね。

編集して取込


次に、以下を編集して取込。

-|K_bookmark =
-|K_bookmarklist =

KC_main = { ; PPcメイン窓
^S ,*setnextkey K_bookmark
^X ,*setnextkey K_bookmarklist
}

K_bookmark = { ** comment **
S , *script %0\Script\setalias.js,bookmark,%%1
R , *script %0\Script\resetalias.js,bookmark
^S , %j %*script("%0\Script\rotateExecute3.js","homu","bookmark")
',' , *script %0\Script\bookmarkmenu.js
}

K_bookmarklist = { ** comment **
^X , *set name=%*script("%0\Script\RotateSubFile.js","%0\bookmark","blistid") %: *linemessage %*name(X,%'name') %: *script %0\Script\file2alias.js,%'name',bookmark
X ,*linemessage defaultに戻しました %: *script %0\Script\file2alias.js,%0\bookmark\default.txt,bookmark
}

使い方


キーコマンドは以下。

  • C_x C_x    ブックマークリストを順次切り替え
  • C_x x    ブックマークリストをdefault.txtに切り替え
  • C_s s    フォルダをブックマークに登録
  • C_s r   ブックマークをリセット
  • C_s C_s    ブックマークしたフォルダに順次移動
  • C_s ","    ブックマークメニューを開く

C_x C_x で、ブックマークリストが切り替わる。今どのリストなのかは、左上にlinemessageで表示されるので、使いたいリストに行き当たるまで何度もC_x C_x 。



目的のリストに行き当たれば、次はC_s C_s 。これで、ブックマークリストに登録されているフォルダに順次切り替わる。

想定している使い方


ファイラを使って行う作業は、わりと限られていると思う。僕の場合は、

  • 画像ファイル管理
  • 文書の作成
  • ダウンロードしたファイルの利用

あたりだ。そして、それぞれの作業で使うフォルダというのも限られている。

  •  画像管理……個々の画像フォルダ
  •  文書の作成……メモフォルダ、ドキュメントフォルダ
  • ダウンロードしたファイルの利用……ダウンロードフォルダ、一時展開用フォルダ、ソフトウェアフォルダ

といったように。
ならば、作業ごとにブックマークリストを作っておき、それを順次切り替えれば、普段行うフォルダ移動というのは、だいたい網羅できてしまうのではないか。そう思って、今回の仕組みを考えた。

つまり、そのようなブックマークリストを作っておけば、後は

  • C_x C_x    ブックマークリストを順次切り替え
  • C_s C_s    ブックマークしたフォルダに順次移動 

の二つの操作だけで、たいていは目的のフォルダに行けて、効率性が上がるのではないか、ということです。