HashtagCandidate?.js

概要

#が入力されたときにハッシュタグを補完します。

@が#になってること、内部で持ってるハッシュタグリストしか参照しないこと以外Scripts/ScreenNameCandidate.js?と同じです。

必要条件

Azurea 1.3.2(API Level >= 15)

スクリプト

// ハッシュタグのリスト
var candidates = [];

// 前方一致で最初にマッチするインデックスを返す
Array.prototype.lowerBound = function(s){
	for(var i = 0; i < this.length; ++i){
		if(this[i].length >= s.length){
			if(this[i].slice(0, s.length) == s){
				return i;
			}
		}
	}
};

// 前方一致でマッチする項目を抽出する
Array.prototype.subset = function(s){
	var arr = [];
	var idx = this.lowerBound(s);
	for(var i = idx; i < this.length; ++i){
		if(this[i].length >= s.length){
			if(this[i].slice(0, s.length) == s){
				arr.push(this[i]);
			}else{
				break;
			}
		}else{
			break;
		}
	}
	return arr;
};

// ハッシュタグ編集中なら#の位置をかえす。
// そうでないならundefined
function hashtagEditing(tex, beg)
{
	var hbeg;
	var hash = false;
	for(var i = beg - 1; i >= 0; --i){
		if(!tex.charAt(i).match(/[a-zA-Z0-9_]/)){
			if(tex.charAt(i) == '#'){
				hbeg = i;
				hash = true;
				break;
			}else{
				return undefined;
			}
		}
	}
	if(!hash) return undefined;
	return hbeg;
}

// ハッシュタグ補完を処理する
function processCandidate(fwd)
{
	var r = TextArea.selectedRange;
	var beg = (r & 0xffff);
	var hbeg = beg;
	var end = (r >> 16) & 0xffff;
	var tex = TextArea.text;
	if(arguments.length == 2){
		tex = tex.slice(0, beg) + arguments[1] + tex.slice(end);
		beg += 1;
		end = beg;
	}
	hbeg = hashtagEditing(tex, beg);
	if(hbeg == undefined) return false;
	var cds = candidates.subset(tex.slice(hbeg, beg));
	var idx = cds.lowerBound(tex.slice(hbeg, end));
	idx += fwd ? 1 : -1;
	if(idx == cds.length) idx = 0;
	if(cds.length == 0 || cds[idx] == undefined) return arguments.length == 0;
	tex = tex.slice(0, hbeg) + cds[idx] + tex.slice(end);
	TextArea.text = tex;
	TextArea.select(beg, cds[idx].length + hbeg);
	return true;
}

// 文字入力されたときのイベント処理。
TextArea.addEventListener('char', function(c){
	if(c=='#'){
		// とりあえずハッシュタグを突っ込む
		var r = TextArea.selectedRange;
		var beg = (r & 0xffff);
		var hbeg = beg;
		var end = (r >> 16) & 0xffff;
		var cur = TextArea.cursor;
		var tex = TextArea.text;
		var partA = tex.slice(0, cur);
		var partB = tex.slice(cur);
		var candidate = false;
		if(beg != end && hashtagEditing(tex, beg) != undefined) return true;
		if(candidates.length > 0){
			tex = partA + candidates[0] + partB;
			candidate = true;
		}else{
			tex = partA + '#' + partB;
		}
		TextArea.text = tex;
		TextArea.cursor = cur + 1;
		if(candidate){
			TextArea.select(cur + 1, cur + candidates[0].length);
		}
		return true;
	}else if(c==' '){
		// 選択範囲があってかつ、ハッシュタグの範囲であれば選択を解除して半角スペースを入力
		var r = TextArea.selectedRange;
		var beg = (r & 0xffff);
		var hbeg = beg;
		var end = (r >> 16) & 0xffff;
		var tex = TextArea.text;
		if(beg == end) return false;
		hbeg = hashtagEditing(tex, beg);
		if(hbeg == undefined) return false;
		tex = tex.slice(0, end) + ' ' + tex.slice(end);
		TextArea.text = tex;
		TextArea.cursor = end + 1;
		return true;
	}else{
		// ハッシュタグとして有効な文字ならさらに補完
		if(c.match(/[a-zA-Z0-9_]/)){
			return processCandidate(true, c);
		}
	}
});

// KeyDownをフック
TextArea.addEventListener('keydown', function(c, m){
	// F4: 予測変換リストを更新
	if(c==0x73){
		TextArea.getHashtagCandidates(candidates);
		candidates.sort();
		return true;
	}
	// Tab: 次の候補を表示
	else if(c==9){
		return processCandidate((m & 1) == 0);
	}
});

// TL更新完了イベントをフック
// ハッシュタグリストを更新する
TwitterService.addEventListener('postProcessTimelineStatuses', function(){
	candidates = [];
	TextArea.getHashtagCandidates(candidates);
	candidates.sort();
});

// 終了イベントをフック
// 補完リストを保存する
System.addEventListener('quit', function(){
	var value = candidates.join(',');
	if(value[0] == ',') value = value.slice(1);
	System.settings.setValue('user.HashtagCandidate', 'candidates', value);
	System.settings.reconfigure();
});

// 保存された補完リストを読み込む
var value = System.settings.getValue('user.HashtagCandidate', 'candidates');
if(value != ''){
	candidates = value.split(',');
	candidates.sort();
}

コメントとか

  • 補完処理おかしかったの修正して、shift+tabで逆順検索できるようにしてみた -- tmyt? 2011-06-08 (水) 15:05:25

もし見えてたら空欄にしてね!:

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-08-27 (土) 10:33:41 (1525d)